Conflicts: tools/perf/Makefile tools/perf/builtin-test.c tools/perf/perf.h tools/perf/tests/parse-events.c tools/perf/util/evsel.h
Unified · Split
| @@ -1823,6 +1823,11 @@ S: Kattreinstr 38 · 1822 unmodified lines | ||
| 1823 | 1823 | S: D-64295 |
| 1824 | 1824 | S: Germany |
| 1825 | 1825 | |
| 1826 | +N: Avi Kivity | |
| 1827 | +E: avi.kivity@gmail.com | |
| 1828 | +D: Kernel-based Virtual Machine (KVM) | |
| 1829 | +S: Ra'annana, Israel | |
| 1830 | + | |
| 1826 | 1831 | N: Andi Kleen |
| 1827 | 1832 | E: andi@firstfloor.org |
| 1828 | 1833 | U: http://www.halobates.de |
| @@ -27,17 +27,17 @@ Start End Size Use · 26 unmodified lines | ||
| 27 | 27 | ----------------------------------------------------------------------- |
| 28 | 28 | 0000000000000000 0000007fffffffff 512GB user |
| 29 | 29 | |
| 30 | −ffffff8000000000 ffffffbbfffcffff ~240GB vmalloc | |
| 30 | +ffffff8000000000 ffffffbbfffeffff ~240GB vmalloc | |
| 31 | 31 | |
| 32 | −ffffffbbfffd0000 ffffffbcfffdffff 64KB [guard page] | |
| 32 | +ffffffbbffff0000 ffffffbbffffffff 64KB [guard page] | |
| 33 | 33 | |
| 34 | −ffffffbbfffe0000 ffffffbcfffeffff 64KB PCI I/O space | |
| 34 | +ffffffbc00000000 ffffffbdffffffff 8GB vmemmap | |
| 35 | 35 | |
| 36 | −ffffffbbffff0000 ffffffbcffffffff 64KB [guard page] | |
| 36 | +ffffffbe00000000 ffffffbffbbfffff ~8GB [guard, future vmmemap] | |
| 37 | 37 | |
| 38 | −ffffffbc00000000 ffffffbdffffffff 8GB vmemmap | |
| 38 | +ffffffbffbe00000 ffffffbffbe0ffff 64KB PCI I/O space | |
| 39 | 39 | |
| 40 | −ffffffbe00000000 ffffffbffbffffff ~8GB [guard, future vmmemap] | |
| 40 | +ffffffbbffff0000 ffffffbcffffffff ~2MB [guard] | |
| 41 | 41 | |
| 42 | 42 | ffffffbffc000000 ffffffbfffffffff 64MB modules |
| 43 | 43 | |
| @@ -466,6 +466,10 @@ Note: · 465 unmodified lines | ||
| 466 | 466 | 5.3 swappiness |
| 467 | 467 | |
| 468 | 468 | Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only. |
| 469 | +Please note that unlike the global swappiness, memcg knob set to 0 | |
| 470 | +really prevents from any swapping even if there is a swap storage | |
| 471 | +available. This might lead to memcg OOM killer if there are no file | |
| 472 | +pages to reclaim. | |
| 469 | 473 | |
| 470 | 474 | Following cgroups' swappiness can't be changed. |
| 471 | 475 | - root cgroup (uses /proc/sys/vm/swappiness). |
| @@ -8,7 +8,7 @@ PIT Timer required properties: · 7 unmodified lines | ||
| 8 | 8 | shared across all System Controller members. |
| 9 | 9 | |
| 10 | 10 | TC/TCLIB Timer required properties: |
| 11 | −- compatible: Should be "atmel,<chip>-pit". | |
| 11 | +- compatible: Should be "atmel,<chip>-tcb". | |
| 12 | 12 | <chip> can be "at91rm9200" or "at91sam9x5" |
| 13 | 13 | - reg: Should contain registers location and length |
| 14 | 14 | - interrupts: Should contain all interrupts for the TC block |
| @@ -0,0 +1,19 @@ | ||
| 1 | +* EETI eGalax Multiple Touch Controller | |
| 2 | + | |
| 3 | +Required properties: | |
| 4 | +- compatible: must be "eeti,egalax_ts" | |
| 5 | +- reg: i2c slave address | |
| 6 | +- interrupt-parent: the phandle for the interrupt controller | |
| 7 | +- interrupts: touch controller interrupt | |
| 8 | +- wakeup-gpios: the gpio pin to be used for waking up the controller | |
| 9 | + as well as uased as irq pin | |
| 10 | + | |
| 11 | +Example: | |
| 12 | + | |
| 13 | + egalax_ts@04 { | |
| 14 | + compatible = "eeti,egalax_ts"; | |
| 15 | + reg = <0x04>; | |
| 16 | + interrupt-parent = <&gpio1>; | |
| 17 | + interrupts = <9 2>; | |
| 18 | + wakeup-gpios = <&gpio1 9 0>; | |
| 19 | + }; | |
| @@ -8,9 +8,16 @@ gpios property as described in section VIII.1 in the following order: · 7 unmodified lines | ||
| 8 | 8 | |
| 9 | 9 | MDC, MDIO. |
| 10 | 10 | |
| 11 | +Note: Each gpio-mdio bus should have an alias correctly numbered in "aliases" | |
| 12 | +node. | |
| 13 | + | |
| 11 | 14 | Example: |
| 12 | 15 | |
| 13 | −mdio { | |
| 16 | +aliases { | |
| 17 | + mdio-gpio0 = <&mdio0>; | |
| 18 | +}; | |
| 19 | + | |
| 20 | +mdio0: mdio { | |
| 14 | 21 | compatible = "virtual,mdio-gpio"; |
| 15 | 22 | #address-cells = <1>; |
| 16 | 23 | #size-cells = <0>; |
| @@ -93,7 +93,7 @@ Valid values for pin and group names are: · 92 unmodified lines | ||
| 93 | 93 | |
| 94 | 94 | With some exceptions, these support nvidia,high-speed-mode, |
| 95 | 95 | nvidia,schmitt, nvidia,low-power-mode, nvidia,pull-down-strength, |
| 96 | − nvidia,pull-up-strength, nvidia,slew_rate-rising, nvidia,slew_rate-falling. | |
| 96 | + nvidia,pull-up-strength, nvidia,slew-rate-rising, nvidia,slew-rate-falling. | |
| 97 | 97 | |
| 98 | 98 | drive_ao1, drive_ao2, drive_at1, drive_at2, drive_cdev1, drive_cdev2, |
| 99 | 99 | drive_csus, drive_dap1, drive_dap2, drive_dap3, drive_dap4, drive_dbg, |
| @@ -83,7 +83,7 @@ Valid values for pin and group names are: · 82 unmodified lines | ||
| 83 | 83 | drive groups: |
| 84 | 84 | |
| 85 | 85 | These all support nvidia,pull-down-strength, nvidia,pull-up-strength, |
| 86 | − nvidia,slew_rate-rising, nvidia,slew_rate-falling. Most but not all | |
| 86 | + nvidia,slew-rate-rising, nvidia,slew-rate-falling. Most but not all | |
| 87 | 87 | support nvidia,high-speed-mode, nvidia,schmitt, nvidia,low-power-mode. |
| 88 | 88 | |
| 89 | 89 | ao1, ao2, at1, at2, at3, at4, at5, cdev1, cdev2, cec, crt, csus, dap1, |
| @@ -33,7 +33,7 @@ Table of Contents · 32 unmodified lines | ||
| 33 | 33 | 2 Modifying System Parameters |
| 34 | 34 | |
| 35 | 35 | 3 Per-Process Parameters |
| 36 | − 3.1 /proc/<pid>/oom_score_adj - Adjust the oom-killer | |
| 36 | + 3.1 /proc/<pid>/oom_adj & /proc/<pid>/oom_score_adj - Adjust the oom-killer | |
| 37 | 37 | score |
| 38 | 38 | 3.2 /proc/<pid>/oom_score - Display current oom-killer score |
| 39 | 39 | 3.3 /proc/<pid>/io - Display the IO accounting fields |
| @@ -1320,10 +1320,10 @@ of the kernel. · 1280 unmodified lines | ||
| 1320 | 1320 | CHAPTER 3: PER-PROCESS PARAMETERS |
| 1321 | 1321 | ------------------------------------------------------------------------------ |
| 1322 | 1322 | |
| 1323 | −3.1 /proc/<pid>/oom_score_adj- Adjust the oom-killer score | |
| 1323 | +3.1 /proc/<pid>/oom_adj & /proc/<pid>/oom_score_adj- Adjust the oom-killer score | |
| 1324 | 1324 | -------------------------------------------------------------------------------- |
| 1325 | 1325 | |
| 1326 | −This file can be used to adjust the badness heuristic used to select which | |
| 1326 | +These file can be used to adjust the badness heuristic used to select which | |
| 1327 | 1327 | process gets killed in out of memory conditions. |
| 1328 | 1328 | |
| 1329 | 1329 | The badness heuristic assigns a value to each candidate task ranging from 0 |
| @@ -1361,6 +1361,12 @@ same system, cpuset, mempolicy, or memory controller resources to use at least · 31 unmodified lines | ||
| 1361 | 1361 | equivalent to discounting 50% of the task's allowed memory from being considered |
| 1362 | 1362 | as scoring against the task. |
| 1363 | 1363 | |
| 1364 | +For backwards compatibility with previous kernels, /proc/<pid>/oom_adj may also | |
| 1365 | +be used to tune the badness score. Its acceptable values range from -16 | |
| 1366 | +(OOM_ADJUST_MIN) to +15 (OOM_ADJUST_MAX) and a special value of -17 | |
| 1367 | +(OOM_DISABLE) to disable oom killing entirely for that task. Its value is | |
| 1368 | +scaled linearly with /proc/<pid>/oom_score_adj. | |
| 1369 | + | |
| 1364 | 1370 | The value of /proc/<pid>/oom_score_adj may be reduced no lower than the last |
| 1365 | 1371 | value set by a CAP_SYS_RESOURCE process. To reduce the value any lower |
| 1366 | 1372 | requires CAP_SYS_RESOURCE. |
| @@ -1375,7 +1381,9 @@ minimal amount of work. · 8 unmodified lines | ||
| 1375 | 1381 | ------------------------------------------------------------- |
| 1376 | 1382 | |
| 1377 | 1383 | This file can be used to check the current score used by the oom-killer is for |
| 1378 | −any given <pid>. | |
| 1384 | +any given <pid>. Use it together with /proc/<pid>/oom_score_adj to tune which | |
| 1385 | +process should be killed in an out-of-memory situation. | |
| 1386 | + | |
| 1379 | 1387 | |
| 1380 | 1388 | 3.3 /proc/<pid>/io - Display the IO accounting fields |
| 1381 | 1389 | ------------------------------------------------------- |
| @@ -18,32 +18,40 @@ · 17 unmodified lines | ||
| 18 | 18 | High level behavior (mixed): |
| 19 | 19 | ============================ |
| 20 | 20 | |
| 21 | − kernel(driver): calls request_firmware(&fw_entry, $FIRMWARE, device) | |
| 22 | − | |
| 23 | − userspace: | |
| 21 | + 1), kernel(driver): | |
| 22 | + - calls request_firmware(&fw_entry, $FIRMWARE, device) | |
| 23 | + - kernel searchs the fimware image with name $FIRMWARE directly | |
| 24 | + in the below search path of root filesystem: | |
| 25 | + "/lib/firmware/updates/" UTS_RELEASE, | |
| 26 | + "/lib/firmware/updates", | |
| 27 | + "/lib/firmware/" UTS_RELEASE, | |
| 28 | + "/lib/firmware" | |
| 29 | + - If found, goto 7), else goto 2) | |
| 30 | + | |
| 31 | + 2), userspace: | |
| 24 | 32 | - /sys/class/firmware/xxx/{loading,data} appear. |
| 25 | 33 | - hotplug gets called with a firmware identifier in $FIRMWARE |
| 26 | 34 | and the usual hotplug environment. |
| 27 | 35 | - hotplug: echo 1 > /sys/class/firmware/xxx/loading |
| 28 | 36 | |
| 29 | − kernel: Discard any previous partial load. | |
| 37 | + 3), kernel: Discard any previous partial load. | |
| 30 | 38 | |
| 31 | − userspace: | |
| 39 | + 4), userspace: | |
| 32 | 40 | - hotplug: cat appropriate_firmware_image > \ |
| 33 | 41 | /sys/class/firmware/xxx/data |
| 34 | 42 | |
| 35 | − kernel: grows a buffer in PAGE_SIZE increments to hold the image as it | |
| 43 | + 5), kernel: grows a buffer in PAGE_SIZE increments to hold the image as it | |
| 36 | 44 | comes in. |
| 37 | 45 | |
| 38 | − userspace: | |
| 46 | + 6), userspace: | |
| 39 | 47 | - hotplug: echo 0 > /sys/class/firmware/xxx/loading |
| 40 | 48 | |
| 41 | − kernel: request_firmware() returns and the driver has the firmware | |
| 49 | + 7), kernel: request_firmware() returns and the driver has the firmware | |
| 42 | 50 | image in fw_entry->{data,size}. If something went wrong |
| 43 | 51 | request_firmware() returns non-zero and fw_entry is set to |
| 44 | 52 | NULL. |
| 45 | 53 | |
| 46 | − kernel(driver): Driver code calls release_firmware(fw_entry) releasing | |
| 54 | + 8), kernel(driver): Driver code calls release_firmware(fw_entry) releasing | |
| 47 | 55 | the firmware image and any related resource. |
| 48 | 56 | |
| 49 | 57 | High level behavior (driver code): |
| @@ -10,7 +10,7 @@ Supported chips: · 9 unmodified lines | ||
| 10 | 10 | BIOS and Kernel Developer's Guide (BKDG) For AMD Family 15h Processors |
| 11 | 11 | (not yet published) |
| 12 | 12 | |
| 13 | −Author: Andreas Herrmann <andreas.herrmann3@amd.com> | |
| 13 | +Author: Andreas Herrmann <herrmann.der.user@googlemail.com> | |
| 14 | 14 | |
| 15 | 15 | Description |
| 16 | 16 | ----------- |
| @@ -164,4 +164,4 @@ read the CRC recorded by the NIC on receipt of the packet. · 163 unmodified lines | ||
| 164 | 164 | This requests that the NIC receive all possible frames, including errored |
| 165 | 165 | frames (such as bad FCS, etc). This can be helpful when sniffing a link with |
| 166 | 166 | bad packets on it. Some NICs may receive more packets if also put into normal |
| 167 | −PROMISC mdoe. | |
| 167 | +PROMISC mode. | |
| @@ -32,7 +32,7 @@ no entry is in the forwarding table. · 31 unmodified lines | ||
| 32 | 32 | # ip link delete vxlan0 |
| 33 | 33 | |
| 34 | 34 | 3. Show vxlan info |
| 35 | − # ip -d show vxlan0 | |
| 35 | + # ip -d link show vxlan0 | |
| 36 | 36 | |
| 37 | 37 | It is possible to create, destroy and display the vxlan |
| 38 | 38 | forwarding table using the new bridge command. |
| @@ -41,7 +41,7 @@ forwarding table using the new bridge command. · 2 unmodified lines | ||
| 41 | 41 | # bridge fdb add to 00:17:42:8a:b4:05 dst 192.19.0.2 dev vxlan0 |
| 42 | 42 | |
| 43 | 43 | 2. Delete forwarding table entry |
| 44 | − # bridge fdb delete 00:17:42:8a:b4:05 | |
| 44 | + # bridge fdb delete 00:17:42:8a:b4:05 dev vxlan0 | |
| 45 | 45 | |
| 46 | 46 | 3. Show forwarding table |
| 47 | 47 | # bridge fdb show dev vxlan0 |
| @@ -0,0 +1,39 @@ | ||
| 1 | +Chinese translated version of Documentation/IRQ.txt | |
| 2 | + | |
| 3 | +If you have any comment or update to the content, please contact the | |
| 4 | +original document maintainer directly. However, if you have a problem | |
| 5 | +communicating in English you can also ask the Chinese maintainer for | |
| 6 | +help. Contact the Chinese maintainer if this translation is outdated | |
| 7 | +or if there is a problem with the translation. | |
| 8 | + | |
| 9 | +Maintainer: Eric W. Biederman <ebiederman@xmission.com> | |
| 10 | +Chinese maintainer: Fu Wei <tekkamanninja@gmail.com> | |
| 11 | +--------------------------------------------------------------------- | |
| 12 | +Documentation/IRQ.txt 的中文翻译 | |
| 13 | + | |
| 14 | +如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文 | |
| 15 | +交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻 | |
| 16 | +译存在问题,请联系中文版维护者。 | |
| 17 | +英文版维护者: Eric W. Biederman <ebiederman@xmission.com> | |
| 18 | +中文版维护者: 傅炜 Fu Wei <tekkamanninja@gmail.com> | |
| 19 | +中文版翻译者: 傅炜 Fu Wei <tekkamanninja@gmail.com> | |
| 20 | +中文版校译者: 傅炜 Fu Wei <tekkamanninja@gmail.com> | |
| 21 | + | |
| 22 | + | |
| 23 | +以下为正文 | |
| 24 | +--------------------------------------------------------------------- | |
| 25 | +何为 IRQ? | |
| 26 | + | |
| 27 | +一个 IRQ 是来自某个设备的一个中断请求。目前,它们可以来自一个硬件引脚, | |
| 28 | +或来自一个数据包。多个设备可能连接到同个硬件引脚,从而共享一个 IRQ。 | |
| 29 | + | |
| 30 | +一个 IRQ 编号是用于告知硬件中断源的内核标识。通常情况下,这是一个 | |
| 31 | +全局 irq_desc 数组的索引,但是除了在 linux/interrupt.h 中的实现, | |
| 32 | +具体的细节是体系结构特定的。 | |
| 33 | + | |
| 34 | +一个 IRQ 编号是设备上某个可能的中断源的枚举。通常情况下,枚举的编号是 | |
| 35 | +该引脚在系统内中断控制器的所有输入引脚中的编号。对于 ISA 总线中的情况, | |
| 36 | +枚举的是在两个 i8259 中断控制器中 16 个输入引脚。 | |
| 37 | + | |
| 38 | +架构可以对 IRQ 编号指定额外的含义,在硬件涉及任何手工配置的情况下, | |
| 39 | +是被提倡的。ISA 的 IRQ 是一个分配这类额外含义的典型例子。 | |
| @@ -0,0 +1,156 @@ | ||
| 1 | +Chinese translated version of Documentation/arm64/booting.txt | |
| 2 | + | |
| 3 | +If you have any comment or update to the content, please contact the | |
| 4 | +original document maintainer directly. However, if you have a problem | |
| 5 | +communicating in English you can also ask the Chinese maintainer for | |
| 6 | +help. Contact the Chinese maintainer if this translation is outdated | |
| 7 | +or if there is a problem with the translation. | |
| 8 | + | |
| 9 | +Maintainer: Will Deacon <will.deacon@arm.com> | |
| 10 | +Chinese maintainer: Fu Wei <tekkamanninja@gmail.com> | |
| 11 | +--------------------------------------------------------------------- | |
| 12 | +Documentation/arm64/booting.txt 的中文翻译 | |
| 13 | + | |
| 14 | +如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文 | |
| 15 | +交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻 | |
| 16 | +译存在问题,请联系中文版维护者。 | |
| 17 | + | |
| 18 | +英文版维护者: Will Deacon <will.deacon@arm.com> | |
| 19 | +中文版维护者: 傅炜 Fu Wei <tekkamanninja@gmail.com> | |
| 20 | +中文版翻译者: 傅炜 Fu Wei <tekkamanninja@gmail.com> | |
| 21 | +中文版校译者: 傅炜 Fu Wei <tekkamanninja@gmail.com> | |
| 22 | + | |
| 23 | +以下为正文 | |
| 24 | +--------------------------------------------------------------------- | |
| 25 | + 启动 AArch64 Linux | |
| 26 | + ================== | |
| 27 | + | |
| 28 | +作者: Will Deacon <will.deacon@arm.com> | |
| 29 | +日期: 2012 年 09 月 07 日 | |
| 30 | + | |
| 31 | +本文档基于 Russell King 的 ARM 启动文档,且适用于所有公开发布的 | |
| 32 | +AArch64 Linux 内核代码。 | |
| 33 | + | |
| 34 | +AArch64 异常模型由多个异常级别(EL0 - EL3)组成,对于 EL0 和 EL1 | |
| 35 | +异常级有对应的安全和非安全模式。EL2 是系统管理级,且仅存在于 | |
| 36 | +非安全模式下。EL3 是最高特权级,且仅存在于安全模式下。 | |
| 37 | + | |
| 38 | +基于本文档的目的,我们将简单地使用‘引导装载程序’(‘boot loader’) | |
| 39 | +这个术语来定义在将控制权交给 Linux 内核前 CPU 上执行的所有软件。 | |
| 40 | +这可能包含安全监控和系统管理代码,或者它可能只是一些用于准备最小启动 | |
| 41 | +环境的指令。 | |
| 42 | + | |
| 43 | +基本上,引导装载程序(至少)应实现以下操作: | |
| 44 | + | |
| 45 | +1、设置和初始化 RAM | |
| 46 | +2、设置设备树数据 | |
| 47 | +3、解压内核映像 | |
| 48 | +4、调用内核映像 | |
| 49 | + | |
| 50 | + | |
| 51 | +1、设置和初始化 RAM | |
| 52 | +----------------- | |
| 53 | + | |
| 54 | +必要性: 强制 | |
| 55 | + | |
| 56 | +引导装载程序应该找到并初始化系统中所有内核用于保持系统变量数据的 RAM。 | |
| 57 | +这个操作的执行是设备依赖的。(它可能使用内部算法来自动定位和计算所有 | |
| 58 | +RAM,或可能使用对这个设备已知的 RAM 信息,还可能使用任何引导装载程序 | |
| 59 | +设计者想到的匹配方法。) | |
| 60 | + | |
| 61 | + | |
| 62 | +2、设置设备树数据 | |
| 63 | +--------------- | |
| 64 | + | |
| 65 | +必要性: 强制 | |
| 66 | + | |
| 67 | +设备树数据块(dtb)大小必须不大于 2 MB,且位于从内核映像起始算起第一个 | |
| 68 | +512MB 内的 2MB 边界上。这使得内核可以通过初始页表中的单个节描述符来 | |
| 69 | +映射此数据块。 | |
| 70 | + | |
| 71 | + | |
| 72 | +3、解压内核映像 | |
| 73 | +------------- | |
| 74 | + | |
| 75 | +必要性: 可选 | |
| 76 | + | |
| 77 | +AArch64 内核当前没有提供自解压代码,因此如果使用了压缩内核映像文件 | |
| 78 | +(比如 Image.gz),则需要通过引导装载程序(使用 gzip 等)来进行解压。 | |
| 79 | +若引导装载程序没有实现这个需求,就要使用非压缩内核映像文件。 | |
| 80 | + | |
| 81 | + | |
| 82 | +4、调用内核映像 | |
| 83 | +------------- | |
| 84 | + | |
| 85 | +必要性: 强制 | |
| 86 | + | |
| 87 | +已解压的内核映像包含一个 32 字节的头,内容如下: | |
| 88 | + | |
| 89 | + u32 magic = 0x14000008; /* 跳转到 stext, 小端 */ | |
| 90 | + u32 res0 = 0; /* 保留 */ | |
| 91 | + u64 text_offset; /* 映像装载偏移 */ | |
| 92 | + u64 res1 = 0; /* 保留 */ | |
| 93 | + u64 res2 = 0; /* 保留 */ | |
| 94 | + | |
| 95 | +映像必须位于系统 RAM 起始处的特定偏移(当前是 0x80000)。系统 RAM | |
| 96 | +的起始地址必须是以 2MB 对齐的。 | |
| 97 | + | |
| 98 | +在跳转入内核前,必须符合以下状态: | |
| 99 | + | |
| 100 | +- 停止所有 DMA 设备,这样内存数据就不会因为虚假网络包或磁盘数据而 | |
| 101 | + 被破坏。这可能可以节省你许多的调试时间。 | |
| 102 | + | |
| 103 | +- 主 CPU 通用寄存器设置 | |
| 104 | + x0 = 系统 RAM 中设备树数据块(dtb)的物理地址。 | |
| 105 | + x1 = 0 (保留,将来可能使用) | |
| 106 | + x2 = 0 (保留,将来可能使用) | |
| 107 | + x3 = 0 (保留,将来可能使用) | |
| 108 | + | |
| 109 | +- CPU 模式 | |
| 110 | + 所有形式的中断必须在 PSTATE.DAIF 中被屏蔽(Debug、SError、IRQ | |
| 111 | + 和 FIQ)。 | |
| 112 | + CPU 必须处于 EL2(推荐,可访问虚拟化扩展)或非安全 EL1 模式下。 | |
| 113 | + | |
| 114 | +- 高速缓存、MMU | |
| 115 | + MMU 必须关闭。 | |
| 116 | + 指令缓存开启或关闭都可以。 | |
| 117 | + 数据缓存必须关闭且无效。 | |
| 118 | + 外部高速缓存(如果存在)必须配置并禁用。 | |
| 119 | + | |
| 120 | +- 架构计时器 | |
| 121 | + CNTFRQ 必须设定为计时器的频率。 | |
| 122 | + 如果在 EL1 模式下进入内核,则 CNTHCTL_EL2 中的 EL1PCTEN (bit 0) | |
| 123 | + 必须置位。 | |
| 124 | + | |
| 125 | +- 一致性 | |
| 126 | + 通过内核启动的所有 CPU 在内核入口地址上必须处于相同的一致性域中。 | |
| 127 | + 这可能要根据具体实现来定义初始化过程,以使能每个CPU上对维护操作的 | |
| 128 | + 接收。 | |
| 129 | + | |
| 130 | +- 系统寄存器 | |
| 131 | + 在进入内核映像的异常级中,所有构架中可写的系统寄存器必须通过软件 | |
| 132 | + 在一个更高的异常级别下初始化,以防止在 未知 状态下运行。 | |
| 133 | + | |
| 134 | +引导装载程序必须在每个 CPU 处于以下状态时跳入内核入口: | |
| 135 | + | |
| 136 | +- 主 CPU 必须直接跳入内核映像的第一条指令。通过此 CPU 传递的设备树 | |
| 137 | + 数据块必须在每个 CPU 节点中包含以下内容: | |
| 138 | + | |
| 139 | + 1、‘enable-method’属性。目前,此字段支持的值仅为字符串“spin-table”。 | |
| 140 | + | |
| 141 | + 2、‘cpu-release-addr’标识一个 64-bit、初始化为零的内存位置。 | |
| 142 | + | |
| 143 | + 引导装载程序必须生成这些设备树属性,并在跳入内核入口之前将其插入 | |
| 144 | + 数据块。 | |
| 145 | + | |
| 146 | +- 任何辅助 CPU 必须在内存保留区(通过设备树中的 /memreserve/ 域传递 | |
| 147 | + 给内核)中自旋于内核之外,轮询它们的 cpu-release-addr 位置(必须 | |
| 148 | + 包含在保留区中)。可通过插入 wfe 指令来降低忙循环开销,而主 CPU 将 | |
| 149 | + 发出 sev 指令。当对 cpu-release-addr 所指位置的读取操作返回非零值 | |
| 150 | + 时,CPU 必须直接跳入此值所指向的地址。 | |
| 151 | + | |
| 152 | +- 辅助 CPU 通用寄存器设置 | |
| 153 | + x0 = 0 (保留,将来可能使用) | |
| 154 | + x1 = 0 (保留,将来可能使用) | |
| 155 | + x2 = 0 (保留,将来可能使用) | |
| 156 | + x3 = 0 (保留,将来可能使用) | |
| @@ -0,0 +1,93 @@ | ||
| 1 | +Chinese translated version of Documentation/arm64/memory.txt | |
| 2 | + | |
| 3 | +If you have any comment or update to the content, please contact the | |
| 4 | +original document maintainer directly. However, if you have a problem | |
| 5 | +communicating in English you can also ask the Chinese maintainer for | |
| 6 | +help. Contact the Chinese maintainer if this translation is outdated | |
| 7 | +or if there is a problem with the translation. | |
| 8 | + | |
| 9 | +Maintainer: Catalin Marinas <catalin.marinas@arm.com> | |
| 10 | +Chinese maintainer: Fu Wei <tekkamanninja@gmail.com> | |
| 11 | +--------------------------------------------------------------------- | |
| 12 | +Documentation/arm64/memory.txt 的中文翻译 | |
| 13 | + | |
| 14 | +如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文 | |
| 15 | +交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻 | |
| 16 | +译存在问题,请联系中文版维护者。 | |
| 17 | + | |
| 18 | +英文版维护者: Catalin Marinas <catalin.marinas@arm.com> | |
| 19 | +中文版维护者: 傅炜 Fu Wei <tekkamanninja@gmail.com> | |
| 20 | +中文版翻译者: 傅炜 Fu Wei <tekkamanninja@gmail.com> | |
| 21 | +中文版校译者: 傅炜 Fu Wei <tekkamanninja@gmail.com> | |
| 22 | + | |
| 23 | +以下为正文 | |
| 24 | +--------------------------------------------------------------------- | |
| 25 | + Linux 在 AArch64 中的内存布局 | |
| 26 | + =========================== | |
| 27 | + | |
| 28 | +作者: Catalin Marinas <catalin.marinas@arm.com> | |
| 29 | +日期: 2012 年 02 月 20 日 | |
| 30 | + | |
| 31 | +本文档描述 AArch64 Linux 内核所使用的虚拟内存布局。此构架可以实现 | |
| 32 | +页大小为 4KB 的 4 级转换表和页大小为 64KB 的 3 级转换表。 | |
| 33 | + | |
| 34 | +AArch64 Linux 使用页大小为 4KB 的 3 级转换表配置,对于用户和内核 | |
| 35 | +都有 39-bit (512GB) 的虚拟地址空间。对于页大小为 64KB的配置,仅 | |
| 36 | +使用 2 级转换表,但内存布局相同。 | |
| 37 | + | |
| 38 | +用户地址空间的 63:39 位为 0,而内核地址空间的相应位为 1。TTBRx 的 | |
| 39 | +选择由虚拟地址的 63 位给出。swapper_pg_dir 仅包含内核(全局)映射, | |
| 40 | +而用户 pgd 仅包含用户(非全局)映射。swapper_pgd_dir 地址被写入 | |
| 41 | +TTBR1 中,且从不写入 TTBR0。 | |
| 42 | + | |
| 43 | + | |
| 44 | +AArch64 Linux 内存布局: | |
| 45 | + | |
| 46 | +起始地址 结束地址 大小 用途 | |
| 47 | +----------------------------------------------------------------------- | |
| 48 | +0000000000000000 0000007fffffffff 512GB 用户空间 | |
| 49 | + | |
| 50 | +ffffff8000000000 ffffffbbfffcffff ~240GB vmalloc | |
| 51 | + | |
| 52 | +ffffffbbfffd0000 ffffffbcfffdffff 64KB [防护页] | |
| 53 | + | |
| 54 | +ffffffbbfffe0000 ffffffbcfffeffff 64KB PCI I/O 空间 | |
| 55 | + | |
| 56 | +ffffffbbffff0000 ffffffbcffffffff 64KB [防护页] | |
| 57 | + | |
| 58 | +ffffffbc00000000 ffffffbdffffffff 8GB vmemmap | |
| 59 | + | |
| 60 | +ffffffbe00000000 ffffffbffbffffff ~8GB [防护页,未来用于 vmmemap] | |
| 61 | + | |
| 62 | +ffffffbffc000000 ffffffbfffffffff 64MB 模块 | |
| 63 | + | |
| 64 | +ffffffc000000000 ffffffffffffffff 256GB 内存空间 | |
| 65 | + | |
| 66 | + | |
| 67 | +4KB 页大小的转换表查找: | |
| 68 | + | |
| 69 | ++--------+--------+--------+--------+--------+--------+--------+--------+ | |
| 70 | +|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0| | |
| 71 | ++--------+--------+--------+--------+--------+--------+--------+--------+ | |
| 72 | + | | | | | | | |
| 73 | + | | | | | v | |
| 74 | + | | | | | [11:0] 页内偏移 | |
| 75 | + | | | | +-> [20:12] L3 索引 | |
| 76 | + | | | +-----------> [29:21] L2 索引 | |
| 77 | + | | +---------------------> [38:30] L1 索引 | |
| 78 | + | +-------------------------------> [47:39] L0 索引 (未使用) | |
| 79 | + +-------------------------------------------------> [63] TTBR0/1 | |
| 80 | + | |
| 81 | + | |
| 82 | +64KB 页大小的转换表查找: | |
| 83 | + | |
| 84 | ++--------+--------+--------+--------+--------+--------+--------+--------+ | |
| 85 | +|63 56|55 48|47 40|39 32|31 24|23 16|15 8|7 0| | |
| 86 | ++--------+--------+--------+--------+--------+--------+--------+--------+ | |
| 87 | + | | | | | | |
| 88 | + | | | | v | |
| 89 | + | | | | [15:0] 页内偏移 | |
| 90 | + | | | +----------> [28:16] L3 索引 | |
| 91 | + | | +--------------------------> [41:29] L2 索引 (仅使用 38:29 ) | |
| 92 | + | +-------------------------------> [47:42] L1 索引 (未使用) | |
| 93 | + +-------------------------------------------------> [63] TTBR0/1 | |
| @@ -503,7 +503,7 @@ F: include/linux/altera_uart.h · 502 unmodified lines | ||
| 503 | 503 | F: include/linux/altera_jtaguart.h |
| 504 | 504 | |
| 505 | 505 | AMD FAM15H PROCESSOR POWER MONITORING DRIVER |
| 506 | −M: Andreas Herrmann <andreas.herrmann3@amd.com> | |
| 506 | +M: Andreas Herrmann <herrmann.der.user@googlemail.com> | |
| 507 | 507 | L: lm-sensors@lm-sensors.org |
| 508 | 508 | S: Maintained |
| 509 | 509 | F: Documentation/hwmon/fam15h_power |
| @@ -526,17 +526,17 @@ F: drivers/video/geode/ · 16 unmodified lines | ||
| 526 | 526 | F: arch/x86/include/asm/geode.h |
| 527 | 527 | |
| 528 | 528 | AMD IOMMU (AMD-VI) |
| 529 | −M: Joerg Roedel <joerg.roedel@amd.com> | |
| 529 | +M: Joerg Roedel <joro@8bytes.org> | |
| 530 | 530 | L: iommu@lists.linux-foundation.org |
| 531 | 531 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git |
| 532 | −S: Supported | |
| 532 | +S: Maintained | |
| 533 | 533 | F: drivers/iommu/amd_iommu*.[ch] |
| 534 | 534 | F: include/linux/amd-iommu.h |
| 535 | 535 | |
| 536 | 536 | AMD MICROCODE UPDATE SUPPORT |
| 537 | −M: Andreas Herrmann <andreas.herrmann3@amd.com> | |
| 537 | +M: Andreas Herrmann <herrmann.der.user@googlemail.com> | |
| 538 | 538 | L: amd64-microcode@amd64.org |
| 539 | −S: Supported | |
| 539 | +S: Maintained | |
| 540 | 540 | F: arch/x86/kernel/microcode_amd.c |
| 541 | 541 | |
| 542 | 542 | AMS (Apple Motion Sensor) DRIVER |
| @@ -637,6 +637,13 @@ W: http://www.arm.linux.org.uk/ · 94 unmodified lines | ||
| 637 | 637 | S: Maintained |
| 638 | 638 | F: arch/arm/ |
| 639 | 639 | |
| 640 | +ARM SUB-ARCHITECTURES | |
| 641 | +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | |
| 642 | +S: MAINTAINED | |
| 643 | +F: arch/arm/mach-*/ | |
| 644 | +F: arch/arm/plat-*/ | |
| 645 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc.git | |
| 646 | + | |
| 640 | 647 | ARM PRIMECELL AACI PL041 DRIVER |
| 641 | 648 | M: Russell King <linux@arm.linux.org.uk> |
| 642 | 649 | S: Maintained |
| @@ -834,6 +841,14 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kristoffer/linux-hpc.git · 191 unmodified lines | ||
| 834 | 841 | F: arch/arm/mach-sa1100/jornada720.c |
| 835 | 842 | F: arch/arm/mach-sa1100/include/mach/jornada720.h |
| 836 | 843 | |
| 844 | +ARM/IGEP MACHINE SUPPORT | |
| 845 | +M: Enric Balletbo i Serra <eballetbo@gmail.com> | |
| 846 | +M: Javier Martinez Canillas <javier@dowhile0.org> | |
| 847 | +L: linux-omap@vger.kernel.org | |
| 848 | +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | |
| 849 | +S: Maintained | |
| 850 | +F: arch/arm/mach-omap2/board-igep0020.c | |
| 851 | + | |
| 837 | 852 | ARM/INCOME PXA270 SUPPORT |
| 838 | 853 | M: Marek Vasut <marek.vasut@gmail.com> |
| 839 | 854 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| @@ -2500,6 +2515,7 @@ M: Joonyoung Shim <jy0922.shim@samsung.com> · 1660 unmodified lines | ||
| 2500 | 2515 | M: Seung-Woo Kim <sw0312.kim@samsung.com> |
| 2501 | 2516 | M: Kyungmin Park <kyungmin.park@samsung.com> |
| 2502 | 2517 | L: dri-devel@lists.freedesktop.org |
| 2518 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git | |
| 2503 | 2519 | S: Supported |
| 2504 | 2520 | F: drivers/gpu/drm/exynos |
| 2505 | 2521 | F: include/drm/exynos* |
| @@ -2700,10 +2716,10 @@ F: include/linux/edac.h · 194 unmodified lines | ||
| 2700 | 2716 | |
| 2701 | 2717 | EDAC-AMD64 |
| 2702 | 2718 | M: Doug Thompson <dougthompson@xmission.com> |
| 2703 | −M: Borislav Petkov <borislav.petkov@amd.com> | |
| 2719 | +M: Borislav Petkov <bp@alien8.de> | |
| 2704 | 2720 | L: linux-edac@vger.kernel.org |
| 2705 | 2721 | W: bluesmoke.sourceforge.net |
| 2706 | −S: Supported | |
| 2722 | +S: Maintained | |
| 2707 | 2723 | F: drivers/edac/amd64_edac* |
| 2708 | 2724 | |
| 2709 | 2725 | EDAC-E752X |
| @@ -2802,6 +2818,7 @@ F: sound/usb/misc/ua101.c · 92 unmodified lines | ||
| 2802 | 2818 | EXTENSIBLE FIRMWARE INTERFACE (EFI) |
| 2803 | 2819 | M: Matt Fleming <matt.fleming@intel.com> |
| 2804 | 2820 | L: linux-efi@vger.kernel.org |
| 2821 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git | |
| 2805 | 2822 | S: Maintained |
| 2806 | 2823 | F: Documentation/x86/efi-stub.txt |
| 2807 | 2824 | F: arch/ia64/kernel/efi.c |
| @@ -3589,6 +3606,49 @@ F: drivers/hid/hid-hyperv.c · 781 unmodified lines | ||
| 3589 | 3606 | F: drivers/net/hyperv/ |
| 3590 | 3607 | F: drivers/staging/hv/ |
| 3591 | 3608 | |
| 3609 | +I2C OVER PARALLEL PORT | |
| 3610 | +M: Jean Delvare <khali@linux-fr.org> | |
| 3611 | +L: linux-i2c@vger.kernel.org | |
| 3612 | +S: Maintained | |
| 3613 | +F: Documentation/i2c/busses/i2c-parport | |
| 3614 | +F: Documentation/i2c/busses/i2c-parport-light | |
| 3615 | +F: drivers/i2c/busses/i2c-parport.c | |
| 3616 | +F: drivers/i2c/busses/i2c-parport-light.c | |
| 3617 | + | |
| 3618 | +I2C/SMBUS CONTROLLER DRIVERS FOR PC | |
| 3619 | +M: Jean Delvare <khali@linux-fr.org> | |
| 3620 | +L: linux-i2c@vger.kernel.org | |
| 3621 | +S: Maintained | |
| 3622 | +F: Documentation/i2c/busses/i2c-ali1535 | |
| 3623 | +F: Documentation/i2c/busses/i2c-ali1563 | |
| 3624 | +F: Documentation/i2c/busses/i2c-ali15x3 | |
| 3625 | +F: Documentation/i2c/busses/i2c-amd756 | |
| 3626 | +F: Documentation/i2c/busses/i2c-amd8111 | |
| 3627 | +F: Documentation/i2c/busses/i2c-i801 | |
| 3628 | +F: Documentation/i2c/busses/i2c-nforce2 | |
| 3629 | +F: Documentation/i2c/busses/i2c-piix4 | |
| 3630 | +F: Documentation/i2c/busses/i2c-sis5595 | |
| 3631 | +F: Documentation/i2c/busses/i2c-sis630 | |
| 3632 | +F: Documentation/i2c/busses/i2c-sis96x | |
| 3633 | +F: Documentation/i2c/busses/i2c-via | |
| 3634 | +F: Documentation/i2c/busses/i2c-viapro | |
| 3635 | +F: drivers/i2c/busses/i2c-ali1535.c | |
| 3636 | +F: drivers/i2c/busses/i2c-ali1563.c | |
| 3637 | +F: drivers/i2c/busses/i2c-ali15x3.c | |
| 3638 | +F: drivers/i2c/busses/i2c-amd756.c | |
| 3639 | +F: drivers/i2c/busses/i2c-amd756-s4882.c | |
| 3640 | +F: drivers/i2c/busses/i2c-amd8111.c | |
| 3641 | +F: drivers/i2c/busses/i2c-i801.c | |
| 3642 | +F: drivers/i2c/busses/i2c-isch.c | |
| 3643 | +F: drivers/i2c/busses/i2c-nforce2.c | |
| 3644 | +F: drivers/i2c/busses/i2c-nforce2-s4985.c | |
| 3645 | +F: drivers/i2c/busses/i2c-piix4.c | |
| 3646 | +F: drivers/i2c/busses/i2c-sis5595.c | |
| 3647 | +F: drivers/i2c/busses/i2c-sis630.c | |
| 3648 | +F: drivers/i2c/busses/i2c-sis96x.c | |
| 3649 | +F: drivers/i2c/busses/i2c-via.c | |
| 3650 | +F: drivers/i2c/busses/i2c-viapro.c | |
| 3651 | + | |
| 3592 | 3652 | I2C/SMBUS STUB DRIVER |
| 3593 | 3653 | M: "Mark M. Hoffman" <mhoffman@lightlink.com> |
| 3594 | 3654 | L: linux-i2c@vger.kernel.org |
| @@ -3596,9 +3656,8 @@ S: Maintained · 1 unmodified line | ||
| 3596 | 3656 | F: drivers/i2c/busses/i2c-stub.c |
| 3597 | 3657 | |
| 3598 | 3658 | I2C SUBSYSTEM |
| 3599 | −M: "Jean Delvare (PC drivers, core)" <khali@linux-fr.org> | |
| 3659 | +M: Wolfram Sang <w.sang@pengutronix.de> | |
| 3600 | 3660 | M: "Ben Dooks (embedded platforms)" <ben-linux@fluff.org> |
| 3601 | −M: "Wolfram Sang (embedded platforms)" <w.sang@pengutronix.de> | |
| 3602 | 3661 | L: linux-i2c@vger.kernel.org |
| 3603 | 3662 | W: http://i2c.wiki.kernel.org/ |
| 3604 | 3663 | T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-i2c/ |
| @@ -3609,6 +3668,13 @@ F: drivers/i2c/ · 4 unmodified lines | ||
| 3609 | 3668 | F: include/linux/i2c.h |
| 3610 | 3669 | F: include/linux/i2c-*.h |
| 3611 | 3670 | |
| 3671 | +I2C-TAOS-EVM DRIVER | |
| 3672 | +M: Jean Delvare <khali@linux-fr.org> | |
| 3673 | +L: linux-i2c@vger.kernel.org | |
| 3674 | +S: Maintained | |
| 3675 | +F: Documentation/i2c/busses/i2c-taos-evm | |
| 3676 | +F: drivers/i2c/busses/i2c-taos-evm.c | |
| 3677 | + | |
| 3612 | 3678 | I2C-TINY-USB DRIVER |
| 3613 | 3679 | M: Till Harbaum <till@harbaum.org> |
| 3614 | 3680 | L: linux-i2c@vger.kernel.org |
| @@ -3695,7 +3761,7 @@ S: Maintained · 80 unmodified lines | ||
| 3695 | 3761 | F: drivers/platform/x86/ideapad-laptop.c |
| 3696 | 3762 | |
| 3697 | 3763 | IDE/ATAPI DRIVERS |
| 3698 | −M: Borislav Petkov <petkovbb@gmail.com> | |
| 3764 | +M: Borislav Petkov <bp@alien8.de> | |
| 3699 | 3765 | L: linux-ide@vger.kernel.org |
| 3700 | 3766 | S: Maintained |
| 3701 | 3767 | F: Documentation/cdrom/ide-cd |
| @@ -4222,8 +4288,8 @@ F: include/linux/lockd/ · 520 unmodified lines | ||
| 4222 | 4288 | F: include/linux/sunrpc/ |
| 4223 | 4289 | |
| 4224 | 4290 | KERNEL VIRTUAL MACHINE (KVM) |
| 4225 | −M: Avi Kivity <avi@redhat.com> | |
| 4226 | 4291 | M: Marcelo Tosatti <mtosatti@redhat.com> |
| 4292 | +M: Gleb Natapov <gleb@redhat.com> | |
| 4227 | 4293 | L: kvm@vger.kernel.org |
| 4228 | 4294 | W: http://kvm.qumranet.com |
| 4229 | 4295 | S: Supported |
| @@ -5061,7 +5127,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git · 831 unmodified lines | ||
| 5061 | 5127 | S: Odd Fixes |
| 5062 | 5128 | F: drivers/net/ |
| 5063 | 5129 | F: include/linux/if_* |
| 5064 | −F: include/linux/*device.h | |
| 5130 | +F: include/linux/netdevice.h | |
| 5131 | +F: include/linux/arcdevice.h | |
| 5132 | +F: include/linux/etherdevice.h | |
| 5133 | +F: include/linux/fcdevice.h | |
| 5134 | +F: include/linux/fddidevice.h | |
| 5135 | +F: include/linux/hippidevice.h | |
| 5136 | +F: include/linux/inetdevice.h | |
| 5065 | 5137 | |
| 5066 | 5138 | NETXEN (1/10) GbE SUPPORT |
| 5067 | 5139 | M: Sony Chacko <sony.chacko@qlogic.com> |
| @@ -5349,7 +5421,7 @@ S: Maintained · 281 unmodified lines | ||
| 5349 | 5421 | F: sound/drivers/opl4/ |
| 5350 | 5422 | |
| 5351 | 5423 | OPROFILE |
| 5352 | −M: Robert Richter <robert.richter@amd.com> | |
| 5424 | +M: Robert Richter <rric@kernel.org> | |
| 5353 | 5425 | L: oprofile-list@lists.sf.net |
| 5354 | 5426 | S: Maintained |
| 5355 | 5427 | F: arch/*/include/asm/oprofile*.h |
| @@ -5633,7 +5705,7 @@ S: Maintained · 277 unmodified lines | ||
| 5633 | 5705 | F: drivers/pinctrl/spear/ |
| 5634 | 5706 | |
| 5635 | 5707 | PKTCDVD DRIVER |
| 5636 | −M: Peter Osterlund <petero2@telia.com> | |
| 5708 | +M: Jiri Kosina <jkosina@suse.cz> | |
| 5637 | 5709 | S: Maintained |
| 5638 | 5710 | F: drivers/block/pktcdvd.c |
| 5639 | 5711 | F: include/linux/pktcdvd.h |
| @@ -7195,6 +7267,14 @@ L: linux-xtensa@linux-xtensa.org · 1555 unmodified lines | ||
| 7195 | 7267 | S: Maintained |
| 7196 | 7268 | F: arch/xtensa/ |
| 7197 | 7269 | |
| 7270 | +THERMAL | |
| 7271 | +M: Zhang Rui <rui.zhang@intel.com> | |
| 7272 | +L: linux-pm@vger.kernel.org | |
| 7273 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git | |
| 7274 | +S: Supported | |
| 7275 | +F: drivers/thermal/ | |
| 7276 | +F: include/linux/thermal.h | |
| 7277 | + | |
| 7198 | 7278 | THINKPAD ACPI EXTRAS DRIVER |
| 7199 | 7279 | M: Henrique de Moraes Holschuh <ibm-acpi@hmh.eng.br> |
| 7200 | 7280 | L: ibm-acpi-devel@lists.sourceforge.net |
| @@ -7872,13 +7952,6 @@ M: Roger Luethi <rl@hellgate.ch> · 671 unmodified lines | ||
| 7872 | 7952 | S: Maintained |
| 7873 | 7953 | F: drivers/net/ethernet/via/via-rhine.c |
| 7874 | 7954 | |
| 7875 | −VIAPRO SMBUS DRIVER | |
| 7876 | −M: Jean Delvare <khali@linux-fr.org> | |
| 7877 | −L: linux-i2c@vger.kernel.org | |
| 7878 | −S: Maintained | |
| 7879 | −F: Documentation/i2c/busses/i2c-viapro | |
| 7880 | −F: drivers/i2c/busses/i2c-viapro.c | |
| 7881 | − | |
| 7882 | 7955 | VIA SD/MMC CARD CONTROLLER DRIVER |
| 7883 | 7956 | M: Bruce Chang <brucechang@via.com.tw> |
| 7884 | 7957 | M: Harald Welte <HaraldWelte@viatech.com> |
| @@ -8133,7 +8206,7 @@ F: drivers/platform/x86 · 248 unmodified lines | ||
| 8133 | 8206 | |
| 8134 | 8207 | X86 MCE INFRASTRUCTURE |
| 8135 | 8208 | M: Tony Luck <tony.luck@intel.com> |
| 8136 | −M: Borislav Petkov <bp@amd64.org> | |
| 8209 | +M: Borislav Petkov <bp@alien8.de> | |
| 8137 | 8210 | L: linux-edac@vger.kernel.org |
| 8138 | 8211 | S: Maintained |
| 8139 | 8212 | F: arch/x86/kernel/cpu/mcheck/* |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | VERSION = 3 |
| 2 | 2 | PATCHLEVEL = 7 |
| 3 | 3 | SUBLEVEL = 0 |
| 4 | −EXTRAVERSION = -rc2 | |
| 4 | +EXTRAVERSION = -rc8 | |
| 5 | 5 | NAME = Terrified Chipmunk |
| 6 | 6 | |
| 7 | 7 | # *DOCUMENTATION* |
| @@ -445,7 +445,7 @@ struct procfs_args { · 444 unmodified lines | ||
| 445 | 445 | * unhappy with OSF UFS. [CHECKME] |
| 446 | 446 | */ |
| 447 | 447 | static int |
| 448 | −osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags) | |
| 448 | +osf_ufs_mount(const char *dirname, struct ufs_args __user *args, int flags) | |
| 449 | 449 | { |
| 450 | 450 | int retval; |
| 451 | 451 | struct cdfs_args tmp; |
| @@ -465,7 +465,7 @@ osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags) · 13 unmodified lines | ||
| 465 | 465 | } |
| 466 | 466 | |
| 467 | 467 | static int |
| 468 | −osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags) | |
| 468 | +osf_cdfs_mount(const char *dirname, struct cdfs_args __user *args, int flags) | |
| 469 | 469 | { |
| 470 | 470 | int retval; |
| 471 | 471 | struct cdfs_args tmp; |
| @@ -485,7 +485,7 @@ osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags) · 13 unmodified lines | ||
| 485 | 485 | } |
| 486 | 486 | |
| 487 | 487 | static int |
| 488 | −osf_procfs_mount(char *dirname, struct procfs_args __user *args, int flags) | |
| 488 | +osf_procfs_mount(const char *dirname, struct procfs_args __user *args, int flags) | |
| 489 | 489 | { |
| 490 | 490 | struct procfs_args tmp; |
| 491 | 491 | |
| @@ -547,6 +547,7 @@ config ARCH_KIRKWOOD · 546 unmodified lines | ||
| 547 | 547 | select CPU_FEROCEON |
| 548 | 548 | select GENERIC_CLOCKEVENTS |
| 549 | 549 | select PCI |
| 550 | + select PCI_QUIRKS | |
| 550 | 551 | select PLAT_ORION_LEGACY |
| 551 | 552 | help |
| 552 | 553 | Support for the following Marvell Kirkwood series SoCs: |
| @@ -1603,8 +1604,8 @@ config NR_CPUS · 1050 unmodified lines | ||
| 1603 | 1604 | default "4" |
| 1604 | 1605 | |
| 1605 | 1606 | config HOTPLUG_CPU |
| 1606 | − bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" | |
| 1607 | − depends on SMP && HOTPLUG && EXPERIMENTAL | |
| 1607 | + bool "Support for hot-pluggable CPUs" | |
| 1608 | + depends on SMP && HOTPLUG | |
| 1608 | 1609 | help |
| 1609 | 1610 | Say Y here to experiment with turning CPUs off and on. CPUs |
| 1610 | 1611 | can be controlled through /sys/devices/system/cpu. |
| @@ -1645,8 +1646,8 @@ config HZ · 34 unmodified lines | ||
| 1645 | 1646 | default 100 |
| 1646 | 1647 | |
| 1647 | 1648 | config THUMB2_KERNEL |
| 1648 | − bool "Compile the kernel in Thumb-2 mode (EXPERIMENTAL)" | |
| 1649 | − depends on CPU_V7 && !CPU_V6 && !CPU_V6K && EXPERIMENTAL | |
| 1649 | + bool "Compile the kernel in Thumb-2 mode" | |
| 1650 | + depends on CPU_V7 && !CPU_V6 && !CPU_V6K | |
| 1650 | 1651 | select AEABI |
| 1651 | 1652 | select ARM_ASM_UNIFIED |
| 1652 | 1653 | select ARM_UNWIND |
| @@ -1850,6 +1851,7 @@ config XEN_DOM0 · 197 unmodified lines | ||
| 1850 | 1851 | config XEN |
| 1851 | 1852 | bool "Xen guest support on ARM (EXPERIMENTAL)" |
| 1852 | 1853 | depends on EXPERIMENTAL && ARM && OF |
| 1854 | + depends on CPU_V7 && !CPU_V6 | |
| 1853 | 1855 | help |
| 1854 | 1856 | Say Y if you want to run Linux in a Virtual Machine on Xen on ARM. |
| 1855 | 1857 | |
| @@ -21,8 +21,6 @@ endif · 20 unmodified lines | ||
| 21 | 21 | OBJCOPYFLAGS :=-O binary -R .comment -S |
| 22 | 22 | GZFLAGS :=-9 |
| 23 | 23 | #KBUILD_CFLAGS +=-pipe |
| 24 | −# Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb: | |
| 25 | −KBUILD_CFLAGS +=$(call cc-option,-marm,) | |
| 26 | 24 | |
| 27 | 25 | # Never generate .eh_frame |
| 28 | 26 | KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm) |
| @@ -105,17 +103,20 @@ endif · 76 unmodified lines | ||
| 105 | 103 | ifeq ($(CONFIG_THUMB2_KERNEL),y) |
| 106 | 104 | AFLAGS_AUTOIT :=$(call as-option,-Wa$(comma)-mimplicit-it=always,-Wa$(comma)-mauto-it) |
| 107 | 105 | AFLAGS_NOWARN :=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W) |
| 108 | −CFLAGS_THUMB2 :=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN) | |
| 109 | −AFLAGS_THUMB2 :=$(CFLAGS_THUMB2) -Wa$(comma)-mthumb | |
| 106 | +CFLAGS_ISA :=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN) | |
| 107 | +AFLAGS_ISA :=$(CFLAGS_ISA) -Wa$(comma)-mthumb | |
| 110 | 108 | # Work around buggy relocation from gas if requested: |
| 111 | 109 | ifeq ($(CONFIG_THUMB2_AVOID_R_ARM_THM_JUMP11),y) |
| 112 | 110 | CFLAGS_MODULE +=-fno-optimize-sibling-calls |
| 113 | 111 | endif |
| 112 | +else | |
| 113 | +CFLAGS_ISA :=$(call cc-option,-marm,) | |
| 114 | +AFLAGS_ISA :=$(CFLAGS_ISA) | |
| 114 | 115 | endif |
| 115 | 116 | |
| 116 | 117 | # Need -Uarm for gcc < 3.x |
| 117 | −KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_THUMB2) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm | |
| 118 | −KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_THUMB2) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float | |
| 118 | +KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm | |
| 119 | +KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_ISA) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float | |
| 119 | 120 | |
| 120 | 121 | CHECKFLAGS += -D__arm__ |
| 121 | 122 | |
| @@ -33,7 +33,7 @@ ifeq ($(CONFIG_XIP_KERNEL),y) · 32 unmodified lines | ||
| 33 | 33 | |
| 34 | 34 | $(obj)/xipImage: vmlinux FORCE |
| 35 | 35 | $(call if_changed,objcopy) |
| 36 | − @echo ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))' | |
| 36 | + @$(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))' | |
| 37 | 37 | |
| 38 | 38 | $(obj)/Image $(obj)/zImage: FORCE |
| 39 | 39 | @echo 'Kernel configured for XIP (CONFIG_XIP_KERNEL=y)' |
| @@ -48,14 +48,14 @@ $(obj)/xipImage: FORCE · 8 unmodified lines | ||
| 48 | 48 | |
| 49 | 49 | $(obj)/Image: vmlinux FORCE |
| 50 | 50 | $(call if_changed,objcopy) |
| 51 | − @echo ' Kernel: $@ is ready' | |
| 51 | + @$(kecho) ' Kernel: $@ is ready' | |
| 52 | 52 | |
| 53 | 53 | $(obj)/compressed/vmlinux: $(obj)/Image FORCE |
| 54 | 54 | $(Q)$(MAKE) $(build)=$(obj)/compressed $@ |
| 55 | 55 | |
| 56 | 56 | $(obj)/zImage: $(obj)/compressed/vmlinux FORCE |
| 57 | 57 | $(call if_changed,objcopy) |
| 58 | − @echo ' Kernel: $@ is ready' | |
| 58 | + @$(kecho) ' Kernel: $@ is ready' | |
| 59 | 59 | |
| 60 | 60 | endif |
| 61 | 61 | |
| @@ -90,7 +90,7 @@ fi · 28 unmodified lines | ||
| 90 | 90 | $(obj)/uImage: $(obj)/zImage FORCE |
| 91 | 91 | @$(check_for_multiple_loadaddr) |
| 92 | 92 | $(call if_changed,uimage) |
| 93 | − @echo ' Image $@ is ready' | |
| 93 | + @$(kecho) ' Image $@ is ready' | |
| 94 | 94 | |
| 95 | 95 | $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE |
| 96 | 96 | $(Q)$(MAKE) $(build)=$(obj)/bootp $@ |
| @@ -98,7 +98,7 @@ $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE · 1 unmodified line | ||
| 98 | 98 | |
| 99 | 99 | $(obj)/bootpImage: $(obj)/bootp/bootp FORCE |
| 100 | 100 | $(call if_changed,objcopy) |
| 101 | − @echo ' Kernel: $@ is ready' | |
| 101 | + @$(kecho) ' Kernel: $@ is ready' | |
| 102 | 102 | |
| 103 | 103 | PHONY += initrd FORCE |
| 104 | 104 | initrd: |
| @@ -652,6 +652,15 @@ __setup_mmu: sub r3, r4, #16384 @ Page directory size · 651 unmodified lines | ||
| 652 | 652 | mov pc, lr |
| 653 | 653 | ENDPROC(__setup_mmu) |
| 654 | 654 | |
| 655 | +@ Enable unaligned access on v6, to allow better code generation | |
| 656 | +@ for the decompressor C code: | |
| 657 | +__armv6_mmu_cache_on: | |
| 658 | + mrc p15, 0, r0, c1, c0, 0 @ read SCTLR | |
| 659 | + bic r0, r0, #2 @ A (no unaligned access fault) | |
| 660 | + orr r0, r0, #1 << 22 @ U (v6 unaligned access model) | |
| 661 | + mcr p15, 0, r0, c1, c0, 0 @ write SCTLR | |
| 662 | + b __armv4_mmu_cache_on | |
| 663 | + | |
| 655 | 664 | __arm926ejs_mmu_cache_on: |
| 656 | 665 | #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH |
| 657 | 666 | mov r0, #4 @ put dcache in WT mode |
| @@ -694,6 +703,9 @@ __armv7_mmu_cache_on: · 36 unmodified lines | ||
| 694 | 703 | bic r0, r0, #1 << 28 @ clear SCTLR.TRE |
| 695 | 704 | orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement |
| 696 | 705 | orr r0, r0, #0x003c @ write buffer |
| 706 | + bic r0, r0, #2 @ A (no unaligned access fault) | |
| 707 | + orr r0, r0, #1 << 22 @ U (v6 unaligned access model) | |
| 708 | + @ (needed for ARM1176) | |
| 697 | 709 | #ifdef CONFIG_MMU |
| 698 | 710 | #ifdef CONFIG_CPU_ENDIAN_BE8 |
| 699 | 711 | orr r0, r0, #1 << 25 @ big-endian page tables |
| @@ -914,7 +926,7 @@ proc_types: · 214 unmodified lines | ||
| 914 | 926 | |
| 915 | 927 | .word 0x0007b000 @ ARMv6 |
| 916 | 928 | .word 0x000ff000 |
| 917 | − W(b) __armv4_mmu_cache_on | |
| 929 | + W(b) __armv6_mmu_cache_on | |
| 918 | 930 | W(b) __armv4_mmu_cache_off |
| 919 | 931 | W(b) __armv6_mmu_cache_flush |
| 920 | 932 | |
| @@ -126,14 +126,14 @@ · 125 unmodified lines | ||
| 126 | 126 | #size-cells = <0>; |
| 127 | 127 | |
| 128 | 128 | btn3 { |
| 129 | − label = "Buttin 3"; | |
| 129 | + label = "Button 3"; | |
| 130 | 130 | gpios = <&pioA 30 1>; |
| 131 | 131 | linux,code = <0x103>; |
| 132 | 132 | gpio-key,wakeup; |
| 133 | 133 | }; |
| 134 | 134 | |
| 135 | 135 | btn4 { |
| 136 | − label = "Buttin 4"; | |
| 136 | + label = "Button 4"; | |
| 137 | 137 | gpios = <&pioA 31 1>; |
| 138 | 138 | linux,code = <0x104>; |
| 139 | 139 | gpio-key,wakeup; |
| @@ -483,6 +483,8 @@ · 482 unmodified lines | ||
| 483 | 483 | compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell"; |
| 484 | 484 | reg = <0x80004000 0x1000>; |
| 485 | 485 | interrupts = <0 21 0x4>; |
| 486 | + arm,primecell-periphid = <0x180024>; | |
| 487 | + | |
| 486 | 488 | #address-cells = <1>; |
| 487 | 489 | #size-cells = <0>; |
| 488 | 490 | v-i2c-supply = <&db8500_vape_reg>; |
| @@ -494,6 +496,8 @@ · 5 unmodified lines | ||
| 494 | 496 | compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell"; |
| 495 | 497 | reg = <0x80122000 0x1000>; |
| 496 | 498 | interrupts = <0 22 0x4>; |
| 499 | + arm,primecell-periphid = <0x180024>; | |
| 500 | + | |
| 497 | 501 | #address-cells = <1>; |
| 498 | 502 | #size-cells = <0>; |
| 499 | 503 | v-i2c-supply = <&db8500_vape_reg>; |
| @@ -505,6 +509,8 @@ · 5 unmodified lines | ||
| 505 | 509 | compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell"; |
| 506 | 510 | reg = <0x80128000 0x1000>; |
| 507 | 511 | interrupts = <0 55 0x4>; |
| 512 | + arm,primecell-periphid = <0x180024>; | |
| 513 | + | |
| 508 | 514 | #address-cells = <1>; |
| 509 | 515 | #size-cells = <0>; |
| 510 | 516 | v-i2c-supply = <&db8500_vape_reg>; |
| @@ -516,6 +522,8 @@ · 5 unmodified lines | ||
| 516 | 522 | compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell"; |
| 517 | 523 | reg = <0x80110000 0x1000>; |
| 518 | 524 | interrupts = <0 12 0x4>; |
| 525 | + arm,primecell-periphid = <0x180024>; | |
| 526 | + | |
| 519 | 527 | #address-cells = <1>; |
| 520 | 528 | #size-cells = <0>; |
| 521 | 529 | v-i2c-supply = <&db8500_vape_reg>; |
| @@ -527,6 +535,8 @@ · 5 unmodified lines | ||
| 527 | 535 | compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell"; |
| 528 | 536 | reg = <0x8012a000 0x1000>; |
| 529 | 537 | interrupts = <0 51 0x4>; |
| 538 | + arm,primecell-periphid = <0x180024>; | |
| 539 | + | |
| 530 | 540 | #address-cells = <1>; |
| 531 | 541 | #size-cells = <0>; |
| 532 | 542 | v-i2c-supply = <&db8500_vape_reg>; |
| @@ -573,33 +583,38 @@ · 40 unmodified lines | ||
| 573 | 583 | interrupts = <0 60 0x4>; |
| 574 | 584 | status = "disabled"; |
| 575 | 585 | }; |
| 586 | + | |
| 576 | 587 | sdi@80118000 { |
| 577 | 588 | compatible = "arm,pl18x", "arm,primecell"; |
| 578 | 589 | reg = <0x80118000 0x1000>; |
| 579 | 590 | interrupts = <0 50 0x4>; |
| 580 | 591 | status = "disabled"; |
| 581 | 592 | }; |
| 593 | + | |
| 582 | 594 | sdi@80005000 { |
| 583 | 595 | compatible = "arm,pl18x", "arm,primecell"; |
| 584 | 596 | reg = <0x80005000 0x1000>; |
| 585 | 597 | interrupts = <0 41 0x4>; |
| 586 | 598 | status = "disabled"; |
| 587 | 599 | }; |
| 600 | + | |
| 588 | 601 | sdi@80119000 { |
| 589 | 602 | compatible = "arm,pl18x", "arm,primecell"; |
| 590 | 603 | reg = <0x80119000 0x1000>; |
| 591 | 604 | interrupts = <0 59 0x4>; |
| 592 | 605 | status = "disabled"; |
| 593 | 606 | }; |
| 607 | + | |
| 594 | 608 | sdi@80114000 { |
| 595 | 609 | compatible = "arm,pl18x", "arm,primecell"; |
| 596 | 610 | reg = <0x80114000 0x1000>; |
| 597 | 611 | interrupts = <0 99 0x4>; |
| 598 | 612 | status = "disabled"; |
| 599 | 613 | }; |
| 614 | + | |
| 600 | 615 | sdi@80008000 { |
| 601 | 616 | compatible = "arm,pl18x", "arm,primecell"; |
| 602 | − reg = <0x80114000 0x1000>; | |
| 617 | + reg = <0x80008000 0x1000>; | |
| 603 | 618 | interrupts = <0 100 0x4>; |
| 604 | 619 | status = "disabled"; |
| 605 | 620 | }; |
| @@ -20,8 +20,10 @@ · 19 unmodified lines | ||
| 20 | 20 | compatible = "samsung,trats", "samsung,exynos4210"; |
| 21 | 21 | |
| 22 | 22 | memory { |
| 23 | − reg = <0x40000000 0x20000000 | |
| 24 | − 0x60000000 0x20000000>; | |
| 23 | + reg = <0x40000000 0x10000000 | |
| 24 | + 0x50000000 0x10000000 | |
| 25 | + 0x60000000 0x10000000 | |
| 26 | + 0x70000000 0x10000000>; | |
| 25 | 27 | }; |
| 26 | 28 | |
| 27 | 29 | chosen { |
| @@ -69,6 +69,7 @@ · 68 unmodified lines | ||
| 69 | 69 | interrupts = <13>, <56>; |
| 70 | 70 | interrupt-names = "gpmi-dma", "bch"; |
| 71 | 71 | clocks = <&clks 34>; |
| 72 | + clock-names = "gpmi_io"; | |
| 72 | 73 | fsl,gpmi-dma-channel = <4>; |
| 73 | 74 | status = "disabled"; |
| 74 | 75 | }; |
| @@ -85,6 +85,7 @@ · 84 unmodified lines | ||
| 85 | 85 | interrupts = <88>, <41>; |
| 86 | 86 | interrupt-names = "gpmi-dma", "bch"; |
| 87 | 87 | clocks = <&clks 50>; |
| 88 | + clock-names = "gpmi_io"; | |
| 88 | 89 | fsl,gpmi-dma-channel = <4>; |
| 89 | 90 | status = "disabled"; |
| 90 | 91 | }; |
| @@ -257,7 +257,7 @@ · 256 unmodified lines | ||
| 257 | 257 | interrupt-names = "common", "tx", "rx", "sidetone"; |
| 258 | 258 | interrupt-parent = <&intc>; |
| 259 | 259 | ti,buffer-size = <1280>; |
| 260 | − ti,hwmods = "mcbsp2"; | |
| 260 | + ti,hwmods = "mcbsp2", "mcbsp2_sidetone"; | |
| 261 | 261 | }; |
| 262 | 262 | |
| 263 | 263 | mcbsp3: mcbsp@49024000 { |
| @@ -272,7 +272,7 @@ · 8 unmodified lines | ||
| 272 | 272 | interrupt-names = "common", "tx", "rx", "sidetone"; |
| 273 | 273 | interrupt-parent = <&intc>; |
| 274 | 274 | ti,buffer-size = <128>; |
| 275 | − ti,hwmods = "mcbsp3"; | |
| 275 | + ti,hwmods = "mcbsp3", "mcbsp3_sidetone"; | |
| 276 | 276 | }; |
| 277 | 277 | |
| 278 | 278 | mcbsp4: mcbsp@49026000 { |
| @@ -73,8 +73,8 @@ · 72 unmodified lines | ||
| 73 | 73 | |
| 74 | 74 | pinmux: pinmux { |
| 75 | 75 | compatible = "nvidia,tegra30-pinmux"; |
| 76 | − reg = <0x70000868 0xd0 /* Pad control registers */ | |
| 77 | − 0x70003000 0x3e0>; /* Mux registers */ | |
| 76 | + reg = <0x70000868 0xd4 /* Pad control registers */ | |
| 77 | + 0x70003000 0x3e4>; /* Mux registers */ | |
| 78 | 78 | }; |
| 79 | 79 | |
| 80 | 80 | serial@70006000 { |
| @@ -162,7 +162,6 @@ static struct clock_event_device sp804_clockevent = { · 161 unmodified lines | ||
| 162 | 162 | .set_mode = sp804_set_mode, |
| 163 | 163 | .set_next_event = sp804_set_next_event, |
| 164 | 164 | .rating = 300, |
| 165 | − .cpumask = cpu_all_mask, | |
| 166 | 165 | }; |
| 167 | 166 | |
| 168 | 167 | static struct irqaction sp804_timer_irq = { |
| @@ -185,6 +184,7 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq, · 16 unmodified lines | ||
| 185 | 184 | clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ); |
| 186 | 185 | evt->name = name; |
| 187 | 186 | evt->irq = irq; |
| 187 | + evt->cpumask = cpu_possible_mask; | |
| 188 | 188 | |
| 189 | 189 | setup_irq(irq, &sp804_timer_irq); |
| 190 | 190 | clockevents_config_and_register(evt, rate, 0xf, 0xffffffff); |
| @@ -139,6 +139,7 @@ CONFIG_I2C_IMX=y · 138 unmodified lines | ||
| 139 | 139 | CONFIG_SPI=y |
| 140 | 140 | CONFIG_SPI_IMX=y |
| 141 | 141 | CONFIG_GPIO_SYSFS=y |
| 142 | +CONFIG_GPIO_MC9S08DZ60=y | |
| 142 | 143 | # CONFIG_HWMON is not set |
| 143 | 144 | CONFIG_WATCHDOG=y |
| 144 | 145 | CONFIG_IMX2_WDT=y |
| @@ -155,6 +156,7 @@ CONFIG_SOC_CAMERA=y · 10 unmodified lines | ||
| 155 | 156 | CONFIG_SOC_CAMERA_OV2640=y |
| 156 | 157 | CONFIG_VIDEO_MX3=y |
| 157 | 158 | CONFIG_FB=y |
| 159 | +CONFIG_LCD_PLATFORM=y | |
| 158 | 160 | CONFIG_BACKLIGHT_LCD_SUPPORT=y |
| 159 | 161 | CONFIG_LCD_CLASS_DEVICE=y |
| 160 | 162 | CONFIG_LCD_L4F00242T03=y |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | CONFIG_EXPERIMENTAL=y |
| 2 | 2 | CONFIG_SYSVIPC=y |
| 3 | −CONFIG_NO_HZ=y | |
| 3 | +CONFIG_IRQ_DOMAIN_DEBUG=y | |
| 4 | 4 | CONFIG_HIGH_RES_TIMERS=y |
| 5 | 5 | CONFIG_LOG_BUF_SHIFT=14 |
| 6 | 6 | CONFIG_BLK_DEV_INITRD=y |
| @@ -9,10 +9,12 @@ CONFIG_SLAB=y · 2 unmodified lines | ||
| 9 | 9 | CONFIG_MODULES=y |
| 10 | 10 | CONFIG_MODULE_UNLOAD=y |
| 11 | 11 | CONFIG_ARCH_MVEBU=y |
| 12 | −CONFIG_MACH_ARMADA_370_XP=y | |
| 12 | +CONFIG_MACH_ARMADA_370=y | |
| 13 | +CONFIG_MACH_ARMADA_XP=y | |
| 14 | +# CONFIG_CACHE_L2X0 is not set | |
| 13 | 15 | CONFIG_AEABI=y |
| 14 | 16 | CONFIG_HIGHMEM=y |
| 15 | −CONFIG_USE_OF=y | |
| 17 | +# CONFIG_COMPACTION is not set | |
| 16 | 18 | CONFIG_ZBOOT_ROM_TEXT=0x0 |
| 17 | 19 | CONFIG_ZBOOT_ROM_BSS=0x0 |
| 18 | 20 | CONFIG_ARM_APPENDED_DTB=y |
| @@ -23,6 +25,8 @@ CONFIG_SERIAL_8250_CONSOLE=y · 4 unmodified lines | ||
| 23 | 25 | CONFIG_SERIAL_OF_PLATFORM=y |
| 24 | 26 | CONFIG_GPIOLIB=y |
| 25 | 27 | CONFIG_GPIO_SYSFS=y |
| 28 | +# CONFIG_USB_SUPPORT is not set | |
| 29 | +# CONFIG_IOMMU_SUPPORT is not set | |
| 26 | 30 | CONFIG_EXT2_FS=y |
| 27 | 31 | CONFIG_EXT3_FS=y |
| 28 | 32 | # CONFIG_EXT3_FS_XATTR is not set |
| @@ -1,3 +1,4 @@ | ||
| 1 | +CONFIG_ARCH_VERSATILE=y | |
| 1 | 2 | CONFIG_EXPERIMENTAL=y |
| 2 | 3 | # CONFIG_LOCALVERSION_AUTO is not set |
| 3 | 4 | CONFIG_SYSVIPC=y |
| @@ -8,7 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | #define flat_argvp_envp_on_stack() 1 |
| 9 | 9 | #define flat_old_ram_flag(flags) (flags) |
| 10 | 10 | #define flat_reloc_valid(reloc, size) ((reloc) <= (size)) |
| 11 | −#define flat_get_addr_from_rp(rp, relval, flags, persistent) get_unaligned(rp) | |
| 11 | +#define flat_get_addr_from_rp(rp, relval, flags, persistent) ((void)persistent,get_unaligned(rp)) | |
| 12 | 12 | #define flat_put_addr_at_rp(rp, val, relval) put_unaligned(val,rp) |
| 13 | 13 | #define flat_get_relocate_addr(rel) (rel) |
| 14 | 14 | #define flat_set_persistent(relval, p) 0 |
| @@ -64,7 +64,7 @@ extern void __raw_readsl(const void __iomem *addr, void *data, int longlen); · 63 unmodified lines | ||
| 64 | 64 | static inline void __raw_writew(u16 val, volatile void __iomem *addr) |
| 65 | 65 | { |
| 66 | 66 | asm volatile("strh %1, %0" |
| 67 | − : "+Qo" (*(volatile u16 __force *)addr) | |
| 67 | + : "+Q" (*(volatile u16 __force *)addr) | |
| 68 | 68 | : "r" (val)); |
| 69 | 69 | } |
| 70 | 70 | |
| @@ -72,7 +72,7 @@ static inline u16 __raw_readw(const volatile void __iomem *addr) · 1 unmodified line | ||
| 72 | 72 | { |
| 73 | 73 | u16 val; |
| 74 | 74 | asm volatile("ldrh %1, %0" |
| 75 | − : "+Qo" (*(volatile u16 __force *)addr), | |
| 75 | + : "+Q" (*(volatile u16 __force *)addr), | |
| 76 | 76 | "=r" (val)); |
| 77 | 77 | return val; |
| 78 | 78 | } |
| @@ -10,7 +10,5 @@ · 9 unmodified lines | ||
| 10 | 10 | |
| 11 | 11 | extern void sched_clock_postinit(void); |
| 12 | 12 | extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate); |
| 13 | −extern void setup_sched_clock_needs_suspend(u32 (*read)(void), int bits, | |
| 14 | − unsigned long rate); | |
| 15 | 13 | |
| 16 | 14 | #endif |
| @@ -200,8 +200,8 @@ extern int __put_user_8(void *, unsigned long long); · 199 unmodified lines | ||
| 200 | 200 | #define USER_DS KERNEL_DS |
| 201 | 201 | |
| 202 | 202 | #define segment_eq(a,b) (1) |
| 203 | −#define __addr_ok(addr) (1) | |
| 204 | −#define __range_ok(addr,size) (0) | |
| 203 | +#define __addr_ok(addr) ((void)(addr),1) | |
| 204 | +#define __range_ok(addr,size) ((void)(addr),0) | |
| 205 | 205 | #define get_fs() (KERNEL_DS) |
| 206 | 206 | |
| 207 | 207 | static inline void set_fs(mm_segment_t fs) |
| @@ -27,9 +27,9 @@ · 26 unmodified lines | ||
| 27 | 27 | #if __LINUX_ARM_ARCH__ <= 6 |
| 28 | 28 | ldr \tmp, =elf_hwcap @ may not have MVFR regs |
| 29 | 29 | ldr \tmp, [\tmp, #0] |
| 30 | − tst \tmp, #HWCAP_VFPv3D16 | |
| 31 | − ldceql p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} | |
| 32 | − addne \base, \base, #32*4 @ step over unused register space | |
| 30 | + tst \tmp, #HWCAP_VFPD32 | |
| 31 | + ldcnel p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} | |
| 32 | + addeq \base, \base, #32*4 @ step over unused register space | |
| 33 | 33 | #else |
| 34 | 34 | VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 |
| 35 | 35 | and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field |
| @@ -51,9 +51,9 @@ · 15 unmodified lines | ||
| 51 | 51 | #if __LINUX_ARM_ARCH__ <= 6 |
| 52 | 52 | ldr \tmp, =elf_hwcap @ may not have MVFR regs |
| 53 | 53 | ldr \tmp, [\tmp, #0] |
| 54 | − tst \tmp, #HWCAP_VFPv3D16 | |
| 55 | − stceql p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} | |
| 56 | − addne \base, \base, #32*4 @ step over unused register space | |
| 54 | + tst \tmp, #HWCAP_VFPD32 | |
| 55 | + stcnel p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} | |
| 56 | + addeq \base, \base, #32*4 @ step over unused register space | |
| 57 | 57 | #else |
| 58 | 58 | VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 |
| 59 | 59 | and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field |
| @@ -0,0 +1,27 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (c) 2011 Picochip Ltd., Jamie Iles | |
| 3 | + * | |
| 4 | + * This program is free software; you can redistribute it and/or modify | |
| 5 | + * it under the terms of the GNU General Public License version 2 as | |
| 6 | + * published by the Free Software Foundation. | |
| 7 | + * | |
| 8 | + * Derived from arch/arm/mach-davinci/include/mach/debug-macro.S to use 32-bit | |
| 9 | + * accesses to the 8250. | |
| 10 | + */ | |
| 11 | + | |
| 12 | +#include <linux/serial_reg.h> | |
| 13 | + | |
| 14 | + .macro senduart,rd,rx | |
| 15 | + str \rd, [\rx, #UART_TX << UART_SHIFT] | |
| 16 | + .endm | |
| 17 | + | |
| 18 | + .macro busyuart,rd,rx | |
| 19 | +1002: ldr \rd, [\rx, #UART_LSR << UART_SHIFT] | |
| 20 | + and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE | |
| 21 | + teq \rd, #UART_LSR_TEMT | UART_LSR_THRE | |
| 22 | + bne 1002b | |
| 23 | + .endm | |
| 24 | + | |
| 25 | + /* The UART's don't have any flow control IO's wired up. */ | |
| 26 | + .macro waituart,rd,rx | |
| 27 | + .endm | |
| @@ -5,10 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | * it under the terms of the GNU General Public License version 2 as |
| 6 | 6 | * published by the Free Software Foundation. |
| 7 | 7 | * |
| 8 | − * Derived from arch/arm/mach-davinci/include/mach/debug-macro.S to use 32-bit | |
| 9 | − * accesses to the 8250. | |
| 10 | 8 | */ |
| 11 | −#include <linux/serial_reg.h> | |
| 12 | 9 | |
| 13 | 10 | #define UART_SHIFT 2 |
| 14 | 11 | #define PICOXCELL_UART1_BASE 0x80230000 |
| @@ -19,17 +16,4 @@ · 4 unmodified lines | ||
| 19 | 16 | ldr \rp, =PICOXCELL_UART1_BASE |
| 20 | 17 | .endm |
| 21 | 18 | |
| 22 | − .macro senduart,rd,rx | |
| 23 | − str \rd, [\rx, #UART_TX << UART_SHIFT] | |
| 24 | − .endm | |
| 25 | − | |
| 26 | − .macro busyuart,rd,rx | |
| 27 | −1002: ldr \rd, [\rx, #UART_LSR << UART_SHIFT] | |
| 28 | − and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE | |
| 29 | − teq \rd, #UART_LSR_TEMT | UART_LSR_THRE | |
| 30 | − bne 1002b | |
| 31 | − .endm | |
| 32 | − | |
| 33 | − /* The UART's don't have any flow control IO's wired up. */ | |
| 34 | − .macro waituart,rd,rx | |
| 35 | − .endm | |
| 19 | +#include "8250_32.S" | |
| @@ -7,6 +7,9 @@ · 6 unmodified lines | ||
| 7 | 7 | * published by the Free Software Foundation. |
| 8 | 8 | */ |
| 9 | 9 | |
| 10 | +#define UART_SHIFT 2 | |
| 11 | +#define DEBUG_LL_UART_OFFSET 0x00002000 | |
| 12 | + | |
| 10 | 13 | .macro addruart, rp, rv, tmp |
| 11 | 14 | mov \rp, #DEBUG_LL_UART_OFFSET |
| 12 | 15 | orr \rp, \rp, #0x00c00000 |
| @@ -14,3 +17,5 @@ · 1 unmodified line | ||
| 14 | 17 | orr \rp, \rp, #0xff000000 @ physical base |
| 15 | 18 | .endm |
| 16 | 19 | |
| 20 | +#include "8250_32.S" | |
| 21 | + | |
| @@ -18,11 +18,12 @@ · 17 unmodified lines | ||
| 18 | 18 | #define HWCAP_THUMBEE (1 << 11) |
| 19 | 19 | #define HWCAP_NEON (1 << 12) |
| 20 | 20 | #define HWCAP_VFPv3 (1 << 13) |
| 21 | −#define HWCAP_VFPv3D16 (1 << 14) | |
| 21 | +#define HWCAP_VFPv3D16 (1 << 14) /* also set for VFPv4-D16 */ | |
| 22 | 22 | #define HWCAP_TLS (1 << 15) |
| 23 | 23 | #define HWCAP_VFPv4 (1 << 16) |
| 24 | 24 | #define HWCAP_IDIVA (1 << 17) |
| 25 | 25 | #define HWCAP_IDIVT (1 << 18) |
| 26 | +#define HWCAP_VFPD32 (1 << 19) /* set if VFP has 32 regs (not 16) */ | |
| 26 | 27 | #define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT) |
| 27 | 28 | |
| 28 | 29 | |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | #include <linux/list.h> |
| 35 | 35 | #include <linux/kallsyms.h> |
| 36 | 36 | #include <linux/proc_fs.h> |
| 37 | +#include <linux/export.h> | |
| 37 | 38 | |
| 38 | 39 | #include <asm/exception.h> |
| 39 | 40 | #include <asm/mach/arch.h> |
| @@ -109,6 +110,7 @@ void set_irq_flags(unsigned int irq, unsigned int iflags) · 69 unmodified lines | ||
| 109 | 110 | /* Order is clear bits in "clr" then set bits in "set" */ |
| 110 | 111 | irq_modify_status(irq, clr, set & ~clr); |
| 111 | 112 | } |
| 113 | +EXPORT_SYMBOL_GPL(set_irq_flags); | |
| 112 | 114 | |
| 113 | 115 | void __init init_IRQ(void) |
| 114 | 116 | { |
| @@ -366,7 +366,9 @@ void kprobe_arm_test_cases(void) · 365 unmodified lines | ||
| 366 | 366 | TEST_UNSUPPORTED(".word 0xe04f0392 @ umaal r0, pc, r2, r3") |
| 367 | 367 | TEST_UNSUPPORTED(".word 0xe0500090 @ undef") |
| 368 | 368 | TEST_UNSUPPORTED(".word 0xe05fff9f @ undef") |
| 369 | +#endif | |
| 369 | 370 | |
| 371 | +#if __LINUX_ARM_ARCH__ >= 7 | |
| 370 | 372 | TEST_RRR( "mls r0, r",1, VAL1,", r",2, VAL2,", r",3, VAL3,"") |
| 371 | 373 | TEST_RRR( "mlshi r7, r",8, VAL3,", r",9, VAL1,", r",10, VAL2,"") |
| 372 | 374 | TEST_RR( "mls lr, r",1, VAL2,", r",2, VAL3,", r13") |
| @@ -456,6 +458,8 @@ void kprobe_arm_test_cases(void) · 83 unmodified lines | ||
| 456 | 458 | TEST_UNSUPPORTED(".word 0xe1700090") /* Unallocated space */ |
| 457 | 459 | #if __LINUX_ARM_ARCH__ >= 6 |
| 458 | 460 | TEST_UNSUPPORTED("ldrex r2, [sp]") |
| 461 | +#endif | |
| 462 | +#if (__LINUX_ARM_ARCH__ >= 7) || defined(CONFIG_CPU_32v6K) | |
| 459 | 463 | TEST_UNSUPPORTED("strexd r0, r2, r3, [sp]") |
| 460 | 464 | TEST_UNSUPPORTED("ldrexd r2, r3, [sp]") |
| 461 | 465 | TEST_UNSUPPORTED("strexb r0, r2, [sp]") |
| @@ -45,10 +45,9 @@ int machine_kexec_prepare(struct kimage *image) · 44 unmodified lines | ||
| 45 | 45 | for (i = 0; i < image->nr_segments; i++) { |
| 46 | 46 | current_segment = &image->segment[i]; |
| 47 | 47 | |
| 48 | − err = memblock_is_region_memory(current_segment->mem, | |
| 49 | − current_segment->memsz); | |
| 50 | − if (err) | |
| 51 | − return - EINVAL; | |
| 48 | + if (!memblock_is_region_memory(current_segment->mem, | |
| 49 | + current_segment->memsz)) | |
| 50 | + return -EINVAL; | |
| 52 | 51 | |
| 53 | 52 | err = get_user(header, (__be32*)current_segment->buf); |
| 54 | 53 | if (err) |
| @@ -96,6 +96,10 @@ armpmu_event_set_period(struct perf_event *event, · 95 unmodified lines | ||
| 96 | 96 | s64 period = hwc->sample_period; |
| 97 | 97 | int ret = 0; |
| 98 | 98 | |
| 99 | + /* The period may have been changed by PERF_EVENT_IOC_PERIOD */ | |
| 100 | + if (unlikely(period != hwc->last_period)) | |
| 101 | + left = period - (hwc->last_period - left); | |
| 102 | + | |
| 99 | 103 | if (unlikely(left <= -period)) { |
| 100 | 104 | left = period; |
| 101 | 105 | local64_set(&hwc->period_left, left); |
| @@ -107,13 +107,6 @@ static void sched_clock_poll(unsigned long wrap_ticks) · 106 unmodified lines | ||
| 107 | 107 | update_sched_clock(); |
| 108 | 108 | } |
| 109 | 109 | |
| 110 | −void __init setup_sched_clock_needs_suspend(u32 (*read)(void), int bits, | |
| 111 | − unsigned long rate) | |
| 112 | −{ | |
| 113 | − setup_sched_clock(read, bits, rate); | |
| 114 | − cd.needs_suspend = true; | |
| 115 | −} | |
| 116 | − | |
| 117 | 110 | void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate) |
| 118 | 111 | { |
| 119 | 112 | unsigned long r, w; |
| @@ -189,18 +182,15 @@ void __init sched_clock_postinit(void) · 69 unmodified lines | ||
| 189 | 182 | static int sched_clock_suspend(void) |
| 190 | 183 | { |
| 191 | 184 | sched_clock_poll(sched_clock_timer.data); |
| 192 | − if (cd.needs_suspend) | |
| 193 | − cd.suspended = true; | |
| 185 | + cd.suspended = true; | |
| 194 | 186 | return 0; |
| 195 | 187 | } |
| 196 | 188 | |
| 197 | 189 | static void sched_clock_resume(void) |
| 198 | 190 | { |
| 199 | − if (cd.needs_suspend) { | |
| 200 | − cd.epoch_cyc = read_sched_clock(); | |
| 201 | − cd.epoch_cyc_copy = cd.epoch_cyc; | |
| 202 | − cd.suspended = false; | |
| 203 | − } | |
| 191 | + cd.epoch_cyc = read_sched_clock(); | |
| 192 | + cd.epoch_cyc_copy = cd.epoch_cyc; | |
| 193 | + cd.suspended = false; | |
| 204 | 194 | } |
| 205 | 195 | |
| 206 | 196 | static struct syscore_ops sched_clock_ops = { |
| @@ -294,18 +294,24 @@ static void percpu_timer_setup(void); · 293 unmodified lines | ||
| 294 | 294 | asmlinkage void __cpuinit secondary_start_kernel(void) |
| 295 | 295 | { |
| 296 | 296 | struct mm_struct *mm = &init_mm; |
| 297 | − unsigned int cpu = smp_processor_id(); | |
| 297 | + unsigned int cpu; | |
| 298 | + | |
| 299 | + /* | |
| 300 | + * The identity mapping is uncached (strongly ordered), so | |
| 301 | + * switch away from it before attempting any exclusive accesses. | |
| 302 | + */ | |
| 303 | + cpu_switch_mm(mm->pgd, mm); | |
| 304 | + enter_lazy_tlb(mm, current); | |
| 305 | + local_flush_tlb_all(); | |
| 298 | 306 | |
| 299 | 307 | /* |
| 300 | 308 | * All kernel threads share the same mm context; grab a |
| 301 | 309 | * reference and switch to it. |
| 302 | 310 | */ |
| 311 | + cpu = smp_processor_id(); | |
| 303 | 312 | atomic_inc(&mm->mm_count); |
| 304 | 313 | current->active_mm = mm; |
| 305 | 314 | cpumask_set_cpu(cpu, mm_cpumask(mm)); |
| 306 | − cpu_switch_mm(mm->pgd, mm); | |
| 307 | − enter_lazy_tlb(mm, current); | |
| 308 | − local_flush_tlb_all(); | |
| 309 | 315 | |
| 310 | 316 | printk("CPU%u: Booted secondary processor\n", cpu); |
| 311 | 317 | |
| @@ -42,10 +42,10 @@ static void twd_set_mode(enum clock_event_mode mode, · 41 unmodified lines | ||
| 42 | 42 | |
| 43 | 43 | switch (mode) { |
| 44 | 44 | case CLOCK_EVT_MODE_PERIODIC: |
| 45 | − /* timer load already set up */ | |
| 46 | 45 | ctrl = TWD_TIMER_CONTROL_ENABLE | TWD_TIMER_CONTROL_IT_ENABLE |
| 47 | 46 | | TWD_TIMER_CONTROL_PERIODIC; |
| 48 | − __raw_writel(twd_timer_rate / HZ, twd_base + TWD_TIMER_LOAD); | |
| 47 | + __raw_writel(DIV_ROUND_CLOSEST(twd_timer_rate, HZ), | |
| 48 | + twd_base + TWD_TIMER_LOAD); | |
| 49 | 49 | break; |
| 50 | 50 | case CLOCK_EVT_MODE_ONESHOT: |
| 51 | 51 | /* period set, and timer enabled in 'next_event' hook */ |
| @@ -45,6 +45,7 @@ int read_current_timer(unsigned long *timer_val) · 44 unmodified lines | ||
| 45 | 45 | *timer_val = delay_timer->read_current_timer(); |
| 46 | 46 | return 0; |
| 47 | 47 | } |
| 48 | +EXPORT_SYMBOL_GPL(read_current_timer); | |
| 48 | 49 | |
| 49 | 50 | static void __timer_delay(unsigned long cycles) |
| 50 | 51 | { |
| @@ -21,19 +21,13 @@ config SOC_AT91SAM9 · 20 unmodified lines | ||
| 21 | 21 | bool |
| 22 | 22 | select CPU_ARM926T |
| 23 | 23 | select GENERIC_CLOCKEVENTS |
| 24 | + select MULTI_IRQ_HANDLER | |
| 25 | + select SPARSE_IRQ | |
| 24 | 26 | |
| 25 | 27 | menu "Atmel AT91 System-on-Chip" |
| 26 | 28 | |
| 27 | 29 | comment "Atmel AT91 Processor" |
| 28 | 30 | |
| 29 | −config SOC_AT91SAM9 | |
| 30 | − bool | |
| 31 | − select AT91_SAM9_SMC | |
| 32 | − select AT91_SAM9_TIME | |
| 33 | − select CPU_ARM926T | |
| 34 | − select MULTI_IRQ_HANDLER | |
| 35 | − select SPARSE_IRQ | |
| 36 | − | |
| 37 | 31 | config SOC_AT91RM9200 |
| 38 | 32 | bool "AT91RM9200" |
| 39 | 33 | select CPU_ARM920T |
| @@ -187,7 +187,7 @@ static struct clk_lookup periph_clocks_lookups[] = { · 186 unmodified lines | ||
| 187 | 187 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), |
| 188 | 188 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), |
| 189 | 189 | CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), |
| 190 | − CLKDEV_CON_DEV_ID(NULL, "i2c-at91rm9200", &twi_clk), | |
| 190 | + CLKDEV_CON_DEV_ID(NULL, "i2c-at91rm9200.0", &twi_clk), | |
| 191 | 191 | /* fake hclk clock */ |
| 192 | 192 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), |
| 193 | 193 | CLKDEV_CON_ID("pioA", &pioA_clk), |
| @@ -68,7 +68,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) · 67 unmodified lines | ||
| 68 | 68 | |
| 69 | 69 | /* Enable overcurrent notification */ |
| 70 | 70 | for (i = 0; i < data->ports; i++) { |
| 71 | − if (data->overcurrent_pin[i]) | |
| 71 | + if (gpio_is_valid(data->overcurrent_pin[i])) | |
| 72 | 72 | at91_set_gpio_input(data->overcurrent_pin[i], 1); |
| 73 | 73 | } |
| 74 | 74 | |
| @@ -479,7 +479,7 @@ static struct i2c_gpio_platform_data pdata = { · 404 unmodified lines | ||
| 479 | 479 | |
| 480 | 480 | static struct platform_device at91rm9200_twi_device = { |
| 481 | 481 | .name = "i2c-gpio", |
| 482 | − .id = -1, | |
| 482 | + .id = 0, | |
| 483 | 483 | .dev.platform_data = &pdata, |
| 484 | 484 | }; |
| 485 | 485 | |
| @@ -512,7 +512,7 @@ static struct resource twi_resources[] = { · 26 unmodified lines | ||
| 512 | 512 | |
| 513 | 513 | static struct platform_device at91rm9200_twi_device = { |
| 514 | 514 | .name = "i2c-at91rm9200", |
| 515 | − .id = -1, | |
| 515 | + .id = 0, | |
| 516 | 516 | .resource = twi_resources, |
| 517 | 517 | .num_resources = ARRAY_SIZE(twi_resources), |
| 518 | 518 | }; |
| @@ -211,8 +211,8 @@ static struct clk_lookup periph_clocks_lookups[] = { · 210 unmodified lines | ||
| 211 | 211 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk), |
| 212 | 212 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk), |
| 213 | 213 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk), |
| 214 | − CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260", &twi_clk), | |
| 215 | − CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20", &twi_clk), | |
| 214 | + CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260.0", &twi_clk), | |
| 215 | + CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi_clk), | |
| 216 | 216 | /* more usart lookup table for DT entries */ |
| 217 | 217 | CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck), |
| 218 | 218 | CLKDEV_CON_DEV_ID("usart", "fffb0000.serial", &usart0_clk), |
| @@ -72,7 +72,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) · 71 unmodified lines | ||
| 72 | 72 | |
| 73 | 73 | /* Enable overcurrent notification */ |
| 74 | 74 | for (i = 0; i < data->ports; i++) { |
| 75 | − if (data->overcurrent_pin[i]) | |
| 75 | + if (gpio_is_valid(data->overcurrent_pin[i])) | |
| 76 | 76 | at91_set_gpio_input(data->overcurrent_pin[i], 1); |
| 77 | 77 | } |
| 78 | 78 | |
| @@ -389,7 +389,7 @@ static struct i2c_gpio_platform_data pdata = { · 310 unmodified lines | ||
| 389 | 389 | |
| 390 | 390 | static struct platform_device at91sam9260_twi_device = { |
| 391 | 391 | .name = "i2c-gpio", |
| 392 | − .id = -1, | |
| 392 | + .id = 0, | |
| 393 | 393 | .dev.platform_data = &pdata, |
| 394 | 394 | }; |
| 395 | 395 | |
| @@ -421,7 +421,7 @@ static struct resource twi_resources[] = { · 25 unmodified lines | ||
| 421 | 421 | }; |
| 422 | 422 | |
| 423 | 423 | static struct platform_device at91sam9260_twi_device = { |
| 424 | − .id = -1, | |
| 424 | + .id = 0, | |
| 425 | 425 | .resource = twi_resources, |
| 426 | 426 | .num_resources = ARRAY_SIZE(twi_resources), |
| 427 | 427 | }; |
| @@ -178,8 +178,8 @@ static struct clk_lookup periph_clocks_lookups[] = { · 177 unmodified lines | ||
| 178 | 178 | CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), |
| 179 | 179 | CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk), |
| 180 | 180 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &hck0), |
| 181 | − CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9261", &twi_clk), | |
| 182 | − CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10", &twi_clk), | |
| 181 | + CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9261.0", &twi_clk), | |
| 182 | + CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.0", &twi_clk), | |
| 183 | 183 | CLKDEV_CON_ID("pioA", &pioA_clk), |
| 184 | 184 | CLKDEV_CON_ID("pioB", &pioB_clk), |
| 185 | 185 | CLKDEV_CON_ID("pioC", &pioC_clk), |
| @@ -72,7 +72,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) · 71 unmodified lines | ||
| 72 | 72 | |
| 73 | 73 | /* Enable overcurrent notification */ |
| 74 | 74 | for (i = 0; i < data->ports; i++) { |
| 75 | − if (data->overcurrent_pin[i]) | |
| 75 | + if (gpio_is_valid(data->overcurrent_pin[i])) | |
| 76 | 76 | at91_set_gpio_input(data->overcurrent_pin[i], 1); |
| 77 | 77 | } |
| 78 | 78 | |
| @@ -285,7 +285,7 @@ static struct i2c_gpio_platform_data pdata = { · 206 unmodified lines | ||
| 285 | 285 | |
| 286 | 286 | static struct platform_device at91sam9261_twi_device = { |
| 287 | 287 | .name = "i2c-gpio", |
| 288 | − .id = -1, | |
| 288 | + .id = 0, | |
| 289 | 289 | .dev.platform_data = &pdata, |
| 290 | 290 | }; |
| 291 | 291 | |
| @@ -317,7 +317,7 @@ static struct resource twi_resources[] = { · 25 unmodified lines | ||
| 317 | 317 | }; |
| 318 | 318 | |
| 319 | 319 | static struct platform_device at91sam9261_twi_device = { |
| 320 | − .id = -1, | |
| 320 | + .id = 0, | |
| 321 | 321 | .resource = twi_resources, |
| 322 | 322 | .num_resources = ARRAY_SIZE(twi_resources), |
| 323 | 323 | }; |
| @@ -193,7 +193,7 @@ static struct clk_lookup periph_clocks_lookups[] = { · 192 unmodified lines | ||
| 193 | 193 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), |
| 194 | 194 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), |
| 195 | 195 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk), |
| 196 | − CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260", &twi_clk), | |
| 196 | + CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260.0", &twi_clk), | |
| 197 | 197 | /* fake hclk clock */ |
| 198 | 198 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), |
| 199 | 199 | CLKDEV_CON_ID("pioA", &pioA_clk), |
| @@ -78,7 +78,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) · 77 unmodified lines | ||
| 78 | 78 | |
| 79 | 79 | /* Enable overcurrent notification */ |
| 80 | 80 | for (i = 0; i < data->ports; i++) { |
| 81 | − if (data->overcurrent_pin[i]) | |
| 81 | + if (gpio_is_valid(data->overcurrent_pin[i])) | |
| 82 | 82 | at91_set_gpio_input(data->overcurrent_pin[i], 1); |
| 83 | 83 | } |
| 84 | 84 | |
| @@ -567,7 +567,7 @@ static struct i2c_gpio_platform_data pdata = { · 482 unmodified lines | ||
| 567 | 567 | |
| 568 | 568 | static struct platform_device at91sam9263_twi_device = { |
| 569 | 569 | .name = "i2c-gpio", |
| 570 | − .id = -1, | |
| 570 | + .id = 0, | |
| 571 | 571 | .dev.platform_data = &pdata, |
| 572 | 572 | }; |
| 573 | 573 | |
| @@ -600,7 +600,7 @@ static struct resource twi_resources[] = { · 26 unmodified lines | ||
| 600 | 600 | |
| 601 | 601 | static struct platform_device at91sam9263_twi_device = { |
| 602 | 602 | .name = "i2c-at91sam9260", |
| 603 | − .id = -1, | |
| 603 | + .id = 0, | |
| 604 | 604 | .resource = twi_resources, |
| 605 | 605 | .num_resources = ARRAY_SIZE(twi_resources), |
| 606 | 606 | }; |
| @@ -1841,8 +1841,8 @@ static struct resource sha_resources[] = { · 1840 unmodified lines | ||
| 1841 | 1841 | .flags = IORESOURCE_MEM, |
| 1842 | 1842 | }, |
| 1843 | 1843 | [1] = { |
| 1844 | − .start = AT91SAM9G45_ID_AESTDESSHA, | |
| 1845 | − .end = AT91SAM9G45_ID_AESTDESSHA, | |
| 1844 | + .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, | |
| 1845 | + .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, | |
| 1846 | 1846 | .flags = IORESOURCE_IRQ, |
| 1847 | 1847 | }, |
| 1848 | 1848 | }; |
| @@ -1874,8 +1874,8 @@ static struct resource tdes_resources[] = { · 25 unmodified lines | ||
| 1874 | 1874 | .flags = IORESOURCE_MEM, |
| 1875 | 1875 | }, |
| 1876 | 1876 | [1] = { |
| 1877 | − .start = AT91SAM9G45_ID_AESTDESSHA, | |
| 1878 | − .end = AT91SAM9G45_ID_AESTDESSHA, | |
| 1877 | + .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, | |
| 1878 | + .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, | |
| 1879 | 1879 | .flags = IORESOURCE_IRQ, |
| 1880 | 1880 | }, |
| 1881 | 1881 | }; |
| @@ -1910,8 +1910,8 @@ static struct resource aes_resources[] = { · 28 unmodified lines | ||
| 1910 | 1910 | .flags = IORESOURCE_MEM, |
| 1911 | 1911 | }, |
| 1912 | 1912 | [1] = { |
| 1913 | − .start = AT91SAM9G45_ID_AESTDESSHA, | |
| 1914 | − .end = AT91SAM9G45_ID_AESTDESSHA, | |
| 1913 | + .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, | |
| 1914 | + .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, | |
| 1915 | 1915 | .flags = IORESOURCE_IRQ, |
| 1916 | 1916 | }, |
| 1917 | 1917 | }; |
| @@ -314,7 +314,7 @@ static struct i2c_gpio_platform_data pdata = { · 313 unmodified lines | ||
| 314 | 314 | |
| 315 | 315 | static struct platform_device at91sam9rl_twi_device = { |
| 316 | 316 | .name = "i2c-gpio", |
| 317 | − .id = -1, | |
| 317 | + .id = 0, | |
| 318 | 318 | .dev.platform_data = &pdata, |
| 319 | 319 | }; |
| 320 | 320 | |
| @@ -347,7 +347,7 @@ static struct resource twi_resources[] = { · 26 unmodified lines | ||
| 347 | 347 | |
| 348 | 348 | static struct platform_device at91sam9rl_twi_device = { |
| 349 | 349 | .name = "i2c-at91sam9g20", |
| 350 | − .id = -1, | |
| 350 | + .id = 0, | |
| 351 | 351 | .resource = twi_resources, |
| 352 | 352 | .num_resources = ARRAY_SIZE(twi_resources), |
| 353 | 353 | }; |
| @@ -88,6 +88,6 @@ void __init at91x40_init_interrupts(unsigned int priority[NR_AIC_IRQS]) · 87 unmodified lines | ||
| 88 | 88 | if (!priority) |
| 89 | 89 | priority = at91x40_default_irq_priority; |
| 90 | 90 | |
| 91 | − at91_aic_init(priority); | |
| 91 | + at91_aic_init(priority, at91_extern_irq); | |
| 92 | 92 | } |
| 93 | 93 | |
| @@ -129,7 +129,7 @@ static struct spi_board_info neocore926_spi_devices[] = { · 128 unmodified lines | ||
| 129 | 129 | .max_speed_hz = 125000 * 16, |
| 130 | 130 | .bus_num = 0, |
| 131 | 131 | .platform_data = &ads_info, |
| 132 | − .irq = AT91SAM9263_ID_IRQ1, | |
| 132 | + .irq = NR_IRQS_LEGACY + AT91SAM9263_ID_IRQ1, | |
| 133 | 133 | }, |
| 134 | 134 | #endif |
| 135 | 135 | }; |
| @@ -309,7 +309,7 @@ static struct spi_board_info ek_spi_devices[] = { · 308 unmodified lines | ||
| 309 | 309 | .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */ |
| 310 | 310 | .bus_num = 0, |
| 311 | 311 | .platform_data = &ads_info, |
| 312 | − .irq = AT91SAM9261_ID_IRQ0, | |
| 312 | + .irq = NR_IRQS_LEGACY + AT91SAM9261_ID_IRQ0, | |
| 313 | 313 | .controller_data = (void *) AT91_PIN_PA28, /* CS pin */ |
| 314 | 314 | }, |
| 315 | 315 | #endif |
| @@ -132,7 +132,7 @@ static struct spi_board_info ek_spi_devices[] = { · 131 unmodified lines | ||
| 132 | 132 | .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */ |
| 133 | 133 | .bus_num = 0, |
| 134 | 134 | .platform_data = &ads_info, |
| 135 | − .irq = AT91SAM9263_ID_IRQ1, | |
| 135 | + .irq = NR_IRQS_LEGACY + AT91SAM9263_ID_IRQ1, | |
| 136 | 136 | }, |
| 137 | 137 | #endif |
| 138 | 138 | }; |
| @@ -26,7 +26,8 @@ extern void __init at91_dt_initialize(void); · 25 unmodified lines | ||
| 26 | 26 | extern void __init at91_init_irq_default(void); |
| 27 | 27 | extern void __init at91_init_interrupts(unsigned int priority[]); |
| 28 | 28 | extern void __init at91x40_init_interrupts(unsigned int priority[]); |
| 29 | −extern void __init at91_aic_init(unsigned int priority[]); | |
| 29 | +extern void __init at91_aic_init(unsigned int priority[], | |
| 30 | + unsigned int ext_irq_mask); | |
| 30 | 31 | extern int __init at91_aic_of_init(struct device_node *node, |
| 31 | 32 | struct device_node *parent); |
| 32 | 33 | extern int __init at91_aic5_of_init(struct device_node *node, |
| @@ -502,14 +502,19 @@ int __init at91_aic5_of_init(struct device_node *node, · 501 unmodified lines | ||
| 502 | 502 | /* |
| 503 | 503 | * Initialize the AIC interrupt controller. |
| 504 | 504 | */ |
| 505 | −void __init at91_aic_init(unsigned int *priority) | |
| 505 | +void __init at91_aic_init(unsigned int *priority, unsigned int ext_irq_mask) | |
| 506 | 506 | { |
| 507 | 507 | unsigned int i; |
| 508 | 508 | int irq_base; |
| 509 | 509 | |
| 510 | − if (at91_aic_pm_init()) | |
| 510 | + at91_extern_irq = kzalloc(BITS_TO_LONGS(n_irqs) | |
| 511 | + * sizeof(*at91_extern_irq), GFP_KERNEL); | |
| 512 | + | |
| 513 | + if (at91_aic_pm_init() || at91_extern_irq == NULL) | |
| 511 | 514 | panic("Unable to allocate bit maps\n"); |
| 512 | 515 | |
| 516 | + *at91_extern_irq = ext_irq_mask; | |
| 517 | + | |
| 513 | 518 | at91_aic_base = ioremap(AT91_AIC, 512); |
| 514 | 519 | if (!at91_aic_base) |
| 515 | 520 | panic("Unable to ioremap AIC registers\n"); |
| @@ -47,7 +47,7 @@ void __init at91_init_irq_default(void) · 46 unmodified lines | ||
| 47 | 47 | void __init at91_init_interrupts(unsigned int *priority) |
| 48 | 48 | { |
| 49 | 49 | /* Initialize the AIC interrupt controller */ |
| 50 | − at91_aic_init(priority); | |
| 50 | + at91_aic_init(priority, at91_extern_irq); | |
| 51 | 51 | |
| 52 | 52 | /* Enable GPIO interrupts */ |
| 53 | 53 | at91_gpio_irq_setup(); |
| @@ -151,7 +151,7 @@ static void __init soc_detect(u32 dbgu_base) · 97 unmodified lines | ||
| 151 | 151 | } |
| 152 | 152 | |
| 153 | 153 | /* at91sam9g10 */ |
| 154 | − if ((cidr & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) { | |
| 154 | + if ((socid & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) { | |
| 155 | 155 | at91_soc_initdata.type = AT91_SOC_SAM9G10; |
| 156 | 156 | at91_boot_soc = at91sam9261_soc; |
| 157 | 157 | } |
| @@ -713,8 +713,7 @@ static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type, · 712 unmodified lines | ||
| 713 | 713 | break; |
| 714 | 714 | case VPBE_ENC_CUSTOM_TIMINGS: |
| 715 | 715 | if (pclock <= 27000000) { |
| 716 | − v |= DM644X_VPSS_MUXSEL_PLL2_MODE | | |
| 717 | − DM644X_VPSS_DACCLKEN; | |
| 716 | + v |= DM644X_VPSS_DACCLKEN; | |
| 718 | 717 | writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL)); |
| 719 | 718 | } else { |
| 720 | 719 | /* |
| @@ -63,7 +63,7 @@ static inline int pmu_to_irq(int pin) · 62 unmodified lines | ||
| 63 | 63 | |
| 64 | 64 | static inline int irq_to_pmu(int irq) |
| 65 | 65 | { |
| 66 | − if (IRQ_DOVE_PMU_START < irq && irq < NR_IRQS) | |
| 66 | + if (IRQ_DOVE_PMU_START <= irq && irq < NR_IRQS) | |
| 67 | 67 | return irq - IRQ_DOVE_PMU_START; |
| 68 | 68 | |
| 69 | 69 | return -EINVAL; |
| @@ -46,8 +46,20 @@ static void pmu_irq_ack(struct irq_data *d) · 45 unmodified lines | ||
| 46 | 46 | int pin = irq_to_pmu(d->irq); |
| 47 | 47 | u32 u; |
| 48 | 48 | |
| 49 | + /* | |
| 50 | + * The PMU mask register is not RW0C: it is RW. This means that | |
| 51 | + * the bits take whatever value is written to them; if you write | |
| 52 | + * a '1', you will set the interrupt. | |
| 53 | + * | |
| 54 | + * Unfortunately this means there is NO race free way to clear | |
| 55 | + * these interrupts. | |
| 56 | + * | |
| 57 | + * So, let's structure the code so that the window is as small as | |
| 58 | + * possible. | |
| 59 | + */ | |
| 49 | 60 | u = ~(1 << (pin & 31)); |
| 50 | − writel(u, PMU_INTERRUPT_CAUSE); | |
| 61 | + u &= readl_relaxed(PMU_INTERRUPT_CAUSE); | |
| 62 | + writel_relaxed(u, PMU_INTERRUPT_CAUSE); | |
| 51 | 63 | } |
| 52 | 64 | |
| 53 | 65 | static struct irq_chip pmu_irq_chip = { |
| @@ -47,6 +47,7 @@ · 46 unmodified lines | ||
| 47 | 47 | #include <plat/fimc-core.h> |
| 48 | 48 | #include <plat/iic-core.h> |
| 49 | 49 | #include <plat/tv-core.h> |
| 50 | +#include <plat/spi-core.h> | |
| 50 | 51 | #include <plat/regs-serial.h> |
| 51 | 52 | |
| 52 | 53 | #include "common.h" |
| @@ -346,6 +347,8 @@ static void __init exynos4_map_io(void) · 293 unmodified lines | ||
| 346 | 347 | |
| 347 | 348 | s5p_fb_setname(0, "exynos4-fb"); |
| 348 | 349 | s5p_hdmi_setname("exynos4-hdmi"); |
| 350 | + | |
| 351 | + s3c64xx_spi_setname("exynos4210-spi"); | |
| 349 | 352 | } |
| 350 | 353 | |
| 351 | 354 | static void __init exynos5_map_io(void) |
| @@ -366,6 +369,8 @@ static void __init exynos5_map_io(void) · 14 unmodified lines | ||
| 366 | 369 | s3c_i2c0_setname("s3c2440-i2c"); |
| 367 | 370 | s3c_i2c1_setname("s3c2440-i2c"); |
| 368 | 371 | s3c_i2c2_setname("s3c2440-i2c"); |
| 372 | + | |
| 373 | + s3c64xx_spi_setname("exynos4210-spi"); | |
| 369 | 374 | } |
| 370 | 375 | |
| 371 | 376 | static void __init exynos4_init_clocks(int xtal) |
| @@ -275,6 +275,9 @@ static int __init exynos_dma_init(void) · 274 unmodified lines | ||
| 275 | 275 | exynos_pdma1_pdata.nr_valid_peri = |
| 276 | 276 | ARRAY_SIZE(exynos4210_pdma1_peri); |
| 277 | 277 | exynos_pdma1_pdata.peri_id = exynos4210_pdma1_peri; |
| 278 | + | |
| 279 | + if (samsung_rev() == EXYNOS4210_REV_0) | |
| 280 | + exynos_mdma1_device.res.start = EXYNOS4_PA_S_MDMA1; | |
| 278 | 281 | } else if (soc_is_exynos4212() || soc_is_exynos4412()) { |
| 279 | 282 | exynos_pdma0_pdata.nr_valid_peri = |
| 280 | 283 | ARRAY_SIZE(exynos4212_pdma0_peri); |
| @@ -90,6 +90,7 @@ · 89 unmodified lines | ||
| 90 | 90 | |
| 91 | 91 | #define EXYNOS4_PA_MDMA0 0x10810000 |
| 92 | 92 | #define EXYNOS4_PA_MDMA1 0x12850000 |
| 93 | +#define EXYNOS4_PA_S_MDMA1 0x12840000 | |
| 93 | 94 | #define EXYNOS4_PA_PDMA0 0x12680000 |
| 94 | 95 | #define EXYNOS4_PA_PDMA1 0x12690000 |
| 95 | 96 | #define EXYNOS5_PA_MDMA0 0x10800000 |
| @@ -99,6 +99,7 @@ static char const *exynos4_dt_compat[] __initdata = { · 98 unmodified lines | ||
| 99 | 99 | |
| 100 | 100 | DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)") |
| 101 | 101 | /* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */ |
| 102 | + .smp = smp_ops(exynos_smp_ops), | |
| 102 | 103 | .init_irq = exynos4_init_irq, |
| 103 | 104 | .map_io = exynos4_dt_map_io, |
| 104 | 105 | .handle_irq = gic_handle_irq, |
| @@ -28,6 +28,7 @@ void highbank_restart(char mode, const char *cmd) · 27 unmodified lines | ||
| 28 | 28 | hignbank_set_pwr_soft_reset(); |
| 29 | 29 | |
| 30 | 30 | scu_power_mode(scu_base_addr, SCU_PM_POWEROFF); |
| 31 | − cpu_do_idle(); | |
| 31 | + while (1) | |
| 32 | + cpu_do_idle(); | |
| 32 | 33 | } |
| 33 | 34 | |
| @@ -108,7 +108,7 @@ struct clk *imx_clk_busy_divider(const char *name, const char *parent_name, · 107 unmodified lines | ||
| 108 | 108 | busy->div.hw.init = &init; |
| 109 | 109 | |
| 110 | 110 | clk = clk_register(NULL, &busy->div.hw); |
| 111 | − if (!clk) | |
| 111 | + if (IS_ERR(clk)) | |
| 112 | 112 | kfree(busy); |
| 113 | 113 | |
| 114 | 114 | return clk; |
| @@ -112,7 +112,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name, · 111 unmodified lines | ||
| 112 | 112 | |
| 113 | 113 | clk = clk_register(dev, &gate->hw); |
| 114 | 114 | if (IS_ERR(clk)) |
| 115 | − kfree(clk); | |
| 115 | + kfree(gate); | |
| 116 | 116 | |
| 117 | 117 | return clk; |
| 118 | 118 | } |
| @@ -127,8 +127,8 @@ int __init mx25_clocks_init(void) · 126 unmodified lines | ||
| 127 | 127 | clk[esdhc2_ipg_per] = imx_clk_gate("esdhc2_ipg_per", "per4", ccm(CCM_CGCR0), 4); |
| 128 | 128 | clk[gpt_ipg_per] = imx_clk_gate("gpt_ipg_per", "per5", ccm(CCM_CGCR0), 5); |
| 129 | 129 | clk[i2c_ipg_per] = imx_clk_gate("i2c_ipg_per", "per6", ccm(CCM_CGCR0), 6); |
| 130 | − clk[lcdc_ipg_per] = imx_clk_gate("lcdc_ipg_per", "per8", ccm(CCM_CGCR0), 7); | |
| 131 | − clk[nfc_ipg_per] = imx_clk_gate("nfc_ipg_per", "ipg_per", ccm(CCM_CGCR0), 8); | |
| 130 | + clk[lcdc_ipg_per] = imx_clk_gate("lcdc_ipg_per", "per7", ccm(CCM_CGCR0), 7); | |
| 131 | + clk[nfc_ipg_per] = imx_clk_gate("nfc_ipg_per", "per8", ccm(CCM_CGCR0), 8); | |
| 132 | 132 | clk[ssi1_ipg_per] = imx_clk_gate("ssi1_ipg_per", "per13", ccm(CCM_CGCR0), 13); |
| 133 | 133 | clk[ssi2_ipg_per] = imx_clk_gate("ssi2_ipg_per", "per14", ccm(CCM_CGCR0), 14); |
| 134 | 134 | clk[uart_ipg_per] = imx_clk_gate("uart_ipg_per", "per15", ccm(CCM_CGCR0), 15); |
| @@ -109,7 +109,7 @@ int __init mx27_clocks_init(unsigned long fref) · 108 unmodified lines | ||
| 109 | 109 | clk[per3_div] = imx_clk_divider("per3_div", "mpll_main2", CCM_PCDR1, 16, 6); |
| 110 | 110 | clk[per4_div] = imx_clk_divider("per4_div", "mpll_main2", CCM_PCDR1, 24, 6); |
| 111 | 111 | clk[vpu_sel] = imx_clk_mux("vpu_sel", CCM_CSCR, 21, 1, vpu_sel_clks, ARRAY_SIZE(vpu_sel_clks)); |
| 112 | − clk[vpu_div] = imx_clk_divider("vpu_div", "vpu_sel", CCM_PCDR0, 10, 3); | |
| 112 | + clk[vpu_div] = imx_clk_divider("vpu_div", "vpu_sel", CCM_PCDR0, 10, 6); | |
| 113 | 113 | clk[usb_div] = imx_clk_divider("usb_div", "spll", CCM_CSCR, 28, 3); |
| 114 | 114 | clk[cpu_sel] = imx_clk_mux("cpu_sel", CCM_CSCR, 15, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks)); |
| 115 | 115 | clk[clko_sel] = imx_clk_mux("clko_sel", CCM_CCSR, 0, 5, clko_sel_clks, ARRAY_SIZE(clko_sel_clks)); |
| @@ -121,7 +121,7 @@ int __init mx27_clocks_init(unsigned long fref) · 5 unmodified lines | ||
| 121 | 121 | clk[ssi1_sel] = imx_clk_mux("ssi1_sel", CCM_CSCR, 22, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks)); |
| 122 | 122 | clk[ssi2_sel] = imx_clk_mux("ssi2_sel", CCM_CSCR, 23, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks)); |
| 123 | 123 | clk[ssi1_div] = imx_clk_divider("ssi1_div", "ssi1_sel", CCM_PCDR0, 16, 6); |
| 124 | − clk[ssi2_div] = imx_clk_divider("ssi2_div", "ssi2_sel", CCM_PCDR0, 26, 3); | |
| 124 | + clk[ssi2_div] = imx_clk_divider("ssi2_div", "ssi2_sel", CCM_PCDR0, 26, 6); | |
| 125 | 125 | clk[clko_en] = imx_clk_gate("clko_en", "clko_div", CCM_PCCR0, 0); |
| 126 | 126 | clk[ssi2_ipg_gate] = imx_clk_gate("ssi2_ipg_gate", "ipg", CCM_PCCR0, 0); |
| 127 | 127 | clk[ssi1_ipg_gate] = imx_clk_gate("ssi1_ipg_gate", "ipg", CCM_PCCR0, 1); |
| @@ -30,7 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | #define MX25_H1_SIC_SHIFT 21 |
| 31 | 31 | #define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT) |
| 32 | 32 | #define MX25_H1_PP_BIT (1 << 18) |
| 33 | −#define MX25_H1_PM_BIT (1 << 8) | |
| 33 | +#define MX25_H1_PM_BIT (1 << 16) | |
| 34 | 34 | #define MX25_H1_IPPUE_UP_BIT (1 << 7) |
| 35 | 35 | #define MX25_H1_IPPUE_DOWN_BIT (1 << 6) |
| 36 | 36 | #define MX25_H1_TLL_BIT (1 << 5) |
| @@ -30,7 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | #define MX35_H1_SIC_SHIFT 21 |
| 31 | 31 | #define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT) |
| 32 | 32 | #define MX35_H1_PP_BIT (1 << 18) |
| 33 | −#define MX35_H1_PM_BIT (1 << 8) | |
| 33 | +#define MX35_H1_PM_BIT (1 << 16) | |
| 34 | 34 | #define MX35_H1_IPPUE_UP_BIT (1 << 7) |
| 35 | 35 | #define MX35_H1_IPPUE_DOWN_BIT (1 << 6) |
| 36 | 36 | #define MX35_H1_TLL_BIT (1 << 5) |
| @@ -108,9 +108,8 @@ void __init imx3_init_l2x0(void) · 107 unmodified lines | ||
| 108 | 108 | } |
| 109 | 109 | |
| 110 | 110 | l2x0_base = ioremap(MX3x_L2CC_BASE_ADDR, 4096); |
| 111 | − if (IS_ERR(l2x0_base)) { | |
| 112 | − printk(KERN_ERR "remapping L2 cache area failed with %ld\n", | |
| 113 | − PTR_ERR(l2x0_base)); | |
| 111 | + if (!l2x0_base) { | |
| 112 | + printk(KERN_ERR "remapping L2 cache area failed\n"); | |
| 114 | 113 | return; |
| 115 | 114 | } |
| 116 | 115 | |
| @@ -410,6 +410,7 @@ void __init ixp4xx_pci_preinit(void) · 409 unmodified lines | ||
| 410 | 410 | * Enable the IO window to be way up high, at 0xfffffc00 |
| 411 | 411 | */ |
| 412 | 412 | local_write_config(PCI_BASE_ADDRESS_5, 4, 0xfffffc01); |
| 413 | + local_write_config(0x40, 4, 0x000080FF); /* No TRDY time limit */ | |
| 413 | 414 | } else { |
| 414 | 415 | printk("PCI: IXP4xx is target - No bus scan performed\n"); |
| 415 | 416 | } |
| @@ -67,15 +67,12 @@ static struct map_desc ixp4xx_io_desc[] __initdata = { · 66 unmodified lines | ||
| 67 | 67 | .pfn = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS), |
| 68 | 68 | .length = IXP4XX_PCI_CFG_REGION_SIZE, |
| 69 | 69 | .type = MT_DEVICE |
| 70 | − }, | |
| 71 | −#ifdef CONFIG_DEBUG_LL | |
| 72 | − { /* Debug UART mapping */ | |
| 73 | − .virtual = (unsigned long)IXP4XX_DEBUG_UART_BASE_VIRT, | |
| 74 | − .pfn = __phys_to_pfn(IXP4XX_DEBUG_UART_BASE_PHYS), | |
| 75 | − .length = IXP4XX_DEBUG_UART_REGION_SIZE, | |
| 70 | + }, { /* Queue Manager */ | |
| 71 | + .virtual = (unsigned long)IXP4XX_QMGR_BASE_VIRT, | |
| 72 | + .pfn = __phys_to_pfn(IXP4XX_QMGR_BASE_PHYS), | |
| 73 | + .length = IXP4XX_QMGR_REGION_SIZE, | |
| 76 | 74 | .type = MT_DEVICE |
| 77 | − } | |
| 78 | −#endif | |
| 75 | + }, | |
| 79 | 76 | }; |
| 80 | 77 | |
| 81 | 78 | void __init ixp4xx_map_io(void) |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <asm/mach/arch.h> |
| 16 | 16 | #include <asm/mach/flash.h> |
| 17 | 17 | #include <asm/mach/pci.h> |
| 18 | +#include <asm/system_info.h> | |
| 18 | 19 | |
| 19 | 20 | #define SLOT_ETHA 0x0B /* IDSEL = AD21 */ |
| 20 | 21 | #define SLOT_ETHB 0x0C /* IDSEL = AD20 */ |
| @@ -329,7 +330,7 @@ static struct platform_device device_hss_tab[] = { · 308 unmodified lines | ||
| 329 | 330 | }; |
| 330 | 331 | |
| 331 | 332 | |
| 332 | −static struct platform_device *device_tab[6] __initdata = { | |
| 333 | +static struct platform_device *device_tab[7] __initdata = { | |
| 333 | 334 | &device_flash, /* index 0 */ |
| 334 | 335 | }; |
| 335 | 336 | |
| @@ -17,8 +17,8 @@ · 16 unmodified lines | ||
| 17 | 17 | #else |
| 18 | 18 | mov \rp, #0 |
| 19 | 19 | #endif |
| 20 | − orr \rv, \rp, #0xff000000 @ virtual | |
| 21 | − orr \rv, \rv, #0x00b00000 | |
| 20 | + orr \rv, \rp, #0xfe000000 @ virtual | |
| 21 | + orr \rv, \rv, #0x00f00000 | |
| 22 | 22 | orr \rp, \rp, #0xc8000000 @ physical |
| 23 | 23 | .endm |
| 24 | 24 | |
| @@ -30,51 +30,43 @@ · 29 unmodified lines | ||
| 30 | 30 | * |
| 31 | 31 | * 0x50000000 0x10000000 ioremap'd EXP BUS |
| 32 | 32 | * |
| 33 | − * 0x6000000 0x00004000 ioremap'd QMgr | |
| 33 | + * 0xC8000000 0x00013000 0xFEF00000 On-Chip Peripherals | |
| 34 | 34 | * |
| 35 | − * 0xC0000000 0x00001000 0xffbff000 PCI CFG | |
| 35 | + * 0xC0000000 0x00001000 0xFEF13000 PCI CFG | |
| 36 | 36 | * |
| 37 | − * 0xC4000000 0x00001000 0xffbfe000 EXP CFG | |
| 37 | + * 0xC4000000 0x00001000 0xFEF14000 EXP CFG | |
| 38 | 38 | * |
| 39 | − * 0xC8000000 0x00013000 0xffbeb000 On-Chip Peripherals | |
| 39 | + * 0x60000000 0x00004000 0xFEF15000 QMgr | |
| 40 | 40 | */ |
| 41 | 41 | |
| 42 | 42 | /* |
| 43 | 43 | * Queue Manager |
| 44 | 44 | */ |
| 45 | −#define IXP4XX_QMGR_BASE_PHYS (0x60000000) | |
| 46 | −#define IXP4XX_QMGR_REGION_SIZE (0x00004000) | |
| 45 | +#define IXP4XX_QMGR_BASE_PHYS 0x60000000 | |
| 46 | +#define IXP4XX_QMGR_BASE_VIRT IOMEM(0xFEF15000) | |
| 47 | +#define IXP4XX_QMGR_REGION_SIZE 0x00004000 | |
| 47 | 48 | |
| 48 | 49 | /* |
| 49 | − * Expansion BUS Configuration registers | |
| 50 | + * Peripheral space, including debug UART. Must be section-aligned so that | |
| 51 | + * it can be used with the low-level debug code. | |
| 50 | 52 | */ |
| 51 | −#define IXP4XX_EXP_CFG_BASE_PHYS (0xC4000000) | |
| 52 | −#define IXP4XX_EXP_CFG_BASE_VIRT IOMEM(0xFFBFE000) | |
| 53 | −#define IXP4XX_EXP_CFG_REGION_SIZE (0x00001000) | |
| 53 | +#define IXP4XX_PERIPHERAL_BASE_PHYS 0xC8000000 | |
| 54 | +#define IXP4XX_PERIPHERAL_BASE_VIRT IOMEM(0xFEF00000) | |
| 55 | +#define IXP4XX_PERIPHERAL_REGION_SIZE 0x00013000 | |
| 54 | 56 | |
| 55 | 57 | /* |
| 56 | 58 | * PCI Config registers |
| 57 | 59 | */ |
| 58 | −#define IXP4XX_PCI_CFG_BASE_PHYS (0xC0000000) | |
| 59 | −#define IXP4XX_PCI_CFG_BASE_VIRT IOMEM(0xFFBFF000) | |
| 60 | −#define IXP4XX_PCI_CFG_REGION_SIZE (0x00001000) | |
| 61 | − | |
| 62 | −/* | |
| 63 | − * Peripheral space | |
| 64 | − */ | |
| 65 | −#define IXP4XX_PERIPHERAL_BASE_PHYS (0xC8000000) | |
| 66 | −#define IXP4XX_PERIPHERAL_BASE_VIRT IOMEM(0xFFBEB000) | |
| 67 | −#define IXP4XX_PERIPHERAL_REGION_SIZE (0x00013000) | |
| 60 | +#define IXP4XX_PCI_CFG_BASE_PHYS 0xC0000000 | |
| 61 | +#define IXP4XX_PCI_CFG_BASE_VIRT IOMEM(0xFEF13000) | |
| 62 | +#define IXP4XX_PCI_CFG_REGION_SIZE 0x00001000 | |
| 68 | 63 | |
| 69 | 64 | /* |
| 70 | − * Debug UART | |
| 71 | − * | |
| 72 | − * This is basically a remap of UART1 into a region that is section | |
| 73 | − * aligned so that it * can be used with the low-level debug code. | |
| 65 | + * Expansion BUS Configuration registers | |
| 74 | 66 | */ |
| 75 | −#define IXP4XX_DEBUG_UART_BASE_PHYS (0xC8000000) | |
| 76 | −#define IXP4XX_DEBUG_UART_BASE_VIRT IOMEM(0xffb00000) | |
| 77 | −#define IXP4XX_DEBUG_UART_REGION_SIZE (0x00001000) | |
| 67 | +#define IXP4XX_EXP_CFG_BASE_PHYS 0xC4000000 | |
| 68 | +#define IXP4XX_EXP_CFG_BASE_VIRT 0xFEF14000 | |
| 69 | +#define IXP4XX_EXP_CFG_REGION_SIZE 0x00001000 | |
| 78 | 70 | |
| 79 | 71 | #define IXP4XX_EXP_CS0_OFFSET 0x00 |
| 80 | 72 | #define IXP4XX_EXP_CS1_OFFSET 0x04 |
| @@ -86,7 +86,7 @@ void qmgr_release_queue(unsigned int queue); · 85 unmodified lines | ||
| 86 | 86 | |
| 87 | 87 | static inline void qmgr_put_entry(unsigned int queue, u32 val) |
| 88 | 88 | { |
| 89 | − extern struct qmgr_regs __iomem *qmgr_regs; | |
| 89 | + struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; | |
| 90 | 90 | #if DEBUG_QMGR |
| 91 | 91 | BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */ |
| 92 | 92 | |
| @@ -99,7 +99,7 @@ static inline void qmgr_put_entry(unsigned int queue, u32 val) · 6 unmodified lines | ||
| 99 | 99 | static inline u32 qmgr_get_entry(unsigned int queue) |
| 100 | 100 | { |
| 101 | 101 | u32 val; |
| 102 | − extern struct qmgr_regs __iomem *qmgr_regs; | |
| 102 | + const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; | |
| 103 | 103 | val = __raw_readl(&qmgr_regs->acc[queue][0]); |
| 104 | 104 | #if DEBUG_QMGR |
| 105 | 105 | BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */ |
| @@ -112,14 +112,14 @@ static inline u32 qmgr_get_entry(unsigned int queue) · 6 unmodified lines | ||
| 112 | 112 | |
| 113 | 113 | static inline int __qmgr_get_stat1(unsigned int queue) |
| 114 | 114 | { |
| 115 | − extern struct qmgr_regs __iomem *qmgr_regs; | |
| 115 | + const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; | |
| 116 | 116 | return (__raw_readl(&qmgr_regs->stat1[queue >> 3]) |
| 117 | 117 | >> ((queue & 7) << 2)) & 0xF; |
| 118 | 118 | } |
| 119 | 119 | |
| 120 | 120 | static inline int __qmgr_get_stat2(unsigned int queue) |
| 121 | 121 | { |
| 122 | − extern struct qmgr_regs __iomem *qmgr_regs; | |
| 122 | + const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; | |
| 123 | 123 | BUG_ON(queue >= HALF_QUEUES); |
| 124 | 124 | return (__raw_readl(&qmgr_regs->stat2[queue >> 4]) |
| 125 | 125 | >> ((queue & 0xF) << 1)) & 0x3; |
| @@ -145,7 +145,7 @@ static inline int qmgr_stat_empty(unsigned int queue) · 19 unmodified lines | ||
| 145 | 145 | */ |
| 146 | 146 | static inline int qmgr_stat_below_low_watermark(unsigned int queue) |
| 147 | 147 | { |
| 148 | − extern struct qmgr_regs __iomem *qmgr_regs; | |
| 148 | + const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; | |
| 149 | 149 | if (queue >= HALF_QUEUES) |
| 150 | 150 | return (__raw_readl(&qmgr_regs->statne_h) >> |
| 151 | 151 | (queue - HALF_QUEUES)) & 0x01; |
| @@ -172,7 +172,7 @@ static inline int qmgr_stat_above_high_watermark(unsigned int queue) · 20 unmodified lines | ||
| 172 | 172 | */ |
| 173 | 173 | static inline int qmgr_stat_full(unsigned int queue) |
| 174 | 174 | { |
| 175 | − extern struct qmgr_regs __iomem *qmgr_regs; | |
| 175 | + const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; | |
| 176 | 176 | if (queue >= HALF_QUEUES) |
| 177 | 177 | return (__raw_readl(&qmgr_regs->statf_h) >> |
| 178 | 178 | (queue - HALF_QUEUES)) & 0x01; |
| @@ -116,7 +116,11 @@ · 115 unmodified lines | ||
| 116 | 116 | /* NPE mailbox_status value for reset */ |
| 117 | 117 | #define RESET_MBOX_STAT 0x0000F0F0 |
| 118 | 118 | |
| 119 | −const char *npe_names[] = { "NPE-A", "NPE-B", "NPE-C" }; | |
| 119 | +#define NPE_A_FIRMWARE "NPE-A" | |
| 120 | +#define NPE_B_FIRMWARE "NPE-B" | |
| 121 | +#define NPE_C_FIRMWARE "NPE-C" | |
| 122 | + | |
| 123 | +const char *npe_names[] = { NPE_A_FIRMWARE, NPE_B_FIRMWARE, NPE_C_FIRMWARE }; | |
| 120 | 124 | |
| 121 | 125 | #define print_npe(pri, npe, fmt, ...) \ |
| 122 | 126 | printk(pri "%s: " fmt, npe_name(npe), ## __VA_ARGS__) |
| @@ -724,6 +728,9 @@ module_exit(npe_cleanup_module); · 601 unmodified lines | ||
| 724 | 728 | |
| 725 | 729 | MODULE_AUTHOR("Krzysztof Halasa"); |
| 726 | 730 | MODULE_LICENSE("GPL v2"); |
| 731 | +MODULE_FIRMWARE(NPE_A_FIRMWARE); | |
| 732 | +MODULE_FIRMWARE(NPE_B_FIRMWARE); | |
| 733 | +MODULE_FIRMWARE(NPE_C_FIRMWARE); | |
| 727 | 734 | |
| 728 | 735 | EXPORT_SYMBOL(npe_names); |
| 729 | 736 | EXPORT_SYMBOL(npe_running); |
| @@ -14,7 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/module.h> |
| 15 | 15 | #include <mach/qmgr.h> |
| 16 | 16 | |
| 17 | −struct qmgr_regs __iomem *qmgr_regs; | |
| 17 | +static struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT; | |
| 18 | 18 | static struct resource *mem_res; |
| 19 | 19 | static spinlock_t qmgr_lock; |
| 20 | 20 | static u32 used_sram_bitmap[4]; /* 128 16-dword pages */ |
| @@ -293,12 +293,6 @@ static int qmgr_init(void) · 272 unmodified lines | ||
| 293 | 293 | if (mem_res == NULL) |
| 294 | 294 | return -EBUSY; |
| 295 | 295 | |
| 296 | − qmgr_regs = ioremap(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE); | |
| 297 | − if (qmgr_regs == NULL) { | |
| 298 | − err = -ENOMEM; | |
| 299 | − goto error_map; | |
| 300 | − } | |
| 301 | − | |
| 302 | 296 | /* reset qmgr registers */ |
| 303 | 297 | for (i = 0; i < 4; i++) { |
| 304 | 298 | __raw_writel(0x33333333, &qmgr_regs->stat1[i]); |
| @@ -347,8 +341,6 @@ static int qmgr_init(void) · 42 unmodified lines | ||
| 347 | 341 | error_irq2: |
| 348 | 342 | free_irq(IRQ_IXP4XX_QM1, NULL); |
| 349 | 343 | error_irq: |
| 350 | − iounmap(qmgr_regs); | |
| 351 | −error_map: | |
| 352 | 344 | release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE); |
| 353 | 345 | return err; |
| 354 | 346 | } |
| @@ -359,7 +351,6 @@ static void qmgr_remove(void) · 4 unmodified lines | ||
| 359 | 351 | free_irq(IRQ_IXP4XX_QM2, NULL); |
| 360 | 352 | synchronize_irq(IRQ_IXP4XX_QM1); |
| 361 | 353 | synchronize_irq(IRQ_IXP4XX_QM2); |
| 362 | − iounmap(qmgr_regs); | |
| 363 | 354 | release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE); |
| 364 | 355 | } |
| 365 | 356 | |
| @@ -369,7 +360,6 @@ module_exit(qmgr_remove); · 3 unmodified lines | ||
| 369 | 360 | MODULE_LICENSE("GPL v2"); |
| 370 | 361 | MODULE_AUTHOR("Krzysztof Halasa"); |
| 371 | 362 | |
| 372 | −EXPORT_SYMBOL(qmgr_regs); | |
| 373 | 363 | EXPORT_SYMBOL(qmgr_set_irq); |
| 374 | 364 | EXPORT_SYMBOL(qmgr_enable_irq); |
| 375 | 365 | EXPORT_SYMBOL(qmgr_disable_irq); |
| @@ -207,14 +207,19 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys) · 206 unmodified lines | ||
| 207 | 207 | return 1; |
| 208 | 208 | } |
| 209 | 209 | |
| 210 | +/* | |
| 211 | + * The root complex has a hardwired class of PCI_CLASS_MEMORY_OTHER, when it | |
| 212 | + * is operating as a root complex this needs to be switched to | |
| 213 | + * PCI_CLASS_BRIDGE_HOST or Linux will errantly try to process the BAR's on | |
| 214 | + * the device. Decoding setup is handled by the orion code. | |
| 215 | + */ | |
| 210 | 216 | static void __devinit rc_pci_fixup(struct pci_dev *dev) |
| 211 | 217 | { |
| 212 | − /* | |
| 213 | − * Prevent enumeration of root complex. | |
| 214 | − */ | |
| 215 | 218 | if (dev->bus->parent == NULL && dev->devfn == 0) { |
| 216 | 219 | int i; |
| 217 | 220 | |
| 221 | + dev->class &= 0xff; | |
| 222 | + dev->class |= PCI_CLASS_BRIDGE_HOST << 8; | |
| 218 | 223 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { |
| 219 | 224 | dev->resource[i].start = 0; |
| 220 | 225 | dev->resource[i].end = 0; |
| @@ -11,7 +11,6 @@ config ARCH_OMAP2PLUS_TYPICAL · 10 unmodified lines | ||
| 11 | 11 | select I2C_OMAP |
| 12 | 12 | select MENELAUS if ARCH_OMAP2 |
| 13 | 13 | select NEON if ARCH_OMAP3 || ARCH_OMAP4 || SOC_OMAP5 |
| 14 | − select PINCTRL | |
| 15 | 14 | select PM_RUNTIME |
| 16 | 15 | select REGULATOR |
| 17 | 16 | select SERIAL_OMAP |
| @@ -580,6 +580,11 @@ static void __init igep_wlan_bt_init(void) · 579 unmodified lines | ||
| 580 | 580 | } else |
| 581 | 581 | return; |
| 582 | 582 | |
| 583 | + /* Make sure that the GPIO pins are muxed correctly */ | |
| 584 | + omap_mux_init_gpio(igep_wlan_bt_gpios[0].gpio, OMAP_PIN_OUTPUT); | |
| 585 | + omap_mux_init_gpio(igep_wlan_bt_gpios[1].gpio, OMAP_PIN_OUTPUT); | |
| 586 | + omap_mux_init_gpio(igep_wlan_bt_gpios[2].gpio, OMAP_PIN_OUTPUT); | |
| 587 | + | |
| 583 | 588 | err = gpio_request_array(igep_wlan_bt_gpios, |
| 584 | 589 | ARRAY_SIZE(igep_wlan_bt_gpios)); |
| 585 | 590 | if (err) { |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | #include <linux/input.h> |
| 25 | 25 | #include <linux/gpio_keys.h> |
| 26 | 26 | #include <linux/opp.h> |
| 27 | +#include <linux/cpu.h> | |
| 27 | 28 | |
| 28 | 29 | #include <linux/mtd/mtd.h> |
| 29 | 30 | #include <linux/mtd/partitions.h> |
| @@ -444,27 +445,31 @@ static struct omap_board_mux board_mux[] __initdata = { · 414 unmodified lines | ||
| 444 | 445 | }; |
| 445 | 446 | #endif |
| 446 | 447 | |
| 447 | −static void __init beagle_opp_init(void) | |
| 448 | +static int __init beagle_opp_init(void) | |
| 448 | 449 | { |
| 449 | 450 | int r = 0; |
| 450 | 451 | |
| 451 | − /* Initialize the omap3 opp table */ | |
| 452 | − if (omap3_opp_init()) { | |
| 452 | + if (!machine_is_omap3_beagle()) | |
| 453 | + return 0; | |
| 454 | + | |
| 455 | + /* Initialize the omap3 opp table if not already created. */ | |
| 456 | + r = omap3_opp_init(); | |
| 457 | + if (IS_ERR_VALUE(r) && (r != -EEXIST)) { | |
| 453 | 458 | pr_err("%s: opp default init failed\n", __func__); |
| 454 | − return; | |
| 459 | + return r; | |
| 455 | 460 | } |
| 456 | 461 | |
| 457 | 462 | /* Custom OPP enabled for all xM versions */ |
| 458 | 463 | if (cpu_is_omap3630()) { |
| 459 | 464 | struct device *mpu_dev, *iva_dev; |
| 460 | 465 | |
| 461 | − mpu_dev = omap_device_get_by_hwmod_name("mpu"); | |
| 466 | + mpu_dev = get_cpu_device(0); | |
| 462 | 467 | iva_dev = omap_device_get_by_hwmod_name("iva"); |
| 463 | 468 | |
| 464 | 469 | if (IS_ERR(mpu_dev) || IS_ERR(iva_dev)) { |
| 465 | 470 | pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n", |
| 466 | 471 | __func__, mpu_dev, iva_dev); |
| 467 | − return; | |
| 472 | + return -ENODEV; | |
| 468 | 473 | } |
| 469 | 474 | /* Enable MPU 1GHz and lower opps */ |
| 470 | 475 | r = opp_enable(mpu_dev, 800000000); |
| @@ -484,8 +489,9 @@ static void __init beagle_opp_init(void) · 13 unmodified lines | ||
| 484 | 489 | opp_disable(iva_dev, 660000000); |
| 485 | 490 | } |
| 486 | 491 | } |
| 487 | − return; | |
| 492 | + return 0; | |
| 488 | 493 | } |
| 494 | +device_initcall(beagle_opp_init); | |
| 489 | 495 | |
| 490 | 496 | static void __init omap3_beagle_init(void) |
| 491 | 497 | { |
| @@ -522,8 +528,6 @@ static void __init omap3_beagle_init(void) · 30 unmodified lines | ||
| 522 | 528 | /* Ensure SDRC pins are mux'd for self-refresh */ |
| 523 | 529 | omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); |
| 524 | 530 | omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); |
| 525 | − | |
| 526 | − beagle_opp_init(); | |
| 527 | 531 | } |
| 528 | 532 | |
| 529 | 533 | MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board") |
| @@ -1073,6 +1073,8 @@ static struct omap_clk am33xx_clks[] = { · 1072 unmodified lines | ||
| 1073 | 1073 | CLK(NULL, "gfx_fck_div_ck", &gfx_fck_div_ck, CK_AM33XX), |
| 1074 | 1074 | CLK(NULL, "sysclkout_pre_ck", &sysclkout_pre_ck, CK_AM33XX), |
| 1075 | 1075 | CLK(NULL, "clkout2_ck", &clkout2_ck, CK_AM33XX), |
| 1076 | + CLK(NULL, "timer_32k_ck", &clkdiv32k_ick, CK_AM33XX), | |
| 1077 | + CLK(NULL, "timer_sys_ck", &sys_clkin_ck, CK_AM33XX), | |
| 1076 | 1078 | }; |
| 1077 | 1079 | |
| 1078 | 1080 | int __init am33xx_clk_init(void) |
| @@ -359,7 +359,7 @@ static struct clockdomain iss_44xx_clkdm = { · 358 unmodified lines | ||
| 359 | 359 | .clkdm_offs = OMAP4430_CM2_CAM_CAM_CDOFFS, |
| 360 | 360 | .wkdep_srcs = iss_wkup_sleep_deps, |
| 361 | 361 | .sleepdep_srcs = iss_wkup_sleep_deps, |
| 362 | − .flags = CLKDM_CAN_HWSUP_SWSUP, | |
| 362 | + .flags = CLKDM_CAN_SWSUP, | |
| 363 | 363 | }; |
| 364 | 364 | |
| 365 | 365 | static struct clockdomain l3_dss_44xx_clkdm = { |
| @@ -64,30 +64,36 @@ void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce, · 63 unmodified lines | ||
| 64 | 64 | struct spi_board_info *spi_bi = &ads7846_spi_board_info; |
| 65 | 65 | int err; |
| 66 | 66 | |
| 67 | − err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown"); | |
| 68 | − if (err) { | |
| 69 | − pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err); | |
| 70 | − return; | |
| 71 | − } | |
| 67 | + /* | |
| 68 | + * If a board defines get_pendown_state() function, request the pendown | |
| 69 | + * GPIO and set the GPIO debounce time. | |
| 70 | + * If a board does not define the get_pendown_state() function, then | |
| 71 | + * the ads7846 driver will setup the pendown GPIO itself. | |
| 72 | + */ | |
| 73 | + if (board_pdata && board_pdata->get_pendown_state) { | |
| 74 | + err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown"); | |
| 75 | + if (err) { | |
| 76 | + pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err); | |
| 77 | + return; | |
| 78 | + } | |
| 72 | 79 | |
| 73 | − if (gpio_debounce) | |
| 74 | − gpio_set_debounce(gpio_pendown, gpio_debounce); | |
| 80 | + if (gpio_debounce) | |
| 81 | + gpio_set_debounce(gpio_pendown, gpio_debounce); | |
| 82 | + | |
| 83 | + gpio_export(gpio_pendown, 0); | |
| 84 | + } | |
| 75 | 85 | |
| 76 | 86 | spi_bi->bus_num = bus_num; |
| 77 | 87 | spi_bi->irq = gpio_to_irq(gpio_pendown); |
| 78 | 88 | |
| 89 | + ads7846_config.gpio_pendown = gpio_pendown; | |
| 90 | + | |
| 79 | 91 | if (board_pdata) { |
| 80 | 92 | board_pdata->gpio_pendown = gpio_pendown; |
| 93 | + board_pdata->gpio_pendown_debounce = gpio_debounce; | |
| 81 | 94 | spi_bi->platform_data = board_pdata; |
| 82 | − if (board_pdata->get_pendown_state) | |
| 83 | − gpio_export(gpio_pendown, 0); | |
| 84 | − } else { | |
| 85 | − ads7846_config.gpio_pendown = gpio_pendown; | |
| 86 | 95 | } |
| 87 | 96 | |
| 88 | − if (!board_pdata || (board_pdata && !board_pdata->get_pendown_state)) | |
| 89 | − gpio_free(gpio_pendown); | |
| 90 | − | |
| 91 | 97 | spi_register_board_info(&ads7846_spi_board_info, 1); |
| 92 | 98 | } |
| 93 | 99 | #else |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | #include <linux/of.h> |
| 20 | 20 | #include <linux/pinctrl/machine.h> |
| 21 | 21 | #include <linux/platform_data/omap4-keypad.h> |
| 22 | +#include <linux/platform_data/omap_ocp2scp.h> | |
| 22 | 23 | |
| 23 | 24 | #include <asm/mach-types.h> |
| 24 | 25 | #include <asm/mach/map.h> |
| @@ -613,6 +614,83 @@ static void omap_init_vout(void) · 588 unmodified lines | ||
| 613 | 614 | static inline void omap_init_vout(void) {} |
| 614 | 615 | #endif |
| 615 | 616 | |
| 617 | +#if defined(CONFIG_OMAP_OCP2SCP) || defined(CONFIG_OMAP_OCP2SCP_MODULE) | |
| 618 | +static int count_ocp2scp_devices(struct omap_ocp2scp_dev *ocp2scp_dev) | |
| 619 | +{ | |
| 620 | + int cnt = 0; | |
| 621 | + | |
| 622 | + while (ocp2scp_dev->drv_name != NULL) { | |
| 623 | + cnt++; | |
| 624 | + ocp2scp_dev++; | |
| 625 | + } | |
| 626 | + | |
| 627 | + return cnt; | |
| 628 | +} | |
| 629 | + | |
| 630 | +static void omap_init_ocp2scp(void) | |
| 631 | +{ | |
| 632 | + struct omap_hwmod *oh; | |
| 633 | + struct platform_device *pdev; | |
| 634 | + int bus_id = -1, dev_cnt = 0, i; | |
| 635 | + struct omap_ocp2scp_dev *ocp2scp_dev; | |
| 636 | + const char *oh_name, *name; | |
| 637 | + struct omap_ocp2scp_platform_data *pdata; | |
| 638 | + | |
| 639 | + if (!cpu_is_omap44xx()) | |
| 640 | + return; | |
| 641 | + | |
| 642 | + oh_name = "ocp2scp_usb_phy"; | |
| 643 | + name = "omap-ocp2scp"; | |
| 644 | + | |
| 645 | + oh = omap_hwmod_lookup(oh_name); | |
| 646 | + if (!oh) { | |
| 647 | + pr_err("%s: could not find omap_hwmod for %s\n", __func__, | |
| 648 | + oh_name); | |
| 649 | + return; | |
| 650 | + } | |
| 651 | + | |
| 652 | + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | |
| 653 | + if (!pdata) { | |
| 654 | + pr_err("%s: No memory for ocp2scp pdata\n", __func__); | |
| 655 | + return; | |
| 656 | + } | |
| 657 | + | |
| 658 | + ocp2scp_dev = oh->dev_attr; | |
| 659 | + dev_cnt = count_ocp2scp_devices(ocp2scp_dev); | |
| 660 | + | |
| 661 | + if (!dev_cnt) { | |
| 662 | + pr_err("%s: No devices connected to ocp2scp\n", __func__); | |
| 663 | + kfree(pdata); | |
| 664 | + return; | |
| 665 | + } | |
| 666 | + | |
| 667 | + pdata->devices = kzalloc(sizeof(struct omap_ocp2scp_dev *) | |
| 668 | + * dev_cnt, GFP_KERNEL); | |
| 669 | + if (!pdata->devices) { | |
| 670 | + pr_err("%s: No memory for ocp2scp pdata devices\n", __func__); | |
| 671 | + kfree(pdata); | |
| 672 | + return; | |
| 673 | + } | |
| 674 | + | |
| 675 | + for (i = 0; i < dev_cnt; i++, ocp2scp_dev++) | |
| 676 | + pdata->devices[i] = ocp2scp_dev; | |
| 677 | + | |
| 678 | + pdata->dev_cnt = dev_cnt; | |
| 679 | + | |
| 680 | + pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(*pdata), NULL, | |
| 681 | + 0, false); | |
| 682 | + if (IS_ERR(pdev)) { | |
| 683 | + pr_err("Could not build omap_device for %s %s\n", | |
| 684 | + name, oh_name); | |
| 685 | + kfree(pdata->devices); | |
| 686 | + kfree(pdata); | |
| 687 | + return; | |
| 688 | + } | |
| 689 | +} | |
| 690 | +#else | |
| 691 | +static inline void omap_init_ocp2scp(void) { } | |
| 692 | +#endif | |
| 693 | + | |
| 616 | 694 | /*-------------------------------------------------------------------------*/ |
| 617 | 695 | |
| 618 | 696 | static int __init omap2_init_devices(void) |
| @@ -640,6 +718,7 @@ static int __init omap2_init_devices(void) · 21 unmodified lines | ||
| 640 | 718 | omap_init_sham(); |
| 641 | 719 | omap_init_aes(); |
| 642 | 720 | omap_init_vout(); |
| 721 | + omap_init_ocp2scp(); | |
| 643 | 722 | |
| 644 | 723 | return 0; |
| 645 | 724 | } |
| @@ -614,16 +614,16 @@ static struct omap_mux __initdata omap3_muxmodes[] = { · 613 unmodified lines | ||
| 614 | 614 | "sys_off_mode", NULL, NULL, NULL, |
| 615 | 615 | "gpio_9", NULL, NULL, "safe_mode"), |
| 616 | 616 | _OMAP3_MUXENTRY(UART1_CTS, 150, |
| 617 | − "uart1_cts", NULL, NULL, NULL, | |
| 617 | + "uart1_cts", "ssi1_rdy_tx", NULL, NULL, | |
| 618 | 618 | "gpio_150", "hsusb3_tll_clk", NULL, "safe_mode"), |
| 619 | 619 | _OMAP3_MUXENTRY(UART1_RTS, 149, |
| 620 | − "uart1_rts", NULL, NULL, NULL, | |
| 620 | + "uart1_rts", "ssi1_flag_tx", NULL, NULL, | |
| 621 | 621 | "gpio_149", NULL, NULL, "safe_mode"), |
| 622 | 622 | _OMAP3_MUXENTRY(UART1_RX, 151, |
| 623 | − "uart1_rx", NULL, "mcbsp1_clkr", "mcspi4_clk", | |
| 623 | + "uart1_rx", "ss1_wake_tx", "mcbsp1_clkr", "mcspi4_clk", | |
| 624 | 624 | "gpio_151", NULL, NULL, "safe_mode"), |
| 625 | 625 | _OMAP3_MUXENTRY(UART1_TX, 148, |
| 626 | − "uart1_tx", NULL, NULL, NULL, | |
| 626 | + "uart1_tx", "ssi1_dat_tx", NULL, NULL, | |
| 627 | 627 | "gpio_148", NULL, NULL, "safe_mode"), |
| 628 | 628 | _OMAP3_MUXENTRY(UART2_CTS, 144, |
| 629 | 629 | "uart2_cts", "mcbsp3_dx", "gpt9_pwm_evt", NULL, |
| @@ -421,6 +421,38 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v) · 420 unmodified lines | ||
| 421 | 421 | return 0; |
| 422 | 422 | } |
| 423 | 423 | |
| 424 | +/** | |
| 425 | + * _wait_softreset_complete - wait for an OCP softreset to complete | |
| 426 | + * @oh: struct omap_hwmod * to wait on | |
| 427 | + * | |
| 428 | + * Wait until the IP block represented by @oh reports that its OCP | |
| 429 | + * softreset is complete. This can be triggered by software (see | |
| 430 | + * _ocp_softreset()) or by hardware upon returning from off-mode (one | |
| 431 | + * example is HSMMC). Waits for up to MAX_MODULE_SOFTRESET_WAIT | |
| 432 | + * microseconds. Returns the number of microseconds waited. | |
| 433 | + */ | |
| 434 | +static int _wait_softreset_complete(struct omap_hwmod *oh) | |
| 435 | +{ | |
| 436 | + struct omap_hwmod_class_sysconfig *sysc; | |
| 437 | + u32 softrst_mask; | |
| 438 | + int c = 0; | |
| 439 | + | |
| 440 | + sysc = oh->class->sysc; | |
| 441 | + | |
| 442 | + if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS) | |
| 443 | + omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs) | |
| 444 | + & SYSS_RESETDONE_MASK), | |
| 445 | + MAX_MODULE_SOFTRESET_WAIT, c); | |
| 446 | + else if (sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { | |
| 447 | + softrst_mask = (0x1 << sysc->sysc_fields->srst_shift); | |
| 448 | + omap_test_timeout(!(omap_hwmod_read(oh, sysc->sysc_offs) | |
| 449 | + & softrst_mask), | |
| 450 | + MAX_MODULE_SOFTRESET_WAIT, c); | |
| 451 | + } | |
| 452 | + | |
| 453 | + return c; | |
| 454 | +} | |
| 455 | + | |
| 424 | 456 | /** |
| 425 | 457 | * _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v |
| 426 | 458 | * @oh: struct omap_hwmod * |
| @@ -1282,6 +1314,18 @@ static void _enable_sysc(struct omap_hwmod *oh) · 855 unmodified lines | ||
| 1282 | 1314 | if (!oh->class->sysc) |
| 1283 | 1315 | return; |
| 1284 | 1316 | |
| 1317 | + /* | |
| 1318 | + * Wait until reset has completed, this is needed as the IP | |
| 1319 | + * block is reset automatically by hardware in some cases | |
| 1320 | + * (off-mode for example), and the drivers require the | |
| 1321 | + * IP to be ready when they access it | |
| 1322 | + */ | |
| 1323 | + if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) | |
| 1324 | + _enable_optional_clocks(oh); | |
| 1325 | + _wait_softreset_complete(oh); | |
| 1326 | + if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) | |
| 1327 | + _disable_optional_clocks(oh); | |
| 1328 | + | |
| 1285 | 1329 | v = oh->_sysc_cache; |
| 1286 | 1330 | sf = oh->class->sysc->sysc_flags; |
| 1287 | 1331 | |
| @@ -1804,7 +1848,7 @@ static int _am33xx_disable_module(struct omap_hwmod *oh) · 516 unmodified lines | ||
| 1804 | 1848 | */ |
| 1805 | 1849 | static int _ocp_softreset(struct omap_hwmod *oh) |
| 1806 | 1850 | { |
| 1807 | − u32 v, softrst_mask; | |
| 1851 | + u32 v; | |
| 1808 | 1852 | int c = 0; |
| 1809 | 1853 | int ret = 0; |
| 1810 | 1854 | |
| @@ -1834,19 +1878,7 @@ static int _ocp_softreset(struct omap_hwmod *oh) · 23 unmodified lines | ||
| 1834 | 1878 | if (oh->class->sysc->srst_udelay) |
| 1835 | 1879 | udelay(oh->class->sysc->srst_udelay); |
| 1836 | 1880 | |
| 1837 | − if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS) | |
| 1838 | − omap_test_timeout((omap_hwmod_read(oh, | |
| 1839 | − oh->class->sysc->syss_offs) | |
| 1840 | − & SYSS_RESETDONE_MASK), | |
| 1841 | − MAX_MODULE_SOFTRESET_WAIT, c); | |
| 1842 | − else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { | |
| 1843 | − softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift); | |
| 1844 | − omap_test_timeout(!(omap_hwmod_read(oh, | |
| 1845 | − oh->class->sysc->sysc_offs) | |
| 1846 | − & softrst_mask), | |
| 1847 | − MAX_MODULE_SOFTRESET_WAIT, c); | |
| 1848 | − } | |
| 1849 | − | |
| 1881 | + c = _wait_softreset_complete(oh); | |
| 1850 | 1882 | if (c == MAX_MODULE_SOFTRESET_WAIT) |
| 1851 | 1883 | pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n", |
| 1852 | 1884 | oh->name, MAX_MODULE_SOFTRESET_WAIT); |
| @@ -2352,6 +2384,9 @@ static int __init _setup_reset(struct omap_hwmod *oh) · 499 unmodified lines | ||
| 2352 | 2384 | if (oh->_state != _HWMOD_STATE_INITIALIZED) |
| 2353 | 2385 | return -EINVAL; |
| 2354 | 2386 | |
| 2387 | + if (oh->flags & HWMOD_EXT_OPT_MAIN_CLK) | |
| 2388 | + return -EPERM; | |
| 2389 | + | |
| 2355 | 2390 | if (oh->rst_lines_cnt == 0) { |
| 2356 | 2391 | r = _enable(oh); |
| 2357 | 2392 | if (r) { |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <linux/io.h> |
| 22 | 22 | #include <linux/platform_data/gpio-omap.h> |
| 23 | 23 | #include <linux/power/smartreflex.h> |
| 24 | +#include <linux/platform_data/omap_ocp2scp.h> | |
| 24 | 25 | |
| 25 | 26 | #include <plat/omap_hwmod.h> |
| 26 | 27 | #include <plat/i2c.h> |
| @@ -2125,6 +2126,14 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = { · 2098 unmodified lines | ||
| 2125 | 2126 | .name = "mcpdm", |
| 2126 | 2127 | .class = &omap44xx_mcpdm_hwmod_class, |
| 2127 | 2128 | .clkdm_name = "abe_clkdm", |
| 2129 | + /* | |
| 2130 | + * It's suspected that the McPDM requires an off-chip main | |
| 2131 | + * functional clock, controlled via I2C. This IP block is | |
| 2132 | + * currently reset very early during boot, before I2C is | |
| 2133 | + * available, so it doesn't seem that we have any choice in | |
| 2134 | + * the kernel other than to avoid resetting it. | |
| 2135 | + */ | |
| 2136 | + .flags = HWMOD_EXT_OPT_MAIN_CLK, | |
| 2128 | 2137 | .mpu_irqs = omap44xx_mcpdm_irqs, |
| 2129 | 2138 | .sdma_reqs = omap44xx_mcpdm_sdma_reqs, |
| 2130 | 2139 | .main_clk = "mcpdm_fck", |
| @@ -2681,6 +2690,32 @@ static struct omap_hwmod_class omap44xx_ocp2scp_hwmod_class = { · 550 unmodified lines | ||
| 2681 | 2690 | .sysc = &omap44xx_ocp2scp_sysc, |
| 2682 | 2691 | }; |
| 2683 | 2692 | |
| 2693 | +/* ocp2scp dev_attr */ | |
| 2694 | +static struct resource omap44xx_usb_phy_and_pll_addrs[] = { | |
| 2695 | + { | |
| 2696 | + .name = "usb_phy", | |
| 2697 | + .start = 0x4a0ad080, | |
| 2698 | + .end = 0x4a0ae000, | |
| 2699 | + .flags = IORESOURCE_MEM, | |
| 2700 | + }, | |
| 2701 | + { | |
| 2702 | + /* XXX: Remove this once control module driver is in place */ | |
| 2703 | + .name = "ctrl_dev", | |
| 2704 | + .start = 0x4a002300, | |
| 2705 | + .end = 0x4a002303, | |
| 2706 | + .flags = IORESOURCE_MEM, | |
| 2707 | + }, | |
| 2708 | + { } | |
| 2709 | +}; | |
| 2710 | + | |
| 2711 | +static struct omap_ocp2scp_dev ocp2scp_dev_attr[] = { | |
| 2712 | + { | |
| 2713 | + .drv_name = "omap-usb2", | |
| 2714 | + .res = omap44xx_usb_phy_and_pll_addrs, | |
| 2715 | + }, | |
| 2716 | + { } | |
| 2717 | +}; | |
| 2718 | + | |
| 2684 | 2719 | /* ocp2scp_usb_phy */ |
| 2685 | 2720 | static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { |
| 2686 | 2721 | .name = "ocp2scp_usb_phy", |
| @@ -2694,6 +2729,7 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { · 7 unmodified lines | ||
| 2694 | 2729 | .modulemode = MODULEMODE_HWCTRL, |
| 2695 | 2730 | }, |
| 2696 | 2731 | }, |
| 2732 | + .dev_attr = ocp2scp_dev_attr, | |
| 2697 | 2733 | }; |
| 2698 | 2734 | |
| 2699 | 2735 | /* |
| @@ -91,6 +91,7 @@ extern void omap3_save_scratchpad_contents(void); · 90 unmodified lines | ||
| 91 | 91 | |
| 92 | 92 | #define PM_RTA_ERRATUM_i608 (1 << 0) |
| 93 | 93 | #define PM_SDRC_WAKEUP_ERRATUM_i583 (1 << 1) |
| 94 | +#define PM_PER_MEMORIES_ERRATUM_i582 (1 << 2) | |
| 94 | 95 | |
| 95 | 96 | #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) |
| 96 | 97 | extern u16 pm34xx_errata; |
| @@ -652,14 +652,17 @@ static void __init pm_errata_configure(void) · 651 unmodified lines | ||
| 652 | 652 | /* Enable the l2 cache toggling in sleep logic */ |
| 653 | 653 | enable_omap3630_toggle_l2_on_restore(); |
| 654 | 654 | if (omap_rev() < OMAP3630_REV_ES1_2) |
| 655 | − pm34xx_errata |= PM_SDRC_WAKEUP_ERRATUM_i583; | |
| 655 | + pm34xx_errata |= (PM_SDRC_WAKEUP_ERRATUM_i583 | | |
| 656 | + PM_PER_MEMORIES_ERRATUM_i582); | |
| 657 | + } else if (cpu_is_omap34xx()) { | |
| 658 | + pm34xx_errata |= PM_PER_MEMORIES_ERRATUM_i582; | |
| 656 | 659 | } |
| 657 | 660 | } |
| 658 | 661 | |
| 659 | 662 | int __init omap3_pm_init(void) |
| 660 | 663 | { |
| 661 | 664 | struct power_state *pwrst, *tmp; |
| 662 | − struct clockdomain *neon_clkdm, *mpu_clkdm; | |
| 665 | + struct clockdomain *neon_clkdm, *mpu_clkdm, *per_clkdm, *wkup_clkdm; | |
| 663 | 666 | int ret; |
| 664 | 667 | |
| 665 | 668 | if (!omap3_has_io_chain_ctrl()) |
| @@ -711,6 +714,8 @@ int __init omap3_pm_init(void) · 45 unmodified lines | ||
| 711 | 714 | |
| 712 | 715 | neon_clkdm = clkdm_lookup("neon_clkdm"); |
| 713 | 716 | mpu_clkdm = clkdm_lookup("mpu_clkdm"); |
| 717 | + per_clkdm = clkdm_lookup("per_clkdm"); | |
| 718 | + wkup_clkdm = clkdm_lookup("wkup_clkdm"); | |
| 714 | 719 | |
| 715 | 720 | #ifdef CONFIG_SUSPEND |
| 716 | 721 | omap_pm_suspend = omap3_pm_suspend; |
| @@ -727,6 +732,27 @@ int __init omap3_pm_init(void) · 10 unmodified lines | ||
| 727 | 732 | if (IS_PM34XX_ERRATUM(PM_RTA_ERRATUM_i608)) |
| 728 | 733 | omap3630_ctrl_disable_rta(); |
| 729 | 734 | |
| 735 | + /* | |
| 736 | + * The UART3/4 FIFO and the sidetone memory in McBSP2/3 are | |
| 737 | + * not correctly reset when the PER powerdomain comes back | |
| 738 | + * from OFF or OSWR when the CORE powerdomain is kept active. | |
| 739 | + * See OMAP36xx Erratum i582 "PER Domain reset issue after | |
| 740 | + * Domain-OFF/OSWR Wakeup". This wakeup dependency is not a | |
| 741 | + * complete workaround. The kernel must also prevent the PER | |
| 742 | + * powerdomain from going to OSWR/OFF while the CORE | |
| 743 | + * powerdomain is not going to OSWR/OFF. And if PER last | |
| 744 | + * power state was off while CORE last power state was ON, the | |
| 745 | + * UART3/4 and McBSP2/3 SIDETONE devices need to run a | |
| 746 | + * self-test using their loopback tests; if that fails, those | |
| 747 | + * devices are unusable until the PER/CORE can complete a transition | |
| 748 | + * from ON to OSWR/OFF and then back to ON. | |
| 749 | + * | |
| 750 | + * XXX Technically this workaround is only needed if off-mode | |
| 751 | + * or OSWR is enabled. | |
| 752 | + */ | |
| 753 | + if (IS_PM34XX_ERRATUM(PM_PER_MEMORIES_ERRATUM_i582)) | |
| 754 | + clkdm_add_wkdep(per_clkdm, wkup_clkdm); | |
| 755 | + | |
| 730 | 756 | clkdm_add_wkdep(neon_clkdm, mpu_clkdm); |
| 731 | 757 | if (omap_type() != OMAP2_DEVICE_TYPE_GP) { |
| 732 | 758 | omap3_secure_ram_storage = |
| @@ -329,6 +329,11 @@ void __init omap_serial_init_port(struct omap_board_data *bdata, · 328 unmodified lines | ||
| 329 | 329 | |
| 330 | 330 | oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt); |
| 331 | 331 | |
| 332 | + if (console_uart_id == bdata->id) { | |
| 333 | + omap_device_enable(pdev); | |
| 334 | + pm_runtime_set_active(&pdev->dev); | |
| 335 | + } | |
| 336 | + | |
| 332 | 337 | oh->dev_attr = uart; |
| 333 | 338 | |
| 334 | 339 | if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) |
| @@ -73,6 +73,7 @@ void __init omap4_pmic_init(const char *pmic_type, · 72 unmodified lines | ||
| 73 | 73 | { |
| 74 | 74 | /* PMIC part*/ |
| 75 | 75 | omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE); |
| 76 | + omap_mux_init_signal("fref_clk0_out.sys_drm_msecure", OMAP_PIN_OUTPUT); | |
| 76 | 77 | omap_pmic_init(1, 400, pmic_type, 7 + OMAP44XX_IRQ_GIC_START, pmic_data); |
| 77 | 78 | |
| 78 | 79 | /* Register additional devices on i2c1 bus if needed */ |
| @@ -366,7 +367,7 @@ static struct regulator_init_data omap4_clk32kg_idata = { · 287 unmodified lines | ||
| 366 | 367 | }; |
| 367 | 368 | |
| 368 | 369 | static struct regulator_consumer_supply omap4_vdd1_supply[] = { |
| 369 | − REGULATOR_SUPPLY("vcc", "mpu.0"), | |
| 370 | + REGULATOR_SUPPLY("vcc", "cpu0"), | |
| 370 | 371 | }; |
| 371 | 372 | |
| 372 | 373 | static struct regulator_consumer_supply omap4_vdd2_supply[] = { |
| @@ -264,7 +264,7 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm) · 263 unmodified lines | ||
| 264 | 264 | |
| 265 | 265 | if (initialized) { |
| 266 | 266 | if (voltdm->pmic->i2c_high_speed != i2c_high_speed) |
| 267 | − pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).", | |
| 267 | + pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).\n", | |
| 268 | 268 | __func__, voltdm->name, i2c_high_speed); |
| 269 | 269 | return; |
| 270 | 270 | } |
| @@ -28,6 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <linux/mfd/asic3.h> |
| 29 | 29 | #include <linux/mtd/physmap.h> |
| 30 | 30 | #include <linux/pda_power.h> |
| 31 | +#include <linux/pwm.h> | |
| 31 | 32 | #include <linux/pwm_backlight.h> |
| 32 | 33 | #include <linux/regulator/driver.h> |
| 33 | 34 | #include <linux/regulator/gpio-regulator.h> |
| @@ -556,7 +557,7 @@ static struct platform_device hx4700_lcd = { · 522 unmodified lines | ||
| 556 | 557 | */ |
| 557 | 558 | |
| 558 | 559 | static struct platform_pwm_backlight_data backlight_data = { |
| 559 | − .pwm_id = 1, | |
| 560 | + .pwm_id = -1, /* Superseded by pwm_lookup */ | |
| 560 | 561 | .max_brightness = 200, |
| 561 | 562 | .dft_brightness = 100, |
| 562 | 563 | .pwm_period_ns = 30923, |
| @@ -571,6 +572,10 @@ static struct platform_device backlight = { · 8 unmodified lines | ||
| 571 | 572 | }, |
| 572 | 573 | }; |
| 573 | 574 | |
| 575 | +static struct pwm_lookup hx4700_pwm_lookup[] = { | |
| 576 | + PWM_LOOKUP("pxa27x-pwm.1", 0, "pwm-backlight", NULL), | |
| 577 | +}; | |
| 578 | + | |
| 574 | 579 | /* |
| 575 | 580 | * USB "Transceiver" |
| 576 | 581 | */ |
| @@ -872,6 +877,7 @@ static void __init hx4700_init(void) · 295 unmodified lines | ||
| 872 | 877 | pxa_set_stuart_info(NULL); |
| 873 | 878 | |
| 874 | 879 | platform_add_devices(devices, ARRAY_SIZE(devices)); |
| 880 | + pwm_add_table(hx4700_pwm_lookup, ARRAY_SIZE(hx4700_pwm_lookup)); | |
| 875 | 881 | |
| 876 | 882 | pxa_set_ficp_info(&ficp_info); |
| 877 | 883 | pxa27x_set_i2c_power_info(NULL); |
| @@ -86,10 +86,7 @@ static void spitz_discharge1(int on) · 85 unmodified lines | ||
| 86 | 86 | gpio_set_value(SPITZ_GPIO_LED_GREEN, on); |
| 87 | 87 | } |
| 88 | 88 | |
| 89 | −static unsigned long gpio18_config[] = { | |
| 90 | − GPIO18_RDY, | |
| 91 | − GPIO18_GPIO, | |
| 92 | −}; | |
| 89 | +static unsigned long gpio18_config = GPIO18_GPIO; | |
| 93 | 90 | |
| 94 | 91 | static void spitz_presuspend(void) |
| 95 | 92 | { |
| @@ -112,7 +109,7 @@ static void spitz_presuspend(void) · 16 unmodified lines | ||
| 112 | 109 | PGSR3 &= ~SPITZ_GPIO_G3_STROBE_BIT; |
| 113 | 110 | PGSR2 |= GPIO_bit(SPITZ_GPIO_KEY_STROBE0); |
| 114 | 111 | |
| 115 | − pxa2xx_mfp_config(&gpio18_config[0], 1); | |
| 112 | + pxa2xx_mfp_config(&gpio18_config, 1); | |
| 116 | 113 | gpio_request_one(18, GPIOF_OUT_INIT_HIGH, "Unknown"); |
| 117 | 114 | gpio_free(18); |
| 118 | 115 | |
| @@ -131,7 +128,6 @@ static void spitz_presuspend(void) · 12 unmodified lines | ||
| 131 | 128 | |
| 132 | 129 | static void spitz_postsuspend(void) |
| 133 | 130 | { |
| 134 | − pxa2xx_mfp_config(&gpio18_config[1], 1); | |
| 135 | 131 | } |
| 136 | 132 | |
| 137 | 133 | static int spitz_should_wakeup(unsigned int resume_on_alarm) |
| @@ -61,6 +61,7 @@ · 60 unmodified lines | ||
| 61 | 61 | #include <plat/nand-core.h> |
| 62 | 62 | #include <plat/adc-core.h> |
| 63 | 63 | #include <plat/rtc-core.h> |
| 64 | +#include <plat/spi-core.h> | |
| 64 | 65 | |
| 65 | 66 | static struct map_desc s3c2416_iodesc[] __initdata = { |
| 66 | 67 | IODESC_ENT(WATCHDOG), |
| @@ -132,6 +133,7 @@ void __init s3c2416_map_io(void) · 65 unmodified lines | ||
| 132 | 133 | /* initialize device information early */ |
| 133 | 134 | s3c2416_default_sdhci0(); |
| 134 | 135 | s3c2416_default_sdhci1(); |
| 136 | + s3c64xx_spi_setname("s3c2443-spi"); | |
| 135 | 137 | |
| 136 | 138 | iotable_init(s3c2416_iodesc, ARRAY_SIZE(s3c2416_iodesc)); |
| 137 | 139 | } |
| @@ -43,6 +43,7 @@ · 42 unmodified lines | ||
| 43 | 43 | #include <plat/nand-core.h> |
| 44 | 44 | #include <plat/adc-core.h> |
| 45 | 45 | #include <plat/rtc-core.h> |
| 46 | +#include <plat/spi-core.h> | |
| 46 | 47 | |
| 47 | 48 | static struct map_desc s3c2443_iodesc[] __initdata = { |
| 48 | 49 | IODESC_ENT(WATCHDOG), |
| @@ -100,6 +101,9 @@ void __init s3c2443_map_io(void) · 51 unmodified lines | ||
| 100 | 101 | s3c24xx_gpiocfg_default.set_pull = s3c2443_gpio_setpull; |
| 101 | 102 | s3c24xx_gpiocfg_default.get_pull = s3c2443_gpio_getpull; |
| 102 | 103 | |
| 104 | + /* initialize device information early */ | |
| 105 | + s3c64xx_spi_setname("s3c2443-spi"); | |
| 106 | + | |
| 103 | 107 | iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc)); |
| 104 | 108 | } |
| 105 | 109 | |
| @@ -44,6 +44,7 @@ · 43 unmodified lines | ||
| 44 | 44 | #include <plat/sdhci.h> |
| 45 | 45 | #include <plat/adc-core.h> |
| 46 | 46 | #include <plat/fb-core.h> |
| 47 | +#include <plat/spi-core.h> | |
| 47 | 48 | #include <plat/gpio-cfg.h> |
| 48 | 49 | #include <plat/regs-irqtype.h> |
| 49 | 50 | #include <plat/regs-serial.h> |
| @@ -179,6 +180,7 @@ void __init s5p6440_map_io(void) · 129 unmodified lines | ||
| 179 | 180 | /* initialize any device information early */ |
| 180 | 181 | s3c_adc_setname("s3c64xx-adc"); |
| 181 | 182 | s3c_fb_setname("s5p64x0-fb"); |
| 183 | + s3c64xx_spi_setname("s5p64x0-spi"); | |
| 182 | 184 | |
| 183 | 185 | s5p64x0_default_sdhci0(); |
| 184 | 186 | s5p64x0_default_sdhci1(); |
| @@ -193,6 +195,7 @@ void __init s5p6450_map_io(void) · 8 unmodified lines | ||
| 193 | 195 | /* initialize any device information early */ |
| 194 | 196 | s3c_adc_setname("s3c64xx-adc"); |
| 195 | 197 | s3c_fb_setname("s5p64x0-fb"); |
| 198 | + s3c64xx_spi_setname("s5p64x0-spi"); | |
| 196 | 199 | |
| 197 | 200 | s5p64x0_default_sdhci0(); |
| 198 | 201 | s5p64x0_default_sdhci1(); |
| @@ -45,6 +45,7 @@ · 44 unmodified lines | ||
| 45 | 45 | #include <plat/fb-core.h> |
| 46 | 46 | #include <plat/iic-core.h> |
| 47 | 47 | #include <plat/onenand-core.h> |
| 48 | +#include <plat/spi-core.h> | |
| 48 | 49 | #include <plat/regs-serial.h> |
| 49 | 50 | #include <plat/watchdog-reset.h> |
| 50 | 51 | |
| @@ -165,6 +166,8 @@ void __init s5pc100_map_io(void) · 114 unmodified lines | ||
| 165 | 166 | s3c_onenand_setname("s5pc100-onenand"); |
| 166 | 167 | s3c_fb_setname("s5pc100-fb"); |
| 167 | 168 | s3c_cfcon_setname("s5pc100-pata"); |
| 169 | + | |
| 170 | + s3c64xx_spi_setname("s5pc100-spi"); | |
| 168 | 171 | } |
| 169 | 172 | |
| 170 | 173 | void __init s5pc100_init_clocks(int xtal) |
| @@ -43,6 +43,7 @@ · 42 unmodified lines | ||
| 43 | 43 | #include <plat/iic-core.h> |
| 44 | 44 | #include <plat/keypad-core.h> |
| 45 | 45 | #include <plat/tv-core.h> |
| 46 | +#include <plat/spi-core.h> | |
| 46 | 47 | #include <plat/regs-serial.h> |
| 47 | 48 | |
| 48 | 49 | #include "common.h" |
| @@ -196,6 +197,8 @@ void __init s5pv210_map_io(void) · 147 unmodified lines | ||
| 196 | 197 | |
| 197 | 198 | /* setup TV devices */ |
| 198 | 199 | s5p_hdmi_setname("s5pv210-hdmi"); |
| 200 | + | |
| 201 | + s3c64xx_spi_setname("s5pv210-spi"); | |
| 199 | 202 | } |
| 200 | 203 | |
| 201 | 204 | void __init s5pv210_init_clocks(int xtal) |
| @@ -247,7 +247,7 @@ void __init r8a7779_add_standard_devices(void) · 246 unmodified lines | ||
| 247 | 247 | { |
| 248 | 248 | #ifdef CONFIG_CACHE_L2X0 |
| 249 | 249 | /* Early BRESP enable, Shared attribute override enable, 64K*16way */ |
| 250 | − l2x0_init((void __iomem __force *)(0xf0100000), 0x40470000, 0x82000fff); | |
| 250 | + l2x0_init(IOMEM(0xf0100000), 0x40470000, 0x82000fff); | |
| 251 | 251 | #endif |
| 252 | 252 | r8a7779_pm_init(); |
| 253 | 253 | |
Empty file deleted.
Empty file deleted.
| @@ -16,6 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/stat.h> |
| 17 | 17 | #include <linux/of.h> |
| 18 | 18 | #include <linux/of_irq.h> |
| 19 | +#include <linux/irq.h> | |
| 19 | 20 | #include <linux/platform_data/clk-ux500.h> |
| 20 | 21 | |
| 21 | 22 | #include <asm/hardware/gic.h> |
| @@ -745,7 +745,7 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs, · 744 unmodified lines | ||
| 745 | 745 | static int |
| 746 | 746 | do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) |
| 747 | 747 | { |
| 748 | − union offset_union offset; | |
| 748 | + union offset_union uninitialized_var(offset); | |
| 749 | 749 | unsigned long instr = 0, instrptr; |
| 750 | 750 | int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs); |
| 751 | 751 | unsigned int type; |
| @@ -856,8 +856,10 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) · 104 unmodified lines | ||
| 856 | 856 | if (thumb2_32b) { |
| 857 | 857 | offset.un = 0; |
| 858 | 858 | handler = do_alignment_t32_to_handler(&instr, regs, &offset); |
| 859 | − } else | |
| 859 | + } else { | |
| 860 | + offset.un = 0; | |
| 860 | 861 | handler = do_alignment_ldmstm; |
| 862 | + } | |
| 861 | 863 | break; |
| 862 | 864 | |
| 863 | 865 | default: |
| @@ -610,7 +610,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, · 609 unmodified lines | ||
| 610 | 610 | gfp_t gfp, pgprot_t prot, bool is_coherent, const void *caller) |
| 611 | 611 | { |
| 612 | 612 | u64 mask = get_coherent_dma_mask(dev); |
| 613 | − struct page *page; | |
| 613 | + struct page *page = NULL; | |
| 614 | 614 | void *addr; |
| 615 | 615 | |
| 616 | 616 | #ifdef CONFIG_DMA_API_DEBUG |
| @@ -89,7 +89,7 @@ ENTRY(cpu_v6_dcache_clean_area) · 88 unmodified lines | ||
| 89 | 89 | mov pc, lr |
| 90 | 90 | |
| 91 | 91 | /* |
| 92 | − * cpu_arm926_switch_mm(pgd_phys, tsk) | |
| 92 | + * cpu_v6_switch_mm(pgd_phys, tsk) | |
| 93 | 93 | * |
| 94 | 94 | * Set the translation table base pointer to be pgd_phys |
| 95 | 95 | * |
| @@ -17,7 +17,6 @@ struct arm_vmregion { · 16 unmodified lines | ||
| 17 | 17 | struct list_head vm_list; |
| 18 | 18 | unsigned long vm_start; |
| 19 | 19 | unsigned long vm_end; |
| 20 | − void *priv; | |
| 21 | 20 | int vm_active; |
| 22 | 21 | const void *caller; |
| 23 | 22 | }; |
| @@ -55,7 +55,7 @@ struct platform_device *__init imx_add_mxc_mmc( · 54 unmodified lines | ||
| 55 | 55 | struct resource res[] = { |
| 56 | 56 | { |
| 57 | 57 | .start = data->iobase, |
| 58 | − .end = data->iobase + SZ_4K - 1, | |
| 58 | + .end = data->iobase + data->iosize - 1, | |
| 59 | 59 | .flags = IORESOURCE_MEM, |
| 60 | 60 | }, { |
| 61 | 61 | .start = data->irq, |
| @@ -26,6 +26,7 @@ config ARCH_OMAP2PLUS · 25 unmodified lines | ||
| 26 | 26 | select CLKDEV_LOOKUP |
| 27 | 27 | select GENERIC_IRQ_CHIP |
| 28 | 28 | select OMAP_DM_TIMER |
| 29 | + select PINCTRL | |
| 29 | 30 | select PROC_DEVICETREE if PROC_FS |
| 30 | 31 | select SPARSE_IRQ |
| 31 | 32 | select USE_OF |
| @@ -26,12 +26,14 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <linux/kernel.h> |
| 27 | 27 | #include <linux/platform_device.h> |
| 28 | 28 | #include <linux/i2c.h> |
| 29 | +#include <linux/i2c-omap.h> | |
| 29 | 30 | #include <linux/slab.h> |
| 30 | 31 | #include <linux/err.h> |
| 31 | 32 | #include <linux/clk.h> |
| 32 | 33 | |
| 33 | 34 | #include <mach/irqs.h> |
| 34 | 35 | #include <plat/i2c.h> |
| 36 | +#include <plat/omap-pm.h> | |
| 35 | 37 | #include <plat/omap_device.h> |
| 36 | 38 | |
| 37 | 39 | #define OMAP_I2C_SIZE 0x3f |
| @@ -127,6 +129,16 @@ static inline int omap1_i2c_add_bus(int bus_id) · 89 unmodified lines | ||
| 127 | 129 | |
| 128 | 130 | |
| 129 | 131 | #ifdef CONFIG_ARCH_OMAP2PLUS |
| 132 | +/* | |
| 133 | + * XXX This function is a temporary compatibility wrapper - only | |
| 134 | + * needed until the I2C driver can be converted to call | |
| 135 | + * omap_pm_set_max_dev_wakeup_lat() and handle a return code. | |
| 136 | + */ | |
| 137 | +static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t) | |
| 138 | +{ | |
| 139 | + omap_pm_set_max_mpu_wakeup_lat(dev, t); | |
| 140 | +} | |
| 141 | + | |
| 130 | 142 | static inline int omap2_i2c_add_bus(int bus_id) |
| 131 | 143 | { |
| 132 | 144 | int l; |
| @@ -158,6 +170,15 @@ static inline int omap2_i2c_add_bus(int bus_id) · 25 unmodified lines | ||
| 158 | 170 | dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr; |
| 159 | 171 | pdata->flags = dev_attr->flags; |
| 160 | 172 | |
| 173 | + /* | |
| 174 | + * When waiting for completion of a i2c transfer, we need to | |
| 175 | + * set a wake up latency constraint for the MPU. This is to | |
| 176 | + * ensure quick enough wakeup from idle, when transfer | |
| 177 | + * completes. | |
| 178 | + * Only omap3 has support for constraints | |
| 179 | + */ | |
| 180 | + if (cpu_is_omap34xx()) | |
| 181 | + pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; | |
| 161 | 182 | pdev = omap_device_build(name, bus_id, oh, pdata, |
| 162 | 183 | sizeof(struct omap_i2c_bus_platform_data), |
| 163 | 184 | NULL, 0, 0); |
| @@ -40,10 +40,10 @@ · 39 unmodified lines | ||
| 40 | 40 | #define OMAP_UART_WER_MOD_WKUP 0X7F |
| 41 | 41 | |
| 42 | 42 | /* Enable XON/XOFF flow control on output */ |
| 43 | −#define OMAP_UART_SW_TX 0x8 | |
| 43 | +#define OMAP_UART_SW_TX 0x04 | |
| 44 | 44 | |
| 45 | 45 | /* Enable XON/XOFF flow control on input */ |
| 46 | −#define OMAP_UART_SW_RX 0x2 | |
| 46 | +#define OMAP_UART_SW_RX 0x04 | |
| 47 | 47 | |
| 48 | 48 | #define OMAP_UART_SYSC_RESET 0X07 |
| 49 | 49 | #define OMAP_UART_TCR_TRIG 0X0F |
| @@ -443,6 +443,11 @@ struct omap_hwmod_omap4_prcm { · 442 unmodified lines | ||
| 443 | 443 | * in order to complete the reset. Optional clocks will be disabled |
| 444 | 444 | * again after the reset. |
| 445 | 445 | * HWMOD_16BIT_REG: Module has 16bit registers |
| 446 | + * HWMOD_EXT_OPT_MAIN_CLK: The only main functional clock source for | |
| 447 | + * this IP block comes from an off-chip source and is not always | |
| 448 | + * enabled. This prevents the hwmod code from being able to | |
| 449 | + * enable and reset the IP block early. XXX Eventually it should | |
| 450 | + * be possible to query the clock framework for this information. | |
| 446 | 451 | */ |
| 447 | 452 | #define HWMOD_SWSUP_SIDLE (1 << 0) |
| 448 | 453 | #define HWMOD_SWSUP_MSTANDBY (1 << 1) |
| @@ -453,6 +458,7 @@ struct omap_hwmod_omap4_prcm { · 4 unmodified lines | ||
| 453 | 458 | #define HWMOD_NO_IDLEST (1 << 6) |
| 454 | 459 | #define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7) |
| 455 | 460 | #define HWMOD_16BIT_REG (1 << 8) |
| 461 | +#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9) | |
| 456 | 462 | |
| 457 | 463 | /* |
| 458 | 464 | * omap_hwmod._int_flags definitions |
| @@ -473,12 +473,13 @@ int s3c2410_dma_enqueue(enum dma_ch channel, void *id, · 472 unmodified lines | ||
| 473 | 473 | pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n", |
| 474 | 474 | chan->number, __func__, buf); |
| 475 | 475 | |
| 476 | − if (chan->end == NULL) | |
| 476 | + if (chan->end == NULL) { | |
| 477 | 477 | pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n", |
| 478 | 478 | chan->number, __func__, chan); |
| 479 | − | |
| 480 | − chan->end->next = buf; | |
| 481 | − chan->end = buf; | |
| 479 | + } else { | |
| 480 | + chan->end->next = buf; | |
| 481 | + chan->end = buf; | |
| 482 | + } | |
| 482 | 483 | } |
| 483 | 484 | |
| 484 | 485 | /* if necessary, update the next buffer field */ |
| @@ -0,0 +1,30 @@ | ||
| 1 | +/* | |
| 2 | + * Copyright (C) 2012 Heiko Stuebner <heiko@sntech.de> | |
| 3 | + * | |
| 4 | + * This program is free software; you can redistribute it and/or modify | |
| 5 | + * it under the terms of the GNU General Public License version 2 as | |
| 6 | + * published by the Free Software Foundation. | |
| 7 | + */ | |
| 8 | + | |
| 9 | +#ifndef __PLAT_S3C_SPI_CORE_H | |
| 10 | +#define __PLAT_S3C_SPI_CORE_H | |
| 11 | + | |
| 12 | +/* These functions are only for use with the core support code, such as | |
| 13 | + * the cpu specific initialisation code | |
| 14 | + */ | |
| 15 | + | |
| 16 | +/* re-define device name depending on support. */ | |
| 17 | +static inline void s3c64xx_spi_setname(char *name) | |
| 18 | +{ | |
| 19 | +#ifdef CONFIG_S3C64XX_DEV_SPI0 | |
| 20 | + s3c64xx_device_spi0.name = name; | |
| 21 | +#endif | |
| 22 | +#ifdef CONFIG_S3C64XX_DEV_SPI1 | |
| 23 | + s3c64xx_device_spi1.name = name; | |
| 24 | +#endif | |
| 25 | +#ifdef CONFIG_S3C64XX_DEV_SPI2 | |
| 26 | + s3c64xx_device_spi2.name = name; | |
| 27 | +#endif | |
| 28 | +} | |
| 29 | + | |
| 30 | +#endif /* __PLAT_S3C_SPI_CORE_H */ | |
| @@ -5,6 +5,6 @@ · 4 unmodified lines | ||
| 5 | 5 | # |
| 6 | 6 | |
| 7 | 7 | include/generated/mach-types.h: $(src)/gen-mach-types $(src)/mach-types |
| 8 | − @echo ' Generating $@' | |
| 8 | + @$(kecho) ' Generating $@' | |
| 9 | 9 | @mkdir -p $(dir $@) |
| 10 | 10 | $(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; } |
| @@ -701,11 +701,14 @@ static int __init vfp_init(void) · 700 unmodified lines | ||
| 701 | 701 | elf_hwcap |= HWCAP_VFPv3; |
| 702 | 702 | |
| 703 | 703 | /* |
| 704 | − * Check for VFPv3 D16. CPUs in this configuration | |
| 705 | − * only have 16 x 64bit registers. | |
| 704 | + * Check for VFPv3 D16 and VFPv4 D16. CPUs in | |
| 705 | + * this configuration only have 16 x 64bit | |
| 706 | + * registers. | |
| 706 | 707 | */ |
| 707 | 708 | if (((fmrx(MVFR0) & MVFR0_A_SIMD_MASK)) == 1) |
| 708 | − elf_hwcap |= HWCAP_VFPv3D16; | |
| 709 | + elf_hwcap |= HWCAP_VFPv3D16; /* also v4-D16 */ | |
| 710 | + else | |
| 711 | + elf_hwcap |= HWCAP_VFPD32; | |
| 709 | 712 | } |
| 710 | 713 | #endif |
| 711 | 714 | /* |
| @@ -166,3 +166,14 @@ void free_xenballooned_pages(int nr_pages, struct page **pages) · 165 unmodified lines | ||
| 166 | 166 | *pages = NULL; |
| 167 | 167 | } |
| 168 | 168 | EXPORT_SYMBOL_GPL(free_xenballooned_pages); |
| 169 | + | |
| 170 | +/* In the hypervisor.S file. */ | |
| 171 | +EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op); | |
| 172 | +EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op); | |
| 173 | +EXPORT_SYMBOL_GPL(HYPERVISOR_xen_version); | |
| 174 | +EXPORT_SYMBOL_GPL(HYPERVISOR_console_io); | |
| 175 | +EXPORT_SYMBOL_GPL(HYPERVISOR_sched_op); | |
| 176 | +EXPORT_SYMBOL_GPL(HYPERVISOR_hvm_op); | |
| 177 | +EXPORT_SYMBOL_GPL(HYPERVISOR_memory_op); | |
| 178 | +EXPORT_SYMBOL_GPL(HYPERVISOR_physdev_op); | |
| 179 | +EXPORT_SYMBOL_GPL(privcmd_call); | |
| @@ -48,20 +48,16 @@ · 47 unmodified lines | ||
| 48 | 48 | |
| 49 | 49 | #include <linux/linkage.h> |
| 50 | 50 | #include <asm/assembler.h> |
| 51 | +#include <asm/opcodes-virt.h> | |
| 51 | 52 | #include <xen/interface/xen.h> |
| 52 | 53 | |
| 53 | 54 | |
| 54 | −/* HVC 0xEA1 */ | |
| 55 | −#ifdef CONFIG_THUMB2_KERNEL | |
| 56 | −#define xen_hvc .word 0xf7e08ea1 | |
| 57 | −#else | |
| 58 | −#define xen_hvc .word 0xe140ea71 | |
| 59 | −#endif | |
| 55 | +#define XEN_IMM 0xEA1 | |
| 60 | 56 | |
| 61 | 57 | #define HYPERCALL_SIMPLE(hypercall) \ |
| 62 | 58 | ENTRY(HYPERVISOR_##hypercall) \ |
| 63 | 59 | mov r12, #__HYPERVISOR_##hypercall; \ |
| 64 | − xen_hvc; \ | |
| 60 | + __HVC(XEN_IMM); \ | |
| 65 | 61 | mov pc, lr; \ |
| 66 | 62 | ENDPROC(HYPERVISOR_##hypercall) |
| 67 | 63 | |
| @@ -76,7 +72,7 @@ ENTRY(HYPERVISOR_##hypercall) \ · 8 unmodified lines | ||
| 76 | 72 | stmdb sp!, {r4} \ |
| 77 | 73 | ldr r4, [sp, #4] \ |
| 78 | 74 | mov r12, #__HYPERVISOR_##hypercall; \ |
| 79 | − xen_hvc \ | |
| 75 | + __HVC(XEN_IMM); \ | |
| 80 | 76 | ldm sp!, {r4} \ |
| 81 | 77 | mov pc, lr \ |
| 82 | 78 | ENDPROC(HYPERVISOR_##hypercall) |
| @@ -100,7 +96,7 @@ ENTRY(privcmd_call) · 17 unmodified lines | ||
| 100 | 96 | mov r2, r3 |
| 101 | 97 | ldr r3, [sp, #8] |
| 102 | 98 | ldr r4, [sp, #4] |
| 103 | − xen_hvc | |
| 99 | + __HVC(XEN_IMM) | |
| 104 | 100 | ldm sp!, {r4} |
| 105 | 101 | mov pc, lr |
| 106 | 102 | ENDPROC(privcmd_call); |
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | config ARM64 |
| 2 | 2 | def_bool y |
| 3 | 3 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE |
| 4 | + select ARCH_WANT_COMPAT_IPC_PARSE_VERSION | |
| 4 | 5 | select GENERIC_CLOCKEVENTS |
| 5 | 6 | select GENERIC_HARDIRQS_NO_DEPRECATED |
| 6 | 7 | select GENERIC_IOMAP |
| @@ -25,12 +25,10 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <asm/user.h> |
| 26 | 26 | |
| 27 | 27 | typedef unsigned long elf_greg_t; |
| 28 | −typedef unsigned long elf_freg_t[3]; | |
| 29 | 28 | |
| 30 | 29 | #define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t)) |
| 31 | 30 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; |
| 32 | − | |
| 33 | −typedef struct user_fp elf_fpregset_t; | |
| 31 | +typedef struct user_fpsimd_state elf_fpregset_t; | |
| 34 | 32 | |
| 35 | 33 | #define EM_AARCH64 183 |
| 36 | 34 | |
| @@ -87,7 +85,6 @@ typedef struct user_fp elf_fpregset_t; · 50 unmodified lines | ||
| 87 | 85 | #define R_AARCH64_MOVW_PREL_G2_NC 292 |
| 88 | 86 | #define R_AARCH64_MOVW_PREL_G3 293 |
| 89 | 87 | |
| 90 | − | |
| 91 | 88 | /* |
| 92 | 89 | * These are used to set parameters in the core dumps. |
| 93 | 90 | */ |
| @@ -25,9 +25,8 @@ · 24 unmodified lines | ||
| 25 | 25 | * - FPSR and FPCR |
| 26 | 26 | * - 32 128-bit data registers |
| 27 | 27 | * |
| 28 | − * Note that user_fp forms a prefix of this structure, which is relied | |
| 29 | − * upon in the ptrace FP/SIMD accessors. struct user_fpsimd_state must | |
| 30 | − * form a prefix of struct fpsimd_state. | |
| 28 | + * Note that user_fpsimd forms a prefix of this structure, which is | |
| 29 | + * relied upon in the ptrace FP/SIMD accessors. | |
| 31 | 30 | */ |
| 32 | 31 | struct fpsimd_state { |
| 33 | 32 | union { |
| @@ -114,7 +114,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) · 113 unmodified lines | ||
| 114 | 114 | * I/O port access primitives. |
| 115 | 115 | */ |
| 116 | 116 | #define IO_SPACE_LIMIT 0xffff |
| 117 | −#define PCI_IOBASE ((void __iomem *)0xffffffbbfffe0000UL) | |
| 117 | +#define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_2M)) | |
| 118 | 118 | |
| 119 | 119 | static inline u8 inb(unsigned long addr) |
| 120 | 120 | { |
| @@ -222,12 +222,12 @@ extern void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot · 101 unmodified lines | ||
| 222 | 222 | extern void __iounmap(volatile void __iomem *addr); |
| 223 | 223 | |
| 224 | 224 | #define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_DIRTY) |
| 225 | −#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_XN | PTE_ATTRINDX(MT_DEVICE_nGnRE)) | |
| 225 | +#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE)) | |
| 226 | 226 | #define PROT_NORMAL_NC (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC)) |
| 227 | 227 | |
| 228 | −#define ioremap(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE) | |
| 229 | −#define ioremap_nocache(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE) | |
| 230 | −#define ioremap_wc(addr, size) __ioremap((addr), (size), PROT_NORMAL_NC) | |
| 228 | +#define ioremap(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) | |
| 229 | +#define ioremap_nocache(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) | |
| 230 | +#define ioremap_wc(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC)) | |
| 231 | 231 | #define iounmap __iounmap |
| 232 | 232 | |
| 233 | 233 | #define ARCH_HAS_IOREMAP_WC |
| @@ -38,7 +38,8 @@ · 37 unmodified lines | ||
| 38 | 38 | #define PMD_SECT_S (_AT(pmdval_t, 3) << 8) |
| 39 | 39 | #define PMD_SECT_AF (_AT(pmdval_t, 1) << 10) |
| 40 | 40 | #define PMD_SECT_NG (_AT(pmdval_t, 1) << 11) |
| 41 | −#define PMD_SECT_XN (_AT(pmdval_t, 1) << 54) | |
| 41 | +#define PMD_SECT_PXN (_AT(pmdval_t, 1) << 53) | |
| 42 | +#define PMD_SECT_UXN (_AT(pmdval_t, 1) << 54) | |
| 42 | 43 | |
| 43 | 44 | /* |
| 44 | 45 | * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). |
| @@ -57,7 +58,8 @@ · 12 unmodified lines | ||
| 57 | 58 | #define PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ |
| 58 | 59 | #define PTE_AF (_AT(pteval_t, 1) << 10) /* Access Flag */ |
| 59 | 60 | #define PTE_NG (_AT(pteval_t, 1) << 11) /* nG */ |
| 60 | −#define PTE_XN (_AT(pteval_t, 1) << 54) /* XN */ | |
| 61 | +#define PTE_PXN (_AT(pteval_t, 1) << 53) /* Privileged XN */ | |
| 62 | +#define PTE_UXN (_AT(pteval_t, 1) << 54) /* User XN */ | |
| 61 | 63 | |
| 62 | 64 | /* |
| 63 | 65 | * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). |
| @@ -62,23 +62,23 @@ extern pgprot_t pgprot_default; · 61 unmodified lines | ||
| 62 | 62 | |
| 63 | 63 | #define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b)) |
| 64 | 64 | |
| 65 | −#define PAGE_NONE _MOD_PROT(pgprot_default, PTE_NG | PTE_XN | PTE_RDONLY) | |
| 66 | −#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN) | |
| 67 | −#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG) | |
| 68 | −#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) | |
| 69 | −#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY) | |
| 70 | −#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) | |
| 71 | −#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY) | |
| 72 | −#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_XN | PTE_DIRTY) | |
| 73 | −#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_DIRTY) | |
| 74 | − | |
| 75 | −#define __PAGE_NONE __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_XN | PTE_RDONLY) | |
| 76 | −#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN) | |
| 77 | −#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG) | |
| 78 | −#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) | |
| 79 | −#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY) | |
| 80 | −#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) | |
| 81 | −#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY) | |
| 65 | +#define PAGE_NONE _MOD_PROT(pgprot_default, PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) | |
| 66 | +#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) | |
| 67 | +#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN) | |
| 68 | +#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) | |
| 69 | +#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) | |
| 70 | +#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) | |
| 71 | +#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) | |
| 72 | +#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY) | |
| 73 | +#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY) | |
| 74 | + | |
| 75 | +#define __PAGE_NONE __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) | |
| 76 | +#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) | |
| 77 | +#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) | |
| 78 | +#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) | |
| 79 | +#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) | |
| 80 | +#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) | |
| 81 | +#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) | |
| 82 | 82 | |
| 83 | 83 | #endif /* __ASSEMBLY__ */ |
| 84 | 84 | |
| @@ -130,10 +130,10 @@ extern struct page *empty_zero_page; · 45 unmodified lines | ||
| 130 | 130 | #define pte_young(pte) (pte_val(pte) & PTE_AF) |
| 131 | 131 | #define pte_special(pte) (pte_val(pte) & PTE_SPECIAL) |
| 132 | 132 | #define pte_write(pte) (!(pte_val(pte) & PTE_RDONLY)) |
| 133 | −#define pte_exec(pte) (!(pte_val(pte) & PTE_XN)) | |
| 133 | +#define pte_exec(pte) (!(pte_val(pte) & PTE_UXN)) | |
| 134 | 134 | |
| 135 | 135 | #define pte_present_exec_user(pte) \ |
| 136 | − ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_XN)) == \ | |
| 136 | + ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == \ | |
| 137 | 137 | (PTE_VALID | PTE_USER)) |
| 138 | 138 | |
| 139 | 139 | #define PTE_BIT_FUNC(fn,op) \ |
| @@ -262,7 +262,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) · 122 unmodified lines | ||
| 262 | 262 | |
| 263 | 263 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) |
| 264 | 264 | { |
| 265 | − const pteval_t mask = PTE_USER | PTE_XN | PTE_RDONLY; | |
| 265 | + const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY; | |
| 266 | 266 | pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); |
| 267 | 267 | return pte; |
| 268 | 268 | } |
| @@ -43,6 +43,8 @@ · 42 unmodified lines | ||
| 43 | 43 | #else |
| 44 | 44 | #define STACK_TOP STACK_TOP_MAX |
| 45 | 45 | #endif /* CONFIG_COMPAT */ |
| 46 | + | |
| 47 | +#define ARCH_LOW_ADDRESS_LIMIT PHYS_MASK | |
| 46 | 48 | #endif /* __KERNEL__ */ |
| 47 | 49 | |
| 48 | 50 | struct debug_info { |
| @@ -14,7 +14,6 @@ · 13 unmodified lines | ||
| 14 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 15 | 15 | */ |
| 16 | 16 | #ifdef CONFIG_COMPAT |
| 17 | −#define __ARCH_WANT_COMPAT_IPC_PARSE_VERSION | |
| 18 | 17 | #define __ARCH_WANT_COMPAT_STAT64 |
| 19 | 18 | #define __ARCH_WANT_SYS_GETHOSTNAME |
| 20 | 19 | #define __ARCH_WANT_SYS_PAUSE |
| @@ -392,7 +392,7 @@ __SYSCALL(367, sys_fanotify_init) · 391 unmodified lines | ||
| 392 | 392 | __SYSCALL(368, compat_sys_fanotify_mark_wrapper) |
| 393 | 393 | __SYSCALL(369, sys_prlimit64) |
| 394 | 394 | __SYSCALL(370, sys_name_to_handle_at) |
| 395 | −__SYSCALL(371, sys_open_by_handle_at) | |
| 395 | +__SYSCALL(371, compat_sys_open_by_handle_at) | |
| 396 | 396 | __SYSCALL(372, sys_clock_adjtime) |
| 397 | 397 | __SYSCALL(373, sys_syncfs) |
| 398 | 398 | |
| @@ -613,17 +613,11 @@ enum armv8_pmuv3_perf_types { · 612 unmodified lines | ||
| 613 | 613 | ARMV8_PMUV3_PERFCTR_BUS_ACCESS = 0x19, |
| 614 | 614 | ARMV8_PMUV3_PERFCTR_MEM_ERROR = 0x1A, |
| 615 | 615 | ARMV8_PMUV3_PERFCTR_BUS_CYCLES = 0x1D, |
| 616 | − | |
| 617 | − /* | |
| 618 | − * This isn't an architected event. | |
| 619 | − * We detect this event number and use the cycle counter instead. | |
| 620 | − */ | |
| 621 | − ARMV8_PMUV3_PERFCTR_CPU_CYCLES = 0xFF, | |
| 622 | 616 | }; |
| 623 | 617 | |
| 624 | 618 | /* PMUv3 HW events mapping. */ |
| 625 | 619 | static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = { |
| 626 | − [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CPU_CYCLES, | |
| 620 | + [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES, | |
| 627 | 621 | [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED, |
| 628 | 622 | [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS, |
| 629 | 623 | [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL, |
| @@ -1106,7 +1100,7 @@ static int armv8pmu_get_event_idx(struct pmu_hw_events *cpuc, · 476 unmodified lines | ||
| 1106 | 1100 | unsigned long evtype = event->config_base & ARMV8_EVTYPE_EVENT; |
| 1107 | 1101 | |
| 1108 | 1102 | /* Always place a cycle counter into the cycle counter. */ |
| 1109 | − if (evtype == ARMV8_PMUV3_PERFCTR_CPU_CYCLES) { | |
| 1103 | + if (evtype == ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES) { | |
| 1110 | 1104 | if (test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask)) |
| 1111 | 1105 | return -EAGAIN; |
| 1112 | 1106 | |
| @@ -309,24 +309,6 @@ struct task_struct *__switch_to(struct task_struct *prev, · 308 unmodified lines | ||
| 309 | 309 | return last; |
| 310 | 310 | } |
| 311 | 311 | |
| 312 | −/* | |
| 313 | − * Fill in the task's elfregs structure for a core dump. | |
| 314 | − */ | |
| 315 | −int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs) | |
| 316 | −{ | |
| 317 | − elf_core_copy_regs(elfregs, task_pt_regs(t)); | |
| 318 | − return 1; | |
| 319 | −} | |
| 320 | − | |
| 321 | −/* | |
| 322 | − * fill in the fpe structure for a core dump... | |
| 323 | − */ | |
| 324 | −int dump_fpu (struct pt_regs *regs, struct user_fp *fp) | |
| 325 | −{ | |
| 326 | − return 0; | |
| 327 | −} | |
| 328 | −EXPORT_SYMBOL(dump_fpu); | |
| 329 | − | |
| 330 | 312 | /* |
| 331 | 313 | * Shuffle the argument into the correct register before calling the |
| 332 | 314 | * thread function. x1 is the thread argument, x2 is the pointer to |
| @@ -211,8 +211,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void) · 210 unmodified lines | ||
| 211 | 211 | * before we continue. |
| 212 | 212 | */ |
| 213 | 213 | set_cpu_online(cpu, true); |
| 214 | − while (!cpu_active(cpu)) | |
| 215 | − cpu_relax(); | |
| 214 | + complete(&cpu_running); | |
| 216 | 215 | |
| 217 | 216 | /* |
| 218 | 217 | * OK, it's off to the idle thread for us |
| @@ -80,7 +80,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) · 79 unmodified lines | ||
| 80 | 80 | #ifdef CONFIG_ZONE_DMA32 |
| 81 | 81 | /* 4GB maximum for 32-bit only capable devices */ |
| 82 | 82 | max_dma32 = min(max, MAX_DMA32_PFN); |
| 83 | − zone_size[ZONE_DMA32] = max_dma32 - min; | |
| 83 | + zone_size[ZONE_DMA32] = max(min, max_dma32) - min; | |
| 84 | 84 | #endif |
| 85 | 85 | zone_size[ZONE_NORMAL] = max - max_dma32; |
| 86 | 86 | |
| @@ -0,0 +1,33 @@ | ||
| 1 | +/* | |
| 2 | + * Port on Texas Instruments TMS320C6x architecture | |
| 3 | + * | |
| 4 | + * Copyright (C) 2004, 2009, 2010 2011 Texas Instruments Incorporated | |
| 5 | + * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) | |
| 6 | + * | |
| 7 | + * This program is free software; you can redistribute it and/or modify | |
| 8 | + * it under the terms of the GNU General Public License version 2 as | |
| 9 | + * published by the Free Software Foundation. | |
| 10 | + */ | |
| 11 | +#ifndef _ASM_C6X_SETUP_H | |
| 12 | +#define _ASM_C6X_SETUP_H | |
| 13 | + | |
| 14 | +#include <uapi/asm/setup.h> | |
| 15 | + | |
| 16 | +#ifndef __ASSEMBLY__ | |
| 17 | +extern char c6x_command_line[COMMAND_LINE_SIZE]; | |
| 18 | + | |
| 19 | +extern int c6x_add_memory(phys_addr_t start, unsigned long size); | |
| 20 | + | |
| 21 | +extern unsigned long ram_start; | |
| 22 | +extern unsigned long ram_end; | |
| 23 | + | |
| 24 | +extern int c6x_num_cores; | |
| 25 | +extern unsigned int c6x_silicon_rev; | |
| 26 | +extern unsigned int c6x_devstat; | |
| 27 | +extern unsigned char c6x_fuse_mac[6]; | |
| 28 | + | |
| 29 | +extern void machine_init(unsigned long dt_ptr); | |
| 30 | +extern void time_init(void); | |
| 31 | + | |
| 32 | +#endif /* !__ASSEMBLY__ */ | |
| 33 | +#endif /* _ASM_C6X_SETUP_H */ | |
| @@ -1,6 +1,8 @@ | ||
| 1 | 1 | # UAPI Header export list |
| 2 | 2 | include include/uapi/asm-generic/Kbuild.asm |
| 3 | 3 | |
| 4 | +generic-y += kvm_para.h | |
| 5 | + | |
| 4 | 6 | header-y += byteorder.h |
| 5 | 7 | header-y += kvm_para.h |
| 6 | 8 | header-y += ptrace.h |
| @@ -1 +0,0 @@ | ||
| 1 | −#include <asm-generic/kvm_para.h> | |
| @@ -1,33 +1,6 @@ | ||
| 1 | −/* | |
| 2 | − * Port on Texas Instruments TMS320C6x architecture | |
| 3 | − * | |
| 4 | − * Copyright (C) 2004, 2009, 2010 2011 Texas Instruments Incorporated | |
| 5 | − * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) | |
| 6 | − * | |
| 7 | − * This program is free software; you can redistribute it and/or modify | |
| 8 | − * it under the terms of the GNU General Public License version 2 as | |
| 9 | − * published by the Free Software Foundation. | |
| 10 | − */ | |
| 11 | −#ifndef _ASM_C6X_SETUP_H | |
| 12 | −#define _ASM_C6X_SETUP_H | |
| 1 | +#ifndef _UAPI_ASM_C6X_SETUP_H | |
| 2 | +#define _UAPI_ASM_C6X_SETUP_H | |
| 13 | 3 | |
| 14 | 4 | #define COMMAND_LINE_SIZE 1024 |
| 15 | 5 | |
| 16 | −#ifndef __ASSEMBLY__ | |
| 17 | −extern char c6x_command_line[COMMAND_LINE_SIZE]; | |
| 18 | − | |
| 19 | −extern int c6x_add_memory(phys_addr_t start, unsigned long size); | |
| 20 | − | |
| 21 | −extern unsigned long ram_start; | |
| 22 | −extern unsigned long ram_end; | |
| 23 | − | |
| 24 | −extern int c6x_num_cores; | |
| 25 | −extern unsigned int c6x_silicon_rev; | |
| 26 | −extern unsigned int c6x_devstat; | |
| 27 | −extern unsigned char c6x_fuse_mac[6]; | |
| 28 | − | |
| 29 | −extern void machine_init(unsigned long dt_ptr); | |
| 30 | −extern void time_init(void); | |
| 31 | − | |
| 32 | −#endif /* !__ASSEMBLY__ */ | |
| 33 | −#endif /* _ASM_C6X_SETUP_H */ | |
| 6 | +#endif /* _UAPI_ASM_C6X_SETUP_H */ | |
| @@ -277,6 +277,8 @@ work_rescheduled: · 276 unmodified lines | ||
| 277 | 277 | [A1] BNOP .S1 work_resched,5 |
| 278 | 278 | |
| 279 | 279 | work_notifysig: |
| 280 | + ;; enable interrupts for do_notify_resume() | |
| 281 | + UNMASK_INT B2 | |
| 280 | 282 | B .S2 do_notify_resume |
| 281 | 283 | LDW .D2T1 *+SP(REGS__END+8),A6 ; syscall flag |
| 282 | 284 | ADDKPC .S2 resume_userspace,B3,1 |
| @@ -427,8 +429,7 @@ ENTRY(ret_from_kernel_execve) · 144 unmodified lines | ||
| 427 | 429 | ENDPROC(ret_from_kernel_execve) |
| 428 | 430 | |
| 429 | 431 | ;; |
| 430 | − ;; These are the interrupt handlers, responsible for calling __do_IRQ() | |
| 431 | − ;; int6 is used for syscalls (see _system_call entry) | |
| 432 | + ;; These are the interrupt handlers, responsible for calling c6x_do_IRQ() | |
| 432 | 433 | ;; |
| 433 | 434 | .macro SAVE_ALL_INT |
| 434 | 435 | SAVE_ALL IRP,ITSR |
| @@ -13,6 +13,7 @@ config FRV · 12 unmodified lines | ||
| 13 | 13 | select GENERIC_CPU_DEVICES |
| 14 | 14 | select ARCH_WANT_IPC_PARSE_VERSION |
| 15 | 15 | select GENERIC_KERNEL_THREAD |
| 16 | + select GENERIC_KERNEL_EXECVE | |
| 16 | 17 | |
| 17 | 18 | config ZONE_DMA |
| 18 | 19 | bool |
| @@ -17,6 +17,8 @@ PARAMS_PHYS = 0x0207c000 · 16 unmodified lines | ||
| 17 | 17 | INITRD_PHYS = 0x02180000 |
| 18 | 18 | INITRD_VIRT = 0x02180000 |
| 19 | 19 | |
| 20 | +OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment | |
| 21 | + | |
| 20 | 22 | # |
| 21 | 23 | # If you don't define ZRELADDR above, |
| 22 | 24 | # then it defaults to ZTEXTADDR |
| @@ -32,18 +34,18 @@ Image: $(obj)/Image · 9 unmodified lines | ||
| 32 | 34 | targets: $(obj)/Image |
| 33 | 35 | |
| 34 | 36 | $(obj)/Image: vmlinux FORCE |
| 35 | − $(OBJCOPY) -O binary -R .note -R .comment -S vmlinux $@ | |
| 37 | + $(OBJCOPY) $(OBJCOPYFLAGS) -S vmlinux $@ | |
| 36 | 38 | |
| 37 | 39 | #$(obj)/Image: $(CONFIGURE) $(SYSTEM) |
| 38 | −# $(OBJCOPY) -O binary -R .note -R .comment -g -S $(SYSTEM) $@ | |
| 40 | +# $(OBJCOPY) $(OBJCOPYFLAGS) -g -S $(SYSTEM) $@ | |
| 39 | 41 | |
| 40 | 42 | bzImage: zImage |
| 41 | 43 | |
| 42 | 44 | zImage: $(CONFIGURE) compressed/$(LINUX) |
| 43 | − $(OBJCOPY) -O binary -R .note -R .comment -S compressed/$(LINUX) $@ | |
| 45 | + $(OBJCOPY) $(OBJCOPYFLAGS) -S compressed/$(LINUX) $@ | |
| 44 | 46 | |
| 45 | 47 | bootpImage: bootp/bootp |
| 46 | − $(OBJCOPY) -O binary -R .note -R .comment -S bootp/bootp $@ | |
| 48 | + $(OBJCOPY) $(OBJCOPYFLAGS) -S bootp/bootp $@ | |
| 47 | 49 | |
| 48 | 50 | compressed/$(LINUX): $(LINUX) dep |
| 49 | 51 | @$(MAKE) -C compressed $(LINUX) |
| @@ -30,7 +30,6 @@ · 29 unmodified lines | ||
| 30 | 30 | #define __ARCH_WANT_SYS_RT_SIGACTION |
| 31 | 31 | #define __ARCH_WANT_SYS_RT_SIGSUSPEND |
| 32 | 32 | #define __ARCH_WANT_SYS_EXECVE |
| 33 | −#define __ARCH_WANT_KERNEL_EXECVE | |
| 34 | 33 | |
| 35 | 34 | /* |
| 36 | 35 | * "Conditional" syscalls |
| @@ -869,11 +869,6 @@ ret_from_kernel_thread: · 868 unmodified lines | ||
| 869 | 869 | call schedule_tail |
| 870 | 870 | calll.p @(gr21,gr0) |
| 871 | 871 | or gr20,gr20,gr8 |
| 872 | − bra sys_exit | |
| 873 | − | |
| 874 | − .globl ret_from_kernel_execve | |
| 875 | −ret_from_kernel_execve: | |
| 876 | − ori gr28,0,sp | |
| 877 | 872 | bra __syscall_exit |
| 878 | 873 | |
| 879 | 874 | ################################################################################################### |
| @@ -1080,27 +1075,10 @@ __entry_return_from_kernel_interrupt: · 200 unmodified lines | ||
| 1080 | 1075 | subicc gr5,#0,gr0,icc0 |
| 1081 | 1076 | beq icc0,#0,__entry_return_direct |
| 1082 | 1077 | |
| 1083 | −__entry_preempt_need_resched: | |
| 1084 | − ldi @(gr15,#TI_FLAGS),gr4 | |
| 1085 | − andicc gr4,#_TIF_NEED_RESCHED,gr0,icc0 | |
| 1086 | − beq icc0,#1,__entry_return_direct | |
| 1087 | − | |
| 1088 | − setlos #PREEMPT_ACTIVE,gr5 | |
| 1089 | − sti gr5,@(gr15,#TI_FLAGS) | |
| 1090 | − | |
| 1091 | − andi gr23,#~PSR_PIL,gr23 | |
| 1092 | − movgs gr23,psr | |
| 1093 | − | |
| 1094 | − call schedule | |
| 1095 | − sti gr0,@(gr15,#TI_PRE_COUNT) | |
| 1096 | − | |
| 1097 | − movsg psr,gr23 | |
| 1098 | − ori gr23,#PSR_PIL_14,gr23 | |
| 1099 | − movgs gr23,psr | |
| 1100 | − bra __entry_preempt_need_resched | |
| 1101 | −#else | |
| 1102 | − bra __entry_return_direct | |
| 1078 | + subcc gr0,gr0,gr0,icc2 /* set Z and clear C */ | |
| 1079 | + call preempt_schedule_irq | |
| 1103 | 1080 | #endif |
| 1081 | + bra __entry_return_direct | |
| 1104 | 1082 | |
| 1105 | 1083 | |
| 1106 | 1084 | ############################################################################### |
| @@ -181,6 +181,9 @@ int copy_thread(unsigned long clone_flags, · 180 unmodified lines | ||
| 181 | 181 | childregs = (struct pt_regs *) |
| 182 | 182 | (task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE); |
| 183 | 183 | |
| 184 | + /* set up the userspace frame (the only place that the USP is stored) */ | |
| 185 | + *childregs = *__kernel_frame0_ptr; | |
| 186 | + | |
| 184 | 187 | p->set_child_tid = p->clear_child_tid = NULL; |
| 185 | 188 | |
| 186 | 189 | p->thread.frame = childregs; |
| @@ -191,10 +194,8 @@ int copy_thread(unsigned long clone_flags, · 4 unmodified lines | ||
| 191 | 194 | p->thread.frame0 = childregs; |
| 192 | 195 | |
| 193 | 196 | if (unlikely(!regs)) { |
| 194 | − memset(childregs, 0, sizeof(struct pt_regs)); | |
| 195 | 197 | childregs->gr9 = usp; /* function */ |
| 196 | 198 | childregs->gr8 = arg; |
| 197 | − childregs->psr = PSR_S; | |
| 198 | 199 | p->thread.pc = (unsigned long) ret_from_kernel_thread; |
| 199 | 200 | save_user_regs(p->thread.user); |
| 200 | 201 | return 0; |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | |
| 12 | 12 | #include <linux/types.h> |
| 13 | 13 | #include <linux/slab.h> |
| 14 | +#include <linux/export.h> | |
| 14 | 15 | #include <linux/dma-mapping.h> |
| 15 | 16 | #include <linux/list.h> |
| 16 | 17 | #include <linux/pci.h> |
| @@ -2,7 +2,8 @@ · 1 unmodified line | ||
| 2 | 2 | #define __ARCH_H8300_CACHE_H |
| 3 | 3 | |
| 4 | 4 | /* bytes per L1 cache line */ |
| 5 | −#define L1_CACHE_BYTES 4 | |
| 5 | +#define L1_CACHE_SHIFT 2 | |
| 6 | +#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) | |
| 6 | 7 | |
| 7 | 8 | /* m68k-elf-gcc 2.95.2 doesn't like these */ |
| 8 | 9 | |
| @@ -637,7 +637,6 @@ mem_init (void) · 636 unmodified lines | ||
| 637 | 637 | |
| 638 | 638 | high_memory = __va(max_low_pfn * PAGE_SIZE); |
| 639 | 639 | |
| 640 | − reset_zone_present_pages(); | |
| 641 | 640 | for_each_online_pgdat(pgdat) |
| 642 | 641 | if (pgdat->bdata->node_bootmem_map) |
| 643 | 642 | totalram_pages += free_all_bootmem_node(pgdat); |
| @@ -41,7 +41,7 @@ struct k_sigaction { · 40 unmodified lines | ||
| 41 | 41 | static inline void sigaddset(sigset_t *set, int _sig) |
| 42 | 42 | { |
| 43 | 43 | asm ("bfset %0{%1,#1}" |
| 44 | − : "+od" (*set) | |
| 44 | + : "+o" (*set) | |
| 45 | 45 | : "id" ((_sig - 1) ^ 31) |
| 46 | 46 | : "cc"); |
| 47 | 47 | } |
| @@ -49,7 +49,7 @@ static inline void sigaddset(sigset_t *set, int _sig) · 1 unmodified line | ||
| 49 | 49 | static inline void sigdelset(sigset_t *set, int _sig) |
| 50 | 50 | { |
| 51 | 51 | asm ("bfclr %0{%1,#1}" |
| 52 | − : "+od" (*set) | |
| 52 | + : "+o" (*set) | |
| 53 | 53 | : "id" ((_sig - 1) ^ 31) |
| 54 | 54 | : "cc"); |
| 55 | 55 | } |
| @@ -65,7 +65,7 @@ static inline int __gen_sigismember(sigset_t *set, int _sig) · 9 unmodified lines | ||
| 65 | 65 | int ret; |
| 66 | 66 | asm ("bfextu %1{%2,#1},%0" |
| 67 | 67 | : "=d" (ret) |
| 68 | − : "od" (*set), "id" ((_sig-1) ^ 31) | |
| 68 | + : "o" (*set), "id" ((_sig-1) ^ 31) | |
| 69 | 69 | : "cc"); |
| 70 | 70 | return ret; |
| 71 | 71 | } |
| @@ -111,7 +111,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) · 110 unmodified lines | ||
| 111 | 111 | |
| 112 | 112 | /* It is more difficult to avoid calling this function than to |
| 113 | 113 | call it and ignore errors. */ |
| 114 | − if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1)) | |
| 114 | + if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1) == -EFAULT) | |
| 115 | 115 | goto badframe; |
| 116 | 116 | |
| 117 | 117 | return rval; |
| @@ -30,6 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | * measurement, and debugging facilities. |
| 31 | 31 | */ |
| 32 | 32 | |
| 33 | +#include <linux/irqflags.h> | |
| 33 | 34 | #include <asm/octeon/cvmx.h> |
| 34 | 35 | #include <asm/octeon/cvmx-l2c.h> |
| 35 | 36 | #include <asm/octeon/cvmx-spinlock.h> |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | */ |
| 12 | 12 | #include <linux/init.h> |
| 13 | 13 | #include <linux/kernel.h> |
| 14 | +#include <linux/irqflags.h> | |
| 14 | 15 | |
| 15 | 16 | #include <asm/bcache.h> |
| 16 | 17 | |
| @@ -14,7 +14,6 @@ · 13 unmodified lines | ||
| 14 | 14 | #endif |
| 15 | 15 | |
| 16 | 16 | #include <linux/compiler.h> |
| 17 | −#include <linux/irqflags.h> | |
| 18 | 17 | #include <linux/types.h> |
| 19 | 18 | #include <asm/barrier.h> |
| 20 | 19 | #include <asm/byteorder.h> /* sigh ... */ |
| @@ -44,6 +43,24 @@ · 23 unmodified lines | ||
| 44 | 43 | #define smp_mb__before_clear_bit() smp_mb__before_llsc() |
| 45 | 44 | #define smp_mb__after_clear_bit() smp_llsc_mb() |
| 46 | 45 | |
| 46 | + | |
| 47 | +/* | |
| 48 | + * These are the "slower" versions of the functions and are in bitops.c. | |
| 49 | + * These functions call raw_local_irq_{save,restore}(). | |
| 50 | + */ | |
| 51 | +void __mips_set_bit(unsigned long nr, volatile unsigned long *addr); | |
| 52 | +void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr); | |
| 53 | +void __mips_change_bit(unsigned long nr, volatile unsigned long *addr); | |
| 54 | +int __mips_test_and_set_bit(unsigned long nr, | |
| 55 | + volatile unsigned long *addr); | |
| 56 | +int __mips_test_and_set_bit_lock(unsigned long nr, | |
| 57 | + volatile unsigned long *addr); | |
| 58 | +int __mips_test_and_clear_bit(unsigned long nr, | |
| 59 | + volatile unsigned long *addr); | |
| 60 | +int __mips_test_and_change_bit(unsigned long nr, | |
| 61 | + volatile unsigned long *addr); | |
| 62 | + | |
| 63 | + | |
| 47 | 64 | /* |
| 48 | 65 | * set_bit - Atomically set a bit in memory |
| 49 | 66 | * @nr: the bit to set |
| @@ -57,7 +74,7 @@ · 7 unmodified lines | ||
| 57 | 74 | static inline void set_bit(unsigned long nr, volatile unsigned long *addr) |
| 58 | 75 | { |
| 59 | 76 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); |
| 60 | − unsigned short bit = nr & SZLONG_MASK; | |
| 77 | + int bit = nr & SZLONG_MASK; | |
| 61 | 78 | unsigned long temp; |
| 62 | 79 | |
| 63 | 80 | if (kernel_uses_llsc && R10000_LLSC_WAR) { |
| @@ -92,17 +109,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) · 28 unmodified lines | ||
| 92 | 109 | : "=&r" (temp), "+m" (*m) |
| 93 | 110 | : "ir" (1UL << bit)); |
| 94 | 111 | } while (unlikely(!temp)); |
| 95 | − } else { | |
| 96 | − volatile unsigned long *a = addr; | |
| 97 | − unsigned long mask; | |
| 98 | − unsigned long flags; | |
| 99 | − | |
| 100 | − a += nr >> SZLONG_LOG; | |
| 101 | − mask = 1UL << bit; | |
| 102 | − raw_local_irq_save(flags); | |
| 103 | − *a |= mask; | |
| 104 | − raw_local_irq_restore(flags); | |
| 105 | − } | |
| 112 | + } else | |
| 113 | + __mips_set_bit(nr, addr); | |
| 106 | 114 | } |
| 107 | 115 | |
| 108 | 116 | /* |
| @@ -118,7 +126,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) · 9 unmodified lines | ||
| 118 | 126 | static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) |
| 119 | 127 | { |
| 120 | 128 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); |
| 121 | − unsigned short bit = nr & SZLONG_MASK; | |
| 129 | + int bit = nr & SZLONG_MASK; | |
| 122 | 130 | unsigned long temp; |
| 123 | 131 | |
| 124 | 132 | if (kernel_uses_llsc && R10000_LLSC_WAR) { |
| @@ -153,17 +161,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) · 28 unmodified lines | ||
| 153 | 161 | : "=&r" (temp), "+m" (*m) |
| 154 | 162 | : "ir" (~(1UL << bit))); |
| 155 | 163 | } while (unlikely(!temp)); |
| 156 | − } else { | |
| 157 | − volatile unsigned long *a = addr; | |
| 158 | − unsigned long mask; | |
| 159 | − unsigned long flags; | |
| 160 | − | |
| 161 | − a += nr >> SZLONG_LOG; | |
| 162 | − mask = 1UL << bit; | |
| 163 | − raw_local_irq_save(flags); | |
| 164 | − *a &= ~mask; | |
| 165 | − raw_local_irq_restore(flags); | |
| 166 | − } | |
| 164 | + } else | |
| 165 | + __mips_clear_bit(nr, addr); | |
| 167 | 166 | } |
| 168 | 167 | |
| 169 | 168 | /* |
| @@ -191,7 +190,7 @@ static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *ad · 21 unmodified lines | ||
| 191 | 190 | */ |
| 192 | 191 | static inline void change_bit(unsigned long nr, volatile unsigned long *addr) |
| 193 | 192 | { |
| 194 | − unsigned short bit = nr & SZLONG_MASK; | |
| 193 | + int bit = nr & SZLONG_MASK; | |
| 195 | 194 | |
| 196 | 195 | if (kernel_uses_llsc && R10000_LLSC_WAR) { |
| 197 | 196 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); |
| @@ -220,17 +219,8 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) · 22 unmodified lines | ||
| 220 | 219 | : "=&r" (temp), "+m" (*m) |
| 221 | 220 | : "ir" (1UL << bit)); |
| 222 | 221 | } while (unlikely(!temp)); |
| 223 | − } else { | |
| 224 | − volatile unsigned long *a = addr; | |
| 225 | − unsigned long mask; | |
| 226 | − unsigned long flags; | |
| 227 | − | |
| 228 | − a += nr >> SZLONG_LOG; | |
| 229 | − mask = 1UL << bit; | |
| 230 | − raw_local_irq_save(flags); | |
| 231 | − *a ^= mask; | |
| 232 | − raw_local_irq_restore(flags); | |
| 233 | − } | |
| 222 | + } else | |
| 223 | + __mips_change_bit(nr, addr); | |
| 234 | 224 | } |
| 235 | 225 | |
| 236 | 226 | /* |
| @@ -244,7 +234,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) · 7 unmodified lines | ||
| 244 | 234 | static inline int test_and_set_bit(unsigned long nr, |
| 245 | 235 | volatile unsigned long *addr) |
| 246 | 236 | { |
| 247 | − unsigned short bit = nr & SZLONG_MASK; | |
| 237 | + int bit = nr & SZLONG_MASK; | |
| 248 | 238 | unsigned long res; |
| 249 | 239 | |
| 250 | 240 | smp_mb__before_llsc(); |
| @@ -281,18 +271,8 @@ static inline int test_and_set_bit(unsigned long nr, · 30 unmodified lines | ||
| 281 | 271 | } while (unlikely(!res)); |
| 282 | 272 | |
| 283 | 273 | res = temp & (1UL << bit); |
| 284 | − } else { | |
| 285 | − volatile unsigned long *a = addr; | |
| 286 | − unsigned long mask; | |
| 287 | − unsigned long flags; | |
| 288 | − | |
| 289 | − a += nr >> SZLONG_LOG; | |
| 290 | − mask = 1UL << bit; | |
| 291 | − raw_local_irq_save(flags); | |
| 292 | − res = (mask & *a); | |
| 293 | − *a |= mask; | |
| 294 | − raw_local_irq_restore(flags); | |
| 295 | − } | |
| 274 | + } else | |
| 275 | + res = __mips_test_and_set_bit(nr, addr); | |
| 296 | 276 | |
| 297 | 277 | smp_llsc_mb(); |
| 298 | 278 | |
| @@ -310,7 +290,7 @@ static inline int test_and_set_bit(unsigned long nr, · 11 unmodified lines | ||
| 310 | 290 | static inline int test_and_set_bit_lock(unsigned long nr, |
| 311 | 291 | volatile unsigned long *addr) |
| 312 | 292 | { |
| 313 | − unsigned short bit = nr & SZLONG_MASK; | |
| 293 | + int bit = nr & SZLONG_MASK; | |
| 314 | 294 | unsigned long res; |
| 315 | 295 | |
| 316 | 296 | if (kernel_uses_llsc && R10000_LLSC_WAR) { |
| @@ -345,18 +325,8 @@ static inline int test_and_set_bit_lock(unsigned long nr, · 28 unmodified lines | ||
| 345 | 325 | } while (unlikely(!res)); |
| 346 | 326 | |
| 347 | 327 | res = temp & (1UL << bit); |
| 348 | − } else { | |
| 349 | − volatile unsigned long *a = addr; | |
| 350 | − unsigned long mask; | |
| 351 | − unsigned long flags; | |
| 352 | − | |
| 353 | − a += nr >> SZLONG_LOG; | |
| 354 | − mask = 1UL << bit; | |
| 355 | − raw_local_irq_save(flags); | |
| 356 | − res = (mask & *a); | |
| 357 | − *a |= mask; | |
| 358 | − raw_local_irq_restore(flags); | |
| 359 | − } | |
| 328 | + } else | |
| 329 | + res = __mips_test_and_set_bit_lock(nr, addr); | |
| 360 | 330 | |
| 361 | 331 | smp_llsc_mb(); |
| 362 | 332 | |
| @@ -373,7 +343,7 @@ static inline int test_and_set_bit_lock(unsigned long nr, · 10 unmodified lines | ||
| 373 | 343 | static inline int test_and_clear_bit(unsigned long nr, |
| 374 | 344 | volatile unsigned long *addr) |
| 375 | 345 | { |
| 376 | − unsigned short bit = nr & SZLONG_MASK; | |
| 346 | + int bit = nr & SZLONG_MASK; | |
| 377 | 347 | unsigned long res; |
| 378 | 348 | |
| 379 | 349 | smp_mb__before_llsc(); |
| @@ -428,18 +398,8 @@ static inline int test_and_clear_bit(unsigned long nr, · 48 unmodified lines | ||
| 428 | 398 | } while (unlikely(!res)); |
| 429 | 399 | |
| 430 | 400 | res = temp & (1UL << bit); |
| 431 | − } else { | |
| 432 | − volatile unsigned long *a = addr; | |
| 433 | − unsigned long mask; | |
| 434 | − unsigned long flags; | |
| 435 | − | |
| 436 | − a += nr >> SZLONG_LOG; | |
| 437 | − mask = 1UL << bit; | |
| 438 | − raw_local_irq_save(flags); | |
| 439 | − res = (mask & *a); | |
| 440 | − *a &= ~mask; | |
| 441 | − raw_local_irq_restore(flags); | |
| 442 | − } | |
| 401 | + } else | |
| 402 | + res = __mips_test_and_clear_bit(nr, addr); | |
| 443 | 403 | |
| 444 | 404 | smp_llsc_mb(); |
| 445 | 405 | |
| @@ -457,7 +417,7 @@ static inline int test_and_clear_bit(unsigned long nr, · 11 unmodified lines | ||
| 457 | 417 | static inline int test_and_change_bit(unsigned long nr, |
| 458 | 418 | volatile unsigned long *addr) |
| 459 | 419 | { |
| 460 | − unsigned short bit = nr & SZLONG_MASK; | |
| 420 | + int bit = nr & SZLONG_MASK; | |
| 461 | 421 | unsigned long res; |
| 462 | 422 | |
| 463 | 423 | smp_mb__before_llsc(); |
| @@ -494,18 +454,8 @@ static inline int test_and_change_bit(unsigned long nr, · 30 unmodified lines | ||
| 494 | 454 | } while (unlikely(!res)); |
| 495 | 455 | |
| 496 | 456 | res = temp & (1UL << bit); |
| 497 | − } else { | |
| 498 | − volatile unsigned long *a = addr; | |
| 499 | − unsigned long mask; | |
| 500 | − unsigned long flags; | |
| 501 | − | |
| 502 | − a += nr >> SZLONG_LOG; | |
| 503 | − mask = 1UL << bit; | |
| 504 | − raw_local_irq_save(flags); | |
| 505 | − res = (mask & *a); | |
| 506 | − *a ^= mask; | |
| 507 | − raw_local_irq_restore(flags); | |
| 508 | − } | |
| 457 | + } else | |
| 458 | + res = __mips_test_and_change_bit(nr, addr); | |
| 509 | 459 | |
| 510 | 460 | smp_llsc_mb(); |
| 511 | 461 | |
| @@ -290,7 +290,7 @@ struct compat_shmid64_ds { · 289 unmodified lines | ||
| 290 | 290 | |
| 291 | 291 | static inline int is_compat_task(void) |
| 292 | 292 | { |
| 293 | − return test_thread_flag(TIF_32BIT); | |
| 293 | + return test_thread_flag(TIF_32BIT_ADDR); | |
| 294 | 294 | } |
| 295 | 295 | |
| 296 | 296 | #endif /* _ASM_COMPAT_H */ |
| @@ -95,7 +95,17 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, · 94 unmodified lines | ||
| 95 | 95 | pte_t *ptep, pte_t pte, |
| 96 | 96 | int dirty) |
| 97 | 97 | { |
| 98 | − return ptep_set_access_flags(vma, addr, ptep, pte, dirty); | |
| 98 | + int changed = !pte_same(*ptep, pte); | |
| 99 | + | |
| 100 | + if (changed) { | |
| 101 | + set_pte_at(vma->vm_mm, addr, ptep, pte); | |
| 102 | + /* | |
| 103 | + * There could be some standard sized pages in there, | |
| 104 | + * get them all. | |
| 105 | + */ | |
| 106 | + flush_tlb_range(vma, addr, addr + HPAGE_SIZE); | |
| 107 | + } | |
| 108 | + return changed; | |
| 99 | 109 | } |
| 100 | 110 | |
| 101 | 111 | static inline pte_t huge_ptep_get(pte_t *ptep) |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/compiler.h> |
| 16 | 16 | #include <linux/kernel.h> |
| 17 | 17 | #include <linux/types.h> |
| 18 | +#include <linux/irqflags.h> | |
| 18 | 19 | |
| 19 | 20 | #include <asm/addrspace.h> |
| 20 | 21 | #include <asm/bug.h> |
| @@ -16,83 +16,13 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/compiler.h> |
| 17 | 17 | #include <asm/hazards.h> |
| 18 | 18 | |
| 19 | −__asm__( | |
| 20 | − " .macro arch_local_irq_enable \n" | |
| 21 | − " .set push \n" | |
| 22 | − " .set reorder \n" | |
| 23 | − " .set noat \n" | |
| 24 | −#ifdef CONFIG_MIPS_MT_SMTC | |
| 25 | − " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n" | |
| 26 | − " ori $1, 0x400 \n" | |
| 27 | − " xori $1, 0x400 \n" | |
| 28 | − " mtc0 $1, $2, 1 \n" | |
| 29 | −#elif defined(CONFIG_CPU_MIPSR2) | |
| 30 | − " ei \n" | |
| 31 | −#else | |
| 32 | − " mfc0 $1,$12 \n" | |
| 33 | − " ori $1,0x1f \n" | |
| 34 | − " xori $1,0x1e \n" | |
| 35 | − " mtc0 $1,$12 \n" | |
| 36 | −#endif | |
| 37 | − " irq_enable_hazard \n" | |
| 38 | − " .set pop \n" | |
| 39 | − " .endm"); | |
| 19 | +#if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC) | |
| 40 | 20 | |
| 41 | −extern void smtc_ipi_replay(void); | |
| 42 | − | |
| 43 | −static inline void arch_local_irq_enable(void) | |
| 44 | −{ | |
| 45 | −#ifdef CONFIG_MIPS_MT_SMTC | |
| 46 | − /* | |
| 47 | − * SMTC kernel needs to do a software replay of queued | |
| 48 | − * IPIs, at the cost of call overhead on each local_irq_enable() | |
| 49 | − */ | |
| 50 | − smtc_ipi_replay(); | |
| 51 | −#endif | |
| 52 | − __asm__ __volatile__( | |
| 53 | − "arch_local_irq_enable" | |
| 54 | − : /* no outputs */ | |
| 55 | − : /* no inputs */ | |
| 56 | − : "memory"); | |
| 57 | −} | |
| 58 | − | |
| 59 | − | |
| 60 | −/* | |
| 61 | − * For cli() we have to insert nops to make sure that the new value | |
| 62 | − * has actually arrived in the status register before the end of this | |
| 63 | − * macro. | |
| 64 | − * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs | |
| 65 | − * no nops at all. | |
| 66 | − */ | |
| 67 | −/* | |
| 68 | − * For TX49, operating only IE bit is not enough. | |
| 69 | − * | |
| 70 | − * If mfc0 $12 follows store and the mfc0 is last instruction of a | |
| 71 | − * page and fetching the next instruction causes TLB miss, the result | |
| 72 | − * of the mfc0 might wrongly contain EXL bit. | |
| 73 | − * | |
| 74 | − * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008 | |
| 75 | − * | |
| 76 | − * Workaround: mask EXL bit of the result or place a nop before mfc0. | |
| 77 | − */ | |
| 78 | 21 | __asm__( |
| 79 | 22 | " .macro arch_local_irq_disable\n" |
| 80 | 23 | " .set push \n" |
| 81 | 24 | " .set noat \n" |
| 82 | −#ifdef CONFIG_MIPS_MT_SMTC | |
| 83 | − " mfc0 $1, $2, 1 \n" | |
| 84 | − " ori $1, 0x400 \n" | |
| 85 | − " .set noreorder \n" | |
| 86 | − " mtc0 $1, $2, 1 \n" | |
| 87 | −#elif defined(CONFIG_CPU_MIPSR2) | |
| 88 | 25 | " di \n" |
| 89 | −#else | |
| 90 | − " mfc0 $1,$12 \n" | |
| 91 | − " ori $1,0x1f \n" | |
| 92 | − " xori $1,0x1f \n" | |
| 93 | − " .set noreorder \n" | |
| 94 | − " mtc0 $1,$12 \n" | |
| 95 | −#endif | |
| 96 | 26 | " irq_disable_hazard \n" |
| 97 | 27 | " .set pop \n" |
| 98 | 28 | " .endm \n"); |
| @@ -106,46 +36,14 @@ static inline void arch_local_irq_disable(void) · 7 unmodified lines | ||
| 106 | 36 | : "memory"); |
| 107 | 37 | } |
| 108 | 38 | |
| 109 | −__asm__( | |
| 110 | − " .macro arch_local_save_flags flags \n" | |
| 111 | − " .set push \n" | |
| 112 | − " .set reorder \n" | |
| 113 | −#ifdef CONFIG_MIPS_MT_SMTC | |
| 114 | − " mfc0 \\flags, $2, 1 \n" | |
| 115 | −#else | |
| 116 | − " mfc0 \\flags, $12 \n" | |
| 117 | −#endif | |
| 118 | − " .set pop \n" | |
| 119 | − " .endm \n"); | |
| 120 | − | |
| 121 | −static inline unsigned long arch_local_save_flags(void) | |
| 122 | −{ | |
| 123 | − unsigned long flags; | |
| 124 | − asm volatile("arch_local_save_flags %0" : "=r" (flags)); | |
| 125 | − return flags; | |
| 126 | −} | |
| 127 | 39 | |
| 128 | 40 | __asm__( |
| 129 | 41 | " .macro arch_local_irq_save result \n" |
| 130 | 42 | " .set push \n" |
| 131 | 43 | " .set reorder \n" |
| 132 | 44 | " .set noat \n" |
| 133 | −#ifdef CONFIG_MIPS_MT_SMTC | |
| 134 | − " mfc0 \\result, $2, 1 \n" | |
| 135 | − " ori $1, \\result, 0x400 \n" | |
| 136 | − " .set noreorder \n" | |
| 137 | − " mtc0 $1, $2, 1 \n" | |
| 138 | − " andi \\result, \\result, 0x400 \n" | |
| 139 | −#elif defined(CONFIG_CPU_MIPSR2) | |
| 140 | 45 | " di \\result \n" |
| 141 | 46 | " andi \\result, 1 \n" |
| 142 | −#else | |
| 143 | − " mfc0 \\result, $12 \n" | |
| 144 | − " ori $1, \\result, 0x1f \n" | |
| 145 | − " xori $1, 0x1f \n" | |
| 146 | − " .set noreorder \n" | |
| 147 | − " mtc0 $1, $12 \n" | |
| 148 | −#endif | |
| 149 | 47 | " irq_disable_hazard \n" |
| 150 | 48 | " .set pop \n" |
| 151 | 49 | " .endm \n"); |
| @@ -160,61 +58,37 @@ static inline unsigned long arch_local_irq_save(void) · 8 unmodified lines | ||
| 160 | 58 | return flags; |
| 161 | 59 | } |
| 162 | 60 | |
| 61 | + | |
| 163 | 62 | __asm__( |
| 164 | 63 | " .macro arch_local_irq_restore flags \n" |
| 165 | 64 | " .set push \n" |
| 166 | 65 | " .set noreorder \n" |
| 167 | 66 | " .set noat \n" |
| 168 | −#ifdef CONFIG_MIPS_MT_SMTC | |
| 169 | − "mfc0 $1, $2, 1 \n" | |
| 170 | − "andi \\flags, 0x400 \n" | |
| 171 | − "ori $1, 0x400 \n" | |
| 172 | − "xori $1, 0x400 \n" | |
| 173 | − "or \\flags, $1 \n" | |
| 174 | − "mtc0 \\flags, $2, 1 \n" | |
| 175 | −#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) | |
| 67 | +#if defined(CONFIG_IRQ_CPU) | |
| 176 | 68 | /* |
| 177 | 69 | * Slow, but doesn't suffer from a relatively unlikely race |
| 178 | 70 | * condition we're having since days 1. |
| 179 | 71 | */ |
| 180 | 72 | " beqz \\flags, 1f \n" |
| 181 | − " di \n" | |
| 73 | + " di \n" | |
| 182 | 74 | " ei \n" |
| 183 | 75 | "1: \n" |
| 184 | −#elif defined(CONFIG_CPU_MIPSR2) | |
| 76 | +#else | |
| 185 | 77 | /* |
| 186 | 78 | * Fast, dangerous. Life is fun, life is good. |
| 187 | 79 | */ |
| 188 | 80 | " mfc0 $1, $12 \n" |
| 189 | 81 | " ins $1, \\flags, 0, 1 \n" |
| 190 | 82 | " mtc0 $1, $12 \n" |
| 191 | −#else | |
| 192 | − " mfc0 $1, $12 \n" | |
| 193 | − " andi \\flags, 1 \n" | |
| 194 | − " ori $1, 0x1f \n" | |
| 195 | − " xori $1, 0x1f \n" | |
| 196 | − " or \\flags, $1 \n" | |
| 197 | − " mtc0 \\flags, $12 \n" | |
| 198 | 83 | #endif |
| 199 | 84 | " irq_disable_hazard \n" |
| 200 | 85 | " .set pop \n" |
| 201 | 86 | " .endm \n"); |
| 202 | 87 | |
| 203 | − | |
| 204 | 88 | static inline void arch_local_irq_restore(unsigned long flags) |
| 205 | 89 | { |
| 206 | 90 | unsigned long __tmp1; |
| 207 | 91 | |
| 208 | −#ifdef CONFIG_MIPS_MT_SMTC | |
| 209 | − /* | |
| 210 | − * SMTC kernel needs to do a software replay of queued | |
| 211 | − * IPIs, at the cost of branch and call overhead on each | |
| 212 | − * local_irq_restore() | |
| 213 | − */ | |
| 214 | − if (unlikely(!(flags & 0x0400))) | |
| 215 | − smtc_ipi_replay(); | |
| 216 | −#endif | |
| 217 | − | |
| 218 | 92 | __asm__ __volatile__( |
| 219 | 93 | "arch_local_irq_restore\t%0" |
| 220 | 94 | : "=r" (__tmp1) |
| @@ -232,6 +106,75 @@ static inline void __arch_local_irq_restore(unsigned long flags) · 11 unmodified lines | ||
| 232 | 106 | : "0" (flags) |
| 233 | 107 | : "memory"); |
| 234 | 108 | } |
| 109 | +#else | |
| 110 | +/* Functions that require preempt_{dis,en}able() are in mips-atomic.c */ | |
| 111 | +void arch_local_irq_disable(void); | |
| 112 | +unsigned long arch_local_irq_save(void); | |
| 113 | +void arch_local_irq_restore(unsigned long flags); | |
| 114 | +void __arch_local_irq_restore(unsigned long flags); | |
| 115 | +#endif /* if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC) */ | |
| 116 | + | |
| 117 | + | |
| 118 | +__asm__( | |
| 119 | + " .macro arch_local_irq_enable \n" | |
| 120 | + " .set push \n" | |
| 121 | + " .set reorder \n" | |
| 122 | + " .set noat \n" | |
| 123 | +#ifdef CONFIG_MIPS_MT_SMTC | |
| 124 | + " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n" | |
| 125 | + " ori $1, 0x400 \n" | |
| 126 | + " xori $1, 0x400 \n" | |
| 127 | + " mtc0 $1, $2, 1 \n" | |
| 128 | +#elif defined(CONFIG_CPU_MIPSR2) | |
| 129 | + " ei \n" | |
| 130 | +#else | |
| 131 | + " mfc0 $1,$12 \n" | |
| 132 | + " ori $1,0x1f \n" | |
| 133 | + " xori $1,0x1e \n" | |
| 134 | + " mtc0 $1,$12 \n" | |
| 135 | +#endif | |
| 136 | + " irq_enable_hazard \n" | |
| 137 | + " .set pop \n" | |
| 138 | + " .endm"); | |
| 139 | + | |
| 140 | +extern void smtc_ipi_replay(void); | |
| 141 | + | |
| 142 | +static inline void arch_local_irq_enable(void) | |
| 143 | +{ | |
| 144 | +#ifdef CONFIG_MIPS_MT_SMTC | |
| 145 | + /* | |
| 146 | + * SMTC kernel needs to do a software replay of queued | |
| 147 | + * IPIs, at the cost of call overhead on each local_irq_enable() | |
| 148 | + */ | |
| 149 | + smtc_ipi_replay(); | |
| 150 | +#endif | |
| 151 | + __asm__ __volatile__( | |
| 152 | + "arch_local_irq_enable" | |
| 153 | + : /* no outputs */ | |
| 154 | + : /* no inputs */ | |
| 155 | + : "memory"); | |
| 156 | +} | |
| 157 | + | |
| 158 | + | |
| 159 | +__asm__( | |
| 160 | + " .macro arch_local_save_flags flags \n" | |
| 161 | + " .set push \n" | |
| 162 | + " .set reorder \n" | |
| 163 | +#ifdef CONFIG_MIPS_MT_SMTC | |
| 164 | + " mfc0 \\flags, $2, 1 \n" | |
| 165 | +#else | |
| 166 | + " mfc0 \\flags, $12 \n" | |
| 167 | +#endif | |
| 168 | + " .set pop \n" | |
| 169 | + " .endm \n"); | |
| 170 | + | |
| 171 | +static inline unsigned long arch_local_save_flags(void) | |
| 172 | +{ | |
| 173 | + unsigned long flags; | |
| 174 | + asm volatile("arch_local_save_flags %0" : "=r" (flags)); | |
| 175 | + return flags; | |
| 176 | +} | |
| 177 | + | |
| 235 | 178 | |
| 236 | 179 | static inline int arch_irqs_disabled_flags(unsigned long flags) |
| 237 | 180 | { |
| @@ -245,7 +188,7 @@ static inline int arch_irqs_disabled_flags(unsigned long flags) · 7 unmodified lines | ||
| 245 | 188 | #endif |
| 246 | 189 | } |
| 247 | 190 | |
| 248 | −#endif | |
| 191 | +#endif /* #ifndef __ASSEMBLY__ */ | |
| 249 | 192 | |
| 250 | 193 | /* |
| 251 | 194 | * Do the CPU's IRQ-state tracing from assembly code. |
| @@ -112,12 +112,6 @@ register struct thread_info *__current_thread_info __asm__("$28"); · 111 unmodified lines | ||
| 112 | 112 | #define TIF_LOAD_WATCH 25 /* If set, load watch registers */ |
| 113 | 113 | #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ |
| 114 | 114 | |
| 115 | −#ifdef CONFIG_MIPS32_O32 | |
| 116 | −#define TIF_32BIT TIF_32BIT_REGS | |
| 117 | −#elif defined(CONFIG_MIPS32_N32) | |
| 118 | −#define TIF_32BIT _TIF_32BIT_ADDR | |
| 119 | −#endif /* CONFIG_MIPS32_O32 */ | |
| 120 | − | |
| 121 | 115 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) |
| 122 | 116 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) |
| 123 | 117 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) |
| @@ -510,7 +510,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) · 509 unmodified lines | ||
| 510 | 510 | c->cputype = CPU_R3000A; |
| 511 | 511 | __cpu_name[cpu] = "R3000A"; |
| 512 | 512 | } |
| 513 | − break; | |
| 514 | 513 | } else { |
| 515 | 514 | c->cputype = CPU_R3000; |
| 516 | 515 | __cpu_name[cpu] = "R3000"; |
| @@ -36,6 +36,11 @@ FEXPORT(ret_from_exception) · 35 unmodified lines | ||
| 36 | 36 | FEXPORT(ret_from_irq) |
| 37 | 37 | LONG_S s0, TI_REGS($28) |
| 38 | 38 | FEXPORT(__ret_from_irq) |
| 39 | +/* | |
| 40 | + * We can be coming here from a syscall done in the kernel space, | |
| 41 | + * e.g. a failed kernel_execve(). | |
| 42 | + */ | |
| 43 | +resume_userspace_check: | |
| 39 | 44 | LONG_L t0, PT_STATUS(sp) # returning to kernel mode? |
| 40 | 45 | andi t0, t0, KU_USER |
| 41 | 46 | beqz t0, resume_kernel |
| @@ -162,7 +167,7 @@ work_notifysig: # deal with pending signals and · 120 unmodified lines | ||
| 162 | 167 | move a0, sp |
| 163 | 168 | li a1, 0 |
| 164 | 169 | jal do_notify_resume # a2 already loaded |
| 165 | − j resume_userspace | |
| 170 | + j resume_userspace_check | |
| 166 | 171 | |
| 167 | 172 | FEXPORT(syscall_exit_partial) |
| 168 | 173 | local_irq_disable # make sure need_resched doesn't |
| @@ -397,14 +397,14 @@ EXPORT(sysn32_call_table) · 396 unmodified lines | ||
| 397 | 397 | PTR sys_timerfd_create |
| 398 | 398 | PTR compat_sys_timerfd_gettime /* 6285 */ |
| 399 | 399 | PTR compat_sys_timerfd_settime |
| 400 | − PTR sys_signalfd4 | |
| 400 | + PTR compat_sys_signalfd4 | |
| 401 | 401 | PTR sys_eventfd2 |
| 402 | 402 | PTR sys_epoll_create1 |
| 403 | 403 | PTR sys_dup3 /* 6290 */ |
| 404 | 404 | PTR sys_pipe2 |
| 405 | 405 | PTR sys_inotify_init1 |
| 406 | − PTR sys_preadv | |
| 407 | − PTR sys_pwritev | |
| 406 | + PTR compat_sys_preadv | |
| 407 | + PTR compat_sys_pwritev | |
| 408 | 408 | PTR compat_sys_rt_tgsigqueueinfo /* 6295 */ |
| 409 | 409 | PTR sys_perf_event_open |
| 410 | 410 | PTR sys_accept4 |
| @@ -79,7 +79,7 @@ static struct resource data_resource = { .name = "Kernel data", }; · 78 unmodified lines | ||
| 79 | 79 | void __init add_memory_region(phys_t start, phys_t size, long type) |
| 80 | 80 | { |
| 81 | 81 | int x = boot_mem_map.nr_map; |
| 82 | − struct boot_mem_map_entry *prev = boot_mem_map.map + x - 1; | |
| 82 | + int i; | |
| 83 | 83 | |
| 84 | 84 | /* Sanity check */ |
| 85 | 85 | if (start + size < start) { |
| @@ -88,15 +88,29 @@ void __init add_memory_region(phys_t start, phys_t size, long type) · 2 unmodified lines | ||
| 88 | 88 | } |
| 89 | 89 | |
| 90 | 90 | /* |
| 91 | − * Try to merge with previous entry if any. This is far less than | |
| 92 | − * perfect but is sufficient for most real world cases. | |
| 91 | + * Try to merge with existing entry, if any. | |
| 93 | 92 | */ |
| 94 | − if (x && prev->addr + prev->size == start && prev->type == type) { | |
| 95 | − prev->size += size; | |
| 93 | + for (i = 0; i < boot_mem_map.nr_map; i++) { | |
| 94 | + struct boot_mem_map_entry *entry = boot_mem_map.map + i; | |
| 95 | + unsigned long top; | |
| 96 | + | |
| 97 | + if (entry->type != type) | |
| 98 | + continue; | |
| 99 | + | |
| 100 | + if (start + size < entry->addr) | |
| 101 | + continue; /* no overlap */ | |
| 102 | + | |
| 103 | + if (entry->addr + entry->size < start) | |
| 104 | + continue; /* no overlap */ | |
| 105 | + | |
| 106 | + top = max(entry->addr + entry->size, start + size); | |
| 107 | + entry->addr = min(entry->addr, start); | |
| 108 | + entry->size = top - entry->addr; | |
| 109 | + | |
| 96 | 110 | return; |
| 97 | 111 | } |
| 98 | 112 | |
| 99 | − if (x == BOOT_MEM_MAP_MAX) { | |
| 113 | + if (boot_mem_map.nr_map == BOOT_MEM_MAP_MAX) { | |
| 100 | 114 | pr_err("Ooops! Too many entries in the memory map!\n"); |
| 101 | 115 | return; |
| 102 | 116 | } |
| @@ -2,8 +2,9 @@ · 1 unmodified line | ||
| 2 | 2 | # Makefile for MIPS-specific library files.. |
| 3 | 3 | # |
| 4 | 4 | |
| 5 | −lib-y += csum_partial.o delay.o memcpy.o memset.o \ | |
| 6 | − strlen_user.o strncpy_user.o strnlen_user.o uncached.o | |
| 5 | +lib-y += bitops.o csum_partial.o delay.o memcpy.o memset.o \ | |
| 6 | + mips-atomic.o strlen_user.o strncpy_user.o \ | |
| 7 | + strnlen_user.o uncached.o | |
| 7 | 8 | |
| 8 | 9 | obj-y += iomap.o |
| 9 | 10 | obj-$(CONFIG_PCI) += iomap-pci.o |
| @@ -0,0 +1,179 @@ | ||
| 1 | +/* | |
| 2 | + * This file is subject to the terms and conditions of the GNU General Public | |
| 3 | + * License. See the file "COPYING" in the main directory of this archive | |
| 4 | + * for more details. | |
| 5 | + * | |
| 6 | + * Copyright (c) 1994-1997, 99, 2000, 06, 07 Ralf Baechle (ralf@linux-mips.org) | |
| 7 | + * Copyright (c) 1999, 2000 Silicon Graphics, Inc. | |
| 8 | + */ | |
| 9 | +#include <linux/bitops.h> | |
| 10 | +#include <linux/irqflags.h> | |
| 11 | +#include <linux/export.h> | |
| 12 | + | |
| 13 | + | |
| 14 | +/** | |
| 15 | + * __mips_set_bit - Atomically set a bit in memory. This is called by | |
| 16 | + * set_bit() if it cannot find a faster solution. | |
| 17 | + * @nr: the bit to set | |
| 18 | + * @addr: the address to start counting from | |
| 19 | + */ | |
| 20 | +void __mips_set_bit(unsigned long nr, volatile unsigned long *addr) | |
| 21 | +{ | |
| 22 | + volatile unsigned long *a = addr; | |
| 23 | + unsigned bit = nr & SZLONG_MASK; | |
| 24 | + unsigned long mask; | |
| 25 | + unsigned long flags; | |
| 26 | + | |
| 27 | + a += nr >> SZLONG_LOG; | |
| 28 | + mask = 1UL << bit; | |
| 29 | + raw_local_irq_save(flags); | |
| 30 | + *a |= mask; | |
| 31 | + raw_local_irq_restore(flags); | |
| 32 | +} | |
| 33 | +EXPORT_SYMBOL(__mips_set_bit); | |
| 34 | + | |
| 35 | + | |
| 36 | +/** | |
| 37 | + * __mips_clear_bit - Clears a bit in memory. This is called by clear_bit() if | |
| 38 | + * it cannot find a faster solution. | |
| 39 | + * @nr: Bit to clear | |
| 40 | + * @addr: Address to start counting from | |
| 41 | + */ | |
| 42 | +void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr) | |
| 43 | +{ | |
| 44 | + volatile unsigned long *a = addr; | |
| 45 | + unsigned bit = nr & SZLONG_MASK; | |
| 46 | + unsigned long mask; | |
| 47 | + unsigned long flags; | |
| 48 | + | |
| 49 | + a += nr >> SZLONG_LOG; | |
| 50 | + mask = 1UL << bit; | |
| 51 | + raw_local_irq_save(flags); | |
| 52 | + *a &= ~mask; | |
| 53 | + raw_local_irq_restore(flags); | |
| 54 | +} | |
| 55 | +EXPORT_SYMBOL(__mips_clear_bit); | |
| 56 | + | |
| 57 | + | |
| 58 | +/** | |
| 59 | + * __mips_change_bit - Toggle a bit in memory. This is called by change_bit() | |
| 60 | + * if it cannot find a faster solution. | |
| 61 | + * @nr: Bit to change | |
| 62 | + * @addr: Address to start counting from | |
| 63 | + */ | |
| 64 | +void __mips_change_bit(unsigned long nr, volatile unsigned long *addr) | |
| 65 | +{ | |
| 66 | + volatile unsigned long *a = addr; | |
| 67 | + unsigned bit = nr & SZLONG_MASK; | |
| 68 | + unsigned long mask; | |
| 69 | + unsigned long flags; | |
| 70 | + | |
| 71 | + a += nr >> SZLONG_LOG; | |
| 72 | + mask = 1UL << bit; | |
| 73 | + raw_local_irq_save(flags); | |
| 74 | + *a ^= mask; | |
| 75 | + raw_local_irq_restore(flags); | |
| 76 | +} | |
| 77 | +EXPORT_SYMBOL(__mips_change_bit); | |
| 78 | + | |
| 79 | + | |
| 80 | +/** | |
| 81 | + * __mips_test_and_set_bit - Set a bit and return its old value. This is | |
| 82 | + * called by test_and_set_bit() if it cannot find a faster solution. | |
| 83 | + * @nr: Bit to set | |
| 84 | + * @addr: Address to count from | |
| 85 | + */ | |
| 86 | +int __mips_test_and_set_bit(unsigned long nr, | |
| 87 | + volatile unsigned long *addr) | |
| 88 | +{ | |
| 89 | + volatile unsigned long *a = addr; | |
| 90 | + unsigned bit = nr & SZLONG_MASK; | |
| 91 | + unsigned long mask; | |
| 92 | + unsigned long flags; | |
| 93 | + unsigned long res; | |
| 94 | + | |
| 95 | + a += nr >> SZLONG_LOG; | |
| 96 | + mask = 1UL << bit; | |
| 97 | + raw_local_irq_save(flags); | |
| 98 | + res = (mask & *a); | |
| 99 | + *a |= mask; | |
| 100 | + raw_local_irq_restore(flags); | |
| 101 | + return res; | |
| 102 | +} | |
| 103 | +EXPORT_SYMBOL(__mips_test_and_set_bit); | |
| 104 | + | |
| 105 | + | |
| 106 | +/** | |
| 107 | + * __mips_test_and_set_bit_lock - Set a bit and return its old value. This is | |
| 108 | + * called by test_and_set_bit_lock() if it cannot find a faster solution. | |
| 109 | + * @nr: Bit to set | |
| 110 | + * @addr: Address to count from | |
| 111 | + */ | |
| 112 | +int __mips_test_and_set_bit_lock(unsigned long nr, | |
| 113 | + volatile unsigned long *addr) | |
| 114 | +{ | |
| 115 | + volatile unsigned long *a = addr; | |
| 116 | + unsigned bit = nr & SZLONG_MASK; | |
| 117 | + unsigned long mask; | |
| 118 | + unsigned long flags; | |
| 119 | + unsigned long res; | |
| 120 | + | |
| 121 | + a += nr >> SZLONG_LOG; | |
| 122 | + mask = 1UL << bit; | |
| 123 | + raw_local_irq_save(flags); | |
| 124 | + res = (mask & *a); | |
| 125 | + *a |= mask; | |
| 126 | + raw_local_irq_restore(flags); | |
| 127 | + return res; | |
| 128 | +} | |
| 129 | +EXPORT_SYMBOL(__mips_test_and_set_bit_lock); | |
| 130 | + | |
| 131 | + | |
| 132 | +/** | |
| 133 | + * __mips_test_and_clear_bit - Clear a bit and return its old value. This is | |
| 134 | + * called by test_and_clear_bit() if it cannot find a faster solution. | |
| 135 | + * @nr: Bit to clear | |
| 136 | + * @addr: Address to count from | |
| 137 | + */ | |
| 138 | +int __mips_test_and_clear_bit(unsigned long nr, volatile unsigned long *addr) | |
| 139 | +{ | |
| 140 | + volatile unsigned long *a = addr; | |
| 141 | + unsigned bit = nr & SZLONG_MASK; | |
| 142 | + unsigned long mask; | |
| 143 | + unsigned long flags; | |
| 144 | + unsigned long res; | |
| 145 | + | |
| 146 | + a += nr >> SZLONG_LOG; | |
| 147 | + mask = 1UL << bit; | |
| 148 | + raw_local_irq_save(flags); | |
| 149 | + res = (mask & *a); | |
| 150 | + *a &= ~mask; | |
| 151 | + raw_local_irq_restore(flags); | |
| 152 | + return res; | |
| 153 | +} | |
| 154 | +EXPORT_SYMBOL(__mips_test_and_clear_bit); | |
| 155 | + | |
| 156 | + | |
| 157 | +/** | |
| 158 | + * __mips_test_and_change_bit - Change a bit and return its old value. This is | |
| 159 | + * called by test_and_change_bit() if it cannot find a faster solution. | |
| 160 | + * @nr: Bit to change | |
| 161 | + * @addr: Address to count from | |
| 162 | + */ | |
| 163 | +int __mips_test_and_change_bit(unsigned long nr, volatile unsigned long *addr) | |
| 164 | +{ | |
| 165 | + volatile unsigned long *a = addr; | |
| 166 | + unsigned bit = nr & SZLONG_MASK; | |
| 167 | + unsigned long mask; | |
| 168 | + unsigned long flags; | |
| 169 | + unsigned long res; | |
| 170 | + | |
| 171 | + a += nr >> SZLONG_LOG; | |
| 172 | + mask = 1UL << bit; | |
| 173 | + raw_local_irq_save(flags); | |
| 174 | + res = (mask & *a); | |
| 175 | + *a ^= mask; | |
| 176 | + raw_local_irq_restore(flags); | |
| 177 | + return res; | |
| 178 | +} | |
| 179 | +EXPORT_SYMBOL(__mips_test_and_change_bit); | |
| @@ -0,0 +1,176 @@ | ||
| 1 | +/* | |
| 2 | + * This file is subject to the terms and conditions of the GNU General Public | |
| 3 | + * License. See the file "COPYING" in the main directory of this archive | |
| 4 | + * for more details. | |
| 5 | + * | |
| 6 | + * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle | |
| 7 | + * Copyright (C) 1996 by Paul M. Antoine | |
| 8 | + * Copyright (C) 1999 Silicon Graphics | |
| 9 | + * Copyright (C) 2000 MIPS Technologies, Inc. | |
| 10 | + */ | |
| 11 | +#include <asm/irqflags.h> | |
| 12 | +#include <asm/hazards.h> | |
| 13 | +#include <linux/compiler.h> | |
| 14 | +#include <linux/preempt.h> | |
| 15 | +#include <linux/export.h> | |
| 16 | + | |
| 17 | +#if !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC) | |
| 18 | + | |
| 19 | +/* | |
| 20 | + * For cli() we have to insert nops to make sure that the new value | |
| 21 | + * has actually arrived in the status register before the end of this | |
| 22 | + * macro. | |
| 23 | + * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs | |
| 24 | + * no nops at all. | |
| 25 | + */ | |
| 26 | +/* | |
| 27 | + * For TX49, operating only IE bit is not enough. | |
| 28 | + * | |
| 29 | + * If mfc0 $12 follows store and the mfc0 is last instruction of a | |
| 30 | + * page and fetching the next instruction causes TLB miss, the result | |
| 31 | + * of the mfc0 might wrongly contain EXL bit. | |
| 32 | + * | |
| 33 | + * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008 | |
| 34 | + * | |
| 35 | + * Workaround: mask EXL bit of the result or place a nop before mfc0. | |
| 36 | + */ | |
| 37 | +__asm__( | |
| 38 | + " .macro arch_local_irq_disable\n" | |
| 39 | + " .set push \n" | |
| 40 | + " .set noat \n" | |
| 41 | +#ifdef CONFIG_MIPS_MT_SMTC | |
| 42 | + " mfc0 $1, $2, 1 \n" | |
| 43 | + " ori $1, 0x400 \n" | |
| 44 | + " .set noreorder \n" | |
| 45 | + " mtc0 $1, $2, 1 \n" | |
| 46 | +#elif defined(CONFIG_CPU_MIPSR2) | |
| 47 | + /* see irqflags.h for inline function */ | |
| 48 | +#else | |
| 49 | + " mfc0 $1,$12 \n" | |
| 50 | + " ori $1,0x1f \n" | |
| 51 | + " xori $1,0x1f \n" | |
| 52 | + " .set noreorder \n" | |
| 53 | + " mtc0 $1,$12 \n" | |
| 54 | +#endif | |
| 55 | + " irq_disable_hazard \n" | |
| 56 | + " .set pop \n" | |
| 57 | + " .endm \n"); | |
| 58 | + | |
| 59 | +notrace void arch_local_irq_disable(void) | |
| 60 | +{ | |
| 61 | + preempt_disable(); | |
| 62 | + __asm__ __volatile__( | |
| 63 | + "arch_local_irq_disable" | |
| 64 | + : /* no outputs */ | |
| 65 | + : /* no inputs */ | |
| 66 | + : "memory"); | |
| 67 | + preempt_enable(); | |
| 68 | +} | |
| 69 | +EXPORT_SYMBOL(arch_local_irq_disable); | |
| 70 | + | |
| 71 | + | |
| 72 | +__asm__( | |
| 73 | + " .macro arch_local_irq_save result \n" | |
| 74 | + " .set push \n" | |
| 75 | + " .set reorder \n" | |
| 76 | + " .set noat \n" | |
| 77 | +#ifdef CONFIG_MIPS_MT_SMTC | |
| 78 | + " mfc0 \\result, $2, 1 \n" | |
| 79 | + " ori $1, \\result, 0x400 \n" | |
| 80 | + " .set noreorder \n" | |
| 81 | + " mtc0 $1, $2, 1 \n" | |
| 82 | + " andi \\result, \\result, 0x400 \n" | |
| 83 | +#elif defined(CONFIG_CPU_MIPSR2) | |
| 84 | + /* see irqflags.h for inline function */ | |
| 85 | +#else | |
| 86 | + " mfc0 \\result, $12 \n" | |
| 87 | + " ori $1, \\result, 0x1f \n" | |
| 88 | + " xori $1, 0x1f \n" | |
| 89 | + " .set noreorder \n" | |
| 90 | + " mtc0 $1, $12 \n" | |
| 91 | +#endif | |
| 92 | + " irq_disable_hazard \n" | |
| 93 | + " .set pop \n" | |
| 94 | + " .endm \n"); | |
| 95 | + | |
| 96 | +notrace unsigned long arch_local_irq_save(void) | |
| 97 | +{ | |
| 98 | + unsigned long flags; | |
| 99 | + preempt_disable(); | |
| 100 | + asm volatile("arch_local_irq_save\t%0" | |
| 101 | + : "=r" (flags) | |
| 102 | + : /* no inputs */ | |
| 103 | + : "memory"); | |
| 104 | + preempt_enable(); | |
| 105 | + return flags; | |
| 106 | +} | |
| 107 | +EXPORT_SYMBOL(arch_local_irq_save); | |
| 108 | + | |
| 109 | + | |
| 110 | +__asm__( | |
| 111 | + " .macro arch_local_irq_restore flags \n" | |
| 112 | + " .set push \n" | |
| 113 | + " .set noreorder \n" | |
| 114 | + " .set noat \n" | |
| 115 | +#ifdef CONFIG_MIPS_MT_SMTC | |
| 116 | + "mfc0 $1, $2, 1 \n" | |
| 117 | + "andi \\flags, 0x400 \n" | |
| 118 | + "ori $1, 0x400 \n" | |
| 119 | + "xori $1, 0x400 \n" | |
| 120 | + "or \\flags, $1 \n" | |
| 121 | + "mtc0 \\flags, $2, 1 \n" | |
| 122 | +#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) | |
| 123 | + /* see irqflags.h for inline function */ | |
| 124 | +#elif defined(CONFIG_CPU_MIPSR2) | |
| 125 | + /* see irqflags.h for inline function */ | |
| 126 | +#else | |
| 127 | + " mfc0 $1, $12 \n" | |
| 128 | + " andi \\flags, 1 \n" | |
| 129 | + " ori $1, 0x1f \n" | |
| 130 | + " xori $1, 0x1f \n" | |
| 131 | + " or \\flags, $1 \n" | |
| 132 | + " mtc0 \\flags, $12 \n" | |
| 133 | +#endif | |
| 134 | + " irq_disable_hazard \n" | |
| 135 | + " .set pop \n" | |
| 136 | + " .endm \n"); | |
| 137 | + | |
| 138 | +notrace void arch_local_irq_restore(unsigned long flags) | |
| 139 | +{ | |
| 140 | + unsigned long __tmp1; | |
| 141 | + | |
| 142 | +#ifdef CONFIG_MIPS_MT_SMTC | |
| 143 | + /* | |
| 144 | + * SMTC kernel needs to do a software replay of queued | |
| 145 | + * IPIs, at the cost of branch and call overhead on each | |
| 146 | + * local_irq_restore() | |
| 147 | + */ | |
| 148 | + if (unlikely(!(flags & 0x0400))) | |
| 149 | + smtc_ipi_replay(); | |
| 150 | +#endif | |
| 151 | + preempt_disable(); | |
| 152 | + __asm__ __volatile__( | |
| 153 | + "arch_local_irq_restore\t%0" | |
| 154 | + : "=r" (__tmp1) | |
| 155 | + : "0" (flags) | |
| 156 | + : "memory"); | |
| 157 | + preempt_enable(); | |
| 158 | +} | |
| 159 | +EXPORT_SYMBOL(arch_local_irq_restore); | |
| 160 | + | |
| 161 | + | |
| 162 | +notrace void __arch_local_irq_restore(unsigned long flags) | |
| 163 | +{ | |
| 164 | + unsigned long __tmp1; | |
| 165 | + | |
| 166 | + preempt_disable(); | |
| 167 | + __asm__ __volatile__( | |
| 168 | + "arch_local_irq_restore\t%0" | |
| 169 | + : "=r" (__tmp1) | |
| 170 | + : "0" (flags) | |
| 171 | + : "memory"); | |
| 172 | + preempt_enable(); | |
| 173 | +} | |
| 174 | +EXPORT_SYMBOL(__arch_local_irq_restore); | |
| 175 | + | |
| 176 | +#endif /* !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC) */ | |
| @@ -120,18 +120,11 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, · 119 unmodified lines | ||
| 120 | 120 | |
| 121 | 121 | if (cpu_context(cpu, mm) != 0) { |
| 122 | 122 | unsigned long size, flags; |
| 123 | − int huge = is_vm_hugetlb_page(vma); | |
| 124 | 123 | |
| 125 | 124 | ENTER_CRITICAL(flags); |
| 126 | − if (huge) { | |
| 127 | − start = round_down(start, HPAGE_SIZE); | |
| 128 | − end = round_up(end, HPAGE_SIZE); | |
| 129 | − size = (end - start) >> HPAGE_SHIFT; | |
| 130 | − } else { | |
| 131 | − start = round_down(start, PAGE_SIZE << 1); | |
| 132 | − end = round_up(end, PAGE_SIZE << 1); | |
| 133 | − size = (end - start) >> (PAGE_SHIFT + 1); | |
| 134 | − } | |
| 125 | + start = round_down(start, PAGE_SIZE << 1); | |
| 126 | + end = round_up(end, PAGE_SIZE << 1); | |
| 127 | + size = (end - start) >> (PAGE_SHIFT + 1); | |
| 135 | 128 | if (size <= current_cpu_data.tlbsize/2) { |
| 136 | 129 | int oldpid = read_c0_entryhi(); |
| 137 | 130 | int newpid = cpu_asid(cpu, mm); |
| @@ -140,10 +133,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, · 2 unmodified lines | ||
| 140 | 133 | int idx; |
| 141 | 134 | |
| 142 | 135 | write_c0_entryhi(start | newpid); |
| 143 | − if (huge) | |
| 144 | − start += HPAGE_SIZE; | |
| 145 | − else | |
| 146 | − start += (PAGE_SIZE << 1); | |
| 136 | + start += (PAGE_SIZE << 1); | |
| 147 | 137 | mtc0_tlbw_hazard(); |
| 148 | 138 | tlb_probe(); |
| 149 | 139 | tlb_probe_hazard(); |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include <linux/mtd/partitions.h> |
| 30 | 30 | #include <linux/mtd/physmap.h> |
| 31 | 31 | #include <linux/platform_device.h> |
| 32 | +#include <asm/mips-boards/maltaint.h> | |
| 32 | 33 | #include <mtd/mtd-abi.h> |
| 33 | 34 | |
| 34 | 35 | #define SMC_PORT(base, int) \ |
| @@ -48,7 +49,7 @@ static struct plat_serial8250_port uart8250_data[] = { · 13 unmodified lines | ||
| 48 | 49 | SMC_PORT(0x2F8, 3), |
| 49 | 50 | { |
| 50 | 51 | .mapbase = 0x1f000900, /* The CBUS UART */ |
| 51 | − .irq = MIPS_CPU_IRQ_BASE + 2, | |
| 52 | + .irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB2, | |
| 52 | 53 | .uartclk = 3686400, /* Twice the usual clk! */ |
| 53 | 54 | .iotype = UPIO_MEM32, |
| 54 | 55 | .flags = CBUS_UART_FLAGS, |
| @@ -84,7 +84,6 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs) · 83 unmodified lines | ||
| 84 | 84 | { |
| 85 | 85 | struct rt_sigframe *frame = (struct rt_sigframe __user *)regs->sp; |
| 86 | 86 | sigset_t set; |
| 87 | − stack_t st; | |
| 88 | 87 | |
| 89 | 88 | /* |
| 90 | 89 | * Since we stacked the signal on a dword boundary, |
| @@ -104,11 +103,10 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs) · 13 unmodified lines | ||
| 104 | 103 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) |
| 105 | 104 | goto badframe; |
| 106 | 105 | |
| 107 | − if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) | |
| 108 | − goto badframe; | |
| 109 | 106 | /* It is more difficult to avoid calling this function than to |
| 110 | 107 | call it and ignore errors. */ |
| 111 | − do_sigaltstack(&st, NULL, regs->sp); | |
| 108 | + if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT) | |
| 109 | + goto badframe; | |
| 112 | 110 | |
| 113 | 111 | return regs->gpr[11]; |
| 114 | 112 | |
| @@ -65,7 +65,8 @@ put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz) · 64 unmodified lines | ||
| 65 | 65 | { |
| 66 | 66 | compat_sigset_t s; |
| 67 | 67 | |
| 68 | − if (sz != sizeof *set) panic("put_sigset32()"); | |
| 68 | + if (sz != sizeof *set) | |
| 69 | + return -EINVAL; | |
| 69 | 70 | sigset_64to32(&s, set); |
| 70 | 71 | |
| 71 | 72 | return copy_to_user(up, &s, sizeof s); |
| @@ -77,7 +78,8 @@ get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz) · 5 unmodified lines | ||
| 77 | 78 | compat_sigset_t s; |
| 78 | 79 | int r; |
| 79 | 80 | |
| 80 | − if (sz != sizeof *set) panic("put_sigset32()"); | |
| 81 | + if (sz != sizeof *set) | |
| 82 | + return -EINVAL; | |
| 81 | 83 | |
| 82 | 84 | if ((r = copy_from_user(&s, up, sz)) == 0) { |
| 83 | 85 | sigset_32to64(set, &s); |
| @@ -73,6 +73,8 @@ static unsigned long get_shared_area(struct address_space *mapping, · 72 unmodified lines | ||
| 73 | 73 | struct vm_area_struct *vma; |
| 74 | 74 | int offset = mapping ? get_offset(mapping) : 0; |
| 75 | 75 | |
| 76 | + offset = (offset + (pgoff << PAGE_SHIFT)) & 0x3FF000; | |
| 77 | + | |
| 76 | 78 | addr = DCACHE_ALIGN(addr - offset) + offset; |
| 77 | 79 | |
| 78 | 80 | for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { |
| @@ -60,7 +60,7 @@ · 59 unmodified lines | ||
| 60 | 60 | ENTRY_SAME(fork_wrapper) |
| 61 | 61 | ENTRY_SAME(read) |
| 62 | 62 | ENTRY_SAME(write) |
| 63 | − ENTRY_SAME(open) /* 5 */ | |
| 63 | + ENTRY_COMP(open) /* 5 */ | |
| 64 | 64 | ENTRY_SAME(close) |
| 65 | 65 | ENTRY_SAME(waitpid) |
| 66 | 66 | ENTRY_SAME(creat) |
| @@ -231,6 +231,12 @@ · 230 unmodified lines | ||
| 231 | 231 | interrupts = <2 7 0>; |
| 232 | 232 | }; |
| 233 | 233 | |
| 234 | + sclpc@3c00 { | |
| 235 | + compatible = "fsl,mpc5200-lpbfifo"; | |
| 236 | + reg = <0x3c00 0x60>; | |
| 237 | + interrupts = <2 23 0>; | |
| 238 | + }; | |
| 239 | + | |
| 234 | 240 | i2c@3d00 { |
| 235 | 241 | #address-cells = <1>; |
| 236 | 242 | #size-cells = <0>; |
| @@ -86,12 +86,6 @@ · 85 unmodified lines | ||
| 86 | 86 | reg = <0>; |
| 87 | 87 | }; |
| 88 | 88 | }; |
| 89 | − | |
| 90 | − sclpc@3c00 { | |
| 91 | − compatible = "fsl,mpc5200-lpbfifo"; | |
| 92 | − reg = <0x3c00 0x60>; | |
| 93 | − interrupts = <3 23 0>; | |
| 94 | − }; | |
| 95 | 89 | }; |
| 96 | 90 | |
| 97 | 91 | localbus { |
| @@ -59,7 +59,7 @@ · 58 unmodified lines | ||
| 59 | 59 | #gpio-cells = <2>; |
| 60 | 60 | }; |
| 61 | 61 | |
| 62 | − psc@2000 { /* PSC1 in ac97 mode */ | |
| 62 | + audioplatform: psc@2000 { /* PSC1 in ac97 mode */ | |
| 63 | 63 | compatible = "mpc5200b-psc-ac97","fsl,mpc5200b-psc-ac97"; |
| 64 | 64 | cell-index = <0>; |
| 65 | 65 | }; |
| @@ -134,4 +134,9 @@ · 68 unmodified lines | ||
| 134 | 134 | localbus { |
| 135 | 135 | status = "disabled"; |
| 136 | 136 | }; |
| 137 | + | |
| 138 | + sound { | |
| 139 | + compatible = "phytec,pcm030-audio-fabric"; | |
| 140 | + asoc-platform = <&audioplatform>; | |
| 141 | + }; | |
| 137 | 142 | }; |
| @@ -372,10 +372,11 @@ static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq, · 371 unmodified lines | ||
| 372 | 372 | case MPC52xx_IRQ_L1_MAIN: irqchip = &mpc52xx_main_irqchip; break; |
| 373 | 373 | case MPC52xx_IRQ_L1_PERP: irqchip = &mpc52xx_periph_irqchip; break; |
| 374 | 374 | case MPC52xx_IRQ_L1_SDMA: irqchip = &mpc52xx_sdma_irqchip; break; |
| 375 | − default: | |
| 376 | − pr_err("%s: invalid irq: virq=%i, l1=%i, l2=%i\n", | |
| 377 | − __func__, virq, l1irq, l2irq); | |
| 378 | − return -EINVAL; | |
| 375 | + case MPC52xx_IRQ_L1_CRIT: | |
| 376 | + pr_warn("%s: Critical IRQ #%d is unsupported! Nopping it.\n", | |
| 377 | + __func__, l2irq); | |
| 378 | + irq_set_chip(virq, &no_irq_chip); | |
| 379 | + return 0; | |
| 379 | 380 | } |
| 380 | 381 | |
| 381 | 382 | irq_set_chip_and_handler(virq, irqchip, handle_level_irq); |
| @@ -449,7 +449,7 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe) · 448 unmodified lines | ||
| 449 | 449 | if (list_empty(&pe->edevs)) { |
| 450 | 450 | cnt = 0; |
| 451 | 451 | list_for_each_entry(child, &pe->child_list, child) { |
| 452 | − if (!(pe->type & EEH_PE_INVALID)) { | |
| 452 | + if (!(child->type & EEH_PE_INVALID)) { | |
| 453 | 453 | cnt++; |
| 454 | 454 | break; |
| 455 | 455 | } |
| @@ -220,7 +220,8 @@ static struct device_node *find_pe_dn(struct pci_dev *dev, int *total) · 219 unmodified lines | ||
| 220 | 220 | |
| 221 | 221 | /* Get the top level device in the PE */ |
| 222 | 222 | edev = of_node_to_eeh_dev(dn); |
| 223 | − edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list); | |
| 223 | + if (edev->pe) | |
| 224 | + edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list); | |
| 224 | 225 | dn = eeh_dev_to_of_node(edev); |
| 225 | 226 | if (!dn) |
| 226 | 227 | return NULL; |
| @@ -96,6 +96,7 @@ config S390 · 95 unmodified lines | ||
| 96 | 96 | select HAVE_MEMBLOCK_NODE_MAP |
| 97 | 97 | select HAVE_CMPXCHG_LOCAL |
| 98 | 98 | select HAVE_CMPXCHG_DOUBLE |
| 99 | + select HAVE_ALIGNED_STRUCT_PAGE if SLUB | |
| 99 | 100 | select HAVE_VIRT_CPU_ACCOUNTING |
| 100 | 101 | select VIRT_CPU_ACCOUNTING |
| 101 | 102 | select ARCH_DISCARD_MEMBLOCK |
| @@ -9,6 +9,8 @@ · 8 unmodified lines | ||
| 9 | 9 | |
| 10 | 10 | #define LPM_ANYPATH 0xff |
| 11 | 11 | #define __MAX_CSSID 0 |
| 12 | +#define __MAX_SUBCHANNEL 65535 | |
| 13 | +#define __MAX_SSID 3 | |
| 12 | 14 | |
| 13 | 15 | #include <asm/scsw.h> |
| 14 | 16 | |
| @@ -20,7 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | #define PSW32_MASK_CC 0x00003000UL |
| 21 | 21 | #define PSW32_MASK_PM 0x00000f00UL |
| 22 | 22 | |
| 23 | −#define PSW32_MASK_USER 0x00003F00UL | |
| 23 | +#define PSW32_MASK_USER 0x0000FF00UL | |
| 24 | 24 | |
| 25 | 25 | #define PSW32_ADDR_AMODE 0x80000000UL |
| 26 | 26 | #define PSW32_ADDR_INSN 0x7FFFFFFFUL |
| @@ -506,12 +506,15 @@ static inline int pud_bad(pud_t pud) · 505 unmodified lines | ||
| 506 | 506 | |
| 507 | 507 | static inline int pmd_present(pmd_t pmd) |
| 508 | 508 | { |
| 509 | − return (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) != 0UL; | |
| 509 | + unsigned long mask = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO; | |
| 510 | + return (pmd_val(pmd) & mask) == _HPAGE_TYPE_NONE || | |
| 511 | + !(pmd_val(pmd) & _SEGMENT_ENTRY_INV); | |
| 510 | 512 | } |
| 511 | 513 | |
| 512 | 514 | static inline int pmd_none(pmd_t pmd) |
| 513 | 515 | { |
| 514 | − return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) != 0UL; | |
| 516 | + return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) && | |
| 517 | + !(pmd_val(pmd) & _SEGMENT_ENTRY_RO); | |
| 515 | 518 | } |
| 516 | 519 | |
| 517 | 520 | static inline int pmd_large(pmd_t pmd) |
| @@ -1223,6 +1226,11 @@ static inline void __pmd_idte(unsigned long address, pmd_t *pmdp) · 705 unmodified lines | ||
| 1223 | 1226 | } |
| 1224 | 1227 | |
| 1225 | 1228 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
| 1229 | + | |
| 1230 | +#define SEGMENT_NONE __pgprot(_HPAGE_TYPE_NONE) | |
| 1231 | +#define SEGMENT_RO __pgprot(_HPAGE_TYPE_RO) | |
| 1232 | +#define SEGMENT_RW __pgprot(_HPAGE_TYPE_RW) | |
| 1233 | + | |
| 1226 | 1234 | #define __HAVE_ARCH_PGTABLE_DEPOSIT |
| 1227 | 1235 | extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable); |
| 1228 | 1236 | |
| @@ -1242,16 +1250,15 @@ static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, · 13 unmodified lines | ||
| 1242 | 1250 | |
| 1243 | 1251 | static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot) |
| 1244 | 1252 | { |
| 1245 | − unsigned long pgprot_pmd = 0; | |
| 1246 | − | |
| 1247 | − if (pgprot_val(pgprot) & _PAGE_INVALID) { | |
| 1248 | − if (pgprot_val(pgprot) & _PAGE_SWT) | |
| 1249 | − pgprot_pmd |= _HPAGE_TYPE_NONE; | |
| 1250 | − pgprot_pmd |= _SEGMENT_ENTRY_INV; | |
| 1251 | − } | |
| 1252 | − if (pgprot_val(pgprot) & _PAGE_RO) | |
| 1253 | − pgprot_pmd |= _SEGMENT_ENTRY_RO; | |
| 1254 | − return pgprot_pmd; | |
| 1253 | + /* | |
| 1254 | + * pgprot is PAGE_NONE, PAGE_RO, or PAGE_RW (see __Pxxx / __Sxxx) | |
| 1255 | + * Convert to segment table entry format. | |
| 1256 | + */ | |
| 1257 | + if (pgprot_val(pgprot) == pgprot_val(PAGE_NONE)) | |
| 1258 | + return pgprot_val(SEGMENT_NONE); | |
| 1259 | + if (pgprot_val(pgprot) == pgprot_val(PAGE_RO)) | |
| 1260 | + return pgprot_val(SEGMENT_RO); | |
| 1261 | + return pgprot_val(SEGMENT_RW); | |
| 1255 | 1262 | } |
| 1256 | 1263 | |
| 1257 | 1264 | static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) |
| @@ -1269,7 +1276,9 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd) · 11 unmodified lines | ||
| 1269 | 1276 | |
| 1270 | 1277 | static inline pmd_t pmd_mkwrite(pmd_t pmd) |
| 1271 | 1278 | { |
| 1272 | − pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO; | |
| 1279 | + /* Do not clobber _HPAGE_TYPE_NONE pages! */ | |
| 1280 | + if (!(pmd_val(pmd) & _SEGMENT_ENTRY_INV)) | |
| 1281 | + pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO; | |
| 1273 | 1282 | return pmd; |
| 1274 | 1283 | } |
| 1275 | 1284 | |
| @@ -8,6 +8,9 @@ struct cpu; · 7 unmodified lines | ||
| 8 | 8 | |
| 9 | 9 | #ifdef CONFIG_SCHED_BOOK |
| 10 | 10 | |
| 11 | +extern unsigned char cpu_socket_id[NR_CPUS]; | |
| 12 | +#define topology_physical_package_id(cpu) (cpu_socket_id[cpu]) | |
| 13 | + | |
| 11 | 14 | extern unsigned char cpu_core_id[NR_CPUS]; |
| 12 | 15 | extern cpumask_t cpu_core_map[NR_CPUS]; |
| 13 | 16 | |
| @@ -239,7 +239,7 @@ typedef struct · 238 unmodified lines | ||
| 239 | 239 | #define PSW_MASK_EA 0x00000000UL |
| 240 | 240 | #define PSW_MASK_BA 0x00000000UL |
| 241 | 241 | |
| 242 | −#define PSW_MASK_USER 0x00003F00UL | |
| 242 | +#define PSW_MASK_USER 0x0000FF00UL | |
| 243 | 243 | |
| 244 | 244 | #define PSW_ADDR_AMODE 0x80000000UL |
| 245 | 245 | #define PSW_ADDR_INSN 0x7FFFFFFFUL |
| @@ -269,7 +269,7 @@ typedef struct · 23 unmodified lines | ||
| 269 | 269 | #define PSW_MASK_EA 0x0000000100000000UL |
| 270 | 270 | #define PSW_MASK_BA 0x0000000080000000UL |
| 271 | 271 | |
| 272 | −#define PSW_MASK_USER 0x00003F8180000000UL | |
| 272 | +#define PSW_MASK_USER 0x0000FF8180000000UL | |
| 273 | 273 | |
| 274 | 274 | #define PSW_ADDR_AMODE 0x0000000000000000UL |
| 275 | 275 | #define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL |
| @@ -309,6 +309,10 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs) · 308 unmodified lines | ||
| 309 | 309 | regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | |
| 310 | 310 | (__u64)(regs32.psw.mask & PSW32_MASK_USER) << 32 | |
| 311 | 311 | (__u64)(regs32.psw.addr & PSW32_ADDR_AMODE); |
| 312 | + /* Check for invalid user address space control. */ | |
| 313 | + if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC)) | |
| 314 | + regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) | | |
| 315 | + (regs->psw.mask & ~PSW_MASK_ASC); | |
| 312 | 316 | regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN); |
| 313 | 317 | for (i = 0; i < NUM_GPRS; i++) |
| 314 | 318 | regs->gprs[i] = (__u64) regs32.gprs[i]; |
| @@ -481,7 +485,10 @@ static int setup_frame32(int sig, struct k_sigaction *ka, · 166 unmodified lines | ||
| 481 | 485 | |
| 482 | 486 | /* Set up registers for signal handler */ |
| 483 | 487 | regs->gprs[15] = (__force __u64) frame; |
| 484 | − regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */ | |
| 488 | + /* Force 31 bit amode and default user address space control. */ | |
| 489 | + regs->psw.mask = PSW_MASK_BA | | |
| 490 | + (psw_user_bits & PSW_MASK_ASC) | | |
| 491 | + (regs->psw.mask & ~PSW_MASK_ASC); | |
| 485 | 492 | regs->psw.addr = (__force __u64) ka->sa.sa_handler; |
| 486 | 493 | |
| 487 | 494 | regs->gprs[2] = map_signal(sig); |
| @@ -549,7 +556,10 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, · 61 unmodified lines | ||
| 549 | 556 | |
| 550 | 557 | /* Set up registers for signal handler */ |
| 551 | 558 | regs->gprs[15] = (__force __u64) frame; |
| 552 | − regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */ | |
| 559 | + /* Force 31 bit amode and default user address space control. */ | |
| 560 | + regs->psw.mask = PSW_MASK_BA | | |
| 561 | + (psw_user_bits & PSW_MASK_ASC) | | |
| 562 | + (regs->psw.mask & ~PSW_MASK_ASC); | |
| 553 | 563 | regs->psw.addr = (__u64) ka->sa.sa_handler; |
| 554 | 564 | |
| 555 | 565 | regs->gprs[2] = map_signal(sig); |
| @@ -28,7 +28,7 @@ ENTRY(sys32_open_wrapper) · 27 unmodified lines | ||
| 28 | 28 | llgtr %r2,%r2 # const char * |
| 29 | 29 | lgfr %r3,%r3 # int |
| 30 | 30 | lgfr %r4,%r4 # int |
| 31 | − jg sys_open # branch to system call | |
| 31 | + jg compat_sys_open # branch to system call | |
| 32 | 32 | |
| 33 | 33 | ENTRY(sys32_close_wrapper) |
| 34 | 34 | llgfr %r2,%r2 # unsigned int |
| @@ -44,6 +44,12 @@ _sclp_wait_int: · 43 unmodified lines | ||
| 44 | 44 | #endif |
| 45 | 45 | mvc .LoldpswS1-.LbaseS1(16,%r13),0(%r8) |
| 46 | 46 | mvc 0(16,%r8),0(%r9) |
| 47 | +#ifdef CONFIG_64BIT | |
| 48 | + epsw %r6,%r7 # set current addressing mode | |
| 49 | + nill %r6,0x1 # in new psw (31 or 64 bit mode) | |
| 50 | + nilh %r7,0x8000 | |
| 51 | + stm %r6,%r7,0(%r8) | |
| 52 | +#endif | |
| 47 | 53 | lhi %r6,0x0200 # cr mask for ext int (cr0.54) |
| 48 | 54 | ltr %r2,%r2 |
| 49 | 55 | jz .LsetctS1 |
| @@ -87,7 +93,7 @@ _sclp_wait_int: · 37 unmodified lines | ||
| 87 | 93 | .long 0x00080000, 0x80000000+.LwaitS1 # PSW to handle ext int |
| 88 | 94 | #ifdef CONFIG_64BIT |
| 89 | 95 | .LextpswS1_64: |
| 90 | − .quad 0x0000000180000000, .LwaitS1 # PSW to handle ext int, 64 bit | |
| 96 | + .quad 0, .LwaitS1 # PSW to handle ext int, 64 bit | |
| 91 | 97 | #endif |
| 92 | 98 | .LwaitpswS1: |
| 93 | 99 | .long 0x010a0000, 0x00000000+.LloopS1 # PSW to wait for ext int |
| @@ -136,6 +136,10 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) · 135 unmodified lines | ||
| 136 | 136 | /* Use regs->psw.mask instead of psw_user_bits to preserve PER bit. */ |
| 137 | 137 | regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | |
| 138 | 138 | (user_sregs.regs.psw.mask & PSW_MASK_USER); |
| 139 | + /* Check for invalid user address space control. */ | |
| 140 | + if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC)) | |
| 141 | + regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) | | |
| 142 | + (regs->psw.mask & ~PSW_MASK_ASC); | |
| 139 | 143 | /* Check for invalid amode */ |
| 140 | 144 | if (regs->psw.mask & PSW_MASK_EA) |
| 141 | 145 | regs->psw.mask |= PSW_MASK_BA; |
| @@ -273,7 +277,10 @@ static int setup_frame(int sig, struct k_sigaction *ka, · 131 unmodified lines | ||
| 273 | 277 | |
| 274 | 278 | /* Set up registers for signal handler */ |
| 275 | 279 | regs->gprs[15] = (unsigned long) frame; |
| 276 | − regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */ | |
| 280 | + /* Force default amode and default user address space control. */ | |
| 281 | + regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | | |
| 282 | + (psw_user_bits & PSW_MASK_ASC) | | |
| 283 | + (regs->psw.mask & ~PSW_MASK_ASC); | |
| 277 | 284 | regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; |
| 278 | 285 | |
| 279 | 286 | regs->gprs[2] = map_signal(sig); |
| @@ -346,7 +353,10 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, · 66 unmodified lines | ||
| 346 | 353 | |
| 347 | 354 | /* Set up registers for signal handler */ |
| 348 | 355 | regs->gprs[15] = (unsigned long) frame; |
| 349 | − regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */ | |
| 356 | + /* Force default amode and default user address space control. */ | |
| 357 | + regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | | |
| 358 | + (psw_user_bits & PSW_MASK_ASC) | | |
| 359 | + (regs->psw.mask & ~PSW_MASK_ASC); | |
| 350 | 360 | regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; |
| 351 | 361 | |
| 352 | 362 | regs->gprs[2] = map_signal(sig); |
| @@ -40,6 +40,7 @@ static DEFINE_SPINLOCK(topology_lock); · 39 unmodified lines | ||
| 40 | 40 | static struct mask_info core_info; |
| 41 | 41 | cpumask_t cpu_core_map[NR_CPUS]; |
| 42 | 42 | unsigned char cpu_core_id[NR_CPUS]; |
| 43 | +unsigned char cpu_socket_id[NR_CPUS]; | |
| 43 | 44 | |
| 44 | 45 | static struct mask_info book_info; |
| 45 | 46 | cpumask_t cpu_book_map[NR_CPUS]; |
| @@ -83,11 +84,12 @@ static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu, · 37 unmodified lines | ||
| 83 | 84 | cpumask_set_cpu(lcpu, &book->mask); |
| 84 | 85 | cpu_book_id[lcpu] = book->id; |
| 85 | 86 | cpumask_set_cpu(lcpu, &core->mask); |
| 87 | + cpu_core_id[lcpu] = rcpu; | |
| 86 | 88 | if (one_core_per_cpu) { |
| 87 | − cpu_core_id[lcpu] = rcpu; | |
| 89 | + cpu_socket_id[lcpu] = rcpu; | |
| 88 | 90 | core = core->next; |
| 89 | 91 | } else { |
| 90 | − cpu_core_id[lcpu] = core->id; | |
| 92 | + cpu_socket_id[lcpu] = core->id; | |
| 91 | 93 | } |
| 92 | 94 | smp_cpu_set_polarization(lcpu, tl_cpu->pp); |
| 93 | 95 | } |
| @@ -39,7 +39,7 @@ static __always_inline unsigned long follow_table(struct mm_struct *mm, · 38 unmodified lines | ||
| 39 | 39 | pmd = pmd_offset(pud, addr); |
| 40 | 40 | if (pmd_none(*pmd)) |
| 41 | 41 | return -0x10UL; |
| 42 | − if (pmd_huge(*pmd)) { | |
| 42 | + if (pmd_large(*pmd)) { | |
| 43 | 43 | if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO)) |
| 44 | 44 | return -0x04UL; |
| 45 | 45 | return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK); |
| @@ -126,7 +126,7 @@ static inline int gup_pmd_range(pud_t *pudp, pud_t pud, unsigned long addr, · 125 unmodified lines | ||
| 126 | 126 | */ |
| 127 | 127 | if (pmd_none(pmd) || pmd_trans_splitting(pmd)) |
| 128 | 128 | return 0; |
| 129 | − if (unlikely(pmd_huge(pmd))) { | |
| 129 | + if (unlikely(pmd_large(pmd))) { | |
| 130 | 130 | if (!gup_huge_pmd(pmdp, pmd, addr, next, |
| 131 | 131 | write, pages, nr)) |
| 132 | 132 | return 0; |
| @@ -180,8 +180,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, · 47 unmodified lines | ||
| 180 | 180 | addr = start; |
| 181 | 181 | len = (unsigned long) nr_pages << PAGE_SHIFT; |
| 182 | 182 | end = start + len; |
| 183 | − if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ, | |
| 184 | − (void __user *)start, len))) | |
| 183 | + if ((end < start) || (end > TASK_SIZE)) | |
| 185 | 184 | return 0; |
| 186 | 185 | |
| 187 | 186 | local_irq_save(flags); |
| @@ -229,7 +228,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, · 41 unmodified lines | ||
| 229 | 228 | addr = start; |
| 230 | 229 | len = (unsigned long) nr_pages << PAGE_SHIFT; |
| 231 | 230 | end = start + len; |
| 232 | − if (end < start) | |
| 231 | + if ((end < start) || (end > TASK_SIZE)) | |
| 233 | 232 | goto slow_irqon; |
| 234 | 233 | |
| 235 | 234 | /* |
| @@ -148,7 +148,6 @@ score_rt_sigreturn(struct pt_regs *regs) · 147 unmodified lines | ||
| 148 | 148 | { |
| 149 | 149 | struct rt_sigframe __user *frame; |
| 150 | 150 | sigset_t set; |
| 151 | − stack_t st; | |
| 152 | 151 | int sig; |
| 153 | 152 | |
| 154 | 153 | /* Always make any pending restarted system calls return -EINTR */ |
| @@ -168,12 +167,10 @@ score_rt_sigreturn(struct pt_regs *regs) · 13 unmodified lines | ||
| 168 | 167 | else if (sig) |
| 169 | 168 | force_sig(sig, current); |
| 170 | 169 | |
| 171 | − if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st))) | |
| 172 | − goto badframe; | |
| 173 | − | |
| 174 | 170 | /* It is more difficult to avoid calling this function than to |
| 175 | 171 | call it and ignore errors. */ |
| 176 | − do_sigaltstack((stack_t __user *)&st, NULL, regs->regs[0]); | |
| 172 | + if (do_sigaltstack(&frame->rs_uc.uc_stack, NULL, regs->regs[0]) == -EFAULT) | |
| 173 | + goto badframe; | |
| 177 | 174 | regs->is_syscall = 0; |
| 178 | 175 | |
| 179 | 176 | __asm__ __volatile__( |
| @@ -347,7 +347,6 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3, · 346 unmodified lines | ||
| 347 | 347 | { |
| 348 | 348 | struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (long) REF_REG_SP; |
| 349 | 349 | sigset_t set; |
| 350 | − stack_t __user st; | |
| 351 | 350 | long long ret; |
| 352 | 351 | |
| 353 | 352 | /* Always make any pending restarted system calls return -EINTR */ |
| @@ -365,11 +364,10 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3, · 11 unmodified lines | ||
| 365 | 364 | goto badframe; |
| 366 | 365 | regs->pc -= 4; |
| 367 | 366 | |
| 368 | − if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) | |
| 369 | − goto badframe; | |
| 370 | 367 | /* It is more difficult to avoid calling this function than to |
| 371 | 368 | call it and ignore errors. */ |
| 372 | − do_sigaltstack(&st, NULL, REF_REG_SP); | |
| 369 | + if (do_sigaltstack(&frame->uc.uc_stack, NULL, REF_REG_SP) == -EFAULT) | |
| 370 | + goto badframe; | |
| 373 | 371 | |
| 374 | 372 | return (int) ret; |
| 375 | 373 | |
| @@ -20,6 +20,7 @@ config SPARC · 19 unmodified lines | ||
| 20 | 20 | select HAVE_ARCH_TRACEHOOK |
| 21 | 21 | select SYSCTL_EXCEPTION_TRACE |
| 22 | 22 | select ARCH_WANT_OPTIONAL_GPIOLIB |
| 23 | + select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | |
| 23 | 24 | select RTC_CLASS |
| 24 | 25 | select RTC_DRV_M48T59 |
| 25 | 26 | select HAVE_IRQ_WORK |
| @@ -81,18 +81,18 @@ static void usage(void) · 80 unmodified lines | ||
| 81 | 81 | |
| 82 | 82 | static int start_line(const char *line) |
| 83 | 83 | { |
| 84 | − if (strcmp(line + 8, " T _start\n") == 0) | |
| 84 | + if (strcmp(line + 10, " _start\n") == 0) | |
| 85 | 85 | return 1; |
| 86 | − else if (strcmp(line + 16, " T _start\n") == 0) | |
| 86 | + else if (strcmp(line + 18, " _start\n") == 0) | |
| 87 | 87 | return 1; |
| 88 | 88 | return 0; |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | 91 | static int end_line(const char *line) |
| 92 | 92 | { |
| 93 | − if (strcmp(line + 8, " A _end\n") == 0) | |
| 93 | + if (strcmp(line + 10, " _end\n") == 0) | |
| 94 | 94 | return 1; |
| 95 | − else if (strcmp (line + 16, " A _end\n") == 0) | |
| 95 | + else if (strcmp (line + 18, " _end\n") == 0) | |
| 96 | 96 | return 1; |
| 97 | 97 | return 0; |
| 98 | 98 | } |
| @@ -100,8 +100,8 @@ static int end_line(const char *line) · 1 unmodified line | ||
| 100 | 100 | /* |
| 101 | 101 | * Find address for start and end in System.map. |
| 102 | 102 | * The file looks like this: |
| 103 | − * f0004000 T _start | |
| 104 | − * f0379f79 A _end | |
| 103 | + * f0004000 ... _start | |
| 104 | + * f0379f79 ... _end | |
| 105 | 105 | * 1234567890123456 |
| 106 | 106 | * ^coloumn 1 |
| 107 | 107 | * There is support for 64 bit addresses too. |
| @@ -13,13 +13,13 @@ obj-$(CONFIG_CRYPTO_DES_SPARC64) += camellia-sparc64.o · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | obj-$(CONFIG_CRYPTO_CRC32C_SPARC64) += crc32c-sparc64.o |
| 15 | 15 | |
| 16 | −sha1-sparc64-y := sha1_asm.o sha1_glue.o crop_devid.o | |
| 17 | −sha256-sparc64-y := sha256_asm.o sha256_glue.o crop_devid.o | |
| 18 | −sha512-sparc64-y := sha512_asm.o sha512_glue.o crop_devid.o | |
| 19 | −md5-sparc64-y := md5_asm.o md5_glue.o crop_devid.o | |
| 16 | +sha1-sparc64-y := sha1_asm.o sha1_glue.o | |
| 17 | +sha256-sparc64-y := sha256_asm.o sha256_glue.o | |
| 18 | +sha512-sparc64-y := sha512_asm.o sha512_glue.o | |
| 19 | +md5-sparc64-y := md5_asm.o md5_glue.o | |
| 20 | 20 | |
| 21 | −aes-sparc64-y := aes_asm.o aes_glue.o crop_devid.o | |
| 22 | −des-sparc64-y := des_asm.o des_glue.o crop_devid.o | |
| 23 | −camellia-sparc64-y := camellia_asm.o camellia_glue.o crop_devid.o | |
| 21 | +aes-sparc64-y := aes_asm.o aes_glue.o | |
| 22 | +des-sparc64-y := des_asm.o des_glue.o | |
| 23 | +camellia-sparc64-y := camellia_asm.o camellia_glue.o | |
| 24 | 24 | |
| 25 | −crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o crop_devid.o | |
| 25 | +crc32c-sparc64-y := crc32c_asm.o crc32c_glue.o | |
| @@ -475,3 +475,5 @@ MODULE_LICENSE("GPL"); · 474 unmodified lines | ||
| 475 | 475 | MODULE_DESCRIPTION("AES Secure Hash Algorithm, sparc64 aes opcode accelerated"); |
| 476 | 476 | |
| 477 | 477 | MODULE_ALIAS("aes"); |
| 478 | + | |
| 479 | +#include "crop_devid.c" | |
| @@ -320,3 +320,5 @@ MODULE_LICENSE("GPL"); · 319 unmodified lines | ||
| 320 | 320 | MODULE_DESCRIPTION("Camellia Cipher Algorithm, sparc64 camellia opcode accelerated"); |
| 321 | 321 | |
| 322 | 322 | MODULE_ALIAS("aes"); |
| 323 | + | |
| 324 | +#include "crop_devid.c" | |
| @@ -177,3 +177,5 @@ MODULE_LICENSE("GPL"); · 176 unmodified lines | ||
| 177 | 177 | MODULE_DESCRIPTION("CRC32c (Castagnoli), sparc64 crc32c opcode accelerated"); |
| 178 | 178 | |
| 179 | 179 | MODULE_ALIAS("crc32c"); |
| 180 | + | |
| 181 | +#include "crop_devid.c" | |
| @@ -527,3 +527,5 @@ MODULE_LICENSE("GPL"); · 526 unmodified lines | ||
| 527 | 527 | MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms, sparc64 des opcode accelerated"); |
| 528 | 528 | |
| 529 | 529 | MODULE_ALIAS("des"); |
| 530 | + | |
| 531 | +#include "crop_devid.c" | |
| @@ -186,3 +186,5 @@ MODULE_LICENSE("GPL"); · 185 unmodified lines | ||
| 186 | 186 | MODULE_DESCRIPTION("MD5 Secure Hash Algorithm, sparc64 md5 opcode accelerated"); |
| 187 | 187 | |
| 188 | 188 | MODULE_ALIAS("md5"); |
| 189 | + | |
| 190 | +#include "crop_devid.c" | |
| @@ -181,3 +181,5 @@ MODULE_LICENSE("GPL"); · 180 unmodified lines | ||
| 181 | 181 | MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, sparc64 sha1 opcode accelerated"); |
| 182 | 182 | |
| 183 | 183 | MODULE_ALIAS("sha1"); |
| 184 | + | |
| 185 | +#include "crop_devid.c" | |
| @@ -239,3 +239,5 @@ MODULE_DESCRIPTION("SHA-224 and SHA-256 Secure Hash Algorithm, sparc64 sha256 op · 238 unmodified lines | ||
| 239 | 239 | |
| 240 | 240 | MODULE_ALIAS("sha224"); |
| 241 | 241 | MODULE_ALIAS("sha256"); |
| 242 | + | |
| 243 | +#include "crop_devid.c" | |
| @@ -224,3 +224,5 @@ MODULE_DESCRIPTION("SHA-384 and SHA-512 Secure Hash Algorithm, sparc64 sha512 op · 223 unmodified lines | ||
| 224 | 224 | |
| 225 | 225 | MODULE_ALIAS("sha384"); |
| 226 | 226 | MODULE_ALIAS("sha512"); |
| 227 | + | |
| 228 | +#include "crop_devid.c" | |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | /* atomic.h: Thankfully the V9 is at least reasonable for this |
| 2 | 2 | * stuff. |
| 3 | 3 | * |
| 4 | − * Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com) | |
| 4 | + * Copyright (C) 1996, 1997, 2000, 2012 David S. Miller (davem@redhat.com) | |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | 7 | #ifndef __ARCH_SPARC64_ATOMIC__ |
| @@ -106,6 +106,8 @@ static inline long atomic64_add_unless(atomic64_t *v, long a, long u) · 98 unmodified lines | ||
| 106 | 106 | |
| 107 | 107 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) |
| 108 | 108 | |
| 109 | +extern long atomic64_dec_if_positive(atomic64_t *v); | |
| 110 | + | |
| 109 | 111 | /* Atomic operations are already serializing */ |
| 110 | 112 | #define smp_mb__before_atomic_dec() barrier() |
| 111 | 113 | #define smp_mb__after_atomic_dec() barrier() |
| @@ -1,6 +1,46 @@ | ||
| 1 | 1 | #ifndef _SPARC64_BACKOFF_H |
| 2 | 2 | #define _SPARC64_BACKOFF_H |
| 3 | 3 | |
| 4 | +/* The macros in this file implement an exponential backoff facility | |
| 5 | + * for atomic operations. | |
| 6 | + * | |
| 7 | + * When multiple threads compete on an atomic operation, it is | |
| 8 | + * possible for one thread to be continually denied a successful | |
| 9 | + * completion of the compare-and-swap instruction. Heavily | |
| 10 | + * threaded cpu implementations like Niagara can compound this | |
| 11 | + * problem even further. | |
| 12 | + * | |
| 13 | + * When an atomic operation fails and needs to be retried, we spin a | |
| 14 | + * certain number of times. At each subsequent failure of the same | |
| 15 | + * operation we double the spin count, realizing an exponential | |
| 16 | + * backoff. | |
| 17 | + * | |
| 18 | + * When we spin, we try to use an operation that will cause the | |
| 19 | + * current cpu strand to block, and therefore make the core fully | |
| 20 | + * available to any other other runnable strands. There are two | |
| 21 | + * options, based upon cpu capabilities. | |
| 22 | + * | |
| 23 | + * On all cpus prior to SPARC-T4 we do three dummy reads of the | |
| 24 | + * condition code register. Each read blocks the strand for something | |
| 25 | + * between 40 and 50 cpu cycles. | |
| 26 | + * | |
| 27 | + * For SPARC-T4 and later we have a special "pause" instruction | |
| 28 | + * available. This is implemented using writes to register %asr27. | |
| 29 | + * The cpu will block the number of cycles written into the register, | |
| 30 | + * unless a disrupting trap happens first. SPARC-T4 specifically | |
| 31 | + * implements pause with a granularity of 8 cycles. Each strand has | |
| 32 | + * an internal pause counter which decrements every 8 cycles. So the | |
| 33 | + * chip shifts the %asr27 value down by 3 bits, and writes the result | |
| 34 | + * into the pause counter. If a value smaller than 8 is written, the | |
| 35 | + * chip blocks for 1 cycle. | |
| 36 | + * | |
| 37 | + * To achieve the same amount of backoff as the three %ccr reads give | |
| 38 | + * on earlier chips, we shift the backoff value up by 7 bits. (Three | |
| 39 | + * %ccr reads block for about 128 cycles, 1 << 7 == 128) We write the | |
| 40 | + * whole amount we want to block into the pause register, rather than | |
| 41 | + * loop writing 128 each time. | |
| 42 | + */ | |
| 43 | + | |
| 4 | 44 | #define BACKOFF_LIMIT (4 * 1024) |
| 5 | 45 | |
| 6 | 46 | #ifdef CONFIG_SMP |
| @@ -11,16 +51,25 @@ · 4 unmodified lines | ||
| 11 | 51 | #define BACKOFF_LABEL(spin_label, continue_label) \ |
| 12 | 52 | spin_label |
| 13 | 53 | |
| 14 | −#define BACKOFF_SPIN(reg, tmp, label) \ | |
| 15 | − mov reg, tmp; \ | |
| 16 | −88: brnz,pt tmp, 88b; \ | |
| 17 | − sub tmp, 1, tmp; \ | |
| 18 | − set BACKOFF_LIMIT, tmp; \ | |
| 19 | − cmp reg, tmp; \ | |
| 20 | − bg,pn %xcc, label; \ | |
| 21 | − nop; \ | |
| 22 | − ba,pt %xcc, label; \ | |
| 23 | − sllx reg, 1, reg; | |
| 54 | +#define BACKOFF_SPIN(reg, tmp, label) \ | |
| 55 | + mov reg, tmp; \ | |
| 56 | +88: rd %ccr, %g0; \ | |
| 57 | + rd %ccr, %g0; \ | |
| 58 | + rd %ccr, %g0; \ | |
| 59 | + .section .pause_3insn_patch,"ax";\ | |
| 60 | + .word 88b; \ | |
| 61 | + sllx tmp, 7, tmp; \ | |
| 62 | + wr tmp, 0, %asr27; \ | |
| 63 | + clr tmp; \ | |
| 64 | + .previous; \ | |
| 65 | + brnz,pt tmp, 88b; \ | |
| 66 | + sub tmp, 1, tmp; \ | |
| 67 | + set BACKOFF_LIMIT, tmp; \ | |
| 68 | + cmp reg, tmp; \ | |
| 69 | + bg,pn %xcc, label; \ | |
| 70 | + nop; \ | |
| 71 | + ba,pt %xcc, label; \ | |
| 72 | + sllx reg, 1, reg; | |
| 24 | 73 | |
| 25 | 74 | #else |
| 26 | 75 | |
| @@ -232,9 +232,10 @@ static inline void __user *arch_compat_alloc_user_space(long len) · 231 unmodified lines | ||
| 232 | 232 | struct pt_regs *regs = current_thread_info()->kregs; |
| 233 | 233 | unsigned long usp = regs->u_regs[UREG_I6]; |
| 234 | 234 | |
| 235 | − if (!(test_thread_flag(TIF_32BIT))) | |
| 235 | + if (test_thread_64bit_stack(usp)) | |
| 236 | 236 | usp += STACK_BIAS; |
| 237 | − else | |
| 237 | + | |
| 238 | + if (test_thread_flag(TIF_32BIT)) | |
| 238 | 239 | usp &= 0xffffffffUL; |
| 239 | 240 | |
| 240 | 241 | usp -= len; |
| @@ -196,7 +196,22 @@ extern unsigned long get_wchan(struct task_struct *task); · 195 unmodified lines | ||
| 196 | 196 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->tpc) |
| 197 | 197 | #define KSTK_ESP(tsk) (task_pt_regs(tsk)->u_regs[UREG_FP]) |
| 198 | 198 | |
| 199 | −#define cpu_relax() barrier() | |
| 199 | +/* Please see the commentary in asm/backoff.h for a description of | |
| 200 | + * what these instructions are doing and how they have been choosen. | |
| 201 | + * To make a long story short, we are trying to yield the current cpu | |
| 202 | + * strand during busy loops. | |
| 203 | + */ | |
| 204 | +#define cpu_relax() asm volatile("\n99:\n\t" \ | |
| 205 | + "rd %%ccr, %%g0\n\t" \ | |
| 206 | + "rd %%ccr, %%g0\n\t" \ | |
| 207 | + "rd %%ccr, %%g0\n\t" \ | |
| 208 | + ".section .pause_3insn_patch,\"ax\"\n\t"\ | |
| 209 | + ".word 99b\n\t" \ | |
| 210 | + "wr %%g0, 128, %%asr27\n\t" \ | |
| 211 | + "nop\n\t" \ | |
| 212 | + "nop\n\t" \ | |
| 213 | + ".previous" \ | |
| 214 | + ::: "memory") | |
| 200 | 215 | |
| 201 | 216 | /* Prefetch support. This is tuned for UltraSPARC-III and later. |
| 202 | 217 | * UltraSPARC-I will treat these as nops, and UltraSPARC-II has |
| @@ -63,5 +63,13 @@ extern char *of_console_options; · 62 unmodified lines | ||
| 63 | 63 | extern void irq_trans_init(struct device_node *dp); |
| 64 | 64 | extern char *build_path_component(struct device_node *dp); |
| 65 | 65 | |
| 66 | +/* SPARC has local implementations */ | |
| 67 | +extern int of_address_to_resource(struct device_node *dev, int index, | |
| 68 | + struct resource *r); | |
| 69 | +#define of_address_to_resource of_address_to_resource | |
| 70 | + | |
| 71 | +void __iomem *of_iomap(struct device_node *node, int index); | |
| 72 | +#define of_iomap of_iomap | |
| 73 | + | |
| 66 | 74 | #endif /* __KERNEL__ */ |
| 67 | 75 | #endif /* _SPARC_PROM_H */ |
| @@ -259,6 +259,11 @@ static inline bool test_and_clear_restore_sigmask(void) · 258 unmodified lines | ||
| 259 | 259 | |
| 260 | 260 | #define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG) |
| 261 | 261 | |
| 262 | +#define thread32_stack_is_64bit(__SP) (((__SP) & 0x1) != 0) | |
| 263 | +#define test_thread_64bit_stack(__SP) \ | |
| 264 | + ((test_thread_flag(TIF_32BIT) && !thread32_stack_is_64bit(__SP)) ? \ | |
| 265 | + false : true) | |
| 266 | + | |
| 262 | 267 | #endif /* !__ASSEMBLY__ */ |
| 263 | 268 | |
| 264 | 269 | #endif /* __KERNEL__ */ |
| @@ -372,7 +372,9 @@ etrap_spill_fixup_64bit: \ · 371 unmodified lines | ||
| 372 | 372 | |
| 373 | 373 | /* Normal 32bit spill */ |
| 374 | 374 | #define SPILL_2_GENERIC(ASI) \ |
| 375 | − srl %sp, 0, %sp; \ | |
| 375 | + and %sp, 1, %g3; \ | |
| 376 | + brnz,pn %g3, (. - (128 + 4)); \ | |
| 377 | + srl %sp, 0, %sp; \ | |
| 376 | 378 | stwa %l0, [%sp + %g0] ASI; \ |
| 377 | 379 | mov 0x04, %g3; \ |
| 378 | 380 | stwa %l1, [%sp + %g3] ASI; \ |
| @@ -398,14 +400,16 @@ etrap_spill_fixup_64bit: \ · 19 unmodified lines | ||
| 398 | 400 | stwa %i6, [%g1 + %g0] ASI; \ |
| 399 | 401 | stwa %i7, [%g1 + %g3] ASI; \ |
| 400 | 402 | saved; \ |
| 401 | − retry; nop; nop; \ | |
| 403 | + retry; \ | |
| 402 | 404 | b,a,pt %xcc, spill_fixup_dax; \ |
| 403 | 405 | b,a,pt %xcc, spill_fixup_mna; \ |
| 404 | 406 | b,a,pt %xcc, spill_fixup; |
| 405 | 407 | |
| 406 | 408 | #define SPILL_2_GENERIC_ETRAP \ |
| 407 | 409 | etrap_user_spill_32bit: \ |
| 408 | − srl %sp, 0, %sp; \ | |
| 410 | + and %sp, 1, %g3; \ | |
| 411 | + brnz,pn %g3, etrap_user_spill_64bit; \ | |
| 412 | + srl %sp, 0, %sp; \ | |
| 409 | 413 | stwa %l0, [%sp + 0x00] %asi; \ |
| 410 | 414 | stwa %l1, [%sp + 0x04] %asi; \ |
| 411 | 415 | stwa %l2, [%sp + 0x08] %asi; \ |
| @@ -427,7 +431,7 @@ etrap_user_spill_32bit: \ · 15 unmodified lines | ||
| 427 | 431 | ba,pt %xcc, etrap_save; \ |
| 428 | 432 | wrpr %g1, %cwp; \ |
| 429 | 433 | nop; nop; nop; nop; \ |
| 430 | − nop; nop; nop; nop; \ | |
| 434 | + nop; nop; \ | |
| 431 | 435 | ba,a,pt %xcc, etrap_spill_fixup_32bit; \ |
| 432 | 436 | ba,a,pt %xcc, etrap_spill_fixup_32bit; \ |
| 433 | 437 | ba,a,pt %xcc, etrap_spill_fixup_32bit; |
| @@ -592,7 +596,9 @@ user_rtt_fill_64bit: \ · 158 unmodified lines | ||
| 592 | 596 | |
| 593 | 597 | /* Normal 32bit fill */ |
| 594 | 598 | #define FILL_2_GENERIC(ASI) \ |
| 595 | − srl %sp, 0, %sp; \ | |
| 599 | + and %sp, 1, %g3; \ | |
| 600 | + brnz,pn %g3, (. - (128 + 4)); \ | |
| 601 | + srl %sp, 0, %sp; \ | |
| 596 | 602 | lduwa [%sp + %g0] ASI, %l0; \ |
| 597 | 603 | mov 0x04, %g2; \ |
| 598 | 604 | mov 0x08, %g3; \ |
| @@ -616,14 +622,16 @@ user_rtt_fill_64bit: \ · 17 unmodified lines | ||
| 616 | 622 | lduwa [%g1 + %g3] ASI, %i6; \ |
| 617 | 623 | lduwa [%g1 + %g5] ASI, %i7; \ |
| 618 | 624 | restored; \ |
| 619 | − retry; nop; nop; nop; nop; \ | |
| 625 | + retry; nop; nop; \ | |
| 620 | 626 | b,a,pt %xcc, fill_fixup_dax; \ |
| 621 | 627 | b,a,pt %xcc, fill_fixup_mna; \ |
| 622 | 628 | b,a,pt %xcc, fill_fixup; |
| 623 | 629 | |
| 624 | 630 | #define FILL_2_GENERIC_RTRAP \ |
| 625 | 631 | user_rtt_fill_32bit: \ |
| 626 | − srl %sp, 0, %sp; \ | |
| 632 | + and %sp, 1, %g3; \ | |
| 633 | + brnz,pn %g3, user_rtt_fill_64bit; \ | |
| 634 | + srl %sp, 0, %sp; \ | |
| 627 | 635 | lduwa [%sp + 0x00] %asi, %l0; \ |
| 628 | 636 | lduwa [%sp + 0x04] %asi, %l1; \ |
| 629 | 637 | lduwa [%sp + 0x08] %asi, %l2; \ |
| @@ -643,7 +651,7 @@ user_rtt_fill_32bit: \ · 13 unmodified lines | ||
| 643 | 651 | ba,pt %xcc, user_rtt_pre_restore; \ |
| 644 | 652 | restored; \ |
| 645 | 653 | nop; nop; nop; nop; nop; \ |
| 646 | − nop; nop; nop; nop; nop; \ | |
| 654 | + nop; nop; nop; \ | |
| 647 | 655 | ba,a,pt %xcc, user_rtt_fill_fixup; \ |
| 648 | 656 | ba,a,pt %xcc, user_rtt_fill_fixup; \ |
| 649 | 657 | ba,a,pt %xcc, user_rtt_fill_fixup; |
| @@ -405,8 +405,13 @@ · 404 unmodified lines | ||
| 405 | 405 | #define __NR_setns 337 |
| 406 | 406 | #define __NR_process_vm_readv 338 |
| 407 | 407 | #define __NR_process_vm_writev 339 |
| 408 | +#define __NR_kern_features 340 | |
| 409 | +#define __NR_kcmp 341 | |
| 408 | 410 | |
| 409 | −#define NR_syscalls 340 | |
| 411 | +#define NR_syscalls 342 | |
| 412 | + | |
| 413 | +/* Bitmask values returned from kern_features system call. */ | |
| 414 | +#define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 | |
| 410 | 415 | |
| 411 | 416 | #ifdef __32bit_syscall_numbers__ |
| 412 | 417 | /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, |
| @@ -59,6 +59,13 @@ struct popc_6insn_patch_entry { · 58 unmodified lines | ||
| 59 | 59 | extern struct popc_6insn_patch_entry __popc_6insn_patch, |
| 60 | 60 | __popc_6insn_patch_end; |
| 61 | 61 | |
| 62 | +struct pause_patch_entry { | |
| 63 | + unsigned int addr; | |
| 64 | + unsigned int insns[3]; | |
| 65 | +}; | |
| 66 | +extern struct pause_patch_entry __pause_3insn_patch, | |
| 67 | + __pause_3insn_patch_end; | |
| 68 | + | |
| 62 | 69 | extern void __init per_cpu_patch(void); |
| 63 | 70 | extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *, |
| 64 | 71 | struct sun4v_1insn_patch_entry *); |
| @@ -56,11 +56,13 @@ static inline unsigned int leon_eirq_get(int cpu) · 55 unmodified lines | ||
| 56 | 56 | static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc) |
| 57 | 57 | { |
| 58 | 58 | unsigned int eirq; |
| 59 | + struct irq_bucket *p; | |
| 59 | 60 | int cpu = sparc_leon3_cpuid(); |
| 60 | 61 | |
| 61 | 62 | eirq = leon_eirq_get(cpu); |
| 62 | − if ((eirq & 0x10) && irq_map[eirq]->irq) /* bit4 tells if IRQ happened */ | |
| 63 | − generic_handle_irq(irq_map[eirq]->irq); | |
| 63 | + p = irq_map[eirq]; | |
| 64 | + if ((eirq & 0x10) && p && p->irq) /* bit4 tells if IRQ happened */ | |
| 65 | + generic_handle_irq(p->irq); | |
| 64 | 66 | } |
| 65 | 67 | |
| 66 | 68 | /* The extended IRQ controller has been found, this function registers it */ |
| @@ -1762,15 +1762,25 @@ static void perf_callchain_user_32(struct perf_callchain_entry *entry, · 1761 unmodified lines | ||
| 1762 | 1762 | |
| 1763 | 1763 | ufp = regs->u_regs[UREG_I6] & 0xffffffffUL; |
| 1764 | 1764 | do { |
| 1765 | − struct sparc_stackf32 *usf, sf; | |
| 1766 | 1765 | unsigned long pc; |
| 1767 | 1766 | |
| 1768 | − usf = (struct sparc_stackf32 *) ufp; | |
| 1769 | − if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) | |
| 1770 | − break; | |
| 1767 | + if (thread32_stack_is_64bit(ufp)) { | |
| 1768 | + struct sparc_stackf *usf, sf; | |
| 1771 | 1769 | |
| 1772 | − pc = sf.callers_pc; | |
| 1773 | − ufp = (unsigned long)sf.fp; | |
| 1770 | + ufp += STACK_BIAS; | |
| 1771 | + usf = (struct sparc_stackf *) ufp; | |
| 1772 | + if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) | |
| 1773 | + break; | |
| 1774 | + pc = sf.callers_pc & 0xffffffff; | |
| 1775 | + ufp = ((unsigned long) sf.fp) & 0xffffffff; | |
| 1776 | + } else { | |
| 1777 | + struct sparc_stackf32 *usf, sf; | |
| 1778 | + usf = (struct sparc_stackf32 *) ufp; | |
| 1779 | + if (__copy_from_user_inatomic(&sf, usf, sizeof(sf))) | |
| 1780 | + break; | |
| 1781 | + pc = sf.callers_pc; | |
| 1782 | + ufp = (unsigned long)sf.fp; | |
| 1783 | + } | |
| 1774 | 1784 | perf_callchain_store(entry, pc); |
| 1775 | 1785 | } while (entry->nr < PERF_MAX_STACK_DEPTH); |
| 1776 | 1786 | } |
| @@ -452,13 +452,16 @@ void flush_thread(void) · 451 unmodified lines | ||
| 452 | 452 | /* It's a bit more tricky when 64-bit tasks are involved... */ |
| 453 | 453 | static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) |
| 454 | 454 | { |
| 455 | + bool stack_64bit = test_thread_64bit_stack(psp); | |
| 455 | 456 | unsigned long fp, distance, rval; |
| 456 | 457 | |
| 457 | − if (!(test_thread_flag(TIF_32BIT))) { | |
| 458 | + if (stack_64bit) { | |
| 458 | 459 | csp += STACK_BIAS; |
| 459 | 460 | psp += STACK_BIAS; |
| 460 | 461 | __get_user(fp, &(((struct reg_window __user *)psp)->ins[6])); |
| 461 | 462 | fp += STACK_BIAS; |
| 463 | + if (test_thread_flag(TIF_32BIT)) | |
| 464 | + fp &= 0xffffffff; | |
| 462 | 465 | } else |
| 463 | 466 | __get_user(fp, &(((struct reg_window32 __user *)psp)->ins[6])); |
| 464 | 467 | |
| @@ -472,7 +475,7 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp) · 7 unmodified lines | ||
| 472 | 475 | rval = (csp - distance); |
| 473 | 476 | if (copy_in_user((void __user *) rval, (void __user *) psp, distance)) |
| 474 | 477 | rval = 0; |
| 475 | − else if (test_thread_flag(TIF_32BIT)) { | |
| 478 | + else if (!stack_64bit) { | |
| 476 | 479 | if (put_user(((u32)csp), |
| 477 | 480 | &(((struct reg_window32 __user *)rval)->ins[6]))) |
| 478 | 481 | rval = 0; |
| @@ -507,18 +510,18 @@ void synchronize_user_stack(void) · 28 unmodified lines | ||
| 507 | 510 | |
| 508 | 511 | flush_user_windows(); |
| 509 | 512 | if ((window = get_thread_wsaved()) != 0) { |
| 510 | − int winsize = sizeof(struct reg_window); | |
| 511 | − int bias = 0; | |
| 512 | − | |
| 513 | − if (test_thread_flag(TIF_32BIT)) | |
| 514 | − winsize = sizeof(struct reg_window32); | |
| 515 | − else | |
| 516 | − bias = STACK_BIAS; | |
| 517 | − | |
| 518 | 513 | window -= 1; |
| 519 | 514 | do { |
| 520 | − unsigned long sp = (t->rwbuf_stkptrs[window] + bias); | |
| 521 | 515 | struct reg_window *rwin = &t->reg_window[window]; |
| 516 | + int winsize = sizeof(struct reg_window); | |
| 517 | + unsigned long sp; | |
| 518 | + | |
| 519 | + sp = t->rwbuf_stkptrs[window]; | |
| 520 | + | |
| 521 | + if (test_thread_64bit_stack(sp)) | |
| 522 | + sp += STACK_BIAS; | |
| 523 | + else | |
| 524 | + winsize = sizeof(struct reg_window32); | |
| 522 | 525 | |
| 523 | 526 | if (!copy_to_user((char __user *)sp, rwin, winsize)) { |
| 524 | 527 | shift_window_buffer(window, get_thread_wsaved() - 1, t); |
| @@ -544,13 +547,6 @@ void fault_in_user_windows(void) · 19 unmodified lines | ||
| 544 | 547 | { |
| 545 | 548 | struct thread_info *t = current_thread_info(); |
| 546 | 549 | unsigned long window; |
| 547 | − int winsize = sizeof(struct reg_window); | |
| 548 | − int bias = 0; | |
| 549 | − | |
| 550 | − if (test_thread_flag(TIF_32BIT)) | |
| 551 | − winsize = sizeof(struct reg_window32); | |
| 552 | − else | |
| 553 | − bias = STACK_BIAS; | |
| 554 | 550 | |
| 555 | 551 | flush_user_windows(); |
| 556 | 552 | window = get_thread_wsaved(); |
| @@ -558,8 +554,16 @@ void fault_in_user_windows(void) · 1 unmodified line | ||
| 558 | 554 | if (likely(window != 0)) { |
| 559 | 555 | window -= 1; |
| 560 | 556 | do { |
| 561 | − unsigned long sp = (t->rwbuf_stkptrs[window] + bias); | |
| 562 | 557 | struct reg_window *rwin = &t->reg_window[window]; |
| 558 | + int winsize = sizeof(struct reg_window); | |
| 559 | + unsigned long sp; | |
| 560 | + | |
| 561 | + sp = t->rwbuf_stkptrs[window]; | |
| 562 | + | |
| 563 | + if (test_thread_64bit_stack(sp)) | |
| 564 | + sp += STACK_BIAS; | |
| 565 | + else | |
| 566 | + winsize = sizeof(struct reg_window32); | |
| 563 | 567 | |
| 564 | 568 | if (unlikely(sp & 0x7UL)) |
| 565 | 569 | stack_unaligned(sp); |
| @@ -151,7 +151,7 @@ static int regwindow64_get(struct task_struct *target, · 150 unmodified lines | ||
| 151 | 151 | { |
| 152 | 152 | unsigned long rw_addr = regs->u_regs[UREG_I6]; |
| 153 | 153 | |
| 154 | − if (test_tsk_thread_flag(current, TIF_32BIT)) { | |
| 154 | + if (!test_thread_64bit_stack(rw_addr)) { | |
| 155 | 155 | struct reg_window32 win32; |
| 156 | 156 | int i; |
| 157 | 157 | |
| @@ -176,7 +176,7 @@ static int regwindow64_set(struct task_struct *target, · 18 unmodified lines | ||
| 176 | 176 | { |
| 177 | 177 | unsigned long rw_addr = regs->u_regs[UREG_I6]; |
| 178 | 178 | |
| 179 | − if (test_tsk_thread_flag(current, TIF_32BIT)) { | |
| 179 | + if (!test_thread_64bit_stack(rw_addr)) { | |
| 180 | 180 | struct reg_window32 win32; |
| 181 | 181 | int i; |
| 182 | 182 | |
| @@ -316,6 +316,25 @@ static void __init popc_patch(void) · 315 unmodified lines | ||
| 316 | 316 | } |
| 317 | 317 | } |
| 318 | 318 | |
| 319 | +static void __init pause_patch(void) | |
| 320 | +{ | |
| 321 | + struct pause_patch_entry *p; | |
| 322 | + | |
| 323 | + p = &__pause_3insn_patch; | |
| 324 | + while (p < &__pause_3insn_patch_end) { | |
| 325 | + unsigned long i, addr = p->addr; | |
| 326 | + | |
| 327 | + for (i = 0; i < 3; i++) { | |
| 328 | + *(unsigned int *) (addr + (i * 4)) = p->insns[i]; | |
| 329 | + wmb(); | |
| 330 | + __asm__ __volatile__("flush %0" | |
| 331 | + : : "r" (addr + (i * 4))); | |
| 332 | + } | |
| 333 | + | |
| 334 | + p++; | |
| 335 | + } | |
| 336 | +} | |
| 337 | + | |
| 319 | 338 | #ifdef CONFIG_SMP |
| 320 | 339 | void __init boot_cpu_id_too_large(int cpu) |
| 321 | 340 | { |
| @@ -528,6 +547,8 @@ static void __init init_sparc64_elf_hwcap(void) · 206 unmodified lines | ||
| 528 | 547 | |
| 529 | 548 | if (sparc64_elf_hwcap & AV_SPARC_POPC) |
| 530 | 549 | popc_patch(); |
| 550 | + if (sparc64_elf_hwcap & AV_SPARC_PAUSE) | |
| 551 | + pause_patch(); | |
| 531 | 552 | } |
| 532 | 553 | |
| 533 | 554 | void __init setup_arch(char **cmdline_p) |
| @@ -295,9 +295,7 @@ void do_rt_sigreturn(struct pt_regs *regs) · 294 unmodified lines | ||
| 295 | 295 | err |= restore_fpu_state(regs, fpu_save); |
| 296 | 296 | |
| 297 | 297 | err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); |
| 298 | − err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf); | |
| 299 | − | |
| 300 | − if (err) | |
| 298 | + if (err || do_sigaltstack(&sf->stack, NULL, (unsigned long)sf) == -EFAULT) | |
| 301 | 299 | goto segv; |
| 302 | 300 | |
| 303 | 301 | err |= __get_user(rwin_save, &sf->rwin_save); |
| @@ -47,7 +47,7 @@ STUB: sra REG1, 0, REG1; \ · 46 unmodified lines | ||
| 47 | 47 | sra REG4, 0, REG4 |
| 48 | 48 | |
| 49 | 49 | SIGN1(sys32_exit, sparc_exit, %o0) |
| 50 | −SIGN1(sys32_exit_group, sys_exit_group, %o0) | |
| 50 | +SIGN1(sys32_exit_group, sparc_exit_group, %o0) | |
| 51 | 51 | SIGN1(sys32_wait4, compat_sys_wait4, %o2) |
| 52 | 52 | SIGN1(sys32_creat, sys_creat, %o1) |
| 53 | 53 | SIGN1(sys32_mknod, sys_mknod, %o1) |
| @@ -751,3 +751,8 @@ int kernel_execve(const char *filename, · 750 unmodified lines | ||
| 751 | 751 | : "cc"); |
| 752 | 752 | return __res; |
| 753 | 753 | } |
| 754 | + | |
| 755 | +asmlinkage long sys_kern_features(void) | |
| 756 | +{ | |
| 757 | + return KERN_FEATURE_MIXED_MODE_STACK; | |
| 758 | +} | |
| @@ -118,10 +118,20 @@ ret_from_syscall: · 117 unmodified lines | ||
| 118 | 118 | ba,pt %xcc, ret_sys_call |
| 119 | 119 | ldx [%sp + PTREGS_OFF + PT_V9_I0], %o0 |
| 120 | 120 | |
| 121 | + .globl sparc_exit_group | |
| 122 | + .type sparc_exit_group,#function | |
| 123 | +sparc_exit_group: | |
| 124 | + sethi %hi(sys_exit_group), %g7 | |
| 125 | + ba,pt %xcc, 1f | |
| 126 | + or %g7, %lo(sys_exit_group), %g7 | |
| 127 | + .size sparc_exit_group,.-sparc_exit_group | |
| 128 | + | |
| 121 | 129 | .globl sparc_exit |
| 122 | 130 | .type sparc_exit,#function |
| 123 | 131 | sparc_exit: |
| 124 | − rdpr %pstate, %g2 | |
| 132 | + sethi %hi(sys_exit), %g7 | |
| 133 | + or %g7, %lo(sys_exit), %g7 | |
| 134 | +1: rdpr %pstate, %g2 | |
| 125 | 135 | wrpr %g2, PSTATE_IE, %pstate |
| 126 | 136 | rdpr %otherwin, %g1 |
| 127 | 137 | rdpr %cansave, %g3 |
| @@ -129,7 +139,7 @@ sparc_exit: · 1 unmodified line | ||
| 129 | 139 | wrpr %g3, 0x0, %cansave |
| 130 | 140 | wrpr %g0, 0x0, %otherwin |
| 131 | 141 | wrpr %g2, 0x0, %pstate |
| 132 | − ba,pt %xcc, sys_exit | |
| 142 | + jmpl %g7, %g0 | |
| 133 | 143 | stb %g0, [%g6 + TI_WSAVED] |
| 134 | 144 | .size sparc_exit,.-sparc_exit |
| 135 | 145 | |
| @@ -85,3 +85,4 @@ sys_call_table: · 84 unmodified lines | ||
| 85 | 85 | /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init |
| 86 | 86 | /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime |
| 87 | 87 | /*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev |
| 88 | +/*340*/ .long sys_ni_syscall, sys_kcmp | |
| @@ -86,6 +86,7 @@ sys_call_table32: · 85 unmodified lines | ||
| 86 | 86 | .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init |
| 87 | 87 | /*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime |
| 88 | 88 | .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev |
| 89 | +/*340*/ .word sys_kern_features, sys_kcmp | |
| 89 | 90 | |
| 90 | 91 | #endif /* CONFIG_COMPAT */ |
| 91 | 92 | |
| @@ -132,7 +133,7 @@ sys_call_table: · 40 unmodified lines | ||
| 132 | 133 | /*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents |
| 133 | 134 | .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr |
| 134 | 135 | /*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall |
| 135 | − .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname | |
| 136 | + .word sys_setpgid, sys_fremovexattr, sys_tkill, sparc_exit_group, sys_newuname | |
| 136 | 137 | /*190*/ .word sys_init_module, sys_sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl |
| 137 | 138 | .word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask |
| 138 | 139 | /*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall |
| @@ -163,3 +164,4 @@ sys_call_table: · 24 unmodified lines | ||
| 163 | 164 | .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init |
| 164 | 165 | /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime |
| 165 | 166 | .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev |
| 167 | +/*340*/ .word sys_kern_features, sys_kcmp | |
| @@ -113,21 +113,24 @@ static inline long sign_extend_imm13(long imm) · 112 unmodified lines | ||
| 113 | 113 | |
| 114 | 114 | static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) |
| 115 | 115 | { |
| 116 | − unsigned long value; | |
| 116 | + unsigned long value, fp; | |
| 117 | 117 | |
| 118 | 118 | if (reg < 16) |
| 119 | 119 | return (!reg ? 0 : regs->u_regs[reg]); |
| 120 | + | |
| 121 | + fp = regs->u_regs[UREG_FP]; | |
| 122 | + | |
| 120 | 123 | if (regs->tstate & TSTATE_PRIV) { |
| 121 | 124 | struct reg_window *win; |
| 122 | − win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); | |
| 125 | + win = (struct reg_window *)(fp + STACK_BIAS); | |
| 123 | 126 | value = win->locals[reg - 16]; |
| 124 | − } else if (test_thread_flag(TIF_32BIT)) { | |
| 127 | + } else if (!test_thread_64bit_stack(fp)) { | |
| 125 | 128 | struct reg_window32 __user *win32; |
| 126 | − win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | |
| 129 | + win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); | |
| 127 | 130 | get_user(value, &win32->locals[reg - 16]); |
| 128 | 131 | } else { |
| 129 | 132 | struct reg_window __user *win; |
| 130 | − win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); | |
| 133 | + win = (struct reg_window __user *)(fp + STACK_BIAS); | |
| 131 | 134 | get_user(value, &win->locals[reg - 16]); |
| 132 | 135 | } |
| 133 | 136 | return value; |
| @@ -135,19 +138,24 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) · 1 unmodified line | ||
| 135 | 138 | |
| 136 | 139 | static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs) |
| 137 | 140 | { |
| 141 | + unsigned long fp; | |
| 142 | + | |
| 138 | 143 | if (reg < 16) |
| 139 | 144 | return ®s->u_regs[reg]; |
| 145 | + | |
| 146 | + fp = regs->u_regs[UREG_FP]; | |
| 147 | + | |
| 140 | 148 | if (regs->tstate & TSTATE_PRIV) { |
| 141 | 149 | struct reg_window *win; |
| 142 | − win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); | |
| 150 | + win = (struct reg_window *)(fp + STACK_BIAS); | |
| 143 | 151 | return &win->locals[reg - 16]; |
| 144 | − } else if (test_thread_flag(TIF_32BIT)) { | |
| 152 | + } else if (!test_thread_64bit_stack(fp)) { | |
| 145 | 153 | struct reg_window32 *win32; |
| 146 | − win32 = (struct reg_window32 *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | |
| 154 | + win32 = (struct reg_window32 *)((unsigned long)((u32)fp)); | |
| 147 | 155 | return (unsigned long *)&win32->locals[reg - 16]; |
| 148 | 156 | } else { |
| 149 | 157 | struct reg_window *win; |
| 150 | − win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); | |
| 158 | + win = (struct reg_window *)(fp + STACK_BIAS); | |
| 151 | 159 | return &win->locals[reg - 16]; |
| 152 | 160 | } |
| 153 | 161 | } |
| @@ -392,13 +400,15 @@ int handle_popc(u32 insn, struct pt_regs *regs) · 238 unmodified lines | ||
| 392 | 400 | if (rd) |
| 393 | 401 | regs->u_regs[rd] = ret; |
| 394 | 402 | } else { |
| 395 | − if (test_thread_flag(TIF_32BIT)) { | |
| 403 | + unsigned long fp = regs->u_regs[UREG_FP]; | |
| 404 | + | |
| 405 | + if (!test_thread_64bit_stack(fp)) { | |
| 396 | 406 | struct reg_window32 __user *win32; |
| 397 | − win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | |
| 407 | + win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); | |
| 398 | 408 | put_user(ret, &win32->locals[rd - 16]); |
| 399 | 409 | } else { |
| 400 | 410 | struct reg_window __user *win; |
| 401 | − win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); | |
| 411 | + win = (struct reg_window __user *)(fp + STACK_BIAS); | |
| 402 | 412 | put_user(ret, &win->locals[rd - 16]); |
| 403 | 413 | } |
| 404 | 414 | } |
| @@ -554,7 +564,7 @@ void handle_ld_nf(u32 insn, struct pt_regs *regs) · 149 unmodified lines | ||
| 554 | 564 | reg[0] = 0; |
| 555 | 565 | if ((insn & 0x780000) == 0x180000) |
| 556 | 566 | reg[1] = 0; |
| 557 | − } else if (test_thread_flag(TIF_32BIT)) { | |
| 567 | + } else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) { | |
| 558 | 568 | put_user(0, (int __user *) reg); |
| 559 | 569 | if ((insn & 0x780000) == 0x180000) |
| 560 | 570 | put_user(0, ((int __user *) reg) + 1); |
| @@ -149,21 +149,24 @@ static inline void maybe_flush_windows(unsigned int rs1, unsigned int rs2, · 148 unmodified lines | ||
| 149 | 149 | |
| 150 | 150 | static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) |
| 151 | 151 | { |
| 152 | − unsigned long value; | |
| 152 | + unsigned long value, fp; | |
| 153 | 153 | |
| 154 | 154 | if (reg < 16) |
| 155 | 155 | return (!reg ? 0 : regs->u_regs[reg]); |
| 156 | + | |
| 157 | + fp = regs->u_regs[UREG_FP]; | |
| 158 | + | |
| 156 | 159 | if (regs->tstate & TSTATE_PRIV) { |
| 157 | 160 | struct reg_window *win; |
| 158 | − win = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS); | |
| 161 | + win = (struct reg_window *)(fp + STACK_BIAS); | |
| 159 | 162 | value = win->locals[reg - 16]; |
| 160 | − } else if (test_thread_flag(TIF_32BIT)) { | |
| 163 | + } else if (!test_thread_64bit_stack(fp)) { | |
| 161 | 164 | struct reg_window32 __user *win32; |
| 162 | − win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | |
| 165 | + win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); | |
| 163 | 166 | get_user(value, &win32->locals[reg - 16]); |
| 164 | 167 | } else { |
| 165 | 168 | struct reg_window __user *win; |
| 166 | − win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); | |
| 169 | + win = (struct reg_window __user *)(fp + STACK_BIAS); | |
| 167 | 170 | get_user(value, &win->locals[reg - 16]); |
| 168 | 171 | } |
| 169 | 172 | return value; |
| @@ -172,16 +175,18 @@ static unsigned long fetch_reg(unsigned int reg, struct pt_regs *regs) · 2 unmodified lines | ||
| 172 | 175 | static inline unsigned long __user *__fetch_reg_addr_user(unsigned int reg, |
| 173 | 176 | struct pt_regs *regs) |
| 174 | 177 | { |
| 178 | + unsigned long fp = regs->u_regs[UREG_FP]; | |
| 179 | + | |
| 175 | 180 | BUG_ON(reg < 16); |
| 176 | 181 | BUG_ON(regs->tstate & TSTATE_PRIV); |
| 177 | 182 | |
| 178 | − if (test_thread_flag(TIF_32BIT)) { | |
| 183 | + if (!test_thread_64bit_stack(fp)) { | |
| 179 | 184 | struct reg_window32 __user *win32; |
| 180 | − win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); | |
| 185 | + win32 = (struct reg_window32 __user *)((unsigned long)((u32)fp)); | |
| 181 | 186 | return (unsigned long __user *)&win32->locals[reg - 16]; |
| 182 | 187 | } else { |
| 183 | 188 | struct reg_window __user *win; |
| 184 | − win = (struct reg_window __user *)(regs->u_regs[UREG_FP] + STACK_BIAS); | |
| 189 | + win = (struct reg_window __user *)(fp + STACK_BIAS); | |
| 185 | 190 | return &win->locals[reg - 16]; |
| 186 | 191 | } |
| 187 | 192 | } |
| @@ -204,7 +209,7 @@ static void store_reg(struct pt_regs *regs, unsigned long val, unsigned long rd) · 16 unmodified lines | ||
| 204 | 209 | } else { |
| 205 | 210 | unsigned long __user *rd_user = __fetch_reg_addr_user(rd, regs); |
| 206 | 211 | |
| 207 | − if (test_thread_flag(TIF_32BIT)) | |
| 212 | + if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) | |
| 208 | 213 | __put_user((u32)val, (u32 __user *)rd_user); |
| 209 | 214 | else |
| 210 | 215 | __put_user(val, rd_user); |
| @@ -132,6 +132,11 @@ SECTIONS · 131 unmodified lines | ||
| 132 | 132 | *(.popc_6insn_patch) |
| 133 | 133 | __popc_6insn_patch_end = .; |
| 134 | 134 | } |
| 135 | + .pause_3insn_patch : { | |
| 136 | + __pause_3insn_patch = .; | |
| 137 | + *(.pause_3insn_patch) | |
| 138 | + __pause_3insn_patch_end = .; | |
| 139 | + } | |
| 135 | 140 | PERCPU_SECTION(SMP_CACHE_BYTES) |
| 136 | 141 | |
| 137 | 142 | . = ALIGN(PAGE_SIZE); |
| @@ -43,6 +43,8 @@ spill_fixup_mna: · 42 unmodified lines | ||
| 43 | 43 | spill_fixup_dax: |
| 44 | 44 | TRAP_LOAD_THREAD_REG(%g6, %g1) |
| 45 | 45 | ldx [%g6 + TI_FLAGS], %g1 |
| 46 | + andcc %sp, 0x1, %g0 | |
| 47 | + movne %icc, 0, %g1 | |
| 46 | 48 | andcc %g1, _TIF_32BIT, %g0 |
| 47 | 49 | ldub [%g6 + TI_WSAVED], %g1 |
| 48 | 50 | sll %g1, 3, %g3 |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | /* atomic.S: These things are too big to do inline. |
| 2 | 2 | * |
| 3 | − * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) | |
| 3 | + * Copyright (C) 1999, 2007 2012 David S. Miller (davem@davemloft.net) | |
| 4 | 4 | */ |
| 5 | 5 | |
| 6 | 6 | #include <linux/linkage.h> |
| @@ -117,3 +117,17 @@ ENTRY(atomic64_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */ · 110 unmodified lines | ||
| 117 | 117 | sub %g1, %o0, %o0 |
| 118 | 118 | 2: BACKOFF_SPIN(%o2, %o3, 1b) |
| 119 | 119 | ENDPROC(atomic64_sub_ret) |
| 120 | + | |
| 121 | +ENTRY(atomic64_dec_if_positive) /* %o0 = atomic_ptr */ | |
| 122 | + BACKOFF_SETUP(%o2) | |
| 123 | +1: ldx [%o0], %g1 | |
| 124 | + brlez,pn %g1, 3f | |
| 125 | + sub %g1, 1, %g7 | |
| 126 | + casx [%o0], %g1, %g7 | |
| 127 | + cmp %g1, %g7 | |
| 128 | + bne,pn %xcc, BACKOFF_LABEL(2f, 1b) | |
| 129 | + nop | |
| 130 | +3: retl | |
| 131 | + sub %g1, 1, %o0 | |
| 132 | +2: BACKOFF_SPIN(%o2, %o3, 1b) | |
| 133 | +ENDPROC(atomic64_dec_if_positive) | |
| @@ -116,6 +116,7 @@ EXPORT_SYMBOL(atomic64_add); · 115 unmodified lines | ||
| 116 | 116 | EXPORT_SYMBOL(atomic64_add_ret); |
| 117 | 117 | EXPORT_SYMBOL(atomic64_sub); |
| 118 | 118 | EXPORT_SYMBOL(atomic64_sub_ret); |
| 119 | +EXPORT_SYMBOL(atomic64_dec_if_positive); | |
| 119 | 120 | |
| 120 | 121 | /* Atomic bit operations. */ |
| 121 | 122 | EXPORT_SYMBOL(test_and_set_bit); |
| @@ -320,7 +320,7 @@ int do_mathemu(struct pt_regs *regs, struct fpustate *f, bool illegal_insn_trap) · 319 unmodified lines | ||
| 320 | 320 | XR = 0; |
| 321 | 321 | else if (freg < 16) |
| 322 | 322 | XR = regs->u_regs[freg]; |
| 323 | − else if (test_thread_flag(TIF_32BIT)) { | |
| 323 | + else if (!test_thread_64bit_stack(regs->u_regs[UREG_FP])) { | |
| 324 | 324 | struct reg_window32 __user *win32; |
| 325 | 325 | flushw_user (); |
| 326 | 326 | win32 = (struct reg_window32 __user *)((unsigned long)((u32)regs->u_regs[UREG_FP])); |
| @@ -32,13 +32,14 @@ void flush_thread(void) · 31 unmodified lines | ||
| 32 | 32 | "err = %d\n", ret); |
| 33 | 33 | force_sig(SIGKILL, current); |
| 34 | 34 | } |
| 35 | + get_safe_registers(current_pt_regs()->regs.gp, | |
| 36 | + current_pt_regs()->regs.fp); | |
| 35 | 37 | |
| 36 | 38 | __switch_mm(¤t->mm->context.id); |
| 37 | 39 | } |
| 38 | 40 | |
| 39 | 41 | void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) |
| 40 | 42 | { |
| 41 | − get_safe_registers(regs->regs.gp, regs->regs.fp); | |
| 42 | 43 | PT_REGS_IP(regs) = eip; |
| 43 | 44 | PT_REGS_SP(regs) = esp; |
| 44 | 45 | current->ptrace &= ~PT_DTRACE; |
| @@ -16,6 +16,8 @@ config UNICORE32 · 15 unmodified lines | ||
| 16 | 16 | select ARCH_WANT_FRAME_POINTERS |
| 17 | 17 | select GENERIC_IOMAP |
| 18 | 18 | select MODULES_USE_ELF_REL |
| 19 | + select GENERIC_KERNEL_THREAD | |
| 20 | + select GENERIC_KERNEL_EXECVE | |
| 19 | 21 | help |
| 20 | 22 | UniCore-32 is 32-bit Instruction Set Architecture, |
| 21 | 23 | including a series of low-power-consumption RISC chip |
| @@ -64,6 +66,9 @@ config GENERIC_CALIBRATE_DELAY · 42 unmodified lines | ||
| 64 | 66 | config ARCH_MAY_HAVE_PC_FDC |
| 65 | 67 | bool |
| 66 | 68 | |
| 69 | +config ZONE_DMA | |
| 70 | + def_bool y | |
| 71 | + | |
| 67 | 72 | config NEED_DMA_MAP_STATE |
| 68 | 73 | def_bool y |
| 69 | 74 | |
| @@ -216,7 +221,7 @@ config PUV3_GPIO · 146 unmodified lines | ||
| 216 | 221 | bool |
| 217 | 222 | depends on !ARCH_FPGA |
| 218 | 223 | select GENERIC_GPIO |
| 219 | − select GPIO_SYSFS if EXPERIMENTAL | |
| 224 | + select GPIO_SYSFS | |
| 220 | 225 | default y |
| 221 | 226 | |
| 222 | 227 | if PUV3_NB0916 |
| @@ -1,4 +1,3 @@ | ||
| 1 | −include include/asm-generic/Kbuild.asm | |
| 2 | 1 | |
| 3 | 2 | generic-y += atomic.h |
| 4 | 3 | generic-y += auxvec.h |
| @@ -19,9 +19,4 @@ extern void die(const char *msg, struct pt_regs *regs, int err); · 18 unmodified lines | ||
| 19 | 19 | extern void uc32_notify_die(const char *str, struct pt_regs *regs, |
| 20 | 20 | struct siginfo *info, unsigned long err, unsigned long trap); |
| 21 | 21 | |
| 22 | −extern asmlinkage void __backtrace(void); | |
| 23 | −extern asmlinkage void c_backtrace(unsigned long fp, int pmode); | |
| 24 | − | |
| 25 | −extern void __show_regs(struct pt_regs *); | |
| 26 | − | |
| 27 | 22 | #endif /* __UNICORE_BUG_H__ */ |
| @@ -35,7 +35,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, · 34 unmodified lines | ||
| 35 | 35 | : "memory", "cc"); |
| 36 | 36 | break; |
| 37 | 37 | default: |
| 38 | − ret = __xchg_bad_pointer(); | |
| 38 | + __xchg_bad_pointer(); | |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | 41 | return ret; |
| @@ -1 +0,0 @@ | ||
| 1 | −#include <asm-generic/kvm_para.h> | |
| @@ -72,11 +72,6 @@ unsigned long get_wchan(struct task_struct *p); · 71 unmodified lines | ||
| 72 | 72 | |
| 73 | 73 | #define cpu_relax() barrier() |
| 74 | 74 | |
| 75 | −/* | |
| 76 | − * Create a new kernel thread | |
| 77 | − */ | |
| 78 | −extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); | |
| 79 | − | |
| 80 | 75 | #define task_pt_regs(p) \ |
| 81 | 76 | ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) |
| 82 | 77 | |
| @@ -12,80 +12,10 @@ · 11 unmodified lines | ||
| 12 | 12 | #ifndef __UNICORE_PTRACE_H__ |
| 13 | 13 | #define __UNICORE_PTRACE_H__ |
| 14 | 14 | |
| 15 | −#define PTRACE_GET_THREAD_AREA 22 | |
| 16 | − | |
| 17 | −/* | |
| 18 | − * PSR bits | |
| 19 | − */ | |
| 20 | −#define USER_MODE 0x00000010 | |
| 21 | −#define REAL_MODE 0x00000011 | |
| 22 | −#define INTR_MODE 0x00000012 | |
| 23 | −#define PRIV_MODE 0x00000013 | |
| 24 | −#define ABRT_MODE 0x00000017 | |
| 25 | −#define EXTN_MODE 0x0000001b | |
| 26 | −#define SUSR_MODE 0x0000001f | |
| 27 | −#define MODE_MASK 0x0000001f | |
| 28 | −#define PSR_R_BIT 0x00000040 | |
| 29 | −#define PSR_I_BIT 0x00000080 | |
| 30 | −#define PSR_V_BIT 0x10000000 | |
| 31 | −#define PSR_C_BIT 0x20000000 | |
| 32 | −#define PSR_Z_BIT 0x40000000 | |
| 33 | −#define PSR_S_BIT 0x80000000 | |
| 34 | − | |
| 35 | −/* | |
| 36 | − * Groups of PSR bits | |
| 37 | − */ | |
| 38 | −#define PSR_f 0xff000000 /* Flags */ | |
| 39 | −#define PSR_c 0x000000ff /* Control */ | |
| 15 | +#include <uapi/asm/ptrace.h> | |
| 40 | 16 | |
| 41 | 17 | #ifndef __ASSEMBLY__ |
| 42 | 18 | |
| 43 | −/* | |
| 44 | − * This struct defines the way the registers are stored on the | |
| 45 | − * stack during a system call. Note that sizeof(struct pt_regs) | |
| 46 | − * has to be a multiple of 8. | |
| 47 | − */ | |
| 48 | −struct pt_regs { | |
| 49 | − unsigned long uregs[34]; | |
| 50 | −}; | |
| 51 | − | |
| 52 | −#define UCreg_asr uregs[32] | |
| 53 | −#define UCreg_pc uregs[31] | |
| 54 | −#define UCreg_lr uregs[30] | |
| 55 | −#define UCreg_sp uregs[29] | |
| 56 | −#define UCreg_ip uregs[28] | |
| 57 | −#define UCreg_fp uregs[27] | |
| 58 | −#define UCreg_26 uregs[26] | |
| 59 | −#define UCreg_25 uregs[25] | |
| 60 | −#define UCreg_24 uregs[24] | |
| 61 | −#define UCreg_23 uregs[23] | |
| 62 | −#define UCreg_22 uregs[22] | |
| 63 | −#define UCreg_21 uregs[21] | |
| 64 | −#define UCreg_20 uregs[20] | |
| 65 | −#define UCreg_19 uregs[19] | |
| 66 | −#define UCreg_18 uregs[18] | |
| 67 | −#define UCreg_17 uregs[17] | |
| 68 | −#define UCreg_16 uregs[16] | |
| 69 | −#define UCreg_15 uregs[15] | |
| 70 | −#define UCreg_14 uregs[14] | |
| 71 | −#define UCreg_13 uregs[13] | |
| 72 | −#define UCreg_12 uregs[12] | |
| 73 | −#define UCreg_11 uregs[11] | |
| 74 | −#define UCreg_10 uregs[10] | |
| 75 | −#define UCreg_09 uregs[9] | |
| 76 | −#define UCreg_08 uregs[8] | |
| 77 | −#define UCreg_07 uregs[7] | |
| 78 | −#define UCreg_06 uregs[6] | |
| 79 | −#define UCreg_05 uregs[5] | |
| 80 | −#define UCreg_04 uregs[4] | |
| 81 | −#define UCreg_03 uregs[3] | |
| 82 | −#define UCreg_02 uregs[2] | |
| 83 | −#define UCreg_01 uregs[1] | |
| 84 | −#define UCreg_00 uregs[0] | |
| 85 | −#define UCreg_ORIG_00 uregs[33] | |
| 86 | − | |
| 87 | −#ifdef __KERNEL__ | |
| 88 | − | |
| 89 | 19 | #define user_mode(regs) \ |
| 90 | 20 | (processor_mode(regs) == USER_MODE) |
| 91 | 21 | |
| @@ -125,9 +55,5 @@ static inline int valid_user_regs(struct pt_regs *regs) · 33 unmodified lines | ||
| 125 | 55 | |
| 126 | 56 | #define instruction_pointer(regs) ((regs)->UCreg_pc) |
| 127 | 57 | |
| 128 | −#endif /* __KERNEL__ */ | |
| 129 | − | |
| 130 | 58 | #endif /* __ASSEMBLY__ */ |
| 131 | − | |
| 132 | 59 | #endif |
| 133 | − | |
| @@ -1,3 +1,10 @@ | ||
| 1 | 1 | # UAPI Header export list |
| 2 | 2 | include include/uapi/asm-generic/Kbuild.asm |
| 3 | 3 | |
| 4 | +header-y += byteorder.h | |
| 5 | +header-y += kvm_para.h | |
| 6 | +header-y += ptrace.h | |
| 7 | +header-y += sigcontext.h | |
| 8 | +header-y += unistd.h | |
| 9 | + | |
| 10 | +generic-y += kvm_para.h | |
File renamed without changes.
| @@ -0,0 +1,90 @@ | ||
| 1 | +/* | |
| 2 | + * linux/arch/unicore32/include/asm/ptrace.h | |
| 3 | + * | |
| 4 | + * Code specific to PKUnity SoC and UniCore ISA | |
| 5 | + * | |
| 6 | + * Copyright (C) 2001-2010 GUAN Xue-tao | |
| 7 | + * | |
| 8 | + * This program is free software; you can redistribute it and/or modify | |
| 9 | + * it under the terms of the GNU General Public License version 2 as | |
| 10 | + * published by the Free Software Foundation. | |
| 11 | + */ | |
| 12 | +#ifndef _UAPI__UNICORE_PTRACE_H__ | |
| 13 | +#define _UAPI__UNICORE_PTRACE_H__ | |
| 14 | + | |
| 15 | +#define PTRACE_GET_THREAD_AREA 22 | |
| 16 | + | |
| 17 | +/* | |
| 18 | + * PSR bits | |
| 19 | + */ | |
| 20 | +#define USER_MODE 0x00000010 | |
| 21 | +#define REAL_MODE 0x00000011 | |
| 22 | +#define INTR_MODE 0x00000012 | |
| 23 | +#define PRIV_MODE 0x00000013 | |
| 24 | +#define ABRT_MODE 0x00000017 | |
| 25 | +#define EXTN_MODE 0x0000001b | |
| 26 | +#define SUSR_MODE 0x0000001f | |
| 27 | +#define MODE_MASK 0x0000001f | |
| 28 | +#define PSR_R_BIT 0x00000040 | |
| 29 | +#define PSR_I_BIT 0x00000080 | |
| 30 | +#define PSR_V_BIT 0x10000000 | |
| 31 | +#define PSR_C_BIT 0x20000000 | |
| 32 | +#define PSR_Z_BIT 0x40000000 | |
| 33 | +#define PSR_S_BIT 0x80000000 | |
| 34 | + | |
| 35 | +/* | |
| 36 | + * Groups of PSR bits | |
| 37 | + */ | |
| 38 | +#define PSR_f 0xff000000 /* Flags */ | |
| 39 | +#define PSR_c 0x000000ff /* Control */ | |
| 40 | + | |
| 41 | +#ifndef __ASSEMBLY__ | |
| 42 | + | |
| 43 | +/* | |
| 44 | + * This struct defines the way the registers are stored on the | |
| 45 | + * stack during a system call. Note that sizeof(struct pt_regs) | |
| 46 | + * has to be a multiple of 8. | |
| 47 | + */ | |
| 48 | +struct pt_regs { | |
| 49 | + unsigned long uregs[34]; | |
| 50 | +}; | |
| 51 | + | |
| 52 | +#define UCreg_asr uregs[32] | |
| 53 | +#define UCreg_pc uregs[31] | |
| 54 | +#define UCreg_lr uregs[30] | |
| 55 | +#define UCreg_sp uregs[29] | |
| 56 | +#define UCreg_ip uregs[28] | |
| 57 | +#define UCreg_fp uregs[27] | |
| 58 | +#define UCreg_26 uregs[26] | |
| 59 | +#define UCreg_25 uregs[25] | |
| 60 | +#define UCreg_24 uregs[24] | |
| 61 | +#define UCreg_23 uregs[23] | |
| 62 | +#define UCreg_22 uregs[22] | |
| 63 | +#define UCreg_21 uregs[21] | |
| 64 | +#define UCreg_20 uregs[20] | |
| 65 | +#define UCreg_19 uregs[19] | |
| 66 | +#define UCreg_18 uregs[18] | |
| 67 | +#define UCreg_17 uregs[17] | |
| 68 | +#define UCreg_16 uregs[16] | |
| 69 | +#define UCreg_15 uregs[15] | |
| 70 | +#define UCreg_14 uregs[14] | |
| 71 | +#define UCreg_13 uregs[13] | |
| 72 | +#define UCreg_12 uregs[12] | |
| 73 | +#define UCreg_11 uregs[11] | |
| 74 | +#define UCreg_10 uregs[10] | |
| 75 | +#define UCreg_09 uregs[9] | |
| 76 | +#define UCreg_08 uregs[8] | |
| 77 | +#define UCreg_07 uregs[7] | |
| 78 | +#define UCreg_06 uregs[6] | |
| 79 | +#define UCreg_05 uregs[5] | |
| 80 | +#define UCreg_04 uregs[4] | |
| 81 | +#define UCreg_03 uregs[3] | |
| 82 | +#define UCreg_02 uregs[2] | |
| 83 | +#define UCreg_01 uregs[1] | |
| 84 | +#define UCreg_00 uregs[0] | |
| 85 | +#define UCreg_ORIG_00 uregs[33] | |
| 86 | + | |
| 87 | + | |
| 88 | +#endif /* __ASSEMBLY__ */ | |
| 89 | + | |
| 90 | +#endif /* _UAPI__UNICORE_PTRACE_H__ */ | |
File renamed without changes.
| @@ -12,3 +12,4 @@ · 11 unmodified lines | ||
| 12 | 12 | |
| 13 | 13 | /* Use the standard ABI for syscalls. */ |
| 14 | 14 | #include <asm-generic/unistd.h> |
| 15 | +#define __ARCH_WANT_SYS_EXECVE | |
| @@ -573,17 +573,16 @@ ENDPROC(ret_to_user) · 572 unmodified lines | ||
| 573 | 573 | */ |
| 574 | 574 | ENTRY(ret_from_fork) |
| 575 | 575 | b.l schedule_tail |
| 576 | − get_thread_info tsk | |
| 577 | − ldw r1, [tsk+], #TI_FLAGS @ check for syscall tracing | |
| 578 | − mov why, #1 | |
| 579 | − cand.a r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? | |
| 580 | − beq ret_slow_syscall | |
| 581 | − mov r1, sp | |
| 582 | − mov r0, #1 @ trace exit [IP = 1] | |
| 583 | − b.l syscall_trace | |
| 584 | 576 | b ret_slow_syscall |
| 585 | 577 | ENDPROC(ret_from_fork) |
| 586 | 578 | |
| 579 | +ENTRY(ret_from_kernel_thread) | |
| 580 | + b.l schedule_tail | |
| 581 | + mov r0, r5 | |
| 582 | + adr lr, ret_slow_syscall | |
| 583 | + mov pc, r4 | |
| 584 | +ENDPROC(ret_from_kernel_thread) | |
| 585 | + | |
| 587 | 586 | /*============================================================================= |
| 588 | 587 | * SWI handler |
| 589 | 588 | *----------------------------------------------------------------------------- |
| @@ -669,11 +668,6 @@ __cr_alignment: · 79 unmodified lines | ||
| 669 | 668 | #endif |
| 670 | 669 | .ltorg |
| 671 | 670 | |
| 672 | −ENTRY(sys_execve) | |
| 673 | − add r3, sp, #S_OFF | |
| 674 | − b __sys_execve | |
| 675 | −ENDPROC(sys_execve) | |
| 676 | − | |
| 677 | 671 | ENTRY(sys_clone) |
| 678 | 672 | add ip, sp, #S_OFF |
| 679 | 673 | stw ip, [sp+], #4 |
| @@ -258,6 +258,7 @@ void release_thread(struct task_struct *dead_task) · 257 unmodified lines | ||
| 258 | 258 | } |
| 259 | 259 | |
| 260 | 260 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); |
| 261 | +asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread"); | |
| 261 | 262 | |
| 262 | 263 | int |
| 263 | 264 | copy_thread(unsigned long clone_flags, unsigned long stack_start, |
| @@ -266,17 +267,22 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start, · 2 unmodified lines | ||
| 266 | 267 | struct thread_info *thread = task_thread_info(p); |
| 267 | 268 | struct pt_regs *childregs = task_pt_regs(p); |
| 268 | 269 | |
| 269 | − *childregs = *regs; | |
| 270 | − childregs->UCreg_00 = 0; | |
| 271 | − childregs->UCreg_sp = stack_start; | |
| 272 | − | |
| 273 | 270 | memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); |
| 274 | 271 | thread->cpu_context.sp = (unsigned long)childregs; |
| 275 | − thread->cpu_context.pc = (unsigned long)ret_from_fork; | |
| 276 | − | |
| 277 | − if (clone_flags & CLONE_SETTLS) | |
| 278 | − childregs->UCreg_16 = regs->UCreg_03; | |
| 272 | + if (unlikely(!regs)) { | |
| 273 | + thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread; | |
| 274 | + thread->cpu_context.r4 = stack_start; | |
| 275 | + thread->cpu_context.r5 = stk_sz; | |
| 276 | + memset(childregs, 0, sizeof(struct pt_regs)); | |
| 277 | + } else { | |
| 278 | + thread->cpu_context.pc = (unsigned long)ret_from_fork; | |
| 279 | + *childregs = *regs; | |
| 280 | + childregs->UCreg_00 = 0; | |
| 281 | + childregs->UCreg_sp = stack_start; | |
| 279 | 282 | |
| 283 | + if (clone_flags & CLONE_SETTLS) | |
| 284 | + childregs->UCreg_16 = regs->UCreg_03; | |
| 285 | + } | |
| 280 | 286 | return 0; |
| 281 | 287 | } |
| 282 | 288 | |
| @@ -305,42 +311,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fp) · 22 unmodified lines | ||
| 305 | 311 | } |
| 306 | 312 | EXPORT_SYMBOL(dump_fpu); |
| 307 | 313 | |
| 308 | −/* | |
| 309 | − * Shuffle the argument into the correct register before calling the | |
| 310 | − * thread function. r1 is the thread argument, r2 is the pointer to | |
| 311 | − * the thread function, and r3 points to the exit function. | |
| 312 | − */ | |
| 313 | −asm(".pushsection .text\n" | |
| 314 | −" .align\n" | |
| 315 | −" .type kernel_thread_helper, #function\n" | |
| 316 | −"kernel_thread_helper:\n" | |
| 317 | −" mov.a asr, r7\n" | |
| 318 | −" mov r0, r4\n" | |
| 319 | −" mov lr, r6\n" | |
| 320 | −" mov pc, r5\n" | |
| 321 | −" .size kernel_thread_helper, . - kernel_thread_helper\n" | |
| 322 | −" .popsection"); | |
| 323 | − | |
| 324 | −/* | |
| 325 | − * Create a kernel thread. | |
| 326 | − */ | |
| 327 | −pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | |
| 328 | −{ | |
| 329 | − struct pt_regs regs; | |
| 330 | − | |
| 331 | − memset(®s, 0, sizeof(regs)); | |
| 332 | − | |
| 333 | − regs.UCreg_04 = (unsigned long)arg; | |
| 334 | − regs.UCreg_05 = (unsigned long)fn; | |
| 335 | − regs.UCreg_06 = (unsigned long)do_exit; | |
| 336 | − regs.UCreg_07 = PRIV_MODE; | |
| 337 | − regs.UCreg_pc = (unsigned long)kernel_thread_helper; | |
| 338 | − regs.UCreg_asr = regs.UCreg_07 | PSR_I_BIT; | |
| 339 | − | |
| 340 | − return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); | |
| 341 | −} | |
| 342 | −EXPORT_SYMBOL(kernel_thread); | |
| 343 | − | |
| 344 | 314 | unsigned long get_wchan(struct task_struct *p) |
| 345 | 315 | { |
| 346 | 316 | struct stackframe frame; |
| @@ -30,4 +30,10 @@ extern char __vectors_start[], __vectors_end[]; · 29 unmodified lines | ||
| 30 | 30 | extern void kernel_thread_helper(void); |
| 31 | 31 | |
| 32 | 32 | extern void __init early_signal_init(void); |
| 33 | + | |
| 34 | +extern asmlinkage void __backtrace(void); | |
| 35 | +extern asmlinkage void c_backtrace(unsigned long fp, int pmode); | |
| 36 | + | |
| 37 | +extern void __show_regs(struct pt_regs *); | |
| 38 | + | |
| 33 | 39 | #endif |
| @@ -42,69 +42,6 @@ asmlinkage long __sys_clone(unsigned long clone_flags, unsigned long newsp, · 41 unmodified lines | ||
| 42 | 42 | parent_tid, child_tid); |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | −/* sys_execve() executes a new program. | |
| 46 | − * This is called indirectly via a small wrapper | |
| 47 | − */ | |
| 48 | −asmlinkage long __sys_execve(const char __user *filename, | |
| 49 | − const char __user *const __user *argv, | |
| 50 | − const char __user *const __user *envp, | |
| 51 | − struct pt_regs *regs) | |
| 52 | −{ | |
| 53 | − int error; | |
| 54 | − struct filename *fn; | |
| 55 | − | |
| 56 | − fn = getname(filename); | |
| 57 | − error = PTR_ERR(fn); | |
| 58 | − if (IS_ERR(fn)) | |
| 59 | − goto out; | |
| 60 | − error = do_execve(fn->name, argv, envp, regs); | |
| 61 | − putname(fn); | |
| 62 | −out: | |
| 63 | − return error; | |
| 64 | −} | |
| 65 | − | |
| 66 | −int kernel_execve(const char *filename, | |
| 67 | − const char *const argv[], | |
| 68 | − const char *const envp[]) | |
| 69 | −{ | |
| 70 | − struct pt_regs regs; | |
| 71 | − int ret; | |
| 72 | − | |
| 73 | − memset(®s, 0, sizeof(struct pt_regs)); | |
| 74 | − ret = do_execve(filename, | |
| 75 | − (const char __user *const __user *)argv, | |
| 76 | − (const char __user *const __user *)envp, ®s); | |
| 77 | − if (ret < 0) | |
| 78 | − goto out; | |
| 79 | − | |
| 80 | − /* | |
| 81 | − * Save argc to the register structure for userspace. | |
| 82 | − */ | |
| 83 | − regs.UCreg_00 = ret; | |
| 84 | − | |
| 85 | − /* | |
| 86 | − * We were successful. We won't be returning to our caller, but | |
| 87 | − * instead to user space by manipulating the kernel stack. | |
| 88 | − */ | |
| 89 | − asm("add r0, %0, %1\n\t" | |
| 90 | − "mov r1, %2\n\t" | |
| 91 | − "mov r2, %3\n\t" | |
| 92 | − "mov r22, #0\n\t" /* not a syscall */ | |
| 93 | − "mov r23, %0\n\t" /* thread structure */ | |
| 94 | − "b.l memmove\n\t" /* copy regs to top of stack */ | |
| 95 | − "mov sp, r0\n\t" /* reposition stack pointer */ | |
| 96 | − "b ret_to_user" | |
| 97 | − : | |
| 98 | − : "r" (current_thread_info()), | |
| 99 | − "Ir" (THREAD_START_SP - sizeof(regs)), | |
| 100 | − "r" (®s), | |
| 101 | − "Ir" (sizeof(regs)) | |
| 102 | − : "r0", "r1", "r2", "r3", "ip", "lr", "memory"); | |
| 103 | − | |
| 104 | − out: | |
| 105 | − return ret; | |
| 106 | −} | |
| 107 | − | |
| 108 | 45 | /* Note: used by the compat code even in 64-bit Linux. */ |
| 109 | 46 | SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, |
| 110 | 47 | unsigned long, prot, unsigned long, flags, |
| @@ -168,7 +168,7 @@ static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma) · 167 unmodified lines | ||
| 168 | 168 | } |
| 169 | 169 | |
| 170 | 170 | static int __do_pf(struct mm_struct *mm, unsigned long addr, unsigned int fsr, |
| 171 | − struct task_struct *tsk) | |
| 171 | + unsigned int flags, struct task_struct *tsk) | |
| 172 | 172 | { |
| 173 | 173 | struct vm_area_struct *vma; |
| 174 | 174 | int fault; |
| @@ -194,14 +194,7 @@ good_area: · 19 unmodified lines | ||
| 194 | 194 | * If for any reason at all we couldn't handle the fault, make |
| 195 | 195 | * sure we exit gracefully rather than endlessly redo the fault. |
| 196 | 196 | */ |
| 197 | − fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, | |
| 198 | − (!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0); | |
| 199 | − if (unlikely(fault & VM_FAULT_ERROR)) | |
| 200 | − return fault; | |
| 201 | − if (fault & VM_FAULT_MAJOR) | |
| 202 | − tsk->maj_flt++; | |
| 203 | − else | |
| 204 | − tsk->min_flt++; | |
| 197 | + fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, flags); | |
| 205 | 198 | return fault; |
| 206 | 199 | |
| 207 | 200 | check_stack: |
| @@ -216,6 +209,8 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) · 8 unmodified lines | ||
| 216 | 209 | struct task_struct *tsk; |
| 217 | 210 | struct mm_struct *mm; |
| 218 | 211 | int fault, sig, code; |
| 212 | + unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | | |
| 213 | + ((!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0); | |
| 219 | 214 | |
| 220 | 215 | tsk = current; |
| 221 | 216 | mm = tsk->mm; |
| @@ -236,6 +231,7 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) · 14 unmodified lines | ||
| 236 | 231 | if (!user_mode(regs) |
| 237 | 232 | && !search_exception_tables(regs->UCreg_pc)) |
| 238 | 233 | goto no_context; |
| 234 | +retry: | |
| 239 | 235 | down_read(&mm->mmap_sem); |
| 240 | 236 | } else { |
| 241 | 237 | /* |
| @@ -251,7 +247,28 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) · 9 unmodified lines | ||
| 251 | 247 | #endif |
| 252 | 248 | } |
| 253 | 249 | |
| 254 | − fault = __do_pf(mm, addr, fsr, tsk); | |
| 250 | + fault = __do_pf(mm, addr, fsr, flags, tsk); | |
| 251 | + | |
| 252 | + /* If we need to retry but a fatal signal is pending, handle the | |
| 253 | + * signal first. We do not need to release the mmap_sem because | |
| 254 | + * it would already be released in __lock_page_or_retry in | |
| 255 | + * mm/filemap.c. */ | |
| 256 | + if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) | |
| 257 | + return 0; | |
| 258 | + | |
| 259 | + if (!(fault & VM_FAULT_ERROR) && (flags & FAULT_FLAG_ALLOW_RETRY)) { | |
| 260 | + if (fault & VM_FAULT_MAJOR) | |
| 261 | + tsk->maj_flt++; | |
| 262 | + else | |
| 263 | + tsk->min_flt++; | |
| 264 | + if (fault & VM_FAULT_RETRY) { | |
| 265 | + /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk | |
| 266 | + * of starvation. */ | |
| 267 | + flags &= ~FAULT_FLAG_ALLOW_RETRY; | |
| 268 | + goto retry; | |
| 269 | + } | |
| 270 | + } | |
| 271 | + | |
| 255 | 272 | up_read(&mm->mmap_sem); |
| 256 | 273 | |
| 257 | 274 | /* |
| @@ -12,6 +12,8 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <asm/setup.h> |
| 13 | 13 | #include <asm/desc.h> |
| 14 | 14 | |
| 15 | +#undef memcpy /* Use memcpy from misc.c */ | |
| 16 | + | |
| 15 | 17 | #include "eboot.h" |
| 16 | 18 | |
| 17 | 19 | static efi_system_table_t *sys_table; |
| @@ -476,6 +476,3 @@ die: · 475 unmodified lines | ||
| 476 | 476 | setup_corrupt: |
| 477 | 477 | .byte 7 |
| 478 | 478 | .string "No setup signature found...\n" |
| 479 | − | |
| 480 | − .data | |
| 481 | −dummy: .long 0 | |
| @@ -12,6 +12,7 @@ header-y += mce.h · 11 unmodified lines | ||
| 12 | 12 | header-y += msr-index.h |
| 13 | 13 | header-y += msr.h |
| 14 | 14 | header-y += mtrr.h |
| 15 | +header-y += perf_regs.h | |
| 15 | 16 | header-y += posix_types_32.h |
| 16 | 17 | header-y += posix_types_64.h |
| 17 | 18 | header-y += posix_types_x32.h |
| @@ -19,8 +20,10 @@ header-y += prctl.h · 1 unmodified line | ||
| 19 | 20 | header-y += processor-flags.h |
| 20 | 21 | header-y += ptrace-abi.h |
| 21 | 22 | header-y += sigcontext32.h |
| 23 | +header-y += svm.h | |
| 22 | 24 | header-y += ucontext.h |
| 23 | 25 | header-y += vm86.h |
| 26 | +header-y += vmx.h | |
| 24 | 27 | header-y += vsyscall.h |
| 25 | 28 | |
| 26 | 29 | genhdr-y += unistd_32.h |
| @@ -35,7 +35,7 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...); · 34 unmodified lines | ||
| 35 | 35 | #define efi_call_virt6(f, a1, a2, a3, a4, a5, a6) \ |
| 36 | 36 | efi_call_virt(f, a1, a2, a3, a4, a5, a6) |
| 37 | 37 | |
| 38 | −#define efi_ioremap(addr, size, type) ioremap_cache(addr, size) | |
| 38 | +#define efi_ioremap(addr, size, type, attr) ioremap_cache(addr, size) | |
| 39 | 39 | |
| 40 | 40 | #else /* !CONFIG_X86_32 */ |
| 41 | 41 | |
| @@ -89,7 +89,7 @@ extern u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3, · 47 unmodified lines | ||
| 89 | 89 | (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6)) |
| 90 | 90 | |
| 91 | 91 | extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size, |
| 92 | − u32 type); | |
| 92 | + u32 type, u64 attribute); | |
| 93 | 93 | |
| 94 | 94 | #endif /* CONFIG_X86_32 */ |
| 95 | 95 | |
| @@ -98,6 +98,8 @@ extern void efi_set_executable(efi_memory_desc_t *md, bool executable); · 2 unmodified lines | ||
| 98 | 98 | extern int efi_memblock_x86_reserve_range(void); |
| 99 | 99 | extern void efi_call_phys_prelog(void); |
| 100 | 100 | extern void efi_call_phys_epilog(void); |
| 101 | +extern void efi_unmap_memmap(void); | |
| 102 | +extern void efi_memory_uc(u64 addr, unsigned long size); | |
| 101 | 103 | |
| 102 | 104 | #ifndef CONFIG_EFI |
| 103 | 105 | /* |
| @@ -399,14 +399,17 @@ static inline void drop_init_fpu(struct task_struct *tsk) · 398 unmodified lines | ||
| 399 | 399 | typedef struct { int preload; } fpu_switch_t; |
| 400 | 400 | |
| 401 | 401 | /* |
| 402 | − * FIXME! We could do a totally lazy restore, but we need to | |
| 403 | − * add a per-cpu "this was the task that last touched the FPU | |
| 404 | − * on this CPU" variable, and the task needs to have a "I last | |
| 405 | − * touched the FPU on this CPU" and check them. | |
| 402 | + * Must be run with preemption disabled: this clears the fpu_owner_task, | |
| 403 | + * on this CPU. | |
| 406 | 404 | * |
| 407 | − * We don't do that yet, so "fpu_lazy_restore()" always returns | |
| 408 | − * false, but some day.. | |
| 405 | + * This will disable any lazy FPU state restore of the current FPU state, | |
| 406 | + * but if the current thread owns the FPU, it will still be saved by. | |
| 409 | 407 | */ |
| 408 | +static inline void __cpu_disable_lazy_restore(unsigned int cpu) | |
| 409 | +{ | |
| 410 | + per_cpu(fpu_owner_task, cpu) = NULL; | |
| 411 | +} | |
| 412 | + | |
| 410 | 413 | static inline int fpu_lazy_restore(struct task_struct *new, unsigned int cpu) |
| 411 | 414 | { |
| 412 | 415 | return new == this_cpu_read_stable(fpu_owner_task) && |
| @@ -205,21 +205,14 @@ static inline bool user_64bit_mode(struct pt_regs *regs) · 204 unmodified lines | ||
| 205 | 205 | } |
| 206 | 206 | #endif |
| 207 | 207 | |
| 208 | −/* | |
| 209 | − * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode | |
| 210 | − * when it traps. The previous stack will be directly underneath the saved | |
| 211 | − * registers, and 'sp/ss' won't even have been saved. Thus the '®s->sp'. | |
| 212 | − * | |
| 213 | − * This is valid only for kernel mode traps. | |
| 214 | − */ | |
| 215 | −static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) | |
| 216 | −{ | |
| 217 | 208 | #ifdef CONFIG_X86_32 |
| 218 | − return (unsigned long)(®s->sp); | |
| 209 | +extern unsigned long kernel_stack_pointer(struct pt_regs *regs); | |
| 219 | 210 | #else |
| 211 | +static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) | |
| 212 | +{ | |
| 220 | 213 | return regs->sp; |
| 221 | −#endif | |
| 222 | 214 | } |
| 215 | +#endif | |
| 223 | 216 | |
| 224 | 217 | #define GET_IP(regs) ((regs)->ip) |
| 225 | 218 | #define GET_FP(regs) ((regs)->bp) |
| @@ -359,18 +359,14 @@ HYPERVISOR_update_va_mapping(unsigned long va, pte_t new_val, · 358 unmodified lines | ||
| 359 | 359 | return _hypercall4(int, update_va_mapping, va, |
| 360 | 360 | new_val.pte, new_val.pte >> 32, flags); |
| 361 | 361 | } |
| 362 | +extern int __must_check xen_event_channel_op_compat(int, void *); | |
| 362 | 363 | |
| 363 | 364 | static inline int |
| 364 | 365 | HYPERVISOR_event_channel_op(int cmd, void *arg) |
| 365 | 366 | { |
| 366 | 367 | int rc = _hypercall2(int, event_channel_op, cmd, arg); |
| 367 | − if (unlikely(rc == -ENOSYS)) { | |
| 368 | − struct evtchn_op op; | |
| 369 | − op.cmd = cmd; | |
| 370 | − memcpy(&op.u, arg, sizeof(op.u)); | |
| 371 | − rc = _hypercall1(int, event_channel_op_compat, &op); | |
| 372 | − memcpy(arg, &op.u, sizeof(op.u)); | |
| 373 | − } | |
| 368 | + if (unlikely(rc == -ENOSYS)) | |
| 369 | + rc = xen_event_channel_op_compat(cmd, arg); | |
| 374 | 370 | return rc; |
| 375 | 371 | } |
| 376 | 372 | |
| @@ -386,17 +382,14 @@ HYPERVISOR_console_io(int cmd, int count, char *str) · 9 unmodified lines | ||
| 386 | 382 | return _hypercall3(int, console_io, cmd, count, str); |
| 387 | 383 | } |
| 388 | 384 | |
| 385 | +extern int __must_check HYPERVISOR_physdev_op_compat(int, void *); | |
| 386 | + | |
| 389 | 387 | static inline int |
| 390 | 388 | HYPERVISOR_physdev_op(int cmd, void *arg) |
| 391 | 389 | { |
| 392 | 390 | int rc = _hypercall2(int, physdev_op, cmd, arg); |
| 393 | − if (unlikely(rc == -ENOSYS)) { | |
| 394 | − struct physdev_op op; | |
| 395 | − op.cmd = cmd; | |
| 396 | − memcpy(&op.u, arg, sizeof(op.u)); | |
| 397 | − rc = _hypercall1(int, physdev_op_compat, &op); | |
| 398 | − memcpy(arg, &op.u, sizeof(op.u)); | |
| 399 | − } | |
| 391 | + if (unlikely(rc == -ENOSYS)) | |
| 392 | + rc = HYPERVISOR_physdev_op_compat(cmd, arg); | |
| 400 | 393 | return rc; |
| 401 | 394 | } |
| 402 | 395 | |
| @@ -33,7 +33,6 @@ · 32 unmodified lines | ||
| 33 | 33 | #ifndef _ASM_X86_XEN_HYPERVISOR_H |
| 34 | 34 | #define _ASM_X86_XEN_HYPERVISOR_H |
| 35 | 35 | |
| 36 | −/* arch/i386/kernel/setup.c */ | |
| 37 | 36 | extern struct shared_info *HYPERVISOR_shared_info; |
| 38 | 37 | extern struct start_info *xen_start_info; |
| 39 | 38 | |
| @@ -2257,6 +2257,9 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void) · 2256 unmodified lines | ||
| 2257 | 2257 | continue; |
| 2258 | 2258 | |
| 2259 | 2259 | cfg = irq_cfg(irq); |
| 2260 | + if (!cfg) | |
| 2261 | + continue; | |
| 2262 | + | |
| 2260 | 2263 | raw_spin_lock(&desc->lock); |
| 2261 | 2264 | |
| 2262 | 2265 | /* |
| @@ -631,6 +631,20 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) · 630 unmodified lines | ||
| 631 | 631 | } |
| 632 | 632 | } |
| 633 | 633 | |
| 634 | + /* | |
| 635 | + * The way access filter has a performance penalty on some workloads. | |
| 636 | + * Disable it on the affected CPUs. | |
| 637 | + */ | |
| 638 | + if ((c->x86 == 0x15) && | |
| 639 | + (c->x86_model >= 0x02) && (c->x86_model < 0x20)) { | |
| 640 | + u64 val; | |
| 641 | + | |
| 642 | + if (!rdmsrl_safe(0xc0011021, &val) && !(val & 0x1E)) { | |
| 643 | + val |= 0x1E; | |
| 644 | + wrmsrl_safe(0xc0011021, val); | |
| 645 | + } | |
| 646 | + } | |
| 647 | + | |
| 634 | 648 | cpu_detect_cache_sizes(c); |
| 635 | 649 | |
| 636 | 650 | /* Multi core CPU? */ |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | * |
| 7 | 7 | * Written by Jacob Shin - AMD, Inc. |
| 8 | 8 | * |
| 9 | − * Support: borislav.petkov@amd.com | |
| 9 | + * Maintained by: Borislav Petkov <bp@alien8.de> | |
| 10 | 10 | * |
| 11 | 11 | * April 2006 |
| 12 | 12 | * - added support for AMD Family 0x10 processors |
| @@ -285,34 +285,39 @@ void cmci_clear(void) · 284 unmodified lines | ||
| 285 | 285 | raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); |
| 286 | 286 | } |
| 287 | 287 | |
| 288 | +static long cmci_rediscover_work_func(void *arg) | |
| 289 | +{ | |
| 290 | + int banks; | |
| 291 | + | |
| 292 | + /* Recheck banks in case CPUs don't all have the same */ | |
| 293 | + if (cmci_supported(&banks)) | |
| 294 | + cmci_discover(banks); | |
| 295 | + | |
| 296 | + return 0; | |
| 297 | +} | |
| 298 | + | |
| 288 | 299 | /* |
| 289 | 300 | * After a CPU went down cycle through all the others and rediscover |
| 290 | 301 | * Must run in process context. |
| 291 | 302 | */ |
| 292 | 303 | void cmci_rediscover(int dying) |
| 293 | 304 | { |
| 294 | − int banks; | |
| 295 | − int cpu; | |
| 296 | − cpumask_var_t old; | |
| 305 | + int cpu, banks; | |
| 297 | 306 | |
| 298 | 307 | if (!cmci_supported(&banks)) |
| 299 | 308 | return; |
| 300 | − if (!alloc_cpumask_var(&old, GFP_KERNEL)) | |
| 301 | − return; | |
| 302 | − cpumask_copy(old, ¤t->cpus_allowed); | |
| 303 | 309 | |
| 304 | 310 | for_each_online_cpu(cpu) { |
| 305 | 311 | if (cpu == dying) |
| 306 | 312 | continue; |
| 307 | − if (set_cpus_allowed_ptr(current, cpumask_of(cpu))) | |
| 313 | + | |
| 314 | + if (cpu == smp_processor_id()) { | |
| 315 | + cmci_rediscover_work_func(NULL); | |
| 308 | 316 | continue; |
| 309 | − /* Recheck banks in case CPUs don't all have the same */ | |
| 310 | − if (cmci_supported(&banks)) | |
| 311 | − cmci_discover(banks); | |
| 312 | − } | |
| 317 | + } | |
| 313 | 318 | |
| 314 | − set_cpus_allowed_ptr(current, old); | |
| 315 | − free_cpumask_var(old); | |
| 319 | + work_on_cpu(cpu, cmci_rediscover_work_func, NULL); | |
| 320 | + } | |
| 316 | 321 | } |
| 317 | 322 | |
| 318 | 323 | /* |
| @@ -118,22 +118,24 @@ static void snbep_uncore_pci_disable_box(struct intel_uncore_box *box) · 117 unmodified lines | ||
| 118 | 118 | { |
| 119 | 119 | struct pci_dev *pdev = box->pci_dev; |
| 120 | 120 | int box_ctl = uncore_pci_box_ctl(box); |
| 121 | − u32 config; | |
| 121 | + u32 config = 0; | |
| 122 | 122 | |
| 123 | − pci_read_config_dword(pdev, box_ctl, &config); | |
| 124 | − config |= SNBEP_PMON_BOX_CTL_FRZ; | |
| 125 | − pci_write_config_dword(pdev, box_ctl, config); | |
| 123 | + if (!pci_read_config_dword(pdev, box_ctl, &config)) { | |
| 124 | + config |= SNBEP_PMON_BOX_CTL_FRZ; | |
| 125 | + pci_write_config_dword(pdev, box_ctl, config); | |
| 126 | + } | |
| 126 | 127 | } |
| 127 | 128 | |
| 128 | 129 | static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box) |
| 129 | 130 | { |
| 130 | 131 | struct pci_dev *pdev = box->pci_dev; |
| 131 | 132 | int box_ctl = uncore_pci_box_ctl(box); |
| 132 | − u32 config; | |
| 133 | + u32 config = 0; | |
| 133 | 134 | |
| 134 | − pci_read_config_dword(pdev, box_ctl, &config); | |
| 135 | − config &= ~SNBEP_PMON_BOX_CTL_FRZ; | |
| 136 | − pci_write_config_dword(pdev, box_ctl, config); | |
| 135 | + if (!pci_read_config_dword(pdev, box_ctl, &config)) { | |
| 136 | + config &= ~SNBEP_PMON_BOX_CTL_FRZ; | |
| 137 | + pci_write_config_dword(pdev, box_ctl, config); | |
| 138 | + } | |
| 137 | 139 | } |
| 138 | 140 | |
| 139 | 141 | static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, struct perf_event *event) |
| @@ -156,7 +158,7 @@ static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, struct pe · 16 unmodified lines | ||
| 156 | 158 | { |
| 157 | 159 | struct pci_dev *pdev = box->pci_dev; |
| 158 | 160 | struct hw_perf_event *hwc = &event->hw; |
| 159 | − u64 count; | |
| 161 | + u64 count = 0; | |
| 160 | 162 | |
| 161 | 163 | pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count); |
| 162 | 164 | pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1); |
| @@ -603,11 +605,12 @@ static struct pci_driver snbep_uncore_pci_driver = { · 440 unmodified lines | ||
| 603 | 605 | /* |
| 604 | 606 | * build pci bus to socket mapping |
| 605 | 607 | */ |
| 606 | −static void snbep_pci2phy_map_init(void) | |
| 608 | +static int snbep_pci2phy_map_init(void) | |
| 607 | 609 | { |
| 608 | 610 | struct pci_dev *ubox_dev = NULL; |
| 609 | 611 | int i, bus, nodeid; |
| 610 | − u32 config; | |
| 612 | + int err = 0; | |
| 613 | + u32 config = 0; | |
| 611 | 614 | |
| 612 | 615 | while (1) { |
| 613 | 616 | /* find the UBOX device */ |
| @@ -618,10 +621,14 @@ static void snbep_pci2phy_map_init(void) · 4 unmodified lines | ||
| 618 | 621 | break; |
| 619 | 622 | bus = ubox_dev->bus->number; |
| 620 | 623 | /* get the Node ID of the local register */ |
| 621 | − pci_read_config_dword(ubox_dev, 0x40, &config); | |
| 624 | + err = pci_read_config_dword(ubox_dev, 0x40, &config); | |
| 625 | + if (err) | |
| 626 | + break; | |
| 622 | 627 | nodeid = config; |
| 623 | 628 | /* get the Node ID mapping */ |
| 624 | − pci_read_config_dword(ubox_dev, 0x54, &config); | |
| 629 | + err = pci_read_config_dword(ubox_dev, 0x54, &config); | |
| 630 | + if (err) | |
| 631 | + break; | |
| 625 | 632 | /* |
| 626 | 633 | * every three bits in the Node ID mapping register maps |
| 627 | 634 | * to a particular node. |
| @@ -633,7 +640,11 @@ static void snbep_pci2phy_map_init(void) · 5 unmodified lines | ||
| 633 | 640 | } |
| 634 | 641 | } |
| 635 | 642 | }; |
| 636 | − return; | |
| 643 | + | |
| 644 | + if (ubox_dev) | |
| 645 | + pci_dev_put(ubox_dev); | |
| 646 | + | |
| 647 | + return err ? pcibios_err_to_errno(err) : 0; | |
| 637 | 648 | } |
| 638 | 649 | /* end of Sandy Bridge-EP uncore support */ |
| 639 | 650 | |
| @@ -1547,7 +1558,6 @@ void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event) · 907 unmodified lines | ||
| 1547 | 1558 | { |
| 1548 | 1559 | struct hw_perf_event *hwc = &event->hw; |
| 1549 | 1560 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; |
| 1550 | − int port; | |
| 1551 | 1561 | |
| 1552 | 1562 | /* adjust the main event selector and extra register index */ |
| 1553 | 1563 | if (reg1->idx % 2) { |
| @@ -1559,7 +1569,6 @@ void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event) · 5 unmodified lines | ||
| 1559 | 1569 | } |
| 1560 | 1570 | |
| 1561 | 1571 | /* adjust extra register config */ |
| 1562 | − port = reg1->idx / 6 + box->pmu->pmu_idx * 4; | |
| 1563 | 1572 | switch (reg1->idx % 6) { |
| 1564 | 1573 | case 2: |
| 1565 | 1574 | /* shift the 8~15 bits to the 0~7 bits */ |
| @@ -2578,9 +2587,11 @@ static int __init uncore_pci_init(void) · 1012 unmodified lines | ||
| 2578 | 2587 | |
| 2579 | 2588 | switch (boot_cpu_data.x86_model) { |
| 2580 | 2589 | case 45: /* Sandy Bridge-EP */ |
| 2590 | + ret = snbep_pci2phy_map_init(); | |
| 2591 | + if (ret) | |
| 2592 | + return ret; | |
| 2581 | 2593 | pci_uncores = snbep_pci_uncores; |
| 2582 | 2594 | uncore_pci_driver = &snbep_uncore_pci_driver; |
| 2583 | − snbep_pci2phy_map_init(); | |
| 2584 | 2595 | break; |
| 2585 | 2596 | default: |
| 2586 | 2597 | return 0; |
| @@ -3,6 +3,8 @@ · 2 unmodified lines | ||
| 3 | 3 | #include <linux/perf_event.h> |
| 4 | 4 | #include <linux/types.h> |
| 5 | 5 | |
| 6 | +#include <asm/hardirq.h> | |
| 7 | + | |
| 6 | 8 | #include "perf_event.h" |
| 7 | 9 | |
| 8 | 10 | static const u64 knc_perfmon_event_map[] = |
| @@ -173,30 +175,100 @@ static void knc_pmu_enable_all(int added) · 164 unmodified lines | ||
| 173 | 175 | static inline void |
| 174 | 176 | knc_pmu_disable_event(struct perf_event *event) |
| 175 | 177 | { |
| 176 | − struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | |
| 177 | 178 | struct hw_perf_event *hwc = &event->hw; |
| 178 | 179 | u64 val; |
| 179 | 180 | |
| 180 | 181 | val = hwc->config; |
| 181 | − if (cpuc->enabled) | |
| 182 | − val &= ~ARCH_PERFMON_EVENTSEL_ENABLE; | |
| 182 | + val &= ~ARCH_PERFMON_EVENTSEL_ENABLE; | |
| 183 | 183 | |
| 184 | 184 | (void)wrmsrl_safe(hwc->config_base + hwc->idx, val); |
| 185 | 185 | } |
| 186 | 186 | |
| 187 | 187 | static void knc_pmu_enable_event(struct perf_event *event) |
| 188 | 188 | { |
| 189 | − struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | |
| 190 | 189 | struct hw_perf_event *hwc = &event->hw; |
| 191 | 190 | u64 val; |
| 192 | 191 | |
| 193 | 192 | val = hwc->config; |
| 194 | − if (cpuc->enabled) | |
| 195 | − val |= ARCH_PERFMON_EVENTSEL_ENABLE; | |
| 193 | + val |= ARCH_PERFMON_EVENTSEL_ENABLE; | |
| 196 | 194 | |
| 197 | 195 | (void)wrmsrl_safe(hwc->config_base + hwc->idx, val); |
| 198 | 196 | } |
| 199 | 197 | |
| 198 | +static inline u64 knc_pmu_get_status(void) | |
| 199 | +{ | |
| 200 | + u64 status; | |
| 201 | + | |
| 202 | + rdmsrl(MSR_KNC_IA32_PERF_GLOBAL_STATUS, status); | |
| 203 | + | |
| 204 | + return status; | |
| 205 | +} | |
| 206 | + | |
| 207 | +static inline void knc_pmu_ack_status(u64 ack) | |
| 208 | +{ | |
| 209 | + wrmsrl(MSR_KNC_IA32_PERF_GLOBAL_OVF_CONTROL, ack); | |
| 210 | +} | |
| 211 | + | |
| 212 | +static int knc_pmu_handle_irq(struct pt_regs *regs) | |
| 213 | +{ | |
| 214 | + struct perf_sample_data data; | |
| 215 | + struct cpu_hw_events *cpuc; | |
| 216 | + int handled = 0; | |
| 217 | + int bit, loops; | |
| 218 | + u64 status; | |
| 219 | + | |
| 220 | + cpuc = &__get_cpu_var(cpu_hw_events); | |
| 221 | + | |
| 222 | + knc_pmu_disable_all(); | |
| 223 | + | |
| 224 | + status = knc_pmu_get_status(); | |
| 225 | + if (!status) { | |
| 226 | + knc_pmu_enable_all(0); | |
| 227 | + return handled; | |
| 228 | + } | |
| 229 | + | |
| 230 | + loops = 0; | |
| 231 | +again: | |
| 232 | + knc_pmu_ack_status(status); | |
| 233 | + if (++loops > 100) { | |
| 234 | + WARN_ONCE(1, "perf: irq loop stuck!\n"); | |
| 235 | + perf_event_print_debug(); | |
| 236 | + goto done; | |
| 237 | + } | |
| 238 | + | |
| 239 | + inc_irq_stat(apic_perf_irqs); | |
| 240 | + | |
| 241 | + for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) { | |
| 242 | + struct perf_event *event = cpuc->events[bit]; | |
| 243 | + | |
| 244 | + handled++; | |
| 245 | + | |
| 246 | + if (!test_bit(bit, cpuc->active_mask)) | |
| 247 | + continue; | |
| 248 | + | |
| 249 | + if (!intel_pmu_save_and_restart(event)) | |
| 250 | + continue; | |
| 251 | + | |
| 252 | + perf_sample_data_init(&data, 0, event->hw.last_period); | |
| 253 | + | |
| 254 | + if (perf_event_overflow(event, &data, regs)) | |
| 255 | + x86_pmu_stop(event, 0); | |
| 256 | + } | |
| 257 | + | |
| 258 | + /* | |
| 259 | + * Repeat if there is more work to be done: | |
| 260 | + */ | |
| 261 | + status = knc_pmu_get_status(); | |
| 262 | + if (status) | |
| 263 | + goto again; | |
| 264 | + | |
| 265 | +done: | |
| 266 | + knc_pmu_enable_all(0); | |
| 267 | + | |
| 268 | + return handled; | |
| 269 | +} | |
| 270 | + | |
| 271 | + | |
| 200 | 272 | PMU_FORMAT_ATTR(event, "config:0-7" ); |
| 201 | 273 | PMU_FORMAT_ATTR(umask, "config:8-15" ); |
| 202 | 274 | PMU_FORMAT_ATTR(edge, "config:18" ); |
| @@ -214,7 +286,7 @@ static struct attribute *intel_knc_formats_attr[] = { · 11 unmodified lines | ||
| 214 | 286 | |
| 215 | 287 | static __initconst struct x86_pmu knc_pmu = { |
| 216 | 288 | .name = "knc", |
| 217 | − .handle_irq = x86_pmu_handle_irq, | |
| 289 | + .handle_irq = knc_pmu_handle_irq, | |
| 218 | 290 | .disable_all = knc_pmu_disable_all, |
| 219 | 291 | .enable_all = knc_pmu_enable_all, |
| 220 | 292 | .enable = knc_pmu_enable_event, |
| @@ -226,12 +298,11 @@ static __initconst struct x86_pmu knc_pmu = { · 5 unmodified lines | ||
| 226 | 298 | .event_map = knc_pmu_event_map, |
| 227 | 299 | .max_events = ARRAY_SIZE(knc_perfmon_event_map), |
| 228 | 300 | .apic = 1, |
| 229 | − .max_period = (1ULL << 31) - 1, | |
| 301 | + .max_period = (1ULL << 39) - 1, | |
| 230 | 302 | .version = 0, |
| 231 | 303 | .num_counters = 2, |
| 232 | − /* in theory 40 bits, early silicon is buggy though */ | |
| 233 | − .cntval_bits = 32, | |
| 234 | − .cntval_mask = (1ULL << 32) - 1, | |
| 304 | + .cntval_bits = 40, | |
| 305 | + .cntval_mask = (1ULL << 40) - 1, | |
| 235 | 306 | .get_event_constraints = x86_get_event_constraints, |
| 236 | 307 | .event_constraints = knc_event_constraints, |
| 237 | 308 | .format_attrs = intel_knc_formats_attr, |
| @@ -8,13 +8,106 @@ · 7 unmodified lines | ||
| 8 | 8 | */ |
| 9 | 9 | static const u64 p6_perfmon_event_map[] = |
| 10 | 10 | { |
| 11 | − [PERF_COUNT_HW_CPU_CYCLES] = 0x0079, | |
| 12 | − [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, | |
| 13 | − [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0f2e, | |
| 14 | − [PERF_COUNT_HW_CACHE_MISSES] = 0x012e, | |
| 15 | − [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4, | |
| 16 | − [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5, | |
| 17 | − [PERF_COUNT_HW_BUS_CYCLES] = 0x0062, | |
| 11 | + [PERF_COUNT_HW_CPU_CYCLES] = 0x0079, /* CPU_CLK_UNHALTED */ | |
| 12 | + [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, /* INST_RETIRED */ | |
| 13 | + [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0f2e, /* L2_RQSTS:M:E:S:I */ | |
| 14 | + [PERF_COUNT_HW_CACHE_MISSES] = 0x012e, /* L2_RQSTS:I */ | |
| 15 | + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4, /* BR_INST_RETIRED */ | |
| 16 | + [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5, /* BR_MISS_PRED_RETIRED */ | |
| 17 | + [PERF_COUNT_HW_BUS_CYCLES] = 0x0062, /* BUS_DRDY_CLOCKS */ | |
| 18 | + [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x00a2, /* RESOURCE_STALLS */ | |
| 19 | + | |
| 20 | +}; | |
| 21 | + | |
| 22 | +static __initconst u64 p6_hw_cache_event_ids | |
| 23 | + [PERF_COUNT_HW_CACHE_MAX] | |
| 24 | + [PERF_COUNT_HW_CACHE_OP_MAX] | |
| 25 | + [PERF_COUNT_HW_CACHE_RESULT_MAX] = | |
| 26 | +{ | |
| 27 | + [ C(L1D) ] = { | |
| 28 | + [ C(OP_READ) ] = { | |
| 29 | + [ C(RESULT_ACCESS) ] = 0x0043, /* DATA_MEM_REFS */ | |
| 30 | + [ C(RESULT_MISS) ] = 0x0045, /* DCU_LINES_IN */ | |
| 31 | + }, | |
| 32 | + [ C(OP_WRITE) ] = { | |
| 33 | + [ C(RESULT_ACCESS) ] = 0, | |
| 34 | + [ C(RESULT_MISS) ] = 0x0f29, /* L2_LD:M:E:S:I */ | |
| 35 | + }, | |
| 36 | + [ C(OP_PREFETCH) ] = { | |
| 37 | + [ C(RESULT_ACCESS) ] = 0, | |
| 38 | + [ C(RESULT_MISS) ] = 0, | |
| 39 | + }, | |
| 40 | + }, | |
| 41 | + [ C(L1I ) ] = { | |
| 42 | + [ C(OP_READ) ] = { | |
| 43 | + [ C(RESULT_ACCESS) ] = 0x0080, /* IFU_IFETCH */ | |
| 44 | + [ C(RESULT_MISS) ] = 0x0f28, /* L2_IFETCH:M:E:S:I */ | |
| 45 | + }, | |
| 46 | + [ C(OP_WRITE) ] = { | |
| 47 | + [ C(RESULT_ACCESS) ] = -1, | |
| 48 | + [ C(RESULT_MISS) ] = -1, | |
| 49 | + }, | |
| 50 | + [ C(OP_PREFETCH) ] = { | |
| 51 | + [ C(RESULT_ACCESS) ] = 0, | |
| 52 | + [ C(RESULT_MISS) ] = 0, | |
| 53 | + }, | |
| 54 | + }, | |
| 55 | + [ C(LL ) ] = { | |
| 56 | + [ C(OP_READ) ] = { | |
| 57 | + [ C(RESULT_ACCESS) ] = 0, | |
| 58 | + [ C(RESULT_MISS) ] = 0, | |
| 59 | + }, | |
| 60 | + [ C(OP_WRITE) ] = { | |
| 61 | + [ C(RESULT_ACCESS) ] = 0, | |
| 62 | + [ C(RESULT_MISS) ] = 0x0025, /* L2_M_LINES_INM */ | |
| 63 | + }, | |
| 64 | + [ C(OP_PREFETCH) ] = { | |
| 65 | + [ C(RESULT_ACCESS) ] = 0, | |
| 66 | + [ C(RESULT_MISS) ] = 0, | |
| 67 | + }, | |
| 68 | + }, | |
| 69 | + [ C(DTLB) ] = { | |
| 70 | + [ C(OP_READ) ] = { | |
| 71 | + [ C(RESULT_ACCESS) ] = 0x0043, /* DATA_MEM_REFS */ | |
| 72 | + [ C(RESULT_MISS) ] = 0, | |
| 73 | + }, | |
| 74 | + [ C(OP_WRITE) ] = { | |
| 75 | + [ C(RESULT_ACCESS) ] = 0, | |
| 76 | + [ C(RESULT_MISS) ] = 0, | |
| 77 | + }, | |
| 78 | + [ C(OP_PREFETCH) ] = { | |
| 79 | + [ C(RESULT_ACCESS) ] = 0, | |
| 80 | + [ C(RESULT_MISS) ] = 0, | |
| 81 | + }, | |
| 82 | + }, | |
| 83 | + [ C(ITLB) ] = { | |
| 84 | + [ C(OP_READ) ] = { | |
| 85 | + [ C(RESULT_ACCESS) ] = 0x0080, /* IFU_IFETCH */ | |
| 86 | + [ C(RESULT_MISS) ] = 0x0085, /* ITLB_MISS */ | |
| 87 | + }, | |
| 88 | + [ C(OP_WRITE) ] = { | |
| 89 | + [ C(RESULT_ACCESS) ] = -1, | |
| 90 | + [ C(RESULT_MISS) ] = -1, | |
| 91 | + }, | |
| 92 | + [ C(OP_PREFETCH) ] = { | |
| 93 | + [ C(RESULT_ACCESS) ] = -1, | |
| 94 | + [ C(RESULT_MISS) ] = -1, | |
| 95 | + }, | |
| 96 | + }, | |
| 97 | + [ C(BPU ) ] = { | |
| 98 | + [ C(OP_READ) ] = { | |
| 99 | + [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED */ | |
| 100 | + [ C(RESULT_MISS) ] = 0x00c5, /* BR_MISS_PRED_RETIRED */ | |
| 101 | + }, | |
| 102 | + [ C(OP_WRITE) ] = { | |
| 103 | + [ C(RESULT_ACCESS) ] = -1, | |
| 104 | + [ C(RESULT_MISS) ] = -1, | |
| 105 | + }, | |
| 106 | + [ C(OP_PREFETCH) ] = { | |
| 107 | + [ C(RESULT_ACCESS) ] = -1, | |
| 108 | + [ C(RESULT_MISS) ] = -1, | |
| 109 | + }, | |
| 110 | + }, | |
| 18 | 111 | }; |
| 19 | 112 | |
| 20 | 113 | static u64 p6_pmu_event_map(int hw_event) |
| @@ -34,7 +127,7 @@ static struct event_constraint p6_event_constraints[] = · 13 unmodified lines | ||
| 34 | 127 | { |
| 35 | 128 | INTEL_EVENT_CONSTRAINT(0xc1, 0x1), /* FLOPS */ |
| 36 | 129 | INTEL_EVENT_CONSTRAINT(0x10, 0x1), /* FP_COMP_OPS_EXE */ |
| 37 | − INTEL_EVENT_CONSTRAINT(0x11, 0x1), /* FP_ASSIST */ | |
| 130 | + INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */ | |
| 38 | 131 | INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */ |
| 39 | 132 | INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */ |
| 40 | 133 | INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */ |
| @@ -64,25 +157,25 @@ static void p6_pmu_enable_all(int added) · 23 unmodified lines | ||
| 64 | 157 | static inline void |
| 65 | 158 | p6_pmu_disable_event(struct perf_event *event) |
| 66 | 159 | { |
| 67 | − struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | |
| 68 | 160 | struct hw_perf_event *hwc = &event->hw; |
| 69 | 161 | u64 val = P6_NOP_EVENT; |
| 70 | 162 | |
| 71 | − if (cpuc->enabled) | |
| 72 | − val |= ARCH_PERFMON_EVENTSEL_ENABLE; | |
| 73 | − | |
| 74 | 163 | (void)wrmsrl_safe(hwc->config_base, val); |
| 75 | 164 | } |
| 76 | 165 | |
| 77 | 166 | static void p6_pmu_enable_event(struct perf_event *event) |
| 78 | 167 | { |
| 79 | − struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | |
| 80 | 168 | struct hw_perf_event *hwc = &event->hw; |
| 81 | 169 | u64 val; |
| 82 | 170 | |
| 83 | 171 | val = hwc->config; |
| 84 | − if (cpuc->enabled) | |
| 85 | − val |= ARCH_PERFMON_EVENTSEL_ENABLE; | |
| 172 | + | |
| 173 | + /* | |
| 174 | + * p6 only has a global event enable, set on PerfEvtSel0 | |
| 175 | + * We "disable" events by programming P6_NOP_EVENT | |
| 176 | + * and we rely on p6_pmu_enable_all() being called | |
| 177 | + * to actually enable the events. | |
| 178 | + */ | |
| 86 | 179 | |
| 87 | 180 | (void)wrmsrl_safe(hwc->config_base, val); |
| 88 | 181 | } |
| @@ -160,5 +253,9 @@ __init int p6_pmu_init(void) · 71 unmodified lines | ||
| 160 | 253 | |
| 161 | 254 | x86_pmu = p6_pmu; |
| 162 | 255 | |
| 256 | + memcpy(hw_cache_event_ids, p6_hw_cache_event_ids, | |
| 257 | + sizeof(hw_cache_event_ids)); | |
| 258 | + | |
| 259 | + | |
| 163 | 260 | return 0; |
| 164 | 261 | } |
| @@ -1077,6 +1077,9 @@ void __init memblock_x86_fill(void) · 1076 unmodified lines | ||
| 1077 | 1077 | memblock_add(ei->addr, ei->size); |
| 1078 | 1078 | } |
| 1079 | 1079 | |
| 1080 | + /* throw away partial pages */ | |
| 1081 | + memblock_trim_memory(PAGE_SIZE); | |
| 1082 | + | |
| 1080 | 1083 | memblock_dump_all(); |
| 1081 | 1084 | } |
| 1082 | 1085 | |
| @@ -995,8 +995,8 @@ END(interrupt) · 994 unmodified lines | ||
| 995 | 995 | */ |
| 996 | 996 | .p2align CONFIG_X86_L1_CACHE_SHIFT |
| 997 | 997 | common_interrupt: |
| 998 | − ASM_CLAC | |
| 999 | 998 | XCPT_FRAME |
| 999 | + ASM_CLAC | |
| 1000 | 1000 | addq $-0x80,(%rsp) /* Adjust vector to [-256,-1] range */ |
| 1001 | 1001 | interrupt do_IRQ |
| 1002 | 1002 | /* 0(%rsp): old_rsp-ARGOFFSET */ |
| @@ -1135,8 +1135,8 @@ END(common_interrupt) · 132 unmodified lines | ||
| 1135 | 1135 | */ |
| 1136 | 1136 | .macro apicinterrupt num sym do_sym |
| 1137 | 1137 | ENTRY(\sym) |
| 1138 | − ASM_CLAC | |
| 1139 | 1138 | INTR_FRAME |
| 1139 | + ASM_CLAC | |
| 1140 | 1140 | pushq_cfi $~(\num) |
| 1141 | 1141 | .Lcommon_\sym: |
| 1142 | 1142 | interrupt \do_sym |
| @@ -1190,8 +1190,8 @@ apicinterrupt IRQ_WORK_VECTOR \ · 47 unmodified lines | ||
| 1190 | 1190 | */ |
| 1191 | 1191 | .macro zeroentry sym do_sym |
| 1192 | 1192 | ENTRY(\sym) |
| 1193 | − ASM_CLAC | |
| 1194 | 1193 | INTR_FRAME |
| 1194 | + ASM_CLAC | |
| 1195 | 1195 | PARAVIRT_ADJUST_EXCEPTION_FRAME |
| 1196 | 1196 | pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ |
| 1197 | 1197 | subq $ORIG_RAX-R15, %rsp |
| @@ -1208,8 +1208,8 @@ END(\sym) · 10 unmodified lines | ||
| 1208 | 1208 | |
| 1209 | 1209 | .macro paranoidzeroentry sym do_sym |
| 1210 | 1210 | ENTRY(\sym) |
| 1211 | − ASM_CLAC | |
| 1212 | 1211 | INTR_FRAME |
| 1212 | + ASM_CLAC | |
| 1213 | 1213 | PARAVIRT_ADJUST_EXCEPTION_FRAME |
| 1214 | 1214 | pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ |
| 1215 | 1215 | subq $ORIG_RAX-R15, %rsp |
| @@ -1227,8 +1227,8 @@ END(\sym) · 11 unmodified lines | ||
| 1227 | 1227 | #define INIT_TSS_IST(x) PER_CPU_VAR(init_tss) + (TSS_ist + ((x) - 1) * 8) |
| 1228 | 1228 | .macro paranoidzeroentry_ist sym do_sym ist |
| 1229 | 1229 | ENTRY(\sym) |
| 1230 | − ASM_CLAC | |
| 1231 | 1230 | INTR_FRAME |
| 1231 | + ASM_CLAC | |
| 1232 | 1232 | PARAVIRT_ADJUST_EXCEPTION_FRAME |
| 1233 | 1233 | pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ |
| 1234 | 1234 | subq $ORIG_RAX-R15, %rsp |
| @@ -1247,8 +1247,8 @@ END(\sym) · 12 unmodified lines | ||
| 1247 | 1247 | |
| 1248 | 1248 | .macro errorentry sym do_sym |
| 1249 | 1249 | ENTRY(\sym) |
| 1250 | − ASM_CLAC | |
| 1251 | 1250 | XCPT_FRAME |
| 1251 | + ASM_CLAC | |
| 1252 | 1252 | PARAVIRT_ADJUST_EXCEPTION_FRAME |
| 1253 | 1253 | subq $ORIG_RAX-R15, %rsp |
| 1254 | 1254 | CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 |
| @@ -1266,8 +1266,8 @@ END(\sym) · 11 unmodified lines | ||
| 1266 | 1266 | /* error code is on the stack already */ |
| 1267 | 1267 | .macro paranoiderrorentry sym do_sym |
| 1268 | 1268 | ENTRY(\sym) |
| 1269 | − ASM_CLAC | |
| 1270 | 1269 | XCPT_FRAME |
| 1270 | + ASM_CLAC | |
| 1271 | 1271 | PARAVIRT_ADJUST_EXCEPTION_FRAME |
| 1272 | 1272 | subq $ORIG_RAX-R15, %rsp |
| 1273 | 1273 | CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 |
| @@ -292,8 +292,8 @@ default_entry: · 291 unmodified lines | ||
| 292 | 292 | * be using the global pages. |
| 293 | 293 | * |
| 294 | 294 | * NOTE! If we are on a 486 we may have no cr4 at all! |
| 295 | − * Specifically, cr4 exists if and only if CPUID exists, | |
| 296 | − * which in turn exists if and only if EFLAGS.ID exists. | |
| 295 | + * Specifically, cr4 exists if and only if CPUID exists | |
| 296 | + * and has flags other than the FPU flag set. | |
| 297 | 297 | */ |
| 298 | 298 | movl $X86_EFLAGS_ID,%ecx |
| 299 | 299 | pushl %ecx |
| @@ -308,6 +308,11 @@ default_entry: · 8 unmodified lines | ||
| 308 | 308 | testl %ecx,%eax |
| 309 | 309 | jz 6f # No ID flag = no CPUID = no CR4 |
| 310 | 310 | |
| 311 | + movl $1,%eax | |
| 312 | + cpuid | |
| 313 | + andl $~1,%edx # Ignore CPUID.FPU | |
| 314 | + jz 6f # No flags or only CPUID.FPU = no CR4 | |
| 315 | + | |
| 311 | 316 | movl pa(mmu_cr4_features),%eax |
| 312 | 317 | movl %eax,%cr4 |
| 313 | 318 | |
| @@ -8,8 +8,8 @@ · 7 unmodified lines | ||
| 8 | 8 | * Tigran Aivazian <tigran@aivazian.fsnet.co.uk> |
| 9 | 9 | * |
| 10 | 10 | * Maintainers: |
| 11 | − * Andreas Herrmann <andreas.herrmann3@amd.com> | |
| 12 | − * Borislav Petkov <borislav.petkov@amd.com> | |
| 11 | + * Andreas Herrmann <herrmann.der.user@googlemail.com> | |
| 12 | + * Borislav Petkov <bp@alien8.de> | |
| 13 | 13 | * |
| 14 | 14 | * This driver allows to upgrade microcode on F10h AMD |
| 15 | 15 | * CPUs and later. |
| @@ -190,6 +190,7 @@ static unsigned int verify_patch_size(int cpu, u32 patch_size, · 174 unmodified lines | ||
| 190 | 190 | #define F1XH_MPB_MAX_SIZE 2048 |
| 191 | 191 | #define F14H_MPB_MAX_SIZE 1824 |
| 192 | 192 | #define F15H_MPB_MAX_SIZE 4096 |
| 193 | +#define F16H_MPB_MAX_SIZE 3458 | |
| 193 | 194 | |
| 194 | 195 | switch (c->x86) { |
| 195 | 196 | case 0x14: |
| @@ -198,6 +199,9 @@ static unsigned int verify_patch_size(int cpu, u32 patch_size, · 2 unmodified lines | ||
| 198 | 199 | case 0x15: |
| 199 | 200 | max_size = F15H_MPB_MAX_SIZE; |
| 200 | 201 | break; |
| 202 | + case 0x16: | |
| 203 | + max_size = F16H_MPB_MAX_SIZE; | |
| 204 | + break; | |
| 201 | 205 | default: |
| 202 | 206 | max_size = F1XH_MPB_MAX_SIZE; |
| 203 | 207 | break; |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | #include <linux/perf_event.h> |
| 23 | 23 | #include <linux/hw_breakpoint.h> |
| 24 | 24 | #include <linux/rcupdate.h> |
| 25 | +#include <linux/module.h> | |
| 25 | 26 | |
| 26 | 27 | #include <asm/uaccess.h> |
| 27 | 28 | #include <asm/pgtable.h> |
| @@ -166,6 +167,35 @@ static inline bool invalid_selector(u16 value) · 138 unmodified lines | ||
| 166 | 167 | |
| 167 | 168 | #define FLAG_MASK FLAG_MASK_32 |
| 168 | 169 | |
| 170 | +/* | |
| 171 | + * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode | |
| 172 | + * when it traps. The previous stack will be directly underneath the saved | |
| 173 | + * registers, and 'sp/ss' won't even have been saved. Thus the '®s->sp'. | |
| 174 | + * | |
| 175 | + * Now, if the stack is empty, '®s->sp' is out of range. In this | |
| 176 | + * case we try to take the previous stack. To always return a non-null | |
| 177 | + * stack pointer we fall back to regs as stack if no previous stack | |
| 178 | + * exists. | |
| 179 | + * | |
| 180 | + * This is valid only for kernel mode traps. | |
| 181 | + */ | |
| 182 | +unsigned long kernel_stack_pointer(struct pt_regs *regs) | |
| 183 | +{ | |
| 184 | + unsigned long context = (unsigned long)regs & ~(THREAD_SIZE - 1); | |
| 185 | + unsigned long sp = (unsigned long)®s->sp; | |
| 186 | + struct thread_info *tinfo; | |
| 187 | + | |
| 188 | + if (context == (sp & ~(THREAD_SIZE - 1))) | |
| 189 | + return sp; | |
| 190 | + | |
| 191 | + tinfo = (struct thread_info *)context; | |
| 192 | + if (tinfo->previous_esp) | |
| 193 | + return tinfo->previous_esp; | |
| 194 | + | |
| 195 | + return (unsigned long)regs; | |
| 196 | +} | |
| 197 | +EXPORT_SYMBOL_GPL(kernel_stack_pointer); | |
| 198 | + | |
| 169 | 199 | static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno) |
| 170 | 200 | { |
| 171 | 201 | BUILD_BUG_ON(offsetof(struct pt_regs, bx) != 0); |
| @@ -1511,6 +1541,13 @@ void syscall_trace_leave(struct pt_regs *regs) · 1339 unmodified lines | ||
| 1511 | 1541 | { |
| 1512 | 1542 | bool step; |
| 1513 | 1543 | |
| 1544 | + /* | |
| 1545 | + * We may come here right after calling schedule_user() | |
| 1546 | + * or do_notify_resume(), in which case we can be in RCU | |
| 1547 | + * user mode. | |
| 1548 | + */ | |
| 1549 | + rcu_user_exit(); | |
| 1550 | + | |
| 1514 | 1551 | audit_syscall_exit(regs); |
| 1515 | 1552 | |
| 1516 | 1553 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) |
| @@ -921,18 +921,19 @@ void __init setup_arch(char **cmdline_p) · 920 unmodified lines | ||
| 921 | 921 | #ifdef CONFIG_X86_64 |
| 922 | 922 | if (max_pfn > max_low_pfn) { |
| 923 | 923 | int i; |
| 924 | − for (i = 0; i < e820.nr_map; i++) { | |
| 925 | − struct e820entry *ei = &e820.map[i]; | |
| 924 | + unsigned long start, end; | |
| 925 | + unsigned long start_pfn, end_pfn; | |
| 926 | 926 | |
| 927 | − if (ei->addr + ei->size <= 1UL << 32) | |
| 928 | − continue; | |
| 927 | + for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, | |
| 928 | + NULL) { | |
| 929 | 929 | |
| 930 | − if (ei->type == E820_RESERVED) | |
| 930 | + end = PFN_PHYS(end_pfn); | |
| 931 | + if (end <= (1UL<<32)) | |
| 931 | 932 | continue; |
| 932 | 933 | |
| 934 | + start = PFN_PHYS(start_pfn); | |
| 933 | 935 | max_pfn_mapped = init_memory_mapping( |
| 934 | − ei->addr < 1UL << 32 ? 1UL << 32 : ei->addr, | |
| 935 | − ei->addr + ei->size); | |
| 936 | + max((1UL<<32), start), end); | |
| 936 | 937 | } |
| 937 | 938 | |
| 938 | 939 | /* can we preseve max_low_pfn ?*/ |
| @@ -1048,6 +1049,18 @@ void __init setup_arch(char **cmdline_p) · 109 unmodified lines | ||
| 1048 | 1049 | arch_init_ideal_nops(); |
| 1049 | 1050 | |
| 1050 | 1051 | register_refined_jiffies(CLOCK_TICK_RATE); |
| 1052 | + | |
| 1053 | +#ifdef CONFIG_EFI | |
| 1054 | + /* Once setup is done above, disable efi_enabled on mismatched | |
| 1055 | + * firmware/kernel archtectures since there is no support for | |
| 1056 | + * runtime services. | |
| 1057 | + */ | |
| 1058 | + if (efi_enabled && IS_ENABLED(CONFIG_X86_64) != efi_64bit) { | |
| 1059 | + pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); | |
| 1060 | + efi_unmap_memmap(); | |
| 1061 | + efi_enabled = 0; | |
| 1062 | + } | |
| 1063 | +#endif | |
| 1051 | 1064 | } |
| 1052 | 1065 | |
| 1053 | 1066 | #ifdef CONFIG_X86_32 |
| @@ -68,6 +68,8 @@ · 67 unmodified lines | ||
| 68 | 68 | #include <asm/mwait.h> |
| 69 | 69 | #include <asm/apic.h> |
| 70 | 70 | #include <asm/io_apic.h> |
| 71 | +#include <asm/i387.h> | |
| 72 | +#include <asm/fpu-internal.h> | |
| 71 | 73 | #include <asm/setup.h> |
| 72 | 74 | #include <asm/uv/uv.h> |
| 73 | 75 | #include <linux/mc146818rtc.h> |
| @@ -818,6 +820,9 @@ int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle) · 744 unmodified lines | ||
| 818 | 820 | |
| 819 | 821 | per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; |
| 820 | 822 | |
| 823 | + /* the FPU context is blank, nobody can own it */ | |
| 824 | + __cpu_disable_lazy_restore(cpu); | |
| 825 | + | |
| 821 | 826 | err = do_boot_cpu(apicid, cpu, tidle); |
| 822 | 827 | if (err) { |
| 823 | 828 | pr_debug("do_boot_cpu failed %d\n", err); |
| @@ -24,6 +24,9 @@ static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu) · 23 unmodified lines | ||
| 24 | 24 | { |
| 25 | 25 | struct kvm_cpuid_entry2 *best; |
| 26 | 26 | |
| 27 | + if (!static_cpu_has(X86_FEATURE_XSAVE)) | |
| 28 | + return 0; | |
| 29 | + | |
| 27 | 30 | best = kvm_find_cpuid_entry(vcpu, 1, 0); |
| 28 | 31 | return best && (best->ecx & bit(X86_FEATURE_XSAVE)); |
| 29 | 32 | } |
| @@ -426,8 +426,7 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt) · 425 unmodified lines | ||
| 426 | 426 | _ASM_EXTABLE(1b, 3b) \ |
| 427 | 427 | : "=m" ((ctxt)->eflags), "=&r" (_tmp), \ |
| 428 | 428 | "+a" (*rax), "+d" (*rdx), "+qm"(_ex) \ |
| 429 | − : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val), \ | |
| 430 | − "a" (*rax), "d" (*rdx)); \ | |
| 429 | + : "i" (EFLAGS_MASK), "m" ((ctxt)->src.val)); \ | |
| 431 | 430 | } while (0) |
| 432 | 431 | |
| 433 | 432 | /* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */ |
| @@ -6549,19 +6549,22 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) · 6548 unmodified lines | ||
| 6549 | 6549 | } |
| 6550 | 6550 | } |
| 6551 | 6551 | |
| 6552 | − exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); | |
| 6553 | 6552 | /* Exposing INVPCID only when PCID is exposed */ |
| 6554 | 6553 | best = kvm_find_cpuid_entry(vcpu, 0x7, 0); |
| 6555 | 6554 | if (vmx_invpcid_supported() && |
| 6556 | 6555 | best && (best->ebx & bit(X86_FEATURE_INVPCID)) && |
| 6557 | 6556 | guest_cpuid_has_pcid(vcpu)) { |
| 6557 | + exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); | |
| 6558 | 6558 | exec_control |= SECONDARY_EXEC_ENABLE_INVPCID; |
| 6559 | 6559 | vmcs_write32(SECONDARY_VM_EXEC_CONTROL, |
| 6560 | 6560 | exec_control); |
| 6561 | 6561 | } else { |
| 6562 | − exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID; | |
| 6563 | − vmcs_write32(SECONDARY_VM_EXEC_CONTROL, | |
| 6564 | − exec_control); | |
| 6562 | + if (cpu_has_secondary_exec_ctrls()) { | |
| 6563 | + exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); | |
| 6564 | + exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID; | |
| 6565 | + vmcs_write32(SECONDARY_VM_EXEC_CONTROL, | |
| 6566 | + exec_control); | |
| 6567 | + } | |
| 6565 | 6568 | if (best) |
| 6566 | 6569 | best->ebx &= ~bit(X86_FEATURE_INVPCID); |
| 6567 | 6570 | } |
| @@ -3779,7 +3779,7 @@ static int write_exit_mmio(struct kvm_vcpu *vcpu, gpa_t gpa, · 3778 unmodified lines | ||
| 3779 | 3779 | { |
| 3780 | 3780 | struct kvm_mmio_fragment *frag = &vcpu->mmio_fragments[0]; |
| 3781 | 3781 | |
| 3782 | − memcpy(vcpu->run->mmio.data, frag->data, frag->len); | |
| 3782 | + memcpy(vcpu->run->mmio.data, frag->data, min(8u, frag->len)); | |
| 3783 | 3783 | return X86EMUL_CONTINUE; |
| 3784 | 3784 | } |
| 3785 | 3785 | |
| @@ -3832,18 +3832,11 @@ mmio: · 46 unmodified lines | ||
| 3832 | 3832 | bytes -= handled; |
| 3833 | 3833 | val += handled; |
| 3834 | 3834 | |
| 3835 | − while (bytes) { | |
| 3836 | − unsigned now = min(bytes, 8U); | |
| 3837 | − | |
| 3838 | − frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++]; | |
| 3839 | − frag->gpa = gpa; | |
| 3840 | − frag->data = val; | |
| 3841 | − frag->len = now; | |
| 3842 | − | |
| 3843 | − gpa += now; | |
| 3844 | − val += now; | |
| 3845 | − bytes -= now; | |
| 3846 | − } | |
| 3835 | + WARN_ON(vcpu->mmio_nr_fragments >= KVM_MAX_MMIO_FRAGMENTS); | |
| 3836 | + frag = &vcpu->mmio_fragments[vcpu->mmio_nr_fragments++]; | |
| 3837 | + frag->gpa = gpa; | |
| 3838 | + frag->data = val; | |
| 3839 | + frag->len = bytes; | |
| 3847 | 3840 | return X86EMUL_CONTINUE; |
| 3848 | 3841 | } |
| 3849 | 3842 | |
| @@ -3890,7 +3883,7 @@ int emulator_read_write(struct x86_emulate_ctxt *ctxt, unsigned long addr, · 40 unmodified lines | ||
| 3890 | 3883 | vcpu->mmio_needed = 1; |
| 3891 | 3884 | vcpu->mmio_cur_fragment = 0; |
| 3892 | 3885 | |
| 3893 | − vcpu->run->mmio.len = vcpu->mmio_fragments[0].len; | |
| 3886 | + vcpu->run->mmio.len = min(8u, vcpu->mmio_fragments[0].len); | |
| 3894 | 3887 | vcpu->run->mmio.is_write = vcpu->mmio_is_write = ops->write; |
| 3895 | 3888 | vcpu->run->exit_reason = KVM_EXIT_MMIO; |
| 3896 | 3889 | vcpu->run->mmio.phys_addr = gpa; |
| @@ -5522,28 +5515,44 @@ static int complete_emulated_pio(struct kvm_vcpu *vcpu) · 1625 unmodified lines | ||
| 5522 | 5515 | * |
| 5523 | 5516 | * read: |
| 5524 | 5517 | * for each fragment |
| 5525 | − * write gpa, len | |
| 5526 | − * exit | |
| 5527 | − * copy data | |
| 5518 | + * for each mmio piece in the fragment | |
| 5519 | + * write gpa, len | |
| 5520 | + * exit | |
| 5521 | + * copy data | |
| 5528 | 5522 | * execute insn |
| 5529 | 5523 | * |
| 5530 | 5524 | * write: |
| 5531 | 5525 | * for each fragment |
| 5532 | − * write gpa, len | |
| 5533 | − * copy data | |
| 5534 | − * exit | |
| 5526 | + * for each mmio piece in the fragment | |
| 5527 | + * write gpa, len | |
| 5528 | + * copy data | |
| 5529 | + * exit | |
| 5535 | 5530 | */ |
| 5536 | 5531 | static int complete_emulated_mmio(struct kvm_vcpu *vcpu) |
| 5537 | 5532 | { |
| 5538 | 5533 | struct kvm_run *run = vcpu->run; |
| 5539 | 5534 | struct kvm_mmio_fragment *frag; |
| 5535 | + unsigned len; | |
| 5540 | 5536 | |
| 5541 | 5537 | BUG_ON(!vcpu->mmio_needed); |
| 5542 | 5538 | |
| 5543 | 5539 | /* Complete previous fragment */ |
| 5544 | − frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment++]; | |
| 5540 | + frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment]; | |
| 5541 | + len = min(8u, frag->len); | |
| 5545 | 5542 | if (!vcpu->mmio_is_write) |
| 5546 | − memcpy(frag->data, run->mmio.data, frag->len); | |
| 5543 | + memcpy(frag->data, run->mmio.data, len); | |
| 5544 | + | |
| 5545 | + if (frag->len <= 8) { | |
| 5546 | + /* Switch to the next fragment. */ | |
| 5547 | + frag++; | |
| 5548 | + vcpu->mmio_cur_fragment++; | |
| 5549 | + } else { | |
| 5550 | + /* Go forward to the next mmio piece. */ | |
| 5551 | + frag->data += len; | |
| 5552 | + frag->gpa += len; | |
| 5553 | + frag->len -= len; | |
| 5554 | + } | |
| 5555 | + | |
| 5547 | 5556 | if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) { |
| 5548 | 5557 | vcpu->mmio_needed = 0; |
| 5549 | 5558 | if (vcpu->mmio_is_write) |
| @@ -5551,13 +5560,12 @@ static int complete_emulated_mmio(struct kvm_vcpu *vcpu) · 1 unmodified line | ||
| 5551 | 5560 | vcpu->mmio_read_completed = 1; |
| 5552 | 5561 | return complete_emulated_io(vcpu); |
| 5553 | 5562 | } |
| 5554 | − /* Initiate next fragment */ | |
| 5555 | − ++frag; | |
| 5563 | + | |
| 5556 | 5564 | run->exit_reason = KVM_EXIT_MMIO; |
| 5557 | 5565 | run->mmio.phys_addr = frag->gpa; |
| 5558 | 5566 | if (vcpu->mmio_is_write) |
| 5559 | − memcpy(run->mmio.data, frag->data, frag->len); | |
| 5560 | − run->mmio.len = frag->len; | |
| 5567 | + memcpy(run->mmio.data, frag->data, min(8u, frag->len)); | |
| 5568 | + run->mmio.len = min(8u, frag->len); | |
| 5561 | 5569 | run->mmio.is_write = vcpu->mmio_is_write; |
| 5562 | 5570 | vcpu->arch.complete_userspace_io = complete_emulated_mmio; |
| 5563 | 5571 | return 0; |
| @@ -5773,6 +5781,9 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, · 209 unmodified lines | ||
| 5773 | 5781 | int pending_vec, max_bits, idx; |
| 5774 | 5782 | struct desc_ptr dt; |
| 5775 | 5783 | |
| 5784 | + if (!guest_cpuid_has_xsave(vcpu) && (sregs->cr4 & X86_CR4_OSXSAVE)) | |
| 5785 | + return -EINVAL; | |
| 5786 | + | |
| 5776 | 5787 | dt.size = sregs->idt.limit; |
| 5777 | 5788 | dt.address = sregs->idt.base; |
| 5778 | 5789 | kvm_x86_ops->set_idt(vcpu, &dt); |
| @@ -35,40 +35,44 @@ struct map_range { · 34 unmodified lines | ||
| 35 | 35 | unsigned page_size_mask; |
| 36 | 36 | }; |
| 37 | 37 | |
| 38 | −static void __init find_early_table_space(struct map_range *mr, unsigned long end, | |
| 39 | − int use_pse, int use_gbpages) | |
| 38 | +/* | |
| 39 | + * First calculate space needed for kernel direct mapping page tables to cover | |
| 40 | + * mr[0].start to mr[nr_range - 1].end, while accounting for possible 2M and 1GB | |
| 41 | + * pages. Then find enough contiguous space for those page tables. | |
| 42 | + */ | |
| 43 | +static void __init find_early_table_space(struct map_range *mr, int nr_range) | |
| 40 | 44 | { |
| 41 | − unsigned long puds, pmds, ptes, tables, start = 0, good_end = end; | |
| 45 | + int i; | |
| 46 | + unsigned long puds = 0, pmds = 0, ptes = 0, tables; | |
| 47 | + unsigned long start = 0, good_end; | |
| 42 | 48 | phys_addr_t base; |
| 43 | 49 | |
| 44 | − puds = (end + PUD_SIZE - 1) >> PUD_SHIFT; | |
| 45 | − tables = roundup(puds * sizeof(pud_t), PAGE_SIZE); | |
| 46 | − | |
| 47 | − if (use_gbpages) { | |
| 48 | − unsigned long extra; | |
| 49 | − | |
| 50 | − extra = end - ((end>>PUD_SHIFT) << PUD_SHIFT); | |
| 51 | − pmds = (extra + PMD_SIZE - 1) >> PMD_SHIFT; | |
| 52 | − } else | |
| 53 | − pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT; | |
| 50 | + for (i = 0; i < nr_range; i++) { | |
| 51 | + unsigned long range, extra; | |
| 54 | 52 | |
| 55 | − tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE); | |
| 53 | + range = mr[i].end - mr[i].start; | |
| 54 | + puds += (range + PUD_SIZE - 1) >> PUD_SHIFT; | |
| 56 | 55 | |
| 57 | − if (use_pse) { | |
| 58 | − unsigned long extra; | |
| 56 | + if (mr[i].page_size_mask & (1 << PG_LEVEL_1G)) { | |
| 57 | + extra = range - ((range >> PUD_SHIFT) << PUD_SHIFT); | |
| 58 | + pmds += (extra + PMD_SIZE - 1) >> PMD_SHIFT; | |
| 59 | + } else { | |
| 60 | + pmds += (range + PMD_SIZE - 1) >> PMD_SHIFT; | |
| 61 | + } | |
| 59 | 62 | |
| 60 | − extra = end - ((end>>PMD_SHIFT) << PMD_SHIFT); | |
| 63 | + if (mr[i].page_size_mask & (1 << PG_LEVEL_2M)) { | |
| 64 | + extra = range - ((range >> PMD_SHIFT) << PMD_SHIFT); | |
| 61 | 65 | #ifdef CONFIG_X86_32 |
| 62 | − extra += PMD_SIZE; | |
| 66 | + extra += PMD_SIZE; | |
| 63 | 67 | #endif |
| 64 | − /* The first 2/4M doesn't use large pages. */ | |
| 65 | − if (mr->start < PMD_SIZE) | |
| 66 | − extra += mr->end - mr->start; | |
| 67 | − | |
| 68 | − ptes = (extra + PAGE_SIZE - 1) >> PAGE_SHIFT; | |
| 69 | − } else | |
| 70 | − ptes = (end + PAGE_SIZE - 1) >> PAGE_SHIFT; | |
| 68 | + ptes += (extra + PAGE_SIZE - 1) >> PAGE_SHIFT; | |
| 69 | + } else { | |
| 70 | + ptes += (range + PAGE_SIZE - 1) >> PAGE_SHIFT; | |
| 71 | + } | |
| 72 | + } | |
| 71 | 73 | |
| 74 | + tables = roundup(puds * sizeof(pud_t), PAGE_SIZE); | |
| 75 | + tables += roundup(pmds * sizeof(pmd_t), PAGE_SIZE); | |
| 72 | 76 | tables += roundup(ptes * sizeof(pte_t), PAGE_SIZE); |
| 73 | 77 | |
| 74 | 78 | #ifdef CONFIG_X86_32 |
| @@ -86,7 +90,7 @@ static void __init find_early_table_space(struct map_range *mr, unsigned long en · 11 unmodified lines | ||
| 86 | 90 | pgt_buf_top = pgt_buf_start + (tables >> PAGE_SHIFT); |
| 87 | 91 | |
| 88 | 92 | printk(KERN_DEBUG "kernel direct mapping tables up to %#lx @ [mem %#010lx-%#010lx]\n", |
| 89 | − end - 1, pgt_buf_start << PAGE_SHIFT, | |
| 93 | + mr[nr_range - 1].end - 1, pgt_buf_start << PAGE_SHIFT, | |
| 90 | 94 | (pgt_buf_top << PAGE_SHIFT) - 1); |
| 91 | 95 | } |
| 92 | 96 | |
| @@ -267,7 +271,7 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, · 174 unmodified lines | ||
| 267 | 271 | * nodes are discovered. |
| 268 | 272 | */ |
| 269 | 273 | if (!after_bootmem) |
| 270 | − find_early_table_space(&mr[0], end, use_pse, use_gbpages); | |
| 274 | + find_early_table_space(mr, nr_range); | |
| 271 | 275 | |
| 272 | 276 | for (i = 0; i < nr_range; i++) |
| 273 | 277 | ret = kernel_physical_mapping_init(mr[i].start, mr[i].end, |
| @@ -386,7 +386,8 @@ phys_pte_init(pte_t *pte_page, unsigned long addr, unsigned long end, · 385 unmodified lines | ||
| 386 | 386 | * these mappings are more intelligent. |
| 387 | 387 | */ |
| 388 | 388 | if (pte_val(*pte)) { |
| 389 | − pages++; | |
| 389 | + if (!after_bootmem) | |
| 390 | + pages++; | |
| 390 | 391 | continue; |
| 391 | 392 | } |
| 392 | 393 | |
| @@ -451,6 +452,8 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end, · 58 unmodified lines | ||
| 451 | 452 | * attributes. |
| 452 | 453 | */ |
| 453 | 454 | if (page_size_mask & (1 << PG_LEVEL_2M)) { |
| 455 | + if (!after_bootmem) | |
| 456 | + pages++; | |
| 454 | 457 | last_map_addr = next; |
| 455 | 458 | continue; |
| 456 | 459 | } |
| @@ -526,6 +529,8 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end, · 69 unmodified lines | ||
| 526 | 529 | * attributes. |
| 527 | 530 | */ |
| 528 | 531 | if (page_size_mask & (1 << PG_LEVEL_1G)) { |
| 532 | + if (!after_bootmem) | |
| 533 | + pages++; | |
| 529 | 534 | last_map_addr = next; |
| 530 | 535 | continue; |
| 531 | 536 | } |
| @@ -197,7 +197,7 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, · 196 unmodified lines | ||
| 197 | 197 | } |
| 198 | 198 | |
| 199 | 199 | if (end == TLB_FLUSH_ALL || tlb_flushall_shift == -1 |
| 200 | − || vmflag == VM_HUGETLB) { | |
| 200 | + || vmflag & VM_HUGETLB) { | |
| 201 | 201 | local_flush_tlb(); |
| 202 | 202 | goto flush_all; |
| 203 | 203 | } |
| @@ -115,6 +115,16 @@ static void sata_revid_read(struct sim_dev_reg *reg, u32 *value) · 114 unmodified lines | ||
| 115 | 115 | reg_read(reg, value); |
| 116 | 116 | } |
| 117 | 117 | |
| 118 | +static void reg_noirq_read(struct sim_dev_reg *reg, u32 *value) | |
| 119 | +{ | |
| 120 | + unsigned long flags; | |
| 121 | + | |
| 122 | + raw_spin_lock_irqsave(&pci_config_lock, flags); | |
| 123 | + /* force interrupt pin value to 0 */ | |
| 124 | + *value = reg->sim_reg.value & 0xfff00ff; | |
| 125 | + raw_spin_unlock_irqrestore(&pci_config_lock, flags); | |
| 126 | +} | |
| 127 | + | |
| 118 | 128 | static struct sim_dev_reg bus1_fixups[] = { |
| 119 | 129 | DEFINE_REG(2, 0, 0x10, (16*MB), reg_init, reg_read, reg_write) |
| 120 | 130 | DEFINE_REG(2, 0, 0x14, (256), reg_init, reg_read, reg_write) |
| @@ -144,6 +154,7 @@ static struct sim_dev_reg bus1_fixups[] = { · 23 unmodified lines | ||
| 144 | 154 | DEFINE_REG(11, 5, 0x10, (64*KB), reg_init, reg_read, reg_write) |
| 145 | 155 | DEFINE_REG(11, 6, 0x10, (256), reg_init, reg_read, reg_write) |
| 146 | 156 | DEFINE_REG(11, 7, 0x10, (64*KB), reg_init, reg_read, reg_write) |
| 157 | + DEFINE_REG(11, 7, 0x3c, 256, reg_init, reg_noirq_read, reg_write) | |
| 147 | 158 | DEFINE_REG(12, 0, 0x10, (128*KB), reg_init, reg_read, reg_write) |
| 148 | 159 | DEFINE_REG(12, 0, 0x14, (256), reg_init, reg_read, reg_write) |
| 149 | 160 | DEFINE_REG(12, 1, 0x10, (1024), reg_init, reg_read, reg_write) |
| @@ -161,8 +172,10 @@ static struct sim_dev_reg bus1_fixups[] = { · 11 unmodified lines | ||
| 161 | 172 | DEFINE_REG(16, 0, 0x10, (64*KB), reg_init, reg_read, reg_write) |
| 162 | 173 | DEFINE_REG(16, 0, 0x14, (64*MB), reg_init, reg_read, reg_write) |
| 163 | 174 | DEFINE_REG(16, 0, 0x18, (64*MB), reg_init, reg_read, reg_write) |
| 175 | + DEFINE_REG(16, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write) | |
| 164 | 176 | DEFINE_REG(17, 0, 0x10, (128*KB), reg_init, reg_read, reg_write) |
| 165 | 177 | DEFINE_REG(18, 0, 0x10, (1*KB), reg_init, reg_read, reg_write) |
| 178 | + DEFINE_REG(18, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write) | |
| 166 | 179 | }; |
| 167 | 180 | |
| 168 | 181 | static void __init init_sim_regs(void) |
| @@ -21,12 +21,25 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <asm/i8259.h> |
| 22 | 22 | #include <asm/io.h> |
| 23 | 23 | #include <asm/io_apic.h> |
| 24 | +#include <asm/emergency-restart.h> | |
| 24 | 25 | |
| 25 | 26 | static int ce4100_i8042_detect(void) |
| 26 | 27 | { |
| 27 | 28 | return 0; |
| 28 | 29 | } |
| 29 | 30 | |
| 31 | +/* | |
| 32 | + * The CE4100 platform has an internal 8051 Microcontroller which is | |
| 33 | + * responsible for signaling to the external Power Management Unit the | |
| 34 | + * intention to reset, reboot or power off the system. This 8051 device has | |
| 35 | + * its command register mapped at I/O port 0xcf9 and the value 0x4 is used | |
| 36 | + * to power off the system. | |
| 37 | + */ | |
| 38 | +static void ce4100_power_off(void) | |
| 39 | +{ | |
| 40 | + outb(0x4, 0xcf9); | |
| 41 | +} | |
| 42 | + | |
| 30 | 43 | #ifdef CONFIG_SERIAL_8250 |
| 31 | 44 | |
| 32 | 45 | static unsigned int mem_serial_in(struct uart_port *p, int offset) |
| @@ -139,8 +152,19 @@ void __init x86_ce4100_early_setup(void) · 106 unmodified lines | ||
| 139 | 152 | x86_init.mpparse.find_smp_config = x86_init_noop; |
| 140 | 153 | x86_init.pci.init = ce4100_pci_init; |
| 141 | 154 | |
| 155 | + /* | |
| 156 | + * By default, the reboot method is ACPI which is supported by the | |
| 157 | + * CE4100 bootloader CEFDK using FADT.ResetReg Address and ResetValue | |
| 158 | + * the bootloader will however issue a system power off instead of | |
| 159 | + * reboot. By using BOOT_KBD we ensure proper system reboot as | |
| 160 | + * expected. | |
| 161 | + */ | |
| 162 | + reboot_type = BOOT_KBD; | |
| 163 | + | |
| 142 | 164 | #ifdef CONFIG_X86_IO_APIC |
| 143 | 165 | x86_init.pci.init_irq = sdv_pci_init; |
| 144 | 166 | x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck; |
| 145 | 167 | #endif |
| 168 | + | |
| 169 | + pm_power_off = ce4100_power_off; | |
| 146 | 170 | } |
| @@ -70,11 +70,15 @@ EXPORT_SYMBOL(efi); · 69 unmodified lines | ||
| 70 | 70 | struct efi_memory_map memmap; |
| 71 | 71 | |
| 72 | 72 | bool efi_64bit; |
| 73 | −static bool efi_native; | |
| 74 | 73 | |
| 75 | 74 | static struct efi efi_phys __initdata; |
| 76 | 75 | static efi_system_table_t efi_systab __initdata; |
| 77 | 76 | |
| 77 | +static inline bool efi_is_native(void) | |
| 78 | +{ | |
| 79 | + return IS_ENABLED(CONFIG_X86_64) == efi_64bit; | |
| 80 | +} | |
| 81 | + | |
| 78 | 82 | static int __init setup_noefi(char *arg) |
| 79 | 83 | { |
| 80 | 84 | efi_enabled = 0; |
| @@ -420,7 +424,7 @@ void __init efi_reserve_boot_services(void) · 339 unmodified lines | ||
| 420 | 424 | } |
| 421 | 425 | } |
| 422 | 426 | |
| 423 | −static void __init efi_unmap_memmap(void) | |
| 427 | +void __init efi_unmap_memmap(void) | |
| 424 | 428 | { |
| 425 | 429 | if (memmap.map) { |
| 426 | 430 | early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); |
| @@ -432,7 +436,7 @@ void __init efi_free_boot_services(void) · 5 unmodified lines | ||
| 432 | 436 | { |
| 433 | 437 | void *p; |
| 434 | 438 | |
| 435 | − if (!efi_native) | |
| 439 | + if (!efi_is_native()) | |
| 436 | 440 | return; |
| 437 | 441 | |
| 438 | 442 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { |
| @@ -684,12 +688,10 @@ void __init efi_init(void) · 245 unmodified lines | ||
| 684 | 688 | return; |
| 685 | 689 | } |
| 686 | 690 | efi_phys.systab = (efi_system_table_t *)boot_params.efi_info.efi_systab; |
| 687 | − efi_native = !efi_64bit; | |
| 688 | 691 | #else |
| 689 | 692 | efi_phys.systab = (efi_system_table_t *) |
| 690 | 693 | (boot_params.efi_info.efi_systab | |
| 691 | 694 | ((__u64)boot_params.efi_info.efi_systab_hi<<32)); |
| 692 | − efi_native = efi_64bit; | |
| 693 | 695 | #endif |
| 694 | 696 | |
| 695 | 697 | if (efi_systab_init(efi_phys.systab)) { |
| @@ -723,7 +725,7 @@ void __init efi_init(void) · 27 unmodified lines | ||
| 723 | 725 | * that doesn't match the kernel 32/64-bit mode. |
| 724 | 726 | */ |
| 725 | 727 | |
| 726 | − if (!efi_native) | |
| 728 | + if (!efi_is_native()) | |
| 727 | 729 | pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n"); |
| 728 | 730 | else if (efi_runtime_init()) { |
| 729 | 731 | efi_enabled = 0; |
| @@ -735,7 +737,7 @@ void __init efi_init(void) · 5 unmodified lines | ||
| 735 | 737 | return; |
| 736 | 738 | } |
| 737 | 739 | #ifdef CONFIG_X86_32 |
| 738 | − if (efi_native) { | |
| 740 | + if (efi_is_native()) { | |
| 739 | 741 | x86_platform.get_wallclock = efi_get_time; |
| 740 | 742 | x86_platform.set_wallclock = efi_set_rtc_mmss; |
| 741 | 743 | } |
| @@ -810,6 +812,16 @@ void __iomem *efi_lookup_mapped_addr(u64 phys_addr) · 68 unmodified lines | ||
| 810 | 812 | return NULL; |
| 811 | 813 | } |
| 812 | 814 | |
| 815 | +void efi_memory_uc(u64 addr, unsigned long size) | |
| 816 | +{ | |
| 817 | + unsigned long page_shift = 1UL << EFI_PAGE_SHIFT; | |
| 818 | + u64 npages; | |
| 819 | + | |
| 820 | + npages = round_up(size, page_shift) / page_shift; | |
| 821 | + memrange_efi_to_native(&addr, &npages); | |
| 822 | + set_memory_uc(addr, npages); | |
| 823 | +} | |
| 824 | + | |
| 813 | 825 | /* |
| 814 | 826 | * This function will switch the EFI runtime services to virtual mode. |
| 815 | 827 | * Essentially, look through the EFI memmap and map every region that |
| @@ -823,7 +835,7 @@ void __init efi_enter_virtual_mode(void) · 7 unmodified lines | ||
| 823 | 835 | efi_memory_desc_t *md, *prev_md = NULL; |
| 824 | 836 | efi_status_t status; |
| 825 | 837 | unsigned long size; |
| 826 | − u64 end, systab, addr, npages, end_pfn; | |
| 838 | + u64 end, systab, end_pfn; | |
| 827 | 839 | void *p, *va, *new_memmap = NULL; |
| 828 | 840 | int count = 0; |
| 829 | 841 | |
| @@ -834,7 +846,7 @@ void __init efi_enter_virtual_mode(void) · 4 unmodified lines | ||
| 834 | 846 | * non-native EFI |
| 835 | 847 | */ |
| 836 | 848 | |
| 837 | − if (!efi_native) { | |
| 849 | + if (!efi_is_native()) { | |
| 838 | 850 | efi_unmap_memmap(); |
| 839 | 851 | return; |
| 840 | 852 | } |
| @@ -879,10 +891,14 @@ void __init efi_enter_virtual_mode(void) · 38 unmodified lines | ||
| 879 | 891 | end_pfn = PFN_UP(end); |
| 880 | 892 | if (end_pfn <= max_low_pfn_mapped |
| 881 | 893 | || (end_pfn > (1UL << (32 - PAGE_SHIFT)) |
| 882 | − && end_pfn <= max_pfn_mapped)) | |
| 894 | + && end_pfn <= max_pfn_mapped)) { | |
| 883 | 895 | va = __va(md->phys_addr); |
| 884 | − else | |
| 885 | − va = efi_ioremap(md->phys_addr, size, md->type); | |
| 896 | + | |
| 897 | + if (!(md->attribute & EFI_MEMORY_WB)) | |
| 898 | + efi_memory_uc((u64)(unsigned long)va, size); | |
| 899 | + } else | |
| 900 | + va = efi_ioremap(md->phys_addr, size, | |
| 901 | + md->type, md->attribute); | |
| 886 | 902 | |
| 887 | 903 | md->virt_addr = (u64) (unsigned long) va; |
| 888 | 904 | |
| @@ -892,13 +908,6 @@ void __init efi_enter_virtual_mode(void) · 3 unmodified lines | ||
| 892 | 908 | continue; |
| 893 | 909 | } |
| 894 | 910 | |
| 895 | − if (!(md->attribute & EFI_MEMORY_WB)) { | |
| 896 | − addr = md->virt_addr; | |
| 897 | − npages = md->num_pages; | |
| 898 | − memrange_efi_to_native(&addr, &npages); | |
| 899 | − set_memory_uc(addr, npages); | |
| 900 | − } | |
| 901 | − | |
| 902 | 911 | systab = (u64) (unsigned long) efi_phys.systab; |
| 903 | 912 | if (md->phys_addr <= systab && systab < end) { |
| 904 | 913 | systab += md->virt_addr - md->phys_addr; |
| @@ -82,7 +82,7 @@ void __init efi_call_phys_epilog(void) · 81 unmodified lines | ||
| 82 | 82 | } |
| 83 | 83 | |
| 84 | 84 | void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size, |
| 85 | − u32 type) | |
| 85 | + u32 type, u64 attribute) | |
| 86 | 86 | { |
| 87 | 87 | unsigned long last_map_pfn; |
| 88 | 88 | |
| @@ -92,8 +92,11 @@ void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size, · 3 unmodified lines | ||
| 92 | 92 | last_map_pfn = init_memory_mapping(phys_addr, phys_addr + size); |
| 93 | 93 | if ((last_map_pfn << PAGE_SHIFT) < phys_addr + size) { |
| 94 | 94 | unsigned long top = last_map_pfn << PAGE_SHIFT; |
| 95 | − efi_ioremap(top, size - (top - phys_addr), type); | |
| 95 | + efi_ioremap(top, size - (top - phys_addr), type, attribute); | |
| 96 | 96 | } |
| 97 | 97 | |
| 98 | + if (!(attribute & EFI_MEMORY_WB)) | |
| 99 | + efi_memory_uc((u64)(unsigned long)__va(phys_addr), size); | |
| 100 | + | |
| 98 | 101 | return (void __iomem *)__va(phys_addr); |
| 99 | 102 | } |
| @@ -1288,6 +1288,25 @@ unsigned long xen_read_cr2_direct(void) · 1287 unmodified lines | ||
| 1288 | 1288 | return this_cpu_read(xen_vcpu_info.arch.cr2); |
| 1289 | 1289 | } |
| 1290 | 1290 | |
| 1291 | +void xen_flush_tlb_all(void) | |
| 1292 | +{ | |
| 1293 | + struct mmuext_op *op; | |
| 1294 | + struct multicall_space mcs; | |
| 1295 | + | |
| 1296 | + trace_xen_mmu_flush_tlb_all(0); | |
| 1297 | + | |
| 1298 | + preempt_disable(); | |
| 1299 | + | |
| 1300 | + mcs = xen_mc_entry(sizeof(*op)); | |
| 1301 | + | |
| 1302 | + op = mcs.args; | |
| 1303 | + op->cmd = MMUEXT_TLB_FLUSH_ALL; | |
| 1304 | + MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF); | |
| 1305 | + | |
| 1306 | + xen_mc_issue(PARAVIRT_LAZY_MMU); | |
| 1307 | + | |
| 1308 | + preempt_enable(); | |
| 1309 | +} | |
| 1291 | 1310 | static void xen_flush_tlb(void) |
| 1292 | 1311 | { |
| 1293 | 1312 | struct mmuext_op *op; |
| @@ -2518,7 +2537,7 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma, · 1224 unmodified lines | ||
| 2518 | 2537 | err = 0; |
| 2519 | 2538 | out: |
| 2520 | 2539 | |
| 2521 | − flush_tlb_all(); | |
| 2540 | + xen_flush_tlb_all(); | |
| 2522 | 2541 | |
| 2523 | 2542 | return err; |
| 2524 | 2543 | } |
| @@ -13,6 +13,8 @@ config XTENSA · 12 unmodified lines | ||
| 13 | 13 | select GENERIC_CPU_DEVICES |
| 14 | 14 | select MODULES_USE_ELF_RELA |
| 15 | 15 | select GENERIC_PCI_IOMAP |
| 16 | + select GENERIC_KERNEL_THREAD | |
| 17 | + select GENERIC_KERNEL_EXECVE | |
| 16 | 18 | select ARCH_WANT_OPTIONAL_GPIOLIB |
| 17 | 19 | help |
| 18 | 20 | Xtensa processors are 32-bit RISC machines designed by Tensilica |
| @@ -62,6 +62,10 @@ static inline void __iomem *ioremap(unsigned long offset, unsigned long size) · 61 unmodified lines | ||
| 62 | 62 | static inline void iounmap(volatile void __iomem *addr) |
| 63 | 63 | { |
| 64 | 64 | } |
| 65 | + | |
| 66 | +#define virt_to_bus virt_to_phys | |
| 67 | +#define bus_to_virt phys_to_virt | |
| 68 | + | |
| 65 | 69 | #endif /* CONFIG_MMU */ |
| 66 | 70 | |
| 67 | 71 | /* |
| @@ -152,6 +152,7 @@ struct thread_struct { · 151 unmodified lines | ||
| 152 | 152 | |
| 153 | 153 | /* Clearing a0 terminates the backtrace. */ |
| 154 | 154 | #define start_thread(regs, new_pc, new_sp) \ |
| 155 | + memset(regs, 0, sizeof(*regs)); \ | |
| 155 | 156 | regs->pc = new_pc; \ |
| 156 | 157 | regs->ps = USER_PS_VALUE; \ |
| 157 | 158 | regs->areg[1] = new_sp; \ |
| @@ -168,9 +169,6 @@ struct mm_struct; · 10 unmodified lines | ||
| 168 | 169 | /* Free all resources held by a thread. */ |
| 169 | 170 | #define release_thread(thread) do { } while(0) |
| 170 | 171 | |
| 171 | −/* Create a kernel thread without removing it from tasklists */ | |
| 172 | −extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); | |
| 173 | − | |
| 174 | 172 | /* Copy and release all segment info associated with a VM */ |
| 175 | 173 | #define copy_segments(p, mm) do { } while(0) |
| 176 | 174 | #define release_segments(mm) do { } while(0) |
| @@ -10,7 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | |
| 11 | 11 | struct pt_regs; |
| 12 | 12 | struct sigaction; |
| 13 | −asmlinkage long xtensa_execve(char*, char**, char**, struct pt_regs*); | |
| 13 | +asmlinkage long sys_execve(char*, char**, char**, struct pt_regs*); | |
| 14 | 14 | asmlinkage long xtensa_clone(unsigned long, unsigned long, struct pt_regs*); |
| 15 | 15 | asmlinkage long xtensa_ptrace(long, long, long, long); |
| 16 | 16 | asmlinkage long xtensa_sigreturn(struct pt_regs*); |
| @@ -1,16 +1,9 @@ | ||
| 1 | −/* | |
| 2 | − * include/asm-xtensa/unistd.h | |
| 3 | − * | |
| 4 | − * This file is subject to the terms and conditions of the GNU General Public | |
| 5 | − * License. See the file "COPYING" in the main directory of this archive | |
| 6 | − * for more details. | |
| 7 | − * | |
| 8 | − * Copyright (C) 2001 - 2005 Tensilica Inc. | |
| 9 | − */ | |
| 1 | +#ifndef _XTENSA_UNISTD_H | |
| 2 | +#define _XTENSA_UNISTD_H | |
| 10 | 3 | |
| 4 | +#define __ARCH_WANT_SYS_EXECVE | |
| 11 | 5 | #include <uapi/asm/unistd.h> |
| 12 | 6 | |
| 13 | − | |
| 14 | 7 | /* |
| 15 | 8 | * "Conditional" syscalls |
| 16 | 9 | * |
| @@ -37,3 +30,5 @@ · 20 unmodified lines | ||
| 37 | 30 | #define __IGNORE_mmap /* use mmap2 */ |
| 38 | 31 | #define __IGNORE_vfork /* use clone */ |
| 39 | 32 | #define __IGNORE_fadvise64 /* use fadvise64_64 */ |
| 33 | + | |
| 34 | +#endif /* _XTENSA_UNISTD_H */ | |
| @@ -1,14 +1,4 @@ | ||
| 1 | −/* | |
| 2 | − * include/asm-xtensa/unistd.h | |
| 3 | − * | |
| 4 | − * This file is subject to the terms and conditions of the GNU General Public | |
| 5 | − * License. See the file "COPYING" in the main directory of this archive | |
| 6 | − * for more details. | |
| 7 | − * | |
| 8 | − * Copyright (C) 2001 - 2012 Tensilica Inc. | |
| 9 | − */ | |
| 10 | − | |
| 11 | −#ifndef _UAPI_XTENSA_UNISTD_H | |
| 1 | +#if !defined(_UAPI_XTENSA_UNISTD_H) || defined(__SYSCALL) | |
| 12 | 2 | #define _UAPI_XTENSA_UNISTD_H |
| 13 | 3 | |
| 14 | 4 | #ifndef __SYSCALL |
| @@ -272,7 +262,7 @@ __SYSCALL(115, sys_sendmmsg, 4) · 257 unmodified lines | ||
| 272 | 262 | #define __NR_clone 116 |
| 273 | 263 | __SYSCALL(116, xtensa_clone, 5) |
| 274 | 264 | #define __NR_execve 117 |
| 275 | −__SYSCALL(117, xtensa_execve, 3) | |
| 265 | +__SYSCALL(117, sys_execve, 3) | |
| 276 | 266 | #define __NR_exit 118 |
| 277 | 267 | __SYSCALL(118, sys_exit, 1) |
| 278 | 268 | #define __NR_exit_group 119 |
| @@ -759,4 +749,6 @@ __SYSCALL(331, sys_kcmp, 5) · 480 unmodified lines | ||
| 759 | 749 | |
| 760 | 750 | #define SYS_XTENSA_COUNT 5 /* count */ |
| 761 | 751 | |
| 752 | +#undef __SYSCALL | |
| 753 | + | |
| 762 | 754 | #endif /* _UAPI_XTENSA_UNISTD_H */ |
| @@ -1832,50 +1832,6 @@ ENTRY(system_call) · 1831 unmodified lines | ||
| 1832 | 1832 | retw |
| 1833 | 1833 | |
| 1834 | 1834 | |
| 1835 | −/* | |
| 1836 | − * Create a kernel thread | |
| 1837 | − * | |
| 1838 | − * int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | |
| 1839 | − * a2 a2 a3 a4 | |
| 1840 | − */ | |
| 1841 | − | |
| 1842 | −ENTRY(kernel_thread) | |
| 1843 | − entry a1, 16 | |
| 1844 | − | |
| 1845 | − mov a5, a2 # preserve fn over syscall | |
| 1846 | − mov a7, a3 # preserve args over syscall | |
| 1847 | − | |
| 1848 | − movi a3, _CLONE_VM | _CLONE_UNTRACED | |
| 1849 | − movi a2, __NR_clone | |
| 1850 | − or a6, a4, a3 # arg0: flags | |
| 1851 | − mov a3, a1 # arg1: sp | |
| 1852 | − syscall | |
| 1853 | − | |
| 1854 | − beq a3, a1, 1f # branch if parent | |
| 1855 | − mov a6, a7 # args | |
| 1856 | − callx4 a5 # fn(args) | |
| 1857 | − | |
| 1858 | − movi a2, __NR_exit | |
| 1859 | − syscall # return value of fn(args) still in a6 | |
| 1860 | − | |
| 1861 | −1: retw | |
| 1862 | − | |
| 1863 | −/* | |
| 1864 | − * Do a system call from kernel instead of calling sys_execve, so we end up | |
| 1865 | − * with proper pt_regs. | |
| 1866 | − * | |
| 1867 | − * int kernel_execve(const char *fname, char *const argv[], charg *const envp[]) | |
| 1868 | − * a2 a2 a3 a4 | |
| 1869 | − */ | |
| 1870 | − | |
| 1871 | −ENTRY(kernel_execve) | |
| 1872 | − entry a1, 16 | |
| 1873 | − mov a6, a2 # arg0 is in a6 | |
| 1874 | − movi a2, __NR_execve | |
| 1875 | − syscall | |
| 1876 | − | |
| 1877 | − retw | |
| 1878 | − | |
| 1879 | 1835 | /* |
| 1880 | 1836 | * Task switch. |
| 1881 | 1837 | * |
| @@ -1958,3 +1914,16 @@ ENTRY(ret_from_fork) · 76 unmodified lines | ||
| 1958 | 1914 | |
| 1959 | 1915 | j common_exception_return |
| 1960 | 1916 | |
| 1917 | +/* | |
| 1918 | + * Kernel thread creation helper | |
| 1919 | + * On entry, set up by copy_thread: a2 = thread_fn, a3 = thread_fn arg | |
| 1920 | + * left from _switch_to: a6 = prev | |
| 1921 | + */ | |
| 1922 | +ENTRY(ret_from_kernel_thread) | |
| 1923 | + | |
| 1924 | + call4 schedule_tail | |
| 1925 | + mov a6, a3 | |
| 1926 | + callx4 a2 | |
| 1927 | + j common_exception_return | |
| 1928 | + | |
| 1929 | +ENDPROC(ret_from_kernel_thread) | |
| @@ -45,6 +45,7 @@ · 44 unmodified lines | ||
| 45 | 45 | #include <asm/regs.h> |
| 46 | 46 | |
| 47 | 47 | extern void ret_from_fork(void); |
| 48 | +extern void ret_from_kernel_thread(void); | |
| 48 | 49 | |
| 49 | 50 | struct task_struct *current_set[NR_CPUS] = {&init_task, }; |
| 50 | 51 | |
| @@ -158,18 +159,30 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) · 107 unmodified lines | ||
| 158 | 159 | /* |
| 159 | 160 | * Copy thread. |
| 160 | 161 | * |
| 162 | + * There are two modes in which this function is called: | |
| 163 | + * 1) Userspace thread creation, | |
| 164 | + * regs != NULL, usp_thread_fn is userspace stack pointer. | |
| 165 | + * It is expected to copy parent regs (in case CLONE_VM is not set | |
| 166 | + * in the clone_flags) and set up passed usp in the childregs. | |
| 167 | + * 2) Kernel thread creation, | |
| 168 | + * regs == NULL, usp_thread_fn is the function to run in the new thread | |
| 169 | + * and thread_fn_arg is its parameter. | |
| 170 | + * childregs are not used for the kernel threads. | |
| 171 | + * | |
| 161 | 172 | * The stack layout for the new thread looks like this: |
| 162 | 173 | * |
| 163 | − * +------------------------+ <- sp in childregs (= tos) | |
| 174 | + * +------------------------+ | |
| 164 | 175 | * | childregs | |
| 165 | 176 | * +------------------------+ <- thread.sp = sp in dummy-frame |
| 166 | 177 | * | dummy-frame | (saved in dummy-frame spill-area) |
| 167 | 178 | * +------------------------+ |
| 168 | 179 | * |
| 169 | − * We create a dummy frame to return to ret_from_fork: | |
| 170 | − * a0 points to ret_from_fork (simulating a call4) | |
| 180 | + * We create a dummy frame to return to either ret_from_fork or | |
| 181 | + * ret_from_kernel_thread: | |
| 182 | + * a0 points to ret_from_fork/ret_from_kernel_thread (simulating a call4) | |
| 171 | 183 | * sp points to itself (thread.sp) |
| 172 | − * a2, a3 are unused. | |
| 184 | + * a2, a3 are unused for userspace threads, | |
| 185 | + * a2 points to thread_fn, a3 holds thread_fn arg for kernel threads. | |
| 173 | 186 | * |
| 174 | 187 | * Note: This is a pristine frame, so we don't need any spill region on top of |
| 175 | 188 | * childregs. |
| @@ -185,43 +198,63 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) · 9 unmodified lines | ||
| 185 | 198 | * involved. Much simpler to just not copy those live frames across. |
| 186 | 199 | */ |
| 187 | 200 | |
| 188 | −int copy_thread(unsigned long clone_flags, unsigned long usp, | |
| 189 | − unsigned long unused, | |
| 190 | − struct task_struct * p, struct pt_regs * regs) | |
| 201 | +int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn, | |
| 202 | + unsigned long thread_fn_arg, | |
| 203 | + struct task_struct *p, struct pt_regs *unused) | |
| 191 | 204 | { |
| 192 | − struct pt_regs *childregs; | |
| 193 | − unsigned long tos; | |
| 194 | − int user_mode = user_mode(regs); | |
| 205 | + struct pt_regs *childregs = task_pt_regs(p); | |
| 195 | 206 | |
| 196 | 207 | #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) |
| 197 | 208 | struct thread_info *ti; |
| 198 | 209 | #endif |
| 199 | 210 | |
| 200 | − /* Set up new TSS. */ | |
| 201 | − tos = (unsigned long)task_stack_page(p) + THREAD_SIZE; | |
| 202 | − if (user_mode) | |
| 203 | − childregs = (struct pt_regs*)(tos - PT_USER_SIZE); | |
| 204 | − else | |
| 205 | − childregs = (struct pt_regs*)tos - 1; | |
| 206 | − | |
| 207 | − /* This does not copy all the regs. In a bout of brilliance or madness, | |
| 208 | − ARs beyond a0-a15 exist past the end of the struct. */ | |
| 209 | − *childregs = *regs; | |
| 210 | − | |
| 211 | 211 | /* Create a call4 dummy-frame: a0 = 0, a1 = childregs. */ |
| 212 | 212 | *((int*)childregs - 3) = (unsigned long)childregs; |
| 213 | 213 | *((int*)childregs - 4) = 0; |
| 214 | 214 | |
| 215 | − childregs->areg[2] = 0; | |
| 216 | − p->set_child_tid = p->clear_child_tid = NULL; | |
| 217 | − p->thread.ra = MAKE_RA_FOR_CALL((unsigned long)ret_from_fork, 0x1); | |
| 218 | 215 | p->thread.sp = (unsigned long)childregs; |
| 219 | 216 | |
| 220 | − if (user_mode(regs)) { | |
| 217 | + if (!(p->flags & PF_KTHREAD)) { | |
| 218 | + struct pt_regs *regs = current_pt_regs(); | |
| 219 | + unsigned long usp = usp_thread_fn ? | |
| 220 | + usp_thread_fn : regs->areg[1]; | |
| 221 | 221 | |
| 222 | + p->thread.ra = MAKE_RA_FOR_CALL( | |
| 223 | + (unsigned long)ret_from_fork, 0x1); | |
| 224 | + | |
| 225 | + /* This does not copy all the regs. | |
| 226 | + * In a bout of brilliance or madness, | |
| 227 | + * ARs beyond a0-a15 exist past the end of the struct. | |
| 228 | + */ | |
| 229 | + *childregs = *regs; | |
| 222 | 230 | childregs->areg[1] = usp; |
| 231 | + childregs->areg[2] = 0; | |
| 232 | + | |
| 233 | + /* When sharing memory with the parent thread, the child | |
| 234 | + usually starts on a pristine stack, so we have to reset | |
| 235 | + windowbase, windowstart and wmask. | |
| 236 | + (Note that such a new thread is required to always create | |
| 237 | + an initial call4 frame) | |
| 238 | + The exception is vfork, where the new thread continues to | |
| 239 | + run on the parent's stack until it calls execve. This could | |
| 240 | + be a call8 or call12, which requires a legal stack frame | |
| 241 | + of the previous caller for the overflow handlers to work. | |
| 242 | + (Note that it's always legal to overflow live registers). | |
| 243 | + In this case, ensure to spill at least the stack pointer | |
| 244 | + of that frame. */ | |
| 245 | + | |
| 223 | 246 | if (clone_flags & CLONE_VM) { |
| 224 | − childregs->wmask = 1; /* can't share live windows */ | |
| 247 | + /* check that caller window is live and same stack */ | |
| 248 | + int len = childregs->wmask & ~0xf; | |
| 249 | + if (regs->areg[1] == usp && len != 0) { | |
| 250 | + int callinc = (regs->areg[0] >> 30) & 3; | |
| 251 | + int caller_ars = XCHAL_NUM_AREGS - callinc * 4; | |
| 252 | + put_user(regs->areg[caller_ars+1], | |
| 253 | + (unsigned __user*)(usp - 12)); | |
| 254 | + } | |
| 255 | + childregs->wmask = 1; | |
| 256 | + childregs->windowstart = 1; | |
| 257 | + childregs->windowbase = 0; | |
| 225 | 258 | } else { |
| 226 | 259 | int len = childregs->wmask & ~0xf; |
| 227 | 260 | memcpy(&childregs->areg[XCHAL_NUM_AREGS - len/4], |
| @@ -230,11 +263,19 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, · 2 unmodified lines | ||
| 230 | 263 | // FIXME: we need to set THREADPTR in thread_info... |
| 231 | 264 | if (clone_flags & CLONE_SETTLS) |
| 232 | 265 | childregs->areg[2] = childregs->areg[6]; |
| 233 | − | |
| 234 | 266 | } else { |
| 235 | − /* In kernel space, we start a new thread with a new stack. */ | |
| 236 | − childregs->wmask = 1; | |
| 237 | − childregs->areg[1] = tos; | |
| 267 | + p->thread.ra = MAKE_RA_FOR_CALL( | |
| 268 | + (unsigned long)ret_from_kernel_thread, 1); | |
| 269 | + | |
| 270 | + /* pass parameters to ret_from_kernel_thread: | |
| 271 | + * a2 = thread_fn, a3 = thread_fn arg | |
| 272 | + */ | |
| 273 | + *((int *)childregs - 1) = thread_fn_arg; | |
| 274 | + *((int *)childregs - 2) = usp_thread_fn; | |
| 275 | + | |
| 276 | + /* Childregs are only used when we're going to userspace | |
| 277 | + * in which case start_thread will set them up. | |
| 278 | + */ | |
| 238 | 279 | } |
| 239 | 280 | |
| 240 | 281 | #if (XTENSA_HAVE_COPROCESSORS || XTENSA_HAVE_IO_PORTS) |
| @@ -330,32 +371,5 @@ long xtensa_clone(unsigned long clone_flags, unsigned long newsp, · 89 unmodified lines | ||
| 330 | 371 | void __user *child_tid, long a5, |
| 331 | 372 | struct pt_regs *regs) |
| 332 | 373 | { |
| 333 | − if (!newsp) | |
| 334 | − newsp = regs->areg[1]; | |
| 335 | 374 | return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); |
| 336 | 375 | } |
| 337 | − | |
| 338 | −/* | |
| 339 | − * xtensa_execve() executes a new program. | |
| 340 | − */ | |
| 341 | − | |
| 342 | −asmlinkage | |
| 343 | −long xtensa_execve(const char __user *name, | |
| 344 | − const char __user *const __user *argv, | |
| 345 | − const char __user *const __user *envp, | |
| 346 | − long a3, long a4, long a5, | |
| 347 | − struct pt_regs *regs) | |
| 348 | −{ | |
| 349 | − long error; | |
| 350 | − struct filename *filename; | |
| 351 | − | |
| 352 | − filename = getname(name); | |
| 353 | − error = PTR_ERR(filename); | |
| 354 | − if (IS_ERR(filename)) | |
| 355 | − goto out; | |
| 356 | − error = do_execve(filename->name, argv, envp, regs); | |
| 357 | − putname(filename); | |
| 358 | −out: | |
| 359 | − return error; | |
| 360 | −} | |
| 361 | − | |
| @@ -32,10 +32,8 @@ typedef void (*syscall_t)(void); · 31 unmodified lines | ||
| 32 | 32 | syscall_t sys_call_table[__NR_syscall_count] /* FIXME __cacheline_aligned */= { |
| 33 | 33 | [0 ... __NR_syscall_count - 1] = (syscall_t)&sys_ni_syscall, |
| 34 | 34 | |
| 35 | −#undef __SYSCALL | |
| 36 | 35 | #define __SYSCALL(nr,symbol,nargs) [ nr ] = (syscall_t)symbol, |
| 37 | −#undef __KERNEL_SYSCALLS__ | |
| 38 | −#include <asm/unistd.h> | |
| 36 | +#include <uapi/asm/unistd.h> | |
| 39 | 37 | }; |
| 40 | 38 | |
| 41 | 39 | asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) |
| @@ -49,7 +47,8 @@ asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) · 7 unmodified lines | ||
| 49 | 47 | return (long)ret; |
| 50 | 48 | } |
| 51 | 49 | |
| 52 | −asmlinkage long xtensa_fadvise64_64(int fd, int advice, unsigned long long offset, unsigned long long len) | |
| 50 | +asmlinkage long xtensa_fadvise64_64(int fd, int advice, | |
| 51 | + unsigned long long offset, unsigned long long len) | |
| 53 | 52 | { |
| 54 | 53 | return sys_fadvise64_64(fd, offset, len, advice); |
| 55 | 54 | } |
| @@ -43,7 +43,6 @@ EXPORT_SYMBOL(__strncpy_user); · 42 unmodified lines | ||
| 43 | 43 | EXPORT_SYMBOL(clear_page); |
| 44 | 44 | EXPORT_SYMBOL(copy_page); |
| 45 | 45 | |
| 46 | −EXPORT_SYMBOL(kernel_thread); | |
| 47 | 46 | EXPORT_SYMBOL(empty_zero_page); |
| 48 | 47 | |
| 49 | 48 | /* |
| @@ -89,7 +89,7 @@ config BLK_DEV_INTEGRITY · 88 unmodified lines | ||
| 89 | 89 | |
| 90 | 90 | config BLK_DEV_THROTTLING |
| 91 | 91 | bool "Block layer bio throttling support" |
| 92 | − depends on BLK_CGROUP=y && EXPERIMENTAL | |
| 92 | + depends on BLK_CGROUP=y | |
| 93 | 93 | default n |
| 94 | 94 | ---help--- |
| 95 | 95 | Block layer bio throttling support. It can be used to limit |
| @@ -285,6 +285,13 @@ static void blkg_destroy_all(struct request_queue *q) · 284 unmodified lines | ||
| 285 | 285 | blkg_destroy(blkg); |
| 286 | 286 | spin_unlock(&blkcg->lock); |
| 287 | 287 | } |
| 288 | + | |
| 289 | + /* | |
| 290 | + * root blkg is destroyed. Just clear the pointer since | |
| 291 | + * root_rl does not take reference on root blkg. | |
| 292 | + */ | |
| 293 | + q->root_blkg = NULL; | |
| 294 | + q->root_rl.blkg = NULL; | |
| 288 | 295 | } |
| 289 | 296 | |
| 290 | 297 | static void blkg_rcu_free(struct rcu_head *rcu_head) |
| @@ -326,6 +333,9 @@ struct request_list *__blk_queue_next_rl(struct request_list *rl, · 35 unmodified lines | ||
| 326 | 333 | */ |
| 327 | 334 | if (rl == &q->root_rl) { |
| 328 | 335 | ent = &q->blkg_list; |
| 336 | + /* There are no more block groups, hence no request lists */ | |
| 337 | + if (list_empty(ent)) | |
| 338 | + return NULL; | |
| 329 | 339 | } else { |
| 330 | 340 | blkg = container_of(rl, struct blkcg_gq, rl); |
| 331 | 341 | ent = &blkg->q_node; |
| @@ -2868,7 +2868,8 @@ static int plug_rq_cmp(void *priv, struct list_head *a, struct list_head *b) · 2867 unmodified lines | ||
| 2868 | 2868 | struct request *rqa = container_of(a, struct request, queuelist); |
| 2869 | 2869 | struct request *rqb = container_of(b, struct request, queuelist); |
| 2870 | 2870 | |
| 2871 | − return !(rqa->q <= rqb->q); | |
| 2871 | + return !(rqa->q < rqb->q || | |
| 2872 | + (rqa->q == rqb->q && blk_rq_pos(rqa) < blk_rq_pos(rqb))); | |
| 2872 | 2873 | } |
| 2873 | 2874 | |
| 2874 | 2875 | /* |
| @@ -52,11 +52,17 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk, · 51 unmodified lines | ||
| 52 | 52 | rq_end_io_fn *done) |
| 53 | 53 | { |
| 54 | 54 | int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK; |
| 55 | + bool is_pm_resume; | |
| 55 | 56 | |
| 56 | 57 | WARN_ON(irqs_disabled()); |
| 57 | 58 | |
| 58 | 59 | rq->rq_disk = bd_disk; |
| 59 | 60 | rq->end_io = done; |
| 61 | + /* | |
| 62 | + * need to check this before __blk_run_queue(), because rq can | |
| 63 | + * be freed before that returns. | |
| 64 | + */ | |
| 65 | + is_pm_resume = rq->cmd_type == REQ_TYPE_PM_RESUME; | |
| 60 | 66 | |
| 61 | 67 | spin_lock_irq(q->queue_lock); |
| 62 | 68 | |
| @@ -71,7 +77,7 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk, · 8 unmodified lines | ||
| 71 | 77 | __elv_add_request(q, rq, where); |
| 72 | 78 | __blk_run_queue(q); |
| 73 | 79 | /* the queue is stopped so it won't be run */ |
| 74 | − if (rq->cmd_type == REQ_TYPE_PM_RESUME) | |
| 80 | + if (is_pm_resume) | |
| 75 | 81 | q->request_fn(q); |
| 76 | 82 | spin_unlock_irq(q->queue_lock); |
| 77 | 83 | } |
| @@ -137,13 +137,18 @@ static void cryptd_queue_worker(struct work_struct *work) · 136 unmodified lines | ||
| 137 | 137 | struct crypto_async_request *req, *backlog; |
| 138 | 138 | |
| 139 | 139 | cpu_queue = container_of(work, struct cryptd_cpu_queue, work); |
| 140 | − /* Only handle one request at a time to avoid hogging crypto | |
| 141 | − * workqueue. preempt_disable/enable is used to prevent | |
| 142 | − * being preempted by cryptd_enqueue_request() */ | |
| 140 | + /* | |
| 141 | + * Only handle one request at a time to avoid hogging crypto workqueue. | |
| 142 | + * preempt_disable/enable is used to prevent being preempted by | |
| 143 | + * cryptd_enqueue_request(). local_bh_disable/enable is used to prevent | |
| 144 | + * cryptd_enqueue_request() being accessed from software interrupts. | |
| 145 | + */ | |
| 146 | + local_bh_disable(); | |
| 143 | 147 | preempt_disable(); |
| 144 | 148 | backlog = crypto_get_backlog(&cpu_queue->queue); |
| 145 | 149 | req = crypto_dequeue_request(&cpu_queue->queue); |
| 146 | 150 | preempt_enable(); |
| 151 | + local_bh_enable(); | |
| 147 | 152 | |
| 148 | 153 | if (!req) |
| 149 | 154 | return; |
| @@ -159,6 +159,7 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) · 158 unmodified lines | ||
| 159 | 159 | if (physical_node->node_id >= ACPI_MAX_PHYSICAL_NODE) { |
| 160 | 160 | retval = -ENOSPC; |
| 161 | 161 | mutex_unlock(&acpi_dev->physical_node_lock); |
| 162 | + kfree(physical_node); | |
| 162 | 163 | goto err; |
| 163 | 164 | } |
| 164 | 165 | |
| @@ -409,6 +409,7 @@ static void acpi_processor_notify(struct acpi_device *device, u32 event) · 408 unmodified lines | ||
| 409 | 409 | acpi_bus_generate_proc_event(device, event, 0); |
| 410 | 410 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
| 411 | 411 | dev_name(&device->dev), event, 0); |
| 412 | + break; | |
| 412 | 413 | default: |
| 413 | 414 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
| 414 | 415 | "Unsupported event [0x%x]\n", event)); |
| @@ -1345,12 +1345,15 @@ static int · 1344 unmodified lines | ||
| 1345 | 1345 | acpi_video_bus_get_devices(struct acpi_video_bus *video, |
| 1346 | 1346 | struct acpi_device *device) |
| 1347 | 1347 | { |
| 1348 | − int status; | |
| 1348 | + int status = 0; | |
| 1349 | 1349 | struct acpi_device *dev; |
| 1350 | 1350 | |
| 1351 | − status = acpi_video_device_enumerate(video); | |
| 1352 | − if (status) | |
| 1353 | − return status; | |
| 1351 | + /* | |
| 1352 | + * There are systems where video module known to work fine regardless | |
| 1353 | + * of broken _DOD and ignoring returned value here doesn't cause | |
| 1354 | + * any issues later. | |
| 1355 | + */ | |
| 1356 | + acpi_video_device_enumerate(video); | |
| 1354 | 1357 | |
| 1355 | 1358 | list_for_each_entry(dev, &device->children, node) { |
| 1356 | 1359 | |
| @@ -238,7 +238,7 @@ static int __devexit ahci_remove(struct platform_device *pdev) · 237 unmodified lines | ||
| 238 | 238 | return 0; |
| 239 | 239 | } |
| 240 | 240 | |
| 241 | −#ifdef CONFIG_PM | |
| 241 | +#ifdef CONFIG_PM_SLEEP | |
| 242 | 242 | static int ahci_suspend(struct device *dev) |
| 243 | 243 | { |
| 244 | 244 | struct ahci_platform_data *pdata = dev_get_platdata(dev); |
| @@ -1105,10 +1105,15 @@ static int ata_acpi_bind_device(struct ata_port *ap, struct scsi_device *sdev, · 1104 unmodified lines | ||
| 1105 | 1105 | struct acpi_device *acpi_dev; |
| 1106 | 1106 | struct acpi_device_power_state *states; |
| 1107 | 1107 | |
| 1108 | − if (ap->flags & ATA_FLAG_ACPI_SATA) | |
| 1109 | − ata_dev = &ap->link.device[sdev->channel]; | |
| 1110 | − else | |
| 1108 | + if (ap->flags & ATA_FLAG_ACPI_SATA) { | |
| 1109 | + if (!sata_pmp_attached(ap)) | |
| 1110 | + ata_dev = &ap->link.device[sdev->id]; | |
| 1111 | + else | |
| 1112 | + ata_dev = &ap->pmp_link[sdev->channel].device[sdev->id]; | |
| 1113 | + } | |
| 1114 | + else { | |
| 1111 | 1115 | ata_dev = &ap->link.device[sdev->id]; |
| 1116 | + } | |
| 1112 | 1117 | |
| 1113 | 1118 | *handle = ata_dev_acpi_handle(ata_dev); |
| 1114 | 1119 | |
| @@ -2942,6 +2942,10 @@ const struct ata_timing *ata_timing_find_mode(u8 xfer_mode) · 2941 unmodified lines | ||
| 2942 | 2942 | |
| 2943 | 2943 | if (xfer_mode == t->mode) |
| 2944 | 2944 | return t; |
| 2945 | + | |
| 2946 | + WARN_ONCE(true, "%s: unable to find timing for xfer_mode 0x%x\n", | |
| 2947 | + __func__, xfer_mode); | |
| 2948 | + | |
| 2945 | 2949 | return NULL; |
| 2946 | 2950 | } |
| 2947 | 2951 | |
| @@ -1052,6 +1052,8 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev) · 1051 unmodified lines | ||
| 1052 | 1052 | { |
| 1053 | 1053 | sdev->use_10_for_rw = 1; |
| 1054 | 1054 | sdev->use_10_for_ms = 1; |
| 1055 | + sdev->no_report_opcodes = 1; | |
| 1056 | + sdev->no_write_same = 1; | |
| 1055 | 1057 | |
| 1056 | 1058 | /* Schedule policy is determined by ->qc_defer() callback and |
| 1057 | 1059 | * it needs to see every deferred qc. Set dev_blocked to 1 to |
| @@ -317,6 +317,12 @@ static int cf_init(struct arasan_cf_dev *acdev) · 316 unmodified lines | ||
| 317 | 317 | return ret; |
| 318 | 318 | } |
| 319 | 319 | |
| 320 | + ret = clk_set_rate(acdev->clk, 166000000); | |
| 321 | + if (ret) { | |
| 322 | + dev_warn(acdev->host->dev, "clock set rate failed"); | |
| 323 | + return ret; | |
| 324 | + } | |
| 325 | + | |
| 320 | 326 | spin_lock_irqsave(&acdev->host->lock, flags); |
| 321 | 327 | /* configure CF interface clock */ |
| 322 | 328 | writel((pdata->cf_if_clk <= CF_IF_CLK_200M) ? pdata->cf_if_clk : |
| @@ -908,7 +914,7 @@ static int __devexit arasan_cf_remove(struct platform_device *pdev) · 585 unmodified lines | ||
| 908 | 914 | return 0; |
| 909 | 915 | } |
| 910 | 916 | |
| 911 | −#ifdef CONFIG_PM | |
| 917 | +#ifdef CONFIG_PM_SLEEP | |
| 912 | 918 | static int arasan_cf_suspend(struct device *dev) |
| 913 | 919 | { |
| 914 | 920 | struct ata_host *host = dev_get_drvdata(dev); |
| @@ -260,7 +260,7 @@ static const struct of_device_id ahci_of_match[] = { · 259 unmodified lines | ||
| 260 | 260 | }; |
| 261 | 261 | MODULE_DEVICE_TABLE(of, ahci_of_match); |
| 262 | 262 | |
| 263 | −static int __init ahci_highbank_probe(struct platform_device *pdev) | |
| 263 | +static int __devinit ahci_highbank_probe(struct platform_device *pdev) | |
| 264 | 264 | { |
| 265 | 265 | struct device *dev = &pdev->dev; |
| 266 | 266 | struct ahci_host_priv *hpriv; |
| @@ -378,7 +378,7 @@ static int __devexit ahci_highbank_remove(struct platform_device *pdev) · 111 unmodified lines | ||
| 378 | 378 | return 0; |
| 379 | 379 | } |
| 380 | 380 | |
| 381 | −#ifdef CONFIG_PM | |
| 381 | +#ifdef CONFIG_PM_SLEEP | |
| 382 | 382 | static int ahci_highbank_suspend(struct device *dev) |
| 383 | 383 | { |
| 384 | 384 | struct ata_host *host = dev_get_drvdata(dev); |
| @@ -142,6 +142,39 @@ static int k2_sata_scr_write(struct ata_link *link, · 141 unmodified lines | ||
| 142 | 142 | return 0; |
| 143 | 143 | } |
| 144 | 144 | |
| 145 | +static int k2_sata_softreset(struct ata_link *link, | |
| 146 | + unsigned int *class, unsigned long deadline) | |
| 147 | +{ | |
| 148 | + u8 dmactl; | |
| 149 | + void __iomem *mmio = link->ap->ioaddr.bmdma_addr; | |
| 150 | + | |
| 151 | + dmactl = readb(mmio + ATA_DMA_CMD); | |
| 152 | + | |
| 153 | + /* Clear the start bit */ | |
| 154 | + if (dmactl & ATA_DMA_START) { | |
| 155 | + dmactl &= ~ATA_DMA_START; | |
| 156 | + writeb(dmactl, mmio + ATA_DMA_CMD); | |
| 157 | + } | |
| 158 | + | |
| 159 | + return ata_sff_softreset(link, class, deadline); | |
| 160 | +} | |
| 161 | + | |
| 162 | +static int k2_sata_hardreset(struct ata_link *link, | |
| 163 | + unsigned int *class, unsigned long deadline) | |
| 164 | +{ | |
| 165 | + u8 dmactl; | |
| 166 | + void __iomem *mmio = link->ap->ioaddr.bmdma_addr; | |
| 167 | + | |
| 168 | + dmactl = readb(mmio + ATA_DMA_CMD); | |
| 169 | + | |
| 170 | + /* Clear the start bit */ | |
| 171 | + if (dmactl & ATA_DMA_START) { | |
| 172 | + dmactl &= ~ATA_DMA_START; | |
| 173 | + writeb(dmactl, mmio + ATA_DMA_CMD); | |
| 174 | + } | |
| 175 | + | |
| 176 | + return sata_sff_hardreset(link, class, deadline); | |
| 177 | +} | |
| 145 | 178 | |
| 146 | 179 | static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) |
| 147 | 180 | { |
| @@ -346,6 +379,8 @@ static struct scsi_host_template k2_sata_sht = { · 198 unmodified lines | ||
| 346 | 379 | |
| 347 | 380 | static struct ata_port_operations k2_sata_ops = { |
| 348 | 381 | .inherits = &ata_bmdma_port_ops, |
| 382 | + .softreset = k2_sata_softreset, | |
| 383 | + .hardreset = k2_sata_hardreset, | |
| 349 | 384 | .sff_tf_load = k2_sata_tf_load, |
| 350 | 385 | .sff_tf_read = k2_sata_tf_read, |
| 351 | 386 | .sff_check_status = k2_stat_check_status, |
| @@ -1961,6 +1961,7 @@ static int __devinit ucode_init (loader_block * lb, amb_dev * dev) { · 1960 unmodified lines | ||
| 1961 | 1961 | res = loader_verify(lb, dev, rec); |
| 1962 | 1962 | if (res) |
| 1963 | 1963 | break; |
| 1964 | + rec = ihex_next_binrec(rec); | |
| 1964 | 1965 | } |
| 1965 | 1966 | release_firmware(fw); |
| 1966 | 1967 | if (!res) |
| @@ -236,7 +236,7 @@ config CMA_SIZE_PERCENTAGE · 235 unmodified lines | ||
| 236 | 236 | |
| 237 | 237 | choice |
| 238 | 238 | prompt "Selected region size" |
| 239 | − default CMA_SIZE_SEL_ABSOLUTE | |
| 239 | + default CMA_SIZE_SEL_MBYTES | |
| 240 | 240 | |
| 241 | 241 | config CMA_SIZE_SEL_MBYTES |
| 242 | 242 | bool "Use mega bytes value only" |
| @@ -191,9 +191,8 @@ EXPORT_SYMBOL(dma_release_from_coherent); · 190 unmodified lines | ||
| 191 | 191 | * This checks whether the memory was allocated from the per-device |
| 192 | 192 | * coherent memory pool and if so, maps that memory to the provided vma. |
| 193 | 193 | * |
| 194 | − * Returns 1 if we correctly mapped the memory, or 0 if | |
| 195 | − * dma_release_coherent() should proceed with mapping memory from | |
| 196 | − * generic pools. | |
| 194 | + * Returns 1 if we correctly mapped the memory, or 0 if the caller should | |
| 195 | + * proceed with mapping memory from generic pools. | |
| 197 | 196 | */ |
| 198 | 197 | int dma_mmap_from_coherent(struct device *dev, struct vm_area_struct *vma, |
| 199 | 198 | void *vaddr, size_t size, int *ret) |
| @@ -27,15 +27,12 @@ · 26 unmodified lines | ||
| 27 | 27 | #include <linux/mm.h> |
| 28 | 28 | #include <linux/mutex.h> |
| 29 | 29 | #include <linux/page-isolation.h> |
| 30 | +#include <linux/sizes.h> | |
| 30 | 31 | #include <linux/slab.h> |
| 31 | 32 | #include <linux/swap.h> |
| 32 | 33 | #include <linux/mm_types.h> |
| 33 | 34 | #include <linux/dma-contiguous.h> |
| 34 | 35 | |
| 35 | −#ifndef SZ_1M | |
| 36 | −#define SZ_1M (1 << 20) | |
| 37 | −#endif | |
| 38 | − | |
| 39 | 36 | struct cma { |
| 40 | 37 | unsigned long base_pfn; |
| 41 | 38 | unsigned long count; |
| @@ -36,68 +36,6 @@ MODULE_AUTHOR("Manuel Estrada Sainz"); · 35 unmodified lines | ||
| 36 | 36 | MODULE_DESCRIPTION("Multi purpose firmware loading support"); |
| 37 | 37 | MODULE_LICENSE("GPL"); |
| 38 | 38 | |
| 39 | −static const char *fw_path[] = { | |
| 40 | − "/lib/firmware/updates/" UTS_RELEASE, | |
| 41 | − "/lib/firmware/updates", | |
| 42 | − "/lib/firmware/" UTS_RELEASE, | |
| 43 | − "/lib/firmware" | |
| 44 | −}; | |
| 45 | − | |
| 46 | −/* Don't inline this: 'struct kstat' is biggish */ | |
| 47 | −static noinline long fw_file_size(struct file *file) | |
| 48 | −{ | |
| 49 | − struct kstat st; | |
| 50 | − if (vfs_getattr(file->f_path.mnt, file->f_path.dentry, &st)) | |
| 51 | − return -1; | |
| 52 | − if (!S_ISREG(st.mode)) | |
| 53 | − return -1; | |
| 54 | − if (st.size != (long)st.size) | |
| 55 | − return -1; | |
| 56 | − return st.size; | |
| 57 | −} | |
| 58 | − | |
| 59 | −static bool fw_read_file_contents(struct file *file, struct firmware *fw) | |
| 60 | −{ | |
| 61 | − long size; | |
| 62 | − char *buf; | |
| 63 | − | |
| 64 | − size = fw_file_size(file); | |
| 65 | − if (size < 0) | |
| 66 | − return false; | |
| 67 | − buf = vmalloc(size); | |
| 68 | − if (!buf) | |
| 69 | − return false; | |
| 70 | − if (kernel_read(file, 0, buf, size) != size) { | |
| 71 | − vfree(buf); | |
| 72 | − return false; | |
| 73 | − } | |
| 74 | − fw->data = buf; | |
| 75 | − fw->size = size; | |
| 76 | − return true; | |
| 77 | −} | |
| 78 | − | |
| 79 | −static bool fw_get_filesystem_firmware(struct firmware *fw, const char *name) | |
| 80 | −{ | |
| 81 | − int i; | |
| 82 | − bool success = false; | |
| 83 | − char *path = __getname(); | |
| 84 | − | |
| 85 | − for (i = 0; i < ARRAY_SIZE(fw_path); i++) { | |
| 86 | − struct file *file; | |
| 87 | − snprintf(path, PATH_MAX, "%s/%s", fw_path[i], name); | |
| 88 | − | |
| 89 | − file = filp_open(path, O_RDONLY, 0); | |
| 90 | − if (IS_ERR(file)) | |
| 91 | − continue; | |
| 92 | − success = fw_read_file_contents(file, fw); | |
| 93 | − fput(file); | |
| 94 | − if (success) | |
| 95 | − break; | |
| 96 | − } | |
| 97 | − __putname(path); | |
| 98 | − return success; | |
| 99 | −} | |
| 100 | − | |
| 101 | 39 | /* Builtin firmware support */ |
| 102 | 40 | |
| 103 | 41 | #ifdef CONFIG_FW_LOADER |
| @@ -150,6 +88,11 @@ enum { · 46 unmodified lines | ||
| 150 | 88 | FW_STATUS_ABORT, |
| 151 | 89 | }; |
| 152 | 90 | |
| 91 | +enum fw_buf_fmt { | |
| 92 | + VMALLOC_BUF, /* used in direct loading */ | |
| 93 | + PAGE_BUF, /* used in loading via userspace */ | |
| 94 | +}; | |
| 95 | + | |
| 153 | 96 | static int loading_timeout = 60; /* In seconds */ |
| 154 | 97 | |
| 155 | 98 | static inline long firmware_loading_timeout(void) |
| @@ -173,8 +116,6 @@ struct firmware_cache { · 17 unmodified lines | ||
| 173 | 116 | spinlock_t name_lock; |
| 174 | 117 | struct list_head fw_names; |
| 175 | 118 | |
| 176 | − wait_queue_head_t wait_queue; | |
| 177 | − int cnt; | |
| 178 | 119 | struct delayed_work work; |
| 179 | 120 | |
| 180 | 121 | struct notifier_block pm_notify; |
| @@ -187,6 +128,7 @@ struct firmware_buf { · 6 unmodified lines | ||
| 187 | 128 | struct completion completion; |
| 188 | 129 | struct firmware_cache *fwc; |
| 189 | 130 | unsigned long status; |
| 131 | + enum fw_buf_fmt fmt; | |
| 190 | 132 | void *data; |
| 191 | 133 | size_t size; |
| 192 | 134 | struct page **pages; |
| @@ -240,6 +182,7 @@ static struct firmware_buf *__allocate_fw_buf(const char *fw_name, · 47 unmodified lines | ||
| 240 | 182 | strcpy(buf->fw_id, fw_name); |
| 241 | 183 | buf->fwc = fwc; |
| 242 | 184 | init_completion(&buf->completion); |
| 185 | + buf->fmt = VMALLOC_BUF; | |
| 243 | 186 | |
| 244 | 187 | pr_debug("%s: fw-%s buf=%p\n", __func__, fw_name, buf); |
| 245 | 188 | |
| @@ -307,10 +250,14 @@ static void __fw_free_buf(struct kref *ref) · 61 unmodified lines | ||
| 307 | 250 | list_del(&buf->list); |
| 308 | 251 | spin_unlock(&fwc->lock); |
| 309 | 252 | |
| 310 | − vunmap(buf->data); | |
| 311 | − for (i = 0; i < buf->nr_pages; i++) | |
| 312 | − __free_page(buf->pages[i]); | |
| 313 | − kfree(buf->pages); | |
| 253 | + | |
| 254 | + if (buf->fmt == PAGE_BUF) { | |
| 255 | + vunmap(buf->data); | |
| 256 | + for (i = 0; i < buf->nr_pages; i++) | |
| 257 | + __free_page(buf->pages[i]); | |
| 258 | + kfree(buf->pages); | |
| 259 | + } else | |
| 260 | + vfree(buf->data); | |
| 314 | 261 | kfree(buf); |
| 315 | 262 | } |
| 316 | 263 | |
| @@ -319,6 +266,69 @@ static void fw_free_buf(struct firmware_buf *buf) · 2 unmodified lines | ||
| 319 | 266 | kref_put(&buf->ref, __fw_free_buf); |
| 320 | 267 | } |
| 321 | 268 | |
| 269 | +/* direct firmware loading support */ | |
| 270 | +static const char *fw_path[] = { | |
| 271 | + "/lib/firmware/updates/" UTS_RELEASE, | |
| 272 | + "/lib/firmware/updates", | |
| 273 | + "/lib/firmware/" UTS_RELEASE, | |
| 274 | + "/lib/firmware" | |
| 275 | +}; | |
| 276 | + | |
| 277 | +/* Don't inline this: 'struct kstat' is biggish */ | |
| 278 | +static noinline long fw_file_size(struct file *file) | |
| 279 | +{ | |
| 280 | + struct kstat st; | |
| 281 | + if (vfs_getattr(file->f_path.mnt, file->f_path.dentry, &st)) | |
| 282 | + return -1; | |
| 283 | + if (!S_ISREG(st.mode)) | |
| 284 | + return -1; | |
| 285 | + if (st.size != (long)st.size) | |
| 286 | + return -1; | |
| 287 | + return st.size; | |
| 288 | +} | |
| 289 | + | |
| 290 | +static bool fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf) | |
| 291 | +{ | |
| 292 | + long size; | |
| 293 | + char *buf; | |
| 294 | + | |
| 295 | + size = fw_file_size(file); | |
| 296 | + if (size < 0) | |
| 297 | + return false; | |
| 298 | + buf = vmalloc(size); | |
| 299 | + if (!buf) | |
| 300 | + return false; | |
| 301 | + if (kernel_read(file, 0, buf, size) != size) { | |
| 302 | + vfree(buf); | |
| 303 | + return false; | |
| 304 | + } | |
| 305 | + fw_buf->data = buf; | |
| 306 | + fw_buf->size = size; | |
| 307 | + return true; | |
| 308 | +} | |
| 309 | + | |
| 310 | +static bool fw_get_filesystem_firmware(struct firmware_buf *buf) | |
| 311 | +{ | |
| 312 | + int i; | |
| 313 | + bool success = false; | |
| 314 | + char *path = __getname(); | |
| 315 | + | |
| 316 | + for (i = 0; i < ARRAY_SIZE(fw_path); i++) { | |
| 317 | + struct file *file; | |
| 318 | + snprintf(path, PATH_MAX, "%s/%s", fw_path[i], buf->fw_id); | |
| 319 | + | |
| 320 | + file = filp_open(path, O_RDONLY, 0); | |
| 321 | + if (IS_ERR(file)) | |
| 322 | + continue; | |
| 323 | + success = fw_read_file_contents(file, buf); | |
| 324 | + fput(file); | |
| 325 | + if (success) | |
| 326 | + break; | |
| 327 | + } | |
| 328 | + __putname(path); | |
| 329 | + return success; | |
| 330 | +} | |
| 331 | + | |
| 322 | 332 | static struct firmware_priv *to_firmware_priv(struct device *dev) |
| 323 | 333 | { |
| 324 | 334 | return container_of(dev, struct firmware_priv, dev); |
| @@ -423,6 +433,21 @@ static void firmware_free_data(const struct firmware *fw) · 98 unmodified lines | ||
| 423 | 433 | #ifndef PAGE_KERNEL_RO |
| 424 | 434 | #define PAGE_KERNEL_RO PAGE_KERNEL |
| 425 | 435 | #endif |
| 436 | + | |
| 437 | +/* one pages buffer should be mapped/unmapped only once */ | |
| 438 | +static int fw_map_pages_buf(struct firmware_buf *buf) | |
| 439 | +{ | |
| 440 | + if (buf->fmt != PAGE_BUF) | |
| 441 | + return 0; | |
| 442 | + | |
| 443 | + if (buf->data) | |
| 444 | + vunmap(buf->data); | |
| 445 | + buf->data = vmap(buf->pages, buf->nr_pages, 0, PAGE_KERNEL_RO); | |
| 446 | + if (!buf->data) | |
| 447 | + return -ENOMEM; | |
| 448 | + return 0; | |
| 449 | +} | |
| 450 | + | |
| 426 | 451 | /** |
| 427 | 452 | * firmware_loading_store - set value in the 'loading' control file |
| 428 | 453 | * @dev: device pointer |
| @@ -467,6 +492,14 @@ static ssize_t firmware_loading_store(struct device *dev, · 38 unmodified lines | ||
| 467 | 492 | if (test_bit(FW_STATUS_LOADING, &fw_buf->status)) { |
| 468 | 493 | set_bit(FW_STATUS_DONE, &fw_buf->status); |
| 469 | 494 | clear_bit(FW_STATUS_LOADING, &fw_buf->status); |
| 495 | + | |
| 496 | + /* | |
| 497 | + * Several loading requests may be pending on | |
| 498 | + * one same firmware buf, so let all requests | |
| 499 | + * see the mapped 'buf->data' once the loading | |
| 500 | + * is completed. | |
| 501 | + * */ | |
| 502 | + fw_map_pages_buf(fw_buf); | |
| 470 | 503 | complete_all(&fw_buf->completion); |
| 471 | 504 | break; |
| 472 | 505 | } |
| @@ -670,15 +703,6 @@ exit: · 197 unmodified lines | ||
| 670 | 703 | return fw_priv; |
| 671 | 704 | } |
| 672 | 705 | |
| 673 | −/* one pages buffer is mapped/unmapped only once */ | |
| 674 | −static int fw_map_pages_buf(struct firmware_buf *buf) | |
| 675 | −{ | |
| 676 | − buf->data = vmap(buf->pages, buf->nr_pages, 0, PAGE_KERNEL_RO); | |
| 677 | − if (!buf->data) | |
| 678 | − return -ENOMEM; | |
| 679 | − return 0; | |
| 680 | −} | |
| 681 | − | |
| 682 | 706 | /* store the pages buffer info firmware from buf */ |
| 683 | 707 | static void fw_set_page_data(struct firmware_buf *buf, struct firmware *fw) |
| 684 | 708 | { |
| @@ -778,11 +802,6 @@ _request_firmware_prepare(const struct firmware **firmware_p, const char *name, · 93 unmodified lines | ||
| 778 | 802 | return NULL; |
| 779 | 803 | } |
| 780 | 804 | |
| 781 | − if (fw_get_filesystem_firmware(firmware, name)) { | |
| 782 | − dev_dbg(device, "firmware: direct-loading firmware %s\n", name); | |
| 783 | − return NULL; | |
| 784 | − } | |
| 785 | − | |
| 786 | 805 | ret = fw_lookup_and_allocate_buf(name, &fw_cache, &buf); |
| 787 | 806 | if (!ret) |
| 788 | 807 | fw_priv = fw_create_instance(firmware, name, device, |
| @@ -832,6 +851,21 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, · 43 unmodified lines | ||
| 832 | 851 | struct device *f_dev = &fw_priv->dev; |
| 833 | 852 | struct firmware_buf *buf = fw_priv->buf; |
| 834 | 853 | struct firmware_cache *fwc = &fw_cache; |
| 854 | + int direct_load = 0; | |
| 855 | + | |
| 856 | + /* try direct loading from fs first */ | |
| 857 | + if (fw_get_filesystem_firmware(buf)) { | |
| 858 | + dev_dbg(f_dev->parent, "firmware: direct-loading" | |
| 859 | + " firmware %s\n", buf->fw_id); | |
| 860 | + | |
| 861 | + set_bit(FW_STATUS_DONE, &buf->status); | |
| 862 | + complete_all(&buf->completion); | |
| 863 | + direct_load = 1; | |
| 864 | + goto handle_fw; | |
| 865 | + } | |
| 866 | + | |
| 867 | + /* fall back on userspace loading */ | |
| 868 | + buf->fmt = PAGE_BUF; | |
| 835 | 869 | |
| 836 | 870 | dev_set_uevent_suppress(f_dev, true); |
| 837 | 871 | |
| @@ -870,6 +904,7 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, · 32 unmodified lines | ||
| 870 | 904 | |
| 871 | 905 | del_timer_sync(&fw_priv->timeout); |
| 872 | 906 | |
| 907 | +handle_fw: | |
| 873 | 908 | mutex_lock(&fw_lock); |
| 874 | 909 | if (!buf->size || test_bit(FW_STATUS_ABORT, &buf->status)) |
| 875 | 910 | retval = -ENOENT; |
| @@ -884,9 +919,6 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, · 8 unmodified lines | ||
| 884 | 919 | if (!retval && f_dev->parent) |
| 885 | 920 | fw_add_devm_name(f_dev->parent, buf->fw_id); |
| 886 | 921 | |
| 887 | − if (!retval) | |
| 888 | − retval = fw_map_pages_buf(buf); | |
| 889 | − | |
| 890 | 922 | /* |
| 891 | 923 | * After caching firmware image is started, let it piggyback |
| 892 | 924 | * on request firmware. |
| @@ -902,6 +934,9 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, · 9 unmodified lines | ||
| 902 | 934 | fw_priv->buf = NULL; |
| 903 | 935 | mutex_unlock(&fw_lock); |
| 904 | 936 | |
| 937 | + if (direct_load) | |
| 938 | + goto err_put_dev; | |
| 939 | + | |
| 905 | 940 | device_remove_file(f_dev, &dev_attr_loading); |
| 906 | 941 | err_del_bin_attr: |
| 907 | 942 | device_remove_bin_file(f_dev, &firmware_attr_data); |
| @@ -1129,6 +1164,8 @@ int uncache_firmware(const char *fw_name) · 221 unmodified lines | ||
| 1129 | 1164 | } |
| 1130 | 1165 | |
| 1131 | 1166 | #ifdef CONFIG_PM_SLEEP |
| 1167 | +static ASYNC_DOMAIN_EXCLUSIVE(fw_cache_domain); | |
| 1168 | + | |
| 1132 | 1169 | static struct fw_cache_entry *alloc_fw_cache_entry(const char *name) |
| 1133 | 1170 | { |
| 1134 | 1171 | struct fw_cache_entry *fce; |
| @@ -1142,17 +1179,27 @@ exit: · 7 unmodified lines | ||
| 1142 | 1179 | return fce; |
| 1143 | 1180 | } |
| 1144 | 1181 | |
| 1145 | −static int fw_cache_piggyback_on_request(const char *name) | |
| 1182 | +static int __fw_entry_found(const char *name) | |
| 1146 | 1183 | { |
| 1147 | 1184 | struct firmware_cache *fwc = &fw_cache; |
| 1148 | 1185 | struct fw_cache_entry *fce; |
| 1149 | − int ret = 0; | |
| 1150 | 1186 | |
| 1151 | − spin_lock(&fwc->name_lock); | |
| 1152 | 1187 | list_for_each_entry(fce, &fwc->fw_names, list) { |
| 1153 | 1188 | if (!strcmp(fce->name, name)) |
| 1154 | − goto found; | |
| 1189 | + return 1; | |
| 1155 | 1190 | } |
| 1191 | + return 0; | |
| 1192 | +} | |
| 1193 | + | |
| 1194 | +static int fw_cache_piggyback_on_request(const char *name) | |
| 1195 | +{ | |
| 1196 | + struct firmware_cache *fwc = &fw_cache; | |
| 1197 | + struct fw_cache_entry *fce; | |
| 1198 | + int ret = 0; | |
| 1199 | + | |
| 1200 | + spin_lock(&fwc->name_lock); | |
| 1201 | + if (__fw_entry_found(name)) | |
| 1202 | + goto found; | |
| 1156 | 1203 | |
| 1157 | 1204 | fce = alloc_fw_cache_entry(name); |
| 1158 | 1205 | if (fce) { |
| @@ -1185,12 +1232,6 @@ static void __async_dev_cache_fw_image(void *fw_entry, · 26 unmodified lines | ||
| 1185 | 1232 | |
| 1186 | 1233 | free_fw_cache_entry(fce); |
| 1187 | 1234 | } |
| 1188 | − | |
| 1189 | − spin_lock(&fwc->name_lock); | |
| 1190 | − fwc->cnt--; | |
| 1191 | − spin_unlock(&fwc->name_lock); | |
| 1192 | − | |
| 1193 | − wake_up(&fwc->wait_queue); | |
| 1194 | 1235 | } |
| 1195 | 1236 | |
| 1196 | 1237 | /* called with dev->devres_lock held */ |
| @@ -1229,11 +1270,19 @@ static void dev_cache_fw_image(struct device *dev, void *data) · 32 unmodified lines | ||
| 1229 | 1270 | list_del(&fce->list); |
| 1230 | 1271 | |
| 1231 | 1272 | spin_lock(&fwc->name_lock); |
| 1232 | − fwc->cnt++; | |
| 1233 | − list_add(&fce->list, &fwc->fw_names); | |
| 1273 | + /* only one cache entry for one firmware */ | |
| 1274 | + if (!__fw_entry_found(fce->name)) { | |
| 1275 | + list_add(&fce->list, &fwc->fw_names); | |
| 1276 | + } else { | |
| 1277 | + free_fw_cache_entry(fce); | |
| 1278 | + fce = NULL; | |
| 1279 | + } | |
| 1234 | 1280 | spin_unlock(&fwc->name_lock); |
| 1235 | 1281 | |
| 1236 | − async_schedule(__async_dev_cache_fw_image, (void *)fce); | |
| 1282 | + if (fce) | |
| 1283 | + async_schedule_domain(__async_dev_cache_fw_image, | |
| 1284 | + (void *)fce, | |
| 1285 | + &fw_cache_domain); | |
| 1237 | 1286 | } |
| 1238 | 1287 | } |
| 1239 | 1288 | |
| @@ -1275,6 +1324,9 @@ static void device_cache_fw_images(void) · 35 unmodified lines | ||
| 1275 | 1324 | |
| 1276 | 1325 | pr_debug("%s\n", __func__); |
| 1277 | 1326 | |
| 1327 | + /* cancel uncache work */ | |
| 1328 | + cancel_delayed_work_sync(&fwc->work); | |
| 1329 | + | |
| 1278 | 1330 | /* |
| 1279 | 1331 | * use small loading timeout for caching devices' firmware |
| 1280 | 1332 | * because all these firmware images have been loaded |
| @@ -1292,21 +1344,7 @@ static void device_cache_fw_images(void) · 11 unmodified lines | ||
| 1292 | 1344 | mutex_unlock(&fw_lock); |
| 1293 | 1345 | |
| 1294 | 1346 | /* wait for completion of caching firmware for all devices */ |
| 1295 | − spin_lock(&fwc->name_lock); | |
| 1296 | − for (;;) { | |
| 1297 | − prepare_to_wait(&fwc->wait_queue, &wait, | |
| 1298 | − TASK_UNINTERRUPTIBLE); | |
| 1299 | − if (!fwc->cnt) | |
| 1300 | − break; | |
| 1301 | − | |
| 1302 | − spin_unlock(&fwc->name_lock); | |
| 1303 | − | |
| 1304 | − schedule(); | |
| 1305 | − | |
| 1306 | − spin_lock(&fwc->name_lock); | |
| 1307 | − } | |
| 1308 | − spin_unlock(&fwc->name_lock); | |
| 1309 | − finish_wait(&fwc->wait_queue, &wait); | |
| 1347 | + async_synchronize_full_domain(&fw_cache_domain); | |
| 1310 | 1348 | |
| 1311 | 1349 | loading_timeout = old_timeout; |
| 1312 | 1350 | } |
| @@ -1394,9 +1432,7 @@ static void __init fw_cache_init(void) · 81 unmodified lines | ||
| 1394 | 1432 | #ifdef CONFIG_PM_SLEEP |
| 1395 | 1433 | spin_lock_init(&fw_cache.name_lock); |
| 1396 | 1434 | INIT_LIST_HEAD(&fw_cache.fw_names); |
| 1397 | − fw_cache.cnt = 0; | |
| 1398 | 1435 | |
| 1399 | − init_waitqueue_head(&fw_cache.wait_queue); | |
| 1400 | 1436 | INIT_DELAYED_WORK(&fw_cache.work, |
| 1401 | 1437 | device_uncache_fw_images_work); |
| 1402 | 1438 | |
| @@ -83,9 +83,16 @@ EXPORT_SYMBOL_GPL(platform_get_resource); · 82 unmodified lines | ||
| 83 | 83 | */ |
| 84 | 84 | int platform_get_irq(struct platform_device *dev, unsigned int num) |
| 85 | 85 | { |
| 86 | +#ifdef CONFIG_SPARC | |
| 87 | + /* sparc does not have irqs represented as IORESOURCE_IRQ resources */ | |
| 88 | + if (!dev || num >= dev->archdata.num_irqs) | |
| 89 | + return -ENXIO; | |
| 90 | + return dev->archdata.irqs[num]; | |
| 91 | +#else | |
| 86 | 92 | struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num); |
| 87 | 93 | |
| 88 | 94 | return r ? r->start : -ENXIO; |
| 95 | +#endif | |
| 89 | 96 | } |
| 90 | 97 | EXPORT_SYMBOL_GPL(platform_get_irq); |
| 91 | 98 | |
| @@ -1862,7 +1862,7 @@ int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state) · 1861 unmodified lines | ||
| 1862 | 1862 | cpuidle_drv = cpuidle_driver_ref(); |
| 1863 | 1863 | if (!cpuidle_drv) { |
| 1864 | 1864 | ret = -ENODEV; |
| 1865 | − goto out; | |
| 1865 | + goto err_drv; | |
| 1866 | 1866 | } |
| 1867 | 1867 | if (cpuidle_drv->state_count <= state) { |
| 1868 | 1868 | ret = -EINVAL; |
| @@ -1884,6 +1884,9 @@ int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state) · 15 unmodified lines | ||
| 1884 | 1884 | |
| 1885 | 1885 | err: |
| 1886 | 1886 | cpuidle_driver_unref(); |
| 1887 | + | |
| 1888 | + err_drv: | |
| 1889 | + kfree(cpu_data); | |
| 1887 | 1890 | goto out; |
| 1888 | 1891 | } |
| 1889 | 1892 | |
| @@ -451,7 +451,7 @@ int dev_pm_qos_add_ancestor_request(struct device *dev, · 450 unmodified lines | ||
| 451 | 451 | if (ancestor) |
| 452 | 452 | error = dev_pm_qos_add_request(ancestor, req, value); |
| 453 | 453 | |
| 454 | − if (error) | |
| 454 | + if (error < 0) | |
| 455 | 455 | req->dev = NULL; |
| 456 | 456 | |
| 457 | 457 | return error; |
| @@ -158,9 +158,10 @@ static int bcma_register_cores(struct bcma_bus *bus) · 157 unmodified lines | ||
| 158 | 158 | |
| 159 | 159 | static void bcma_unregister_cores(struct bcma_bus *bus) |
| 160 | 160 | { |
| 161 | − struct bcma_device *core; | |
| 161 | + struct bcma_device *core, *tmp; | |
| 162 | 162 | |
| 163 | − list_for_each_entry(core, &bus->cores, list) { | |
| 163 | + list_for_each_entry_safe(core, tmp, &bus->cores, list) { | |
| 164 | + list_del(&core->list); | |
| 164 | 165 | if (core->dev_registered) |
| 165 | 166 | device_unregister(&core->dev); |
| 166 | 167 | } |
| @@ -131,6 +131,7 @@ config BLK_CPQ_DA · 130 unmodified lines | ||
| 131 | 131 | config BLK_CPQ_CISS_DA |
| 132 | 132 | tristate "Compaq Smart Array 5xxx support" |
| 133 | 133 | depends on PCI |
| 134 | + select CHECK_SIGNATURE | |
| 134 | 135 | help |
| 135 | 136 | This is the driver for Compaq Smart Array 5xxx controllers. |
| 136 | 137 | Everyone using these boards should say Y here. |
| @@ -166,8 +167,8 @@ config BLK_DEV_DAC960 · 29 unmodified lines | ||
| 166 | 167 | module will be called DAC960. |
| 167 | 168 | |
| 168 | 169 | config BLK_DEV_UMEM |
| 169 | − tristate "Micro Memory MM5415 Battery Backed RAM support (EXPERIMENTAL)" | |
| 170 | − depends on PCI && EXPERIMENTAL | |
| 170 | + tristate "Micro Memory MM5415 Battery Backed RAM support" | |
| 171 | + depends on PCI | |
| 171 | 172 | ---help--- |
| 172 | 173 | Saying Y here will include support for the MM5415 family of |
| 173 | 174 | battery backed (Non-volatile) RAM cards. |
| @@ -430,8 +431,8 @@ config CDROM_PKTCDVD_BUFFERS · 256 unmodified lines | ||
| 430 | 431 | a disc is opened for writing. |
| 431 | 432 | |
| 432 | 433 | config CDROM_PKTCDVD_WCACHE |
| 433 | − bool "Enable write caching (EXPERIMENTAL)" | |
| 434 | − depends on CDROM_PKTCDVD && EXPERIMENTAL | |
| 434 | + bool "Enable write caching" | |
| 435 | + depends on CDROM_PKTCDVD | |
| 435 | 436 | help |
| 436 | 437 | If enabled, write caching will be set for the CD-R/W device. For now |
| 437 | 438 | this option is dangerous unless the CD-RW media is known good, as we |
| @@ -508,8 +509,8 @@ config XEN_BLKDEV_BACKEND · 70 unmodified lines | ||
| 508 | 509 | |
| 509 | 510 | |
| 510 | 511 | config VIRTIO_BLK |
| 511 | − tristate "Virtio block driver (EXPERIMENTAL)" | |
| 512 | − depends on EXPERIMENTAL && VIRTIO | |
| 512 | + tristate "Virtio block driver" | |
| 513 | + depends on VIRTIO | |
| 513 | 514 | ---help--- |
| 514 | 515 | This is the virtual block driver for virtio. It can be used with |
| 515 | 516 | lguest or QEMU based VMMs (like KVM or Xen). Say Y or M. |
| @@ -528,7 +529,7 @@ config BLK_DEV_HD · 12 unmodified lines | ||
| 528 | 529 | |
| 529 | 530 | config BLK_DEV_RBD |
| 530 | 531 | tristate "Rados block device (RBD)" |
| 531 | − depends on INET && EXPERIMENTAL && BLOCK | |
| 532 | + depends on INET && BLOCK | |
| 532 | 533 | select CEPH_LIB |
| 533 | 534 | select LIBCRC32C |
| 534 | 535 | select CRYPTO_AES |
| @@ -935,7 +935,7 @@ aoe_end_request(struct aoedev *d, struct request *rq, int fastfail) · 934 unmodified lines | ||
| 935 | 935 | |
| 936 | 936 | /* cf. http://lkml.org/lkml/2006/10/31/28 */ |
| 937 | 937 | if (!fastfail) |
| 938 | − q->request_fn(q); | |
| 938 | + __blk_run_queue(q); | |
| 939 | 939 | } |
| 940 | 940 | |
| 941 | 941 | static void |
| @@ -5205,7 +5205,6 @@ static void cciss_shutdown(struct pci_dev *pdev) · 5204 unmodified lines | ||
| 5205 | 5205 | return; |
| 5206 | 5206 | } |
| 5207 | 5207 | /* write all data in the battery backed cache to disk */ |
| 5208 | − memset(flush_buf, 0, 4); | |
| 5209 | 5208 | return_code = sendcmd_withirq(h, CCISS_CACHE_FLUSH, flush_buf, |
| 5210 | 5209 | 4, 0, CTLR_LUNID, TYPE_CMD); |
| 5211 | 5210 | kfree(flush_buf); |
| @@ -4109,12 +4109,19 @@ static struct platform_driver floppy_driver = { · 4108 unmodified lines | ||
| 4109 | 4109 | |
| 4110 | 4110 | static struct platform_device floppy_device[N_DRIVE]; |
| 4111 | 4111 | |
| 4112 | +static bool floppy_available(int drive) | |
| 4113 | +{ | |
| 4114 | + if (!(allowed_drive_mask & (1 << drive))) | |
| 4115 | + return false; | |
| 4116 | + if (fdc_state[FDC(drive)].version == FDC_NONE) | |
| 4117 | + return false; | |
| 4118 | + return true; | |
| 4119 | +} | |
| 4120 | + | |
| 4112 | 4121 | static struct kobject *floppy_find(dev_t dev, int *part, void *data) |
| 4113 | 4122 | { |
| 4114 | 4123 | int drive = (*part & 3) | ((*part & 0x80) >> 5); |
| 4115 | − if (drive >= N_DRIVE || | |
| 4116 | − !(allowed_drive_mask & (1 << drive)) || | |
| 4117 | − fdc_state[FDC(drive)].version == FDC_NONE) | |
| 4124 | + if (drive >= N_DRIVE || !floppy_available(drive)) | |
| 4118 | 4125 | return NULL; |
| 4119 | 4126 | if (((*part >> 2) & 0x1f) >= ARRAY_SIZE(floppy_type)) |
| 4120 | 4127 | return NULL; |
| @@ -4124,8 +4131,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data) · 3 unmodified lines | ||
| 4124 | 4131 | |
| 4125 | 4132 | static int __init do_floppy_init(void) |
| 4126 | 4133 | { |
| 4127 | − int i, unit, drive; | |
| 4128 | − int err, dr; | |
| 4134 | + int i, unit, drive, err; | |
| 4129 | 4135 | |
| 4130 | 4136 | set_debugt(); |
| 4131 | 4137 | interruptjiffies = resultjiffies = jiffies; |
| @@ -4137,34 +4143,32 @@ static int __init do_floppy_init(void) · 5 unmodified lines | ||
| 4137 | 4143 | |
| 4138 | 4144 | raw_cmd = NULL; |
| 4139 | 4145 | |
| 4140 | − for (dr = 0; dr < N_DRIVE; dr++) { | |
| 4141 | − disks[dr] = alloc_disk(1); | |
| 4142 | − if (!disks[dr]) { | |
| 4143 | − err = -ENOMEM; | |
| 4144 | − goto out_put_disk; | |
| 4145 | − } | |
| 4146 | + floppy_wq = alloc_ordered_workqueue("floppy", 0); | |
| 4147 | + if (!floppy_wq) | |
| 4148 | + return -ENOMEM; | |
| 4146 | 4149 | |
| 4147 | − floppy_wq = alloc_ordered_workqueue("floppy", 0); | |
| 4148 | − if (!floppy_wq) { | |
| 4150 | + for (drive = 0; drive < N_DRIVE; drive++) { | |
| 4151 | + disks[drive] = alloc_disk(1); | |
| 4152 | + if (!disks[drive]) { | |
| 4149 | 4153 | err = -ENOMEM; |
| 4150 | 4154 | goto out_put_disk; |
| 4151 | 4155 | } |
| 4152 | 4156 | |
| 4153 | − disks[dr]->queue = blk_init_queue(do_fd_request, &floppy_lock); | |
| 4154 | − if (!disks[dr]->queue) { | |
| 4157 | + disks[drive]->queue = blk_init_queue(do_fd_request, &floppy_lock); | |
| 4158 | + if (!disks[drive]->queue) { | |
| 4155 | 4159 | err = -ENOMEM; |
| 4156 | − goto out_destroy_workq; | |
| 4160 | + goto out_put_disk; | |
| 4157 | 4161 | } |
| 4158 | 4162 | |
| 4159 | − blk_queue_max_hw_sectors(disks[dr]->queue, 64); | |
| 4160 | − disks[dr]->major = FLOPPY_MAJOR; | |
| 4161 | − disks[dr]->first_minor = TOMINOR(dr); | |
| 4162 | − disks[dr]->fops = &floppy_fops; | |
| 4163 | − sprintf(disks[dr]->disk_name, "fd%d", dr); | |
| 4163 | + blk_queue_max_hw_sectors(disks[drive]->queue, 64); | |
| 4164 | + disks[drive]->major = FLOPPY_MAJOR; | |
| 4165 | + disks[drive]->first_minor = TOMINOR(drive); | |
| 4166 | + disks[drive]->fops = &floppy_fops; | |
| 4167 | + sprintf(disks[drive]->disk_name, "fd%d", drive); | |
| 4164 | 4168 | |
| 4165 | − init_timer(&motor_off_timer[dr]); | |
| 4166 | − motor_off_timer[dr].data = dr; | |
| 4167 | − motor_off_timer[dr].function = motor_off_callback; | |
| 4169 | + init_timer(&motor_off_timer[drive]); | |
| 4170 | + motor_off_timer[drive].data = drive; | |
| 4171 | + motor_off_timer[drive].function = motor_off_callback; | |
| 4168 | 4172 | } |
| 4169 | 4173 | |
| 4170 | 4174 | err = register_blkdev(FLOPPY_MAJOR, "fd"); |
| @@ -4282,9 +4286,7 @@ static int __init do_floppy_init(void) · 111 unmodified lines | ||
| 4282 | 4286 | } |
| 4283 | 4287 | |
| 4284 | 4288 | for (drive = 0; drive < N_DRIVE; drive++) { |
| 4285 | − if (!(allowed_drive_mask & (1 << drive))) | |
| 4286 | − continue; | |
| 4287 | − if (fdc_state[FDC(drive)].version == FDC_NONE) | |
| 4289 | + if (!floppy_available(drive)) | |
| 4288 | 4290 | continue; |
| 4289 | 4291 | |
| 4290 | 4292 | floppy_device[drive].name = floppy_device_name; |
| @@ -4293,7 +4295,7 @@ static int __init do_floppy_init(void) · 2 unmodified lines | ||
| 4293 | 4295 | |
| 4294 | 4296 | err = platform_device_register(&floppy_device[drive]); |
| 4295 | 4297 | if (err) |
| 4296 | − goto out_release_dma; | |
| 4298 | + goto out_remove_drives; | |
| 4297 | 4299 | |
| 4298 | 4300 | err = device_create_file(&floppy_device[drive].dev, |
| 4299 | 4301 | &dev_attr_cmos); |
| @@ -4311,28 +4313,33 @@ static int __init do_floppy_init(void) · 11 unmodified lines | ||
| 4311 | 4313 | |
| 4312 | 4314 | out_unreg_platform_dev: |
| 4313 | 4315 | platform_device_unregister(&floppy_device[drive]); |
| 4316 | +out_remove_drives: | |
| 4317 | + while (drive--) { | |
| 4318 | + if (floppy_available(drive)) { | |
| 4319 | + del_gendisk(disks[drive]); | |
| 4320 | + device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos); | |
| 4321 | + platform_device_unregister(&floppy_device[drive]); | |
| 4322 | + } | |
| 4323 | + } | |
| 4314 | 4324 | out_release_dma: |
| 4315 | 4325 | if (atomic_read(&usage_count)) |
| 4316 | 4326 | floppy_release_irq_and_dma(); |
| 4317 | 4327 | out_unreg_region: |
| 4318 | 4328 | blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); |
| 4319 | 4329 | platform_driver_unregister(&floppy_driver); |
| 4320 | −out_destroy_workq: | |
| 4321 | − destroy_workqueue(floppy_wq); | |
| 4322 | 4330 | out_unreg_blkdev: |
| 4323 | 4331 | unregister_blkdev(FLOPPY_MAJOR, "fd"); |
| 4324 | 4332 | out_put_disk: |
| 4325 | − while (dr--) { | |
| 4326 | − del_timer_sync(&motor_off_timer[dr]); | |
| 4327 | − if (disks[dr]->queue) { | |
| 4328 | − blk_cleanup_queue(disks[dr]->queue); | |
| 4329 | − /* | |
| 4330 | − * put_disk() is not paired with add_disk() and | |
| 4331 | − * will put queue reference one extra time. fix it. | |
| 4332 | − */ | |
| 4333 | − disks[dr]->queue = NULL; | |
| 4333 | + destroy_workqueue(floppy_wq); | |
| 4334 | + for (drive = 0; drive < N_DRIVE; drive++) { | |
| 4335 | + if (!disks[drive]) | |
| 4336 | + break; | |
| 4337 | + if (disks[drive]->queue) { | |
| 4338 | + del_timer_sync(&motor_off_timer[drive]); | |
| 4339 | + blk_cleanup_queue(disks[drive]->queue); | |
| 4340 | + disks[drive]->queue = NULL; | |
| 4334 | 4341 | } |
| 4335 | − put_disk(disks[dr]); | |
| 4342 | + put_disk(disks[drive]); | |
| 4336 | 4343 | } |
| 4337 | 4344 | return err; |
| 4338 | 4345 | } |
| @@ -4548,11 +4555,12 @@ static void __exit floppy_module_exit(void) · 209 unmodified lines | ||
| 4548 | 4555 | unregister_blkdev(FLOPPY_MAJOR, "fd"); |
| 4549 | 4556 | platform_driver_unregister(&floppy_driver); |
| 4550 | 4557 | |
| 4558 | + destroy_workqueue(floppy_wq); | |
| 4559 | + | |
| 4551 | 4560 | for (drive = 0; drive < N_DRIVE; drive++) { |
| 4552 | 4561 | del_timer_sync(&motor_off_timer[drive]); |
| 4553 | 4562 | |
| 4554 | − if ((allowed_drive_mask & (1 << drive)) && | |
| 4555 | − fdc_state[FDC(drive)].version != FDC_NONE) { | |
| 4563 | + if (floppy_available(drive)) { | |
| 4556 | 4564 | del_gendisk(disks[drive]); |
| 4557 | 4565 | device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos); |
| 4558 | 4566 | platform_device_unregister(&floppy_device[drive]); |
| @@ -4572,7 +4580,6 @@ static void __exit floppy_module_exit(void) · 13 unmodified lines | ||
| 4572 | 4580 | |
| 4573 | 4581 | cancel_delayed_work_sync(&fd_timeout); |
| 4574 | 4582 | cancel_delayed_work_sync(&fd_timer); |
| 4575 | − destroy_workqueue(floppy_wq); | |
| 4576 | 4583 | |
| 4577 | 4584 | if (atomic_read(&usage_count)) |
| 4578 | 4585 | floppy_release_irq_and_dma(); |
| @@ -976,8 +976,21 @@ static int loop_clr_fd(struct loop_device *lo) · 975 unmodified lines | ||
| 976 | 976 | if (lo->lo_state != Lo_bound) |
| 977 | 977 | return -ENXIO; |
| 978 | 978 | |
| 979 | − if (lo->lo_refcnt > 1) /* we needed one fd for the ioctl */ | |
| 980 | − return -EBUSY; | |
| 979 | + /* | |
| 980 | + * If we've explicitly asked to tear down the loop device, | |
| 981 | + * and it has an elevated reference count, set it for auto-teardown when | |
| 982 | + * the last reference goes away. This stops $!~#$@ udev from | |
| 983 | + * preventing teardown because it decided that it needs to run blkid on | |
| 984 | + * the loopback device whenever they appear. xfstests is notorious for | |
| 985 | + * failing tests because blkid via udev races with a losetup | |
| 986 | + * <dev>/do something like mkfs/losetup -d <dev> causing the losetup -d | |
| 987 | + * command to fail with EBUSY. | |
| 988 | + */ | |
| 989 | + if (lo->lo_refcnt > 1) { | |
| 990 | + lo->lo_flags |= LO_FLAGS_AUTOCLEAR; | |
| 991 | + mutex_unlock(&lo->lo_ctl_mutex); | |
| 992 | + return 0; | |
| 993 | + } | |
| 981 | 994 | |
| 982 | 995 | if (filp == NULL) |
| 983 | 996 | return -EINVAL; |
| @@ -559,7 +559,7 @@ static void mtip_timeout_function(unsigned long int data) · 558 unmodified lines | ||
| 559 | 559 | struct mtip_cmd *command; |
| 560 | 560 | int tag, cmdto_cnt = 0; |
| 561 | 561 | unsigned int bit, group; |
| 562 | − unsigned int num_command_slots = port->dd->slot_groups * 32; | |
| 562 | + unsigned int num_command_slots; | |
| 563 | 563 | unsigned long to, tagaccum[SLOTBITS_IN_LONGS]; |
| 564 | 564 | |
| 565 | 565 | if (unlikely(!port)) |
| @@ -572,6 +572,7 @@ static void mtip_timeout_function(unsigned long int data) · 6 unmodified lines | ||
| 572 | 572 | } |
| 573 | 573 | /* clear the tag accumulator */ |
| 574 | 574 | memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long)); |
| 575 | + num_command_slots = port->dd->slot_groups * 32; | |
| 575 | 576 | |
| 576 | 577 | for (tag = 0; tag < num_command_slots; tag++) { |
| 577 | 578 | /* |
| @@ -2035,8 +2036,9 @@ static unsigned int implicit_sector(unsigned char command, · 1457 unmodified lines | ||
| 2035 | 2036 | } |
| 2036 | 2037 | return rv; |
| 2037 | 2038 | } |
| 2038 | − | |
| 2039 | −static void mtip_set_timeout(struct host_to_dev_fis *fis, unsigned int *timeout) | |
| 2039 | +static void mtip_set_timeout(struct driver_data *dd, | |
| 2040 | + struct host_to_dev_fis *fis, | |
| 2041 | + unsigned int *timeout, u8 erasemode) | |
| 2040 | 2042 | { |
| 2041 | 2043 | switch (fis->command) { |
| 2042 | 2044 | case ATA_CMD_DOWNLOAD_MICRO: |
| @@ -2044,7 +2046,10 @@ static void mtip_set_timeout(struct host_to_dev_fis *fis, unsigned int *timeout) · 1 unmodified line | ||
| 2044 | 2046 | break; |
| 2045 | 2047 | case ATA_CMD_SEC_ERASE_UNIT: |
| 2046 | 2048 | case 0xFC: |
| 2047 | − *timeout = 240000; /* 4 minutes */ | |
| 2049 | + if (erasemode) | |
| 2050 | + *timeout = ((*(dd->port->identify + 90) * 2) * 60000); | |
| 2051 | + else | |
| 2052 | + *timeout = ((*(dd->port->identify + 89) * 2) * 60000); | |
| 2048 | 2053 | break; |
| 2049 | 2054 | case ATA_CMD_STANDBYNOW1: |
| 2050 | 2055 | *timeout = 120000; /* 2 minutes */ |
| @@ -2087,6 +2092,7 @@ static int exec_drive_taskfile(struct driver_data *dd, · 36 unmodified lines | ||
| 2087 | 2092 | unsigned int transfer_size; |
| 2088 | 2093 | unsigned long task_file_data; |
| 2089 | 2094 | int intotal = outtotal + req_task->out_size; |
| 2095 | + int erasemode = 0; | |
| 2090 | 2096 | |
| 2091 | 2097 | taskout = req_task->out_size; |
| 2092 | 2098 | taskin = req_task->in_size; |
| @@ -2212,7 +2218,13 @@ static int exec_drive_taskfile(struct driver_data *dd, · 119 unmodified lines | ||
| 2212 | 2218 | fis.lba_hi, |
| 2213 | 2219 | fis.device); |
| 2214 | 2220 | |
| 2215 | − mtip_set_timeout(&fis, &timeout); | |
| 2221 | + /* check for erase mode support during secure erase.*/ | |
| 2222 | + if ((fis.command == ATA_CMD_SEC_ERASE_UNIT) && outbuf && | |
| 2223 | + (outbuf[0] & MTIP_SEC_ERASE_MODE)) { | |
| 2224 | + erasemode = 1; | |
| 2225 | + } | |
| 2226 | + | |
| 2227 | + mtip_set_timeout(dd, &fis, &timeout, erasemode); | |
| 2216 | 2228 | |
| 2217 | 2229 | /* Determine the correct transfer size.*/ |
| 2218 | 2230 | if (force_single_sector) |
| @@ -2428,7 +2440,7 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd, · 209 unmodified lines | ||
| 2428 | 2440 | * return value |
| 2429 | 2441 | * None |
| 2430 | 2442 | */ |
| 2431 | −static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, | |
| 2443 | +static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector, | |
| 2432 | 2444 | int nsect, int nents, int tag, void *callback, |
| 2433 | 2445 | void *data, int dir) |
| 2434 | 2446 | { |
| @@ -2436,6 +2448,7 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, · 1 unmodified line | ||
| 2436 | 2448 | struct mtip_port *port = dd->port; |
| 2437 | 2449 | struct mtip_cmd *command = &port->commands[tag]; |
| 2438 | 2450 | int dma_dir = (dir == READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; |
| 2451 | + u64 start = sector; | |
| 2439 | 2452 | |
| 2440 | 2453 | /* Map the scatter list for DMA access */ |
| 2441 | 2454 | nents = dma_map_sg(&dd->pdev->dev, command->sg, nents, dma_dir); |
| @@ -2454,8 +2467,12 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, · 12 unmodified lines | ||
| 2454 | 2467 | fis->opts = 1 << 7; |
| 2455 | 2468 | fis->command = |
| 2456 | 2469 | (dir == READ ? ATA_CMD_FPDMA_READ : ATA_CMD_FPDMA_WRITE); |
| 2457 | − *((unsigned int *) &fis->lba_low) = (start & 0xFFFFFF); | |
| 2458 | − *((unsigned int *) &fis->lba_low_ex) = ((start >> 24) & 0xFFFFFF); | |
| 2470 | + fis->lba_low = start & 0xFF; | |
| 2471 | + fis->lba_mid = (start >> 8) & 0xFF; | |
| 2472 | + fis->lba_hi = (start >> 16) & 0xFF; | |
| 2473 | + fis->lba_low_ex = (start >> 24) & 0xFF; | |
| 2474 | + fis->lba_mid_ex = (start >> 32) & 0xFF; | |
| 2475 | + fis->lba_hi_ex = (start >> 40) & 0xFF; | |
| 2459 | 2476 | fis->device = 1 << 6; |
| 2460 | 2477 | fis->features = nsect & 0xFF; |
| 2461 | 2478 | fis->features_ex = (nsect >> 8) & 0xFF; |
| @@ -33,6 +33,9 @@ · 32 unmodified lines | ||
| 33 | 33 | /* offset of Device Control register in PCIe extended capabilites space */ |
| 34 | 34 | #define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET 0x48 |
| 35 | 35 | |
| 36 | +/* check for erase mode support during secure erase */ | |
| 37 | +#define MTIP_SEC_ERASE_MODE 0x2 | |
| 38 | + | |
| 36 | 39 | /* # of times to retry timed out/failed IOs */ |
| 37 | 40 | #define MTIP_MAX_RETRIES 2 |
| 38 | 41 | |
| @@ -152,14 +155,14 @@ enum { · 113 unmodified lines | ||
| 152 | 155 | MTIP_DDF_REBUILD_FAILED_BIT = 8, |
| 153 | 156 | }; |
| 154 | 157 | |
| 155 | −__packed struct smart_attr{ | |
| 158 | +struct smart_attr { | |
| 156 | 159 | u8 attr_id; |
| 157 | 160 | u16 flags; |
| 158 | 161 | u8 cur; |
| 159 | 162 | u8 worst; |
| 160 | 163 | u32 data; |
| 161 | 164 | u8 res[3]; |
| 162 | −}; | |
| 165 | +} __packed; | |
| 163 | 166 | |
| 164 | 167 | /* Register Frame Information Structure (FIS), host to device. */ |
| 165 | 168 | struct host_to_dev_fis { |
| @@ -158,8 +158,8 @@ struct xen_vbd { · 157 unmodified lines | ||
| 158 | 158 | struct block_device *bdev; |
| 159 | 159 | /* Cached size parameter. */ |
| 160 | 160 | sector_t size; |
| 161 | − bool flush_support; | |
| 162 | − bool discard_secure; | |
| 161 | + unsigned int flush_support:1; | |
| 162 | + unsigned int discard_secure:1; | |
| 163 | 163 | }; |
| 164 | 164 | |
| 165 | 165 | struct backend_info; |
| @@ -105,11 +105,10 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid) · 104 unmodified lines | ||
| 105 | 105 | { |
| 106 | 106 | struct xen_blkif *blkif; |
| 107 | 107 | |
| 108 | − blkif = kmem_cache_alloc(xen_blkif_cachep, GFP_KERNEL); | |
| 108 | + blkif = kmem_cache_zalloc(xen_blkif_cachep, GFP_KERNEL); | |
| 109 | 109 | if (!blkif) |
| 110 | 110 | return ERR_PTR(-ENOMEM); |
| 111 | 111 | |
| 112 | − memset(blkif, 0, sizeof(*blkif)); | |
| 113 | 112 | blkif->domid = domid; |
| 114 | 113 | spin_lock_init(&blkif->blk_ring_lock); |
| 115 | 114 | atomic_set(&blkif->refcnt, 1); |
| @@ -196,7 +195,7 @@ static void xen_blkif_disconnect(struct xen_blkif *blkif) · 80 unmodified lines | ||
| 196 | 195 | } |
| 197 | 196 | } |
| 198 | 197 | |
| 199 | −void xen_blkif_free(struct xen_blkif *blkif) | |
| 198 | +static void xen_blkif_free(struct xen_blkif *blkif) | |
| 200 | 199 | { |
| 201 | 200 | if (!atomic_dec_and_test(&blkif->refcnt)) |
| 202 | 201 | BUG(); |
| @@ -257,7 +256,7 @@ static struct attribute_group xen_vbdstat_group = { · 54 unmodified lines | ||
| 257 | 256 | VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor); |
| 258 | 257 | VBD_SHOW(mode, "%s\n", be->mode); |
| 259 | 258 | |
| 260 | −int xenvbd_sysfs_addif(struct xenbus_device *dev) | |
| 259 | +static int xenvbd_sysfs_addif(struct xenbus_device *dev) | |
| 261 | 260 | { |
| 262 | 261 | int error; |
| 263 | 262 | |
| @@ -281,7 +280,7 @@ fail1: device_remove_file(&dev->dev, &dev_attr_physical_device); · 17 unmodified lines | ||
| 281 | 280 | return error; |
| 282 | 281 | } |
| 283 | 282 | |
| 284 | −void xenvbd_sysfs_delif(struct xenbus_device *dev) | |
| 283 | +static void xenvbd_sysfs_delif(struct xenbus_device *dev) | |
| 285 | 284 | { |
| 286 | 285 | sysfs_remove_group(&dev->dev.kobj, &xen_vbdstat_group); |
| 287 | 286 | device_remove_file(&dev->dev, &dev_attr_mode); |
| @@ -67,6 +67,7 @@ static struct usb_device_id ath3k_table[] = { · 66 unmodified lines | ||
| 67 | 67 | { USB_DEVICE(0x13d3, 0x3304) }, |
| 68 | 68 | { USB_DEVICE(0x0930, 0x0215) }, |
| 69 | 69 | { USB_DEVICE(0x0489, 0xE03D) }, |
| 70 | + { USB_DEVICE(0x0489, 0xE027) }, | |
| 70 | 71 | |
| 71 | 72 | /* Atheros AR9285 Malbec with sflash firmware */ |
| 72 | 73 | { USB_DEVICE(0x03F0, 0x311D) }, |
| @@ -124,6 +124,7 @@ static struct usb_device_id blacklist_table[] = { · 123 unmodified lines | ||
| 124 | 124 | { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, |
| 125 | 125 | { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, |
| 126 | 126 | { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE }, |
| 127 | + { USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE }, | |
| 127 | 128 | |
| 128 | 129 | /* Atheros AR9285 Malbec with sflash firmware */ |
| 129 | 130 | { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, |
| @@ -22,6 +22,26 @@ · 21 unmodified lines | ||
| 22 | 22 | #include <linux/pm_runtime.h> |
| 23 | 23 | #include <linux/of.h> |
| 24 | 24 | #include <linux/of_platform.h> |
| 25 | +#include <linux/platform_data/omap_ocp2scp.h> | |
| 26 | + | |
| 27 | +/** | |
| 28 | + * _count_resources - count for the number of resources | |
| 29 | + * @res: struct resource * | |
| 30 | + * | |
| 31 | + * Count and return the number of resources populated for the device that is | |
| 32 | + * connected to ocp2scp. | |
| 33 | + */ | |
| 34 | +static unsigned _count_resources(struct resource *res) | |
| 35 | +{ | |
| 36 | + int cnt = 0; | |
| 37 | + | |
| 38 | + while (res->start != res->end) { | |
| 39 | + cnt++; | |
| 40 | + res++; | |
| 41 | + } | |
| 42 | + | |
| 43 | + return cnt; | |
| 44 | +} | |
| 25 | 45 | |
| 26 | 46 | static int ocp2scp_remove_devices(struct device *dev, void *c) |
| 27 | 47 | { |
| @@ -34,20 +54,62 @@ static int ocp2scp_remove_devices(struct device *dev, void *c) · 6 unmodified lines | ||
| 34 | 54 | |
| 35 | 55 | static int __devinit omap_ocp2scp_probe(struct platform_device *pdev) |
| 36 | 56 | { |
| 37 | − int ret; | |
| 38 | − struct device_node *np = pdev->dev.of_node; | |
| 57 | + int ret; | |
| 58 | + unsigned res_cnt, i; | |
| 59 | + struct device_node *np = pdev->dev.of_node; | |
| 60 | + struct platform_device *pdev_child; | |
| 61 | + struct omap_ocp2scp_platform_data *pdata = pdev->dev.platform_data; | |
| 62 | + struct omap_ocp2scp_dev *dev; | |
| 39 | 63 | |
| 40 | 64 | if (np) { |
| 41 | 65 | ret = of_platform_populate(np, NULL, NULL, &pdev->dev); |
| 42 | 66 | if (ret) { |
| 43 | − dev_err(&pdev->dev, "failed to add resources for ocp2scp child\n"); | |
| 67 | + dev_err(&pdev->dev, | |
| 68 | + "failed to add resources for ocp2scp child\n"); | |
| 44 | 69 | goto err0; |
| 45 | 70 | } |
| 71 | + } else if (pdata) { | |
| 72 | + for (i = 0, dev = *pdata->devices; i < pdata->dev_cnt; i++, | |
| 73 | + dev++) { | |
| 74 | + res_cnt = _count_resources(dev->res); | |
| 75 | + | |
| 76 | + pdev_child = platform_device_alloc(dev->drv_name, | |
| 77 | + PLATFORM_DEVID_AUTO); | |
| 78 | + if (!pdev_child) { | |
| 79 | + dev_err(&pdev->dev, | |
| 80 | + "failed to allocate mem for ocp2scp child\n"); | |
| 81 | + goto err0; | |
| 82 | + } | |
| 83 | + | |
| 84 | + ret = platform_device_add_resources(pdev_child, | |
| 85 | + dev->res, res_cnt); | |
| 86 | + if (ret) { | |
| 87 | + dev_err(&pdev->dev, | |
| 88 | + "failed to add resources for ocp2scp child\n"); | |
| 89 | + goto err1; | |
| 90 | + } | |
| 91 | + | |
| 92 | + pdev_child->dev.parent = &pdev->dev; | |
| 93 | + | |
| 94 | + ret = platform_device_add(pdev_child); | |
| 95 | + if (ret) { | |
| 96 | + dev_err(&pdev->dev, | |
| 97 | + "failed to register ocp2scp child device\n"); | |
| 98 | + goto err1; | |
| 99 | + } | |
| 100 | + } | |
| 101 | + } else { | |
| 102 | + dev_err(&pdev->dev, "OCP2SCP initialized without plat data\n"); | |
| 103 | + return -EINVAL; | |
| 46 | 104 | } |
| 105 | + | |
| 47 | 106 | pm_runtime_enable(&pdev->dev); |
| 48 | 107 | |
| 49 | 108 | return 0; |
| 50 | 109 | |
| 110 | +err1: | |
| 111 | + platform_device_put(pdev_child); | |
| 112 | + | |
| 51 | 113 | err0: |
| 52 | 114 | device_for_each_child(&pdev->dev, NULL, ocp2scp_remove_devices); |
| 53 | 115 | |
| @@ -127,12 +127,12 @@ config HW_RANDOM_VIA · 126 unmodified lines | ||
| 127 | 127 | If unsure, say Y. |
| 128 | 128 | |
| 129 | 129 | config HW_RANDOM_IXP4XX |
| 130 | − tristate "Intel IXP4xx NPU HW Random Number Generator support" | |
| 130 | + tristate "Intel IXP4xx NPU HW Pseudo-Random Number Generator support" | |
| 131 | 131 | depends on HW_RANDOM && ARCH_IXP4XX |
| 132 | 132 | default HW_RANDOM |
| 133 | 133 | ---help--- |
| 134 | − This driver provides kernel-side support for the Random | |
| 135 | − Number Generator hardware found on the Intel IXP4xx NPU. | |
| 134 | + This driver provides kernel-side support for the Pseudo-Random | |
| 135 | + Number Generator hardware found on the Intel IXP45x/46x NPU. | |
| 136 | 136 | |
| 137 | 137 | To compile this driver as a module, choose M here: the |
| 138 | 138 | module will be called ixp4xx-rng. |
| @@ -45,6 +45,9 @@ static int __init ixp4xx_rng_init(void) · 44 unmodified lines | ||
| 45 | 45 | void __iomem * rng_base; |
| 46 | 46 | int err; |
| 47 | 47 | |
| 48 | + if (!cpu_is_ixp46x()) /* includes IXP455 */ | |
| 49 | + return -ENOSYS; | |
| 50 | + | |
| 48 | 51 | rng_base = ioremap(0x70002100, 4); |
| 49 | 52 | if (!rng_base) |
| 50 | 53 | return -ENOMEM; |
| @@ -68,5 +71,5 @@ module_init(ixp4xx_rng_init); · 17 unmodified lines | ||
| 68 | 71 | module_exit(ixp4xx_rng_exit); |
| 69 | 72 | |
| 70 | 73 | MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>"); |
| 71 | −MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver for IXP4xx"); | |
| 74 | +MODULE_DESCRIPTION("H/W Pseudo-Random Number Generator (RNG) driver for IXP45x/46x"); | |
| 72 | 75 | MODULE_LICENSE("GPL"); |
| @@ -285,7 +285,7 @@ static long raw_ctl_compat_ioctl(struct file *file, unsigned int cmd, · 284 unmodified lines | ||
| 285 | 285 | |
| 286 | 286 | static const struct file_operations raw_fops = { |
| 287 | 287 | .read = do_sync_read, |
| 288 | − .aio_read = blkdev_aio_read, | |
| 288 | + .aio_read = generic_file_aio_read, | |
| 289 | 289 | .write = do_sync_write, |
| 290 | 290 | .aio_write = blkdev_aio_write, |
| 291 | 291 | .fsync = blkdev_fsync, |
| @@ -1456,7 +1456,7 @@ static int __devexit sonypi_remove(struct platform_device *dev) · 1455 unmodified lines | ||
| 1456 | 1456 | return 0; |
| 1457 | 1457 | } |
| 1458 | 1458 | |
| 1459 | −#ifdef CONFIG_PM | |
| 1459 | +#ifdef CONFIG_PM_SLEEP | |
| 1460 | 1460 | static int old_camera_power; |
| 1461 | 1461 | |
| 1462 | 1462 | static int sonypi_suspend(struct device *dev) |
| @@ -40,7 +40,7 @@ void u8500_clk_init(void) · 39 unmodified lines | ||
| 40 | 40 | CLK_IS_ROOT|CLK_IGNORE_UNUSED, |
| 41 | 41 | 32768); |
| 42 | 42 | clk_register_clkdev(clk, "clk32k", NULL); |
| 43 | − clk_register_clkdev(clk, NULL, "rtc-pl031"); | |
| 43 | + clk_register_clkdev(clk, "apb_pclk", "rtc-pl031"); | |
| 44 | 44 | |
| 45 | 45 | /* PRCMU clocks */ |
| 46 | 46 | fw_version = prcmu_get_fw_version(); |
| @@ -228,10 +228,17 @@ void u8500_clk_init(void) · 181 unmodified lines | ||
| 228 | 228 | |
| 229 | 229 | clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", U8500_CLKRST1_BASE, |
| 230 | 230 | BIT(2), 0); |
| 231 | + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.1"); | |
| 232 | + | |
| 231 | 233 | clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", U8500_CLKRST1_BASE, |
| 232 | 234 | BIT(3), 0); |
| 235 | + clk_register_clkdev(clk, "apb_pclk", "msp0"); | |
| 236 | + clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.0"); | |
| 237 | + | |
| 233 | 238 | clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", U8500_CLKRST1_BASE, |
| 234 | 239 | BIT(4), 0); |
| 240 | + clk_register_clkdev(clk, "apb_pclk", "msp1"); | |
| 241 | + clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.1"); | |
| 235 | 242 | |
| 236 | 243 | clk = clk_reg_prcc_pclk("p1_pclk5", "per1clk", U8500_CLKRST1_BASE, |
| 237 | 244 | BIT(5), 0); |
| @@ -239,6 +246,7 @@ void u8500_clk_init(void) · 1 unmodified line | ||
| 239 | 246 | |
| 240 | 247 | clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", U8500_CLKRST1_BASE, |
| 241 | 248 | BIT(6), 0); |
| 249 | + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.2"); | |
| 242 | 250 | |
| 243 | 251 | clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", U8500_CLKRST1_BASE, |
| 244 | 252 | BIT(7), 0); |
| @@ -246,6 +254,7 @@ void u8500_clk_init(void) · 1 unmodified line | ||
| 246 | 254 | |
| 247 | 255 | clk = clk_reg_prcc_pclk("p1_pclk8", "per1clk", U8500_CLKRST1_BASE, |
| 248 | 256 | BIT(8), 0); |
| 257 | + clk_register_clkdev(clk, "apb_pclk", "slimbus0"); | |
| 249 | 258 | |
| 250 | 259 | clk = clk_reg_prcc_pclk("p1_pclk9", "per1clk", U8500_CLKRST1_BASE, |
| 251 | 260 | BIT(9), 0); |
| @@ -255,11 +264,16 @@ void u8500_clk_init(void) · 3 unmodified lines | ||
| 255 | 264 | |
| 256 | 265 | clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", U8500_CLKRST1_BASE, |
| 257 | 266 | BIT(10), 0); |
| 267 | + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.4"); | |
| 268 | + | |
| 258 | 269 | clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", U8500_CLKRST1_BASE, |
| 259 | 270 | BIT(11), 0); |
| 271 | + clk_register_clkdev(clk, "apb_pclk", "msp3"); | |
| 272 | + clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.3"); | |
| 260 | 273 | |
| 261 | 274 | clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", U8500_CLKRST2_BASE, |
| 262 | 275 | BIT(0), 0); |
| 276 | + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.3"); | |
| 263 | 277 | |
| 264 | 278 | clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", U8500_CLKRST2_BASE, |
| 265 | 279 | BIT(1), 0); |
| @@ -279,12 +293,13 @@ void u8500_clk_init(void) · 13 unmodified lines | ||
| 279 | 293 | |
| 280 | 294 | clk = clk_reg_prcc_pclk("p2_pclk5", "per2clk", U8500_CLKRST2_BASE, |
| 281 | 295 | BIT(5), 0); |
| 296 | + clk_register_clkdev(clk, "apb_pclk", "msp2"); | |
| 297 | + clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.2"); | |
| 282 | 298 | |
| 283 | 299 | clk = clk_reg_prcc_pclk("p2_pclk6", "per2clk", U8500_CLKRST2_BASE, |
| 284 | 300 | BIT(6), 0); |
| 285 | 301 | clk_register_clkdev(clk, "apb_pclk", "sdi1"); |
| 286 | 302 | |
| 287 | − | |
| 288 | 303 | clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", U8500_CLKRST2_BASE, |
| 289 | 304 | BIT(7), 0); |
| 290 | 305 | clk_register_clkdev(clk, "apb_pclk", "sdi3"); |
| @@ -316,10 +331,15 @@ void u8500_clk_init(void) · 25 unmodified lines | ||
| 316 | 331 | |
| 317 | 332 | clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", U8500_CLKRST3_BASE, |
| 318 | 333 | BIT(1), 0); |
| 334 | + clk_register_clkdev(clk, "apb_pclk", "ssp0"); | |
| 335 | + | |
| 319 | 336 | clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", U8500_CLKRST3_BASE, |
| 320 | 337 | BIT(2), 0); |
| 338 | + clk_register_clkdev(clk, "apb_pclk", "ssp1"); | |
| 339 | + | |
| 321 | 340 | clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", U8500_CLKRST3_BASE, |
| 322 | 341 | BIT(3), 0); |
| 342 | + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.0"); | |
| 323 | 343 | |
| 324 | 344 | clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", U8500_CLKRST3_BASE, |
| 325 | 345 | BIT(4), 0); |
| @@ -401,10 +421,17 @@ void u8500_clk_init(void) · 75 unmodified lines | ||
| 401 | 421 | |
| 402 | 422 | clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk", |
| 403 | 423 | U8500_CLKRST1_BASE, BIT(2), CLK_SET_RATE_GATE); |
| 424 | + clk_register_clkdev(clk, NULL, "nmk-i2c.1"); | |
| 425 | + | |
| 404 | 426 | clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk", |
| 405 | 427 | U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); |
| 428 | + clk_register_clkdev(clk, NULL, "msp0"); | |
| 429 | + clk_register_clkdev(clk, NULL, "ux500-msp-i2s.0"); | |
| 430 | + | |
| 406 | 431 | clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk", |
| 407 | 432 | U8500_CLKRST1_BASE, BIT(4), CLK_SET_RATE_GATE); |
| 433 | + clk_register_clkdev(clk, NULL, "msp1"); | |
| 434 | + clk_register_clkdev(clk, NULL, "ux500-msp-i2s.1"); | |
| 408 | 435 | |
| 409 | 436 | clk = clk_reg_prcc_kclk("p1_sdi0_kclk", "sdmmcclk", |
| 410 | 437 | U8500_CLKRST1_BASE, BIT(5), CLK_SET_RATE_GATE); |
| @@ -412,17 +439,25 @@ void u8500_clk_init(void) · 1 unmodified line | ||
| 412 | 439 | |
| 413 | 440 | clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk", |
| 414 | 441 | U8500_CLKRST1_BASE, BIT(6), CLK_SET_RATE_GATE); |
| 442 | + clk_register_clkdev(clk, NULL, "nmk-i2c.2"); | |
| 443 | + | |
| 415 | 444 | clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk", |
| 416 | − U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); | |
| 417 | − /* FIXME: Redefinition of BIT(3). */ | |
| 445 | + U8500_CLKRST1_BASE, BIT(8), CLK_SET_RATE_GATE); | |
| 446 | + clk_register_clkdev(clk, NULL, "slimbus0"); | |
| 447 | + | |
| 418 | 448 | clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk", |
| 419 | 449 | U8500_CLKRST1_BASE, BIT(9), CLK_SET_RATE_GATE); |
| 450 | + clk_register_clkdev(clk, NULL, "nmk-i2c.4"); | |
| 451 | + | |
| 420 | 452 | clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk", |
| 421 | 453 | U8500_CLKRST1_BASE, BIT(10), CLK_SET_RATE_GATE); |
| 454 | + clk_register_clkdev(clk, NULL, "msp3"); | |
| 455 | + clk_register_clkdev(clk, NULL, "ux500-msp-i2s.3"); | |
| 422 | 456 | |
| 423 | 457 | /* Periph2 */ |
| 424 | 458 | clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk", |
| 425 | 459 | U8500_CLKRST2_BASE, BIT(0), CLK_SET_RATE_GATE); |
| 460 | + clk_register_clkdev(clk, NULL, "nmk-i2c.3"); | |
| 426 | 461 | |
| 427 | 462 | clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmcclk", |
| 428 | 463 | U8500_CLKRST2_BASE, BIT(2), CLK_SET_RATE_GATE); |
| @@ -430,6 +465,8 @@ void u8500_clk_init(void) · 1 unmodified line | ||
| 430 | 465 | |
| 431 | 466 | clk = clk_reg_prcc_kclk("p2_msp2_kclk", "msp02clk", |
| 432 | 467 | U8500_CLKRST2_BASE, BIT(3), CLK_SET_RATE_GATE); |
| 468 | + clk_register_clkdev(clk, NULL, "msp2"); | |
| 469 | + clk_register_clkdev(clk, NULL, "ux500-msp-i2s.2"); | |
| 433 | 470 | |
| 434 | 471 | clk = clk_reg_prcc_kclk("p2_sdi1_kclk", "sdmmcclk", |
| 435 | 472 | U8500_CLKRST2_BASE, BIT(4), CLK_SET_RATE_GATE); |
| @@ -450,10 +487,15 @@ void u8500_clk_init(void) · 14 unmodified lines | ||
| 450 | 487 | /* Periph3 */ |
| 451 | 488 | clk = clk_reg_prcc_kclk("p3_ssp0_kclk", "sspclk", |
| 452 | 489 | U8500_CLKRST3_BASE, BIT(1), CLK_SET_RATE_GATE); |
| 490 | + clk_register_clkdev(clk, NULL, "ssp0"); | |
| 491 | + | |
| 453 | 492 | clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk", |
| 454 | 493 | U8500_CLKRST3_BASE, BIT(2), CLK_SET_RATE_GATE); |
| 494 | + clk_register_clkdev(clk, NULL, "ssp1"); | |
| 495 | + | |
| 455 | 496 | clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk", |
| 456 | 497 | U8500_CLKRST3_BASE, BIT(3), CLK_SET_RATE_GATE); |
| 498 | + clk_register_clkdev(clk, NULL, "nmk-i2c.0"); | |
| 457 | 499 | |
| 458 | 500 | clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmcclk", |
| 459 | 501 | U8500_CLKRST3_BASE, BIT(4), CLK_SET_RATE_GATE); |
| @@ -328,6 +328,7 @@ static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb, · 327 unmodified lines | ||
| 328 | 328 | cpufreq_update_policy(cpu); |
| 329 | 329 | break; |
| 330 | 330 | case CPU_DOWN_PREPARE: |
| 331 | + case CPU_DOWN_PREPARE_FROZEN: | |
| 331 | 332 | cpufreq_stats_free_sysfs(cpu); |
| 332 | 333 | break; |
| 333 | 334 | case CPU_DEAD: |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | * http://www.gnu.org/licenses/gpl.html |
| 6 | 6 | * |
| 7 | 7 | * Maintainer: |
| 8 | − * Andreas Herrmann <andreas.herrmann3@amd.com> | |
| 8 | + * Andreas Herrmann <herrmann.der.user@googlemail.com> | |
| 9 | 9 | * |
| 10 | 10 | * Based on the powernow-k7.c module written by Dave Jones. |
| 11 | 11 | * (C) 2003 Dave Jones on behalf of SuSE Labs |
| @@ -1052,14 +1052,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, · 1040 unmodified lines | ||
| 1052 | 1052 | struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq, |
| 1053 | 1053 | .relation = relation }; |
| 1054 | 1054 | |
| 1055 | − /* | |
| 1056 | − * Must run on @pol->cpu. cpufreq core is responsible for ensuring | |
| 1057 | − * that we're bound to the current CPU and pol->cpu stays online. | |
| 1058 | − */ | |
| 1059 | − if (smp_processor_id() == pol->cpu) | |
| 1060 | − return powernowk8_target_fn(&pta); | |
| 1061 | − else | |
| 1062 | − return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta); | |
| 1055 | + return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta); | |
| 1063 | 1056 | } |
| 1064 | 1057 | |
| 1065 | 1058 | /* Driver entry point to verify the policy and range of frequencies */ |
| @@ -224,7 +224,7 @@ config CRYPTO_DEV_TALITOS · 223 unmodified lines | ||
| 224 | 224 | |
| 225 | 225 | config CRYPTO_DEV_IXP4XX |
| 226 | 226 | tristate "Driver for IXP4xx crypto hardware acceleration" |
| 227 | − depends on ARCH_IXP4XX | |
| 227 | + depends on ARCH_IXP4XX && IXP4XX_QMGR && IXP4XX_NPE | |
| 228 | 228 | select CRYPTO_DES |
| 229 | 229 | select CRYPTO_ALGAPI |
| 230 | 230 | select CRYPTO_AUTHENC |
| @@ -750,12 +750,12 @@ static int setup_cipher(struct crypto_tfm *tfm, int encrypt, · 749 unmodified lines | ||
| 750 | 750 | } |
| 751 | 751 | if (cipher_cfg & MOD_AES) { |
| 752 | 752 | switch (key_len) { |
| 753 | − case 16: keylen_cfg = MOD_AES128 | KEYLEN_128; break; | |
| 754 | − case 24: keylen_cfg = MOD_AES192 | KEYLEN_192; break; | |
| 755 | − case 32: keylen_cfg = MOD_AES256 | KEYLEN_256; break; | |
| 756 | − default: | |
| 757 | − *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | |
| 758 | − return -EINVAL; | |
| 753 | + case 16: keylen_cfg = MOD_AES128; break; | |
| 754 | + case 24: keylen_cfg = MOD_AES192; break; | |
| 755 | + case 32: keylen_cfg = MOD_AES256; break; | |
| 756 | + default: | |
| 757 | + *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | |
| 758 | + return -EINVAL; | |
| 759 | 759 | } |
| 760 | 760 | cipher_cfg |= keylen_cfg; |
| 761 | 761 | } else if (cipher_cfg & MOD_3DES) { |
| @@ -90,6 +90,17 @@ config DW_DMAC · 89 unmodified lines | ||
| 90 | 90 | Support the Synopsys DesignWare AHB DMA controller. This |
| 91 | 91 | can be integrated in chips such as the Atmel AT32ap7000. |
| 92 | 92 | |
| 93 | +config DW_DMAC_BIG_ENDIAN_IO | |
| 94 | + bool "Use big endian I/O register access" | |
| 95 | + default y if AVR32 | |
| 96 | + depends on DW_DMAC | |
| 97 | + help | |
| 98 | + Say yes here to use big endian I/O access when reading and writing | |
| 99 | + to the DMA controller registers. This is needed on some platforms, | |
| 100 | + like the Atmel AVR32 architecture. | |
| 101 | + | |
| 102 | + If unsure, use the default setting. | |
| 103 | + | |
| 93 | 104 | config AT_HDMAC |
| 94 | 105 | tristate "Atmel AHB DMA support" |
| 95 | 106 | depends on ARCH_AT91 |
| @@ -98,9 +98,17 @@ struct dw_dma_regs { · 97 unmodified lines | ||
| 98 | 98 | u32 DW_PARAMS; |
| 99 | 99 | }; |
| 100 | 100 | |
| 101 | +#ifdef CONFIG_DW_DMAC_BIG_ENDIAN_IO | |
| 102 | +#define dma_readl_native ioread32be | |
| 103 | +#define dma_writel_native iowrite32be | |
| 104 | +#else | |
| 105 | +#define dma_readl_native readl | |
| 106 | +#define dma_writel_native writel | |
| 107 | +#endif | |
| 108 | + | |
| 101 | 109 | /* To access the registers in early stage of probe */ |
| 102 | 110 | #define dma_read_byaddr(addr, name) \ |
| 103 | − readl((addr) + offsetof(struct dw_dma_regs, name)) | |
| 111 | + dma_readl_native((addr) + offsetof(struct dw_dma_regs, name)) | |
| 104 | 112 | |
| 105 | 113 | /* Bitfields in DW_PARAMS */ |
| 106 | 114 | #define DW_PARAMS_NR_CHAN 8 /* number of channels */ |
| @@ -216,9 +224,9 @@ __dwc_regs(struct dw_dma_chan *dwc) · 109 unmodified lines | ||
| 216 | 224 | } |
| 217 | 225 | |
| 218 | 226 | #define channel_readl(dwc, name) \ |
| 219 | − readl(&(__dwc_regs(dwc)->name)) | |
| 227 | + dma_readl_native(&(__dwc_regs(dwc)->name)) | |
| 220 | 228 | #define channel_writel(dwc, name, val) \ |
| 221 | − writel((val), &(__dwc_regs(dwc)->name)) | |
| 229 | + dma_writel_native((val), &(__dwc_regs(dwc)->name)) | |
| 222 | 230 | |
| 223 | 231 | static inline struct dw_dma_chan *to_dw_dma_chan(struct dma_chan *chan) |
| 224 | 232 | { |
| @@ -246,9 +254,9 @@ static inline struct dw_dma_regs __iomem *__dw_regs(struct dw_dma *dw) · 21 unmodified lines | ||
| 246 | 254 | } |
| 247 | 255 | |
| 248 | 256 | #define dma_readl(dw, name) \ |
| 249 | − readl(&(__dw_regs(dw)->name)) | |
| 257 | + dma_readl_native(&(__dw_regs(dw)->name)) | |
| 250 | 258 | #define dma_writel(dw, name, val) \ |
| 251 | − writel((val), &(__dw_regs(dw)->name)) | |
| 259 | + dma_writel_native((val), &(__dw_regs(dw)->name)) | |
| 252 | 260 | |
| 253 | 261 | #define channel_set_bit(dw, reg, mask) \ |
| 254 | 262 | dma_writel(dw, reg, ((mask) << 8) | (mask)) |
| @@ -474,8 +474,10 @@ static int imxdma_xfer_desc(struct imxdma_desc *d) · 473 unmodified lines | ||
| 474 | 474 | slot = i; |
| 475 | 475 | break; |
| 476 | 476 | } |
| 477 | − if (slot < 0) | |
| 477 | + if (slot < 0) { | |
| 478 | + spin_unlock_irqrestore(&imxdma->lock, flags); | |
| 478 | 479 | return -EBUSY; |
| 480 | + } | |
| 479 | 481 | |
| 480 | 482 | imxdma->slots_2d[slot].xsr = d->x; |
| 481 | 483 | imxdma->slots_2d[slot].ysr = d->y; |
| @@ -109,7 +109,7 @@ static void sirfsoc_dma_execute(struct sirfsoc_dma_chan *schan) · 108 unmodified lines | ||
| 109 | 109 | sdesc = list_first_entry(&schan->queued, struct sirfsoc_dma_desc, |
| 110 | 110 | node); |
| 111 | 111 | /* Move the first queued descriptor to active list */ |
| 112 | − list_move_tail(&schan->queued, &schan->active); | |
| 112 | + list_move_tail(&sdesc->node, &schan->active); | |
| 113 | 113 | |
| 114 | 114 | /* Start the DMA transfer */ |
| 115 | 115 | writel_relaxed(sdesc->width, sdma->base + SIRFSOC_DMA_WIDTH_0 + |
| @@ -428,7 +428,7 @@ static struct dma_async_tx_descriptor *sirfsoc_dma_prep_interleaved( · 312 unmodified lines | ||
| 428 | 428 | unsigned long iflags; |
| 429 | 429 | int ret; |
| 430 | 430 | |
| 431 | − if ((xt->dir != DMA_MEM_TO_DEV) || (xt->dir != DMA_DEV_TO_MEM)) { | |
| 431 | + if ((xt->dir != DMA_MEM_TO_DEV) && (xt->dir != DMA_DEV_TO_MEM)) { | |
| 432 | 432 | ret = -EINVAL; |
| 433 | 433 | goto err_dir; |
| 434 | 434 | } |
| @@ -170,8 +170,11 @@ static int __amd64_set_scrub_rate(struct pci_dev *ctl, u32 new_bw, u32 min_rate) · 169 unmodified lines | ||
| 170 | 170 | * memory controller and apply to register. Search for the first |
| 171 | 171 | * bandwidth entry that is greater or equal than the setting requested |
| 172 | 172 | * and program that. If at last entry, turn off DRAM scrubbing. |
| 173 | + * | |
| 174 | + * If no suitable bandwidth is found, turn off DRAM scrubbing entirely | |
| 175 | + * by falling back to the last element in scrubrates[]. | |
| 173 | 176 | */ |
| 174 | − for (i = 0; i < ARRAY_SIZE(scrubrates); i++) { | |
| 177 | + for (i = 0; i < ARRAY_SIZE(scrubrates) - 1; i++) { | |
| 175 | 178 | /* |
| 176 | 179 | * skip scrub rates which aren't recommended |
| 177 | 180 | * (see F10 BKDG, F3x58) |
| @@ -181,12 +184,6 @@ static int __amd64_set_scrub_rate(struct pci_dev *ctl, u32 new_bw, u32 min_rate) · 3 unmodified lines | ||
| 181 | 184 | |
| 182 | 185 | if (scrubrates[i].bandwidth <= new_bw) |
| 183 | 186 | break; |
| 184 | − | |
| 185 | − /* | |
| 186 | − * if no suitable bandwidth found, turn off DRAM scrubbing | |
| 187 | − * entirely by falling back to the last element in the | |
| 188 | − * scrubrates array. | |
| 189 | − */ | |
| 190 | 187 | } |
| 191 | 188 | |
| 192 | 189 | scrubval = scrubrates[i].scrubval; |
| @@ -33,7 +33,7 @@ · 32 unmodified lines | ||
| 33 | 33 | * detection. The mods to Rev F required more family |
| 34 | 34 | * information detection. |
| 35 | 35 | * |
| 36 | − * Changes/Fixes by Borislav Petkov <borislav.petkov@amd.com>: | |
| 36 | + * Changes/Fixes by Borislav Petkov <bp@alien8.de>: | |
| 37 | 37 | * - misc fixes and code cleanups |
| 38 | 38 | * |
| 39 | 39 | * This module is based on the following documents |
| @@ -416,10 +416,18 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num, · 415 unmodified lines | ||
| 416 | 416 | dimm->cschannel = chn; |
| 417 | 417 | |
| 418 | 418 | /* Increment csrow location */ |
| 419 | − row++; | |
| 420 | − if (row == tot_csrows) { | |
| 421 | − row = 0; | |
| 419 | + if (layers[0].is_virt_csrow) { | |
| 422 | 420 | chn++; |
| 421 | + if (chn == tot_channels) { | |
| 422 | + chn = 0; | |
| 423 | + row++; | |
| 424 | + } | |
| 425 | + } else { | |
| 426 | + row++; | |
| 427 | + if (row == tot_csrows) { | |
| 428 | + row = 0; | |
| 429 | + chn++; | |
| 430 | + } | |
| 423 | 431 | } |
| 424 | 432 | |
| 425 | 433 | /* Increment dimm location */ |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | * |
| 6 | 6 | * 2007 (c) MontaVista Software, Inc. |
| 7 | 7 | * 2010 (c) Advanced Micro Devices Inc. |
| 8 | − * Borislav Petkov <borislav.petkov@amd.com> | |
| 8 | + * Borislav Petkov <bp@alien8.de> | |
| 9 | 9 | * |
| 10 | 10 | * This file is licensed under the terms of the GNU General Public |
| 11 | 11 | * License version 2. This program is licensed "as is" without any |
| @@ -197,8 +197,8 @@ static const char *ferr_fat_fbd_name[] = { · 196 unmodified lines | ||
| 197 | 197 | [0] = "Memory Write error on non-redundant retry or " |
| 198 | 198 | "FBD configuration Write error on retry", |
| 199 | 199 | }; |
| 200 | −#define GET_FBD_FAT_IDX(fbderr) (fbderr & (3 << 28)) | |
| 201 | −#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)) | |
| 200 | +#define GET_FBD_FAT_IDX(fbderr) (((fbderr) >> 28) & 3) | |
| 201 | +#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 22)) | |
| 202 | 202 | |
| 203 | 203 | #define FERR_NF_FBD 0xa0 |
| 204 | 204 | static const char *ferr_nf_fbd_name[] = { |
| @@ -225,7 +225,7 @@ static const char *ferr_nf_fbd_name[] = { · 20 unmodified lines | ||
| 225 | 225 | [1] = "Aliased Uncorrectable Non-Mirrored Demand Data ECC", |
| 226 | 226 | [0] = "Uncorrectable Data ECC on Replay", |
| 227 | 227 | }; |
| 228 | −#define GET_FBD_NF_IDX(fbderr) (fbderr & (3 << 28)) | |
| 228 | +#define GET_FBD_NF_IDX(fbderr) (((fbderr) >> 28) & 3) | |
| 229 | 229 | #define FERR_NF_FBD_ERR_MASK ((1 << 24) | (1 << 23) | (1 << 22) | (1 << 21) |\ |
| 230 | 230 | (1 << 18) | (1 << 17) | (1 << 16) | (1 << 15) |\ |
| 231 | 231 | (1 << 14) | (1 << 13) | (1 << 11) | (1 << 10) |\ |
| @@ -464,7 +464,7 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci) · 232 unmodified lines | ||
| 464 | 464 | errnum = find_first_bit(&errors, |
| 465 | 465 | ARRAY_SIZE(ferr_nf_fbd_name)); |
| 466 | 466 | specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum); |
| 467 | − branch = (GET_FBD_FAT_IDX(error_reg) == 2) ? 1 : 0; | |
| 467 | + branch = (GET_FBD_NF_IDX(error_reg) == 2) ? 1 : 0; | |
| 468 | 468 | |
| 469 | 469 | pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, |
| 470 | 470 | REDMEMA, &syndrome); |
| @@ -816,7 +816,7 @@ static ssize_t i7core_inject_store_##param( \ · 815 unmodified lines | ||
| 816 | 816 | struct device_attribute *mattr, \ |
| 817 | 817 | const char *data, size_t count) \ |
| 818 | 818 | { \ |
| 819 | − struct mem_ctl_info *mci = to_mci(dev); \ | |
| 819 | + struct mem_ctl_info *mci = dev_get_drvdata(dev); \ | |
| 820 | 820 | struct i7core_pvt *pvt; \ |
| 821 | 821 | long value; \ |
| 822 | 822 | int rc; \ |
| @@ -845,7 +845,7 @@ static ssize_t i7core_inject_show_##param( \ · 22 unmodified lines | ||
| 845 | 845 | struct device_attribute *mattr, \ |
| 846 | 846 | char *data) \ |
| 847 | 847 | { \ |
| 848 | − struct mem_ctl_info *mci = to_mci(dev); \ | |
| 848 | + struct mem_ctl_info *mci = dev_get_drvdata(dev); \ | |
| 849 | 849 | struct i7core_pvt *pvt; \ |
| 850 | 850 | \ |
| 851 | 851 | pvt = mci->pvt_info; \ |
| @@ -1052,7 +1052,7 @@ static ssize_t i7core_show_counter_##param( \ · 200 unmodified lines | ||
| 1052 | 1052 | struct device_attribute *mattr, \ |
| 1053 | 1053 | char *data) \ |
| 1054 | 1054 | { \ |
| 1055 | − struct mem_ctl_info *mci = to_mci(dev); \ | |
| 1055 | + struct mem_ctl_info *mci = dev_get_drvdata(dev); \ | |
| 1056 | 1056 | struct i7core_pvt *pvt = mci->pvt_info; \ |
| 1057 | 1057 | \ |
| 1058 | 1058 | edac_dbg(1, "\n"); \ |
| @@ -370,10 +370,6 @@ static enum dev_type i82975x_dram_type(void __iomem *mch_window, int rank) · 369 unmodified lines | ||
| 370 | 370 | static void i82975x_init_csrows(struct mem_ctl_info *mci, |
| 371 | 371 | struct pci_dev *pdev, void __iomem *mch_window) |
| 372 | 372 | { |
| 373 | − static const char *labels[4] = { | |
| 374 | − "DIMM A1", "DIMM A2", | |
| 375 | − "DIMM B1", "DIMM B2" | |
| 376 | − }; | |
| 377 | 373 | struct csrow_info *csrow; |
| 378 | 374 | unsigned long last_cumul_size; |
| 379 | 375 | u8 value; |
| @@ -423,9 +419,10 @@ static void i82975x_init_csrows(struct mem_ctl_info *mci, · 43 unmodified lines | ||
| 423 | 419 | dimm = mci->csrows[index]->channels[chan]->dimm; |
| 424 | 420 | |
| 425 | 421 | dimm->nr_pages = nr_pages / csrow->nr_channels; |
| 426 | − strncpy(csrow->channels[chan]->dimm->label, | |
| 427 | − labels[(index >> 1) + (chan * 2)], | |
| 428 | − EDAC_MC_LABEL_LEN); | |
| 422 | + | |
| 423 | + snprintf(csrow->channels[chan]->dimm->label, EDAC_MC_LABEL_LEN, "DIMM %c%d", | |
| 424 | + (chan == 0) ? 'A' : 'B', | |
| 425 | + index); | |
| 429 | 426 | dimm->grain = 1 << 7; /* 128Byte cache-line resolution */ |
| 430 | 427 | dimm->dtype = i82975x_dram_type(mch_window, index); |
| 431 | 428 | dimm->mtype = MEM_DDR2; /* I82975x supports only DDR2 */ |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | * This file may be distributed under the terms of the GNU General Public |
| 7 | 7 | * License version 2. |
| 8 | 8 | * |
| 9 | − * Copyright (c) 2010: Borislav Petkov <borislav.petkov@amd.com> | |
| 9 | + * Copyright (c) 2010: Borislav Petkov <bp@alien8.de> | |
| 10 | 10 | * Advanced Micro Devices Inc. |
| 11 | 11 | */ |
| 12 | 12 | |
| @@ -168,6 +168,6 @@ module_init(edac_init_mce_inject); · 155 unmodified lines | ||
| 168 | 168 | module_exit(edac_exit_mce_inject); |
| 169 | 169 | |
| 170 | 170 | MODULE_LICENSE("GPL"); |
| 171 | −MODULE_AUTHOR("Borislav Petkov <borislav.petkov@amd.com>"); | |
| 171 | +MODULE_AUTHOR("Borislav Petkov <bp@alien8.de>"); | |
| 172 | 172 | MODULE_AUTHOR("AMD Inc."); |
| 173 | 173 | MODULE_DESCRIPTION("MCE injection facility for testing MCE decoding"); |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | * |
| 15 | 15 | */ |
| 16 | 16 | |
| 17 | +#include <linux/module.h> | |
| 17 | 18 | #include <linux/slab.h> |
| 18 | 19 | #include <linux/device.h> |
| 19 | 20 | #include <linux/platform_device.h> |
| @@ -161,13 +162,12 @@ static int __devinit adc_jack_probe(struct platform_device *pdev) · 141 unmodified lines | ||
| 161 | 162 | err = request_any_context_irq(data->irq, adc_jack_irq_thread, |
| 162 | 163 | pdata->irq_flags, pdata->name, data); |
| 163 | 164 | |
| 164 | − if (err) { | |
| 165 | + if (err < 0) { | |
| 165 | 166 | dev_err(&pdev->dev, "error: irq %d\n", data->irq); |
| 166 | − err = -EINVAL; | |
| 167 | 167 | goto err_irq; |
| 168 | 168 | } |
| 169 | 169 | |
| 170 | − goto out; | |
| 170 | + return 0; | |
| 171 | 171 | |
| 172 | 172 | err_irq: |
| 173 | 173 | extcon_dev_unregister(&data->edev); |
| @@ -196,3 +196,7 @@ static struct platform_driver adc_jack_driver = { · 22 unmodified lines | ||
| 196 | 196 | }; |
| 197 | 197 | |
| 198 | 198 | module_platform_driver(adc_jack_driver); |
| 199 | + | |
| 200 | +MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); | |
| 201 | +MODULE_DESCRIPTION("ADC Jack extcon driver"); | |
| 202 | +MODULE_LICENSE("GPL v2"); | |
| @@ -41,7 +41,7 @@ · 40 unmodified lines | ||
| 41 | 41 | * every single port-type of the following cable names. Please choose cable |
| 42 | 42 | * names that are actually used in your extcon device. |
| 43 | 43 | */ |
| 44 | −const char *extcon_cable_name[] = { | |
| 44 | +const char extcon_cable_name[][CABLE_NAME_MAX + 1] = { | |
| 45 | 45 | [EXTCON_USB] = "USB", |
| 46 | 46 | [EXTCON_USB_HOST] = "USB-Host", |
| 47 | 47 | [EXTCON_TA] = "TA", |
| @@ -62,8 +62,6 @@ const char *extcon_cable_name[] = { · 14 unmodified lines | ||
| 62 | 62 | [EXTCON_VIDEO_IN] = "Video-in", |
| 63 | 63 | [EXTCON_VIDEO_OUT] = "Video-out", |
| 64 | 64 | [EXTCON_MECHANICAL] = "Mechanical", |
| 65 | − | |
| 66 | − NULL, | |
| 67 | 65 | }; |
| 68 | 66 | |
| 69 | 67 | static struct class *extcon_class; |
| @@ -91,17 +89,13 @@ static int check_mutually_exclusive(struct extcon_dev *edev, u32 new_state) · 21 unmodified lines | ||
| 91 | 89 | return 0; |
| 92 | 90 | |
| 93 | 91 | for (i = 0; edev->mutually_exclusive[i]; i++) { |
| 94 | − int count = 0, j; | |
| 92 | + int weight; | |
| 95 | 93 | u32 correspondants = new_state & edev->mutually_exclusive[i]; |
| 96 | − u32 exp = 1; | |
| 97 | − | |
| 98 | − for (j = 0; j < 32; j++) { | |
| 99 | − if (exp & correspondants) | |
| 100 | − count++; | |
| 101 | − if (count > 1) | |
| 102 | − return i + 1; | |
| 103 | − exp <<= 1; | |
| 104 | − } | |
| 94 | + | |
| 95 | + /* calculate the total number of bits set */ | |
| 96 | + weight = hweight32(correspondants); | |
| 97 | + if (weight > 1) | |
| 98 | + return i + 1; | |
| 105 | 99 | } |
| 106 | 100 | |
| 107 | 101 | return 0; |
| @@ -362,7 +356,7 @@ int extcon_get_cable_state(struct extcon_dev *edev, const char *cable_name) · 254 unmodified lines | ||
| 362 | 356 | EXPORT_SYMBOL_GPL(extcon_get_cable_state); |
| 363 | 357 | |
| 364 | 358 | /** |
| 365 | − * extcon_get_cable_state_() - Set the status of a specific cable. | |
| 359 | + * extcon_set_cable_state_() - Set the status of a specific cable. | |
| 366 | 360 | * @edev: the extcon device that has the cable. |
| 367 | 361 | * @index: cable index that can be retrieved by extcon_find_cable_index(). |
| 368 | 362 | * @cable_state: the new cable status. The default semantics is |
| @@ -382,7 +376,7 @@ int extcon_set_cable_state_(struct extcon_dev *edev, · 13 unmodified lines | ||
| 382 | 376 | EXPORT_SYMBOL_GPL(extcon_set_cable_state_); |
| 383 | 377 | |
| 384 | 378 | /** |
| 385 | − * extcon_get_cable_state() - Set the status of a specific cable. | |
| 379 | + * extcon_set_cable_state() - Set the status of a specific cable. | |
| 386 | 380 | * @edev: the extcon device that has the cable. |
| 387 | 381 | * @cable_name: cable name. |
| 388 | 382 | * @cable_state: the new cable status. The default semantics is |
| @@ -447,6 +441,8 @@ static int _call_per_cable(struct notifier_block *nb, unsigned long val, · 58 unmodified lines | ||
| 447 | 441 | * extcon device. |
| 448 | 442 | * @obj: an empty extcon_specific_cable_nb object to be returned. |
| 449 | 443 | * @extcon_name: the name of extcon device. |
| 444 | + * if NULL, extcon_register_interest will register | |
| 445 | + * every cable with the target cable_name given. | |
| 450 | 446 | * @cable_name: the target cable name. |
| 451 | 447 | * @nb: the notifier block to get notified. |
| 452 | 448 | * |
| @@ -466,22 +462,44 @@ int extcon_register_interest(struct extcon_specific_cable_nb *obj, · 13 unmodified lines | ||
| 466 | 462 | const char *extcon_name, const char *cable_name, |
| 467 | 463 | struct notifier_block *nb) |
| 468 | 464 | { |
| 469 | − if (!obj || !extcon_name || !cable_name || !nb) | |
| 465 | + if (!obj || !cable_name || !nb) | |
| 470 | 466 | return -EINVAL; |
| 471 | 467 | |
| 472 | − obj->edev = extcon_get_extcon_dev(extcon_name); | |
| 473 | − if (!obj->edev) | |
| 474 | − return -ENODEV; | |
| 468 | + if (extcon_name) { | |
| 469 | + obj->edev = extcon_get_extcon_dev(extcon_name); | |
| 470 | + if (!obj->edev) | |
| 471 | + return -ENODEV; | |
| 475 | 472 | |
| 476 | − obj->cable_index = extcon_find_cable_index(obj->edev, cable_name); | |
| 477 | − if (obj->cable_index < 0) | |
| 478 | − return -ENODEV; | |
| 473 | + obj->cable_index = extcon_find_cable_index(obj->edev, cable_name); | |
| 474 | + if (obj->cable_index < 0) | |
| 475 | + return -ENODEV; | |
| 476 | + | |
| 477 | + obj->user_nb = nb; | |
| 479 | 478 | |
| 480 | − obj->user_nb = nb; | |
| 479 | + obj->internal_nb.notifier_call = _call_per_cable; | |
| 481 | 480 | |
| 482 | − obj->internal_nb.notifier_call = _call_per_cable; | |
| 481 | + return raw_notifier_chain_register(&obj->edev->nh, &obj->internal_nb); | |
| 482 | + } else { | |
| 483 | + struct class_dev_iter iter; | |
| 484 | + struct extcon_dev *extd; | |
| 485 | + struct device *dev; | |
| 486 | + | |
| 487 | + if (!extcon_class) | |
| 488 | + return -ENODEV; | |
| 489 | + class_dev_iter_init(&iter, extcon_class, NULL, NULL); | |
| 490 | + while ((dev = class_dev_iter_next(&iter))) { | |
| 491 | + extd = (struct extcon_dev *)dev_get_drvdata(dev); | |
| 492 | + | |
| 493 | + if (extcon_find_cable_index(extd, cable_name) < 0) | |
| 494 | + continue; | |
| 495 | + | |
| 496 | + class_dev_iter_exit(&iter); | |
| 497 | + return extcon_register_interest(obj, extd->name, | |
| 498 | + cable_name, nb); | |
| 499 | + } | |
| 483 | 500 | |
| 484 | − return raw_notifier_chain_register(&obj->edev->nh, &obj->internal_nb); | |
| 501 | + return -ENODEV; | |
| 502 | + } | |
| 485 | 503 | } |
| 486 | 504 | |
| 487 | 505 | /** |
| @@ -551,43 +569,9 @@ static int create_extcon_class(void) · 63 unmodified lines | ||
| 551 | 569 | return 0; |
| 552 | 570 | } |
| 553 | 571 | |
| 554 | −static void extcon_cleanup(struct extcon_dev *edev, bool skip) | |
| 555 | −{ | |
| 556 | − mutex_lock(&extcon_dev_list_lock); | |
| 557 | − list_del(&edev->entry); | |
| 558 | − mutex_unlock(&extcon_dev_list_lock); | |
| 559 | − | |
| 560 | − if (!skip && get_device(edev->dev)) { | |
| 561 | − int index; | |
| 562 | − | |
| 563 | − if (edev->mutually_exclusive && edev->max_supported) { | |
| 564 | − for (index = 0; edev->mutually_exclusive[index]; | |
| 565 | − index++) | |
| 566 | − kfree(edev->d_attrs_muex[index].attr.name); | |
| 567 | − kfree(edev->d_attrs_muex); | |
| 568 | − kfree(edev->attrs_muex); | |
| 569 | − } | |
| 570 | − | |
| 571 | − for (index = 0; index < edev->max_supported; index++) | |
| 572 | − kfree(edev->cables[index].attr_g.name); | |
| 573 | − | |
| 574 | − if (edev->max_supported) { | |
| 575 | − kfree(edev->extcon_dev_type.groups); | |
| 576 | − kfree(edev->cables); | |
| 577 | − } | |
| 578 | − | |
| 579 | − device_unregister(edev->dev); | |
| 580 | − put_device(edev->dev); | |
| 581 | − } | |
| 582 | − | |
| 583 | − kfree(edev->dev); | |
| 584 | −} | |
| 585 | − | |
| 586 | 572 | static void extcon_dev_release(struct device *dev) |
| 587 | 573 | { |
| 588 | − struct extcon_dev *edev = (struct extcon_dev *) dev_get_drvdata(dev); | |
| 589 | − | |
| 590 | − extcon_cleanup(edev, true); | |
| 574 | + kfree(dev); | |
| 591 | 575 | } |
| 592 | 576 | |
| 593 | 577 | static const char *muex_name = "mutually_exclusive"; |
| @@ -813,7 +797,40 @@ EXPORT_SYMBOL_GPL(extcon_dev_register); · 219 unmodified lines | ||
| 813 | 797 | */ |
| 814 | 798 | void extcon_dev_unregister(struct extcon_dev *edev) |
| 815 | 799 | { |
| 816 | − extcon_cleanup(edev, false); | |
| 800 | + int index; | |
| 801 | + | |
| 802 | + mutex_lock(&extcon_dev_list_lock); | |
| 803 | + list_del(&edev->entry); | |
| 804 | + mutex_unlock(&extcon_dev_list_lock); | |
| 805 | + | |
| 806 | + if (IS_ERR_OR_NULL(get_device(edev->dev))) { | |
| 807 | + dev_err(edev->dev, "Failed to unregister extcon_dev (%s)\n", | |
| 808 | + dev_name(edev->dev)); | |
| 809 | + return; | |
| 810 | + } | |
| 811 | + | |
| 812 | + if (edev->mutually_exclusive && edev->max_supported) { | |
| 813 | + for (index = 0; edev->mutually_exclusive[index]; | |
| 814 | + index++) | |
| 815 | + kfree(edev->d_attrs_muex[index].attr.name); | |
| 816 | + kfree(edev->d_attrs_muex); | |
| 817 | + kfree(edev->attrs_muex); | |
| 818 | + } | |
| 819 | + | |
| 820 | + for (index = 0; index < edev->max_supported; index++) | |
| 821 | + kfree(edev->cables[index].attr_g.name); | |
| 822 | + | |
| 823 | + if (edev->max_supported) { | |
| 824 | + kfree(edev->extcon_dev_type.groups); | |
| 825 | + kfree(edev->cables); | |
| 826 | + } | |
| 827 | + | |
| 828 | +#if defined(CONFIG_ANDROID) | |
| 829 | + if (switch_class) | |
| 830 | + class_compat_remove_link(switch_class, edev->dev, NULL); | |
| 831 | +#endif | |
| 832 | + device_unregister(edev->dev); | |
| 833 | + put_device(edev->dev); | |
| 817 | 834 | } |
| 818 | 835 | EXPORT_SYMBOL_GPL(extcon_dev_unregister); |
| 819 | 836 | |
| @@ -825,6 +842,9 @@ module_init(extcon_class_init); · 5 unmodified lines | ||
| 825 | 842 | |
| 826 | 843 | static void __exit extcon_class_exit(void) |
| 827 | 844 | { |
| 845 | +#if defined(CONFIG_ANDROID) | |
| 846 | + class_compat_unregister(switch_class); | |
| 847 | +#endif | |
| 828 | 848 | class_destroy(extcon_class); |
| 829 | 849 | } |
| 830 | 850 | module_exit(extcon_class_exit); |
| @@ -26,7 +26,6 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <linux/interrupt.h> |
| 27 | 27 | #include <linux/platform_device.h> |
| 28 | 28 | #include <linux/slab.h> |
| 29 | −#include <linux/extcon.h> | |
| 30 | 29 | #include <linux/workqueue.h> |
| 31 | 30 | #include <linux/gpio.h> |
| 32 | 31 | #include <linux/extcon.h> |
| @@ -239,25 +239,19 @@ const char *max77693_extcon_cable[] = { · 238 unmodified lines | ||
| 239 | 239 | static int max77693_muic_set_debounce_time(struct max77693_muic_info *info, |
| 240 | 240 | enum max77693_muic_adc_debounce_time time) |
| 241 | 241 | { |
| 242 | − int ret = 0; | |
| 243 | − u8 ctrl3; | |
| 242 | + int ret; | |
| 244 | 243 | |
| 245 | 244 | switch (time) { |
| 246 | 245 | case ADC_DEBOUNCE_TIME_5MS: |
| 247 | 246 | case ADC_DEBOUNCE_TIME_10MS: |
| 248 | 247 | case ADC_DEBOUNCE_TIME_25MS: |
| 249 | 248 | case ADC_DEBOUNCE_TIME_38_62MS: |
| 250 | − ret = max77693_read_reg(info->max77693->regmap_muic, | |
| 251 | − MAX77693_MUIC_REG_CTRL3, &ctrl3); | |
| 252 | − ctrl3 &= ~CONTROL3_ADCDBSET_MASK; | |
| 253 | − ctrl3 |= (time << CONTROL3_ADCDBSET_SHIFT); | |
| 254 | − | |
| 255 | − ret = max77693_write_reg(info->max77693->regmap_muic, | |
| 256 | − MAX77693_MUIC_REG_CTRL3, ctrl3); | |
| 257 | − if (ret) { | |
| 249 | + ret = max77693_update_reg(info->max77693->regmap_muic, | |
| 250 | + MAX77693_MUIC_REG_CTRL3, | |
| 251 | + time << CONTROL3_ADCDBSET_SHIFT, | |
| 252 | + CONTROL3_ADCDBSET_MASK); | |
| 253 | + if (ret) | |
| 258 | 254 | dev_err(info->dev, "failed to set ADC debounce time\n"); |
| 259 | − ret = -EINVAL; | |
| 260 | − } | |
| 261 | 255 | break; |
| 262 | 256 | default: |
| 263 | 257 | dev_err(info->dev, "invalid ADC debounce time\n"); |
| @@ -657,6 +651,8 @@ out: · 393 unmodified lines | ||
| 657 | 651 | static int __devinit max77693_muic_probe(struct platform_device *pdev) |
| 658 | 652 | { |
| 659 | 653 | struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent); |
| 654 | + struct max77693_platform_data *pdata = dev_get_platdata(max77693->dev); | |
| 655 | + struct max77693_muic_platform_data *muic_pdata = pdata->muic_data; | |
| 660 | 656 | struct max77693_muic_info *info; |
| 661 | 657 | int ret, i; |
| 662 | 658 | u8 id; |
| @@ -727,6 +723,31 @@ static int __devinit max77693_muic_probe(struct platform_device *pdev) · 64 unmodified lines | ||
| 727 | 723 | goto err_extcon; |
| 728 | 724 | } |
| 729 | 725 | |
| 726 | + /* Initialize MUIC register by using platform data */ | |
| 727 | + for (i = 0 ; i < muic_pdata->num_init_data ; i++) { | |
| 728 | + enum max77693_irq_source irq_src = MAX77693_IRQ_GROUP_NR; | |
| 729 | + | |
| 730 | + max77693_write_reg(info->max77693->regmap_muic, | |
| 731 | + muic_pdata->init_data[i].addr, | |
| 732 | + muic_pdata->init_data[i].data); | |
| 733 | + | |
| 734 | + switch (muic_pdata->init_data[i].addr) { | |
| 735 | + case MAX77693_MUIC_REG_INTMASK1: | |
| 736 | + irq_src = MUIC_INT1; | |
| 737 | + break; | |
| 738 | + case MAX77693_MUIC_REG_INTMASK2: | |
| 739 | + irq_src = MUIC_INT2; | |
| 740 | + break; | |
| 741 | + case MAX77693_MUIC_REG_INTMASK3: | |
| 742 | + irq_src = MUIC_INT3; | |
| 743 | + break; | |
| 744 | + } | |
| 745 | + | |
| 746 | + if (irq_src < MAX77693_IRQ_GROUP_NR) | |
| 747 | + info->max77693->irq_masks_cur[irq_src] | |
| 748 | + = muic_pdata->init_data[i].data; | |
| 749 | + } | |
| 750 | + | |
| 730 | 751 | /* Check revision number of MUIC device*/ |
| 731 | 752 | ret = max77693_read_reg(info->max77693->regmap_muic, |
| 732 | 753 | MAX77693_MUIC_REG_ID, &id); |
| @@ -762,6 +783,7 @@ static int __devexit max77693_muic_remove(struct platform_device *pdev) · 29 unmodified lines | ||
| 762 | 783 | free_irq(muic_irqs[i].virq, info); |
| 763 | 784 | cancel_work_sync(&info->irq_work); |
| 764 | 785 | extcon_dev_unregister(info->edev); |
| 786 | + kfree(info->edev); | |
| 765 | 787 | kfree(info); |
| 766 | 788 | |
| 767 | 789 | return 0; |
| @@ -271,8 +271,6 @@ out: · 270 unmodified lines | ||
| 271 | 271 | static int max8997_muic_handle_charger_type_detach( |
| 272 | 272 | struct max8997_muic_info *info) |
| 273 | 273 | { |
| 274 | − int ret = 0; | |
| 275 | − | |
| 276 | 274 | switch (info->pre_charger_type) { |
| 277 | 275 | case MAX8997_CHARGER_TYPE_USB: |
| 278 | 276 | extcon_set_cable_state(info->edev, "USB", false); |
| @@ -290,11 +288,11 @@ static int max8997_muic_handle_charger_type_detach( · 11 unmodified lines | ||
| 290 | 288 | extcon_set_cable_state(info->edev, "Fast-charger", false); |
| 291 | 289 | break; |
| 292 | 290 | default: |
| 293 | − ret = -EINVAL; | |
| 291 | + return -EINVAL; | |
| 294 | 292 | break; |
| 295 | 293 | } |
| 296 | 294 | |
| 297 | − return ret; | |
| 295 | + return 0; | |
| 298 | 296 | } |
| 299 | 297 | |
| 300 | 298 | static int max8997_muic_handle_charger_type(struct max8997_muic_info *info, |
| @@ -1546,6 +1546,8 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) · 1545 unmodified lines | ||
| 1546 | 1546 | struct sbp2_logical_unit *lu = sdev->hostdata; |
| 1547 | 1547 | |
| 1548 | 1548 | sdev->use_10_for_rw = 1; |
| 1549 | + sdev->no_report_opcodes = 1; | |
| 1550 | + sdev->no_write_same = 1; | |
| 1549 | 1551 | |
| 1550 | 1552 | if (sbp2_param_exclusive_login) |
| 1551 | 1553 | sdev->manage_start_stop = 1; |
| @@ -47,7 +47,7 @@ if GPIOLIB · 46 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | config OF_GPIO |
| 49 | 49 | def_bool y |
| 50 | − depends on OF && !SPARC | |
| 50 | + depends on OF | |
| 51 | 51 | |
| 52 | 52 | config DEBUG_GPIO |
| 53 | 53 | bool "Debug GPIO calls" |
| @@ -466,7 +466,7 @@ config GPIO_ADP5588_IRQ · 412 unmodified lines | ||
| 466 | 466 | |
| 467 | 467 | config GPIO_ADNP |
| 468 | 468 | tristate "Avionic Design N-bit GPIO expander" |
| 469 | − depends on I2C && OF | |
| 469 | + depends on I2C && OF_GPIO | |
| 470 | 470 | help |
| 471 | 471 | This option enables support for N GPIOs found on Avionic Design |
| 472 | 472 | I2C GPIO expanders. The register space will be extended by powers |
| @@ -153,7 +153,7 @@ static int __devinit gen_74x164_probe(struct spi_device *spi) · 152 unmodified lines | ||
| 153 | 153 | } |
| 154 | 154 | |
| 155 | 155 | chip->gpio_chip.ngpio = GEN_74X164_NUMBER_GPIOS * chip->registers; |
| 156 | − chip->buffer = devm_kzalloc(&spi->dev, chip->gpio_chip.ngpio, GFP_KERNEL); | |
| 156 | + chip->buffer = devm_kzalloc(&spi->dev, chip->registers, GFP_KERNEL); | |
| 157 | 157 | if (!chip->buffer) { |
| 158 | 158 | ret = -ENOMEM; |
| 159 | 159 | goto exit_destroy; |
| @@ -77,7 +77,7 @@ struct mcp23s08_driver_data { · 76 unmodified lines | ||
| 77 | 77 | |
| 78 | 78 | /*----------------------------------------------------------------------*/ |
| 79 | 79 | |
| 80 | −#ifdef CONFIG_I2C | |
| 80 | +#if IS_ENABLED(CONFIG_I2C) | |
| 81 | 81 | |
| 82 | 82 | static int mcp23008_read(struct mcp23s08 *mcp, unsigned reg) |
| 83 | 83 | { |
| @@ -399,7 +399,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, · 315 unmodified lines | ||
| 399 | 399 | break; |
| 400 | 400 | #endif /* CONFIG_SPI_MASTER */ |
| 401 | 401 | |
| 402 | −#ifdef CONFIG_I2C | |
| 402 | +#if IS_ENABLED(CONFIG_I2C) | |
| 403 | 403 | case MCP_TYPE_008: |
| 404 | 404 | mcp->ops = &mcp23008_ops; |
| 405 | 405 | mcp->chip.ngpio = 8; |
| @@ -473,7 +473,7 @@ fail: · 67 unmodified lines | ||
| 473 | 473 | |
| 474 | 474 | /*----------------------------------------------------------------------*/ |
| 475 | 475 | |
| 476 | −#ifdef CONFIG_I2C | |
| 476 | +#if IS_ENABLED(CONFIG_I2C) | |
| 477 | 477 | |
| 478 | 478 | static int __devinit mcp230xx_probe(struct i2c_client *client, |
| 479 | 479 | const struct i2c_device_id *id) |
| @@ -92,6 +92,11 @@ static inline void __iomem *mvebu_gpioreg_out(struct mvebu_gpio_chip *mvchip) · 91 unmodified lines | ||
| 92 | 92 | return mvchip->membase + GPIO_OUT_OFF; |
| 93 | 93 | } |
| 94 | 94 | |
| 95 | +static inline void __iomem *mvebu_gpioreg_blink(struct mvebu_gpio_chip *mvchip) | |
| 96 | +{ | |
| 97 | + return mvchip->membase + GPIO_BLINK_EN_OFF; | |
| 98 | +} | |
| 99 | + | |
| 95 | 100 | static inline void __iomem *mvebu_gpioreg_io_conf(struct mvebu_gpio_chip *mvchip) |
| 96 | 101 | { |
| 97 | 102 | return mvchip->membase + GPIO_IO_CONF_OFF; |
| @@ -206,6 +211,23 @@ static int mvebu_gpio_get(struct gpio_chip *chip, unsigned pin) · 108 unmodified lines | ||
| 206 | 211 | return (u >> pin) & 1; |
| 207 | 212 | } |
| 208 | 213 | |
| 214 | +static void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value) | |
| 215 | +{ | |
| 216 | + struct mvebu_gpio_chip *mvchip = | |
| 217 | + container_of(chip, struct mvebu_gpio_chip, chip); | |
| 218 | + unsigned long flags; | |
| 219 | + u32 u; | |
| 220 | + | |
| 221 | + spin_lock_irqsave(&mvchip->lock, flags); | |
| 222 | + u = readl_relaxed(mvebu_gpioreg_blink(mvchip)); | |
| 223 | + if (value) | |
| 224 | + u |= 1 << pin; | |
| 225 | + else | |
| 226 | + u &= ~(1 << pin); | |
| 227 | + writel_relaxed(u, mvebu_gpioreg_blink(mvchip)); | |
| 228 | + spin_unlock_irqrestore(&mvchip->lock, flags); | |
| 229 | +} | |
| 230 | + | |
| 209 | 231 | static int mvebu_gpio_direction_input(struct gpio_chip *chip, unsigned pin) |
| 210 | 232 | { |
| 211 | 233 | struct mvebu_gpio_chip *mvchip = |
| @@ -244,6 +266,9 @@ static int mvebu_gpio_direction_output(struct gpio_chip *chip, unsigned pin, · 32 unmodified lines | ||
| 244 | 266 | if (ret) |
| 245 | 267 | return ret; |
| 246 | 268 | |
| 269 | + mvebu_gpio_blink(chip, pin, 0); | |
| 270 | + mvebu_gpio_set(chip, pin, value); | |
| 271 | + | |
| 247 | 272 | spin_lock_irqsave(&mvchip->lock, flags); |
| 248 | 273 | u = readl_relaxed(mvebu_gpioreg_io_conf(mvchip)); |
| 249 | 274 | u &= ~(1 << pin); |
| @@ -644,7 +669,7 @@ static int __devinit mvebu_gpio_probe(struct platform_device *pdev) · 394 unmodified lines | ||
| 644 | 669 | ct->handler = handle_edge_irq; |
| 645 | 670 | ct->chip.name = mvchip->chip.label; |
| 646 | 671 | |
| 647 | − irq_setup_generic_chip(gc, IRQ_MSK(ngpios), IRQ_GC_INIT_MASK_CACHE, | |
| 672 | + irq_setup_generic_chip(gc, IRQ_MSK(ngpios), 0, | |
| 648 | 673 | IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); |
| 649 | 674 | |
| 650 | 675 | /* Setup irq domain on top of the generic chip. */ |
| @@ -251,6 +251,40 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio, · 250 unmodified lines | ||
| 251 | 251 | } |
| 252 | 252 | } |
| 253 | 253 | |
| 254 | +/** | |
| 255 | + * _clear_gpio_debounce - clear debounce settings for a gpio | |
| 256 | + * @bank: the gpio bank we're acting upon | |
| 257 | + * @gpio: the gpio number on this @gpio | |
| 258 | + * | |
| 259 | + * If a gpio is using debounce, then clear the debounce enable bit and if | |
| 260 | + * this is the only gpio in this bank using debounce, then clear the debounce | |
| 261 | + * time too. The debounce clock will also be disabled when calling this function | |
| 262 | + * if this is the only gpio in the bank using debounce. | |
| 263 | + */ | |
| 264 | +static void _clear_gpio_debounce(struct gpio_bank *bank, unsigned gpio) | |
| 265 | +{ | |
| 266 | + u32 gpio_bit = GPIO_BIT(bank, gpio); | |
| 267 | + | |
| 268 | + if (!bank->dbck_flag) | |
| 269 | + return; | |
| 270 | + | |
| 271 | + if (!(bank->dbck_enable_mask & gpio_bit)) | |
| 272 | + return; | |
| 273 | + | |
| 274 | + bank->dbck_enable_mask &= ~gpio_bit; | |
| 275 | + bank->context.debounce_en &= ~gpio_bit; | |
| 276 | + __raw_writel(bank->context.debounce_en, | |
| 277 | + bank->base + bank->regs->debounce_en); | |
| 278 | + | |
| 279 | + if (!bank->dbck_enable_mask) { | |
| 280 | + bank->context.debounce = 0; | |
| 281 | + __raw_writel(bank->context.debounce, bank->base + | |
| 282 | + bank->regs->debounce); | |
| 283 | + clk_disable(bank->dbck); | |
| 284 | + bank->dbck_enabled = false; | |
| 285 | + } | |
| 286 | +} | |
| 287 | + | |
| 254 | 288 | static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio, |
| 255 | 289 | unsigned trigger) |
| 256 | 290 | { |
| @@ -539,6 +573,7 @@ static void _reset_gpio(struct gpio_bank *bank, int gpio) · 282 unmodified lines | ||
| 539 | 573 | _set_gpio_irqenable(bank, gpio, 0); |
| 540 | 574 | _clear_gpio_irqstatus(bank, gpio); |
| 541 | 575 | _set_gpio_triggering(bank, GPIO_INDEX(bank, gpio), IRQ_TYPE_NONE); |
| 576 | + _clear_gpio_debounce(bank, gpio); | |
| 542 | 577 | } |
| 543 | 578 | |
| 544 | 579 | /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ |
| @@ -116,7 +116,7 @@ static void timbgpio_irq_disable(struct irq_data *d) · 115 unmodified lines | ||
| 116 | 116 | unsigned long flags; |
| 117 | 117 | |
| 118 | 118 | spin_lock_irqsave(&tgpio->lock, flags); |
| 119 | − tgpio->last_ier &= ~(1 << offset); | |
| 119 | + tgpio->last_ier &= ~(1UL << offset); | |
| 120 | 120 | iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); |
| 121 | 121 | spin_unlock_irqrestore(&tgpio->lock, flags); |
| 122 | 122 | } |
| @@ -128,7 +128,7 @@ static void timbgpio_irq_enable(struct irq_data *d) · 5 unmodified lines | ||
| 128 | 128 | unsigned long flags; |
| 129 | 129 | |
| 130 | 130 | spin_lock_irqsave(&tgpio->lock, flags); |
| 131 | − tgpio->last_ier |= 1 << offset; | |
| 131 | + tgpio->last_ier |= 1UL << offset; | |
| 132 | 132 | iowrite32(tgpio->last_ier, tgpio->membase + TGPIO_IER); |
| 133 | 133 | spin_unlock_irqrestore(&tgpio->lock, flags); |
| 134 | 134 | } |
| @@ -623,9 +623,11 @@ static ssize_t export_store(struct class *class, · 622 unmodified lines | ||
| 623 | 623 | */ |
| 624 | 624 | |
| 625 | 625 | status = gpio_request(gpio, "sysfs"); |
| 626 | − if (status < 0) | |
| 626 | + if (status < 0) { | |
| 627 | + if (status == -EPROBE_DEFER) | |
| 628 | + status = -ENODEV; | |
| 627 | 629 | goto done; |
| 628 | − | |
| 630 | + } | |
| 629 | 631 | status = gpio_export(gpio, true); |
| 630 | 632 | if (status < 0) |
| 631 | 633 | gpio_free(gpio); |
| @@ -1191,8 +1193,10 @@ int gpio_request(unsigned gpio, const char *label) · 559 unmodified lines | ||
| 1191 | 1193 | |
| 1192 | 1194 | spin_lock_irqsave(&gpio_lock, flags); |
| 1193 | 1195 | |
| 1194 | − if (!gpio_is_valid(gpio)) | |
| 1196 | + if (!gpio_is_valid(gpio)) { | |
| 1197 | + status = -EINVAL; | |
| 1195 | 1198 | goto done; |
| 1199 | + } | |
| 1196 | 1200 | desc = &gpio_desc[gpio]; |
| 1197 | 1201 | chip = desc->chip; |
| 1198 | 1202 | if (chip == NULL) |
| @@ -121,6 +121,8 @@ int drm_open(struct inode *inode, struct file *filp) · 120 unmodified lines | ||
| 121 | 121 | int minor_id = iminor(inode); |
| 122 | 122 | struct drm_minor *minor; |
| 123 | 123 | int retcode = 0; |
| 124 | + int need_setup = 0; | |
| 125 | + struct address_space *old_mapping; | |
| 124 | 126 | |
| 125 | 127 | minor = idr_find(&drm_minors_idr, minor_id); |
| 126 | 128 | if (!minor) |
| @@ -132,23 +134,37 @@ int drm_open(struct inode *inode, struct file *filp) · 5 unmodified lines | ||
| 132 | 134 | if (drm_device_is_unplugged(dev)) |
| 133 | 135 | return -ENODEV; |
| 134 | 136 | |
| 137 | + if (!dev->open_count++) | |
| 138 | + need_setup = 1; | |
| 139 | + mutex_lock(&dev->struct_mutex); | |
| 140 | + old_mapping = dev->dev_mapping; | |
| 141 | + if (old_mapping == NULL) | |
| 142 | + dev->dev_mapping = &inode->i_data; | |
| 143 | + /* ihold ensures nobody can remove inode with our i_data */ | |
| 144 | + ihold(container_of(dev->dev_mapping, struct inode, i_data)); | |
| 145 | + inode->i_mapping = dev->dev_mapping; | |
| 146 | + filp->f_mapping = dev->dev_mapping; | |
| 147 | + mutex_unlock(&dev->struct_mutex); | |
| 148 | + | |
| 135 | 149 | retcode = drm_open_helper(inode, filp, dev); |
| 136 | − if (!retcode) { | |
| 137 | − atomic_inc(&dev->counts[_DRM_STAT_OPENS]); | |
| 138 | − if (!dev->open_count++) | |
| 139 | − retcode = drm_setup(dev); | |
| 140 | − } | |
| 141 | − if (!retcode) { | |
| 142 | − mutex_lock(&dev->struct_mutex); | |
| 143 | − if (dev->dev_mapping == NULL) | |
| 144 | − dev->dev_mapping = &inode->i_data; | |
| 145 | − /* ihold ensures nobody can remove inode with our i_data */ | |
| 146 | − ihold(container_of(dev->dev_mapping, struct inode, i_data)); | |
| 147 | − inode->i_mapping = dev->dev_mapping; | |
| 148 | − filp->f_mapping = dev->dev_mapping; | |
| 149 | − mutex_unlock(&dev->struct_mutex); | |
| 150 | + if (retcode) | |
| 151 | + goto err_undo; | |
| 152 | + atomic_inc(&dev->counts[_DRM_STAT_OPENS]); | |
| 153 | + if (need_setup) { | |
| 154 | + retcode = drm_setup(dev); | |
| 155 | + if (retcode) | |
| 156 | + goto err_undo; | |
| 150 | 157 | } |
| 158 | + return 0; | |
| 151 | 159 | |
| 160 | +err_undo: | |
| 161 | + mutex_lock(&dev->struct_mutex); | |
| 162 | + filp->f_mapping = old_mapping; | |
| 163 | + inode->i_mapping = old_mapping; | |
| 164 | + iput(container_of(dev->dev_mapping, struct inode, i_data)); | |
| 165 | + dev->dev_mapping = old_mapping; | |
| 166 | + mutex_unlock(&dev->struct_mutex); | |
| 167 | + dev->open_count--; | |
| 152 | 168 | return retcode; |
| 153 | 169 | } |
| 154 | 170 | EXPORT_SYMBOL(drm_open); |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | config DRM_EXYNOS |
| 2 | 2 | tristate "DRM Support for Samsung SoC EXYNOS Series" |
| 3 | − depends on DRM && PLAT_SAMSUNG | |
| 3 | + depends on DRM && (PLAT_SAMSUNG || ARCH_MULTIPLATFORM) | |
| 4 | 4 | select DRM_KMS_HELPER |
| 5 | 5 | select FB_CFB_FILLRECT |
| 6 | 6 | select FB_CFB_COPYAREA |
| @@ -374,6 +374,7 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev, · 373 unmodified lines | ||
| 374 | 374 | exynos_connector->encoder_id = encoder->base.id; |
| 375 | 375 | exynos_connector->manager = manager; |
| 376 | 376 | exynos_connector->dpms = DRM_MODE_DPMS_OFF; |
| 377 | + connector->dpms = DRM_MODE_DPMS_OFF; | |
| 377 | 378 | connector->encoder = encoder; |
| 378 | 379 | |
| 379 | 380 | err = drm_mode_connector_attach_encoder(connector, encoder); |
| @@ -43,12 +43,14 @@ · 42 unmodified lines | ||
| 43 | 43 | * @manager: specific encoder has its own manager to control a hardware |
| 44 | 44 | * appropriately and we can access a hardware drawing on this manager. |
| 45 | 45 | * @dpms: store the encoder dpms value. |
| 46 | + * @updated: indicate whether overlay data updating is needed or not. | |
| 46 | 47 | */ |
| 47 | 48 | struct exynos_drm_encoder { |
| 48 | 49 | struct drm_crtc *old_crtc; |
| 49 | 50 | struct drm_encoder drm_encoder; |
| 50 | 51 | struct exynos_drm_manager *manager; |
| 51 | − int dpms; | |
| 52 | + int dpms; | |
| 53 | + bool updated; | |
| 52 | 54 | }; |
| 53 | 55 | |
| 54 | 56 | static void exynos_drm_connector_power(struct drm_encoder *encoder, int mode) |
| @@ -85,7 +87,9 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) · 30 unmodified lines | ||
| 85 | 87 | switch (mode) { |
| 86 | 88 | case DRM_MODE_DPMS_ON: |
| 87 | 89 | if (manager_ops && manager_ops->apply) |
| 88 | − manager_ops->apply(manager->dev); | |
| 90 | + if (!exynos_encoder->updated) | |
| 91 | + manager_ops->apply(manager->dev); | |
| 92 | + | |
| 89 | 93 | exynos_drm_connector_power(encoder, mode); |
| 90 | 94 | exynos_encoder->dpms = mode; |
| 91 | 95 | break; |
| @@ -94,6 +98,7 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode) · 2 unmodified lines | ||
| 94 | 98 | case DRM_MODE_DPMS_OFF: |
| 95 | 99 | exynos_drm_connector_power(encoder, mode); |
| 96 | 100 | exynos_encoder->dpms = mode; |
| 101 | + exynos_encoder->updated = false; | |
| 97 | 102 | break; |
| 98 | 103 | default: |
| 99 | 104 | DRM_ERROR("unspecified mode %d\n", mode); |
| @@ -205,13 +210,28 @@ static void exynos_drm_encoder_prepare(struct drm_encoder *encoder) · 105 unmodified lines | ||
| 205 | 210 | |
| 206 | 211 | static void exynos_drm_encoder_commit(struct drm_encoder *encoder) |
| 207 | 212 | { |
| 208 | − struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder); | |
| 213 | + struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); | |
| 214 | + struct exynos_drm_manager *manager = exynos_encoder->manager; | |
| 209 | 215 | struct exynos_drm_manager_ops *manager_ops = manager->ops; |
| 210 | 216 | |
| 211 | 217 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 212 | 218 | |
| 213 | 219 | if (manager_ops && manager_ops->commit) |
| 214 | 220 | manager_ops->commit(manager->dev); |
| 221 | + | |
| 222 | + /* | |
| 223 | + * this will avoid one issue that overlay data is updated to | |
| 224 | + * real hardware two times. | |
| 225 | + * And this variable will be used to check if the data was | |
| 226 | + * already updated or not by exynos_drm_encoder_dpms function. | |
| 227 | + */ | |
| 228 | + exynos_encoder->updated = true; | |
| 229 | + | |
| 230 | + /* | |
| 231 | + * In case of setcrtc, there is no way to update encoder's dpms | |
| 232 | + * so update it here. | |
| 233 | + */ | |
| 234 | + exynos_encoder->dpms = DRM_MODE_DPMS_ON; | |
| 215 | 235 | } |
| 216 | 236 | |
| 217 | 237 | static void exynos_drm_encoder_disable(struct drm_encoder *encoder) |
| @@ -400,19 +420,6 @@ void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data) · 182 unmodified lines | ||
| 400 | 420 | if (manager_ops && manager_ops->dpms) |
| 401 | 421 | manager_ops->dpms(manager->dev, mode); |
| 402 | 422 | |
| 403 | − /* | |
| 404 | − * set current mode to new one so that data aren't updated into | |
| 405 | − * registers by drm_helper_connector_dpms two times. | |
| 406 | − * | |
| 407 | − * in case that drm_crtc_helper_set_mode() is called, | |
| 408 | − * overlay_ops->commit() and manager_ops->commit() callbacks | |
| 409 | − * can be called two times, first at drm_crtc_helper_set_mode() | |
| 410 | − * and second at drm_helper_connector_dpms(). | |
| 411 | − * so with this setting, when drm_helper_connector_dpms() is called | |
| 412 | − * encoder->funcs->dpms() will be ignored. | |
| 413 | − */ | |
| 414 | − exynos_encoder->dpms = mode; | |
| 415 | − | |
| 416 | 423 | /* |
| 417 | 424 | * if this condition is ok then it means that the crtc is already |
| 418 | 425 | * detached from encoder and last function for detaching is properly |
| @@ -506,6 +513,6 @@ void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data) · 87 unmodified lines | ||
| 506 | 513 | * because the setting for disabling the overlay will be updated |
| 507 | 514 | * at vsync. |
| 508 | 515 | */ |
| 509 | − if (overlay_ops->wait_for_vblank) | |
| 516 | + if (overlay_ops && overlay_ops->wait_for_vblank) | |
| 510 | 517 | overlay_ops->wait_for_vblank(manager->dev); |
| 511 | 518 | } |
| @@ -87,7 +87,8 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, · 86 unmodified lines | ||
| 87 | 87 | |
| 88 | 88 | dev->mode_config.fb_base = (resource_size_t)buffer->dma_addr; |
| 89 | 89 | fbi->screen_base = buffer->kvaddr + offset; |
| 90 | − fbi->fix.smem_start = (unsigned long)(buffer->dma_addr + offset); | |
| 90 | + fbi->fix.smem_start = (unsigned long)(page_to_phys(buffer->pages[0]) + | |
| 91 | + offset); | |
| 91 | 92 | fbi->screen_size = size; |
| 92 | 93 | fbi->fix.smem_len = size; |
| 93 | 94 | |
| @@ -61,11 +61,11 @@ struct fimd_driver_data { · 60 unmodified lines | ||
| 61 | 61 | unsigned int timing_base; |
| 62 | 62 | }; |
| 63 | 63 | |
| 64 | −struct fimd_driver_data exynos4_fimd_driver_data = { | |
| 64 | +static struct fimd_driver_data exynos4_fimd_driver_data = { | |
| 65 | 65 | .timing_base = 0x0, |
| 66 | 66 | }; |
| 67 | 67 | |
| 68 | −struct fimd_driver_data exynos5_fimd_driver_data = { | |
| 68 | +static struct fimd_driver_data exynos5_fimd_driver_data = { | |
| 69 | 69 | .timing_base = 0x20000, |
| 70 | 70 | }; |
| 71 | 71 | |
| @@ -204,7 +204,6 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, · 203 unmodified lines | ||
| 204 | 204 | return ret; |
| 205 | 205 | |
| 206 | 206 | plane->crtc = crtc; |
| 207 | − plane->fb = crtc->fb; | |
| 208 | 207 | |
| 209 | 208 | exynos_plane_commit(plane); |
| 210 | 209 | exynos_plane_dpms(plane, DRM_MODE_DPMS_ON); |
| @@ -1142,7 +1142,7 @@ static int __devinit mixer_probe(struct platform_device *pdev) · 1141 unmodified lines | ||
| 1142 | 1142 | const struct of_device_id *match; |
| 1143 | 1143 | match = of_match_node(of_match_ptr(mixer_match_types), |
| 1144 | 1144 | pdev->dev.of_node); |
| 1145 | − drv = match->data; | |
| 1145 | + drv = (struct mixer_drv_data *)match->data; | |
| 1146 | 1146 | } else { |
| 1147 | 1147 | drv = (struct mixer_drv_data *) |
| 1148 | 1148 | platform_get_device_id(pdev)->driver_data; |
| @@ -1505,7 +1505,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) · 1504 unmodified lines | ||
| 1505 | 1505 | goto put_gmch; |
| 1506 | 1506 | } |
| 1507 | 1507 | |
| 1508 | − i915_kick_out_firmware_fb(dev_priv); | |
| 1508 | + if (drm_core_check_feature(dev, DRIVER_MODESET)) | |
| 1509 | + i915_kick_out_firmware_fb(dev_priv); | |
| 1509 | 1510 | |
| 1510 | 1511 | pci_set_master(dev->pdev); |
| 1511 | 1512 | |
| @@ -499,12 +499,8 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb) · 498 unmodified lines | ||
| 499 | 499 | |
| 500 | 500 | edp = find_section(bdb, BDB_EDP); |
| 501 | 501 | if (!edp) { |
| 502 | − if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp.support) { | |
| 503 | − DRM_DEBUG_KMS("No eDP BDB found but eDP panel " | |
| 504 | − "supported, assume %dbpp panel color " | |
| 505 | − "depth.\n", | |
| 506 | − dev_priv->edp.bpp); | |
| 507 | − } | |
| 502 | + if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp.support) | |
| 503 | + DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported.\n"); | |
| 508 | 504 | return; |
| 509 | 505 | } |
| 510 | 506 | |
| @@ -657,9 +653,6 @@ init_vbt_defaults(struct drm_i915_private *dev_priv) · 146 unmodified lines | ||
| 657 | 653 | dev_priv->lvds_use_ssc = 1; |
| 658 | 654 | dev_priv->lvds_ssc_freq = intel_bios_ssc_frequency(dev, 1); |
| 659 | 655 | DRM_DEBUG_KMS("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq); |
| 660 | − | |
| 661 | − /* eDP data */ | |
| 662 | − dev_priv->edp.bpp = 18; | |
| 663 | 656 | } |
| 664 | 657 | |
| 665 | 658 | static int __init intel_no_opregion_vbt_callback(const struct dmi_system_id *id) |
| @@ -143,7 +143,7 @@ static void intel_crt_dpms(struct drm_connector *connector, int mode) · 142 unmodified lines | ||
| 143 | 143 | int old_dpms; |
| 144 | 144 | |
| 145 | 145 | /* PCH platforms and VLV only support on/off. */ |
| 146 | − if (INTEL_INFO(dev)->gen < 5 && mode != DRM_MODE_DPMS_ON) | |
| 146 | + if (INTEL_INFO(dev)->gen >= 5 && mode != DRM_MODE_DPMS_ON) | |
| 147 | 147 | mode = DRM_MODE_DPMS_OFF; |
| 148 | 148 | |
| 149 | 149 | if (mode == connector->dpms) |
| @@ -729,7 +729,7 @@ void intel_crt_init(struct drm_device *dev) · 579 unmodified lines | ||
| 729 | 729 | |
| 730 | 730 | crt->base.type = INTEL_OUTPUT_ANALOG; |
| 731 | 731 | crt->base.cloneable = true; |
| 732 | − if (IS_HASWELL(dev)) | |
| 732 | + if (IS_HASWELL(dev) || IS_I830(dev)) | |
| 733 | 733 | crt->base.crtc_mask = (1 << 0); |
| 734 | 734 | else |
| 735 | 735 | crt->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2); |
| @@ -3841,6 +3841,17 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, · 3840 unmodified lines | ||
| 3841 | 3841 | } |
| 3842 | 3842 | } |
| 3843 | 3843 | |
| 3844 | + if (intel_encoder->type == INTEL_OUTPUT_EDP) { | |
| 3845 | + /* Use VBT settings if we have an eDP panel */ | |
| 3846 | + unsigned int edp_bpc = dev_priv->edp.bpp / 3; | |
| 3847 | + | |
| 3848 | + if (edp_bpc && edp_bpc < display_bpc) { | |
| 3849 | + DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); | |
| 3850 | + display_bpc = edp_bpc; | |
| 3851 | + } | |
| 3852 | + continue; | |
| 3853 | + } | |
| 3854 | + | |
| 3844 | 3855 | /* |
| 3845 | 3856 | * HDMI is either 12 or 8, so if the display lets 10bpc sneak |
| 3846 | 3857 | * through, clamp it down. (Note: >12bpc will be caught below.) |
| @@ -341,9 +341,17 @@ static int intel_overlay_off(struct intel_overlay *overlay) · 340 unmodified lines | ||
| 341 | 341 | intel_ring_emit(ring, flip_addr); |
| 342 | 342 | intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); |
| 343 | 343 | /* turn overlay off */ |
| 344 | − intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF); | |
| 345 | − intel_ring_emit(ring, flip_addr); | |
| 346 | − intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | |
| 344 | + if (IS_I830(dev)) { | |
| 345 | + /* Workaround: Don't disable the overlay fully, since otherwise | |
| 346 | + * it dies on the next OVERLAY_ON cmd. */ | |
| 347 | + intel_ring_emit(ring, MI_NOOP); | |
| 348 | + intel_ring_emit(ring, MI_NOOP); | |
| 349 | + intel_ring_emit(ring, MI_NOOP); | |
| 350 | + } else { | |
| 351 | + intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF); | |
| 352 | + intel_ring_emit(ring, flip_addr); | |
| 353 | + intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); | |
| 354 | + } | |
| 347 | 355 | intel_ring_advance(ring); |
| 348 | 356 | |
| 349 | 357 | return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail); |
| @@ -435,7 +435,7 @@ int intel_panel_setup_backlight(struct drm_device *dev) · 434 unmodified lines | ||
| 435 | 435 | props.type = BACKLIGHT_RAW; |
| 436 | 436 | props.max_brightness = _intel_panel_get_max_backlight(dev); |
| 437 | 437 | if (props.max_brightness == 0) { |
| 438 | − DRM_ERROR("Failed to get maximum backlight value\n"); | |
| 438 | + DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n"); | |
| 439 | 439 | return -ENODEV; |
| 440 | 440 | } |
| 441 | 441 | dev_priv->backlight = |
| @@ -2373,15 +2373,9 @@ int intel_enable_rc6(const struct drm_device *dev) · 2372 unmodified lines | ||
| 2373 | 2373 | if (i915_enable_rc6 >= 0) |
| 2374 | 2374 | return i915_enable_rc6; |
| 2375 | 2375 | |
| 2376 | − if (INTEL_INFO(dev)->gen == 5) { | |
| 2377 | −#ifdef CONFIG_INTEL_IOMMU | |
| 2378 | − /* Disable rc6 on ilk if VT-d is on. */ | |
| 2379 | − if (intel_iommu_gfx_mapped) | |
| 2380 | − return false; | |
| 2381 | −#endif | |
| 2382 | − DRM_DEBUG_DRIVER("Ironlake: only RC6 available\n"); | |
| 2383 | − return INTEL_RC6_ENABLE; | |
| 2384 | − } | |
| 2376 | + /* Disable RC6 on Ironlake */ | |
| 2377 | + if (INTEL_INFO(dev)->gen == 5) | |
| 2378 | + return 0; | |
| 2385 | 2379 | |
| 2386 | 2380 | if (IS_HASWELL(dev)) { |
| 2387 | 2381 | DRM_DEBUG_DRIVER("Haswell: only RC6 available\n"); |
| @@ -894,6 +894,45 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo) · 893 unmodified lines | ||
| 894 | 894 | } |
| 895 | 895 | #endif |
| 896 | 896 | |
| 897 | +static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo, | |
| 898 | + unsigned if_index, uint8_t tx_rate, | |
| 899 | + uint8_t *data, unsigned length) | |
| 900 | +{ | |
| 901 | + uint8_t set_buf_index[2] = { if_index, 0 }; | |
| 902 | + uint8_t hbuf_size, tmp[8]; | |
| 903 | + int i; | |
| 904 | + | |
| 905 | + if (!intel_sdvo_set_value(intel_sdvo, | |
| 906 | + SDVO_CMD_SET_HBUF_INDEX, | |
| 907 | + set_buf_index, 2)) | |
| 908 | + return false; | |
| 909 | + | |
| 910 | + if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HBUF_INFO, | |
| 911 | + &hbuf_size, 1)) | |
| 912 | + return false; | |
| 913 | + | |
| 914 | + /* Buffer size is 0 based, hooray! */ | |
| 915 | + hbuf_size++; | |
| 916 | + | |
| 917 | + DRM_DEBUG_KMS("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n", | |
| 918 | + if_index, length, hbuf_size); | |
| 919 | + | |
| 920 | + for (i = 0; i < hbuf_size; i += 8) { | |
| 921 | + memset(tmp, 0, 8); | |
| 922 | + if (i < length) | |
| 923 | + memcpy(tmp, data + i, min_t(unsigned, 8, length - i)); | |
| 924 | + | |
| 925 | + if (!intel_sdvo_set_value(intel_sdvo, | |
| 926 | + SDVO_CMD_SET_HBUF_DATA, | |
| 927 | + tmp, 8)) | |
| 928 | + return false; | |
| 929 | + } | |
| 930 | + | |
| 931 | + return intel_sdvo_set_value(intel_sdvo, | |
| 932 | + SDVO_CMD_SET_HBUF_TXRATE, | |
| 933 | + &tx_rate, 1); | |
| 934 | +} | |
| 935 | + | |
| 897 | 936 | static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) |
| 898 | 937 | { |
| 899 | 938 | struct dip_infoframe avi_if = { |
| @@ -901,11 +940,7 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) · 1 unmodified line | ||
| 901 | 940 | .ver = DIP_VERSION_AVI, |
| 902 | 941 | .len = DIP_LEN_AVI, |
| 903 | 942 | }; |
| 904 | − uint8_t tx_rate = SDVO_HBUF_TX_VSYNC; | |
| 905 | − uint8_t set_buf_index[2] = { 1, 0 }; | |
| 906 | 943 | uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)]; |
| 907 | − uint64_t *data = (uint64_t *)sdvo_data; | |
| 908 | − unsigned i; | |
| 909 | 944 | |
| 910 | 945 | intel_dip_infoframe_csum(&avi_if); |
| 911 | 946 | |
| @@ -915,22 +950,9 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) · 3 unmodified lines | ||
| 915 | 950 | sdvo_data[3] = avi_if.checksum; |
| 916 | 951 | memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi)); |
| 917 | 952 | |
| 918 | − if (!intel_sdvo_set_value(intel_sdvo, | |
| 919 | − SDVO_CMD_SET_HBUF_INDEX, | |
| 920 | − set_buf_index, 2)) | |
| 921 | − return false; | |
| 922 | − | |
| 923 | − for (i = 0; i < sizeof(sdvo_data); i += 8) { | |
| 924 | − if (!intel_sdvo_set_value(intel_sdvo, | |
| 925 | − SDVO_CMD_SET_HBUF_DATA, | |
| 926 | − data, 8)) | |
| 927 | − return false; | |
| 928 | − data++; | |
| 929 | − } | |
| 930 | − | |
| 931 | − return intel_sdvo_set_value(intel_sdvo, | |
| 932 | − SDVO_CMD_SET_HBUF_TXRATE, | |
| 933 | − &tx_rate, 1); | |
| 953 | + return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF, | |
| 954 | + SDVO_HBUF_TX_VSYNC, | |
| 955 | + sdvo_data, sizeof(sdvo_data)); | |
| 934 | 956 | } |
| 935 | 957 | |
| 936 | 958 | static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) |
| @@ -2179,7 +2201,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) · 1242 unmodified lines | ||
| 2179 | 2201 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; |
| 2180 | 2202 | intel_sdvo->is_hdmi = true; |
| 2181 | 2203 | } |
| 2182 | − intel_sdvo->base.cloneable = true; | |
| 2183 | 2204 | |
| 2184 | 2205 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
| 2185 | 2206 | if (intel_sdvo->is_hdmi) |
| @@ -2210,7 +2231,6 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) · 24 unmodified lines | ||
| 2210 | 2231 | |
| 2211 | 2232 | intel_sdvo->is_tv = true; |
| 2212 | 2233 | intel_sdvo->base.needs_tv_clock = true; |
| 2213 | − intel_sdvo->base.cloneable = false; | |
| 2214 | 2234 | |
| 2215 | 2235 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
| 2216 | 2236 | |
| @@ -2253,8 +2273,6 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device) · 36 unmodified lines | ||
| 2253 | 2273 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; |
| 2254 | 2274 | } |
| 2255 | 2275 | |
| 2256 | − intel_sdvo->base.cloneable = true; | |
| 2257 | − | |
| 2258 | 2276 | intel_sdvo_connector_init(intel_sdvo_connector, |
| 2259 | 2277 | intel_sdvo); |
| 2260 | 2278 | return true; |
| @@ -2285,9 +2303,6 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) · 24 unmodified lines | ||
| 2285 | 2303 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; |
| 2286 | 2304 | } |
| 2287 | 2305 | |
| 2288 | − /* SDVO LVDS is not cloneable because the input mode gets adjusted by the encoder */ | |
| 2289 | − intel_sdvo->base.cloneable = false; | |
| 2290 | − | |
| 2291 | 2306 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
| 2292 | 2307 | if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) |
| 2293 | 2308 | goto err; |
| @@ -2360,6 +2375,18 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags) · 66 unmodified lines | ||
| 2360 | 2375 | return true; |
| 2361 | 2376 | } |
| 2362 | 2377 | |
| 2378 | +static void intel_sdvo_output_cleanup(struct intel_sdvo *intel_sdvo) | |
| 2379 | +{ | |
| 2380 | + struct drm_device *dev = intel_sdvo->base.base.dev; | |
| 2381 | + struct drm_connector *connector, *tmp; | |
| 2382 | + | |
| 2383 | + list_for_each_entry_safe(connector, tmp, | |
| 2384 | + &dev->mode_config.connector_list, head) { | |
| 2385 | + if (intel_attached_encoder(connector) == &intel_sdvo->base) | |
| 2386 | + intel_sdvo_destroy(connector); | |
| 2387 | + } | |
| 2388 | +} | |
| 2389 | + | |
| 2363 | 2390 | static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, |
| 2364 | 2391 | struct intel_sdvo_connector *intel_sdvo_connector, |
| 2365 | 2392 | int type) |
| @@ -2683,9 +2710,20 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) · 317 unmodified lines | ||
| 2683 | 2710 | intel_sdvo->caps.output_flags) != true) { |
| 2684 | 2711 | DRM_DEBUG_KMS("SDVO output failed to setup on %s\n", |
| 2685 | 2712 | SDVO_NAME(intel_sdvo)); |
| 2686 | − goto err; | |
| 2713 | + /* Output_setup can leave behind connectors! */ | |
| 2714 | + goto err_output; | |
| 2687 | 2715 | } |
| 2688 | 2716 | |
| 2717 | + /* | |
| 2718 | + * Cloning SDVO with anything is often impossible, since the SDVO | |
| 2719 | + * encoder can request a special input timing mode. And even if that's | |
| 2720 | + * not the case we have evidence that cloning a plain unscaled mode with | |
| 2721 | + * VGA doesn't really work. Furthermore the cloning flags are way too | |
| 2722 | + * simplistic anyway to express such constraints, so just give up on | |
| 2723 | + * cloning for SDVO encoders. | |
| 2724 | + */ | |
| 2725 | + intel_sdvo->base.cloneable = false; | |
| 2726 | + | |
| 2689 | 2727 | /* Only enable the hotplug irq if we need it, to work around noisy |
| 2690 | 2728 | * hotplug lines. |
| 2691 | 2729 | */ |
| @@ -2696,12 +2734,12 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) · 4 unmodified lines | ||
| 2696 | 2734 | |
| 2697 | 2735 | /* Set the input timing to the screen. Assume always input 0. */ |
| 2698 | 2736 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
| 2699 | − goto err; | |
| 2737 | + goto err_output; | |
| 2700 | 2738 | |
| 2701 | 2739 | if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo, |
| 2702 | 2740 | &intel_sdvo->pixel_clock_min, |
| 2703 | 2741 | &intel_sdvo->pixel_clock_max)) |
| 2704 | − goto err; | |
| 2742 | + goto err_output; | |
| 2705 | 2743 | |
| 2706 | 2744 | DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " |
| 2707 | 2745 | "clock range %dMHz - %dMHz, " |
| @@ -2721,6 +2759,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) · 13 unmodified lines | ||
| 2721 | 2759 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); |
| 2722 | 2760 | return true; |
| 2723 | 2761 | |
| 2762 | +err_output: | |
| 2763 | + intel_sdvo_output_cleanup(intel_sdvo); | |
| 2764 | + | |
| 2724 | 2765 | err: |
| 2725 | 2766 | drm_encoder_cleanup(&intel_encoder->base); |
| 2726 | 2767 | i2c_del_adapter(&intel_sdvo->ddc); |
| @@ -708,6 +708,8 @@ struct intel_sdvo_enhancements_arg { · 707 unmodified lines | ||
| 708 | 708 | #define SDVO_CMD_SET_AUDIO_STAT 0x91 |
| 709 | 709 | #define SDVO_CMD_GET_AUDIO_STAT 0x92 |
| 710 | 710 | #define SDVO_CMD_SET_HBUF_INDEX 0x93 |
| 711 | + #define SDVO_HBUF_INDEX_ELD 0 | |
| 712 | + #define SDVO_HBUF_INDEX_AVI_IF 1 | |
| 711 | 713 | #define SDVO_CMD_GET_HBUF_INDEX 0x94 |
| 712 | 714 | #define SDVO_CMD_GET_HBUF_INFO 0x95 |
| 713 | 715 | #define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96 |
| @@ -218,13 +218,16 @@ nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block) · 217 unmodified lines | ||
| 218 | 218 | node = kzalloc(sizeof(*node), GFP_KERNEL); |
| 219 | 219 | if (!node) |
| 220 | 220 | return -ENOMEM; |
| 221 | − node->offset = roundup(offset, mm->block_size); | |
| 222 | − node->length = rounddown(offset + length, mm->block_size) - node->offset; | |
| 221 | + | |
| 222 | + if (length) { | |
| 223 | + node->offset = roundup(offset, mm->block_size); | |
| 224 | + node->length = rounddown(offset + length, mm->block_size); | |
| 225 | + node->length -= node->offset; | |
| 226 | + } | |
| 223 | 227 | |
| 224 | 228 | list_add_tail(&node->nl_entry, &mm->nodes); |
| 225 | 229 | list_add_tail(&node->fl_entry, &mm->free); |
| 226 | 230 | mm->heap_nodes++; |
| 227 | − mm->heap_size += length; | |
| 228 | 231 | return 0; |
| 229 | 232 | } |
| 230 | 233 | |
| @@ -22,6 +22,8 @@ · 21 unmodified lines | ||
| 22 | 22 | * Authors: Ben Skeggs |
| 23 | 23 | */ |
| 24 | 24 | |
| 25 | +#include <subdev/bar.h> | |
| 26 | + | |
| 25 | 27 | #include <engine/software.h> |
| 26 | 28 | #include <engine/disp.h> |
| 27 | 29 | |
| @@ -37,6 +39,7 @@ nv50_disp_sclass[] = { · 9 unmodified lines | ||
| 37 | 39 | static void |
| 38 | 40 | nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) |
| 39 | 41 | { |
| 42 | + struct nouveau_bar *bar = nouveau_bar(priv); | |
| 40 | 43 | struct nouveau_disp *disp = &priv->base; |
| 41 | 44 | struct nouveau_software_chan *chan, *temp; |
| 42 | 45 | unsigned long flags; |
| @@ -46,19 +49,25 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) · 3 unmodified lines | ||
| 46 | 49 | if (chan->vblank.crtc != crtc) |
| 47 | 50 | continue; |
| 48 | 51 | |
| 49 | − nv_wr32(priv, 0x001704, chan->vblank.channel); | |
| 50 | − nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma); | |
| 51 | − | |
| 52 | − if (nv_device(priv)->chipset == 0x50) { | |
| 53 | − nv_wr32(priv, 0x001570, chan->vblank.offset); | |
| 54 | − nv_wr32(priv, 0x001574, chan->vblank.value); | |
| 52 | + if (nv_device(priv)->chipset >= 0xc0) { | |
| 53 | + nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel); | |
| 54 | + bar->flush(bar); | |
| 55 | + nv_wr32(priv, 0x06000c, | |
| 56 | + upper_32_bits(chan->vblank.offset)); | |
| 57 | + nv_wr32(priv, 0x060010, | |
| 58 | + lower_32_bits(chan->vblank.offset)); | |
| 59 | + nv_wr32(priv, 0x060014, chan->vblank.value); | |
| 55 | 60 | } else { |
| 56 | − if (nv_device(priv)->chipset >= 0xc0) { | |
| 57 | − nv_wr32(priv, 0x06000c, | |
| 58 | − upper_32_bits(chan->vblank.offset)); | |
| 61 | + nv_wr32(priv, 0x001704, chan->vblank.channel); | |
| 62 | + nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma); | |
| 63 | + bar->flush(bar); | |
| 64 | + if (nv_device(priv)->chipset == 0x50) { | |
| 65 | + nv_wr32(priv, 0x001570, chan->vblank.offset); | |
| 66 | + nv_wr32(priv, 0x001574, chan->vblank.value); | |
| 67 | + } else { | |
| 68 | + nv_wr32(priv, 0x060010, chan->vblank.offset); | |
| 69 | + nv_wr32(priv, 0x060014, chan->vblank.value); | |
| 59 | 70 | } |
| 60 | − nv_wr32(priv, 0x060010, chan->vblank.offset); | |
| 61 | − nv_wr32(priv, 0x060014, chan->vblank.value); | |
| 62 | 71 | } |
| 63 | 72 | |
| 64 | 73 | list_del(&chan->vblank.head); |
| @@ -669,21 +669,27 @@ nv40_grctx_fill(struct nouveau_device *device, struct nouveau_gpuobj *mem) · 668 unmodified lines | ||
| 669 | 669 | }); |
| 670 | 670 | } |
| 671 | 671 | |
| 672 | −void | |
| 672 | +int | |
| 673 | 673 | nv40_grctx_init(struct nouveau_device *device, u32 *size) |
| 674 | 674 | { |
| 675 | − u32 ctxprog[256], i; | |
| 675 | + u32 *ctxprog = kmalloc(256 * 4, GFP_KERNEL), i; | |
| 676 | 676 | struct nouveau_grctx ctx = { |
| 677 | 677 | .device = device, |
| 678 | 678 | .mode = NOUVEAU_GRCTX_PROG, |
| 679 | 679 | .data = ctxprog, |
| 680 | − .ctxprog_max = ARRAY_SIZE(ctxprog) | |
| 680 | + .ctxprog_max = 256, | |
| 681 | 681 | }; |
| 682 | 682 | |
| 683 | + if (!ctxprog) | |
| 684 | + return -ENOMEM; | |
| 685 | + | |
| 683 | 686 | nv40_grctx_generate(&ctx); |
| 684 | 687 | |
| 685 | 688 | nv_wr32(device, 0x400324, 0); |
| 686 | 689 | for (i = 0; i < ctx.ctxprog_len; i++) |
| 687 | 690 | nv_wr32(device, 0x400328, ctxprog[i]); |
| 688 | 691 | *size = ctx.ctxvals_pos * 4; |
| 692 | + | |
| 693 | + kfree(ctxprog); | |
| 694 | + return 0; | |
| 689 | 695 | } |
| @@ -156,8 +156,8 @@ nv40_graph_context_ctor(struct nouveau_object *parent, · 155 unmodified lines | ||
| 156 | 156 | static int |
| 157 | 157 | nv40_graph_context_fini(struct nouveau_object *object, bool suspend) |
| 158 | 158 | { |
| 159 | − struct nv04_graph_priv *priv = (void *)object->engine; | |
| 160 | − struct nv04_graph_chan *chan = (void *)object; | |
| 159 | + struct nv40_graph_priv *priv = (void *)object->engine; | |
| 160 | + struct nv40_graph_chan *chan = (void *)object; | |
| 161 | 161 | u32 inst = 0x01000000 | nv_gpuobj(chan)->addr >> 4; |
| 162 | 162 | int ret = 0; |
| 163 | 163 | |
| @@ -346,7 +346,9 @@ nv40_graph_init(struct nouveau_object *object) · 182 unmodified lines | ||
| 346 | 346 | return ret; |
| 347 | 347 | |
| 348 | 348 | /* generate and upload context program */ |
| 349 | − nv40_grctx_init(nv_device(priv), &priv->size); | |
| 349 | + ret = nv40_grctx_init(nv_device(priv), &priv->size); | |
| 350 | + if (ret) | |
| 351 | + return ret; | |
| 350 | 352 | |
| 351 | 353 | /* No context present currently */ |
| 352 | 354 | nv_wr32(priv, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); |
| @@ -15,7 +15,7 @@ nv44_graph_class(void *priv) · 14 unmodified lines | ||
| 15 | 15 | return !(0x0baf & (1 << (device->chipset & 0x0f))); |
| 16 | 16 | } |
| 17 | 17 | |
| 18 | −void nv40_grctx_init(struct nouveau_device *, u32 *size); | |
| 18 | +int nv40_grctx_init(struct nouveau_device *, u32 *size); | |
| 19 | 19 | void nv40_grctx_fill(struct nouveau_device *, struct nouveau_gpuobj *); |
| 20 | 20 | |
| 21 | 21 | #endif |
| @@ -38,7 +38,7 @@ struct nv40_mpeg_priv { · 37 unmodified lines | ||
| 38 | 38 | }; |
| 39 | 39 | |
| 40 | 40 | struct nv40_mpeg_chan { |
| 41 | − struct nouveau_mpeg base; | |
| 41 | + struct nouveau_mpeg_chan base; | |
| 42 | 42 | }; |
| 43 | 43 | |
| 44 | 44 | /******************************************************************************* |
| @@ -19,7 +19,6 @@ struct nouveau_mm { · 18 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | u32 block_size; |
| 21 | 21 | int heap_nodes; |
| 22 | − u32 heap_size; | |
| 23 | 22 | }; |
| 24 | 23 | |
| 25 | 24 | int nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block); |
| @@ -175,14 +175,18 @@ nv_mo32(void *obj, u32 addr, u32 mask, u32 data) · 174 unmodified lines | ||
| 175 | 175 | return temp; |
| 176 | 176 | } |
| 177 | 177 | |
| 178 | −static inline bool | |
| 179 | −nv_strncmp(void *obj, u32 addr, u32 len, const char *str) | |
| 178 | +static inline int | |
| 179 | +nv_memcmp(void *obj, u32 addr, const char *str, u32 len) | |
| 180 | 180 | { |
| 181 | + unsigned char c1, c2; | |
| 182 | + | |
| 181 | 183 | while (len--) { |
| 182 | − if (nv_ro08(obj, addr++) != *(str++)) | |
| 183 | − return false; | |
| 184 | + c1 = nv_ro08(obj, addr++); | |
| 185 | + c2 = *(str++); | |
| 186 | + if (c1 != c2) | |
| 187 | + return c1 - c2; | |
| 184 | 188 | } |
| 185 | − return true; | |
| 189 | + return 0; | |
| 186 | 190 | } |
| 187 | 191 | |
| 188 | 192 | #endif |
| @@ -54,6 +54,7 @@ int nv04_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *, · 53 unmodified lines | ||
| 54 | 54 | int clk, struct nouveau_pll_vals *); |
| 55 | 55 | int nv04_clock_pll_prog(struct nouveau_clock *, u32 reg1, |
| 56 | 56 | struct nouveau_pll_vals *); |
| 57 | − | |
| 57 | +int nva3_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *, | |
| 58 | + int clk, struct nouveau_pll_vals *); | |
| 58 | 59 | |
| 59 | 60 | #endif |
| @@ -64,7 +64,7 @@ dcb_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) · 63 unmodified lines | ||
| 64 | 64 | } |
| 65 | 65 | } else |
| 66 | 66 | if (*ver >= 0x15) { |
| 67 | − if (!nv_strncmp(bios, dcb - 7, 7, "DEV_REC")) { | |
| 67 | + if (!nv_memcmp(bios, dcb - 7, "DEV_REC", 7)) { | |
| 68 | 68 | u16 i2c = nv_ro16(bios, dcb + 2); |
| 69 | 69 | *hdr = 4; |
| 70 | 70 | *cnt = (i2c - dcb) / 10; |
| @@ -66,6 +66,24 @@ nva3_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq) · 65 unmodified lines | ||
| 66 | 66 | return ret; |
| 67 | 67 | } |
| 68 | 68 | |
| 69 | +int | |
| 70 | +nva3_clock_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info, | |
| 71 | + int clk, struct nouveau_pll_vals *pv) | |
| 72 | +{ | |
| 73 | + int ret, N, M, P; | |
| 74 | + | |
| 75 | + ret = nva3_pll_calc(clock, info, clk, &N, NULL, &M, &P); | |
| 76 | + | |
| 77 | + if (ret > 0) { | |
| 78 | + pv->refclk = info->refclk; | |
| 79 | + pv->N1 = N; | |
| 80 | + pv->M1 = M; | |
| 81 | + pv->log2P = P; | |
| 82 | + } | |
| 83 | + return ret; | |
| 84 | +} | |
| 85 | + | |
| 86 | + | |
| 69 | 87 | static int |
| 70 | 88 | nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, |
| 71 | 89 | struct nouveau_oclass *oclass, void *data, u32 size, |
| @@ -80,6 +98,7 @@ nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, · 8 unmodified lines | ||
| 80 | 98 | return ret; |
| 81 | 99 | |
| 82 | 100 | priv->base.pll_set = nva3_clock_pll_set; |
| 101 | + priv->base.pll_calc = nva3_clock_pll_calc; | |
| 83 | 102 | return 0; |
| 84 | 103 | } |
| 85 | 104 | |
| @@ -79,6 +79,7 @@ nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, · 78 unmodified lines | ||
| 79 | 79 | return ret; |
| 80 | 80 | |
| 81 | 81 | priv->base.pll_set = nvc0_clock_pll_set; |
| 82 | + priv->base.pll_calc = nva3_clock_pll_calc; | |
| 82 | 83 | return 0; |
| 83 | 84 | } |
| 84 | 85 | |
| @@ -219,13 +219,11 @@ nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, · 218 unmodified lines | ||
| 219 | 219 | ((priv->base.ram.size & 0x000000ff) << 32); |
| 220 | 220 | |
| 221 | 221 | tags = nv_rd32(priv, 0x100320); |
| 222 | − if (tags) { | |
| 223 | − ret = nouveau_mm_init(&priv->base.tags, 0, tags, 1); | |
| 224 | − if (ret) | |
| 225 | − return ret; | |
| 222 | + ret = nouveau_mm_init(&priv->base.tags, 0, tags, 1); | |
| 223 | + if (ret) | |
| 224 | + return ret; | |
| 226 | 225 | |
| 227 | − nv_debug(priv, "%d compression tags\n", tags); | |
| 228 | − } | |
| 226 | + nv_debug(priv, "%d compression tags\n", tags); | |
| 229 | 227 | |
| 230 | 228 | size = (priv->base.ram.size >> 12) - rsvd_head - rsvd_tail; |
| 231 | 229 | switch (device->chipset) { |
| @@ -292,7 +292,7 @@ nouveau_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine, · 291 unmodified lines | ||
| 292 | 292 | case DCB_I2C_NVIO_BIT: |
| 293 | 293 | port->drive = info.drive & 0x0f; |
| 294 | 294 | if (device->card_type < NV_D0) { |
| 295 | − if (info.drive >= ARRAY_SIZE(nv50_i2c_port)) | |
| 295 | + if (port->drive >= ARRAY_SIZE(nv50_i2c_port)) | |
| 296 | 296 | break; |
| 297 | 297 | port->drive = nv50_i2c_port[port->drive]; |
| 298 | 298 | port->sense = port->drive; |
| @@ -67,7 +67,7 @@ nv41_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt) · 66 unmodified lines | ||
| 67 | 67 | static void |
| 68 | 68 | nv41_vm_flush(struct nouveau_vm *vm) |
| 69 | 69 | { |
| 70 | − struct nv04_vm_priv *priv = (void *)vm->vmm; | |
| 70 | + struct nv04_vmmgr_priv *priv = (void *)vm->vmm; | |
| 71 | 71 | |
| 72 | 72 | mutex_lock(&nv_subdev(priv)->mutex); |
| 73 | 73 | nv_wr32(priv, 0x100810, 0x00000022); |
| @@ -241,6 +241,10 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) · 240 unmodified lines | ||
| 241 | 241 | |
| 242 | 242 | if (unlikely(!abi16)) |
| 243 | 243 | return -ENOMEM; |
| 244 | + | |
| 245 | + if (!drm->channel) | |
| 246 | + return nouveau_abi16_put(abi16, -ENODEV); | |
| 247 | + | |
| 244 | 248 | client = nv_client(abi16->client); |
| 245 | 249 | |
| 246 | 250 | if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) |
| @@ -355,7 +355,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector, bool force) · 354 unmodified lines | ||
| 355 | 355 | * valid - it's not (rh#613284) |
| 356 | 356 | */ |
| 357 | 357 | if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) { |
| 358 | − if (!(nv_connector->edid = nouveau_acpi_edid(dev, connector))) { | |
| 358 | + if ((nv_connector->edid = nouveau_acpi_edid(dev, connector))) { | |
| 359 | 359 | status = connector_status_connected; |
| 360 | 360 | goto out; |
| 361 | 361 | } |
| @@ -290,6 +290,7 @@ nouveau_display_create(struct drm_device *dev) · 289 unmodified lines | ||
| 290 | 290 | struct nouveau_drm *drm = nouveau_drm(dev); |
| 291 | 291 | struct nouveau_disp *pdisp = nouveau_disp(drm->device); |
| 292 | 292 | struct nouveau_display *disp; |
| 293 | + u32 pclass = dev->pdev->class >> 8; | |
| 293 | 294 | int ret, gen; |
| 294 | 295 | |
| 295 | 296 | disp = drm->display = kzalloc(sizeof(*disp), GFP_KERNEL); |
| @@ -360,23 +361,27 @@ nouveau_display_create(struct drm_device *dev) · 64 unmodified lines | ||
| 360 | 361 | drm_kms_helper_poll_init(dev); |
| 361 | 362 | drm_kms_helper_poll_disable(dev); |
| 362 | 363 | |
| 363 | − if (nv_device(drm->device)->card_type < NV_50) | |
| 364 | − ret = nv04_display_create(dev); | |
| 365 | − else | |
| 366 | − if (nv_device(drm->device)->card_type < NV_D0) | |
| 367 | − ret = nv50_display_create(dev); | |
| 368 | − else | |
| 369 | − ret = nvd0_display_create(dev); | |
| 370 | − if (ret) | |
| 371 | − goto disp_create_err; | |
| 372 | − | |
| 373 | − if (dev->mode_config.num_crtc) { | |
| 374 | − ret = drm_vblank_init(dev, dev->mode_config.num_crtc); | |
| 364 | + if (nouveau_modeset == 1 || | |
| 365 | + (nouveau_modeset < 0 && pclass == PCI_CLASS_DISPLAY_VGA)) { | |
| 366 | + if (nv_device(drm->device)->card_type < NV_50) | |
| 367 | + ret = nv04_display_create(dev); | |
| 368 | + else | |
| 369 | + if (nv_device(drm->device)->card_type < NV_D0) | |
| 370 | + ret = nv50_display_create(dev); | |
| 371 | + else | |
| 372 | + ret = nvd0_display_create(dev); | |
| 375 | 373 | if (ret) |
| 376 | − goto vblank_err; | |
| 374 | + goto disp_create_err; | |
| 375 | + | |
| 376 | + if (dev->mode_config.num_crtc) { | |
| 377 | + ret = drm_vblank_init(dev, dev->mode_config.num_crtc); | |
| 378 | + if (ret) | |
| 379 | + goto vblank_err; | |
| 380 | + } | |
| 381 | + | |
| 382 | + nouveau_backlight_init(dev); | |
| 377 | 383 | } |
| 378 | 384 | |
| 379 | − nouveau_backlight_init(dev); | |
| 380 | 385 | return 0; |
| 381 | 386 | |
| 382 | 387 | vblank_err: |
| @@ -395,7 +400,8 @@ nouveau_display_destroy(struct drm_device *dev) · 12 unmodified lines | ||
| 395 | 400 | nouveau_backlight_exit(dev); |
| 396 | 401 | drm_vblank_cleanup(dev); |
| 397 | 402 | |
| 398 | − disp->dtor(dev); | |
| 403 | + if (disp->dtor) | |
| 404 | + disp->dtor(dev); | |
| 399 | 405 | |
| 400 | 406 | drm_kms_helper_poll_fini(dev); |
| 401 | 407 | drm_mode_config_cleanup(dev); |
| @@ -63,8 +63,9 @@ MODULE_PARM_DESC(noaccel, "disable kernel/abi16 acceleration"); · 62 unmodified lines | ||
| 63 | 63 | static int nouveau_noaccel = 0; |
| 64 | 64 | module_param_named(noaccel, nouveau_noaccel, int, 0400); |
| 65 | 65 | |
| 66 | −MODULE_PARM_DESC(modeset, "enable driver"); | |
| 67 | −static int nouveau_modeset = -1; | |
| 66 | +MODULE_PARM_DESC(modeset, "enable driver (default: auto, " | |
| 67 | + "0 = disabled, 1 = enabled, 2 = headless)"); | |
| 68 | +int nouveau_modeset = -1; | |
| 68 | 69 | module_param_named(modeset, nouveau_modeset, int, 0400); |
| 69 | 70 | |
| 70 | 71 | static struct drm_driver driver; |
| @@ -128,7 +129,8 @@ nouveau_accel_init(struct nouveau_drm *drm) · 57 unmodified lines | ||
| 128 | 129 | |
| 129 | 130 | /* initialise synchronisation routines */ |
| 130 | 131 | if (device->card_type < NV_10) ret = nv04_fence_create(drm); |
| 131 | − else if (device->chipset < 0x84) ret = nv10_fence_create(drm); | |
| 132 | + else if (device->card_type < NV_50) ret = nv10_fence_create(drm); | |
| 133 | + else if (device->chipset < 0x84) ret = nv50_fence_create(drm); | |
| 132 | 134 | else if (device->card_type < NV_C0) ret = nv84_fence_create(drm); |
| 133 | 135 | else ret = nvc0_fence_create(drm); |
| 134 | 136 | if (ret) { |
| @@ -363,7 +365,8 @@ nouveau_drm_unload(struct drm_device *dev) · 228 unmodified lines | ||
| 363 | 365 | |
| 364 | 366 | nouveau_pm_fini(dev); |
| 365 | 367 | |
| 366 | − nouveau_display_fini(dev); | |
| 368 | + if (dev->mode_config.num_crtc) | |
| 369 | + nouveau_display_fini(dev); | |
| 367 | 370 | nouveau_display_destroy(dev); |
| 368 | 371 | |
| 369 | 372 | nouveau_irq_fini(dev); |
| @@ -403,13 +406,15 @@ nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state) · 33 unmodified lines | ||
| 403 | 406 | pm_state.event == PM_EVENT_PRETHAW) |
| 404 | 407 | return 0; |
| 405 | 408 | |
| 406 | − NV_INFO(drm, "suspending fbcon...\n"); | |
| 407 | − nouveau_fbcon_set_suspend(dev, 1); | |
| 409 | + if (dev->mode_config.num_crtc) { | |
| 410 | + NV_INFO(drm, "suspending fbcon...\n"); | |
| 411 | + nouveau_fbcon_set_suspend(dev, 1); | |
| 408 | 412 | |
| 409 | − NV_INFO(drm, "suspending display...\n"); | |
| 410 | − ret = nouveau_display_suspend(dev); | |
| 411 | − if (ret) | |
| 412 | − return ret; | |
| 413 | + NV_INFO(drm, "suspending display...\n"); | |
| 414 | + ret = nouveau_display_suspend(dev); | |
| 415 | + if (ret) | |
| 416 | + return ret; | |
| 417 | + } | |
| 413 | 418 | |
| 414 | 419 | NV_INFO(drm, "evicting buffers...\n"); |
| 415 | 420 | ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM); |
| @@ -445,8 +450,10 @@ fail_client: · 29 unmodified lines | ||
| 445 | 450 | nouveau_client_init(&cli->base); |
| 446 | 451 | } |
| 447 | 452 | |
| 448 | − NV_INFO(drm, "resuming display...\n"); | |
| 449 | − nouveau_display_resume(dev); | |
| 453 | + if (dev->mode_config.num_crtc) { | |
| 454 | + NV_INFO(drm, "resuming display...\n"); | |
| 455 | + nouveau_display_resume(dev); | |
| 456 | + } | |
| 450 | 457 | return ret; |
| 451 | 458 | } |
| 452 | 459 | |
| @@ -486,8 +493,10 @@ nouveau_drm_resume(struct pci_dev *pdev) · 33 unmodified lines | ||
| 486 | 493 | nouveau_irq_postinstall(dev); |
| 487 | 494 | nouveau_pm_resume(dev); |
| 488 | 495 | |
| 489 | − NV_INFO(drm, "resuming display...\n"); | |
| 490 | − nouveau_display_resume(dev); | |
| 496 | + if (dev->mode_config.num_crtc) { | |
| 497 | + NV_INFO(drm, "resuming display...\n"); | |
| 498 | + nouveau_display_resume(dev); | |
| 499 | + } | |
| 491 | 500 | return 0; |
| 492 | 501 | } |
| 493 | 502 | |
| @@ -662,9 +671,7 @@ nouveau_drm_init(void) · 168 unmodified lines | ||
| 662 | 671 | #ifdef CONFIG_VGA_CONSOLE |
| 663 | 672 | if (vgacon_text_force()) |
| 664 | 673 | nouveau_modeset = 0; |
| 665 | − else | |
| 666 | 674 | #endif |
| 667 | − nouveau_modeset = 1; | |
| 668 | 675 | } |
| 669 | 676 | |
| 670 | 677 | if (!nouveau_modeset) |
| @@ -141,4 +141,6 @@ int nouveau_drm_resume(struct pci_dev *); · 140 unmodified lines | ||
| 141 | 141 | nv_info((cli), fmt, ##args); \ |
| 142 | 142 | } while (0) |
| 143 | 143 | |
| 144 | +extern int nouveau_modeset; | |
| 145 | + | |
| 144 | 146 | #endif |
| @@ -61,13 +61,15 @@ nouveau_irq_handler(DRM_IRQ_ARGS) · 60 unmodified lines | ||
| 61 | 61 | |
| 62 | 62 | nv_subdev(pmc)->intr(nv_subdev(pmc)); |
| 63 | 63 | |
| 64 | − if (device->card_type >= NV_D0) { | |
| 65 | − if (nv_rd32(device, 0x000100) & 0x04000000) | |
| 66 | − nvd0_display_intr(dev); | |
| 67 | − } else | |
| 68 | − if (device->card_type >= NV_50) { | |
| 69 | − if (nv_rd32(device, 0x000100) & 0x04000000) | |
| 70 | − nv50_display_intr(dev); | |
| 64 | + if (dev->mode_config.num_crtc) { | |
| 65 | + if (device->card_type >= NV_D0) { | |
| 66 | + if (nv_rd32(device, 0x000100) & 0x04000000) | |
| 67 | + nvd0_display_intr(dev); | |
| 68 | + } else | |
| 69 | + if (device->card_type >= NV_50) { | |
| 70 | + if (nv_rd32(device, 0x000100) & 0x04000000) | |
| 71 | + nv50_display_intr(dev); | |
| 72 | + } | |
| 71 | 73 | } |
| 72 | 74 | |
| 73 | 75 | return IRQ_HANDLED; |
| @@ -220,7 +220,7 @@ out: · 219 unmodified lines | ||
| 220 | 220 | NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode); |
| 221 | 221 | |
| 222 | 222 | if (blue == 0x18) { |
| 223 | − NV_INFO(drm, "Load detected on head A\n"); | |
| 223 | + NV_DEBUG(drm, "Load detected on head A\n"); | |
| 224 | 224 | return connector_status_connected; |
| 225 | 225 | } |
| 226 | 226 | |
| @@ -338,8 +338,8 @@ nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) · 111 unmodified lines | ||
| 338 | 338 | |
| 339 | 339 | if (nv17_dac_sample_load(encoder) & |
| 340 | 340 | NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) { |
| 341 | − NV_INFO(drm, "Load detected on output %c\n", | |
| 342 | − '@' + ffs(dcb->or)); | |
| 341 | + NV_DEBUG(drm, "Load detected on output %c\n", | |
| 342 | + '@' + ffs(dcb->or)); | |
| 343 | 343 | return connector_status_connected; |
| 344 | 344 | } else { |
| 345 | 345 | return connector_status_disconnected; |
| @@ -413,9 +413,9 @@ static void nv04_dac_commit(struct drm_encoder *encoder) · 67 unmodified lines | ||
| 413 | 413 | |
| 414 | 414 | helper->dpms(encoder, DRM_MODE_DPMS_ON); |
| 415 | 415 | |
| 416 | − NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n", | |
| 417 | − drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), | |
| 418 | − nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); | |
| 416 | + NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n", | |
| 417 | + drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), | |
| 418 | + nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); | |
| 419 | 419 | } |
| 420 | 420 | |
| 421 | 421 | void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable) |
| @@ -461,8 +461,8 @@ static void nv04_dac_dpms(struct drm_encoder *encoder, int mode) · 39 unmodified lines | ||
| 461 | 461 | return; |
| 462 | 462 | nv_encoder->last_dpms = mode; |
| 463 | 463 | |
| 464 | − NV_INFO(drm, "Setting dpms mode %d on vga encoder (output %d)\n", | |
| 465 | − mode, nv_encoder->dcb->index); | |
| 464 | + NV_DEBUG(drm, "Setting dpms mode %d on vga encoder (output %d)\n", | |
| 465 | + mode, nv_encoder->dcb->index); | |
| 466 | 466 | |
| 467 | 467 | nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON); |
| 468 | 468 | } |
| @@ -476,9 +476,9 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) · 475 unmodified lines | ||
| 476 | 476 | |
| 477 | 477 | helper->dpms(encoder, DRM_MODE_DPMS_ON); |
| 478 | 478 | |
| 479 | − NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n", | |
| 480 | − drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), | |
| 481 | − nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); | |
| 479 | + NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n", | |
| 480 | + drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), | |
| 481 | + nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); | |
| 482 | 482 | } |
| 483 | 483 | |
| 484 | 484 | static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode) |
| @@ -520,8 +520,8 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) · 35 unmodified lines | ||
| 520 | 520 | return; |
| 521 | 521 | nv_encoder->last_dpms = mode; |
| 522 | 522 | |
| 523 | − NV_INFO(drm, "Setting dpms mode %d on lvds encoder (output %d)\n", | |
| 524 | − mode, nv_encoder->dcb->index); | |
| 523 | + NV_DEBUG(drm, "Setting dpms mode %d on lvds encoder (output %d)\n", | |
| 524 | + mode, nv_encoder->dcb->index); | |
| 525 | 525 | |
| 526 | 526 | if (was_powersaving && is_powersaving_dpms(mode)) |
| 527 | 527 | return; |
| @@ -565,8 +565,8 @@ static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode) · 37 unmodified lines | ||
| 565 | 565 | return; |
| 566 | 566 | nv_encoder->last_dpms = mode; |
| 567 | 567 | |
| 568 | − NV_INFO(drm, "Setting dpms mode %d on tmds encoder (output %d)\n", | |
| 569 | − mode, nv_encoder->dcb->index); | |
| 568 | + NV_DEBUG(drm, "Setting dpms mode %d on tmds encoder (output %d)\n", | |
| 569 | + mode, nv_encoder->dcb->index); | |
| 570 | 570 | |
| 571 | 571 | nv04_dfp_update_backlight(encoder, mode); |
| 572 | 572 | nv04_dfp_update_fp_control(encoder, mode); |
| @@ -75,8 +75,8 @@ static void nv04_tv_dpms(struct drm_encoder *encoder, int mode) · 74 unmodified lines | ||
| 75 | 75 | struct nv04_mode_state *state = &nv04_display(dev)->mode_reg; |
| 76 | 76 | uint8_t crtc1A; |
| 77 | 77 | |
| 78 | − NV_INFO(drm, "Setting dpms mode %d on TV encoder (output %d)\n", | |
| 79 | − mode, nv_encoder->dcb->index); | |
| 78 | + NV_DEBUG(drm, "Setting dpms mode %d on TV encoder (output %d)\n", | |
| 79 | + mode, nv_encoder->dcb->index); | |
| 80 | 80 | |
| 81 | 81 | state->pllsel &= ~(PLLSEL_TV_CRTC1_MASK | PLLSEL_TV_CRTC2_MASK); |
| 82 | 82 | |
| @@ -167,9 +167,8 @@ static void nv04_tv_commit(struct drm_encoder *encoder) · 84 unmodified lines | ||
| 167 | 167 | |
| 168 | 168 | helper->dpms(encoder, DRM_MODE_DPMS_ON); |
| 169 | 169 | |
| 170 | − NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n", | |
| 171 | − drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index, | |
| 172 | − '@' + ffs(nv_encoder->dcb->or)); | |
| 170 | + NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n", | |
| 171 | + drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); | |
| 173 | 172 | } |
| 174 | 173 | |
| 175 | 174 | static void nv04_tv_destroy(struct drm_encoder *encoder) |
| @@ -1697,34 +1697,22 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) · 1696 unmodified lines | ||
| 1697 | 1697 | DRM_ERROR("unable to allocate a PPLL\n"); |
| 1698 | 1698 | return ATOM_PPLL_INVALID; |
| 1699 | 1699 | } else { |
| 1700 | − if (ASIC_IS_AVIVO(rdev)) { | |
| 1701 | − /* in DP mode, the DP ref clock can come from either PPLL | |
| 1702 | − * depending on the asic: | |
| 1703 | − * DCE3: PPLL1 or PPLL2 | |
| 1704 | − */ | |
| 1705 | − if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) { | |
| 1706 | − /* use the same PPLL for all DP monitors */ | |
| 1707 | − pll = radeon_get_shared_dp_ppll(crtc); | |
| 1708 | − if (pll != ATOM_PPLL_INVALID) | |
| 1709 | − return pll; | |
| 1710 | − } else { | |
| 1711 | − /* use the same PPLL for all monitors with the same clock */ | |
| 1712 | − pll = radeon_get_shared_nondp_ppll(crtc); | |
| 1713 | − if (pll != ATOM_PPLL_INVALID) | |
| 1714 | − return pll; | |
| 1715 | − } | |
| 1716 | − /* all other cases */ | |
| 1717 | − pll_in_use = radeon_get_pll_use_mask(crtc); | |
| 1718 | − if (!(pll_in_use & (1 << ATOM_PPLL1))) | |
| 1719 | − return ATOM_PPLL1; | |
| 1720 | − if (!(pll_in_use & (1 << ATOM_PPLL2))) | |
| 1721 | − return ATOM_PPLL2; | |
| 1722 | − DRM_ERROR("unable to allocate a PPLL\n"); | |
| 1723 | − return ATOM_PPLL_INVALID; | |
| 1724 | − } else { | |
| 1725 | − /* on pre-R5xx asics, the crtc to pll mapping is hardcoded */ | |
| 1726 | − return radeon_crtc->crtc_id; | |
| 1727 | − } | |
| 1700 | + /* on pre-R5xx asics, the crtc to pll mapping is hardcoded */ | |
| 1701 | + /* some atombios (observed in some DCE2/DCE3) code have a bug, | |
| 1702 | + * the matching btw pll and crtc is done through | |
| 1703 | + * PCLK_CRTC[1|2]_CNTL (0x480/0x484) but atombios code use the | |
| 1704 | + * pll (1 or 2) to select which register to write. ie if using | |
| 1705 | + * pll1 it will use PCLK_CRTC1_CNTL (0x480) and if using pll2 | |
| 1706 | + * it will use PCLK_CRTC2_CNTL (0x484), it then use crtc id to | |
| 1707 | + * choose which value to write. Which is reverse order from | |
| 1708 | + * register logic. So only case that works is when pllid is | |
| 1709 | + * same as crtcid or when both pll and crtc are enabled and | |
| 1710 | + * both use same clock. | |
| 1711 | + * | |
| 1712 | + * So just return crtc id as if crtc and pll were hard linked | |
| 1713 | + * together even if they aren't | |
| 1714 | + */ | |
| 1715 | + return radeon_crtc->crtc_id; | |
| 1728 | 1716 | } |
| 1729 | 1717 | } |
| 1730 | 1718 | |
| @@ -184,6 +184,7 @@ void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder, · 183 unmodified lines | ||
| 184 | 184 | struct radeon_backlight_privdata *pdata; |
| 185 | 185 | struct radeon_encoder_atom_dig *dig; |
| 186 | 186 | u8 backlight_level; |
| 187 | + char bl_name[16]; | |
| 187 | 188 | |
| 188 | 189 | if (!radeon_encoder->enc_priv) |
| 189 | 190 | return; |
| @@ -203,7 +204,9 @@ void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder, · 13 unmodified lines | ||
| 203 | 204 | memset(&props, 0, sizeof(props)); |
| 204 | 205 | props.max_brightness = RADEON_MAX_BL_LEVEL; |
| 205 | 206 | props.type = BACKLIGHT_RAW; |
| 206 | − bd = backlight_device_register("radeon_bl", &drm_connector->kdev, | |
| 207 | + snprintf(bl_name, sizeof(bl_name), | |
| 208 | + "radeon_bl%d", dev->primary->index); | |
| 209 | + bd = backlight_device_register(bl_name, &drm_connector->kdev, | |
| 207 | 210 | pdata, &radeon_atom_backlight_ops, &props); |
| 208 | 211 | if (IS_ERR(bd)) { |
| 209 | 212 | DRM_ERROR("Backlight registration failed\n"); |
| @@ -1622,7 +1625,7 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) · 1412 unmodified lines | ||
| 1622 | 1625 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); |
| 1623 | 1626 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); |
| 1624 | 1627 | /* some early dce3.2 boards have a bug in their transmitter control table */ |
| 1625 | − if ((rdev->family != CHIP_RV710) || (rdev->family != CHIP_RV730)) | |
| 1628 | + if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730)) | |
| 1626 | 1629 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); |
| 1627 | 1630 | } |
| 1628 | 1631 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { |
| @@ -1330,6 +1330,8 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav · 1329 unmodified lines | ||
| 1330 | 1330 | break; |
| 1331 | 1331 | udelay(1); |
| 1332 | 1332 | } |
| 1333 | + } else { | |
| 1334 | + save->crtc_enabled[i] = false; | |
| 1333 | 1335 | } |
| 1334 | 1336 | } |
| 1335 | 1337 | |
| @@ -1372,7 +1374,7 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s · 36 unmodified lines | ||
| 1372 | 1374 | WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN); |
| 1373 | 1375 | |
| 1374 | 1376 | for (i = 0; i < rdev->num_crtc; i++) { |
| 1375 | − if (save->crtc_enabled) { | |
| 1377 | + if (save->crtc_enabled[i]) { | |
| 1376 | 1378 | if (ASIC_IS_DCE6(rdev)) { |
| 1377 | 1379 | tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]); |
| 1378 | 1380 | tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; |
| @@ -264,7 +264,7 @@ static int evergreen_surface_check_2d(struct radeon_cs_parser *p, · 263 unmodified lines | ||
| 264 | 264 | /* macro tile width & height */ |
| 265 | 265 | palign = (8 * surf->bankw * track->npipes) * surf->mtilea; |
| 266 | 266 | halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea; |
| 267 | − mtileb = (palign / 8) * (halign / 8) * tileb;; | |
| 267 | + mtileb = (palign / 8) * (halign / 8) * tileb; | |
| 268 | 268 | mtile_pr = surf->nbx / palign; |
| 269 | 269 | mtile_ps = (mtile_pr * surf->nby) / halign; |
| 270 | 270 | surf->layer_size = mtile_ps * mtileb * slice_pt; |
| @@ -2725,6 +2725,9 @@ static bool evergreen_vm_reg_valid(u32 reg) · 2454 unmodified lines | ||
| 2725 | 2725 | /* check config regs */ |
| 2726 | 2726 | switch (reg) { |
| 2727 | 2727 | case GRBM_GFX_INDEX: |
| 2728 | + case CP_STRMOUT_CNTL: | |
| 2729 | + case CP_COHER_CNTL: | |
| 2730 | + case CP_COHER_SIZE: | |
| 2728 | 2731 | case VGT_VTX_VECT_EJECT_REG: |
| 2729 | 2732 | case VGT_CACHE_INVALIDATION: |
| 2730 | 2733 | case VGT_GS_VERTEX_REUSE: |
| @@ -2829,6 +2832,7 @@ static bool evergreen_vm_reg_valid(u32 reg) · 98 unmodified lines | ||
| 2829 | 2832 | case CAYMAN_SQ_EX_ALLOC_TABLE_SLOTS: |
| 2830 | 2833 | return true; |
| 2831 | 2834 | default: |
| 2835 | + DRM_ERROR("Invalid register 0x%x in CS\n", reg); | |
| 2832 | 2836 | return false; |
| 2833 | 2837 | } |
| 2834 | 2838 | } |
| @@ -91,6 +91,10 @@ · 90 unmodified lines | ||
| 91 | 91 | #define FB_READ_EN (1 << 0) |
| 92 | 92 | #define FB_WRITE_EN (1 << 1) |
| 93 | 93 | |
| 94 | +#define CP_STRMOUT_CNTL 0x84FC | |
| 95 | + | |
| 96 | +#define CP_COHER_CNTL 0x85F0 | |
| 97 | +#define CP_COHER_SIZE 0x85F4 | |
| 94 | 98 | #define CP_COHER_BASE 0x85F8 |
| 95 | 99 | #define CP_STALLED_STAT1 0x8674 |
| 96 | 100 | #define CP_STALLED_STAT2 0x8678 |
| @@ -1538,26 +1538,31 @@ void cayman_vm_set_page(struct radeon_device *rdev, uint64_t pe, · 1537 unmodified lines | ||
| 1538 | 1538 | { |
| 1539 | 1539 | struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index]; |
| 1540 | 1540 | uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); |
| 1541 | − int i; | |
| 1542 | 1541 | |
| 1543 | − radeon_ring_write(ring, PACKET3(PACKET3_ME_WRITE, 1 + count * 2)); | |
| 1544 | − radeon_ring_write(ring, pe); | |
| 1545 | − radeon_ring_write(ring, upper_32_bits(pe) & 0xff); | |
| 1546 | − for (i = 0; i < count; ++i) { | |
| 1547 | − uint64_t value = 0; | |
| 1548 | − if (flags & RADEON_VM_PAGE_SYSTEM) { | |
| 1549 | − value = radeon_vm_map_gart(rdev, addr); | |
| 1550 | − value &= 0xFFFFFFFFFFFFF000ULL; | |
| 1551 | − addr += incr; | |
| 1552 | − | |
| 1553 | − } else if (flags & RADEON_VM_PAGE_VALID) { | |
| 1554 | − value = addr; | |
| 1555 | − addr += incr; | |
| 1556 | − } | |
| 1542 | + while (count) { | |
| 1543 | + unsigned ndw = 1 + count * 2; | |
| 1544 | + if (ndw > 0x3FFF) | |
| 1545 | + ndw = 0x3FFF; | |
| 1546 | + | |
| 1547 | + radeon_ring_write(ring, PACKET3(PACKET3_ME_WRITE, ndw)); | |
| 1548 | + radeon_ring_write(ring, pe); | |
| 1549 | + radeon_ring_write(ring, upper_32_bits(pe) & 0xff); | |
| 1550 | + for (; ndw > 1; ndw -= 2, --count, pe += 8) { | |
| 1551 | + uint64_t value = 0; | |
| 1552 | + if (flags & RADEON_VM_PAGE_SYSTEM) { | |
| 1553 | + value = radeon_vm_map_gart(rdev, addr); | |
| 1554 | + value &= 0xFFFFFFFFFFFFF000ULL; | |
| 1555 | + addr += incr; | |
| 1556 | + | |
| 1557 | + } else if (flags & RADEON_VM_PAGE_VALID) { | |
| 1558 | + value = addr; | |
| 1559 | + addr += incr; | |
| 1560 | + } | |
| 1557 | 1561 | |
| 1558 | − value |= r600_flags; | |
| 1559 | − radeon_ring_write(ring, value); | |
| 1560 | − radeon_ring_write(ring, upper_32_bits(value)); | |
| 1562 | + value |= r600_flags; | |
| 1563 | + radeon_ring_write(ring, value); | |
| 1564 | + radeon_ring_write(ring, upper_32_bits(value)); | |
| 1565 | + } | |
| 1561 | 1566 | } |
| 1562 | 1567 | } |
| 1563 | 1568 | |
| @@ -1586,4 +1591,8 @@ void cayman_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) · 22 unmodified lines | ||
| 1586 | 1591 | /* bits 0-7 are the VM contexts0-7 */ |
| 1587 | 1592 | radeon_ring_write(ring, PACKET0(VM_INVALIDATE_REQUEST, 0)); |
| 1588 | 1593 | radeon_ring_write(ring, 1 << vm->id); |
| 1594 | + | |
| 1595 | + /* sync PFP to ME, otherwise we might get invalid PFP reads */ | |
| 1596 | + radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); | |
| 1597 | + radeon_ring_write(ring, 0x0); | |
| 1589 | 1598 | } |
| @@ -502,6 +502,7 @@ · 501 unmodified lines | ||
| 502 | 502 | #define PACKET3_MPEG_INDEX 0x3A |
| 503 | 503 | #define PACKET3_WAIT_REG_MEM 0x3C |
| 504 | 504 | #define PACKET3_MEM_WRITE 0x3D |
| 505 | +#define PACKET3_PFP_SYNC_ME 0x42 | |
| 505 | 506 | #define PACKET3_SURFACE_SYNC 0x43 |
| 506 | 507 | # define PACKET3_CB0_DEST_BASE_ENA (1 << 6) |
| 507 | 508 | # define PACKET3_CB1_DEST_BASE_ENA (1 << 7) |
| @@ -69,9 +69,12 @@ static struct radeon_agpmode_quirk radeon_agpmode_quirk_list[] = { · 68 unmodified lines | ||
| 69 | 69 | /* Intel 82830 830 Chipset Host Bridge / Mobility M6 LY Needs AGPMode 2 (fdo #17360)*/ |
| 70 | 70 | { PCI_VENDOR_ID_INTEL, 0x3575, PCI_VENDOR_ID_ATI, 0x4c59, |
| 71 | 71 | PCI_VENDOR_ID_DELL, 0x00e3, 2}, |
| 72 | − /* Intel 82852/82855 host bridge / Mobility FireGL 9000 R250 Needs AGPMode 1 (lp #296617) */ | |
| 72 | + /* Intel 82852/82855 host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 (lp #296617) */ | |
| 73 | 73 | { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4c66, |
| 74 | 74 | PCI_VENDOR_ID_DELL, 0x0149, 1}, |
| 75 | + /* Intel 82855PM host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 for suspend/resume */ | |
| 76 | + { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4c66, | |
| 77 | + PCI_VENDOR_ID_IBM, 0x0531, 1}, | |
| 75 | 78 | /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (deb #467460) */ |
| 76 | 79 | { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4e50, |
| 77 | 80 | 0x1025, 0x0061, 1}, |
| @@ -87,7 +87,7 @@ static union acpi_object *radeon_atpx_call(acpi_handle handle, int function, · 86 unmodified lines | ||
| 87 | 87 | atpx_arg_elements[1].integer.value = 0; |
| 88 | 88 | } |
| 89 | 89 | |
| 90 | − status = acpi_evaluate_object(handle, "ATPX", &atpx_arg, &buffer); | |
| 90 | + status = acpi_evaluate_object(handle, NULL, &atpx_arg, &buffer); | |
| 91 | 91 | |
| 92 | 92 | /* Fail only if calling the method fails and ATPX is supported */ |
| 93 | 93 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
| @@ -352,9 +352,9 @@ static int radeon_atpx_switchto(enum vga_switcheroo_client_id id) · 258 unmodified lines | ||
| 352 | 352 | } |
| 353 | 353 | |
| 354 | 354 | /** |
| 355 | − * radeon_atpx_switchto - switch to the requested GPU | |
| 355 | + * radeon_atpx_power_state - power down/up the requested GPU | |
| 356 | 356 | * |
| 357 | − * @id: GPU to switch to | |
| 357 | + * @id: GPU to power down/up | |
| 358 | 358 | * @state: requested power state (0 = off, 1 = on) |
| 359 | 359 | * |
| 360 | 360 | * Execute the necessary ATPX function to power down/up the discrete GPU |
| @@ -373,11 +373,11 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id, · 12 unmodified lines | ||
| 373 | 373 | } |
| 374 | 374 | |
| 375 | 375 | /** |
| 376 | − * radeon_atpx_pci_probe_handle - look up the ATRM and ATPX handles | |
| 376 | + * radeon_atpx_pci_probe_handle - look up the ATPX handle | |
| 377 | 377 | * |
| 378 | 378 | * @pdev: pci device |
| 379 | 379 | * |
| 380 | − * Look up the ATPX and ATRM handles (all asics). | |
| 380 | + * Look up the ATPX handles (all asics). | |
| 381 | 381 | * Returns true if the handles are found, false if not. |
| 382 | 382 | */ |
| 383 | 383 | static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) |
| @@ -941,7 +941,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) · 940 unmodified lines | ||
| 941 | 941 | struct drm_mode_object *obj; |
| 942 | 942 | int i; |
| 943 | 943 | enum drm_connector_status ret = connector_status_disconnected; |
| 944 | − bool dret = false; | |
| 944 | + bool dret = false, broken_edid = false; | |
| 945 | 945 | |
| 946 | 946 | if (!force && radeon_check_hpd_status_unchanged(connector)) |
| 947 | 947 | return connector->status; |
| @@ -965,6 +965,9 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) · 17 unmodified lines | ||
| 965 | 965 | ret = connector_status_disconnected; |
| 966 | 966 | DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector)); |
| 967 | 967 | radeon_connector->ddc_bus = NULL; |
| 968 | + } else { | |
| 969 | + ret = connector_status_connected; | |
| 970 | + broken_edid = true; /* defer use_digital to later */ | |
| 968 | 971 | } |
| 969 | 972 | } else { |
| 970 | 973 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); |
| @@ -1047,13 +1050,24 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) · 76 unmodified lines | ||
| 1047 | 1050 | |
| 1048 | 1051 | encoder_funcs = encoder->helper_private; |
| 1049 | 1052 | if (encoder_funcs->detect) { |
| 1050 | − if (ret != connector_status_connected) { | |
| 1051 | − ret = encoder_funcs->detect(encoder, connector); | |
| 1052 | − if (ret == connector_status_connected) { | |
| 1053 | − radeon_connector->use_digital = false; | |
| 1053 | + if (!broken_edid) { | |
| 1054 | + if (ret != connector_status_connected) { | |
| 1055 | + /* deal with analog monitors without DDC */ | |
| 1056 | + ret = encoder_funcs->detect(encoder, connector); | |
| 1057 | + if (ret == connector_status_connected) { | |
| 1058 | + radeon_connector->use_digital = false; | |
| 1059 | + } | |
| 1060 | + if (ret != connector_status_disconnected) | |
| 1061 | + radeon_connector->detected_by_load = true; | |
| 1054 | 1062 | } |
| 1055 | − if (ret != connector_status_disconnected) | |
| 1056 | − radeon_connector->detected_by_load = true; | |
| 1063 | + } else { | |
| 1064 | + enum drm_connector_status lret; | |
| 1065 | + /* assume digital unless load detected otherwise */ | |
| 1066 | + radeon_connector->use_digital = true; | |
| 1067 | + lret = encoder_funcs->detect(encoder, connector); | |
| 1068 | + DRM_DEBUG_KMS("load_detect %x returned: %x\n",encoder->encoder_type,lret); | |
| 1069 | + if (lret == connector_status_connected) | |
| 1070 | + radeon_connector->use_digital = false; | |
| 1057 | 1071 | } |
| 1058 | 1072 | break; |
| 1059 | 1073 | } |
| @@ -355,6 +355,8 @@ int radeon_wb_init(struct radeon_device *rdev) · 354 unmodified lines | ||
| 355 | 355 | */ |
| 356 | 356 | void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base) |
| 357 | 357 | { |
| 358 | + uint64_t limit = (uint64_t)radeon_vram_limit << 20; | |
| 359 | + | |
| 358 | 360 | mc->vram_start = base; |
| 359 | 361 | if (mc->mc_vram_size > (0xFFFFFFFF - base + 1)) { |
| 360 | 362 | dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); |
| @@ -368,8 +370,8 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 · 7 unmodified lines | ||
| 368 | 370 | mc->mc_vram_size = mc->aper_size; |
| 369 | 371 | } |
| 370 | 372 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; |
| 371 | − if (radeon_vram_limit && radeon_vram_limit < mc->real_vram_size) | |
| 372 | − mc->real_vram_size = radeon_vram_limit; | |
| 373 | + if (limit && limit < mc->real_vram_size) | |
| 374 | + mc->real_vram_size = limit; | |
| 373 | 375 | dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n", |
| 374 | 376 | mc->mc_vram_size >> 20, mc->vram_start, |
| 375 | 377 | mc->vram_end, mc->real_vram_size >> 20); |
| @@ -834,6 +836,19 @@ static unsigned int radeon_vga_set_decode(void *cookie, bool state) · 458 unmodified lines | ||
| 834 | 836 | return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; |
| 835 | 837 | } |
| 836 | 838 | |
| 839 | +/** | |
| 840 | + * radeon_check_pot_argument - check that argument is a power of two | |
| 841 | + * | |
| 842 | + * @arg: value to check | |
| 843 | + * | |
| 844 | + * Validates that a certain argument is a power of two (all asics). | |
| 845 | + * Returns true if argument is valid. | |
| 846 | + */ | |
| 847 | +static bool radeon_check_pot_argument(int arg) | |
| 848 | +{ | |
| 849 | + return (arg & (arg - 1)) == 0; | |
| 850 | +} | |
| 851 | + | |
| 837 | 852 | /** |
| 838 | 853 | * radeon_check_arguments - validate module params |
| 839 | 854 | * |
| @@ -845,52 +860,25 @@ static unsigned int radeon_vga_set_decode(void *cookie, bool state) · 5 unmodified lines | ||
| 845 | 860 | static void radeon_check_arguments(struct radeon_device *rdev) |
| 846 | 861 | { |
| 847 | 862 | /* vramlimit must be a power of two */ |
| 848 | − switch (radeon_vram_limit) { | |
| 849 | − case 0: | |
| 850 | − case 4: | |
| 851 | − case 8: | |
| 852 | − case 16: | |
| 853 | − case 32: | |
| 854 | − case 64: | |
| 855 | − case 128: | |
| 856 | − case 256: | |
| 857 | − case 512: | |
| 858 | − case 1024: | |
| 859 | − case 2048: | |
| 860 | − case 4096: | |
| 861 | − break; | |
| 862 | − default: | |
| 863 | + if (!radeon_check_pot_argument(radeon_vram_limit)) { | |
| 863 | 864 | dev_warn(rdev->dev, "vram limit (%d) must be a power of 2\n", |
| 864 | 865 | radeon_vram_limit); |
| 865 | 866 | radeon_vram_limit = 0; |
| 866 | − break; | |
| 867 | 867 | } |
| 868 | − radeon_vram_limit = radeon_vram_limit << 20; | |
| 868 | + | |
| 869 | 869 | /* gtt size must be power of two and greater or equal to 32M */ |
| 870 | − switch (radeon_gart_size) { | |
| 871 | − case 4: | |
| 872 | − case 8: | |
| 873 | − case 16: | |
| 870 | + if (radeon_gart_size < 32) { | |
| 874 | 871 | dev_warn(rdev->dev, "gart size (%d) too small forcing to 512M\n", |
| 875 | 872 | radeon_gart_size); |
| 876 | 873 | radeon_gart_size = 512; |
| 877 | − break; | |
| 878 | − case 32: | |
| 879 | − case 64: | |
| 880 | − case 128: | |
| 881 | − case 256: | |
| 882 | − case 512: | |
| 883 | − case 1024: | |
| 884 | − case 2048: | |
| 885 | − case 4096: | |
| 886 | − break; | |
| 887 | − default: | |
| 874 | + | |
| 875 | + } else if (!radeon_check_pot_argument(radeon_gart_size)) { | |
| 888 | 876 | dev_warn(rdev->dev, "gart size (%d) must be a power of 2\n", |
| 889 | 877 | radeon_gart_size); |
| 890 | 878 | radeon_gart_size = 512; |
| 891 | − break; | |
| 892 | 879 | } |
| 893 | − rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | |
| 880 | + rdev->mc.gtt_size = (uint64_t)radeon_gart_size << 20; | |
| 881 | + | |
| 894 | 882 | /* AGP mode can only be -1, 1, 2, 4, 8 */ |
| 895 | 883 | switch (radeon_agpmode) { |
| 896 | 884 | case -1: |
| @@ -355,14 +355,13 @@ int radeon_gart_init(struct radeon_device *rdev) · 354 unmodified lines | ||
| 355 | 355 | DRM_INFO("GART: num cpu pages %u, num gpu pages %u\n", |
| 356 | 356 | rdev->gart.num_cpu_pages, rdev->gart.num_gpu_pages); |
| 357 | 357 | /* Allocate pages table */ |
| 358 | − rdev->gart.pages = kzalloc(sizeof(void *) * rdev->gart.num_cpu_pages, | |
| 359 | − GFP_KERNEL); | |
| 358 | + rdev->gart.pages = vzalloc(sizeof(void *) * rdev->gart.num_cpu_pages); | |
| 360 | 359 | if (rdev->gart.pages == NULL) { |
| 361 | 360 | radeon_gart_fini(rdev); |
| 362 | 361 | return -ENOMEM; |
| 363 | 362 | } |
| 364 | − rdev->gart.pages_addr = kzalloc(sizeof(dma_addr_t) * | |
| 365 | − rdev->gart.num_cpu_pages, GFP_KERNEL); | |
| 363 | + rdev->gart.pages_addr = vzalloc(sizeof(dma_addr_t) * | |
| 364 | + rdev->gart.num_cpu_pages); | |
| 366 | 365 | if (rdev->gart.pages_addr == NULL) { |
| 367 | 366 | radeon_gart_fini(rdev); |
| 368 | 367 | return -ENOMEM; |
| @@ -388,8 +387,8 @@ void radeon_gart_fini(struct radeon_device *rdev) · 19 unmodified lines | ||
| 388 | 387 | radeon_gart_unbind(rdev, 0, rdev->gart.num_cpu_pages); |
| 389 | 388 | } |
| 390 | 389 | rdev->gart.ready = false; |
| 391 | − kfree(rdev->gart.pages); | |
| 392 | − kfree(rdev->gart.pages_addr); | |
| 390 | + vfree(rdev->gart.pages); | |
| 391 | + vfree(rdev->gart.pages_addr); | |
| 393 | 392 | rdev->gart.pages = NULL; |
| 394 | 393 | rdev->gart.pages_addr = NULL; |
| 395 | 394 | |
| @@ -577,7 +576,7 @@ void radeon_vm_manager_fini(struct radeon_device *rdev) · 181 unmodified lines | ||
| 577 | 576 | * |
| 578 | 577 | * Global and local mutex must be locked! |
| 579 | 578 | */ |
| 580 | −int radeon_vm_evict(struct radeon_device *rdev, struct radeon_vm *vm) | |
| 579 | +static int radeon_vm_evict(struct radeon_device *rdev, struct radeon_vm *vm) | |
| 581 | 580 | { |
| 582 | 581 | struct radeon_vm *vm_evict; |
| 583 | 582 | |
| @@ -1036,8 +1035,7 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev, · 452 unmodified lines | ||
| 1036 | 1035 | pte = radeon_sa_bo_gpu_addr(vm->page_tables[pt_idx]); |
| 1037 | 1036 | pte += (addr & mask) * 8; |
| 1038 | 1037 | |
| 1039 | − if (((last_pte + 8 * count) != pte) || | |
| 1040 | − ((count + nptes) > 1 << 11)) { | |
| 1038 | + if ((last_pte + 8 * count) != pte) { | |
| 1041 | 1039 | |
| 1042 | 1040 | if (count) { |
| 1043 | 1041 | radeon_asic_vm_set_page(rdev, last_pte, |
| @@ -1148,17 +1146,17 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, · 104 unmodified lines | ||
| 1148 | 1146 | |
| 1149 | 1147 | if (RADEON_VM_BLOCK_SIZE > 11) |
| 1150 | 1148 | /* reserve space for one header for every 2k dwords */ |
| 1151 | − ndw += (nptes >> 11) * 3; | |
| 1149 | + ndw += (nptes >> 11) * 4; | |
| 1152 | 1150 | else |
| 1153 | 1151 | /* reserve space for one header for |
| 1154 | 1152 | every (1 << BLOCK_SIZE) entries */ |
| 1155 | − ndw += (nptes >> RADEON_VM_BLOCK_SIZE) * 3; | |
| 1153 | + ndw += (nptes >> RADEON_VM_BLOCK_SIZE) * 4; | |
| 1156 | 1154 | |
| 1157 | 1155 | /* reserve space for pte addresses */ |
| 1158 | 1156 | ndw += nptes * 2; |
| 1159 | 1157 | |
| 1160 | 1158 | /* reserve space for one header for every 2k dwords */ |
| 1161 | − ndw += (npdes >> 11) * 3; | |
| 1159 | + ndw += (npdes >> 11) * 4; | |
| 1162 | 1160 | |
| 1163 | 1161 | /* reserve space for pde addresses */ |
| 1164 | 1162 | ndw += npdes * 2; |
| @@ -53,6 +53,7 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size, · 52 unmodified lines | ||
| 53 | 53 | struct drm_gem_object **obj) |
| 54 | 54 | { |
| 55 | 55 | struct radeon_bo *robj; |
| 56 | + unsigned long max_size; | |
| 56 | 57 | int r; |
| 57 | 58 | |
| 58 | 59 | *obj = NULL; |
| @@ -60,11 +61,26 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size, · 1 unmodified line | ||
| 60 | 61 | if (alignment < PAGE_SIZE) { |
| 61 | 62 | alignment = PAGE_SIZE; |
| 62 | 63 | } |
| 64 | + | |
| 65 | + /* maximun bo size is the minimun btw visible vram and gtt size */ | |
| 66 | + max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size); | |
| 67 | + if (size > max_size) { | |
| 68 | + printk(KERN_WARNING "%s:%d alloc size %dMb bigger than %ldMb limit\n", | |
| 69 | + __func__, __LINE__, size >> 20, max_size >> 20); | |
| 70 | + return -ENOMEM; | |
| 71 | + } | |
| 72 | + | |
| 73 | +retry: | |
| 63 | 74 | r = radeon_bo_create(rdev, size, alignment, kernel, initial_domain, NULL, &robj); |
| 64 | 75 | if (r) { |
| 65 | − if (r != -ERESTARTSYS) | |
| 76 | + if (r != -ERESTARTSYS) { | |
| 77 | + if (initial_domain == RADEON_GEM_DOMAIN_VRAM) { | |
| 78 | + initial_domain |= RADEON_GEM_DOMAIN_GTT; | |
| 79 | + goto retry; | |
| 80 | + } | |
| 66 | 81 | DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n", |
| 67 | 82 | size, initial_domain, alignment, r); |
| 83 | + } | |
| 68 | 84 | return r; |
| 69 | 85 | } |
| 70 | 86 | *obj = &robj->gem_base; |
| @@ -295,6 +295,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) · 294 unmodified lines | ||
| 295 | 295 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
| 296 | 296 | struct drm_device *dev = crtc->dev; |
| 297 | 297 | struct radeon_device *rdev = dev->dev_private; |
| 298 | + uint32_t crtc_ext_cntl = 0; | |
| 298 | 299 | uint32_t mask; |
| 299 | 300 | |
| 300 | 301 | if (radeon_crtc->crtc_id) |
| @@ -307,6 +308,16 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) · 6 unmodified lines | ||
| 307 | 308 | RADEON_CRTC_VSYNC_DIS | |
| 308 | 309 | RADEON_CRTC_HSYNC_DIS); |
| 309 | 310 | |
| 311 | + /* | |
| 312 | + * On all dual CRTC GPUs this bit controls the CRTC of the primary DAC. | |
| 313 | + * Therefore it is set in the DAC DMPS function. | |
| 314 | + * This is different for GPU's with a single CRTC but a primary and a | |
| 315 | + * TV DAC: here it controls the single CRTC no matter where it is | |
| 316 | + * routed. Therefore we set it here. | |
| 317 | + */ | |
| 318 | + if (rdev->flags & RADEON_SINGLE_CRTC) | |
| 319 | + crtc_ext_cntl = RADEON_CRTC_CRT_ON; | |
| 320 | + | |
| 310 | 321 | switch (mode) { |
| 311 | 322 | case DRM_MODE_DPMS_ON: |
| 312 | 323 | radeon_crtc->enabled = true; |
| @@ -317,7 +328,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) · 4 unmodified lines | ||
| 317 | 328 | else { |
| 318 | 329 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN | |
| 319 | 330 | RADEON_CRTC_DISP_REQ_EN_B)); |
| 320 | − WREG32_P(RADEON_CRTC_EXT_CNTL, 0, ~mask); | |
| 331 | + WREG32_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ~(mask | crtc_ext_cntl)); | |
| 321 | 332 | } |
| 322 | 333 | drm_vblank_post_modeset(dev, radeon_crtc->crtc_id); |
| 323 | 334 | radeon_crtc_load_lut(crtc); |
| @@ -331,7 +342,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) · 7 unmodified lines | ||
| 331 | 342 | else { |
| 332 | 343 | WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN | |
| 333 | 344 | RADEON_CRTC_DISP_REQ_EN_B)); |
| 334 | − WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~mask); | |
| 345 | + WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~(mask | crtc_ext_cntl)); | |
| 335 | 346 | } |
| 336 | 347 | radeon_crtc->enabled = false; |
| 337 | 348 | /* adjust pm to dpms changes AFTER disabling crtcs */ |
| @@ -370,6 +370,7 @@ void radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, · 369 unmodified lines | ||
| 370 | 370 | struct backlight_properties props; |
| 371 | 371 | struct radeon_backlight_privdata *pdata; |
| 372 | 372 | uint8_t backlight_level; |
| 373 | + char bl_name[16]; | |
| 373 | 374 | |
| 374 | 375 | if (!radeon_encoder->enc_priv) |
| 375 | 376 | return; |
| @@ -389,7 +390,9 @@ void radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, · 13 unmodified lines | ||
| 389 | 390 | memset(&props, 0, sizeof(props)); |
| 390 | 391 | props.max_brightness = RADEON_MAX_BL_LEVEL; |
| 391 | 392 | props.type = BACKLIGHT_RAW; |
| 392 | − bd = backlight_device_register("radeon_bl", &drm_connector->kdev, | |
| 393 | + snprintf(bl_name, sizeof(bl_name), | |
| 394 | + "radeon_bl%d", dev->primary->index); | |
| 395 | + bd = backlight_device_register(bl_name, &drm_connector->kdev, | |
| 393 | 396 | pdata, &radeon_backlight_ops, &props); |
| 394 | 397 | if (IS_ERR(bd)) { |
| 395 | 398 | DRM_ERROR("Backlight registration failed\n"); |
| @@ -534,7 +537,9 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode · 138 unmodified lines | ||
| 534 | 537 | break; |
| 535 | 538 | } |
| 536 | 539 | |
| 537 | − WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); | |
| 540 | + /* handled in radeon_crtc_dpms() */ | |
| 541 | + if (!(rdev->flags & RADEON_SINGLE_CRTC)) | |
| 542 | + WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); | |
| 538 | 543 | WREG32(RADEON_DAC_CNTL, dac_cntl); |
| 539 | 544 | WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); |
| 540 | 545 | |
| @@ -659,6 +664,8 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc · 118 unmodified lines | ||
| 659 | 664 | |
| 660 | 665 | if (ASIC_IS_R300(rdev)) |
| 661 | 666 | tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT); |
| 667 | + else if (ASIC_IS_RV100(rdev)) | |
| 668 | + tmp |= (0x1ac << RADEON_DAC_FORCE_DATA_SHIFT); | |
| 662 | 669 | else |
| 663 | 670 | tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT); |
| 664 | 671 | |
| @@ -668,6 +675,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc · 3 unmodified lines | ||
| 668 | 675 | tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN; |
| 669 | 676 | WREG32(RADEON_DAC_CNTL, tmp); |
| 670 | 677 | |
| 678 | + tmp = dac_macro_cntl; | |
| 671 | 679 | tmp &= ~(RADEON_DAC_PDWN_R | |
| 672 | 680 | RADEON_DAC_PDWN_G | |
| 673 | 681 | RADEON_DAC_PDWN_B); |
| @@ -1089,7 +1097,8 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) · 415 unmodified lines | ||
| 1089 | 1097 | } else { |
| 1090 | 1098 | if (is_tv) |
| 1091 | 1099 | WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl); |
| 1092 | − else | |
| 1100 | + /* handled in radeon_crtc_dpms() */ | |
| 1101 | + else if (!(rdev->flags & RADEON_SINGLE_CRTC)) | |
| 1093 | 1102 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); |
| 1094 | 1103 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); |
| 1095 | 1104 | } |
| @@ -1413,13 +1422,104 @@ static bool radeon_legacy_tv_detect(struct drm_encoder *encoder, · 317 unmodified lines | ||
| 1413 | 1422 | return found; |
| 1414 | 1423 | } |
| 1415 | 1424 | |
| 1425 | +static bool radeon_legacy_ext_dac_detect(struct drm_encoder *encoder, | |
| 1426 | + struct drm_connector *connector) | |
| 1427 | +{ | |
| 1428 | + struct drm_device *dev = encoder->dev; | |
| 1429 | + struct radeon_device *rdev = dev->dev_private; | |
| 1430 | + uint32_t gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl; | |
| 1431 | + uint32_t disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c; | |
| 1432 | + uint32_t disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f; | |
| 1433 | + uint32_t tmp, crtc2_h_total_disp, crtc2_v_total_disp; | |
| 1434 | + uint32_t crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid; | |
| 1435 | + bool found = false; | |
| 1436 | + int i; | |
| 1437 | + | |
| 1438 | + /* save the regs we need */ | |
| 1439 | + gpio_monid = RREG32(RADEON_GPIO_MONID); | |
| 1440 | + fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL); | |
| 1441 | + disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); | |
| 1442 | + crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); | |
| 1443 | + disp_lin_trans_grph_a = RREG32(RADEON_DISP_LIN_TRANS_GRPH_A); | |
| 1444 | + disp_lin_trans_grph_b = RREG32(RADEON_DISP_LIN_TRANS_GRPH_B); | |
| 1445 | + disp_lin_trans_grph_c = RREG32(RADEON_DISP_LIN_TRANS_GRPH_C); | |
| 1446 | + disp_lin_trans_grph_d = RREG32(RADEON_DISP_LIN_TRANS_GRPH_D); | |
| 1447 | + disp_lin_trans_grph_e = RREG32(RADEON_DISP_LIN_TRANS_GRPH_E); | |
| 1448 | + disp_lin_trans_grph_f = RREG32(RADEON_DISP_LIN_TRANS_GRPH_F); | |
| 1449 | + crtc2_h_total_disp = RREG32(RADEON_CRTC2_H_TOTAL_DISP); | |
| 1450 | + crtc2_v_total_disp = RREG32(RADEON_CRTC2_V_TOTAL_DISP); | |
| 1451 | + crtc2_h_sync_strt_wid = RREG32(RADEON_CRTC2_H_SYNC_STRT_WID); | |
| 1452 | + crtc2_v_sync_strt_wid = RREG32(RADEON_CRTC2_V_SYNC_STRT_WID); | |
| 1453 | + | |
| 1454 | + tmp = RREG32(RADEON_GPIO_MONID); | |
| 1455 | + tmp &= ~RADEON_GPIO_A_0; | |
| 1456 | + WREG32(RADEON_GPIO_MONID, tmp); | |
| 1457 | + | |
| 1458 | + WREG32(RADEON_FP2_GEN_CNTL, (RADEON_FP2_ON | | |
| 1459 | + RADEON_FP2_PANEL_FORMAT | | |
| 1460 | + R200_FP2_SOURCE_SEL_TRANS_UNIT | | |
| 1461 | + RADEON_FP2_DVO_EN | | |
| 1462 | + R200_FP2_DVO_RATE_SEL_SDR)); | |
| 1463 | + | |
| 1464 | + WREG32(RADEON_DISP_OUTPUT_CNTL, (RADEON_DISP_DAC_SOURCE_RMX | | |
| 1465 | + RADEON_DISP_TRANS_MATRIX_GRAPHICS)); | |
| 1466 | + | |
| 1467 | + WREG32(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_EN | | |
| 1468 | + RADEON_CRTC2_DISP_REQ_EN_B)); | |
| 1469 | + | |
| 1470 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000); | |
| 1471 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0); | |
| 1472 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000); | |
| 1473 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0); | |
| 1474 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000); | |
| 1475 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0); | |
| 1476 | + | |
| 1477 | + WREG32(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008); | |
| 1478 | + WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800); | |
| 1479 | + WREG32(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001); | |
| 1480 | + WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080); | |
| 1481 | + | |
| 1482 | + for (i = 0; i < 200; i++) { | |
| 1483 | + tmp = RREG32(RADEON_GPIO_MONID); | |
| 1484 | + if (tmp & RADEON_GPIO_Y_0) | |
| 1485 | + found = true; | |
| 1486 | + | |
| 1487 | + if (found) | |
| 1488 | + break; | |
| 1489 | + | |
| 1490 | + if (!drm_can_sleep()) | |
| 1491 | + mdelay(1); | |
| 1492 | + else | |
| 1493 | + msleep(1); | |
| 1494 | + } | |
| 1495 | + | |
| 1496 | + /* restore the regs we used */ | |
| 1497 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a); | |
| 1498 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b); | |
| 1499 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c); | |
| 1500 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d); | |
| 1501 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e); | |
| 1502 | + WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f); | |
| 1503 | + WREG32(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp); | |
| 1504 | + WREG32(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp); | |
| 1505 | + WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid); | |
| 1506 | + WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid); | |
| 1507 | + WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); | |
| 1508 | + WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); | |
| 1509 | + WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); | |
| 1510 | + WREG32(RADEON_GPIO_MONID, gpio_monid); | |
| 1511 | + | |
| 1512 | + return found; | |
| 1513 | +} | |
| 1514 | + | |
| 1416 | 1515 | static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, |
| 1417 | 1516 | struct drm_connector *connector) |
| 1418 | 1517 | { |
| 1419 | 1518 | struct drm_device *dev = encoder->dev; |
| 1420 | 1519 | struct radeon_device *rdev = dev->dev_private; |
| 1421 | − uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl; | |
| 1422 | − uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp; | |
| 1520 | + uint32_t crtc2_gen_cntl = 0, tv_dac_cntl, dac_cntl2, dac_ext_cntl; | |
| 1521 | + uint32_t gpiopad_a = 0, pixclks_cntl, tmp; | |
| 1522 | + uint32_t disp_output_cntl = 0, disp_hw_debug = 0, crtc_ext_cntl = 0; | |
| 1423 | 1523 | enum drm_connector_status found = connector_status_disconnected; |
| 1424 | 1524 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 1425 | 1525 | struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv; |
| @@ -1456,12 +1556,27 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder · 30 unmodified lines | ||
| 1456 | 1556 | return connector_status_disconnected; |
| 1457 | 1557 | } |
| 1458 | 1558 | |
| 1559 | + /* R200 uses an external DAC for secondary DAC */ | |
| 1560 | + if (rdev->family == CHIP_R200) { | |
| 1561 | + if (radeon_legacy_ext_dac_detect(encoder, connector)) | |
| 1562 | + found = connector_status_connected; | |
| 1563 | + return found; | |
| 1564 | + } | |
| 1565 | + | |
| 1459 | 1566 | /* save the regs we need */ |
| 1460 | 1567 | pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL); |
| 1461 | − gpiopad_a = ASIC_IS_R300(rdev) ? RREG32(RADEON_GPIOPAD_A) : 0; | |
| 1462 | − disp_output_cntl = ASIC_IS_R300(rdev) ? RREG32(RADEON_DISP_OUTPUT_CNTL) : 0; | |
| 1463 | − disp_hw_debug = ASIC_IS_R300(rdev) ? 0 : RREG32(RADEON_DISP_HW_DEBUG); | |
| 1464 | − crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); | |
| 1568 | + | |
| 1569 | + if (rdev->flags & RADEON_SINGLE_CRTC) { | |
| 1570 | + crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); | |
| 1571 | + } else { | |
| 1572 | + if (ASIC_IS_R300(rdev)) { | |
| 1573 | + gpiopad_a = RREG32(RADEON_GPIOPAD_A); | |
| 1574 | + disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL); | |
| 1575 | + } else { | |
| 1576 | + disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG); | |
| 1577 | + } | |
| 1578 | + crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); | |
| 1579 | + } | |
| 1465 | 1580 | tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL); |
| 1466 | 1581 | dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL); |
| 1467 | 1582 | dac_cntl2 = RREG32(RADEON_DAC_CNTL2); |
| @@ -1470,22 +1585,24 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder · 2 unmodified lines | ||
| 1470 | 1585 | | RADEON_PIX2CLK_DAC_ALWAYS_ONb); |
| 1471 | 1586 | WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); |
| 1472 | 1587 | |
| 1473 | − if (ASIC_IS_R300(rdev)) | |
| 1474 | − WREG32_P(RADEON_GPIOPAD_A, 1, ~1); | |
| 1475 | − | |
| 1476 | − tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK; | |
| 1477 | − tmp |= RADEON_CRTC2_CRT2_ON | | |
| 1478 | − (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT); | |
| 1479 | − | |
| 1480 | − WREG32(RADEON_CRTC2_GEN_CNTL, tmp); | |
| 1481 | − | |
| 1482 | − if (ASIC_IS_R300(rdev)) { | |
| 1483 | − tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; | |
| 1484 | − tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; | |
| 1485 | − WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); | |
| 1588 | + if (rdev->flags & RADEON_SINGLE_CRTC) { | |
| 1589 | + tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON; | |
| 1590 | + WREG32(RADEON_CRTC_EXT_CNTL, tmp); | |
| 1486 | 1591 | } else { |
| 1487 | − tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL; | |
| 1488 | − WREG32(RADEON_DISP_HW_DEBUG, tmp); | |
| 1592 | + tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK; | |
| 1593 | + tmp |= RADEON_CRTC2_CRT2_ON | | |
| 1594 | + (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT); | |
| 1595 | + WREG32(RADEON_CRTC2_GEN_CNTL, tmp); | |
| 1596 | + | |
| 1597 | + if (ASIC_IS_R300(rdev)) { | |
| 1598 | + WREG32_P(RADEON_GPIOPAD_A, 1, ~1); | |
| 1599 | + tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; | |
| 1600 | + tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; | |
| 1601 | + WREG32(RADEON_DISP_OUTPUT_CNTL, tmp); | |
| 1602 | + } else { | |
| 1603 | + tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL; | |
| 1604 | + WREG32(RADEON_DISP_HW_DEBUG, tmp); | |
| 1605 | + } | |
| 1489 | 1606 | } |
| 1490 | 1607 | |
| 1491 | 1608 | tmp = RADEON_TV_DAC_NBLANK | |
| @@ -1527,14 +1644,19 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder · 35 unmodified lines | ||
| 1527 | 1644 | WREG32(RADEON_DAC_CNTL2, dac_cntl2); |
| 1528 | 1645 | WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl); |
| 1529 | 1646 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); |
| 1530 | − WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); | |
| 1531 | 1647 | |
| 1532 | − if (ASIC_IS_R300(rdev)) { | |
| 1533 | − WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); | |
| 1534 | − WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); | |
| 1648 | + if (rdev->flags & RADEON_SINGLE_CRTC) { | |
| 1649 | + WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); | |
| 1535 | 1650 | } else { |
| 1536 | − WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); | |
| 1651 | + WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); | |
| 1652 | + if (ASIC_IS_R300(rdev)) { | |
| 1653 | + WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); | |
| 1654 | + WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1); | |
| 1655 | + } else { | |
| 1656 | + WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); | |
| 1657 | + } | |
| 1537 | 1658 | } |
| 1659 | + | |
| 1538 | 1660 | WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl); |
| 1539 | 1661 | |
| 1540 | 1662 | return found; |
| @@ -105,7 +105,6 @@ int radeon_bo_create(struct radeon_device *rdev, · 104 unmodified lines | ||
| 105 | 105 | struct radeon_bo *bo; |
| 106 | 106 | enum ttm_bo_type type; |
| 107 | 107 | unsigned long page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; |
| 108 | − unsigned long max_size = 0; | |
| 109 | 108 | size_t acc_size; |
| 110 | 109 | int r; |
| 111 | 110 | |
| @@ -121,18 +120,9 @@ int radeon_bo_create(struct radeon_device *rdev, · 9 unmodified lines | ||
| 121 | 120 | } |
| 122 | 121 | *bo_ptr = NULL; |
| 123 | 122 | |
| 124 | − /* maximun bo size is the minimun btw visible vram and gtt size */ | |
| 125 | − max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size); | |
| 126 | − if ((page_align << PAGE_SHIFT) >= max_size) { | |
| 127 | − printk(KERN_WARNING "%s:%d alloc size %ldM bigger than %ldMb limit\n", | |
| 128 | − __func__, __LINE__, page_align >> (20 - PAGE_SHIFT), max_size >> 20); | |
| 129 | − return -ENOMEM; | |
| 130 | − } | |
| 131 | − | |
| 132 | 123 | acc_size = ttm_bo_dma_acc_size(&rdev->mman.bdev, size, |
| 133 | 124 | sizeof(struct radeon_bo)); |
| 134 | 125 | |
| 135 | −retry: | |
| 136 | 126 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); |
| 137 | 127 | if (bo == NULL) |
| 138 | 128 | return -ENOMEM; |
| @@ -154,15 +144,6 @@ retry: · 15 unmodified lines | ||
| 154 | 144 | acc_size, sg, &radeon_ttm_bo_destroy); |
| 155 | 145 | up_read(&rdev->pm.mclk_lock); |
| 156 | 146 | if (unlikely(r != 0)) { |
| 157 | − if (r != -ERESTARTSYS) { | |
| 158 | − if (domain == RADEON_GEM_DOMAIN_VRAM) { | |
| 159 | − domain |= RADEON_GEM_DOMAIN_GTT; | |
| 160 | − goto retry; | |
| 161 | − } | |
| 162 | − dev_err(rdev->dev, | |
| 163 | − "object_init failed for (%lu, 0x%08X)\n", | |
| 164 | − size, domain); | |
| 165 | − } | |
| 166 | 147 | return r; |
| 167 | 148 | } |
| 168 | 149 | *bo_ptr = bo; |
| @@ -2474,6 +2474,7 @@ static bool si_vm_reg_valid(u32 reg) · 2473 unmodified lines | ||
| 2474 | 2474 | /* check config regs */ |
| 2475 | 2475 | switch (reg) { |
| 2476 | 2476 | case GRBM_GFX_INDEX: |
| 2477 | + case CP_STRMOUT_CNTL: | |
| 2477 | 2478 | case VGT_VTX_VECT_EJECT_REG: |
| 2478 | 2479 | case VGT_CACHE_INVALIDATION: |
| 2479 | 2480 | case VGT_ESGS_RING_SIZE: |
| @@ -2808,26 +2809,31 @@ void si_vm_set_page(struct radeon_device *rdev, uint64_t pe, · 328 unmodified lines | ||
| 2808 | 2809 | { |
| 2809 | 2810 | struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index]; |
| 2810 | 2811 | uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); |
| 2811 | − int i; | |
| 2812 | − uint64_t value; | |
| 2813 | 2812 | |
| 2814 | − radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 2 + count * 2)); | |
| 2815 | − radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | | |
| 2816 | − WRITE_DATA_DST_SEL(1))); | |
| 2817 | − radeon_ring_write(ring, pe); | |
| 2818 | − radeon_ring_write(ring, upper_32_bits(pe)); | |
| 2819 | − for (i = 0; i < count; ++i) { | |
| 2820 | − if (flags & RADEON_VM_PAGE_SYSTEM) { | |
| 2821 | − value = radeon_vm_map_gart(rdev, addr); | |
| 2822 | − value &= 0xFFFFFFFFFFFFF000ULL; | |
| 2823 | − } else if (flags & RADEON_VM_PAGE_VALID) | |
| 2824 | − value = addr; | |
| 2825 | − else | |
| 2826 | − value = 0; | |
| 2827 | − addr += incr; | |
| 2828 | − value |= r600_flags; | |
| 2829 | − radeon_ring_write(ring, value); | |
| 2830 | − radeon_ring_write(ring, upper_32_bits(value)); | |
| 2813 | + while (count) { | |
| 2814 | + unsigned ndw = 2 + count * 2; | |
| 2815 | + if (ndw > 0x3FFE) | |
| 2816 | + ndw = 0x3FFE; | |
| 2817 | + | |
| 2818 | + radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, ndw)); | |
| 2819 | + radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | | |
| 2820 | + WRITE_DATA_DST_SEL(1))); | |
| 2821 | + radeon_ring_write(ring, pe); | |
| 2822 | + radeon_ring_write(ring, upper_32_bits(pe)); | |
| 2823 | + for (; ndw > 2; ndw -= 2, --count, pe += 8) { | |
| 2824 | + uint64_t value; | |
| 2825 | + if (flags & RADEON_VM_PAGE_SYSTEM) { | |
| 2826 | + value = radeon_vm_map_gart(rdev, addr); | |
| 2827 | + value &= 0xFFFFFFFFFFFFF000ULL; | |
| 2828 | + } else if (flags & RADEON_VM_PAGE_VALID) | |
| 2829 | + value = addr; | |
| 2830 | + else | |
| 2831 | + value = 0; | |
| 2832 | + addr += incr; | |
| 2833 | + value |= r600_flags; | |
| 2834 | + radeon_ring_write(ring, value); | |
| 2835 | + radeon_ring_write(ring, upper_32_bits(value)); | |
| 2836 | + } | |
| 2831 | 2837 | } |
| 2832 | 2838 | } |
| 2833 | 2839 | |
| @@ -2868,6 +2874,10 @@ void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) · 34 unmodified lines | ||
| 2868 | 2874 | radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); |
| 2869 | 2875 | radeon_ring_write(ring, 0); |
| 2870 | 2876 | radeon_ring_write(ring, 1 << vm->id); |
| 2877 | + | |
| 2878 | + /* sync PFP to ME, otherwise we might get invalid PFP reads */ | |
| 2879 | + radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); | |
| 2880 | + radeon_ring_write(ring, 0x0); | |
| 2871 | 2881 | } |
| 2872 | 2882 | |
| 2873 | 2883 | /* |
| @@ -424,6 +424,7 @@ · 423 unmodified lines | ||
| 424 | 424 | # define RDERR_INT_ENABLE (1 << 0) |
| 425 | 425 | # define GUI_IDLE_INT_ENABLE (1 << 19) |
| 426 | 426 | |
| 427 | +#define CP_STRMOUT_CNTL 0x84FC | |
| 427 | 428 | #define SCRATCH_REG0 0x8500 |
| 428 | 429 | #define SCRATCH_REG1 0x8504 |
| 429 | 430 | #define SCRATCH_REG2 0x8508 |
| @@ -749,7 +749,10 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags, · 748 unmodified lines | ||
| 749 | 749 | /* clear the pages coming from the pool if requested */ |
| 750 | 750 | if (flags & TTM_PAGE_FLAG_ZERO_ALLOC) { |
| 751 | 751 | list_for_each_entry(p, &plist, lru) { |
| 752 | − clear_page(page_address(p)); | |
| 752 | + if (PageHighMem(p)) | |
| 753 | + clear_highpage(p); | |
| 754 | + else | |
| 755 | + clear_page(page_address(p)); | |
| 753 | 756 | } |
| 754 | 757 | } |
| 755 | 758 | |
| @@ -308,9 +308,7 @@ int ttm_tt_swapin(struct ttm_tt *ttm) · 307 unmodified lines | ||
| 308 | 308 | if (unlikely(to_page == NULL)) |
| 309 | 309 | goto out_err; |
| 310 | 310 | |
| 311 | − preempt_disable(); | |
| 312 | 311 | copy_highpage(to_page, from_page); |
| 313 | − preempt_enable(); | |
| 314 | 312 | page_cache_release(from_page); |
| 315 | 313 | } |
| 316 | 314 | |
| @@ -358,9 +356,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage) · 41 unmodified lines | ||
| 358 | 356 | ret = PTR_ERR(to_page); |
| 359 | 357 | goto out_err; |
| 360 | 358 | } |
| 361 | − preempt_disable(); | |
| 362 | 359 | copy_highpage(to_page, from_page); |
| 363 | − preempt_enable(); | |
| 364 | 360 | set_page_dirty(to_page); |
| 365 | 361 | mark_page_accessed(to_page); |
| 366 | 362 | page_cache_release(to_page); |
| @@ -104,7 +104,7 @@ udl_fb_user_fb_create(struct drm_device *dev, · 103 unmodified lines | ||
| 104 | 104 | |
| 105 | 105 | int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr, |
| 106 | 106 | const char *front, char **urb_buf_ptr, |
| 107 | − u32 byte_offset, u32 byte_width, | |
| 107 | + u32 byte_offset, u32 device_byte_offset, u32 byte_width, | |
| 108 | 108 | int *ident_ptr, int *sent_ptr); |
| 109 | 109 | |
| 110 | 110 | int udl_dumb_create(struct drm_file *file_priv, |
| @@ -114,9 +114,10 @@ static void udlfb_dpy_deferred_io(struct fb_info *info, · 113 unmodified lines | ||
| 114 | 114 | list_for_each_entry(cur, &fbdefio->pagelist, lru) { |
| 115 | 115 | |
| 116 | 116 | if (udl_render_hline(dev, (ufbdev->ufb.base.bits_per_pixel / 8), |
| 117 | − &urb, (char *) info->fix.smem_start, | |
| 118 | − &cmd, cur->index << PAGE_SHIFT, | |
| 119 | − PAGE_SIZE, &bytes_identical, &bytes_sent)) | |
| 117 | + &urb, (char *) info->fix.smem_start, | |
| 118 | + &cmd, cur->index << PAGE_SHIFT, | |
| 119 | + cur->index << PAGE_SHIFT, | |
| 120 | + PAGE_SIZE, &bytes_identical, &bytes_sent)) | |
| 120 | 121 | goto error; |
| 121 | 122 | bytes_rendered += PAGE_SIZE; |
| 122 | 123 | } |
| @@ -187,10 +188,11 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, · 64 unmodified lines | ||
| 187 | 188 | for (i = y; i < y + height ; i++) { |
| 188 | 189 | const int line_offset = fb->base.pitches[0] * i; |
| 189 | 190 | const int byte_offset = line_offset + (x * bpp); |
| 190 | − | |
| 191 | + const int dev_byte_offset = (fb->base.width * bpp * i) + (x * bpp); | |
| 191 | 192 | if (udl_render_hline(dev, bpp, &urb, |
| 192 | 193 | (char *) fb->obj->vmapping, |
| 193 | − &cmd, byte_offset, width * bpp, | |
| 194 | + &cmd, byte_offset, dev_byte_offset, | |
| 195 | + width * bpp, | |
| 194 | 196 | &bytes_identical, &bytes_sent)) |
| 195 | 197 | goto error; |
| 196 | 198 | } |
| @@ -213,11 +213,12 @@ static void udl_compress_hline16( · 212 unmodified lines | ||
| 213 | 213 | */ |
| 214 | 214 | int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr, |
| 215 | 215 | const char *front, char **urb_buf_ptr, |
| 216 | − u32 byte_offset, u32 byte_width, | |
| 216 | + u32 byte_offset, u32 device_byte_offset, | |
| 217 | + u32 byte_width, | |
| 217 | 218 | int *ident_ptr, int *sent_ptr) |
| 218 | 219 | { |
| 219 | 220 | const u8 *line_start, *line_end, *next_pixel; |
| 220 | − u32 base16 = 0 + (byte_offset / bpp) * 2; | |
| 221 | + u32 base16 = 0 + (device_byte_offset / bpp) * 2; | |
| 221 | 222 | struct urb *urb = *urb_ptr; |
| 222 | 223 | u8 *cmd = *urb_buf_ptr; |
| 223 | 224 | u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length; |
| @@ -306,7 +306,7 @@ void vmw_bo_pin(struct ttm_buffer_object *bo, bool pin) · 305 unmodified lines | ||
| 306 | 306 | |
| 307 | 307 | BUG_ON(!atomic_read(&bo->reserved)); |
| 308 | 308 | BUG_ON(old_mem_type != TTM_PL_VRAM && |
| 309 | − old_mem_type != VMW_PL_FLAG_GMR); | |
| 309 | + old_mem_type != VMW_PL_GMR); | |
| 310 | 310 | |
| 311 | 311 | pl_flags = TTM_PL_FLAG_VRAM | VMW_PL_FLAG_GMR | TTM_PL_FLAG_CACHED; |
| 312 | 312 | if (pin) |
| @@ -1098,6 +1098,11 @@ static void vmw_pm_complete(struct device *kdev) · 1097 unmodified lines | ||
| 1098 | 1098 | struct drm_device *dev = pci_get_drvdata(pdev); |
| 1099 | 1099 | struct vmw_private *dev_priv = vmw_priv(dev); |
| 1100 | 1100 | |
| 1101 | + mutex_lock(&dev_priv->hw_mutex); | |
| 1102 | + vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); | |
| 1103 | + (void) vmw_read(dev_priv, SVGA_REG_ID); | |
| 1104 | + mutex_unlock(&dev_priv->hw_mutex); | |
| 1105 | + | |
| 1101 | 1106 | /** |
| 1102 | 1107 | * Reclaim 3d reference held by fbdev and potentially |
| 1103 | 1108 | * start fifo. |
| @@ -110,6 +110,8 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, · 109 unmodified lines | ||
| 110 | 110 | memcpy_fromio(bounce, &fifo_mem[SVGA_FIFO_3D_CAPS], size); |
| 111 | 111 | |
| 112 | 112 | ret = copy_to_user(buffer, bounce, size); |
| 113 | + if (ret) | |
| 114 | + ret = -EFAULT; | |
| 113 | 115 | vfree(bounce); |
| 114 | 116 | |
| 115 | 117 | if (unlikely(ret != 0)) |
| @@ -522,6 +522,12 @@ static const struct hid_device_id apple_devices[] = { · 521 unmodified lines | ||
| 522 | 522 | .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, |
| 523 | 523 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS), |
| 524 | 524 | .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, |
| 525 | + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI), | |
| 526 | + .driver_data = APPLE_HAS_FN }, | |
| 527 | + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO), | |
| 528 | + .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, | |
| 529 | + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS), | |
| 530 | + .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, | |
| 525 | 531 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), |
| 526 | 532 | .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, |
| 527 | 533 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), |
| @@ -1532,6 +1532,9 @@ static const struct hid_device_id hid_have_special_driver[] = { · 1531 unmodified lines | ||
| 1532 | 1532 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI) }, |
| 1533 | 1533 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO) }, |
| 1534 | 1534 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS) }, |
| 1535 | + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI) }, | |
| 1536 | + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO) }, | |
| 1537 | + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS) }, | |
| 1535 | 1538 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, |
| 1536 | 1539 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, |
| 1537 | 1540 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, |
| @@ -2139,6 +2142,9 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { · 601 unmodified lines | ||
| 2139 | 2142 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI) }, |
| 2140 | 2143 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO) }, |
| 2141 | 2144 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS) }, |
| 2145 | + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI) }, | |
| 2146 | + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO) }, | |
| 2147 | + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS) }, | |
| 2142 | 2148 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, |
| 2143 | 2149 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, |
| 2144 | 2150 | { } |
| @@ -118,6 +118,9 @@ · 117 unmodified lines | ||
| 118 | 118 | #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI 0x0252 |
| 119 | 119 | #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO 0x0253 |
| 120 | 120 | #define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS 0x0254 |
| 121 | +#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI 0x0259 | |
| 122 | +#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO 0x025a | |
| 123 | +#define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS 0x025b | |
| 121 | 124 | #define USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI 0x0249 |
| 122 | 125 | #define USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO 0x024a |
| 123 | 126 | #define USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS 0x024b |
| @@ -28,22 +28,30 @@ · 27 unmodified lines | ||
| 28 | 28 | #define MS_RDESC 0x08 |
| 29 | 29 | #define MS_NOGET 0x10 |
| 30 | 30 | #define MS_DUPLICATE_USAGES 0x20 |
| 31 | +#define MS_RDESC_3K 0x40 | |
| 31 | 32 | |
| 32 | −/* | |
| 33 | − * Microsoft Wireless Desktop Receiver (Model 1028) has | |
| 34 | − * 'Usage Min/Max' where it ought to have 'Physical Min/Max' | |
| 35 | − */ | |
| 36 | 33 | static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
| 37 | 34 | unsigned int *rsize) |
| 38 | 35 | { |
| 39 | 36 | unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); |
| 40 | 37 | |
| 38 | + /* | |
| 39 | + * Microsoft Wireless Desktop Receiver (Model 1028) has | |
| 40 | + * 'Usage Min/Max' where it ought to have 'Physical Min/Max' | |
| 41 | + */ | |
| 41 | 42 | if ((quirks & MS_RDESC) && *rsize == 571 && rdesc[557] == 0x19 && |
| 42 | 43 | rdesc[559] == 0x29) { |
| 43 | 44 | hid_info(hdev, "fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n"); |
| 44 | 45 | rdesc[557] = 0x35; |
| 45 | 46 | rdesc[559] = 0x45; |
| 46 | 47 | } |
| 48 | + /* the same as above (s/usage/physical/) */ | |
| 49 | + if ((quirks & MS_RDESC_3K) && *rsize == 106 && rdesc[94] == 0x19 && | |
| 50 | + rdesc[95] == 0x00 && rdesc[96] == 0x29 && | |
| 51 | + rdesc[97] == 0xff) { | |
| 52 | + rdesc[94] = 0x35; | |
| 53 | + rdesc[96] = 0x45; | |
| 54 | + } | |
| 47 | 55 | return rdesc; |
| 48 | 56 | } |
| 49 | 57 | |
| @@ -192,7 +200,7 @@ static const struct hid_device_id ms_devices[] = { · 142 unmodified lines | ||
| 192 | 200 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB), |
| 193 | 201 | .driver_data = MS_PRESENTER }, |
| 194 | 202 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K), |
| 195 | − .driver_data = MS_ERGONOMY }, | |
| 203 | + .driver_data = MS_ERGONOMY | MS_RDESC_3K }, | |
| 196 | 204 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0), |
| 197 | 205 | .driver_data = MS_NOGET }, |
| 198 | 206 | { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), |
| @@ -210,8 +210,7 @@ static struct mt_class mt_classes[] = { · 209 unmodified lines | ||
| 210 | 210 | }, |
| 211 | 211 | { .name = MT_CLS_GENERALTOUCH_PWT_TENFINGERS, |
| 212 | 212 | .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | |
| 213 | − MT_QUIRK_SLOT_IS_CONTACTNUMBER, | |
| 214 | − .maxcontacts = 10 | |
| 213 | + MT_QUIRK_SLOT_IS_CONTACTNUMBER | |
| 215 | 214 | }, |
| 216 | 215 | |
| 217 | 216 | { .name = MT_CLS_FLATFROG, |
| @@ -421,11 +420,11 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 203 unmodified lines | ||
| 421 | 420 | * contact max are global to the report */ |
| 422 | 421 | td->last_field_index = field->index; |
| 423 | 422 | return -1; |
| 424 | − } | |
| 425 | 423 | case HID_DG_TOUCH: |
| 426 | 424 | /* Legacy devices use TIPSWITCH and not TOUCH. |
| 427 | 425 | * Let's just ignore this field. */ |
| 428 | 426 | return -1; |
| 427 | + } | |
| 429 | 428 | /* let hid-input decide for the others */ |
| 430 | 429 | return 0; |
| 431 | 430 | |
| @@ -42,7 +42,6 @@ static struct cdev hidraw_cdev; · 41 unmodified lines | ||
| 42 | 42 | static struct class *hidraw_class; |
| 43 | 43 | static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES]; |
| 44 | 44 | static DEFINE_MUTEX(minors_lock); |
| 45 | −static void drop_ref(struct hidraw *hid, int exists_bit); | |
| 46 | 45 | |
| 47 | 46 | static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) |
| 48 | 47 | { |
| @@ -114,7 +113,7 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer, · 65 unmodified lines | ||
| 114 | 113 | __u8 *buf; |
| 115 | 114 | int ret = 0; |
| 116 | 115 | |
| 117 | − if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { | |
| 116 | + if (!hidraw_table[minor]) { | |
| 118 | 117 | ret = -ENODEV; |
| 119 | 118 | goto out; |
| 120 | 119 | } |
| @@ -262,7 +261,7 @@ static int hidraw_open(struct inode *inode, struct file *file) · 141 unmodified lines | ||
| 262 | 261 | } |
| 263 | 262 | |
| 264 | 263 | mutex_lock(&minors_lock); |
| 265 | − if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { | |
| 264 | + if (!hidraw_table[minor]) { | |
| 266 | 265 | err = -ENODEV; |
| 267 | 266 | goto out_unlock; |
| 268 | 267 | } |
| @@ -299,12 +298,36 @@ out: · 30 unmodified lines | ||
| 299 | 298 | static int hidraw_release(struct inode * inode, struct file * file) |
| 300 | 299 | { |
| 301 | 300 | unsigned int minor = iminor(inode); |
| 301 | + struct hidraw *dev; | |
| 302 | 302 | struct hidraw_list *list = file->private_data; |
| 303 | + int ret; | |
| 304 | + int i; | |
| 305 | + | |
| 306 | + mutex_lock(&minors_lock); | |
| 307 | + if (!hidraw_table[minor]) { | |
| 308 | + ret = -ENODEV; | |
| 309 | + goto unlock; | |
| 310 | + } | |
| 303 | 311 | |
| 304 | − drop_ref(hidraw_table[minor], 0); | |
| 305 | 312 | list_del(&list->node); |
| 313 | + dev = hidraw_table[minor]; | |
| 314 | + if (!--dev->open) { | |
| 315 | + if (list->hidraw->exist) { | |
| 316 | + hid_hw_power(dev->hid, PM_HINT_NORMAL); | |
| 317 | + hid_hw_close(dev->hid); | |
| 318 | + } else { | |
| 319 | + kfree(list->hidraw); | |
| 320 | + } | |
| 321 | + } | |
| 322 | + | |
| 323 | + for (i = 0; i < HIDRAW_BUFFER_SIZE; ++i) | |
| 324 | + kfree(list->buffer[i].value); | |
| 306 | 325 | kfree(list); |
| 307 | − return 0; | |
| 326 | + ret = 0; | |
| 327 | +unlock: | |
| 328 | + mutex_unlock(&minors_lock); | |
| 329 | + | |
| 330 | + return ret; | |
| 308 | 331 | } |
| 309 | 332 | |
| 310 | 333 | static long hidraw_ioctl(struct file *file, unsigned int cmd, |
| @@ -506,7 +529,21 @@ EXPORT_SYMBOL_GPL(hidraw_connect); · 195 unmodified lines | ||
| 506 | 529 | void hidraw_disconnect(struct hid_device *hid) |
| 507 | 530 | { |
| 508 | 531 | struct hidraw *hidraw = hid->hidraw; |
| 509 | − drop_ref(hidraw, 1); | |
| 532 | + | |
| 533 | + mutex_lock(&minors_lock); | |
| 534 | + hidraw->exist = 0; | |
| 535 | + | |
| 536 | + device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); | |
| 537 | + | |
| 538 | + hidraw_table[hidraw->minor] = NULL; | |
| 539 | + | |
| 540 | + if (hidraw->open) { | |
| 541 | + hid_hw_close(hid); | |
| 542 | + wake_up_interruptible(&hidraw->wait); | |
| 543 | + } else { | |
| 544 | + kfree(hidraw); | |
| 545 | + } | |
| 546 | + mutex_unlock(&minors_lock); | |
| 510 | 547 | } |
| 511 | 548 | EXPORT_SYMBOL_GPL(hidraw_disconnect); |
| 512 | 549 | |
| @@ -555,23 +592,3 @@ void hidraw_exit(void) · 42 unmodified lines | ||
| 555 | 592 | unregister_chrdev_region(dev_id, HIDRAW_MAX_DEVICES); |
| 556 | 593 | |
| 557 | 594 | } |
| 558 | − | |
| 559 | −static void drop_ref(struct hidraw *hidraw, int exists_bit) | |
| 560 | −{ | |
| 561 | − mutex_lock(&minors_lock); | |
| 562 | − if (exists_bit) { | |
| 563 | − hid_hw_close(hidraw->hid); | |
| 564 | − hidraw->exist = 0; | |
| 565 | − if (hidraw->open) | |
| 566 | − wake_up_interruptible(&hidraw->wait); | |
| 567 | − } else { | |
| 568 | − --hidraw->open; | |
| 569 | − } | |
| 570 | − | |
| 571 | − if (!hidraw->open && !hidraw->exist) { | |
| 572 | − device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); | |
| 573 | − hidraw_table[hidraw->minor] = NULL; | |
| 574 | − kfree(hidraw); | |
| 575 | − } | |
| 576 | − mutex_unlock(&minors_lock); | |
| 577 | −} | |
| @@ -146,14 +146,14 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, · 145 unmodified lines | ||
| 146 | 146 | |
| 147 | 147 | if (ret != 0) { |
| 148 | 148 | err = ret; |
| 149 | − goto errorout; | |
| 149 | + goto error0; | |
| 150 | 150 | } |
| 151 | 151 | |
| 152 | 152 | ret = hv_ringbuffer_init( |
| 153 | 153 | &newchannel->inbound, in, recv_ringbuffer_size); |
| 154 | 154 | if (ret != 0) { |
| 155 | 155 | err = ret; |
| 156 | − goto errorout; | |
| 156 | + goto error0; | |
| 157 | 157 | } |
| 158 | 158 | |
| 159 | 159 | |
| @@ -168,7 +168,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, · 8 unmodified lines | ||
| 168 | 168 | |
| 169 | 169 | if (ret != 0) { |
| 170 | 170 | err = ret; |
| 171 | − goto errorout; | |
| 171 | + goto error0; | |
| 172 | 172 | } |
| 173 | 173 | |
| 174 | 174 | /* Create and init the channel open message */ |
| @@ -177,7 +177,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, · 2 unmodified lines | ||
| 177 | 177 | GFP_KERNEL); |
| 178 | 178 | if (!open_info) { |
| 179 | 179 | err = -ENOMEM; |
| 180 | − goto errorout; | |
| 180 | + goto error0; | |
| 181 | 181 | } |
| 182 | 182 | |
| 183 | 183 | init_completion(&open_info->waitevent); |
| @@ -193,7 +193,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, · 9 unmodified lines | ||
| 193 | 193 | |
| 194 | 194 | if (userdatalen > MAX_USER_DEFINED_BYTES) { |
| 195 | 195 | err = -EINVAL; |
| 196 | − goto errorout; | |
| 196 | + goto error0; | |
| 197 | 197 | } |
| 198 | 198 | |
| 199 | 199 | if (userdatalen) |
| @@ -208,19 +208,18 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, · 8 unmodified lines | ||
| 208 | 208 | sizeof(struct vmbus_channel_open_channel)); |
| 209 | 209 | |
| 210 | 210 | if (ret != 0) |
| 211 | − goto cleanup; | |
| 211 | + goto error1; | |
| 212 | 212 | |
| 213 | 213 | t = wait_for_completion_timeout(&open_info->waitevent, 5*HZ); |
| 214 | 214 | if (t == 0) { |
| 215 | 215 | err = -ETIMEDOUT; |
| 216 | − goto errorout; | |
| 216 | + goto error1; | |
| 217 | 217 | } |
| 218 | 218 | |
| 219 | 219 | |
| 220 | 220 | if (open_info->response.open_result.status) |
| 221 | 221 | err = open_info->response.open_result.status; |
| 222 | 222 | |
| 223 | −cleanup: | |
| 224 | 223 | spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); |
| 225 | 224 | list_del(&open_info->msglistentry); |
| 226 | 225 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); |
| @@ -228,9 +227,12 @@ cleanup: · 1 unmodified line | ||
| 228 | 227 | kfree(open_info); |
| 229 | 228 | return err; |
| 230 | 229 | |
| 231 | −errorout: | |
| 232 | − hv_ringbuffer_cleanup(&newchannel->outbound); | |
| 233 | − hv_ringbuffer_cleanup(&newchannel->inbound); | |
| 230 | +error1: | |
| 231 | + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); | |
| 232 | + list_del(&open_info->msglistentry); | |
| 233 | + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); | |
| 234 | + | |
| 235 | +error0: | |
| 234 | 236 | free_pages((unsigned long)out, |
| 235 | 237 | get_order(send_ringbuffer_size + recv_ringbuffer_size)); |
| 236 | 238 | kfree(open_info); |
| @@ -32,7 +32,7 @@ · 31 unmodified lines | ||
| 32 | 32 | * ASB100-A supports pwm1, while plain ASB100 does not. There is no known |
| 33 | 33 | * way for the driver to tell which one is there. |
| 34 | 34 | * |
| 35 | − * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 35 | + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 36 | 36 | * asb100 7 3 1 4 0x31 0x0694 yes no |
| 37 | 37 | */ |
| 38 | 38 | |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | * fam15h_power.c - AMD Family 15h processor power monitoring |
| 3 | 3 | * |
| 4 | 4 | * Copyright (c) 2011 Advanced Micro Devices, Inc. |
| 5 | − * Author: Andreas Herrmann <andreas.herrmann3@amd.com> | |
| 5 | + * Author: Andreas Herrmann <herrmann.der.user@googlemail.com> | |
| 6 | 6 | * |
| 7 | 7 | * |
| 8 | 8 | * This driver is free software; you can redistribute it and/or |
| @@ -28,7 +28,7 @@ · 19 unmodified lines | ||
| 28 | 28 | #include <asm/processor.h> |
| 29 | 29 | |
| 30 | 30 | MODULE_DESCRIPTION("AMD Family 15h CPU processor power monitor"); |
| 31 | −MODULE_AUTHOR("Andreas Herrmann <andreas.herrmann3@amd.com>"); | |
| 31 | +MODULE_AUTHOR("Andreas Herrmann <herrmann.der.user@googlemail.com>"); | |
| 32 | 32 | MODULE_LICENSE("GPL"); |
| 33 | 33 | |
| 34 | 34 | /* D18F3 */ |
| @@ -630,7 +630,9 @@ static struct platform_driver gpio_fan_driver = { · 629 unmodified lines | ||
| 630 | 630 | .driver = { |
| 631 | 631 | .name = "gpio-fan", |
| 632 | 632 | .pm = GPIO_FAN_PM, |
| 633 | +#ifdef CONFIG_OF_GPIO | |
| 633 | 634 | .of_match_table = of_match_ptr(of_gpio_fan_match), |
| 635 | +#endif | |
| 634 | 636 | }, |
| 635 | 637 | }; |
| 636 | 638 | |
| @@ -2083,6 +2083,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) · 2082 unmodified lines | ||
| 2083 | 2083 | mutex_init(&data->lock); |
| 2084 | 2084 | mutex_init(&data->update_lock); |
| 2085 | 2085 | data->name = w83627ehf_device_names[sio_data->kind]; |
| 2086 | + data->bank = 0xff; /* Force initial bank selection */ | |
| 2086 | 2087 | platform_set_drvdata(pdev, data); |
| 2087 | 2088 | |
| 2088 | 2089 | /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */ |
| @@ -25,7 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | /* |
| 26 | 26 | * Supports following chips: |
| 27 | 27 | * |
| 28 | − * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 28 | + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 29 | 29 | * w83627hf 9 3 2 3 0x20 0x5ca3 no yes(LPC) |
| 30 | 30 | * w83627thf 7 3 3 3 0x90 0x5ca3 no yes(LPC) |
| 31 | 31 | * w83637hf 7 3 3 3 0x80 0x5ca3 no yes(LPC) |
| @@ -24,7 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | /* |
| 25 | 25 | * Supports following chips: |
| 26 | 26 | * |
| 27 | − * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 27 | + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 28 | 28 | * as99127f 7 3 0 3 0x31 0x12c3 yes no |
| 29 | 29 | * as99127f rev.2 (type_name = as99127f) 0x31 0x5ca3 yes no |
| 30 | 30 | * w83781d 7 3 0 3 0x10-1 0x5ca3 yes yes |
| @@ -22,7 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | /* |
| 23 | 23 | * Supports following chips: |
| 24 | 24 | * |
| 25 | − * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 25 | + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 26 | 26 | * w83791d 10 5 5 3 0x71 0x5ca3 yes no |
| 27 | 27 | * |
| 28 | 28 | * The w83791d chip appears to be part way between the 83781d and the |
| @@ -31,7 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | /* |
| 32 | 32 | * Supports following chips: |
| 33 | 33 | * |
| 34 | − * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 34 | + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 35 | 35 | * w83792d 9 7 7 3 0x7a 0x5ca3 yes no |
| 36 | 36 | */ |
| 37 | 37 | |
| @@ -20,7 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | /* |
| 21 | 21 | * Supports following chips: |
| 22 | 22 | * |
| 23 | − * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 23 | + * Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA | |
| 24 | 24 | * w83l786ng 3 2 2 2 0x7b 0x5ca3 yes no |
| 25 | 25 | */ |
| 26 | 26 | |
| @@ -8,6 +8,7 @@ obj-$(CONFIG_I2C_SMBUS) += i2c-smbus.o · 7 unmodified lines | ||
| 8 | 8 | obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o |
| 9 | 9 | obj-$(CONFIG_I2C_MUX) += i2c-mux.o |
| 10 | 10 | obj-y += algos/ busses/ muxes/ |
| 11 | +obj-$(CONFIG_I2C_STUB) += i2c-stub.o | |
| 11 | 12 | |
| 12 | 13 | ccflags-$(CONFIG_I2C_DEBUG_CORE) := -DDEBUG |
| 13 | 14 | CFLAGS_i2c-core.o := -Wno-deprecated-declarations |
| @@ -81,7 +81,6 @@ config I2C_I801 · 80 unmodified lines | ||
| 81 | 81 | tristate "Intel 82801 (ICH/PCH)" |
| 82 | 82 | depends on PCI |
| 83 | 83 | select CHECK_SIGNATURE if X86 && DMI |
| 84 | − select GPIOLIB if I2C_MUX | |
| 85 | 84 | help |
| 86 | 85 | If you say yes to this option, support will be included for the Intel |
| 87 | 86 | 801 family of mainboard I2C interfaces. Specifically, the following |
| @@ -85,7 +85,6 @@ obj-$(CONFIG_I2C_ACORN) += i2c-acorn.o · 84 unmodified lines | ||
| 85 | 85 | obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o |
| 86 | 86 | obj-$(CONFIG_I2C_PCA_ISA) += i2c-pca-isa.o |
| 87 | 87 | obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o |
| 88 | −obj-$(CONFIG_I2C_STUB) += i2c-stub.o | |
| 89 | 88 | obj-$(CONFIG_SCx200_ACB) += scx200_acb.o |
| 90 | 89 | obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o |
| 91 | 90 | |
| @@ -39,6 +39,7 @@ · 38 unmodified lines | ||
| 39 | 39 | #define AT91_TWI_STOP 0x0002 /* Send a Stop Condition */ |
| 40 | 40 | #define AT91_TWI_MSEN 0x0004 /* Master Transfer Enable */ |
| 41 | 41 | #define AT91_TWI_SVDIS 0x0020 /* Slave Transfer Disable */ |
| 42 | +#define AT91_TWI_QUICK 0x0040 /* SMBus quick command */ | |
| 42 | 43 | #define AT91_TWI_SWRST 0x0080 /* Software Reset */ |
| 43 | 44 | |
| 44 | 45 | #define AT91_TWI_MMR 0x0004 /* Master Mode Register */ |
| @@ -212,7 +213,11 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev) · 167 unmodified lines | ||
| 212 | 213 | |
| 213 | 214 | INIT_COMPLETION(dev->cmd_complete); |
| 214 | 215 | dev->transfer_status = 0; |
| 215 | − if (dev->msg->flags & I2C_M_RD) { | |
| 216 | + | |
| 217 | + if (!dev->buf_len) { | |
| 218 | + at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_QUICK); | |
| 219 | + at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP); | |
| 220 | + } else if (dev->msg->flags & I2C_M_RD) { | |
| 216 | 221 | unsigned start_flags = AT91_TWI_START; |
| 217 | 222 | |
| 218 | 223 | if (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY) { |
| @@ -82,7 +82,8 @@ · 81 unmodified lines | ||
| 82 | 82 | #include <linux/wait.h> |
| 83 | 83 | #include <linux/err.h> |
| 84 | 84 | |
| 85 | −#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE | |
| 85 | +#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \ | |
| 86 | + defined CONFIG_DMI | |
| 86 | 87 | #include <linux/gpio.h> |
| 87 | 88 | #include <linux/i2c-mux-gpio.h> |
| 88 | 89 | #include <linux/platform_device.h> |
| @@ -192,7 +193,8 @@ struct i801_priv { · 103 unmodified lines | ||
| 192 | 193 | int len; |
| 193 | 194 | u8 *data; |
| 194 | 195 | |
| 195 | −#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE | |
| 196 | +#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \ | |
| 197 | + defined CONFIG_DMI | |
| 196 | 198 | const struct i801_mux_config *mux_drvdata; |
| 197 | 199 | struct platform_device *mux_pdev; |
| 198 | 200 | #endif |
| @@ -921,7 +923,8 @@ static void __init input_apanel_init(void) {} · 722 unmodified lines | ||
| 921 | 923 | static void __devinit i801_probe_optional_slaves(struct i801_priv *priv) {} |
| 922 | 924 | #endif /* CONFIG_X86 && CONFIG_DMI */ |
| 923 | 925 | |
| 924 | −#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE | |
| 926 | +#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \ | |
| 927 | + defined CONFIG_DMI | |
| 925 | 928 | static struct i801_mux_config i801_mux_config_asus_z8_d12 = { |
| 926 | 929 | .gpio_chip = "gpio_ich", |
| 927 | 930 | .values = { 0x02, 0x03 }, |
| @@ -1059,7 +1062,7 @@ static unsigned int __devinit i801_get_adapter_class(struct i801_priv *priv) · 131 unmodified lines | ||
| 1059 | 1062 | |
| 1060 | 1063 | id = dmi_first_match(mux_dmi_table); |
| 1061 | 1064 | if (id) { |
| 1062 | − /* Remove from branch classes from trunk */ | |
| 1065 | + /* Remove branch classes from trunk */ | |
| 1063 | 1066 | mux_config = id->driver_data; |
| 1064 | 1067 | for (i = 0; i < mux_config->n_values; i++) |
| 1065 | 1068 | class &= ~mux_config->classes[i]; |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | /* |
| 2 | 2 | * Freescale MXS I2C bus driver |
| 3 | 3 | * |
| 4 | − * Copyright (C) 2011 Wolfram Sang, Pengutronix e.K. | |
| 4 | + * Copyright (C) 2011-2012 Wolfram Sang, Pengutronix e.K. | |
| 5 | 5 | * |
| 6 | 6 | * based on a (non-working) driver which was: |
| 7 | 7 | * |
| @@ -35,10 +35,6 @@ · 27 unmodified lines | ||
| 35 | 35 | |
| 36 | 36 | #define DRIVER_NAME "mxs-i2c" |
| 37 | 37 | |
| 38 | −static bool use_pioqueue; | |
| 39 | −module_param(use_pioqueue, bool, 0); | |
| 40 | −MODULE_PARM_DESC(use_pioqueue, "Use PIOQUEUE mode for transfer instead of DMA"); | |
| 41 | − | |
| 42 | 38 | #define MXS_I2C_CTRL0 (0x00) |
| 43 | 39 | #define MXS_I2C_CTRL0_SET (0x04) |
| 44 | 40 | |
| @@ -75,23 +71,6 @@ MODULE_PARM_DESC(use_pioqueue, "Use PIOQUEUE mode for transfer instead of DMA"); · 30 unmodified lines | ||
| 75 | 71 | MXS_I2C_CTRL1_SLAVE_STOP_IRQ | \ |
| 76 | 72 | MXS_I2C_CTRL1_SLAVE_IRQ) |
| 77 | 73 | |
| 78 | −#define MXS_I2C_QUEUECTRL (0x60) | |
| 79 | −#define MXS_I2C_QUEUECTRL_SET (0x64) | |
| 80 | −#define MXS_I2C_QUEUECTRL_CLR (0x68) | |
| 81 | − | |
| 82 | −#define MXS_I2C_QUEUECTRL_QUEUE_RUN 0x20 | |
| 83 | −#define MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE 0x04 | |
| 84 | − | |
| 85 | −#define MXS_I2C_QUEUESTAT (0x70) | |
| 86 | −#define MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY 0x00002000 | |
| 87 | −#define MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK 0x0000001F | |
| 88 | − | |
| 89 | −#define MXS_I2C_QUEUECMD (0x80) | |
| 90 | − | |
| 91 | −#define MXS_I2C_QUEUEDATA (0x90) | |
| 92 | − | |
| 93 | −#define MXS_I2C_DATA (0xa0) | |
| 94 | − | |
| 95 | 74 | |
| 96 | 75 | #define MXS_CMD_I2C_SELECT (MXS_I2C_CTRL0_RETAIN_CLOCK | \ |
| 97 | 76 | MXS_I2C_CTRL0_PRE_SEND_START | \ |
| @@ -153,7 +132,6 @@ struct mxs_i2c_dev { · 55 unmodified lines | ||
| 153 | 132 | const struct mxs_i2c_speed_config *speed; |
| 154 | 133 | |
| 155 | 134 | /* DMA support components */ |
| 156 | − bool dma_mode; | |
| 157 | 135 | int dma_channel; |
| 158 | 136 | struct dma_chan *dmach; |
| 159 | 137 | struct mxs_dma_data dma_data; |
| @@ -172,99 +150,6 @@ static void mxs_i2c_reset(struct mxs_i2c_dev *i2c) · 12 unmodified lines | ||
| 172 | 150 | writel(i2c->speed->timing2, i2c->regs + MXS_I2C_TIMING2); |
| 173 | 151 | |
| 174 | 152 | writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET); |
| 175 | − if (i2c->dma_mode) | |
| 176 | − writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE, | |
| 177 | − i2c->regs + MXS_I2C_QUEUECTRL_CLR); | |
| 178 | − else | |
| 179 | − writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE, | |
| 180 | − i2c->regs + MXS_I2C_QUEUECTRL_SET); | |
| 181 | −} | |
| 182 | − | |
| 183 | −static void mxs_i2c_pioq_setup_read(struct mxs_i2c_dev *i2c, u8 addr, int len, | |
| 184 | − int flags) | |
| 185 | −{ | |
| 186 | − u32 data; | |
| 187 | − | |
| 188 | − writel(MXS_CMD_I2C_SELECT, i2c->regs + MXS_I2C_QUEUECMD); | |
| 189 | − | |
| 190 | − data = (addr << 1) | I2C_SMBUS_READ; | |
| 191 | − writel(data, i2c->regs + MXS_I2C_DATA); | |
| 192 | − | |
| 193 | − data = MXS_CMD_I2C_READ | MXS_I2C_CTRL0_XFER_COUNT(len) | flags; | |
| 194 | − writel(data, i2c->regs + MXS_I2C_QUEUECMD); | |
| 195 | −} | |
| 196 | − | |
| 197 | −static void mxs_i2c_pioq_setup_write(struct mxs_i2c_dev *i2c, | |
| 198 | − u8 addr, u8 *buf, int len, int flags) | |
| 199 | −{ | |
| 200 | − u32 data; | |
| 201 | − int i, shifts_left; | |
| 202 | − | |
| 203 | − data = MXS_CMD_I2C_WRITE | MXS_I2C_CTRL0_XFER_COUNT(len + 1) | flags; | |
| 204 | − writel(data, i2c->regs + MXS_I2C_QUEUECMD); | |
| 205 | − | |
| 206 | − /* | |
| 207 | − * We have to copy the slave address (u8) and buffer (arbitrary number | |
| 208 | − * of u8) into the data register (u32). To achieve that, the u8 are put | |
| 209 | − * into the MSBs of 'data' which is then shifted for the next u8. When | |
| 210 | − * appropriate, 'data' is written to MXS_I2C_DATA. So, the first u32 | |
| 211 | − * looks like this: | |
| 212 | − * | |
| 213 | − * 3 2 1 0 | |
| 214 | − * 10987654|32109876|54321098|76543210 | |
| 215 | − * --------+--------+--------+-------- | |
| 216 | − * buffer+2|buffer+1|buffer+0|slave_addr | |
| 217 | − */ | |
| 218 | − | |
| 219 | − data = ((addr << 1) | I2C_SMBUS_WRITE) << 24; | |
| 220 | − | |
| 221 | − for (i = 0; i < len; i++) { | |
| 222 | − data >>= 8; | |
| 223 | − data |= buf[i] << 24; | |
| 224 | − if ((i & 3) == 2) | |
| 225 | − writel(data, i2c->regs + MXS_I2C_DATA); | |
| 226 | − } | |
| 227 | − | |
| 228 | − /* Write out the remaining bytes if any */ | |
| 229 | − shifts_left = 24 - (i & 3) * 8; | |
| 230 | − if (shifts_left) | |
| 231 | − writel(data >> shifts_left, i2c->regs + MXS_I2C_DATA); | |
| 232 | −} | |
| 233 | − | |
| 234 | −/* | |
| 235 | − * TODO: should be replaceable with a waitqueue and RD_QUEUE_IRQ (setting the | |
| 236 | − * rd_threshold to 1). Couldn't get this to work, though. | |
| 237 | − */ | |
| 238 | −static int mxs_i2c_wait_for_data(struct mxs_i2c_dev *i2c) | |
| 239 | −{ | |
| 240 | − unsigned long timeout = jiffies + msecs_to_jiffies(1000); | |
| 241 | − | |
| 242 | − while (readl(i2c->regs + MXS_I2C_QUEUESTAT) | |
| 243 | − & MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY) { | |
| 244 | − if (time_after(jiffies, timeout)) | |
| 245 | − return -ETIMEDOUT; | |
| 246 | − cond_resched(); | |
| 247 | − } | |
| 248 | − | |
| 249 | − return 0; | |
| 250 | −} | |
| 251 | − | |
| 252 | −static int mxs_i2c_finish_read(struct mxs_i2c_dev *i2c, u8 *buf, int len) | |
| 253 | −{ | |
| 254 | − u32 uninitialized_var(data); | |
| 255 | − int i; | |
| 256 | − | |
| 257 | − for (i = 0; i < len; i++) { | |
| 258 | − if ((i & 3) == 0) { | |
| 259 | − if (mxs_i2c_wait_for_data(i2c)) | |
| 260 | − return -ETIMEDOUT; | |
| 261 | − data = readl(i2c->regs + MXS_I2C_QUEUEDATA); | |
| 262 | − } | |
| 263 | − buf[i] = data & 0xff; | |
| 264 | − data >>= 8; | |
| 265 | − } | |
| 266 | − | |
| 267 | − return 0; | |
| 268 | 153 | } |
| 269 | 154 | |
| 270 | 155 | static void mxs_i2c_dma_finish(struct mxs_i2c_dev *i2c) |
| @@ -402,12 +287,14 @@ read_init_dma_fail: · 131 unmodified lines | ||
| 402 | 287 | select_init_dma_fail: |
| 403 | 288 | dma_unmap_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE); |
| 404 | 289 | select_init_pio_fail: |
| 290 | + dmaengine_terminate_all(i2c->dmach); | |
| 405 | 291 | return -EINVAL; |
| 406 | 292 | |
| 407 | 293 | /* Write failpath. */ |
| 408 | 294 | write_init_dma_fail: |
| 409 | 295 | dma_unmap_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE); |
| 410 | 296 | write_init_pio_fail: |
| 297 | + dmaengine_terminate_all(i2c->dmach); | |
| 411 | 298 | return -EINVAL; |
| 412 | 299 | } |
| 413 | 300 | |
| @@ -432,39 +319,17 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, · 18 unmodified lines | ||
| 432 | 319 | init_completion(&i2c->cmd_complete); |
| 433 | 320 | i2c->cmd_err = 0; |
| 434 | 321 | |
| 435 | − if (i2c->dma_mode) { | |
| 436 | − ret = mxs_i2c_dma_setup_xfer(adap, msg, flags); | |
| 437 | − if (ret) | |
| 438 | − return ret; | |
| 439 | − } else { | |
| 440 | − if (msg->flags & I2C_M_RD) { | |
| 441 | − mxs_i2c_pioq_setup_read(i2c, msg->addr, | |
| 442 | − msg->len, flags); | |
| 443 | − } else { | |
| 444 | − mxs_i2c_pioq_setup_write(i2c, msg->addr, msg->buf, | |
| 445 | − msg->len, flags); | |
| 446 | − } | |
| 447 | − | |
| 448 | − writel(MXS_I2C_QUEUECTRL_QUEUE_RUN, | |
| 449 | − i2c->regs + MXS_I2C_QUEUECTRL_SET); | |
| 450 | − } | |
| 322 | + ret = mxs_i2c_dma_setup_xfer(adap, msg, flags); | |
| 323 | + if (ret) | |
| 324 | + return ret; | |
| 451 | 325 | |
| 452 | 326 | ret = wait_for_completion_timeout(&i2c->cmd_complete, |
| 453 | 327 | msecs_to_jiffies(1000)); |
| 454 | 328 | if (ret == 0) |
| 455 | 329 | goto timeout; |
| 456 | 330 | |
| 457 | − if (!i2c->dma_mode && !i2c->cmd_err && (msg->flags & I2C_M_RD)) { | |
| 458 | − ret = mxs_i2c_finish_read(i2c, msg->buf, msg->len); | |
| 459 | − if (ret) | |
| 460 | − goto timeout; | |
| 461 | − } | |
| 462 | − | |
| 463 | 331 | if (i2c->cmd_err == -ENXIO) |
| 464 | 332 | mxs_i2c_reset(i2c); |
| 465 | − else | |
| 466 | − writel(MXS_I2C_QUEUECTRL_QUEUE_RUN, | |
| 467 | − i2c->regs + MXS_I2C_QUEUECTRL_CLR); | |
| 468 | 333 | |
| 469 | 334 | dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err); |
| 470 | 335 | |
| @@ -472,8 +337,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, · 1 unmodified line | ||
| 472 | 337 | |
| 473 | 338 | timeout: |
| 474 | 339 | dev_dbg(i2c->dev, "Timeout!\n"); |
| 475 | − if (i2c->dma_mode) | |
| 476 | − mxs_i2c_dma_finish(i2c); | |
| 340 | + mxs_i2c_dma_finish(i2c); | |
| 477 | 341 | mxs_i2c_reset(i2c); |
| 478 | 342 | return -ETIMEDOUT; |
| 479 | 343 | } |
| @@ -502,7 +366,6 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) · 22 unmodified lines | ||
| 502 | 366 | { |
| 503 | 367 | struct mxs_i2c_dev *i2c = dev_id; |
| 504 | 368 | u32 stat = readl(i2c->regs + MXS_I2C_CTRL1) & MXS_I2C_IRQ_MASK; |
| 505 | − bool is_last_cmd; | |
| 506 | 369 | |
| 507 | 370 | if (!stat) |
| 508 | 371 | return IRQ_NONE; |
| @@ -515,14 +378,6 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) · 6 unmodified lines | ||
| 515 | 378 | /* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */ |
| 516 | 379 | i2c->cmd_err = -EIO; |
| 517 | 380 | |
| 518 | − if (!i2c->dma_mode) { | |
| 519 | − is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) & | |
| 520 | − MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0; | |
| 521 | − | |
| 522 | − if (is_last_cmd || i2c->cmd_err) | |
| 523 | − complete(&i2c->cmd_complete); | |
| 524 | − } | |
| 525 | − | |
| 526 | 381 | writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR); |
| 527 | 382 | |
| 528 | 383 | return IRQ_HANDLED; |
| @@ -555,15 +410,6 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c) · 26 unmodified lines | ||
| 555 | 410 | struct device_node *node = dev->of_node; |
| 556 | 411 | int ret; |
| 557 | 412 | |
| 558 | − /* | |
| 559 | − * The MXS I2C DMA mode is prefered and enabled by default. | |
| 560 | − * The PIO mode is still supported, but should be used only | |
| 561 | − * for debuging purposes etc. | |
| 562 | − */ | |
| 563 | − i2c->dma_mode = !use_pioqueue; | |
| 564 | − if (!i2c->dma_mode) | |
| 565 | − dev_info(dev, "Using PIOQUEUE mode for I2C transfers!\n"); | |
| 566 | − | |
| 567 | 413 | /* |
| 568 | 414 | * TODO: This is a temporary solution and should be changed |
| 569 | 415 | * to use generic DMA binding later when the helpers get in. |
| @@ -571,8 +417,8 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c) · 1 unmodified line | ||
| 571 | 417 | ret = of_property_read_u32(node, "fsl,i2c-dma-channel", |
| 572 | 418 | &i2c->dma_channel); |
| 573 | 419 | if (ret) { |
| 574 | − dev_warn(dev, "Failed to get DMA channel, using PIOQUEUE!\n"); | |
| 575 | − i2c->dma_mode = 0; | |
| 420 | + dev_err(dev, "Failed to get DMA channel!\n"); | |
| 421 | + return -ENODEV; | |
| 576 | 422 | } |
| 577 | 423 | |
| 578 | 424 | ret = of_property_read_u32(node, "clock-frequency", &speed); |
| @@ -634,15 +480,13 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev) · 55 unmodified lines | ||
| 634 | 480 | } |
| 635 | 481 | |
| 636 | 482 | /* Setup the DMA */ |
| 637 | − if (i2c->dma_mode) { | |
| 638 | − dma_cap_zero(mask); | |
| 639 | − dma_cap_set(DMA_SLAVE, mask); | |
| 640 | − i2c->dma_data.chan_irq = dmairq; | |
| 641 | − i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c); | |
| 642 | − if (!i2c->dmach) { | |
| 643 | − dev_err(dev, "Failed to request dma\n"); | |
| 644 | − return -ENODEV; | |
| 645 | − } | |
| 483 | + dma_cap_zero(mask); | |
| 484 | + dma_cap_set(DMA_SLAVE, mask); | |
| 485 | + i2c->dma_data.chan_irq = dmairq; | |
| 486 | + i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c); | |
| 487 | + if (!i2c->dmach) { | |
| 488 | + dev_err(dev, "Failed to request dma\n"); | |
| 489 | + return -ENODEV; | |
| 646 | 490 | } |
| 647 | 491 | |
| 648 | 492 | platform_set_drvdata(pdev, i2c); |
| @@ -644,7 +644,11 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap, · 643 unmodified lines | ||
| 644 | 644 | |
| 645 | 645 | pm_runtime_get_sync(&dev->adev->dev); |
| 646 | 646 | |
| 647 | − clk_enable(dev->clk); | |
| 647 | + status = clk_prepare_enable(dev->clk); | |
| 648 | + if (status) { | |
| 649 | + dev_err(&dev->adev->dev, "can't prepare_enable clock\n"); | |
| 650 | + goto out_clk; | |
| 651 | + } | |
| 648 | 652 | |
| 649 | 653 | status = init_hw(dev); |
| 650 | 654 | if (status) |
| @@ -671,7 +675,8 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap, · 20 unmodified lines | ||
| 671 | 675 | } |
| 672 | 676 | |
| 673 | 677 | out: |
| 674 | − clk_disable(dev->clk); | |
| 678 | + clk_disable_unprepare(dev->clk); | |
| 679 | +out_clk: | |
| 675 | 680 | pm_runtime_put_sync(&dev->adev->dev); |
| 676 | 681 | |
| 677 | 682 | dev->busy = false; |
| @@ -43,7 +43,6 @@ · 42 unmodified lines | ||
| 43 | 43 | #include <linux/slab.h> |
| 44 | 44 | #include <linux/i2c-omap.h> |
| 45 | 45 | #include <linux/pm_runtime.h> |
| 46 | −#include <linux/pm_qos.h> | |
| 47 | 46 | |
| 48 | 47 | /* I2C controller revisions */ |
| 49 | 48 | #define OMAP_I2C_OMAP1_REV_2 0x20 |
| @@ -187,8 +186,9 @@ struct omap_i2c_dev { · 137 unmodified lines | ||
| 187 | 186 | int reg_shift; /* bit shift for I2C register addresses */ |
| 188 | 187 | struct completion cmd_complete; |
| 189 | 188 | struct resource *ioarea; |
| 190 | − u32 latency; /* maximum MPU wkup latency */ | |
| 191 | − struct pm_qos_request pm_qos_request; | |
| 189 | + u32 latency; /* maximum mpu wkup latency */ | |
| 190 | + void (*set_mpu_wkup_lat)(struct device *dev, | |
| 191 | + long latency); | |
| 192 | 192 | u32 speed; /* Speed of bus in kHz */ |
| 193 | 193 | u32 dtrev; /* extra revision from DT */ |
| 194 | 194 | u32 flags; |
| @@ -494,7 +494,9 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx) · 299 unmodified lines | ||
| 494 | 494 | dev->b_hw = 1; /* Enable hardware fixes */ |
| 495 | 495 | |
| 496 | 496 | /* calculate wakeup latency constraint for MPU */ |
| 497 | − dev->latency = (1000000 * dev->threshold) / (1000 * dev->speed / 8); | |
| 497 | + if (dev->set_mpu_wkup_lat != NULL) | |
| 498 | + dev->latency = (1000000 * dev->threshold) / | |
| 499 | + (1000 * dev->speed / 8); | |
| 498 | 500 | } |
| 499 | 501 | |
| 500 | 502 | /* |
| @@ -522,6 +524,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, · 21 unmodified lines | ||
| 522 | 524 | dev->buf = msg->buf; |
| 523 | 525 | dev->buf_len = msg->len; |
| 524 | 526 | |
| 527 | + /* make sure writes to dev->buf_len are ordered */ | |
| 528 | + barrier(); | |
| 529 | + | |
| 525 | 530 | omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len); |
| 526 | 531 | |
| 527 | 532 | /* Clear the FIFO Buffers */ |
| @@ -579,7 +584,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, · 51 unmodified lines | ||
| 579 | 584 | */ |
| 580 | 585 | timeout = wait_for_completion_timeout(&dev->cmd_complete, |
| 581 | 586 | OMAP_I2C_TIMEOUT); |
| 582 | − dev->buf_len = 0; | |
| 583 | 587 | if (timeout == 0) { |
| 584 | 588 | dev_err(dev->dev, "controller timed out\n"); |
| 585 | 589 | omap_i2c_init(dev); |
| @@ -629,16 +633,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) · 43 unmodified lines | ||
| 629 | 633 | if (r < 0) |
| 630 | 634 | goto out; |
| 631 | 635 | |
| 632 | − /* | |
| 633 | − * When waiting for completion of a i2c transfer, we need to | |
| 634 | − * set a wake up latency constraint for the MPU. This is to | |
| 635 | − * ensure quick enough wakeup from idle, when transfer | |
| 636 | − * completes. | |
| 637 | − */ | |
| 638 | − if (dev->latency) | |
| 639 | − pm_qos_add_request(&dev->pm_qos_request, | |
| 640 | − PM_QOS_CPU_DMA_LATENCY, | |
| 641 | − dev->latency); | |
| 636 | + if (dev->set_mpu_wkup_lat != NULL) | |
| 637 | + dev->set_mpu_wkup_lat(dev->dev, dev->latency); | |
| 642 | 638 | |
| 643 | 639 | for (i = 0; i < num; i++) { |
| 644 | 640 | r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1))); |
| @@ -646,8 +642,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) · 1 unmodified line | ||
| 646 | 642 | break; |
| 647 | 643 | } |
| 648 | 644 | |
| 649 | − if (dev->latency) | |
| 650 | − pm_qos_remove_request(&dev->pm_qos_request); | |
| 645 | + if (dev->set_mpu_wkup_lat != NULL) | |
| 646 | + dev->set_mpu_wkup_lat(dev->dev, -1); | |
| 651 | 647 | |
| 652 | 648 | if (r == 0) |
| 653 | 649 | r = num; |
| @@ -1104,6 +1100,7 @@ omap_i2c_probe(struct platform_device *pdev) · 450 unmodified lines | ||
| 1104 | 1100 | } else if (pdata != NULL) { |
| 1105 | 1101 | dev->speed = pdata->clkrate; |
| 1106 | 1102 | dev->flags = pdata->flags; |
| 1103 | + dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat; | |
| 1107 | 1104 | dev->dtrev = pdata->rev; |
| 1108 | 1105 | } |
| 1109 | 1106 | |
| @@ -1159,8 +1156,9 @@ omap_i2c_probe(struct platform_device *pdev) · 49 unmodified lines | ||
| 1159 | 1156 | dev->b_hw = 1; /* Enable hardware fixes */ |
| 1160 | 1157 | |
| 1161 | 1158 | /* calculate wakeup latency constraint for MPU */ |
| 1162 | − dev->latency = (1000000 * dev->fifo_size) / | |
| 1163 | − (1000 * dev->speed / 8); | |
| 1159 | + if (dev->set_mpu_wkup_lat != NULL) | |
| 1160 | + dev->latency = (1000000 * dev->fifo_size) / | |
| 1161 | + (1000 * dev->speed / 8); | |
| 1164 | 1162 | } |
| 1165 | 1163 | |
| 1166 | 1164 | /* reset ASAP, clearing any IRQs */ |
| @@ -806,6 +806,7 @@ static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c) · 805 unmodified lines | ||
| 806 | 806 | dev_err(i2c->dev, "invalid gpio[%d]: %d\n", idx, gpio); |
| 807 | 807 | goto free_gpio; |
| 808 | 808 | } |
| 809 | + i2c->gpios[idx] = gpio; | |
| 809 | 810 | |
| 810 | 811 | ret = gpio_request(gpio, "i2c-bus"); |
| 811 | 812 | if (ret) { |
| @@ -742,7 +742,7 @@ static int __devinit tegra_i2c_probe(struct platform_device *pdev) · 741 unmodified lines | ||
| 742 | 742 | } |
| 743 | 743 | |
| 744 | 744 | ret = devm_request_irq(&pdev->dev, i2c_dev->irq, |
| 745 | − tegra_i2c_isr, 0, pdev->name, i2c_dev); | |
| 745 | + tegra_i2c_isr, 0, dev_name(&pdev->dev), i2c_dev); | |
| 746 | 746 | if (ret) { |
| 747 | 747 | dev_err(&pdev->dev, "Failed to request irq %i\n", i2c_dev->irq); |
| 748 | 748 | return ret; |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | i2c-stub.c - I2C/SMBus chip emulator |
| 3 | 3 | |
| 4 | 4 | Copyright (c) 2004 Mark M. Hoffman <mhoffman@lightlink.com> |
| 5 | − Copyright (C) 2007 Jean Delvare <khali@linux-fr.org> | |
| 5 | + Copyright (C) 2007, 2012 Jean Delvare <khali@linux-fr.org> | |
| 6 | 6 | |
| 7 | 7 | This program is free software; you can redistribute it and/or modify |
| 8 | 8 | it under the terms of the GNU General Public License as published by |
| @@ -51,8 +51,8 @@ struct stub_chip { · 42 unmodified lines | ||
| 51 | 51 | static struct stub_chip *stub_chips; |
| 52 | 52 | |
| 53 | 53 | /* Return negative errno on error. */ |
| 54 | −static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, | |
| 55 | − char read_write, u8 command, int size, union i2c_smbus_data * data) | |
| 54 | +static s32 stub_xfer(struct i2c_adapter *adap, u16 addr, unsigned short flags, | |
| 55 | + char read_write, u8 command, int size, union i2c_smbus_data *data) | |
| 56 | 56 | { |
| 57 | 57 | s32 ret; |
| 58 | 58 | int i, len; |
| @@ -78,14 +78,14 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, · 19 unmodified lines | ||
| 78 | 78 | case I2C_SMBUS_BYTE: |
| 79 | 79 | if (read_write == I2C_SMBUS_WRITE) { |
| 80 | 80 | chip->pointer = command; |
| 81 | − dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, " | |
| 82 | − "wrote 0x%02x.\n", | |
| 83 | − addr, command); | |
| 81 | + dev_dbg(&adap->dev, | |
| 82 | + "smbus byte - addr 0x%02x, wrote 0x%02x.\n", | |
| 83 | + addr, command); | |
| 84 | 84 | } else { |
| 85 | 85 | data->byte = chip->words[chip->pointer++] & 0xff; |
| 86 | − dev_dbg(&adap->dev, "smbus byte - addr 0x%02x, " | |
| 87 | − "read 0x%02x.\n", | |
| 88 | − addr, data->byte); | |
| 86 | + dev_dbg(&adap->dev, | |
| 87 | + "smbus byte - addr 0x%02x, read 0x%02x.\n", | |
| 88 | + addr, data->byte); | |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | 91 | ret = 0; |
| @@ -95,14 +95,14 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, · 3 unmodified lines | ||
| 95 | 95 | if (read_write == I2C_SMBUS_WRITE) { |
| 96 | 96 | chip->words[command] &= 0xff00; |
| 97 | 97 | chip->words[command] |= data->byte; |
| 98 | − dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, " | |
| 99 | − "wrote 0x%02x at 0x%02x.\n", | |
| 100 | − addr, data->byte, command); | |
| 98 | + dev_dbg(&adap->dev, | |
| 99 | + "smbus byte data - addr 0x%02x, wrote 0x%02x at 0x%02x.\n", | |
| 100 | + addr, data->byte, command); | |
| 101 | 101 | } else { |
| 102 | 102 | data->byte = chip->words[command] & 0xff; |
| 103 | − dev_dbg(&adap->dev, "smbus byte data - addr 0x%02x, " | |
| 104 | − "read 0x%02x at 0x%02x.\n", | |
| 105 | − addr, data->byte, command); | |
| 103 | + dev_dbg(&adap->dev, | |
| 104 | + "smbus byte data - addr 0x%02x, read 0x%02x at 0x%02x.\n", | |
| 105 | + addr, data->byte, command); | |
| 106 | 106 | } |
| 107 | 107 | chip->pointer = command + 1; |
| 108 | 108 | |
| @@ -112,14 +112,14 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, · 3 unmodified lines | ||
| 112 | 112 | case I2C_SMBUS_WORD_DATA: |
| 113 | 113 | if (read_write == I2C_SMBUS_WRITE) { |
| 114 | 114 | chip->words[command] = data->word; |
| 115 | − dev_dbg(&adap->dev, "smbus word data - addr 0x%02x, " | |
| 116 | − "wrote 0x%04x at 0x%02x.\n", | |
| 117 | − addr, data->word, command); | |
| 115 | + dev_dbg(&adap->dev, | |
| 116 | + "smbus word data - addr 0x%02x, wrote 0x%04x at 0x%02x.\n", | |
| 117 | + addr, data->word, command); | |
| 118 | 118 | } else { |
| 119 | 119 | data->word = chip->words[command]; |
| 120 | − dev_dbg(&adap->dev, "smbus word data - addr 0x%02x, " | |
| 121 | − "read 0x%04x at 0x%02x.\n", | |
| 122 | − addr, data->word, command); | |
| 120 | + dev_dbg(&adap->dev, | |
| 121 | + "smbus word data - addr 0x%02x, read 0x%04x at 0x%02x.\n", | |
| 122 | + addr, data->word, command); | |
| 123 | 123 | } |
| 124 | 124 | |
| 125 | 125 | ret = 0; |
| @@ -132,17 +132,17 @@ static s32 stub_xfer(struct i2c_adapter * adap, u16 addr, unsigned short flags, · 6 unmodified lines | ||
| 132 | 132 | chip->words[command + i] &= 0xff00; |
| 133 | 133 | chip->words[command + i] |= data->block[1 + i]; |
| 134 | 134 | } |
| 135 | − dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, " | |
| 136 | − "wrote %d bytes at 0x%02x.\n", | |
| 137 | − addr, len, command); | |
| 135 | + dev_dbg(&adap->dev, | |
| 136 | + "i2c block data - addr 0x%02x, wrote %d bytes at 0x%02x.\n", | |
| 137 | + addr, len, command); | |
| 138 | 138 | } else { |
| 139 | 139 | for (i = 0; i < len; i++) { |
| 140 | 140 | data->block[1 + i] = |
| 141 | 141 | chip->words[command + i] & 0xff; |
| 142 | 142 | } |
| 143 | − dev_dbg(&adap->dev, "i2c block data - addr 0x%02x, " | |
| 144 | − "read %d bytes at 0x%02x.\n", | |
| 145 | − addr, len, command); | |
| 143 | + dev_dbg(&adap->dev, | |
| 144 | + "i2c block data - addr 0x%02x, read %d bytes at 0x%02x.\n", | |
| 145 | + addr, len, command); | |
| 146 | 146 | } |
| 147 | 147 | |
| 148 | 148 | ret = 0; |
| @@ -179,25 +179,24 @@ static int __init i2c_stub_init(void) · 30 unmodified lines | ||
| 179 | 179 | int i, ret; |
| 180 | 180 | |
| 181 | 181 | if (!chip_addr[0]) { |
| 182 | − printk(KERN_ERR "i2c-stub: Please specify a chip address\n"); | |
| 182 | + pr_err("i2c-stub: Please specify a chip address\n"); | |
| 183 | 183 | return -ENODEV; |
| 184 | 184 | } |
| 185 | 185 | |
| 186 | 186 | for (i = 0; i < MAX_CHIPS && chip_addr[i]; i++) { |
| 187 | 187 | if (chip_addr[i] < 0x03 || chip_addr[i] > 0x77) { |
| 188 | − printk(KERN_ERR "i2c-stub: Invalid chip address " | |
| 189 | − "0x%02x\n", chip_addr[i]); | |
| 188 | + pr_err("i2c-stub: Invalid chip address 0x%02x\n", | |
| 189 | + chip_addr[i]); | |
| 190 | 190 | return -EINVAL; |
| 191 | 191 | } |
| 192 | 192 | |
| 193 | − printk(KERN_INFO "i2c-stub: Virtual chip at 0x%02x\n", | |
| 194 | − chip_addr[i]); | |
| 193 | + pr_info("i2c-stub: Virtual chip at 0x%02x\n", chip_addr[i]); | |
| 195 | 194 | } |
| 196 | 195 | |
| 197 | 196 | /* Allocate memory for all chips at once */ |
| 198 | 197 | stub_chips = kzalloc(i * sizeof(struct stub_chip), GFP_KERNEL); |
| 199 | 198 | if (!stub_chips) { |
| 200 | − printk(KERN_ERR "i2c-stub: Out of memory\n"); | |
| 199 | + pr_err("i2c-stub: Out of memory\n"); | |
| 201 | 200 | return -ENOMEM; |
| 202 | 201 | } |
| 203 | 202 | |
| @@ -219,4 +218,3 @@ MODULE_LICENSE("GPL"); · 15 unmodified lines | ||
| 219 | 218 | |
| 220 | 219 | module_init(i2c_stub_init); |
| 221 | 220 | module_exit(i2c_stub_exit); |
| 222 | − | |
| @@ -169,7 +169,7 @@ static int __devinit i2c_mux_pinctrl_probe(struct platform_device *pdev) · 168 unmodified lines | ||
| 169 | 169 | mux->busses = devm_kzalloc(&pdev->dev, |
| 170 | 170 | sizeof(mux->busses) * mux->pdata->bus_count, |
| 171 | 171 | GFP_KERNEL); |
| 172 | − if (!mux->states) { | |
| 172 | + if (!mux->busses) { | |
| 173 | 173 | dev_err(&pdev->dev, "Cannot allocate busses\n"); |
| 174 | 174 | ret = -ENOMEM; |
| 175 | 175 | goto err; |
| @@ -62,7 +62,6 @@ source "drivers/iio/frequency/Kconfig" · 61 unmodified lines | ||
| 62 | 62 | source "drivers/iio/dac/Kconfig" |
| 63 | 63 | source "drivers/iio/common/Kconfig" |
| 64 | 64 | source "drivers/iio/gyro/Kconfig" |
| 65 | −source "drivers/iio/light/Kconfig" | |
| 66 | 65 | source "drivers/iio/magnetometer/Kconfig" |
| 67 | 66 | |
| 68 | 67 | endif # IIO |
| @@ -18,5 +18,4 @@ obj-y += frequency/ · 17 unmodified lines | ||
| 18 | 18 | obj-y += dac/ |
| 19 | 19 | obj-y += common/ |
| 20 | 20 | obj-y += gyro/ |
| 21 | −obj-y += light/ | |
| 22 | 21 | obj-y += magnetometer/ |
| @@ -468,7 +468,7 @@ struct ib_mr *c4iw_register_phys_mem(struct ib_pd *pd, · 467 unmodified lines | ||
| 468 | 468 | ret = alloc_pbl(mhp, npages); |
| 469 | 469 | if (ret) { |
| 470 | 470 | kfree(page_list); |
| 471 | − goto err_pbl; | |
| 471 | + goto err; | |
| 472 | 472 | } |
| 473 | 473 | |
| 474 | 474 | ret = write_pbl(&mhp->rhp->rdev, page_list, mhp->attr.pbl_addr, |
| @@ -107,7 +107,7 @@ static __be64 get_cached_alias_guid(struct mlx4_ib_dev *dev, int port, int index · 106 unmodified lines | ||
| 107 | 107 | { |
| 108 | 108 | if (index >= NUM_ALIAS_GUID_PER_PORT) { |
| 109 | 109 | pr_err("%s: ERROR: asked for index:%d\n", __func__, index); |
| 110 | − return (__force __be64) ((u64) 0xFFFFFFFFFFFFFFFFUL); | |
| 110 | + return (__force __be64) -1; | |
| 111 | 111 | } |
| 112 | 112 | return *(__be64 *)&dev->sriov.demux[port - 1].guid_cache[index]; |
| 113 | 113 | } |
| @@ -409,38 +409,45 @@ int mlx4_ib_find_real_gid(struct ib_device *ibdev, u8 port, __be64 guid) · 408 unmodified lines | ||
| 409 | 409 | } |
| 410 | 410 | |
| 411 | 411 | |
| 412 | −static int get_pkey_phys_indices(struct mlx4_ib_dev *ibdev, u8 port, u8 ph_pkey_ix, | |
| 413 | − u8 *full_pk_ix, u8 *partial_pk_ix, | |
| 414 | − int *is_full_member) | |
| 412 | +static int find_slave_port_pkey_ix(struct mlx4_ib_dev *dev, int slave, | |
| 413 | + u8 port, u16 pkey, u16 *ix) | |
| 415 | 414 | { |
| 416 | − u16 search_pkey; | |
| 417 | − int fm; | |
| 418 | − int err = 0; | |
| 419 | − u16 pk; | |
| 415 | + int i, ret; | |
| 416 | + u8 unassigned_pkey_ix, pkey_ix, partial_ix = 0xFF; | |
| 417 | + u16 slot_pkey; | |
| 420 | 418 | |
| 421 | − err = ib_get_cached_pkey(&ibdev->ib_dev, port, ph_pkey_ix, &search_pkey); | |
| 422 | − if (err) | |
| 423 | − return err; | |
| 419 | + if (slave == mlx4_master_func_num(dev->dev)) | |
| 420 | + return ib_find_cached_pkey(&dev->ib_dev, port, pkey, ix); | |
| 424 | 421 | |
| 425 | − fm = (search_pkey & 0x8000) ? 1 : 0; | |
| 426 | − if (fm) { | |
| 427 | − *full_pk_ix = ph_pkey_ix; | |
| 428 | − search_pkey &= 0x7FFF; | |
| 429 | − } else { | |
| 430 | − *partial_pk_ix = ph_pkey_ix; | |
| 431 | − search_pkey |= 0x8000; | |
| 432 | − } | |
| 422 | + unassigned_pkey_ix = dev->dev->phys_caps.pkey_phys_table_len[port] - 1; | |
| 433 | 423 | |
| 434 | − if (ib_find_exact_cached_pkey(&ibdev->ib_dev, port, search_pkey, &pk)) | |
| 435 | − pk = 0xFFFF; | |
| 424 | + for (i = 0; i < dev->dev->caps.pkey_table_len[port]; i++) { | |
| 425 | + if (dev->pkeys.virt2phys_pkey[slave][port - 1][i] == unassigned_pkey_ix) | |
| 426 | + continue; | |
| 436 | 427 | |
| 437 | − if (fm) | |
| 438 | − *partial_pk_ix = (pk & 0xFF); | |
| 439 | − else | |
| 440 | − *full_pk_ix = (pk & 0xFF); | |
| 428 | + pkey_ix = dev->pkeys.virt2phys_pkey[slave][port - 1][i]; | |
| 441 | 429 | |
| 442 | − *is_full_member = fm; | |
| 443 | − return err; | |
| 430 | + ret = ib_get_cached_pkey(&dev->ib_dev, port, pkey_ix, &slot_pkey); | |
| 431 | + if (ret) | |
| 432 | + continue; | |
| 433 | + if ((slot_pkey & 0x7FFF) == (pkey & 0x7FFF)) { | |
| 434 | + if (slot_pkey & 0x8000) { | |
| 435 | + *ix = (u16) pkey_ix; | |
| 436 | + return 0; | |
| 437 | + } else { | |
| 438 | + /* take first partial pkey index found */ | |
| 439 | + if (partial_ix == 0xFF) | |
| 440 | + partial_ix = pkey_ix; | |
| 441 | + } | |
| 442 | + } | |
| 443 | + } | |
| 444 | + | |
| 445 | + if (partial_ix < 0xFF) { | |
| 446 | + *ix = (u16) partial_ix; | |
| 447 | + return 0; | |
| 448 | + } | |
| 449 | + | |
| 450 | + return -EINVAL; | |
| 444 | 451 | } |
| 445 | 452 | |
| 446 | 453 | int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, |
| @@ -458,10 +465,8 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, · 11 unmodified lines | ||
| 458 | 465 | unsigned tun_tx_ix = 0; |
| 459 | 466 | int dqpn; |
| 460 | 467 | int ret = 0; |
| 461 | − int i; | |
| 462 | − int is_full_member = 0; | |
| 463 | 468 | u16 tun_pkey_ix; |
| 464 | − u8 ph_pkey_ix, full_pk_ix = 0, partial_pk_ix = 0; | |
| 469 | + u16 cached_pkey; | |
| 465 | 470 | |
| 466 | 471 | if (dest_qpt > IB_QPT_GSI) |
| 467 | 472 | return -EINVAL; |
| @@ -481,27 +486,17 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port, · 13 unmodified lines | ||
| 481 | 486 | else |
| 482 | 487 | tun_qp = &tun_ctx->qp[1]; |
| 483 | 488 | |
| 484 | − /* compute pkey index for slave */ | |
| 485 | − /* get physical pkey -- virtualized Dom0 pkey to phys*/ | |
| 489 | + /* compute P_Key index to put in tunnel header for slave */ | |
| 486 | 490 | if (dest_qpt) { |
| 487 | − ph_pkey_ix = | |
| 488 | − dev->pkeys.virt2phys_pkey[mlx4_master_func_num(dev->dev)][port - 1][wc->pkey_index]; | |
| 489 | − | |
| 490 | − /* now, translate this to the slave pkey index */ | |
| 491 | − ret = get_pkey_phys_indices(dev, port, ph_pkey_ix, &full_pk_ix, | |
| 492 | − &partial_pk_ix, &is_full_member); | |
| 491 | + u16 pkey_ix; | |
| 492 | + ret = ib_get_cached_pkey(&dev->ib_dev, port, wc->pkey_index, &cached_pkey); | |
| 493 | 493 | if (ret) |
| 494 | 494 | return -EINVAL; |
| 495 | 495 | |
| 496 | − for (i = 0; i < dev->dev->caps.pkey_table_len[port]; i++) { | |
| 497 | − if ((dev->pkeys.virt2phys_pkey[slave][port - 1][i] == full_pk_ix) || | |
| 498 | − (is_full_member && | |
| 499 | − (dev->pkeys.virt2phys_pkey[slave][port - 1][i] == partial_pk_ix))) | |
| 500 | − break; | |
| 501 | − } | |
| 502 | − if (i == dev->dev->caps.pkey_table_len[port]) | |
| 496 | + ret = find_slave_port_pkey_ix(dev, slave, port, cached_pkey, &pkey_ix); | |
| 497 | + if (ret) | |
| 503 | 498 | return -EINVAL; |
| 504 | − tun_pkey_ix = i; | |
| 499 | + tun_pkey_ix = pkey_ix; | |
| 505 | 500 | } else |
| 506 | 501 | tun_pkey_ix = dev->pkeys.virt2phys_pkey[slave][port - 1][0]; |
| 507 | 502 | |
| @@ -233,7 +233,8 @@ static int send_mad_to_slave(int slave, struct mlx4_ib_demux_ctx *ctx, · 232 unmodified lines | ||
| 233 | 233 | |
| 234 | 234 | ib_query_ah(dev->sm_ah[ctx->port - 1], &ah_attr); |
| 235 | 235 | |
| 236 | − wc.pkey_index = 0; | |
| 236 | + if (ib_find_cached_pkey(&dev->ib_dev, ctx->port, IB_DEFAULT_PKEY_FULL, &wc.pkey_index)) | |
| 237 | + return -EINVAL; | |
| 237 | 238 | wc.sl = 0; |
| 238 | 239 | wc.dlid_path_bits = 0; |
| 239 | 240 | wc.port_num = ctx->port; |
| @@ -1074,10 +1075,6 @@ static void _mlx4_ib_mcg_port_cleanup(struct mlx4_ib_demux_ctx *ctx, int destroy · 834 unmodified lines | ||
| 1074 | 1075 | unsigned long end; |
| 1075 | 1076 | int count; |
| 1076 | 1077 | |
| 1077 | − if (ctx->flushing) | |
| 1078 | − return; | |
| 1079 | − | |
| 1080 | − ctx->flushing = 1; | |
| 1081 | 1078 | for (i = 0; i < MAX_VFS; ++i) |
| 1082 | 1079 | clean_vf_mcast(ctx, i); |
| 1083 | 1080 | |
| @@ -1107,9 +1104,6 @@ static void _mlx4_ib_mcg_port_cleanup(struct mlx4_ib_demux_ctx *ctx, int destroy · 23 unmodified lines | ||
| 1107 | 1104 | force_clean_group(group); |
| 1108 | 1105 | } |
| 1109 | 1106 | mutex_unlock(&ctx->mcg_table_lock); |
| 1110 | − | |
| 1111 | − if (!destroy_wq) | |
| 1112 | − ctx->flushing = 0; | |
| 1113 | 1107 | } |
| 1114 | 1108 | |
| 1115 | 1109 | struct clean_work { |
| @@ -1123,6 +1117,7 @@ static void mcg_clean_task(struct work_struct *work) · 7 unmodified lines | ||
| 1123 | 1117 | struct clean_work *cw = container_of(work, struct clean_work, work); |
| 1124 | 1118 | |
| 1125 | 1119 | _mlx4_ib_mcg_port_cleanup(cw->ctx, cw->destroy_wq); |
| 1120 | + cw->ctx->flushing = 0; | |
| 1126 | 1121 | kfree(cw); |
| 1127 | 1122 | } |
| 1128 | 1123 | |
| @@ -1130,13 +1125,20 @@ void mlx4_ib_mcg_port_cleanup(struct mlx4_ib_demux_ctx *ctx, int destroy_wq) · 1 unmodified line | ||
| 1130 | 1125 | { |
| 1131 | 1126 | struct clean_work *work; |
| 1132 | 1127 | |
| 1128 | + if (ctx->flushing) | |
| 1129 | + return; | |
| 1130 | + | |
| 1131 | + ctx->flushing = 1; | |
| 1132 | + | |
| 1133 | 1133 | if (destroy_wq) { |
| 1134 | 1134 | _mlx4_ib_mcg_port_cleanup(ctx, destroy_wq); |
| 1135 | + ctx->flushing = 0; | |
| 1135 | 1136 | return; |
| 1136 | 1137 | } |
| 1137 | 1138 | |
| 1138 | 1139 | work = kmalloc(sizeof *work, GFP_KERNEL); |
| 1139 | 1140 | if (!work) { |
| 1141 | + ctx->flushing = 0; | |
| 1140 | 1142 | mcg_warn("failed allocating work for cleanup\n"); |
| 1141 | 1143 | return; |
| 1142 | 1144 | } |
| @@ -26,10 +26,14 @@ static void copy_abs(struct input_dev *dev, unsigned int dst, unsigned int src) · 25 unmodified lines | ||
| 26 | 26 | * input_mt_init_slots() - initialize MT input slots |
| 27 | 27 | * @dev: input device supporting MT events and finger tracking |
| 28 | 28 | * @num_slots: number of slots used by the device |
| 29 | + * @flags: mt tasks to handle in core | |
| 29 | 30 | * |
| 30 | 31 | * This function allocates all necessary memory for MT slot handling |
| 31 | 32 | * in the input device, prepares the ABS_MT_SLOT and |
| 32 | 33 | * ABS_MT_TRACKING_ID events for use and sets up appropriate buffers. |
| 34 | + * Depending on the flags set, it also performs pointer emulation and | |
| 35 | + * frame synchronization. | |
| 36 | + * | |
| 33 | 37 | * May be called repeatedly. Returns -EINVAL if attempting to |
| 34 | 38 | * reinitialize with a different number of slots. |
| 35 | 39 | */ |
| @@ -335,6 +335,7 @@ config KEYBOARD_LOCOMO · 334 unmodified lines | ||
| 335 | 335 | config KEYBOARD_LPC32XX |
| 336 | 336 | tristate "LPC32XX matrix key scanner support" |
| 337 | 337 | depends on ARCH_LPC32XX && OF |
| 338 | + select INPUT_MATRIXKMAP | |
| 338 | 339 | help |
| 339 | 340 | Say Y here if you want to use NXP LPC32XX SoC key scanner interface, |
| 340 | 341 | connected to a key matrix. |
| @@ -368,6 +368,9 @@ static void pxa27x_keypad_config(struct pxa27x_keypad *keypad) · 367 unmodified lines | ||
| 368 | 368 | unsigned int mask = 0, direct_key_num = 0; |
| 369 | 369 | unsigned long kpc = 0; |
| 370 | 370 | |
| 371 | + /* clear pending interrupt bit */ | |
| 372 | + keypad_readl(KPC); | |
| 373 | + | |
| 371 | 374 | /* enable matrix keys with automatic scan */ |
| 372 | 375 | if (pdata->matrix_key_rows && pdata->matrix_key_cols) { |
| 373 | 376 | kpc |= KPC_ASACT | KPC_MIE | KPC_ME | KPC_MS_ALL; |
| @@ -311,7 +311,6 @@ static void xenkbd_backend_changed(struct xenbus_device *dev, · 310 unmodified lines | ||
| 311 | 311 | case XenbusStateReconfiguring: |
| 312 | 312 | case XenbusStateReconfigured: |
| 313 | 313 | case XenbusStateUnknown: |
| 314 | − case XenbusStateClosed: | |
| 315 | 314 | break; |
| 316 | 315 | |
| 317 | 316 | case XenbusStateInitWait: |
| @@ -350,6 +349,10 @@ InitWait: · 32 unmodified lines | ||
| 350 | 349 | |
| 351 | 350 | break; |
| 352 | 351 | |
| 352 | + case XenbusStateClosed: | |
| 353 | + if (dev->state == XenbusStateClosed) | |
| 354 | + break; | |
| 355 | + /* Missed the backend's CLOSING state -- fallthrough */ | |
| 353 | 356 | case XenbusStateClosing: |
| 354 | 357 | xenbus_frontend_closed(dev); |
| 355 | 358 | break; |
| @@ -84,6 +84,10 @@ · 83 unmodified lines | ||
| 84 | 84 | #define USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI 0x0262 |
| 85 | 85 | #define USB_DEVICE_ID_APPLE_WELLSPRING7_ISO 0x0263 |
| 86 | 86 | #define USB_DEVICE_ID_APPLE_WELLSPRING7_JIS 0x0264 |
| 87 | +/* MacbookPro10,2 (unibody, October 2012) */ | |
| 88 | +#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI 0x0259 | |
| 89 | +#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO 0x025a | |
| 90 | +#define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS 0x025b | |
| 87 | 91 | |
| 88 | 92 | #define BCM5974_DEVICE(prod) { \ |
| 89 | 93 | .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ |
| @@ -137,6 +141,10 @@ static const struct usb_device_id bcm5974_table[] = { · 47 unmodified lines | ||
| 137 | 141 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI), |
| 138 | 142 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ISO), |
| 139 | 143 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_JIS), |
| 144 | + /* MacbookPro10,2 */ | |
| 145 | + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI), | |
| 146 | + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO), | |
| 147 | + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS), | |
| 140 | 148 | /* Terminating entry */ |
| 141 | 149 | {} |
| 142 | 150 | }; |
| @@ -379,6 +387,19 @@ static const struct bcm5974_config bcm5974_config_table[] = { · 236 unmodified lines | ||
| 379 | 387 | { SN_COORD, -150, 6730 }, |
| 380 | 388 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } |
| 381 | 389 | }, |
| 390 | + { | |
| 391 | + USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI, | |
| 392 | + USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO, | |
| 393 | + USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS, | |
| 394 | + HAS_INTEGRATED_BUTTON, | |
| 395 | + 0x84, sizeof(struct bt_data), | |
| 396 | + 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | |
| 397 | + { SN_PRESSURE, 0, 300 }, | |
| 398 | + { SN_WIDTH, 0, 2048 }, | |
| 399 | + { SN_COORD, -4750, 5280 }, | |
| 400 | + { SN_COORD, -150, 6730 }, | |
| 401 | + { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | |
| 402 | + }, | |
| 382 | 403 | {} |
| 383 | 404 | }; |
| 384 | 405 | |
| @@ -12,8 +12,8 @@ · 11 unmodified lines | ||
| 12 | 12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 13 | 13 | |
| 14 | 14 | #define MOUSEDEV_MINOR_BASE 32 |
| 15 | −#define MOUSEDEV_MINORS 32 | |
| 16 | −#define MOUSEDEV_MIX 31 | |
| 15 | +#define MOUSEDEV_MINORS 31 | |
| 16 | +#define MOUSEDEV_MIX 63 | |
| 17 | 17 | |
| 18 | 18 | #include <linux/sched.h> |
| 19 | 19 | #include <linux/slab.h> |
| @@ -391,7 +391,7 @@ static int wacom_parse_hid(struct usb_interface *intf, · 390 unmodified lines | ||
| 391 | 391 | features->pktlen = WACOM_PKGLEN_TPC2FG; |
| 392 | 392 | } |
| 393 | 393 | |
| 394 | − if (features->type == MTSCREEN) | |
| 394 | + if (features->type == MTSCREEN || features->type == WACOM_24HDT) | |
| 395 | 395 | features->pktlen = WACOM_PKGLEN_MTOUCH; |
| 396 | 396 | |
| 397 | 397 | if (features->type == BAMBOO_PT) { |
| @@ -402,6 +402,14 @@ static int wacom_parse_hid(struct usb_interface *intf, · 4 unmodified lines | ||
| 402 | 402 | features->x_max = |
| 403 | 403 | get_unaligned_le16(&report[i + 8]); |
| 404 | 404 | i += 15; |
| 405 | + } else if (features->type == WACOM_24HDT) { | |
| 406 | + features->x_max = | |
| 407 | + get_unaligned_le16(&report[i + 3]); | |
| 408 | + features->x_phy = | |
| 409 | + get_unaligned_le16(&report[i + 8]); | |
| 410 | + features->unit = report[i - 1]; | |
| 411 | + features->unitExpo = report[i - 3]; | |
| 412 | + i += 12; | |
| 405 | 413 | } else { |
| 406 | 414 | features->x_max = |
| 407 | 415 | get_unaligned_le16(&report[i + 3]); |
| @@ -434,6 +442,12 @@ static int wacom_parse_hid(struct usb_interface *intf, · 26 unmodified lines | ||
| 434 | 442 | features->y_phy = |
| 435 | 443 | get_unaligned_le16(&report[i + 6]); |
| 436 | 444 | i += 7; |
| 445 | + } else if (type == WACOM_24HDT) { | |
| 446 | + features->y_max = | |
| 447 | + get_unaligned_le16(&report[i + 3]); | |
| 448 | + features->y_phy = | |
| 449 | + get_unaligned_le16(&report[i - 2]); | |
| 450 | + i += 7; | |
| 437 | 451 | } else if (type == BAMBOO_PT) { |
| 438 | 452 | features->y_phy = |
| 439 | 453 | get_unaligned_le16(&report[i + 3]); |
| @@ -541,6 +555,9 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat · 101 unmodified lines | ||
| 541 | 555 | /* MT Tablet PC touch */ |
| 542 | 556 | return wacom_set_device_mode(intf, 3, 4, 4); |
| 543 | 557 | } |
| 558 | + else if (features->type == WACOM_24HDT) { | |
| 559 | + return wacom_set_device_mode(intf, 18, 3, 2); | |
| 560 | + } | |
| 544 | 561 | } else if (features->device_type == BTN_TOOL_PEN) { |
| 545 | 562 | if (features->type <= BAMBOO_PT && features->type != WIRELESS) { |
| 546 | 563 | return wacom_set_device_mode(intf, 2, 2, 2); |
| @@ -613,6 +630,30 @@ struct wacom_usbdev_data { · 66 unmodified lines | ||
| 613 | 630 | static LIST_HEAD(wacom_udev_list); |
| 614 | 631 | static DEFINE_MUTEX(wacom_udev_list_lock); |
| 615 | 632 | |
| 633 | +static struct usb_device *wacom_get_sibling(struct usb_device *dev, int vendor, int product) | |
| 634 | +{ | |
| 635 | + int port1; | |
| 636 | + struct usb_device *sibling; | |
| 637 | + | |
| 638 | + if (vendor == 0 && product == 0) | |
| 639 | + return dev; | |
| 640 | + | |
| 641 | + if (dev->parent == NULL) | |
| 642 | + return NULL; | |
| 643 | + | |
| 644 | + usb_hub_for_each_child(dev->parent, port1, sibling) { | |
| 645 | + struct usb_device_descriptor *d; | |
| 646 | + if (sibling == NULL) | |
| 647 | + continue; | |
| 648 | + | |
| 649 | + d = &sibling->descriptor; | |
| 650 | + if (d->idVendor == vendor && d->idProduct == product) | |
| 651 | + return sibling; | |
| 652 | + } | |
| 653 | + | |
| 654 | + return NULL; | |
| 655 | +} | |
| 656 | + | |
| 616 | 657 | static struct wacom_usbdev_data *wacom_get_usbdev_data(struct usb_device *dev) |
| 617 | 658 | { |
| 618 | 659 | struct wacom_usbdev_data *data; |
| @@ -1257,13 +1298,19 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i · 638 unmodified lines | ||
| 1257 | 1298 | strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name)); |
| 1258 | 1299 | |
| 1259 | 1300 | if (features->quirks & WACOM_QUIRK_MULTI_INPUT) { |
| 1301 | + struct usb_device *other_dev; | |
| 1302 | + | |
| 1260 | 1303 | /* Append the device type to the name */ |
| 1261 | 1304 | strlcat(wacom_wac->name, |
| 1262 | 1305 | features->device_type == BTN_TOOL_PEN ? |
| 1263 | 1306 | " Pen" : " Finger", |
| 1264 | 1307 | sizeof(wacom_wac->name)); |
| 1265 | 1308 | |
| 1266 | − error = wacom_add_shared_data(wacom_wac, dev); | |
| 1309 | + | |
| 1310 | + other_dev = wacom_get_sibling(dev, features->oVid, features->oPid); | |
| 1311 | + if (other_dev == NULL || wacom_get_usbdev_data(other_dev) == NULL) | |
| 1312 | + other_dev = dev; | |
| 1313 | + error = wacom_add_shared_data(wacom_wac, other_dev); | |
| 1267 | 1314 | if (error) |
| 1268 | 1315 | goto fail3; |
| 1269 | 1316 | } |
| @@ -806,6 +806,70 @@ static int find_slot_from_contactid(struct wacom_wac *wacom, int contactid) · 805 unmodified lines | ||
| 806 | 806 | return -1; |
| 807 | 807 | } |
| 808 | 808 | |
| 809 | +static int int_dist(int x1, int y1, int x2, int y2) | |
| 810 | +{ | |
| 811 | + int x = x2 - x1; | |
| 812 | + int y = y2 - y1; | |
| 813 | + | |
| 814 | + return int_sqrt(x*x + y*y); | |
| 815 | +} | |
| 816 | + | |
| 817 | +static int wacom_24hdt_irq(struct wacom_wac *wacom) | |
| 818 | +{ | |
| 819 | + struct input_dev *input = wacom->input; | |
| 820 | + char *data = wacom->data; | |
| 821 | + int i; | |
| 822 | + int current_num_contacts = data[61]; | |
| 823 | + int contacts_to_send = 0; | |
| 824 | + | |
| 825 | + /* | |
| 826 | + * First packet resets the counter since only the first | |
| 827 | + * packet in series will have non-zero current_num_contacts. | |
| 828 | + */ | |
| 829 | + if (current_num_contacts) | |
| 830 | + wacom->num_contacts_left = current_num_contacts; | |
| 831 | + | |
| 832 | + /* There are at most 4 contacts per packet */ | |
| 833 | + contacts_to_send = min(4, wacom->num_contacts_left); | |
| 834 | + | |
| 835 | + for (i = 0; i < contacts_to_send; i++) { | |
| 836 | + int offset = (WACOM_BYTES_PER_24HDT_PACKET * i) + 1; | |
| 837 | + bool touch = data[offset] & 0x1 && !wacom->shared->stylus_in_proximity; | |
| 838 | + int id = data[offset + 1]; | |
| 839 | + int slot = find_slot_from_contactid(wacom, id); | |
| 840 | + | |
| 841 | + if (slot < 0) | |
| 842 | + continue; | |
| 843 | + input_mt_slot(input, slot); | |
| 844 | + input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); | |
| 845 | + | |
| 846 | + if (touch) { | |
| 847 | + int t_x = le16_to_cpup((__le16 *)&data[offset + 2]); | |
| 848 | + int c_x = le16_to_cpup((__le16 *)&data[offset + 4]); | |
| 849 | + int t_y = le16_to_cpup((__le16 *)&data[offset + 6]); | |
| 850 | + int c_y = le16_to_cpup((__le16 *)&data[offset + 8]); | |
| 851 | + int w = le16_to_cpup((__le16 *)&data[offset + 10]); | |
| 852 | + int h = le16_to_cpup((__le16 *)&data[offset + 12]); | |
| 853 | + | |
| 854 | + input_report_abs(input, ABS_MT_POSITION_X, t_x); | |
| 855 | + input_report_abs(input, ABS_MT_POSITION_Y, t_y); | |
| 856 | + input_report_abs(input, ABS_MT_TOUCH_MAJOR, min(w,h)); | |
| 857 | + input_report_abs(input, ABS_MT_WIDTH_MAJOR, min(w, h) + int_dist(t_x, t_y, c_x, c_y)); | |
| 858 | + input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h)); | |
| 859 | + input_report_abs(input, ABS_MT_ORIENTATION, w > h); | |
| 860 | + } | |
| 861 | + wacom->slots[slot] = touch ? id : -1; | |
| 862 | + } | |
| 863 | + | |
| 864 | + input_mt_report_pointer_emulation(input, true); | |
| 865 | + | |
| 866 | + wacom->num_contacts_left -= contacts_to_send; | |
| 867 | + if (wacom->num_contacts_left <= 0) | |
| 868 | + wacom->num_contacts_left = 0; | |
| 869 | + | |
| 870 | + return 1; | |
| 871 | +} | |
| 872 | + | |
| 809 | 873 | static int wacom_mt_touch(struct wacom_wac *wacom) |
| 810 | 874 | { |
| 811 | 875 | struct input_dev *input = wacom->input; |
| @@ -1255,6 +1319,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) · 443 unmodified lines | ||
| 1255 | 1319 | sync = wacom_intuos_irq(wacom_wac); |
| 1256 | 1320 | break; |
| 1257 | 1321 | |
| 1322 | + case WACOM_24HDT: | |
| 1323 | + sync = wacom_24hdt_irq(wacom_wac); | |
| 1324 | + break; | |
| 1325 | + | |
| 1258 | 1326 | case INTUOS5S: |
| 1259 | 1327 | case INTUOS5: |
| 1260 | 1328 | case INTUOS5L: |
| @@ -1340,7 +1408,8 @@ void wacom_setup_device_quirks(struct wacom_features *features) · 79 unmodified lines | ||
| 1340 | 1408 | |
| 1341 | 1409 | /* these device have multiple inputs */ |
| 1342 | 1410 | if (features->type >= WIRELESS || |
| 1343 | − (features->type >= INTUOS5S && features->type <= INTUOS5L)) | |
| 1411 | + (features->type >= INTUOS5S && features->type <= INTUOS5L) || | |
| 1412 | + (features->oVid && features->oPid)) | |
| 1344 | 1413 | features->quirks |= WACOM_QUIRK_MULTI_INPUT; |
| 1345 | 1414 | |
| 1346 | 1415 | /* quirk for bamboo touch with 2 low res touches */ |
| @@ -1449,6 +1518,9 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, · 102 unmodified lines | ||
| 1449 | 1518 | |
| 1450 | 1519 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); |
| 1451 | 1520 | input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0); |
| 1521 | + | |
| 1522 | + __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); | |
| 1523 | + | |
| 1452 | 1524 | wacom_setup_cintiq(wacom_wac); |
| 1453 | 1525 | break; |
| 1454 | 1526 | |
| @@ -1575,6 +1647,15 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, · 120 unmodified lines | ||
| 1575 | 1647 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); |
| 1576 | 1648 | break; |
| 1577 | 1649 | |
| 1650 | + case WACOM_24HDT: | |
| 1651 | + if (features->device_type == BTN_TOOL_FINGER) { | |
| 1652 | + input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, features->x_max, 0, 0); | |
| 1653 | + input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, features->x_max, 0, 0); | |
| 1654 | + input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR, 0, features->y_max, 0, 0); | |
| 1655 | + input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0); | |
| 1656 | + } | |
| 1657 | + /* fall through */ | |
| 1658 | + | |
| 1578 | 1659 | case MTSCREEN: |
| 1579 | 1660 | if (features->device_type == BTN_TOOL_FINGER) { |
| 1580 | 1661 | wacom_wac->slots = kmalloc(features->touch_max * |
| @@ -1869,8 +1950,11 @@ static const struct wacom_features wacom_features_0xF4 = · 288 unmodified lines | ||
| 1869 | 1950 | { "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, |
| 1870 | 1951 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; |
| 1871 | 1952 | static const struct wacom_features wacom_features_0xF8 = |
| 1872 | − { "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, | |
| 1873 | − 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | |
| 1953 | + { "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, /* Pen */ | |
| 1954 | + 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 }; | |
| 1955 | +static const struct wacom_features wacom_features_0xF6 = | |
| 1956 | + { "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */ | |
| 1957 | + .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10 }; | |
| 1874 | 1958 | static const struct wacom_features wacom_features_0x3F = |
| 1875 | 1959 | { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, |
| 1876 | 1960 | 63, CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; |
| @@ -2113,6 +2197,7 @@ const struct usb_device_id wacom_ids[] = { · 236 unmodified lines | ||
| 2113 | 2197 | { USB_DEVICE_WACOM(0x47) }, |
| 2114 | 2198 | { USB_DEVICE_WACOM(0xF4) }, |
| 2115 | 2199 | { USB_DEVICE_WACOM(0xF8) }, |
| 2200 | + { USB_DEVICE_WACOM(0xF6) }, | |
| 2116 | 2201 | { USB_DEVICE_WACOM(0xFA) }, |
| 2117 | 2202 | { USB_DEVICE_LENOVO(0x6004) }, |
| 2118 | 2203 | { } |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | |
| 30 | 30 | /* wacom data size per MT contact */ |
| 31 | 31 | #define WACOM_BYTES_PER_MT_PACKET 11 |
| 32 | +#define WACOM_BYTES_PER_24HDT_PACKET 14 | |
| 32 | 33 | |
| 33 | 34 | /* device IDs */ |
| 34 | 35 | #define STYLUS_DEVICE_ID 0x02 |
| @@ -49,6 +50,7 @@ · 14 unmodified lines | ||
| 49 | 50 | #define WACOM_REPORT_TPCHID 15 |
| 50 | 51 | #define WACOM_REPORT_TPCST 16 |
| 51 | 52 | #define WACOM_REPORT_TPC1FGE 18 |
| 53 | +#define WACOM_REPORT_24HDT 1 | |
| 52 | 54 | |
| 53 | 55 | /* device quirks */ |
| 54 | 56 | #define WACOM_QUIRK_MULTI_INPUT 0x0001 |
| @@ -81,6 +83,7 @@ enum { · 26 unmodified lines | ||
| 81 | 83 | WACOM_MO, |
| 82 | 84 | WIRELESS, |
| 83 | 85 | BAMBOO_PT, |
| 86 | + WACOM_24HDT, | |
| 84 | 87 | TABLETPC, /* add new TPC below */ |
| 85 | 88 | TABLETPCE, |
| 86 | 89 | TABLETPC2FG, |
| @@ -109,6 +112,8 @@ struct wacom_features { · 22 unmodified lines | ||
| 109 | 112 | int distance_fuzz; |
| 110 | 113 | unsigned quirks; |
| 111 | 114 | unsigned touch_max; |
| 115 | + int oVid; | |
| 116 | + int oPid; | |
| 112 | 117 | }; |
| 113 | 118 | |
| 114 | 119 | struct wacom_shared { |
| @@ -239,7 +239,7 @@ config TOUCHSCREEN_EETI · 238 unmodified lines | ||
| 239 | 239 | |
| 240 | 240 | config TOUCHSCREEN_EGALAX |
| 241 | 241 | tristate "EETI eGalax multi-touch panel support" |
| 242 | − depends on I2C | |
| 242 | + depends on I2C && OF | |
| 243 | 243 | help |
| 244 | 244 | Say Y here to enable support for I2C connected EETI |
| 245 | 245 | eGalax multi-touch panels. |
| @@ -955,7 +955,8 @@ static int ads7846_resume(struct device *dev) · 954 unmodified lines | ||
| 955 | 955 | |
| 956 | 956 | static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume); |
| 957 | 957 | |
| 958 | −static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads7846 *ts) | |
| 958 | +static int __devinit ads7846_setup_pendown(struct spi_device *spi, | |
| 959 | + struct ads7846 *ts) | |
| 959 | 960 | { |
| 960 | 961 | struct ads7846_platform_data *pdata = spi->dev.platform_data; |
| 961 | 962 | int err; |
| @@ -981,6 +982,9 @@ static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads784 · 19 unmodified lines | ||
| 981 | 982 | |
| 982 | 983 | ts->gpio_pendown = pdata->gpio_pendown; |
| 983 | 984 | |
| 985 | + if (pdata->gpio_pendown_debounce) | |
| 986 | + gpio_set_debounce(pdata->gpio_pendown, | |
| 987 | + pdata->gpio_pendown_debounce); | |
| 984 | 988 | } else { |
| 985 | 989 | dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); |
| 986 | 990 | return -EINVAL; |
| @@ -28,6 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <linux/slab.h> |
| 29 | 29 | #include <linux/bitops.h> |
| 30 | 30 | #include <linux/input/mt.h> |
| 31 | +#include <linux/of_gpio.h> | |
| 31 | 32 | |
| 32 | 33 | /* |
| 33 | 34 | * Mouse Mode: some panel may configure the controller to mouse mode, |
| @@ -122,9 +123,17 @@ static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id) · 88 unmodified lines | ||
| 122 | 123 | /* wake up controller by an falling edge of interrupt gpio. */ |
| 123 | 124 | static int egalax_wake_up_device(struct i2c_client *client) |
| 124 | 125 | { |
| 125 | − int gpio = irq_to_gpio(client->irq); | |
| 126 | + struct device_node *np = client->dev.of_node; | |
| 127 | + int gpio; | |
| 126 | 128 | int ret; |
| 127 | 129 | |
| 130 | + if (!np) | |
| 131 | + return -ENODEV; | |
| 132 | + | |
| 133 | + gpio = of_get_named_gpio(np, "wakeup-gpios", 0); | |
| 134 | + if (!gpio_is_valid(gpio)) | |
| 135 | + return -ENODEV; | |
| 136 | + | |
| 128 | 137 | ret = gpio_request(gpio, "egalax_irq"); |
| 129 | 138 | if (ret < 0) { |
| 130 | 139 | dev_err(&client->dev, |
| @@ -181,7 +190,11 @@ static int __devinit egalax_ts_probe(struct i2c_client *client, · 50 unmodified lines | ||
| 181 | 190 | ts->input_dev = input_dev; |
| 182 | 191 | |
| 183 | 192 | /* controller may be in sleep, wake it up. */ |
| 184 | − egalax_wake_up_device(client); | |
| 193 | + error = egalax_wake_up_device(client); | |
| 194 | + if (error) { | |
| 195 | + dev_err(&client->dev, "Failed to wake up the controller\n"); | |
| 196 | + goto err_free_dev; | |
| 197 | + } | |
| 185 | 198 | |
| 186 | 199 | ret = egalax_firmware_version(client); |
| 187 | 200 | if (ret < 0) { |
| @@ -274,11 +287,17 @@ static int egalax_ts_resume(struct device *dev) · 86 unmodified lines | ||
| 274 | 287 | |
| 275 | 288 | static SIMPLE_DEV_PM_OPS(egalax_ts_pm_ops, egalax_ts_suspend, egalax_ts_resume); |
| 276 | 289 | |
| 290 | +static struct of_device_id egalax_ts_dt_ids[] = { | |
| 291 | + { .compatible = "eeti,egalax_ts" }, | |
| 292 | + { /* sentinel */ } | |
| 293 | +}; | |
| 294 | + | |
| 277 | 295 | static struct i2c_driver egalax_ts_driver = { |
| 278 | 296 | .driver = { |
| 279 | 297 | .name = "egalax_ts", |
| 280 | 298 | .owner = THIS_MODULE, |
| 281 | 299 | .pm = &egalax_ts_pm_ops, |
| 300 | + .of_match_table = of_match_ptr(egalax_ts_dt_ids), | |
| 282 | 301 | }, |
| 283 | 302 | .id_table = egalax_ts_id, |
| 284 | 303 | .probe = egalax_ts_probe, |
| @@ -107,7 +107,6 @@ static int tsc_connect(struct serio *serio, struct serio_driver *drv) · 106 unmodified lines | ||
| 107 | 107 | __set_bit(BTN_TOUCH, input_dev->keybit); |
| 108 | 108 | input_set_abs_params(ptsc->dev, ABS_X, 0, 0x3ff, 0, 0); |
| 109 | 109 | input_set_abs_params(ptsc->dev, ABS_Y, 0, 0x3ff, 0, 0); |
| 110 | − input_set_abs_params(ptsc->dev, ABS_PRESSURE, 0, 0, 0, 0); | |
| 111 | 110 | |
| 112 | 111 | serio_set_drvdata(serio, ptsc); |
| 113 | 112 | |
| @@ -1599,21 +1599,46 @@ static void __init free_on_init_error(void) · 1598 unmodified lines | ||
| 1599 | 1599 | #endif |
| 1600 | 1600 | } |
| 1601 | 1601 | |
| 1602 | +/* SB IOAPIC is always on this device in AMD systems */ | |
| 1603 | +#define IOAPIC_SB_DEVID ((0x00 << 8) | PCI_DEVFN(0x14, 0)) | |
| 1604 | + | |
| 1602 | 1605 | static bool __init check_ioapic_information(void) |
| 1603 | 1606 | { |
| 1607 | + bool ret, has_sb_ioapic; | |
| 1604 | 1608 | int idx; |
| 1605 | 1609 | |
| 1606 | − for (idx = 0; idx < nr_ioapics; idx++) { | |
| 1607 | − int id = mpc_ioapic_id(idx); | |
| 1610 | + has_sb_ioapic = false; | |
| 1611 | + ret = false; | |
| 1608 | 1612 | |
| 1609 | − if (get_ioapic_devid(id) < 0) { | |
| 1610 | − pr_err(FW_BUG "AMD-Vi: IO-APIC[%d] not in IVRS table\n", id); | |
| 1611 | − pr_err("AMD-Vi: Disabling interrupt remapping due to BIOS Bug\n"); | |
| 1612 | − return false; | |
| 1613 | + for (idx = 0; idx < nr_ioapics; idx++) { | |
| 1614 | + int devid, id = mpc_ioapic_id(idx); | |
| 1615 | + | |
| 1616 | + devid = get_ioapic_devid(id); | |
| 1617 | + if (devid < 0) { | |
| 1618 | + pr_err(FW_BUG "AMD-Vi: IOAPIC[%d] not in IVRS table\n", id); | |
| 1619 | + ret = false; | |
| 1620 | + } else if (devid == IOAPIC_SB_DEVID) { | |
| 1621 | + has_sb_ioapic = true; | |
| 1622 | + ret = true; | |
| 1613 | 1623 | } |
| 1614 | 1624 | } |
| 1615 | 1625 | |
| 1616 | − return true; | |
| 1626 | + if (!has_sb_ioapic) { | |
| 1627 | + /* | |
| 1628 | + * We expect the SB IOAPIC to be listed in the IVRS | |
| 1629 | + * table. The system timer is connected to the SB IOAPIC | |
| 1630 | + * and if we don't have it in the list the system will | |
| 1631 | + * panic at boot time. This situation usually happens | |
| 1632 | + * when the BIOS is buggy and provides us the wrong | |
| 1633 | + * device id for the IOAPIC in the system. | |
| 1634 | + */ | |
| 1635 | + pr_err(FW_BUG "AMD-Vi: No southbridge IOAPIC found in IVRS table\n"); | |
| 1636 | + } | |
| 1637 | + | |
| 1638 | + if (!ret) | |
| 1639 | + pr_err("AMD-Vi: Disabling interrupt remapping due to BIOS Bug(s)\n"); | |
| 1640 | + | |
| 1641 | + return ret; | |
| 1617 | 1642 | } |
| 1618 | 1643 | |
| 1619 | 1644 | static void __init free_dma_resources(void) |
| @@ -4108,7 +4108,7 @@ static void swap_pci_ref(struct pci_dev **from, struct pci_dev *to) · 4107 unmodified lines | ||
| 4108 | 4108 | static int intel_iommu_add_device(struct device *dev) |
| 4109 | 4109 | { |
| 4110 | 4110 | struct pci_dev *pdev = to_pci_dev(dev); |
| 4111 | − struct pci_dev *bridge, *dma_pdev; | |
| 4111 | + struct pci_dev *bridge, *dma_pdev = NULL; | |
| 4112 | 4112 | struct iommu_group *group; |
| 4113 | 4113 | int ret; |
| 4114 | 4114 | |
| @@ -4122,7 +4122,7 @@ static int intel_iommu_add_device(struct device *dev) · 7 unmodified lines | ||
| 4122 | 4122 | dma_pdev = pci_get_domain_bus_and_slot( |
| 4123 | 4123 | pci_domain_nr(pdev->bus), |
| 4124 | 4124 | bridge->subordinate->number, 0); |
| 4125 | − else | |
| 4125 | + if (!dma_pdev) | |
| 4126 | 4126 | dma_pdev = pci_dev_get(bridge); |
| 4127 | 4127 | } else |
| 4128 | 4128 | dma_pdev = pci_dev_get(pdev); |
| @@ -200,7 +200,7 @@ enum { · 199 unmodified lines | ||
| 200 | 200 | |
| 201 | 201 | #define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12) |
| 202 | 202 | #define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22) |
| 203 | −#define SMMU_PDN_TO_ADDR(addr) ((pdn) << 22) | |
| 203 | +#define SMMU_PDN_TO_ADDR(pdn) ((pdn) << 22) | |
| 204 | 204 | |
| 205 | 205 | #define _READABLE (1 << SMMU_PTB_DATA_ASID_READABLE_SHIFT) |
| 206 | 206 | #define _WRITABLE (1 << SMMU_PTB_DATA_ASID_WRITABLE_SHIFT) |
| @@ -1054,6 +1054,7 @@ static int smmu_debugfs_stats_show(struct seq_file *s, void *v) · 847 unmodified lines | ||
| 1054 | 1054 | stats[i], val, offs); |
| 1055 | 1055 | } |
| 1056 | 1056 | seq_printf(s, "\n"); |
| 1057 | + dput(dent); | |
| 1057 | 1058 | |
| 1058 | 1059 | return 0; |
| 1059 | 1060 | } |
| @@ -168,7 +168,8 @@ static int __init armctrl_of_init(struct device_node *node, · 167 unmodified lines | ||
| 168 | 168 | } |
| 169 | 169 | |
| 170 | 170 | static struct of_device_id irq_of_match[] __initconst = { |
| 171 | − { .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init } | |
| 171 | + { .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init }, | |
| 172 | + { } | |
| 172 | 173 | }; |
| 173 | 174 | |
| 174 | 175 | void __init bcm2835_init_irq(void) |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | menuconfig ISDN |
| 6 | 6 | bool "ISDN support" |
| 7 | − depends on NET | |
| 7 | + depends on NET && NETDEVICES | |
| 8 | 8 | depends on !S390 && !UML |
| 9 | 9 | ---help--- |
| 10 | 10 | ISDN ("Integrated Services Digital Network", called RNIS in France) |
| @@ -617,7 +617,13 @@ static void int_in_work(struct work_struct *work) · 616 unmodified lines | ||
| 617 | 617 | if (rc == 0) |
| 618 | 618 | /* success, resubmit interrupt read URB */ |
| 619 | 619 | rc = usb_submit_urb(urb, GFP_ATOMIC); |
| 620 | − if (rc != 0 && rc != -ENODEV) { | |
| 620 | + | |
| 621 | + switch (rc) { | |
| 622 | + case 0: /* success */ | |
| 623 | + case -ENODEV: /* device gone */ | |
| 624 | + case -EINVAL: /* URB already resubmitted, or terminal badness */ | |
| 625 | + break; | |
| 626 | + default: /* failure: try to recover by resetting the device */ | |
| 621 | 627 | dev_err(cs->dev, "clear halt failed: %s\n", get_usb_rcmsg(rc)); |
| 622 | 628 | rc = usb_lock_device_for_reset(ucs->udev, ucs->interface); |
| 623 | 629 | if (rc == 0) { |
| @@ -2442,7 +2448,9 @@ static void gigaset_disconnect(struct usb_interface *interface) · 1818 unmodified lines | ||
| 2442 | 2448 | } |
| 2443 | 2449 | |
| 2444 | 2450 | /* gigaset_suspend |
| 2445 | − * This function is called before the USB connection is suspended. | |
| 2451 | + * This function is called before the USB connection is suspended | |
| 2452 | + * or before the USB device is reset. | |
| 2453 | + * In the latter case, message == PMSG_ON. | |
| 2446 | 2454 | */ |
| 2447 | 2455 | static int gigaset_suspend(struct usb_interface *intf, pm_message_t message) |
| 2448 | 2456 | { |
| @@ -2498,7 +2506,12 @@ static int gigaset_suspend(struct usb_interface *intf, pm_message_t message) · 49 unmodified lines | ||
| 2498 | 2506 | del_timer_sync(&ucs->timer_atrdy); |
| 2499 | 2507 | del_timer_sync(&ucs->timer_cmd_in); |
| 2500 | 2508 | del_timer_sync(&ucs->timer_int_in); |
| 2501 | − cancel_work_sync(&ucs->int_in_wq); | |
| 2509 | + | |
| 2510 | + /* don't try to cancel int_in_wq from within reset as it | |
| 2511 | + * might be the one requesting the reset | |
| 2512 | + */ | |
| 2513 | + if (message.event != PM_EVENT_ON) | |
| 2514 | + cancel_work_sync(&ucs->int_in_wq); | |
| 2502 | 2515 | |
| 2503 | 2516 | gig_dbg(DEBUG_SUSPEND, "suspend complete"); |
| 2504 | 2517 | return 0; |
| @@ -6,7 +6,7 @@ if ISDN_I4L · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 7 | config ISDN_PPP |
| 8 | 8 | bool "Support synchronous PPP" |
| 9 | − depends on INET && NETDEVICES | |
| 9 | + depends on INET | |
| 10 | 10 | select SLHC |
| 11 | 11 | help |
| 12 | 12 | Over digital connections such as ISDN, there is no need to |
| @@ -1312,7 +1312,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) · 1311 unmodified lines | ||
| 1312 | 1312 | } else |
| 1313 | 1313 | return -EINVAL; |
| 1314 | 1314 | break; |
| 1315 | −#ifdef CONFIG_NETDEVICES | |
| 1316 | 1315 | case IIOCNETGPN: |
| 1317 | 1316 | /* Get peer phone number of a connected |
| 1318 | 1317 | * isdn network interface */ |
| @@ -1322,7 +1321,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) · 3 unmodified lines | ||
| 1322 | 1321 | return isdn_net_getpeer(&phone, argp); |
| 1323 | 1322 | } else |
| 1324 | 1323 | return -EINVAL; |
| 1325 | −#endif | |
| 1326 | 1324 | default: |
| 1327 | 1325 | return -EINVAL; |
| 1328 | 1326 | } |
| @@ -1352,7 +1350,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) · 23 unmodified lines | ||
| 1352 | 1350 | case IIOCNETLCR: |
| 1353 | 1351 | printk(KERN_INFO "INFO: ISDN_ABC_LCR_SUPPORT not enabled\n"); |
| 1354 | 1352 | return -ENODEV; |
| 1355 | −#ifdef CONFIG_NETDEVICES | |
| 1356 | 1353 | case IIOCNETAIF: |
| 1357 | 1354 | /* Add a network-interface */ |
| 1358 | 1355 | if (arg) { |
| @@ -1491,7 +1488,6 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg) · 132 unmodified lines | ||
| 1491 | 1488 | return -EFAULT; |
| 1492 | 1489 | return isdn_net_force_hangup(name); |
| 1493 | 1490 | break; |
| 1494 | −#endif /* CONFIG_NETDEVICES */ | |
| 1495 | 1491 | case IIOCSETVER: |
| 1496 | 1492 | dev->net_verbose = arg; |
| 1497 | 1493 | printk(KERN_INFO "isdn: Verbose-Level is %d\n", dev->net_verbose); |
| @@ -33,8 +33,6 @@ · 32 unmodified lines | ||
| 33 | 33 | struct led_trigger_cpu { |
| 34 | 34 | char name[MAX_NAME_LEN]; |
| 35 | 35 | struct led_trigger *_trig; |
| 36 | − struct mutex lock; | |
| 37 | − int lock_is_inited; | |
| 38 | 36 | }; |
| 39 | 37 | |
| 40 | 38 | static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig); |
| @@ -50,12 +48,6 @@ void ledtrig_cpu(enum cpu_led_event ledevt) · 9 unmodified lines | ||
| 50 | 48 | { |
| 51 | 49 | struct led_trigger_cpu *trig = &__get_cpu_var(cpu_trig); |
| 52 | 50 | |
| 53 | − /* mutex lock should be initialized before calling mutex_call() */ | |
| 54 | − if (!trig->lock_is_inited) | |
| 55 | − return; | |
| 56 | − | |
| 57 | − mutex_lock(&trig->lock); | |
| 58 | − | |
| 59 | 51 | /* Locate the correct CPU LED */ |
| 60 | 52 | switch (ledevt) { |
| 61 | 53 | case CPU_LED_IDLE_END: |
| @@ -75,8 +67,6 @@ void ledtrig_cpu(enum cpu_led_event ledevt) · 13 unmodified lines | ||
| 75 | 67 | /* Will leave the LED as it is */ |
| 76 | 68 | break; |
| 77 | 69 | } |
| 78 | − | |
| 79 | − mutex_unlock(&trig->lock); | |
| 80 | 70 | } |
| 81 | 71 | EXPORT_SYMBOL(ledtrig_cpu); |
| 82 | 72 | |
| @@ -117,14 +107,9 @@ static int __init ledtrig_cpu_init(void) · 34 unmodified lines | ||
| 117 | 107 | for_each_possible_cpu(cpu) { |
| 118 | 108 | struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); |
| 119 | 109 | |
| 120 | − mutex_init(&trig->lock); | |
| 121 | − | |
| 122 | 110 | snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu); |
| 123 | 111 | |
| 124 | − mutex_lock(&trig->lock); | |
| 125 | 112 | led_trigger_register_simple(trig->name, &trig->_trig); |
| 126 | − trig->lock_is_inited = 1; | |
| 127 | − mutex_unlock(&trig->lock); | |
| 128 | 113 | } |
| 129 | 114 | |
| 130 | 115 | register_syscore_ops(&ledtrig_cpu_syscore_ops); |
| @@ -142,15 +127,9 @@ static void __exit ledtrig_cpu_exit(void) · 11 unmodified lines | ||
| 142 | 127 | for_each_possible_cpu(cpu) { |
| 143 | 128 | struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); |
| 144 | 129 | |
| 145 | − mutex_lock(&trig->lock); | |
| 146 | − | |
| 147 | 130 | led_trigger_unregister_simple(trig->_trig); |
| 148 | 131 | trig->_trig = NULL; |
| 149 | 132 | memset(trig->name, 0, MAX_NAME_LEN); |
| 150 | − trig->lock_is_inited = 0; | |
| 151 | − | |
| 152 | − mutex_unlock(&trig->lock); | |
| 153 | − mutex_destroy(&trig->lock); | |
| 154 | 133 | } |
| 155 | 134 | |
| 156 | 135 | unregister_syscore_ops(&ledtrig_cpu_syscore_ops); |
| @@ -740,8 +740,14 @@ static void rq_completed(struct mapped_device *md, int rw, int run_queue) · 739 unmodified lines | ||
| 740 | 740 | if (!md_in_flight(md)) |
| 741 | 741 | wake_up(&md->wait); |
| 742 | 742 | |
| 743 | + /* | |
| 744 | + * Run this off this callpath, as drivers could invoke end_io while | |
| 745 | + * inside their request_fn (and holding the queue lock). Calling | |
| 746 | + * back into ->request_fn() could deadlock attempting to grab the | |
| 747 | + * queue lock again. | |
| 748 | + */ | |
| 743 | 749 | if (run_queue) |
| 744 | − blk_run_queue(md->queue); | |
| 750 | + blk_run_queue_async(md->queue); | |
| 745 | 751 | |
| 746 | 752 | /* |
| 747 | 753 | * dm_put() must be at the end of this function. See the comment above |
| @@ -315,8 +315,11 @@ static int run(struct mddev *mddev) · 314 unmodified lines | ||
| 315 | 315 | } |
| 316 | 316 | conf->nfaults = 0; |
| 317 | 317 | |
| 318 | − rdev_for_each(rdev, mddev) | |
| 318 | + rdev_for_each(rdev, mddev) { | |
| 319 | 319 | conf->rdev = rdev; |
| 320 | + disk_stack_limits(mddev->gendisk, rdev->bdev, | |
| 321 | + rdev->data_offset << 9); | |
| 322 | + } | |
| 320 | 323 | |
| 321 | 324 | md_set_array_sectors(mddev, faulty_size(mddev, 0, 0)); |
| 322 | 325 | mddev->private = conf; |
| @@ -1817,10 +1817,10 @@ retry: · 1816 unmodified lines | ||
| 1817 | 1817 | memset(bbp, 0xff, PAGE_SIZE); |
| 1818 | 1818 | |
| 1819 | 1819 | for (i = 0 ; i < bb->count ; i++) { |
| 1820 | − u64 internal_bb = *p++; | |
| 1820 | + u64 internal_bb = p[i]; | |
| 1821 | 1821 | u64 store_bb = ((BB_OFFSET(internal_bb) << 10) |
| 1822 | 1822 | | BB_LEN(internal_bb)); |
| 1823 | − *bbp++ = cpu_to_le64(store_bb); | |
| 1823 | + bbp[i] = cpu_to_le64(store_bb); | |
| 1824 | 1824 | } |
| 1825 | 1825 | bb->changed = 0; |
| 1826 | 1826 | if (read_seqretry(&bb->lock, seq)) |
| @@ -5294,7 +5294,7 @@ void md_stop_writes(struct mddev *mddev) · 3467 unmodified lines | ||
| 5294 | 5294 | } |
| 5295 | 5295 | EXPORT_SYMBOL_GPL(md_stop_writes); |
| 5296 | 5296 | |
| 5297 | −void md_stop(struct mddev *mddev) | |
| 5297 | +static void __md_stop(struct mddev *mddev) | |
| 5298 | 5298 | { |
| 5299 | 5299 | mddev->ready = 0; |
| 5300 | 5300 | mddev->pers->stop(mddev); |
| @@ -5304,6 +5304,18 @@ void md_stop(struct mddev *mddev) · 3 unmodified lines | ||
| 5304 | 5304 | mddev->pers = NULL; |
| 5305 | 5305 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); |
| 5306 | 5306 | } |
| 5307 | + | |
| 5308 | +void md_stop(struct mddev *mddev) | |
| 5309 | +{ | |
| 5310 | + /* stop the array and free an attached data structures. | |
| 5311 | + * This is called from dm-raid | |
| 5312 | + */ | |
| 5313 | + __md_stop(mddev); | |
| 5314 | + bitmap_destroy(mddev); | |
| 5315 | + if (mddev->bio_set) | |
| 5316 | + bioset_free(mddev->bio_set); | |
| 5317 | +} | |
| 5318 | + | |
| 5307 | 5319 | EXPORT_SYMBOL_GPL(md_stop); |
| 5308 | 5320 | |
| 5309 | 5321 | static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) |
| @@ -5364,7 +5376,7 @@ static int do_md_stop(struct mddev * mddev, int mode, · 54 unmodified lines | ||
| 5364 | 5376 | set_disk_ro(disk, 0); |
| 5365 | 5377 | |
| 5366 | 5378 | __md_stop_writes(mddev); |
| 5367 | − md_stop(mddev); | |
| 5379 | + __md_stop(mddev); | |
| 5368 | 5380 | mddev->queue->merge_bvec_fn = NULL; |
| 5369 | 5381 | mddev->queue->backing_dev_info.congested_fn = NULL; |
| 5370 | 5382 | |
| @@ -7936,9 +7948,9 @@ int md_is_badblock(struct badblocks *bb, sector_t s, int sectors, · 2565 unmodified lines | ||
| 7936 | 7948 | sector_t *first_bad, int *bad_sectors) |
| 7937 | 7949 | { |
| 7938 | 7950 | int hi; |
| 7939 | − int lo = 0; | |
| 7951 | + int lo; | |
| 7940 | 7952 | u64 *p = bb->page; |
| 7941 | − int rv = 0; | |
| 7953 | + int rv; | |
| 7942 | 7954 | sector_t target = s + sectors; |
| 7943 | 7955 | unsigned seq; |
| 7944 | 7956 | |
| @@ -7953,7 +7965,8 @@ int md_is_badblock(struct badblocks *bb, sector_t s, int sectors, · 8 unmodified lines | ||
| 7953 | 7965 | |
| 7954 | 7966 | retry: |
| 7955 | 7967 | seq = read_seqbegin(&bb->lock); |
| 7956 | − | |
| 7968 | + lo = 0; | |
| 7969 | + rv = 0; | |
| 7957 | 7970 | hi = bb->count; |
| 7958 | 7971 | |
| 7959 | 7972 | /* Binary search between lo and hi for 'target' |
| @@ -963,7 +963,7 @@ static void raid1_unplug(struct blk_plug_cb *cb, bool from_schedule) · 962 unmodified lines | ||
| 963 | 963 | struct r1conf *conf = mddev->private; |
| 964 | 964 | struct bio *bio; |
| 965 | 965 | |
| 966 | − if (from_schedule) { | |
| 966 | + if (from_schedule || current->bio_list) { | |
| 967 | 967 | spin_lock_irq(&conf->device_lock); |
| 968 | 968 | bio_list_merge(&conf->pending_bio_list, &plug->pending); |
| 969 | 969 | conf->pending_count += plug->pending_cnt; |
| @@ -2710,7 +2710,7 @@ static struct r1conf *setup_conf(struct mddev *mddev) · 1740 unmodified lines | ||
| 2710 | 2710 | || disk_idx < 0) |
| 2711 | 2711 | continue; |
| 2712 | 2712 | if (test_bit(Replacement, &rdev->flags)) |
| 2713 | − disk = conf->mirrors + conf->raid_disks + disk_idx; | |
| 2713 | + disk = conf->mirrors + mddev->raid_disks + disk_idx; | |
| 2714 | 2714 | else |
| 2715 | 2715 | disk = conf->mirrors + disk_idx; |
| 2716 | 2716 | |
| @@ -499,7 +499,7 @@ static void raid10_end_write_request(struct bio *bio, int error) · 498 unmodified lines | ||
| 499 | 499 | */ |
| 500 | 500 | one_write_done(r10_bio); |
| 501 | 501 | if (dec_rdev) |
| 502 | − rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev); | |
| 502 | + rdev_dec_pending(rdev, conf->mddev); | |
| 503 | 503 | } |
| 504 | 504 | |
| 505 | 505 | /* |
| @@ -1069,7 +1069,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule) · 563 unmodified lines | ||
| 1069 | 1069 | struct r10conf *conf = mddev->private; |
| 1070 | 1070 | struct bio *bio; |
| 1071 | 1071 | |
| 1072 | − if (from_schedule) { | |
| 1072 | + if (from_schedule || current->bio_list) { | |
| 1073 | 1073 | spin_lock_irq(&conf->device_lock); |
| 1074 | 1074 | bio_list_merge(&conf->pending_bio_list, &plug->pending); |
| 1075 | 1075 | conf->pending_count += plug->pending_cnt; |
| @@ -1334,18 +1334,21 @@ retry_write: · 258 unmodified lines | ||
| 1334 | 1334 | blocked_rdev = rrdev; |
| 1335 | 1335 | break; |
| 1336 | 1336 | } |
| 1337 | + if (rdev && (test_bit(Faulty, &rdev->flags) | |
| 1338 | + || test_bit(Unmerged, &rdev->flags))) | |
| 1339 | + rdev = NULL; | |
| 1337 | 1340 | if (rrdev && (test_bit(Faulty, &rrdev->flags) |
| 1338 | 1341 | || test_bit(Unmerged, &rrdev->flags))) |
| 1339 | 1342 | rrdev = NULL; |
| 1340 | 1343 | |
| 1341 | 1344 | r10_bio->devs[i].bio = NULL; |
| 1342 | 1345 | r10_bio->devs[i].repl_bio = NULL; |
| 1343 | − if (!rdev || test_bit(Faulty, &rdev->flags) || | |
| 1344 | − test_bit(Unmerged, &rdev->flags)) { | |
| 1346 | + | |
| 1347 | + if (!rdev && !rrdev) { | |
| 1345 | 1348 | set_bit(R10BIO_Degraded, &r10_bio->state); |
| 1346 | 1349 | continue; |
| 1347 | 1350 | } |
| 1348 | − if (test_bit(WriteErrorSeen, &rdev->flags)) { | |
| 1351 | + if (rdev && test_bit(WriteErrorSeen, &rdev->flags)) { | |
| 1349 | 1352 | sector_t first_bad; |
| 1350 | 1353 | sector_t dev_sector = r10_bio->devs[i].addr; |
| 1351 | 1354 | int bad_sectors; |
| @@ -1387,8 +1390,10 @@ retry_write: · 35 unmodified lines | ||
| 1387 | 1390 | max_sectors = good_sectors; |
| 1388 | 1391 | } |
| 1389 | 1392 | } |
| 1390 | − r10_bio->devs[i].bio = bio; | |
| 1391 | − atomic_inc(&rdev->nr_pending); | |
| 1393 | + if (rdev) { | |
| 1394 | + r10_bio->devs[i].bio = bio; | |
| 1395 | + atomic_inc(&rdev->nr_pending); | |
| 1396 | + } | |
| 1392 | 1397 | if (rrdev) { |
| 1393 | 1398 | r10_bio->devs[i].repl_bio = bio; |
| 1394 | 1399 | atomic_inc(&rrdev->nr_pending); |
| @@ -1444,69 +1449,71 @@ retry_write: · 49 unmodified lines | ||
| 1444 | 1449 | for (i = 0; i < conf->copies; i++) { |
| 1445 | 1450 | struct bio *mbio; |
| 1446 | 1451 | int d = r10_bio->devs[i].devnum; |
| 1447 | − if (!r10_bio->devs[i].bio) | |
| 1448 | − continue; | |
| 1452 | + if (r10_bio->devs[i].bio) { | |
| 1453 | + struct md_rdev *rdev = conf->mirrors[d].rdev; | |
| 1454 | + mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | |
| 1455 | + md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, | |
| 1456 | + max_sectors); | |
| 1457 | + r10_bio->devs[i].bio = mbio; | |
| 1458 | + | |
| 1459 | + mbio->bi_sector = (r10_bio->devs[i].addr+ | |
| 1460 | + choose_data_offset(r10_bio, | |
| 1461 | + rdev)); | |
| 1462 | + mbio->bi_bdev = rdev->bdev; | |
| 1463 | + mbio->bi_end_io = raid10_end_write_request; | |
| 1464 | + mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; | |
| 1465 | + mbio->bi_private = r10_bio; | |
| 1449 | 1466 | |
| 1450 | − mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | |
| 1451 | − md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, | |
| 1452 | − max_sectors); | |
| 1453 | − r10_bio->devs[i].bio = mbio; | |
| 1467 | + atomic_inc(&r10_bio->remaining); | |
| 1454 | 1468 | |
| 1455 | − mbio->bi_sector = (r10_bio->devs[i].addr+ | |
| 1456 | − choose_data_offset(r10_bio, | |
| 1457 | − conf->mirrors[d].rdev)); | |
| 1458 | − mbio->bi_bdev = conf->mirrors[d].rdev->bdev; | |
| 1459 | − mbio->bi_end_io = raid10_end_write_request; | |
| 1460 | − mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; | |
| 1461 | − mbio->bi_private = r10_bio; | |
| 1469 | + cb = blk_check_plugged(raid10_unplug, mddev, | |
| 1470 | + sizeof(*plug)); | |
| 1471 | + if (cb) | |
| 1472 | + plug = container_of(cb, struct raid10_plug_cb, | |
| 1473 | + cb); | |
| 1474 | + else | |
| 1475 | + plug = NULL; | |
| 1476 | + spin_lock_irqsave(&conf->device_lock, flags); | |
| 1477 | + if (plug) { | |
| 1478 | + bio_list_add(&plug->pending, mbio); | |
| 1479 | + plug->pending_cnt++; | |
| 1480 | + } else { | |
| 1481 | + bio_list_add(&conf->pending_bio_list, mbio); | |
| 1482 | + conf->pending_count++; | |
| 1483 | + } | |
| 1484 | + spin_unlock_irqrestore(&conf->device_lock, flags); | |
| 1485 | + if (!plug) | |
| 1486 | + md_wakeup_thread(mddev->thread); | |
| 1487 | + } | |
| 1462 | 1488 | |
| 1463 | − atomic_inc(&r10_bio->remaining); | |
| 1489 | + if (r10_bio->devs[i].repl_bio) { | |
| 1490 | + struct md_rdev *rdev = conf->mirrors[d].replacement; | |
| 1491 | + if (rdev == NULL) { | |
| 1492 | + /* Replacement just got moved to main 'rdev' */ | |
| 1493 | + smp_mb(); | |
| 1494 | + rdev = conf->mirrors[d].rdev; | |
| 1495 | + } | |
| 1496 | + mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | |
| 1497 | + md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, | |
| 1498 | + max_sectors); | |
| 1499 | + r10_bio->devs[i].repl_bio = mbio; | |
| 1500 | + | |
| 1501 | + mbio->bi_sector = (r10_bio->devs[i].addr + | |
| 1502 | + choose_data_offset( | |
| 1503 | + r10_bio, rdev)); | |
| 1504 | + mbio->bi_bdev = rdev->bdev; | |
| 1505 | + mbio->bi_end_io = raid10_end_write_request; | |
| 1506 | + mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; | |
| 1507 | + mbio->bi_private = r10_bio; | |
| 1464 | 1508 | |
| 1465 | − cb = blk_check_plugged(raid10_unplug, mddev, sizeof(*plug)); | |
| 1466 | − if (cb) | |
| 1467 | − plug = container_of(cb, struct raid10_plug_cb, cb); | |
| 1468 | − else | |
| 1469 | − plug = NULL; | |
| 1470 | − spin_lock_irqsave(&conf->device_lock, flags); | |
| 1471 | − if (plug) { | |
| 1472 | − bio_list_add(&plug->pending, mbio); | |
| 1473 | − plug->pending_cnt++; | |
| 1474 | − } else { | |
| 1509 | + atomic_inc(&r10_bio->remaining); | |
| 1510 | + spin_lock_irqsave(&conf->device_lock, flags); | |
| 1475 | 1511 | bio_list_add(&conf->pending_bio_list, mbio); |
| 1476 | 1512 | conf->pending_count++; |
| 1513 | + spin_unlock_irqrestore(&conf->device_lock, flags); | |
| 1514 | + if (!mddev_check_plugged(mddev)) | |
| 1515 | + md_wakeup_thread(mddev->thread); | |
| 1477 | 1516 | } |
| 1478 | − spin_unlock_irqrestore(&conf->device_lock, flags); | |
| 1479 | − if (!plug) | |
| 1480 | − md_wakeup_thread(mddev->thread); | |
| 1481 | − | |
| 1482 | − if (!r10_bio->devs[i].repl_bio) | |
| 1483 | − continue; | |
| 1484 | − | |
| 1485 | − mbio = bio_clone_mddev(bio, GFP_NOIO, mddev); | |
| 1486 | − md_trim_bio(mbio, r10_bio->sector - bio->bi_sector, | |
| 1487 | − max_sectors); | |
| 1488 | − r10_bio->devs[i].repl_bio = mbio; | |
| 1489 | − | |
| 1490 | − /* We are actively writing to the original device | |
| 1491 | − * so it cannot disappear, so the replacement cannot | |
| 1492 | − * become NULL here | |
| 1493 | − */ | |
| 1494 | − mbio->bi_sector = (r10_bio->devs[i].addr + | |
| 1495 | − choose_data_offset( | |
| 1496 | − r10_bio, | |
| 1497 | − conf->mirrors[d].replacement)); | |
| 1498 | − mbio->bi_bdev = conf->mirrors[d].replacement->bdev; | |
| 1499 | − mbio->bi_end_io = raid10_end_write_request; | |
| 1500 | − mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; | |
| 1501 | − mbio->bi_private = r10_bio; | |
| 1502 | − | |
| 1503 | − atomic_inc(&r10_bio->remaining); | |
| 1504 | − spin_lock_irqsave(&conf->device_lock, flags); | |
| 1505 | − bio_list_add(&conf->pending_bio_list, mbio); | |
| 1506 | − conf->pending_count++; | |
| 1507 | − spin_unlock_irqrestore(&conf->device_lock, flags); | |
| 1508 | − if (!mddev_check_plugged(mddev)) | |
| 1509 | − md_wakeup_thread(mddev->thread); | |
| 1510 | 1517 | } |
| 1511 | 1518 | |
| 1512 | 1519 | /* Don't remove the bias on 'remaining' (one_write_done) until |
| @@ -1783,7 +1790,7 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev) · 270 unmodified lines | ||
| 1783 | 1790 | clear_bit(Unmerged, &rdev->flags); |
| 1784 | 1791 | } |
| 1785 | 1792 | md_integrity_add_rdev(rdev, mddev); |
| 1786 | − if (blk_queue_discard(bdev_get_queue(rdev->bdev))) | |
| 1793 | + if (mddev->queue && blk_queue_discard(bdev_get_queue(rdev->bdev))) | |
| 1787 | 1794 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue); |
| 1788 | 1795 | |
| 1789 | 1796 | print_conf(conf); |
| @@ -3613,11 +3620,14 @@ static int run(struct mddev *mddev) · 1823 unmodified lines | ||
| 3613 | 3620 | discard_supported = true; |
| 3614 | 3621 | } |
| 3615 | 3622 | |
| 3616 | − if (discard_supported) | |
| 3617 | − queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue); | |
| 3618 | − else | |
| 3619 | − queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, mddev->queue); | |
| 3620 | − | |
| 3623 | + if (mddev->queue) { | |
| 3624 | + if (discard_supported) | |
| 3625 | + queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, | |
| 3626 | + mddev->queue); | |
| 3627 | + else | |
| 3628 | + queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, | |
| 3629 | + mddev->queue); | |
| 3630 | + } | |
| 3621 | 3631 | /* need to check that every block has at least one working mirror */ |
| 3622 | 3632 | if (!enough(conf, -1)) { |
| 3623 | 3633 | printk(KERN_ERR "md/raid10:%s: not enough operational mirrors.\n", |
| @@ -2774,10 +2774,12 @@ static void handle_stripe_clean_event(struct r5conf *conf, · 2773 unmodified lines | ||
| 2774 | 2774 | dev = &sh->dev[i]; |
| 2775 | 2775 | if (!test_bit(R5_LOCKED, &dev->flags) && |
| 2776 | 2776 | (test_bit(R5_UPTODATE, &dev->flags) || |
| 2777 | − test_and_clear_bit(R5_Discard, &dev->flags))) { | |
| 2777 | + test_bit(R5_Discard, &dev->flags))) { | |
| 2778 | 2778 | /* We can return any write requests */ |
| 2779 | 2779 | struct bio *wbi, *wbi2; |
| 2780 | 2780 | pr_debug("Return write for disc %d\n", i); |
| 2781 | + if (test_and_clear_bit(R5_Discard, &dev->flags)) | |
| 2782 | + clear_bit(R5_UPTODATE, &dev->flags); | |
| 2781 | 2783 | wbi = dev->written; |
| 2782 | 2784 | dev->written = NULL; |
| 2783 | 2785 | while (wbi && wbi->bi_sector < |
| @@ -2795,7 +2797,8 @@ static void handle_stripe_clean_event(struct r5conf *conf, · 11 unmodified lines | ||
| 2795 | 2797 | !test_bit(STRIPE_DEGRADED, &sh->state), |
| 2796 | 2798 | 0); |
| 2797 | 2799 | } |
| 2798 | − } | |
| 2800 | + } else if (test_bit(R5_Discard, &sh->dev[i].flags)) | |
| 2801 | + clear_bit(R5_Discard, &sh->dev[i].flags); | |
| 2799 | 2802 | |
| 2800 | 2803 | if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state)) |
| 2801 | 2804 | if (atomic_dec_and_test(&conf->pending_full_writes)) |
| @@ -3490,40 +3493,6 @@ static void handle_stripe(struct stripe_head *sh) · 688 unmodified lines | ||
| 3490 | 3493 | handle_failed_sync(conf, sh, &s); |
| 3491 | 3494 | } |
| 3492 | 3495 | |
| 3493 | − /* | |
| 3494 | − * might be able to return some write requests if the parity blocks | |
| 3495 | − * are safe, or on a failed drive | |
| 3496 | − */ | |
| 3497 | − pdev = &sh->dev[sh->pd_idx]; | |
| 3498 | − s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx) | |
| 3499 | − || (s.failed >= 2 && s.failed_num[1] == sh->pd_idx); | |
| 3500 | − qdev = &sh->dev[sh->qd_idx]; | |
| 3501 | − s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx) | |
| 3502 | − || (s.failed >= 2 && s.failed_num[1] == sh->qd_idx) | |
| 3503 | − || conf->level < 6; | |
| 3504 | − | |
| 3505 | − if (s.written && | |
| 3506 | − (s.p_failed || ((test_bit(R5_Insync, &pdev->flags) | |
| 3507 | − && !test_bit(R5_LOCKED, &pdev->flags) | |
| 3508 | − && (test_bit(R5_UPTODATE, &pdev->flags) || | |
| 3509 | − test_bit(R5_Discard, &pdev->flags))))) && | |
| 3510 | − (s.q_failed || ((test_bit(R5_Insync, &qdev->flags) | |
| 3511 | − && !test_bit(R5_LOCKED, &qdev->flags) | |
| 3512 | − && (test_bit(R5_UPTODATE, &qdev->flags) || | |
| 3513 | − test_bit(R5_Discard, &qdev->flags)))))) | |
| 3514 | − handle_stripe_clean_event(conf, sh, disks, &s.return_bi); | |
| 3515 | − | |
| 3516 | − /* Now we might consider reading some blocks, either to check/generate | |
| 3517 | − * parity, or to satisfy requests | |
| 3518 | − * or to load a block that is being partially written. | |
| 3519 | − */ | |
| 3520 | − if (s.to_read || s.non_overwrite | |
| 3521 | − || (conf->level == 6 && s.to_write && s.failed) | |
| 3522 | − || (s.syncing && (s.uptodate + s.compute < disks)) | |
| 3523 | − || s.replacing | |
| 3524 | − || s.expanding) | |
| 3525 | − handle_stripe_fill(sh, &s, disks); | |
| 3526 | − | |
| 3527 | 3496 | /* Now we check to see if any write operations have recently |
| 3528 | 3497 | * completed |
| 3529 | 3498 | */ |
| @@ -3561,6 +3530,40 @@ static void handle_stripe(struct stripe_head *sh) · 31 unmodified lines | ||
| 3561 | 3530 | s.dec_preread_active = 1; |
| 3562 | 3531 | } |
| 3563 | 3532 | |
| 3533 | + /* | |
| 3534 | + * might be able to return some write requests if the parity blocks | |
| 3535 | + * are safe, or on a failed drive | |
| 3536 | + */ | |
| 3537 | + pdev = &sh->dev[sh->pd_idx]; | |
| 3538 | + s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx) | |
| 3539 | + || (s.failed >= 2 && s.failed_num[1] == sh->pd_idx); | |
| 3540 | + qdev = &sh->dev[sh->qd_idx]; | |
| 3541 | + s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx) | |
| 3542 | + || (s.failed >= 2 && s.failed_num[1] == sh->qd_idx) | |
| 3543 | + || conf->level < 6; | |
| 3544 | + | |
| 3545 | + if (s.written && | |
| 3546 | + (s.p_failed || ((test_bit(R5_Insync, &pdev->flags) | |
| 3547 | + && !test_bit(R5_LOCKED, &pdev->flags) | |
| 3548 | + && (test_bit(R5_UPTODATE, &pdev->flags) || | |
| 3549 | + test_bit(R5_Discard, &pdev->flags))))) && | |
| 3550 | + (s.q_failed || ((test_bit(R5_Insync, &qdev->flags) | |
| 3551 | + && !test_bit(R5_LOCKED, &qdev->flags) | |
| 3552 | + && (test_bit(R5_UPTODATE, &qdev->flags) || | |
| 3553 | + test_bit(R5_Discard, &qdev->flags)))))) | |
| 3554 | + handle_stripe_clean_event(conf, sh, disks, &s.return_bi); | |
| 3555 | + | |
| 3556 | + /* Now we might consider reading some blocks, either to check/generate | |
| 3557 | + * parity, or to satisfy requests | |
| 3558 | + * or to load a block that is being partially written. | |
| 3559 | + */ | |
| 3560 | + if (s.to_read || s.non_overwrite | |
| 3561 | + || (conf->level == 6 && s.to_write && s.failed) | |
| 3562 | + || (s.syncing && (s.uptodate + s.compute < disks)) | |
| 3563 | + || s.replacing | |
| 3564 | + || s.expanding) | |
| 3565 | + handle_stripe_fill(sh, &s, disks); | |
| 3566 | + | |
| 3564 | 3567 | /* Now to consider new write requests and what else, if anything |
| 3565 | 3568 | * should be read. We do not handle new writes when: |
| 3566 | 3569 | * 1/ A 'write' operation (copy+xor) is already in flight. |
| @@ -5529,6 +5532,10 @@ static int run(struct mddev *mddev) · 1962 unmodified lines | ||
| 5529 | 5532 | * discard data disk but write parity disk |
| 5530 | 5533 | */ |
| 5531 | 5534 | stripe = stripe * PAGE_SIZE; |
| 5535 | + /* Round up to power of 2, as discard handling | |
| 5536 | + * currently assumes that */ | |
| 5537 | + while ((stripe-1) & stripe) | |
| 5538 | + stripe = (stripe | (stripe-1)) + 1; | |
| 5532 | 5539 | mddev->queue->limits.discard_alignment = stripe; |
| 5533 | 5540 | mddev->queue->limits.discard_granularity = stripe; |
| 5534 | 5541 | /* |
| @@ -300,15 +300,15 @@ static enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32 · 299 unmodified lines | ||
| 300 | 300 | { |
| 301 | 301 | u32 m_div, clk_sel; |
| 302 | 302 | |
| 303 | − dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk, | |
| 304 | − intp->quartz); | |
| 305 | − | |
| 306 | 303 | if (intp == NULL) |
| 307 | 304 | return STV0900_INVALID_HANDLE; |
| 308 | 305 | |
| 309 | 306 | if (intp->errs) |
| 310 | 307 | return STV0900_I2C_ERROR; |
| 311 | 308 | |
| 309 | + dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk, | |
| 310 | + intp->quartz); | |
| 311 | + | |
| 312 | 312 | clk_sel = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6); |
| 313 | 313 | m_div = ((clk_sel * mclk) / intp->quartz) - 1; |
| 314 | 314 | stv0900_write_bits(intp, F0900_M_DIV, m_div); |
| @@ -53,8 +53,7 @@ MODULE_LICENSE("GPL"); · 52 unmodified lines | ||
| 53 | 53 | /* ADV7604 system clock frequency */ |
| 54 | 54 | #define ADV7604_fsc (28636360) |
| 55 | 55 | |
| 56 | −#define DIGITAL_INPUT ((state->prim_mode == ADV7604_PRIM_MODE_HDMI_COMP) || \ | |
| 57 | − (state->prim_mode == ADV7604_PRIM_MODE_HDMI_GR)) | |
| 56 | +#define DIGITAL_INPUT (state->mode == ADV7604_MODE_HDMI) | |
| 58 | 57 | |
| 59 | 58 | /* |
| 60 | 59 | ********************************************************************** |
| @@ -68,7 +67,7 @@ struct adv7604_state { · 7 unmodified lines | ||
| 68 | 67 | struct v4l2_subdev sd; |
| 69 | 68 | struct media_pad pad; |
| 70 | 69 | struct v4l2_ctrl_handler hdl; |
| 71 | − enum adv7604_prim_mode prim_mode; | |
| 70 | + enum adv7604_mode mode; | |
| 72 | 71 | struct v4l2_dv_timings timings; |
| 73 | 72 | u8 edid[256]; |
| 74 | 73 | unsigned edid_blocks; |
| @@ -77,6 +76,7 @@ struct adv7604_state { · 2 unmodified lines | ||
| 77 | 76 | struct workqueue_struct *work_queues; |
| 78 | 77 | struct delayed_work delayed_work_enable_hotplug; |
| 79 | 78 | bool connector_hdmi; |
| 79 | + bool restart_stdi_once; | |
| 80 | 80 | |
| 81 | 81 | /* i2c clients */ |
| 82 | 82 | struct i2c_client *i2c_avlink; |
| @@ -106,7 +106,6 @@ static const struct v4l2_dv_timings adv7604_timings[] = { · 23 unmodified lines | ||
| 106 | 106 | V4L2_DV_BT_CEA_720X576P50, |
| 107 | 107 | V4L2_DV_BT_CEA_1280X720P24, |
| 108 | 108 | V4L2_DV_BT_CEA_1280X720P25, |
| 109 | − V4L2_DV_BT_CEA_1280X720P30, | |
| 110 | 109 | V4L2_DV_BT_CEA_1280X720P50, |
| 111 | 110 | V4L2_DV_BT_CEA_1280X720P60, |
| 112 | 111 | V4L2_DV_BT_CEA_1920X1080P24, |
| @@ -115,6 +114,7 @@ static const struct v4l2_dv_timings adv7604_timings[] = { · 2 unmodified lines | ||
| 115 | 114 | V4L2_DV_BT_CEA_1920X1080P50, |
| 116 | 115 | V4L2_DV_BT_CEA_1920X1080P60, |
| 117 | 116 | |
| 117 | + /* sorted by DMT ID */ | |
| 118 | 118 | V4L2_DV_BT_DMT_640X350P85, |
| 119 | 119 | V4L2_DV_BT_DMT_640X400P85, |
| 120 | 120 | V4L2_DV_BT_DMT_720X400P85, |
| @@ -164,6 +164,89 @@ static const struct v4l2_dv_timings adv7604_timings[] = { · 43 unmodified lines | ||
| 164 | 164 | { }, |
| 165 | 165 | }; |
| 166 | 166 | |
| 167 | +struct adv7604_video_standards { | |
| 168 | + struct v4l2_dv_timings timings; | |
| 169 | + u8 vid_std; | |
| 170 | + u8 v_freq; | |
| 171 | +}; | |
| 172 | + | |
| 173 | +/* sorted by number of lines */ | |
| 174 | +static const struct adv7604_video_standards adv7604_prim_mode_comp[] = { | |
| 175 | + /* { V4L2_DV_BT_CEA_720X480P59_94, 0x0a, 0x00 }, TODO flickering */ | |
| 176 | + { V4L2_DV_BT_CEA_720X576P50, 0x0b, 0x00 }, | |
| 177 | + { V4L2_DV_BT_CEA_1280X720P50, 0x19, 0x01 }, | |
| 178 | + { V4L2_DV_BT_CEA_1280X720P60, 0x19, 0x00 }, | |
| 179 | + { V4L2_DV_BT_CEA_1920X1080P24, 0x1e, 0x04 }, | |
| 180 | + { V4L2_DV_BT_CEA_1920X1080P25, 0x1e, 0x03 }, | |
| 181 | + { V4L2_DV_BT_CEA_1920X1080P30, 0x1e, 0x02 }, | |
| 182 | + { V4L2_DV_BT_CEA_1920X1080P50, 0x1e, 0x01 }, | |
| 183 | + { V4L2_DV_BT_CEA_1920X1080P60, 0x1e, 0x00 }, | |
| 184 | + /* TODO add 1920x1080P60_RB (CVT timing) */ | |
| 185 | + { }, | |
| 186 | +}; | |
| 187 | + | |
| 188 | +/* sorted by number of lines */ | |
| 189 | +static const struct adv7604_video_standards adv7604_prim_mode_gr[] = { | |
| 190 | + { V4L2_DV_BT_DMT_640X480P60, 0x08, 0x00 }, | |
| 191 | + { V4L2_DV_BT_DMT_640X480P72, 0x09, 0x00 }, | |
| 192 | + { V4L2_DV_BT_DMT_640X480P75, 0x0a, 0x00 }, | |
| 193 | + { V4L2_DV_BT_DMT_640X480P85, 0x0b, 0x00 }, | |
| 194 | + { V4L2_DV_BT_DMT_800X600P56, 0x00, 0x00 }, | |
| 195 | + { V4L2_DV_BT_DMT_800X600P60, 0x01, 0x00 }, | |
| 196 | + { V4L2_DV_BT_DMT_800X600P72, 0x02, 0x00 }, | |
| 197 | + { V4L2_DV_BT_DMT_800X600P75, 0x03, 0x00 }, | |
| 198 | + { V4L2_DV_BT_DMT_800X600P85, 0x04, 0x00 }, | |
| 199 | + { V4L2_DV_BT_DMT_1024X768P60, 0x0c, 0x00 }, | |
| 200 | + { V4L2_DV_BT_DMT_1024X768P70, 0x0d, 0x00 }, | |
| 201 | + { V4L2_DV_BT_DMT_1024X768P75, 0x0e, 0x00 }, | |
| 202 | + { V4L2_DV_BT_DMT_1024X768P85, 0x0f, 0x00 }, | |
| 203 | + { V4L2_DV_BT_DMT_1280X1024P60, 0x05, 0x00 }, | |
| 204 | + { V4L2_DV_BT_DMT_1280X1024P75, 0x06, 0x00 }, | |
| 205 | + { V4L2_DV_BT_DMT_1360X768P60, 0x12, 0x00 }, | |
| 206 | + { V4L2_DV_BT_DMT_1366X768P60, 0x13, 0x00 }, | |
| 207 | + { V4L2_DV_BT_DMT_1400X1050P60, 0x14, 0x00 }, | |
| 208 | + { V4L2_DV_BT_DMT_1400X1050P75, 0x15, 0x00 }, | |
| 209 | + { V4L2_DV_BT_DMT_1600X1200P60, 0x16, 0x00 }, /* TODO not tested */ | |
| 210 | + /* TODO add 1600X1200P60_RB (not a DMT timing) */ | |
| 211 | + { V4L2_DV_BT_DMT_1680X1050P60, 0x18, 0x00 }, | |
| 212 | + { V4L2_DV_BT_DMT_1920X1200P60_RB, 0x19, 0x00 }, /* TODO not tested */ | |
| 213 | + { }, | |
| 214 | +}; | |
| 215 | + | |
| 216 | +/* sorted by number of lines */ | |
| 217 | +static const struct adv7604_video_standards adv7604_prim_mode_hdmi_comp[] = { | |
| 218 | + { V4L2_DV_BT_CEA_720X480P59_94, 0x0a, 0x00 }, | |
| 219 | + { V4L2_DV_BT_CEA_720X576P50, 0x0b, 0x00 }, | |
| 220 | + { V4L2_DV_BT_CEA_1280X720P50, 0x13, 0x01 }, | |
| 221 | + { V4L2_DV_BT_CEA_1280X720P60, 0x13, 0x00 }, | |
| 222 | + { V4L2_DV_BT_CEA_1920X1080P24, 0x1e, 0x04 }, | |
| 223 | + { V4L2_DV_BT_CEA_1920X1080P25, 0x1e, 0x03 }, | |
| 224 | + { V4L2_DV_BT_CEA_1920X1080P30, 0x1e, 0x02 }, | |
| 225 | + { V4L2_DV_BT_CEA_1920X1080P50, 0x1e, 0x01 }, | |
| 226 | + { V4L2_DV_BT_CEA_1920X1080P60, 0x1e, 0x00 }, | |
| 227 | + { }, | |
| 228 | +}; | |
| 229 | + | |
| 230 | +/* sorted by number of lines */ | |
| 231 | +static const struct adv7604_video_standards adv7604_prim_mode_hdmi_gr[] = { | |
| 232 | + { V4L2_DV_BT_DMT_640X480P60, 0x08, 0x00 }, | |
| 233 | + { V4L2_DV_BT_DMT_640X480P72, 0x09, 0x00 }, | |
| 234 | + { V4L2_DV_BT_DMT_640X480P75, 0x0a, 0x00 }, | |
| 235 | + { V4L2_DV_BT_DMT_640X480P85, 0x0b, 0x00 }, | |
| 236 | + { V4L2_DV_BT_DMT_800X600P56, 0x00, 0x00 }, | |
| 237 | + { V4L2_DV_BT_DMT_800X600P60, 0x01, 0x00 }, | |
| 238 | + { V4L2_DV_BT_DMT_800X600P72, 0x02, 0x00 }, | |
| 239 | + { V4L2_DV_BT_DMT_800X600P75, 0x03, 0x00 }, | |
| 240 | + { V4L2_DV_BT_DMT_800X600P85, 0x04, 0x00 }, | |
| 241 | + { V4L2_DV_BT_DMT_1024X768P60, 0x0c, 0x00 }, | |
| 242 | + { V4L2_DV_BT_DMT_1024X768P70, 0x0d, 0x00 }, | |
| 243 | + { V4L2_DV_BT_DMT_1024X768P75, 0x0e, 0x00 }, | |
| 244 | + { V4L2_DV_BT_DMT_1024X768P85, 0x0f, 0x00 }, | |
| 245 | + { V4L2_DV_BT_DMT_1280X1024P60, 0x05, 0x00 }, | |
| 246 | + { V4L2_DV_BT_DMT_1280X1024P75, 0x06, 0x00 }, | |
| 247 | + { }, | |
| 248 | +}; | |
| 249 | + | |
| 167 | 250 | /* ----------------------------------------------------------------------- */ |
| 168 | 251 | |
| 169 | 252 | static inline struct adv7604_state *to_state(struct v4l2_subdev *sd) |
| @@ -672,64 +755,144 @@ static int adv7604_s_detect_tx_5v_ctrl(struct v4l2_subdev *sd) · 502 unmodified lines | ||
| 672 | 755 | ((io_read(sd, 0x6f) & 0x10) >> 4)); |
| 673 | 756 | } |
| 674 | 757 | |
| 675 | −static void configure_free_run(struct v4l2_subdev *sd, const struct v4l2_bt_timings *timings) | |
| 758 | +static int find_and_set_predefined_video_timings(struct v4l2_subdev *sd, | |
| 759 | + u8 prim_mode, | |
| 760 | + const struct adv7604_video_standards *predef_vid_timings, | |
| 761 | + const struct v4l2_dv_timings *timings) | |
| 762 | +{ | |
| 763 | + struct adv7604_state *state = to_state(sd); | |
| 764 | + int i; | |
| 765 | + | |
| 766 | + for (i = 0; predef_vid_timings[i].timings.bt.width; i++) { | |
| 767 | + if (!v4l_match_dv_timings(timings, &predef_vid_timings[i].timings, | |
| 768 | + DIGITAL_INPUT ? 250000 : 1000000)) | |
| 769 | + continue; | |
| 770 | + io_write(sd, 0x00, predef_vid_timings[i].vid_std); /* video std */ | |
| 771 | + io_write(sd, 0x01, (predef_vid_timings[i].v_freq << 4) + | |
| 772 | + prim_mode); /* v_freq and prim mode */ | |
| 773 | + return 0; | |
| 774 | + } | |
| 775 | + | |
| 776 | + return -1; | |
| 777 | +} | |
| 778 | + | |
| 779 | +static int configure_predefined_video_timings(struct v4l2_subdev *sd, | |
| 780 | + struct v4l2_dv_timings *timings) | |
| 676 | 781 | { |
| 782 | + struct adv7604_state *state = to_state(sd); | |
| 783 | + int err; | |
| 784 | + | |
| 785 | + v4l2_dbg(1, debug, sd, "%s", __func__); | |
| 786 | + | |
| 787 | + /* reset to default values */ | |
| 788 | + io_write(sd, 0x16, 0x43); | |
| 789 | + io_write(sd, 0x17, 0x5a); | |
| 790 | + /* disable embedded syncs for auto graphics mode */ | |
| 791 | + cp_write_and_or(sd, 0x81, 0xef, 0x00); | |
| 792 | + cp_write(sd, 0x8f, 0x00); | |
| 793 | + cp_write(sd, 0x90, 0x00); | |
| 794 | + cp_write(sd, 0xa2, 0x00); | |
| 795 | + cp_write(sd, 0xa3, 0x00); | |
| 796 | + cp_write(sd, 0xa4, 0x00); | |
| 797 | + cp_write(sd, 0xa5, 0x00); | |
| 798 | + cp_write(sd, 0xa6, 0x00); | |
| 799 | + cp_write(sd, 0xa7, 0x00); | |
| 800 | + cp_write(sd, 0xab, 0x00); | |
| 801 | + cp_write(sd, 0xac, 0x00); | |
| 802 | + | |
| 803 | + switch (state->mode) { | |
| 804 | + case ADV7604_MODE_COMP: | |
| 805 | + case ADV7604_MODE_GR: | |
| 806 | + err = find_and_set_predefined_video_timings(sd, | |
| 807 | + 0x01, adv7604_prim_mode_comp, timings); | |
| 808 | + if (err) | |
| 809 | + err = find_and_set_predefined_video_timings(sd, | |
| 810 | + 0x02, adv7604_prim_mode_gr, timings); | |
| 811 | + break; | |
| 812 | + case ADV7604_MODE_HDMI: | |
| 813 | + err = find_and_set_predefined_video_timings(sd, | |
| 814 | + 0x05, adv7604_prim_mode_hdmi_comp, timings); | |
| 815 | + if (err) | |
| 816 | + err = find_and_set_predefined_video_timings(sd, | |
| 817 | + 0x06, adv7604_prim_mode_hdmi_gr, timings); | |
| 818 | + break; | |
| 819 | + default: | |
| 820 | + v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n", | |
| 821 | + __func__, state->mode); | |
| 822 | + err = -1; | |
| 823 | + break; | |
| 824 | + } | |
| 825 | + | |
| 826 | + | |
| 827 | + return err; | |
| 828 | +} | |
| 829 | + | |
| 830 | +static void configure_custom_video_timings(struct v4l2_subdev *sd, | |
| 831 | + const struct v4l2_bt_timings *bt) | |
| 832 | +{ | |
| 833 | + struct adv7604_state *state = to_state(sd); | |
| 677 | 834 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 678 | − u32 width = htotal(timings); | |
| 679 | − u32 height = vtotal(timings); | |
| 680 | − u16 ch1_fr_ll = (((u32)timings->pixelclock / 100) > 0) ? | |
| 681 | − ((width * (ADV7604_fsc / 100)) / ((u32)timings->pixelclock / 100)) : 0; | |
| 835 | + u32 width = htotal(bt); | |
| 836 | + u32 height = vtotal(bt); | |
| 837 | + u16 cp_start_sav = bt->hsync + bt->hbackporch - 4; | |
| 838 | + u16 cp_start_eav = width - bt->hfrontporch; | |
| 839 | + u16 cp_start_vbi = height - bt->vfrontporch; | |
| 840 | + u16 cp_end_vbi = bt->vsync + bt->vbackporch; | |
| 841 | + u16 ch1_fr_ll = (((u32)bt->pixelclock / 100) > 0) ? | |
| 842 | + ((width * (ADV7604_fsc / 100)) / ((u32)bt->pixelclock / 100)) : 0; | |
| 843 | + const u8 pll[2] = { | |
| 844 | + 0xc0 | ((width >> 8) & 0x1f), | |
| 845 | + width & 0xff | |
| 846 | + }; | |
| 682 | 847 | |
| 683 | 848 | v4l2_dbg(2, debug, sd, "%s\n", __func__); |
| 684 | 849 | |
| 685 | − cp_write(sd, 0x8f, (ch1_fr_ll >> 8) & 0x7); /* CH1_FR_LL */ | |
| 686 | − cp_write(sd, 0x90, ch1_fr_ll & 0xff); /* CH1_FR_LL */ | |
| 687 | − cp_write(sd, 0xab, (height >> 4) & 0xff); /* CP_LCOUNT_MAX */ | |
| 688 | − cp_write(sd, 0xac, (height & 0x0f) << 4); /* CP_LCOUNT_MAX */ | |
| 689 | − /* TODO support interlaced */ | |
| 690 | − cp_write(sd, 0x91, 0x10); /* INTERLACED */ | |
| 691 | − | |
| 692 | − /* Should only be set in auto-graphics mode [REF_02 p. 91-92] */ | |
| 693 | − if ((io_read(sd, 0x00) == 0x07) && (io_read(sd, 0x01) == 0x02)) { | |
| 694 | − u16 cp_start_sav, cp_start_eav, cp_start_vbi, cp_end_vbi; | |
| 695 | − const u8 pll[2] = { | |
| 696 | − (0xc0 | ((width >> 8) & 0x1f)), | |
| 697 | − (width & 0xff) | |
| 698 | − }; | |
| 850 | + switch (state->mode) { | |
| 851 | + case ADV7604_MODE_COMP: | |
| 852 | + case ADV7604_MODE_GR: | |
| 853 | + /* auto graphics */ | |
| 854 | + io_write(sd, 0x00, 0x07); /* video std */ | |
| 855 | + io_write(sd, 0x01, 0x02); /* prim mode */ | |
| 856 | + /* enable embedded syncs for auto graphics mode */ | |
| 857 | + cp_write_and_or(sd, 0x81, 0xef, 0x10); | |
| 699 | 858 | |
| 859 | + /* Should only be set in auto-graphics mode [REF_02, p. 91-92] */ | |
| 700 | 860 | /* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */ |
| 701 | 861 | /* IO-map reg. 0x16 and 0x17 should be written in sequence */ |
| 702 | 862 | if (adv_smbus_write_i2c_block_data(client, 0x16, 2, pll)) { |
| 703 | 863 | v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n"); |
| 704 | − return; | |
| 864 | + break; | |
| 705 | 865 | } |
| 706 | 866 | |
| 707 | 867 | /* active video - horizontal timing */ |
| 708 | − cp_start_sav = timings->hsync + timings->hbackporch - 4; | |
| 709 | − cp_start_eav = width - timings->hfrontporch; | |
| 710 | 868 | cp_write(sd, 0xa2, (cp_start_sav >> 4) & 0xff); |
| 711 | − cp_write(sd, 0xa3, ((cp_start_sav & 0x0f) << 4) | ((cp_start_eav >> 8) & 0x0f)); | |
| 869 | + cp_write(sd, 0xa3, ((cp_start_sav & 0x0f) << 4) | | |
| 870 | + ((cp_start_eav >> 8) & 0x0f)); | |
| 712 | 871 | cp_write(sd, 0xa4, cp_start_eav & 0xff); |
| 713 | 872 | |
| 714 | 873 | /* active video - vertical timing */ |
| 715 | − cp_start_vbi = height - timings->vfrontporch; | |
| 716 | − cp_end_vbi = timings->vsync + timings->vbackporch; | |
| 717 | 874 | cp_write(sd, 0xa5, (cp_start_vbi >> 4) & 0xff); |
| 718 | − cp_write(sd, 0xa6, ((cp_start_vbi & 0xf) << 4) | ((cp_end_vbi >> 8) & 0xf)); | |
| 875 | + cp_write(sd, 0xa6, ((cp_start_vbi & 0xf) << 4) | | |
| 876 | + ((cp_end_vbi >> 8) & 0xf)); | |
| 719 | 877 | cp_write(sd, 0xa7, cp_end_vbi & 0xff); |
| 720 | − } else { | |
| 721 | − /* reset to default values */ | |
| 722 | − io_write(sd, 0x16, 0x43); | |
| 723 | − io_write(sd, 0x17, 0x5a); | |
| 724 | − cp_write(sd, 0xa2, 0x00); | |
| 725 | − cp_write(sd, 0xa3, 0x00); | |
| 726 | − cp_write(sd, 0xa4, 0x00); | |
| 727 | − cp_write(sd, 0xa5, 0x00); | |
| 728 | − cp_write(sd, 0xa6, 0x00); | |
| 729 | − cp_write(sd, 0xa7, 0x00); | |
| 878 | + break; | |
| 879 | + case ADV7604_MODE_HDMI: | |
| 880 | + /* set default prim_mode/vid_std for HDMI | |
| 881 | + accoring to [REF_03, c. 4.2] */ | |
| 882 | + io_write(sd, 0x00, 0x02); /* video std */ | |
| 883 | + io_write(sd, 0x01, 0x06); /* prim mode */ | |
| 884 | + break; | |
| 885 | + default: | |
| 886 | + v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n", | |
| 887 | + __func__, state->mode); | |
| 888 | + break; | |
| 730 | 889 | } |
| 731 | −} | |
| 732 | 890 | |
| 891 | + cp_write(sd, 0x8f, (ch1_fr_ll >> 8) & 0x7); | |
| 892 | + cp_write(sd, 0x90, ch1_fr_ll & 0xff); | |
| 893 | + cp_write(sd, 0xab, (height >> 4) & 0xff); | |
| 894 | + cp_write(sd, 0xac, (height & 0x0f) << 4); | |
| 895 | +} | |
| 733 | 896 | |
| 734 | 897 | static void set_rgb_quantization_range(struct v4l2_subdev *sd) |
| 735 | 898 | { |
| @@ -738,12 +901,7 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd) · 2 unmodified lines | ||
| 738 | 901 | switch (state->rgb_quantization_range) { |
| 739 | 902 | case V4L2_DV_RGB_RANGE_AUTO: |
| 740 | 903 | /* automatic */ |
| 741 | − if ((hdmi_read(sd, 0x05) & 0x80) || | |
| 742 | − (state->prim_mode == ADV7604_PRIM_MODE_COMP) || | |
| 743 | − (state->prim_mode == ADV7604_PRIM_MODE_RGB)) { | |
| 744 | − /* receiving HDMI or analog signal */ | |
| 745 | − io_write_and_or(sd, 0x02, 0x0f, 0xf0); | |
| 746 | − } else { | |
| 904 | + if (DIGITAL_INPUT && !(hdmi_read(sd, 0x05) & 0x80)) { | |
| 747 | 905 | /* receiving DVI-D signal */ |
| 748 | 906 | |
| 749 | 907 | /* ADV7604 selects RGB limited range regardless of |
| @@ -756,6 +914,9 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd) · 6 unmodified lines | ||
| 756 | 914 | /* RGB full range (0-255) */ |
| 757 | 915 | io_write_and_or(sd, 0x02, 0x0f, 0x10); |
| 758 | 916 | } |
| 917 | + } else { | |
| 918 | + /* receiving HDMI or analog signal, set automode */ | |
| 919 | + io_write_and_or(sd, 0x02, 0x0f, 0xf0); | |
| 759 | 920 | } |
| 760 | 921 | break; |
| 761 | 922 | case V4L2_DV_RGB_RANGE_LIMITED: |
| @@ -967,8 +1128,10 @@ static int stdi2dv_timings(struct v4l2_subdev *sd, · 205 unmodified lines | ||
| 967 | 1128 | state->aspect_ratio, timings)) |
| 968 | 1129 | return 0; |
| 969 | 1130 | |
| 970 | − v4l2_dbg(2, debug, sd, "%s: No format candidate found for lcf=%d, bl = %d\n", | |
| 971 | − __func__, stdi->lcf, stdi->bl); | |
| 1131 | + v4l2_dbg(2, debug, sd, | |
| 1132 | + "%s: No format candidate found for lcvs = %d, lcf=%d, bl = %d, %chsync, %cvsync\n", | |
| 1133 | + __func__, stdi->lcvs, stdi->lcf, stdi->bl, | |
| 1134 | + stdi->hs_pol, stdi->vs_pol); | |
| 972 | 1135 | return -1; |
| 973 | 1136 | } |
| 974 | 1137 | |
| @@ -1123,7 +1286,7 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd, · 148 unmodified lines | ||
| 1123 | 1286 | adv7604_fill_optional_dv_timings_fields(sd, timings); |
| 1124 | 1287 | } else { |
| 1125 | 1288 | /* find format |
| 1126 | − * Since LCVS values are inaccurate (REF_03, page 275-276), | |
| 1289 | + * Since LCVS values are inaccurate [REF_03, p. 275-276], | |
| 1127 | 1290 | * stdi2dv_timings() is called with lcvs +-1 if the first attempt fails. |
| 1128 | 1291 | */ |
| 1129 | 1292 | if (!stdi2dv_timings(sd, &stdi, timings)) |
| @@ -1135,9 +1298,31 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd, · 5 unmodified lines | ||
| 1135 | 1298 | stdi.lcvs -= 2; |
| 1136 | 1299 | v4l2_dbg(1, debug, sd, "%s: lcvs - 1 = %d\n", __func__, stdi.lcvs); |
| 1137 | 1300 | if (stdi2dv_timings(sd, &stdi, timings)) { |
| 1301 | + /* | |
| 1302 | + * The STDI block may measure wrong values, especially | |
| 1303 | + * for lcvs and lcf. If the driver can not find any | |
| 1304 | + * valid timing, the STDI block is restarted to measure | |
| 1305 | + * the video timings again. The function will return an | |
| 1306 | + * error, but the restart of STDI will generate a new | |
| 1307 | + * STDI interrupt and the format detection process will | |
| 1308 | + * restart. | |
| 1309 | + */ | |
| 1310 | + if (state->restart_stdi_once) { | |
| 1311 | + v4l2_dbg(1, debug, sd, "%s: restart STDI\n", __func__); | |
| 1312 | + /* TODO restart STDI for Sync Channel 2 */ | |
| 1313 | + /* enter one-shot mode */ | |
| 1314 | + cp_write_and_or(sd, 0x86, 0xf9, 0x00); | |
| 1315 | + /* trigger STDI restart */ | |
| 1316 | + cp_write_and_or(sd, 0x86, 0xf9, 0x04); | |
| 1317 | + /* reset to continuous mode */ | |
| 1318 | + cp_write_and_or(sd, 0x86, 0xf9, 0x02); | |
| 1319 | + state->restart_stdi_once = false; | |
| 1320 | + return -ENOLINK; | |
| 1321 | + } | |
| 1138 | 1322 | v4l2_dbg(1, debug, sd, "%s: format not supported\n", __func__); |
| 1139 | 1323 | return -ERANGE; |
| 1140 | 1324 | } |
| 1325 | + state->restart_stdi_once = true; | |
| 1141 | 1326 | } |
| 1142 | 1327 | found: |
| 1143 | 1328 | |
| @@ -1166,6 +1351,7 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd, · 22 unmodified lines | ||
| 1166 | 1351 | { |
| 1167 | 1352 | struct adv7604_state *state = to_state(sd); |
| 1168 | 1353 | struct v4l2_bt_timings *bt; |
| 1354 | + int err; | |
| 1169 | 1355 | |
| 1170 | 1356 | if (!timings) |
| 1171 | 1357 | return -EINVAL; |
| @@ -1178,12 +1364,20 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd, · 6 unmodified lines | ||
| 1178 | 1364 | __func__, (u32)bt->pixelclock); |
| 1179 | 1365 | return -ERANGE; |
| 1180 | 1366 | } |
| 1367 | + | |
| 1181 | 1368 | adv7604_fill_optional_dv_timings_fields(sd, timings); |
| 1182 | 1369 | |
| 1183 | 1370 | state->timings = *timings; |
| 1184 | 1371 | |
| 1185 | − /* freerun */ | |
| 1186 | − configure_free_run(sd, bt); | |
| 1372 | + cp_write(sd, 0x91, bt->interlaced ? 0x50 : 0x10); | |
| 1373 | + | |
| 1374 | + /* Use prim_mode and vid_std when available */ | |
| 1375 | + err = configure_predefined_video_timings(sd, timings); | |
| 1376 | + if (err) { | |
| 1377 | + /* custom settings when the video format | |
| 1378 | + does not have prim_mode/vid_std */ | |
| 1379 | + configure_custom_video_timings(sd, bt); | |
| 1380 | + } | |
| 1187 | 1381 | |
| 1188 | 1382 | set_rgb_quantization_range(sd); |
| 1189 | 1383 | |
| @@ -1203,24 +1397,25 @@ static int adv7604_g_dv_timings(struct v4l2_subdev *sd, · 13 unmodified lines | ||
| 1203 | 1397 | return 0; |
| 1204 | 1398 | } |
| 1205 | 1399 | |
| 1206 | −static void enable_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode) | |
| 1400 | +static void enable_input(struct v4l2_subdev *sd) | |
| 1207 | 1401 | { |
| 1208 | − switch (prim_mode) { | |
| 1209 | − case ADV7604_PRIM_MODE_COMP: | |
| 1210 | − case ADV7604_PRIM_MODE_RGB: | |
| 1402 | + struct adv7604_state *state = to_state(sd); | |
| 1403 | + | |
| 1404 | + switch (state->mode) { | |
| 1405 | + case ADV7604_MODE_COMP: | |
| 1406 | + case ADV7604_MODE_GR: | |
| 1211 | 1407 | /* enable */ |
| 1212 | 1408 | io_write(sd, 0x15, 0xb0); /* Disable Tristate of Pins (no audio) */ |
| 1213 | 1409 | break; |
| 1214 | − case ADV7604_PRIM_MODE_HDMI_COMP: | |
| 1215 | − case ADV7604_PRIM_MODE_HDMI_GR: | |
| 1410 | + case ADV7604_MODE_HDMI: | |
| 1216 | 1411 | /* enable */ |
| 1217 | 1412 | hdmi_write(sd, 0x1a, 0x0a); /* Unmute audio */ |
| 1218 | 1413 | hdmi_write(sd, 0x01, 0x00); /* Enable HDMI clock terminators */ |
| 1219 | 1414 | io_write(sd, 0x15, 0xa0); /* Disable Tristate of Pins */ |
| 1220 | 1415 | break; |
| 1221 | 1416 | default: |
| 1222 | − v4l2_err(sd, "%s: reserved primary mode 0x%0x\n", | |
| 1223 | − __func__, prim_mode); | |
| 1417 | + v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n", | |
| 1418 | + __func__, state->mode); | |
| 1224 | 1419 | break; |
| 1225 | 1420 | } |
| 1226 | 1421 | } |
| @@ -1233,17 +1428,13 @@ static void disable_input(struct v4l2_subdev *sd) · 6 unmodified lines | ||
| 1233 | 1428 | hdmi_write(sd, 0x01, 0x78); /* Disable HDMI clock terminators */ |
| 1234 | 1429 | } |
| 1235 | 1430 | |
| 1236 | −static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode) | |
| 1431 | +static void select_input(struct v4l2_subdev *sd) | |
| 1237 | 1432 | { |
| 1238 | − switch (prim_mode) { | |
| 1239 | − case ADV7604_PRIM_MODE_COMP: | |
| 1240 | − case ADV7604_PRIM_MODE_RGB: | |
| 1241 | − /* set mode and select free run resolution */ | |
| 1242 | − io_write(sd, 0x00, 0x07); /* video std */ | |
| 1243 | − io_write(sd, 0x01, 0x02); /* prim mode */ | |
| 1244 | − /* enable embedded syncs for auto graphics mode */ | |
| 1245 | − cp_write_and_or(sd, 0x81, 0xef, 0x10); | |
| 1433 | + struct adv7604_state *state = to_state(sd); | |
| 1246 | 1434 | |
| 1435 | + switch (state->mode) { | |
| 1436 | + case ADV7604_MODE_COMP: | |
| 1437 | + case ADV7604_MODE_GR: | |
| 1247 | 1438 | /* reset ADI recommended settings for HDMI: */ |
| 1248 | 1439 | /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */ |
| 1249 | 1440 | hdmi_write(sd, 0x0d, 0x04); /* HDMI filter optimization */ |
| @@ -1271,16 +1462,7 @@ static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mod · 21 unmodified lines | ||
| 1271 | 1462 | cp_write(sd, 0x40, 0x5c); /* CP core pre-gain control. Graphics mode */ |
| 1272 | 1463 | break; |
| 1273 | 1464 | |
| 1274 | − case ADV7604_PRIM_MODE_HDMI_COMP: | |
| 1275 | − case ADV7604_PRIM_MODE_HDMI_GR: | |
| 1276 | − /* set mode and select free run resolution */ | |
| 1277 | − /* video std */ | |
| 1278 | − io_write(sd, 0x00, | |
| 1279 | − (prim_mode == ADV7604_PRIM_MODE_HDMI_GR) ? 0x02 : 0x1e); | |
| 1280 | − io_write(sd, 0x01, prim_mode); /* prim mode */ | |
| 1281 | − /* disable embedded syncs for auto graphics mode */ | |
| 1282 | − cp_write_and_or(sd, 0x81, 0xef, 0x00); | |
| 1283 | − | |
| 1465 | + case ADV7604_MODE_HDMI: | |
| 1284 | 1466 | /* set ADI recommended settings for HDMI: */ |
| 1285 | 1467 | /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */ |
| 1286 | 1468 | hdmi_write(sd, 0x0d, 0x84); /* HDMI filter optimization */ |
| @@ -1309,7 +1491,8 @@ static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mod · 22 unmodified lines | ||
| 1309 | 1491 | |
| 1310 | 1492 | break; |
| 1311 | 1493 | default: |
| 1312 | − v4l2_err(sd, "%s: reserved primary mode 0x%0x\n", __func__, prim_mode); | |
| 1494 | + v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n", | |
| 1495 | + __func__, state->mode); | |
| 1313 | 1496 | break; |
| 1314 | 1497 | } |
| 1315 | 1498 | } |
| @@ -1321,26 +1504,13 @@ static int adv7604_s_routing(struct v4l2_subdev *sd, · 5 unmodified lines | ||
| 1321 | 1504 | |
| 1322 | 1505 | v4l2_dbg(2, debug, sd, "%s: input %d", __func__, input); |
| 1323 | 1506 | |
| 1324 | − switch (input) { | |
| 1325 | − case 0: | |
| 1326 | − /* TODO select HDMI_COMP or HDMI_GR */ | |
| 1327 | − state->prim_mode = ADV7604_PRIM_MODE_HDMI_COMP; | |
| 1328 | − break; | |
| 1329 | − case 1: | |
| 1330 | − state->prim_mode = ADV7604_PRIM_MODE_RGB; | |
| 1331 | − break; | |
| 1332 | − case 2: | |
| 1333 | − state->prim_mode = ADV7604_PRIM_MODE_COMP; | |
| 1334 | − break; | |
| 1335 | − default: | |
| 1336 | − return -EINVAL; | |
| 1337 | − } | |
| 1507 | + state->mode = input; | |
| 1338 | 1508 | |
| 1339 | 1509 | disable_input(sd); |
| 1340 | 1510 | |
| 1341 | − select_input(sd, state->prim_mode); | |
| 1511 | + select_input(sd); | |
| 1342 | 1512 | |
| 1343 | − enable_input(sd, state->prim_mode); | |
| 1513 | + enable_input(sd); | |
| 1344 | 1514 | |
| 1345 | 1515 | return 0; |
| 1346 | 1516 | } |
| @@ -1549,8 +1719,9 @@ static int adv7604_log_status(struct v4l2_subdev *sd) · 202 unmodified lines | ||
| 1549 | 1719 | v4l2_info(sd, "CP locked: %s\n", no_lock_cp(sd) ? "false" : "true"); |
| 1550 | 1720 | v4l2_info(sd, "CP free run: %s\n", |
| 1551 | 1721 | (!!(cp_read(sd, 0xff) & 0x10) ? "on" : "off")); |
| 1552 | − v4l2_info(sd, "Prim-mode = 0x%x, video std = 0x%x\n", | |
| 1553 | − io_read(sd, 0x01) & 0x0f, io_read(sd, 0x00) & 0x3f); | |
| 1722 | + v4l2_info(sd, "Prim-mode = 0x%x, video std = 0x%x, v_freq = 0x%x\n", | |
| 1723 | + io_read(sd, 0x01) & 0x0f, io_read(sd, 0x00) & 0x3f, | |
| 1724 | + (io_read(sd, 0x01) & 0x70) >> 4); | |
| 1554 | 1725 | |
| 1555 | 1726 | v4l2_info(sd, "-----Video Timings-----\n"); |
| 1556 | 1727 | if (read_stdi(sd, &stdi)) |
| @@ -1712,9 +1883,9 @@ static int adv7604_core_init(struct v4l2_subdev *sd) · 155 unmodified lines | ||
| 1712 | 1883 | cp_write(sd, 0xba, (pdata->hdmi_free_run_mode << 1) | 0x01); /* HDMI free run */ |
| 1713 | 1884 | cp_write(sd, 0xf3, 0xdc); /* Low threshold to enter/exit free run mode */ |
| 1714 | 1885 | cp_write(sd, 0xf9, 0x23); /* STDI ch. 1 - LCVS change threshold - |
| 1715 | − ADI recommended setting [REF_01 c. 2.3.3] */ | |
| 1886 | + ADI recommended setting [REF_01, c. 2.3.3] */ | |
| 1716 | 1887 | cp_write(sd, 0x45, 0x23); /* STDI ch. 2 - LCVS change threshold - |
| 1717 | − ADI recommended setting [REF_01 c. 2.3.3] */ | |
| 1888 | + ADI recommended setting [REF_01, c. 2.3.3] */ | |
| 1718 | 1889 | cp_write(sd, 0xc9, 0x2d); /* use prim_mode and vid_std as free run resolution |
| 1719 | 1890 | for digital formats */ |
| 1720 | 1891 | |
| @@ -1724,11 +1895,6 @@ static int adv7604_core_init(struct v4l2_subdev *sd) · 3 unmodified lines | ||
| 1724 | 1895 | afe_write(sd, 0x02, pdata->ain_sel); /* Select analog input muxing mode */ |
| 1725 | 1896 | io_write_and_or(sd, 0x30, ~(1 << 4), pdata->output_bus_lsb_to_msb << 4); |
| 1726 | 1897 | |
| 1727 | − state->prim_mode = pdata->prim_mode; | |
| 1728 | − select_input(sd, pdata->prim_mode); | |
| 1729 | − | |
| 1730 | − enable_input(sd, pdata->prim_mode); | |
| 1731 | − | |
| 1732 | 1898 | /* interrupts */ |
| 1733 | 1899 | io_write(sd, 0x40, 0xc2); /* Configure INT1 */ |
| 1734 | 1900 | io_write(sd, 0x41, 0xd7); /* STDI irq for any change, disable INT2 */ |
| @@ -1883,6 +2049,7 @@ static int adv7604_probe(struct i2c_client *client, · 148 unmodified lines | ||
| 1883 | 2049 | v4l2_err(sd, "failed to create all i2c clients\n"); |
| 1884 | 2050 | goto err_i2c; |
| 1885 | 2051 | } |
| 2052 | + state->restart_stdi_once = true; | |
| 1886 | 2053 | |
| 1887 | 2054 | /* work queues */ |
| 1888 | 2055 | state->work_queues = create_singlethread_workqueue(client->name); |
| @@ -263,9 +263,14 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) · 262 unmodified lines | ||
| 263 | 263 | if (ret & 1) /* Autoexposure */ |
| 264 | 264 | ret = reg_write(client, mt9v022->reg->max_total_shutter_width, |
| 265 | 265 | rect.height + mt9v022->y_skip_top + 43); |
| 266 | − else | |
| 267 | − ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, | |
| 268 | − rect.height + mt9v022->y_skip_top + 43); | |
| 266 | + /* | |
| 267 | + * If autoexposure is off, there is no need to set | |
| 268 | + * MT9V022_TOTAL_SHUTTER_WIDTH here. Autoexposure can be off | |
| 269 | + * only if the user has set exposure manually, using the | |
| 270 | + * V4L2_CID_EXPOSURE_AUTO with the value V4L2_EXPOSURE_MANUAL. | |
| 271 | + * In this case the register MT9V022_TOTAL_SHUTTER_WIDTH | |
| 272 | + * already contains the correct value. | |
| 273 | + */ | |
| 269 | 274 | } |
| 270 | 275 | /* Setup frame format: defaults apart from width and height */ |
| 271 | 276 | if (!ret) |
| @@ -965,8 +965,10 @@ static struct platform_device_id gsc_driver_ids[] = { · 964 unmodified lines | ||
| 965 | 965 | MODULE_DEVICE_TABLE(platform, gsc_driver_ids); |
| 966 | 966 | |
| 967 | 967 | static const struct of_device_id exynos_gsc_match[] = { |
| 968 | − { .compatible = "samsung,exynos5250-gsc", | |
| 969 | − .data = &gsc_v_100_drvdata, }, | |
| 968 | + { | |
| 969 | + .compatible = "samsung,exynos5-gsc", | |
| 970 | + .data = &gsc_v_100_drvdata, | |
| 971 | + }, | |
| 970 | 972 | {}, |
| 971 | 973 | }; |
| 972 | 974 | MODULE_DEVICE_TABLE(of, exynos_gsc_match); |
| @@ -657,8 +657,7 @@ static int gsc_m2m_release(struct file *file) · 656 unmodified lines | ||
| 657 | 657 | pr_debug("pid: %d, state: 0x%lx, refcnt= %d", |
| 658 | 658 | task_pid_nr(current), gsc->state, gsc->m2m.refcnt); |
| 659 | 659 | |
| 660 | − if (mutex_lock_interruptible(&gsc->lock)) | |
| 661 | − return -ERESTARTSYS; | |
| 660 | + mutex_lock(&gsc->lock); | |
| 662 | 661 | |
| 663 | 662 | v4l2_m2m_ctx_release(ctx->m2m_ctx); |
| 664 | 663 | gsc_ctrls_delete(ctx); |
| @@ -732,6 +731,7 @@ int gsc_register_m2m_device(struct gsc_dev *gsc) · 67 unmodified lines | ||
| 732 | 731 | gsc->vdev.ioctl_ops = &gsc_m2m_ioctl_ops; |
| 733 | 732 | gsc->vdev.release = video_device_release_empty; |
| 734 | 733 | gsc->vdev.lock = &gsc->lock; |
| 734 | + gsc->vdev.vfl_dir = VFL_DIR_M2M; | |
| 735 | 735 | snprintf(gsc->vdev.name, sizeof(gsc->vdev.name), "%s.%d:m2m", |
| 736 | 736 | GSC_MODULE_NAME, gsc->id); |
| 737 | 737 | |
| @@ -40,10 +40,10 @@ · 39 unmodified lines | ||
| 40 | 40 | #define GSC_IN_ROT_YFLIP (2 << 16) |
| 41 | 41 | #define GSC_IN_ROT_XFLIP (1 << 16) |
| 42 | 42 | #define GSC_IN_RGB_TYPE_MASK (3 << 14) |
| 43 | −#define GSC_IN_RGB_HD_WIDE (3 << 14) | |
| 44 | −#define GSC_IN_RGB_HD_NARROW (2 << 14) | |
| 45 | −#define GSC_IN_RGB_SD_WIDE (1 << 14) | |
| 46 | −#define GSC_IN_RGB_SD_NARROW (0 << 14) | |
| 43 | +#define GSC_IN_RGB_HD_NARROW (3 << 14) | |
| 44 | +#define GSC_IN_RGB_HD_WIDE (2 << 14) | |
| 45 | +#define GSC_IN_RGB_SD_NARROW (1 << 14) | |
| 46 | +#define GSC_IN_RGB_SD_WIDE (0 << 14) | |
| 47 | 47 | #define GSC_IN_YUV422_1P_ORDER_MASK (1 << 13) |
| 48 | 48 | #define GSC_IN_YUV422_1P_ORDER_LSB_Y (0 << 13) |
| 49 | 49 | #define GSC_IN_YUV422_1P_OEDER_LSB_C (1 << 13) |
| @@ -85,10 +85,10 @@ · 35 unmodified lines | ||
| 85 | 85 | #define GSC_OUT_GLOBAL_ALPHA_MASK (0xff << 24) |
| 86 | 86 | #define GSC_OUT_GLOBAL_ALPHA(x) ((x) << 24) |
| 87 | 87 | #define GSC_OUT_RGB_TYPE_MASK (3 << 10) |
| 88 | −#define GSC_OUT_RGB_HD_NARROW (3 << 10) | |
| 89 | −#define GSC_OUT_RGB_HD_WIDE (2 << 10) | |
| 90 | −#define GSC_OUT_RGB_SD_NARROW (1 << 10) | |
| 91 | −#define GSC_OUT_RGB_SD_WIDE (0 << 10) | |
| 88 | +#define GSC_OUT_RGB_HD_WIDE (3 << 10) | |
| 89 | +#define GSC_OUT_RGB_HD_NARROW (2 << 10) | |
| 90 | +#define GSC_OUT_RGB_SD_WIDE (1 << 10) | |
| 91 | +#define GSC_OUT_RGB_SD_NARROW (0 << 10) | |
| 92 | 92 | #define GSC_OUT_YUV422_1P_ORDER_MASK (1 << 9) |
| 93 | 93 | #define GSC_OUT_YUV422_1P_ORDER_LSB_Y (0 << 9) |
| 94 | 94 | #define GSC_OUT_YUV422_1P_OEDER_LSB_C (1 << 9) |
| @@ -1706,7 +1706,7 @@ static long ccdc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) · 1705 unmodified lines | ||
| 1706 | 1706 | } |
| 1707 | 1707 | |
| 1708 | 1708 | static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, |
| 1709 | − const struct v4l2_event_subscription *sub) | |
| 1709 | + struct v4l2_event_subscription *sub) | |
| 1710 | 1710 | { |
| 1711 | 1711 | if (sub->type != V4L2_EVENT_FRAME_SYNC) |
| 1712 | 1712 | return -EINVAL; |
| @@ -1719,7 +1719,7 @@ static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, · 6 unmodified lines | ||
| 1719 | 1719 | } |
| 1720 | 1720 | |
| 1721 | 1721 | static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, |
| 1722 | − const struct v4l2_event_subscription *sub) | |
| 1722 | + struct v4l2_event_subscription *sub) | |
| 1723 | 1723 | { |
| 1724 | 1724 | return v4l2_event_unsubscribe(fh, sub); |
| 1725 | 1725 | } |
| @@ -1025,7 +1025,7 @@ void omap3isp_stat_dma_isr(struct ispstat *stat) · 1024 unmodified lines | ||
| 1025 | 1025 | |
| 1026 | 1026 | int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev, |
| 1027 | 1027 | struct v4l2_fh *fh, |
| 1028 | − const struct v4l2_event_subscription *sub) | |
| 1028 | + struct v4l2_event_subscription *sub) | |
| 1029 | 1029 | { |
| 1030 | 1030 | struct ispstat *stat = v4l2_get_subdevdata(subdev); |
| 1031 | 1031 | |
| @@ -1037,7 +1037,7 @@ int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev, · 5 unmodified lines | ||
| 1037 | 1037 | |
| 1038 | 1038 | int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev, |
| 1039 | 1039 | struct v4l2_fh *fh, |
| 1040 | − const struct v4l2_event_subscription *sub) | |
| 1040 | + struct v4l2_event_subscription *sub) | |
| 1041 | 1041 | { |
| 1042 | 1042 | return v4l2_event_unsubscribe(fh, sub); |
| 1043 | 1043 | } |
| @@ -147,10 +147,10 @@ int omap3isp_stat_init(struct ispstat *stat, const char *name, · 146 unmodified lines | ||
| 147 | 147 | void omap3isp_stat_cleanup(struct ispstat *stat); |
| 148 | 148 | int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev, |
| 149 | 149 | struct v4l2_fh *fh, |
| 150 | − const struct v4l2_event_subscription *sub); | |
| 150 | + struct v4l2_event_subscription *sub); | |
| 151 | 151 | int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev, |
| 152 | 152 | struct v4l2_fh *fh, |
| 153 | − const struct v4l2_event_subscription *sub); | |
| 153 | + struct v4l2_event_subscription *sub); | |
| 154 | 154 | int omap3isp_stat_s_stream(struct v4l2_subdev *subdev, int enable); |
| 155 | 155 | |
| 156 | 156 | int omap3isp_stat_busy(struct ispstat *stat); |
| @@ -792,7 +792,7 @@ isp_video_get_crop(struct file *file, void *fh, struct v4l2_crop *crop) · 791 unmodified lines | ||
| 792 | 792 | } |
| 793 | 793 | |
| 794 | 794 | static int |
| 795 | −isp_video_set_crop(struct file *file, void *fh, struct v4l2_crop *crop) | |
| 795 | +isp_video_set_crop(struct file *file, void *fh, const struct v4l2_crop *crop) | |
| 796 | 796 | { |
| 797 | 797 | struct isp_video *video = video_drvdata(file); |
| 798 | 798 | struct v4l2_subdev *subdev; |
| @@ -24,6 +24,7 @@ config VIDEO_S5P_FIMC · 23 unmodified lines | ||
| 24 | 24 | config VIDEO_S5P_MIPI_CSIS |
| 25 | 25 | tristate "S5P/EXYNOS MIPI-CSI2 receiver (MIPI-CSIS) driver" |
| 26 | 26 | depends on REGULATOR |
| 27 | + select S5P_SETUP_MIPIPHY | |
| 27 | 28 | help |
| 28 | 29 | This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC MIPI-CSI2 |
| 29 | 30 | receiver (MIPI-CSIS) devices. |
| @@ -556,8 +556,7 @@ static int fimc_capture_close(struct file *file) · 555 unmodified lines | ||
| 556 | 556 | |
| 557 | 557 | dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state); |
| 558 | 558 | |
| 559 | − if (mutex_lock_interruptible(&fimc->lock)) | |
| 560 | − return -ERESTARTSYS; | |
| 559 | + mutex_lock(&fimc->lock); | |
| 561 | 560 | |
| 562 | 561 | if (--fimc->vid_cap.refcnt == 0) { |
| 563 | 562 | clear_bit(ST_CAPT_BUSY, &fimc->state); |
| @@ -1736,7 +1735,9 @@ static int fimc_register_capture_device(struct fimc_dev *fimc, · 1172 unmodified lines | ||
| 1736 | 1735 | q->mem_ops = &vb2_dma_contig_memops; |
| 1737 | 1736 | q->buf_struct_size = sizeof(struct fimc_vid_buffer); |
| 1738 | 1737 | |
| 1739 | − vb2_queue_init(q); | |
| 1738 | + ret = vb2_queue_init(q); | |
| 1739 | + if (ret) | |
| 1740 | + goto err_ent; | |
| 1740 | 1741 | |
| 1741 | 1742 | vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK; |
| 1742 | 1743 | ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0); |
| @@ -1772,9 +1773,13 @@ static int fimc_capture_subdev_registered(struct v4l2_subdev *sd) · 29 unmodified lines | ||
| 1772 | 1773 | if (ret) |
| 1773 | 1774 | return ret; |
| 1774 | 1775 | |
| 1776 | + fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd); | |
| 1777 | + | |
| 1775 | 1778 | ret = fimc_register_capture_device(fimc, sd->v4l2_dev); |
| 1776 | − if (ret) | |
| 1779 | + if (ret) { | |
| 1777 | 1780 | fimc_unregister_m2m_device(fimc); |
| 1781 | + fimc->pipeline_ops = NULL; | |
| 1782 | + } | |
| 1778 | 1783 | |
| 1779 | 1784 | return ret; |
| 1780 | 1785 | } |
| @@ -1791,6 +1796,7 @@ static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd) · 10 unmodified lines | ||
| 1791 | 1796 | if (video_is_registered(&fimc->vid_cap.vfd)) { |
| 1792 | 1797 | video_unregister_device(&fimc->vid_cap.vfd); |
| 1793 | 1798 | media_entity_cleanup(&fimc->vid_cap.vfd.entity); |
| 1799 | + fimc->pipeline_ops = NULL; | |
| 1794 | 1800 | } |
| 1795 | 1801 | kfree(fimc->vid_cap.ctx); |
| 1796 | 1802 | fimc->vid_cap.ctx = NULL; |
| @@ -491,8 +491,7 @@ static int fimc_lite_close(struct file *file) · 490 unmodified lines | ||
| 491 | 491 | struct fimc_lite *fimc = video_drvdata(file); |
| 492 | 492 | int ret; |
| 493 | 493 | |
| 494 | − if (mutex_lock_interruptible(&fimc->lock)) | |
| 495 | − return -ERESTARTSYS; | |
| 494 | + mutex_lock(&fimc->lock); | |
| 496 | 495 | |
| 497 | 496 | if (--fimc->ref_count == 0 && fimc->out_path == FIMC_IO_DMA) { |
| 498 | 497 | clear_bit(ST_FLITE_IN_USE, &fimc->state); |
| @@ -1253,7 +1252,9 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd) · 754 unmodified lines | ||
| 1253 | 1252 | q->buf_struct_size = sizeof(struct flite_buffer); |
| 1254 | 1253 | q->drv_priv = fimc; |
| 1255 | 1254 | |
| 1256 | − vb2_queue_init(q); | |
| 1255 | + ret = vb2_queue_init(q); | |
| 1256 | + if (ret < 0) | |
| 1257 | + return ret; | |
| 1257 | 1258 | |
| 1258 | 1259 | fimc->vd_pad.flags = MEDIA_PAD_FL_SINK; |
| 1259 | 1260 | ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0); |
| @@ -1261,10 +1262,12 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd) · 1 unmodified line | ||
| 1261 | 1262 | return ret; |
| 1262 | 1263 | |
| 1263 | 1264 | video_set_drvdata(vfd, fimc); |
| 1265 | + fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd); | |
| 1264 | 1266 | |
| 1265 | 1267 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); |
| 1266 | 1268 | if (ret < 0) { |
| 1267 | 1269 | media_entity_cleanup(&vfd->entity); |
| 1270 | + fimc->pipeline_ops = NULL; | |
| 1268 | 1271 | return ret; |
| 1269 | 1272 | } |
| 1270 | 1273 | |
| @@ -1283,6 +1286,7 @@ static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd) · 12 unmodified lines | ||
| 1283 | 1286 | if (video_is_registered(&fimc->vfd)) { |
| 1284 | 1287 | video_unregister_device(&fimc->vfd); |
| 1285 | 1288 | media_entity_cleanup(&fimc->vfd.entity); |
| 1289 | + fimc->pipeline_ops = NULL; | |
| 1286 | 1290 | } |
| 1287 | 1291 | } |
| 1288 | 1292 | |
| @@ -718,8 +718,7 @@ static int fimc_m2m_release(struct file *file) · 717 unmodified lines | ||
| 718 | 718 | dbg("pid: %d, state: 0x%lx, refcnt= %d", |
| 719 | 719 | task_pid_nr(current), fimc->state, fimc->m2m.refcnt); |
| 720 | 720 | |
| 721 | − if (mutex_lock_interruptible(&fimc->lock)) | |
| 722 | − return -ERESTARTSYS; | |
| 721 | + mutex_lock(&fimc->lock); | |
| 723 | 722 | |
| 724 | 723 | v4l2_m2m_ctx_release(ctx->m2m_ctx); |
| 725 | 724 | fimc_ctrls_delete(ctx); |
| @@ -343,53 +343,50 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) · 342 unmodified lines | ||
| 343 | 343 | static int fimc_register_callback(struct device *dev, void *p) |
| 344 | 344 | { |
| 345 | 345 | struct fimc_dev *fimc = dev_get_drvdata(dev); |
| 346 | − struct v4l2_subdev *sd = &fimc->vid_cap.subdev; | |
| 346 | + struct v4l2_subdev *sd; | |
| 347 | 347 | struct fimc_md *fmd = p; |
| 348 | − int ret = 0; | |
| 349 | − | |
| 350 | − if (!fimc || !fimc->pdev) | |
| 351 | − return 0; | |
| 348 | + int ret; | |
| 352 | 349 | |
| 353 | − if (fimc->pdev->id < 0 || fimc->pdev->id >= FIMC_MAX_DEVS) | |
| 350 | + if (fimc == NULL || fimc->id >= FIMC_MAX_DEVS) | |
| 354 | 351 | return 0; |
| 355 | 352 | |
| 356 | − fimc->pipeline_ops = &fimc_pipeline_ops; | |
| 357 | − fmd->fimc[fimc->pdev->id] = fimc; | |
| 353 | + sd = &fimc->vid_cap.subdev; | |
| 358 | 354 | sd->grp_id = FIMC_GROUP_ID; |
| 355 | + v4l2_set_subdev_hostdata(sd, (void *)&fimc_pipeline_ops); | |
| 359 | 356 | |
| 360 | 357 | ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); |
| 361 | 358 | if (ret) { |
| 362 | 359 | v4l2_err(&fmd->v4l2_dev, "Failed to register FIMC.%d (%d)\n", |
| 363 | 360 | fimc->id, ret); |
| 361 | + return ret; | |
| 364 | 362 | } |
| 365 | 363 | |
| 366 | − return ret; | |
| 364 | + fmd->fimc[fimc->id] = fimc; | |
| 365 | + return 0; | |
| 367 | 366 | } |
| 368 | 367 | |
| 369 | 368 | static int fimc_lite_register_callback(struct device *dev, void *p) |
| 370 | 369 | { |
| 371 | 370 | struct fimc_lite *fimc = dev_get_drvdata(dev); |
| 372 | − struct v4l2_subdev *sd = &fimc->subdev; | |
| 373 | 371 | struct fimc_md *fmd = p; |
| 374 | 372 | int ret; |
| 375 | 373 | |
| 376 | − if (fimc == NULL) | |
| 374 | + if (fimc == NULL || fimc->index >= FIMC_LITE_MAX_DEVS) | |
| 377 | 375 | return 0; |
| 378 | 376 | |
| 379 | − if (fimc->index >= FIMC_LITE_MAX_DEVS) | |
| 380 | − return 0; | |
| 381 | − | |
| 382 | − fimc->pipeline_ops = &fimc_pipeline_ops; | |
| 383 | − fmd->fimc_lite[fimc->index] = fimc; | |
| 384 | − sd->grp_id = FLITE_GROUP_ID; | |
| 377 | + fimc->subdev.grp_id = FLITE_GROUP_ID; | |
| 378 | + v4l2_set_subdev_hostdata(&fimc->subdev, (void *)&fimc_pipeline_ops); | |
| 385 | 379 | |
| 386 | − ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); | |
| 380 | + ret = v4l2_device_register_subdev(&fmd->v4l2_dev, &fimc->subdev); | |
| 387 | 381 | if (ret) { |
| 388 | 382 | v4l2_err(&fmd->v4l2_dev, |
| 389 | 383 | "Failed to register FIMC-LITE.%d (%d)\n", |
| 390 | 384 | fimc->index, ret); |
| 385 | + return ret; | |
| 391 | 386 | } |
| 392 | − return ret; | |
| 387 | + | |
| 388 | + fmd->fimc_lite[fimc->index] = fimc; | |
| 389 | + return 0; | |
| 393 | 390 | } |
| 394 | 391 | |
| 395 | 392 | static int csis_register_callback(struct device *dev, void *p) |
| @@ -407,10 +404,12 @@ static int csis_register_callback(struct device *dev, void *p) · 11 unmodified lines | ||
| 407 | 404 | v4l2_info(sd, "csis%d sd: %s\n", pdev->id, sd->name); |
| 408 | 405 | |
| 409 | 406 | id = pdev->id < 0 ? 0 : pdev->id; |
| 410 | − fmd->csis[id].sd = sd; | |
| 411 | 407 | sd->grp_id = CSIS_GROUP_ID; |
| 408 | + | |
| 412 | 409 | ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); |
| 413 | − if (ret) | |
| 410 | + if (!ret) | |
| 411 | + fmd->csis[id].sd = sd; | |
| 412 | + else | |
| 414 | 413 | v4l2_err(&fmd->v4l2_dev, |
| 415 | 414 | "Failed to register CSIS subdevice: %d\n", ret); |
| 416 | 415 | return ret; |
| @@ -381,11 +381,8 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx, · 380 unmodified lines | ||
| 381 | 381 | ctx->consumed_stream += s5p_mfc_hw_call(dev->mfc_ops, |
| 382 | 382 | get_consumed_stream, dev); |
| 383 | 383 | if (ctx->codec_mode != S5P_MFC_CODEC_H264_DEC && |
| 384 | − s5p_mfc_hw_call(dev->mfc_ops, | |
| 385 | − get_dec_frame_type, dev) == | |
| 386 | − S5P_FIMV_DECODE_FRAME_P_FRAME | |
| 387 | − && ctx->consumed_stream + STUFF_BYTE < | |
| 388 | − src_buf->b->v4l2_planes[0].bytesused) { | |
| 384 | + ctx->consumed_stream + STUFF_BYTE < | |
| 385 | + src_buf->b->v4l2_planes[0].bytesused) { | |
| 389 | 386 | /* Run MFC again on the same buffer */ |
| 390 | 387 | mfc_debug(2, "Running again the same buffer\n"); |
| 391 | 388 | ctx->after_packed_pb = 1; |
| @@ -1762,7 +1762,7 @@ int s5p_mfc_get_dspl_y_adr_v6(struct s5p_mfc_dev *dev) · 1761 unmodified lines | ||
| 1762 | 1762 | |
| 1763 | 1763 | int s5p_mfc_get_dec_y_adr_v6(struct s5p_mfc_dev *dev) |
| 1764 | 1764 | { |
| 1765 | − return mfc_read(dev, S5P_FIMV_D_DISPLAY_LUMA_ADDR_V6); | |
| 1765 | + return mfc_read(dev, S5P_FIMV_D_DECODED_LUMA_ADDR_V6); | |
| 1766 | 1766 | } |
| 1767 | 1767 | |
| 1768 | 1768 | int s5p_mfc_get_dspl_status_v6(struct s5p_mfc_dev *dev) |
| @@ -935,9 +935,10 @@ static int sh_vou_g_crop(struct file *file, void *fh, struct v4l2_crop *a) · 934 unmodified lines | ||
| 935 | 935 | /* Assume a dull encoder, do all the work ourselves. */ |
| 936 | 936 | static int sh_vou_s_crop(struct file *file, void *fh, const struct v4l2_crop *a) |
| 937 | 937 | { |
| 938 | + struct v4l2_crop a_writable = *a; | |
| 938 | 939 | struct video_device *vdev = video_devdata(file); |
| 939 | 940 | struct sh_vou_device *vou_dev = video_get_drvdata(vdev); |
| 940 | − struct v4l2_rect *rect = &a->c; | |
| 941 | + struct v4l2_rect *rect = &a_writable.c; | |
| 941 | 942 | struct v4l2_crop sd_crop = {.type = V4L2_BUF_TYPE_VIDEO_OUTPUT}; |
| 942 | 943 | struct v4l2_pix_format *pix = &vou_dev->pix; |
| 943 | 944 | struct sh_vou_geometry geo; |
| @@ -470,14 +470,6 @@ static void mx1_camera_remove_device(struct soc_camera_device *icd) · 469 unmodified lines | ||
| 470 | 470 | pcdev->icd = NULL; |
| 471 | 471 | } |
| 472 | 472 | |
| 473 | −static int mx1_camera_set_crop(struct soc_camera_device *icd, | |
| 474 | − struct v4l2_crop *a) | |
| 475 | −{ | |
| 476 | − struct v4l2_subdev *sd = soc_camera_to_subdev(icd); | |
| 477 | − | |
| 478 | − return v4l2_subdev_call(sd, video, s_crop, a); | |
| 479 | −} | |
| 480 | − | |
| 481 | 473 | static int mx1_camera_set_bus_param(struct soc_camera_device *icd) |
| 482 | 474 | { |
| 483 | 475 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
| @@ -689,7 +681,6 @@ static struct soc_camera_host_ops mx1_soc_camera_host_ops = { · 205 unmodified lines | ||
| 689 | 681 | .add = mx1_camera_add_device, |
| 690 | 682 | .remove = mx1_camera_remove_device, |
| 691 | 683 | .set_bus_param = mx1_camera_set_bus_param, |
| 692 | − .set_crop = mx1_camera_set_crop, | |
| 693 | 684 | .set_fmt = mx1_camera_set_fmt, |
| 694 | 685 | .try_fmt = mx1_camera_try_fmt, |
| 695 | 686 | .init_videobuf = mx1_camera_init_videobuf, |
| @@ -864,8 +864,10 @@ static int mx2_start_streaming(struct vb2_queue *q, unsigned int count) · 863 unmodified lines | ||
| 864 | 864 | |
| 865 | 865 | bytesperline = soc_mbus_bytes_per_line(icd->user_width, |
| 866 | 866 | icd->current_fmt->host_fmt); |
| 867 | − if (bytesperline < 0) | |
| 867 | + if (bytesperline < 0) { | |
| 868 | + spin_unlock_irqrestore(&pcdev->lock, flags); | |
| 868 | 869 | return bytesperline; |
| 870 | + } | |
| 869 | 871 | |
| 870 | 872 | /* |
| 871 | 873 | * I didn't manage to properly enable/disable the prp |
| @@ -878,8 +880,10 @@ static int mx2_start_streaming(struct vb2_queue *q, unsigned int count) · 6 unmodified lines | ||
| 878 | 880 | pcdev->discard_buffer = dma_alloc_coherent(ici->v4l2_dev.dev, |
| 879 | 881 | pcdev->discard_size, &pcdev->discard_buffer_dma, |
| 880 | 882 | GFP_KERNEL); |
| 881 | − if (!pcdev->discard_buffer) | |
| 883 | + if (!pcdev->discard_buffer) { | |
| 884 | + spin_unlock_irqrestore(&pcdev->lock, flags); | |
| 882 | 885 | return -ENOMEM; |
| 886 | + } | |
| 883 | 887 | |
| 884 | 888 | pcdev->buf_discard[0].discard = true; |
| 885 | 889 | list_add_tail(&pcdev->buf_discard[0].queue, |
| @@ -1099,9 +1103,10 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd) · 213 unmodified lines | ||
| 1099 | 1103 | } |
| 1100 | 1104 | |
| 1101 | 1105 | static int mx2_camera_set_crop(struct soc_camera_device *icd, |
| 1102 | − struct v4l2_crop *a) | |
| 1106 | + const struct v4l2_crop *a) | |
| 1103 | 1107 | { |
| 1104 | − struct v4l2_rect *rect = &a->c; | |
| 1108 | + struct v4l2_crop a_writable = *a; | |
| 1109 | + struct v4l2_rect *rect = &a_writable.c; | |
| 1105 | 1110 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
| 1106 | 1111 | struct v4l2_mbus_framefmt mf; |
| 1107 | 1112 | int ret; |
| @@ -799,9 +799,10 @@ static inline void stride_align(__u32 *width) · 798 unmodified lines | ||
| 799 | 799 | * default g_crop and cropcap from soc_camera.c |
| 800 | 800 | */ |
| 801 | 801 | static int mx3_camera_set_crop(struct soc_camera_device *icd, |
| 802 | − struct v4l2_crop *a) | |
| 802 | + const struct v4l2_crop *a) | |
| 803 | 803 | { |
| 804 | − struct v4l2_rect *rect = &a->c; | |
| 804 | + struct v4l2_crop a_writable = *a; | |
| 805 | + struct v4l2_rect *rect = &a_writable.c; | |
| 805 | 806 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
| 806 | 807 | struct mx3_camera_dev *mx3_cam = ici->priv; |
| 807 | 808 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
| @@ -1215,9 +1215,9 @@ static int set_mbus_format(struct omap1_cam_dev *pcdev, struct device *dev, · 1214 unmodified lines | ||
| 1215 | 1215 | } |
| 1216 | 1216 | |
| 1217 | 1217 | static int omap1_cam_set_crop(struct soc_camera_device *icd, |
| 1218 | − struct v4l2_crop *crop) | |
| 1218 | + const struct v4l2_crop *crop) | |
| 1219 | 1219 | { |
| 1220 | − struct v4l2_rect *rect = &crop->c; | |
| 1220 | + const struct v4l2_rect *rect = &crop->c; | |
| 1221 | 1221 | const struct soc_camera_format_xlate *xlate = icd->current_fmt; |
| 1222 | 1222 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
| 1223 | 1223 | struct device *dev = icd->parent; |
| @@ -1337,9 +1337,9 @@ static int pxa_camera_check_frame(u32 width, u32 height) · 1336 unmodified lines | ||
| 1337 | 1337 | } |
| 1338 | 1338 | |
| 1339 | 1339 | static int pxa_camera_set_crop(struct soc_camera_device *icd, |
| 1340 | − struct v4l2_crop *a) | |
| 1340 | + const struct v4l2_crop *a) | |
| 1341 | 1341 | { |
| 1342 | − struct v4l2_rect *rect = &a->c; | |
| 1342 | + const struct v4l2_rect *rect = &a->c; | |
| 1343 | 1343 | struct device *dev = icd->parent; |
| 1344 | 1344 | struct soc_camera_host *ici = to_soc_camera_host(dev); |
| 1345 | 1345 | struct pxa_camera_dev *pcdev = ici->priv; |
| @@ -1182,13 +1182,13 @@ static void sh_mobile_ceu_put_formats(struct soc_camera_device *icd) · 1181 unmodified lines | ||
| 1182 | 1182 | } |
| 1183 | 1183 | |
| 1184 | 1184 | /* Check if any dimension of r1 is smaller than respective one of r2 */ |
| 1185 | −static bool is_smaller(struct v4l2_rect *r1, struct v4l2_rect *r2) | |
| 1185 | +static bool is_smaller(const struct v4l2_rect *r1, const struct v4l2_rect *r2) | |
| 1186 | 1186 | { |
| 1187 | 1187 | return r1->width < r2->width || r1->height < r2->height; |
| 1188 | 1188 | } |
| 1189 | 1189 | |
| 1190 | 1190 | /* Check if r1 fails to cover r2 */ |
| 1191 | −static bool is_inside(struct v4l2_rect *r1, struct v4l2_rect *r2) | |
| 1191 | +static bool is_inside(const struct v4l2_rect *r1, const struct v4l2_rect *r2) | |
| 1192 | 1192 | { |
| 1193 | 1193 | return r1->left > r2->left || r1->top > r2->top || |
| 1194 | 1194 | r1->left + r1->width < r2->left + r2->width || |
| @@ -1263,7 +1263,7 @@ static void update_subrect(struct sh_mobile_ceu_cam *cam) · 68 unmodified lines | ||
| 1263 | 1263 | * 3. if (2) failed, try to request the maximum image |
| 1264 | 1264 | */ |
| 1265 | 1265 | static int client_s_crop(struct soc_camera_device *icd, struct v4l2_crop *crop, |
| 1266 | − const struct v4l2_crop *cam_crop) | |
| 1266 | + struct v4l2_crop *cam_crop) | |
| 1267 | 1267 | { |
| 1268 | 1268 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
| 1269 | 1269 | struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c; |
| @@ -1519,7 +1519,8 @@ static int client_scale(struct soc_camera_device *icd, · 249 unmodified lines | ||
| 1519 | 1519 | static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, |
| 1520 | 1520 | const struct v4l2_crop *a) |
| 1521 | 1521 | { |
| 1522 | − struct v4l2_rect *rect = &a->c; | |
| 1522 | + struct v4l2_crop a_writable = *a; | |
| 1523 | + const struct v4l2_rect *rect = &a_writable.c; | |
| 1523 | 1524 | struct device *dev = icd->parent; |
| 1524 | 1525 | struct soc_camera_host *ici = to_soc_camera_host(dev); |
| 1525 | 1526 | struct sh_mobile_ceu_dev *pcdev = ici->priv; |
| @@ -1545,7 +1546,7 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, · 19 unmodified lines | ||
| 1545 | 1546 | * 1. - 2. Apply iterative camera S_CROP for new input window, read back |
| 1546 | 1547 | * actual camera rectangle. |
| 1547 | 1548 | */ |
| 1548 | − ret = client_s_crop(icd, a, &cam_crop); | |
| 1549 | + ret = client_s_crop(icd, &a_writable, &cam_crop); | |
| 1549 | 1550 | if (ret < 0) |
| 1550 | 1551 | return ret; |
| 1551 | 1552 | |
| @@ -1946,7 +1947,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, · 394 unmodified lines | ||
| 1946 | 1947 | } |
| 1947 | 1948 | |
| 1948 | 1949 | static int sh_mobile_ceu_set_livecrop(struct soc_camera_device *icd, |
| 1949 | − struct v4l2_crop *a) | |
| 1950 | + const struct v4l2_crop *a) | |
| 1950 | 1951 | { |
| 1951 | 1952 | struct v4l2_subdev *sd = soc_camera_to_subdev(icd); |
| 1952 | 1953 | struct soc_camera_host *ici = to_soc_camera_host(icd->parent); |
| @@ -283,14 +283,13 @@ static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, · 282 unmodified lines | ||
| 283 | 283 | |
| 284 | 284 | /* activate the pid on the device pid filter */ |
| 285 | 285 | if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER && |
| 286 | − adap->pid_filtering && | |
| 287 | − adap->props->pid_filter) | |
| 286 | + adap->pid_filtering && adap->props->pid_filter) { | |
| 288 | 287 | ret = adap->props->pid_filter(adap, dvbdmxfeed->index, |
| 289 | 288 | dvbdmxfeed->pid, (count == 1) ? 1 : 0); |
| 290 | − if (ret < 0) | |
| 291 | − dev_err(&d->udev->dev, "%s: pid_filter() " \ | |
| 292 | − "failed=%d\n", KBUILD_MODNAME, | |
| 293 | − ret); | |
| 289 | + if (ret < 0) | |
| 290 | + dev_err(&d->udev->dev, "%s: pid_filter() failed=%d\n", | |
| 291 | + KBUILD_MODNAME, ret); | |
| 292 | + } | |
| 294 | 293 | |
| 295 | 294 | /* start feeding if it is first pid */ |
| 296 | 295 | if (adap->feed_count == 1 && count == 1) { |
| @@ -32,9 +32,7 @@ int dvb_usbv2_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, · 31 unmodified lines | ||
| 32 | 32 | return -EINVAL; |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | − ret = mutex_lock_interruptible(&d->usb_mutex); | |
| 36 | − if (ret < 0) | |
| 37 | − return ret; | |
| 35 | + mutex_lock(&d->usb_mutex); | |
| 38 | 36 | |
| 39 | 37 | dev_dbg(&d->udev->dev, "%s: >>> %*ph\n", __func__, wlen, wbuf); |
| 40 | 38 | |
| @@ -1346,6 +1346,10 @@ static const struct usb_device_id rtl28xxu_id_table[] = { · 1345 unmodified lines | ||
| 1346 | 1346 | &rtl2832u_props, "DigitalNow Quad DVB-T Receiver", NULL) }, |
| 1347 | 1347 | { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00d3, |
| 1348 | 1348 | &rtl2832u_props, "TerraTec Cinergy T Stick RC (Rev. 3)", NULL) }, |
| 1349 | + { DVB_USB_DEVICE(USB_VID_DEXATEK, 0x1102, | |
| 1350 | + &rtl2832u_props, "Dexatek DK mini DVB-T Dongle", NULL) }, | |
| 1351 | + { DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00d7, | |
| 1352 | + &rtl2832u_props, "TerraTec Cinergy T Stick+", NULL) }, | |
| 1349 | 1353 | { } |
| 1350 | 1354 | }; |
| 1351 | 1355 | MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table); |
| @@ -96,11 +96,11 @@ static irqreturn_t arizona_underclocked(int irq, void *data) · 95 unmodified lines | ||
| 96 | 96 | return IRQ_NONE; |
| 97 | 97 | } |
| 98 | 98 | |
| 99 | − if (val & ARIZONA_AIF3_UNDERCLOCKED_STS) | |
| 100 | − dev_err(arizona->dev, "AIF3 underclocked\n"); | |
| 101 | 99 | if (val & ARIZONA_AIF3_UNDERCLOCKED_STS) |
| 102 | 100 | dev_err(arizona->dev, "AIF3 underclocked\n"); |
| 103 | 101 | if (val & ARIZONA_AIF2_UNDERCLOCKED_STS) |
| 102 | + dev_err(arizona->dev, "AIF2 underclocked\n"); | |
| 103 | + if (val & ARIZONA_AIF1_UNDERCLOCKED_STS) | |
| 104 | 104 | dev_err(arizona->dev, "AIF1 underclocked\n"); |
| 105 | 105 | if (val & ARIZONA_ISRC2_UNDERCLOCKED_STS) |
| 106 | 106 | dev_err(arizona->dev, "ISRC2 underclocked\n"); |
| @@ -415,11 +415,19 @@ int __devinit arizona_dev_init(struct arizona *arizona) · 308 unmodified lines | ||
| 415 | 415 | |
| 416 | 416 | /* If we have a /RESET GPIO we'll already be reset */ |
| 417 | 417 | if (!arizona->pdata.reset) { |
| 418 | + regcache_mark_dirty(arizona->regmap); | |
| 419 | + | |
| 418 | 420 | ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0); |
| 419 | 421 | if (ret != 0) { |
| 420 | 422 | dev_err(dev, "Failed to reset device: %d\n", ret); |
| 421 | 423 | goto err_reset; |
| 422 | 424 | } |
| 425 | + | |
| 426 | + ret = regcache_sync(arizona->regmap); | |
| 427 | + if (ret != 0) { | |
| 428 | + dev_err(dev, "Failed to sync device: %d\n", ret); | |
| 429 | + goto err_reset; | |
| 430 | + } | |
| 423 | 431 | } |
| 424 | 432 | |
| 425 | 433 | ret = arizona_wait_for_boot(arizona); |
| @@ -520,7 +528,7 @@ int __devinit arizona_dev_init(struct arizona *arizona) · 94 unmodified lines | ||
| 520 | 528 | break; |
| 521 | 529 | case WM5110: |
| 522 | 530 | ret = mfd_add_devices(arizona->dev, -1, wm5110_devs, |
| 523 | − ARRAY_SIZE(wm5102_devs), NULL, 0, NULL); | |
| 531 | + ARRAY_SIZE(wm5110_devs), NULL, 0, NULL); | |
| 524 | 532 | break; |
| 525 | 533 | } |
| 526 | 534 | |
| @@ -178,6 +178,7 @@ int arizona_irq_init(struct arizona *arizona) · 177 unmodified lines | ||
| 178 | 178 | |
| 179 | 179 | switch (arizona->rev) { |
| 180 | 180 | case 0: |
| 181 | + case 1: | |
| 181 | 182 | ctrlif_error = false; |
| 182 | 183 | break; |
| 183 | 184 | default: |
| @@ -671,7 +671,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base, · 670 unmodified lines | ||
| 671 | 671 | } |
| 672 | 672 | |
| 673 | 673 | if (IS_ENABLED(CONFIG_PWM_TWL6030) && twl_class_is_6030()) { |
| 674 | − child = add_child(TWL6030_MODULE_ID1, "twl6030-pwm", NULL, 0, | |
| 674 | + child = add_child(SUB_CHIP_ID1, "twl6030-pwm", NULL, 0, | |
| 675 | 675 | false, 0, 0); |
| 676 | 676 | if (IS_ERR(child)) |
| 677 | 677 | return PTR_ERR(child); |
| @@ -672,7 +672,8 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base) · 671 unmodified lines | ||
| 672 | 672 | irq = sih_mod + twl4030_irq_base; |
| 673 | 673 | irq_set_handler_data(irq, agent); |
| 674 | 674 | agent->irq_name = kasprintf(GFP_KERNEL, "twl4030_%s", sih->name); |
| 675 | − status = request_threaded_irq(irq, NULL, handle_twl4030_sih, 0, | |
| 675 | + status = request_threaded_irq(irq, NULL, handle_twl4030_sih, | |
| 676 | + IRQF_EARLY_RESUME, | |
| 676 | 677 | agent->irq_name ?: sih->name, NULL); |
| 677 | 678 | |
| 678 | 679 | dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", sih->name, |
| @@ -43,6 +43,7 @@ static const struct reg_default wm5102_reva_patch[] = { · 42 unmodified lines | ||
| 43 | 43 | { 0x479, 0x0A30 }, |
| 44 | 44 | { 0x47B, 0x0810 }, |
| 45 | 45 | { 0x47D, 0x0510 }, |
| 46 | + { 0x4D1, 0x017F }, | |
| 46 | 47 | { 0x500, 0x000D }, |
| 47 | 48 | { 0x507, 0x1820 }, |
| 48 | 49 | { 0x508, 0x1820 }, |
| @@ -52,524 +53,6 @@ static const struct reg_default wm5102_reva_patch[] = { · 3 unmodified lines | ||
| 52 | 53 | { 0x580, 0x000D }, |
| 53 | 54 | { 0x587, 0x1820 }, |
| 54 | 55 | { 0x588, 0x1820 }, |
| 55 | − { 0x101, 0x8140 }, | |
| 56 | − { 0x3000, 0x2225 }, | |
| 57 | − { 0x3001, 0x3a03 }, | |
| 58 | − { 0x3002, 0x0225 }, | |
| 59 | − { 0x3003, 0x0801 }, | |
| 60 | − { 0x3004, 0x6249 }, | |
| 61 | − { 0x3005, 0x0c04 }, | |
| 62 | − { 0x3006, 0x0225 }, | |
| 63 | − { 0x3007, 0x5901 }, | |
| 64 | − { 0x3008, 0xe249 }, | |
| 65 | − { 0x3009, 0x030d }, | |
| 66 | − { 0x300a, 0x0249 }, | |
| 67 | − { 0x300b, 0x2c01 }, | |
| 68 | − { 0x300c, 0xe249 }, | |
| 69 | − { 0x300d, 0x4342 }, | |
| 70 | − { 0x300e, 0xe249 }, | |
| 71 | − { 0x300f, 0x73c0 }, | |
| 72 | − { 0x3010, 0x4249 }, | |
| 73 | − { 0x3011, 0x0c00 }, | |
| 74 | − { 0x3012, 0x0225 }, | |
| 75 | − { 0x3013, 0x1f01 }, | |
| 76 | − { 0x3014, 0x0225 }, | |
| 77 | − { 0x3015, 0x1e01 }, | |
| 78 | − { 0x3016, 0x0225 }, | |
| 79 | − { 0x3017, 0xfa00 }, | |
| 80 | − { 0x3018, 0x0000 }, | |
| 81 | − { 0x3019, 0xf000 }, | |
| 82 | − { 0x301a, 0x0000 }, | |
| 83 | − { 0x301b, 0xf000 }, | |
| 84 | − { 0x301c, 0x0000 }, | |
| 85 | − { 0x301d, 0xf000 }, | |
| 86 | − { 0x301e, 0x0000 }, | |
| 87 | − { 0x301f, 0xf000 }, | |
| 88 | − { 0x3020, 0x0000 }, | |
| 89 | − { 0x3021, 0xf000 }, | |
| 90 | − { 0x3022, 0x0000 }, | |
| 91 | − { 0x3023, 0xf000 }, | |
| 92 | − { 0x3024, 0x0000 }, | |
| 93 | − { 0x3025, 0xf000 }, | |
| 94 | − { 0x3026, 0x0000 }, | |
| 95 | − { 0x3027, 0xf000 }, | |
| 96 | − { 0x3028, 0x0000 }, | |
| 97 | − { 0x3029, 0xf000 }, | |
| 98 | − { 0x302a, 0x0000 }, | |
| 99 | − { 0x302b, 0xf000 }, | |
| 100 | − { 0x302c, 0x0000 }, | |
| 101 | − { 0x302d, 0xf000 }, | |
| 102 | − { 0x302e, 0x0000 }, | |
| 103 | − { 0x302f, 0xf000 }, | |
| 104 | − { 0x3030, 0x0225 }, | |
| 105 | − { 0x3031, 0x1a01 }, | |
| 106 | − { 0x3032, 0x0225 }, | |
| 107 | − { 0x3033, 0x1e00 }, | |
| 108 | − { 0x3034, 0x0225 }, | |
| 109 | − { 0x3035, 0x1f00 }, | |
| 110 | − { 0x3036, 0x6225 }, | |
| 111 | − { 0x3037, 0xf800 }, | |
| 112 | − { 0x3038, 0x0000 }, | |
| 113 | − { 0x3039, 0xf000 }, | |
| 114 | − { 0x303a, 0x0000 }, | |
| 115 | − { 0x303b, 0xf000 }, | |
| 116 | − { 0x303c, 0x0000 }, | |
| 117 | − { 0x303d, 0xf000 }, | |
| 118 | − { 0x303e, 0x0000 }, | |
| 119 | − { 0x303f, 0xf000 }, | |
| 120 | − { 0x3040, 0x2226 }, | |
| 121 | − { 0x3041, 0x3a03 }, | |
| 122 | − { 0x3042, 0x0226 }, | |
| 123 | − { 0x3043, 0x0801 }, | |
| 124 | − { 0x3044, 0x6249 }, | |
| 125 | − { 0x3045, 0x0c06 }, | |
| 126 | − { 0x3046, 0x0226 }, | |
| 127 | − { 0x3047, 0x5901 }, | |
| 128 | − { 0x3048, 0xe249 }, | |
| 129 | − { 0x3049, 0x030d }, | |
| 130 | − { 0x304a, 0x0249 }, | |
| 131 | − { 0x304b, 0x2c01 }, | |
| 132 | − { 0x304c, 0xe249 }, | |
| 133 | − { 0x304d, 0x4342 }, | |
| 134 | − { 0x304e, 0xe249 }, | |
| 135 | − { 0x304f, 0x73c0 }, | |
| 136 | − { 0x3050, 0x4249 }, | |
| 137 | − { 0x3051, 0x0c00 }, | |
| 138 | − { 0x3052, 0x0226 }, | |
| 139 | − { 0x3053, 0x1f01 }, | |
| 140 | − { 0x3054, 0x0226 }, | |
| 141 | − { 0x3055, 0x1e01 }, | |
| 142 | − { 0x3056, 0x0226 }, | |
| 143 | − { 0x3057, 0xfa00 }, | |
| 144 | − { 0x3058, 0x0000 }, | |
| 145 | − { 0x3059, 0xf000 }, | |
| 146 | − { 0x305a, 0x0000 }, | |
| 147 | − { 0x305b, 0xf000 }, | |
| 148 | − { 0x305c, 0x0000 }, | |
| 149 | − { 0x305d, 0xf000 }, | |
| 150 | − { 0x305e, 0x0000 }, | |
| 151 | − { 0x305f, 0xf000 }, | |
| 152 | − { 0x3060, 0x0000 }, | |
| 153 | − { 0x3061, 0xf000 }, | |
| 154 | − { 0x3062, 0x0000 }, | |
| 155 | − { 0x3063, 0xf000 }, | |
| 156 | − { 0x3064, 0x0000 }, | |
| 157 | − { 0x3065, 0xf000 }, | |
| 158 | − { 0x3066, 0x0000 }, | |
| 159 | − { 0x3067, 0xf000 }, | |
| 160 | − { 0x3068, 0x0000 }, | |
| 161 | − { 0x3069, 0xf000 }, | |
| 162 | − { 0x306a, 0x0000 }, | |
| 163 | − { 0x306b, 0xf000 }, | |
| 164 | − { 0x306c, 0x0000 }, | |
| 165 | − { 0x306d, 0xf000 }, | |
| 166 | − { 0x306e, 0x0000 }, | |
| 167 | − { 0x306f, 0xf000 }, | |
| 168 | − { 0x3070, 0x0226 }, | |
| 169 | − { 0x3071, 0x1a01 }, | |
| 170 | − { 0x3072, 0x0226 }, | |
| 171 | − { 0x3073, 0x1e00 }, | |
| 172 | − { 0x3074, 0x0226 }, | |
| 173 | − { 0x3075, 0x1f00 }, | |
| 174 | − { 0x3076, 0x6226 }, | |
| 175 | − { 0x3077, 0xf800 }, | |
| 176 | − { 0x3078, 0x0000 }, | |
| 177 | − { 0x3079, 0xf000 }, | |
| 178 | − { 0x307a, 0x0000 }, | |
| 179 | − { 0x307b, 0xf000 }, | |
| 180 | − { 0x307c, 0x0000 }, | |
| 181 | − { 0x307d, 0xf000 }, | |
| 182 | − { 0x307e, 0x0000 }, | |
| 183 | − { 0x307f, 0xf000 }, | |
| 184 | − { 0x3080, 0x2227 }, | |
| 185 | − { 0x3081, 0x3a03 }, | |
| 186 | − { 0x3082, 0x0227 }, | |
| 187 | − { 0x3083, 0x0801 }, | |
| 188 | − { 0x3084, 0x6255 }, | |
| 189 | − { 0x3085, 0x0c04 }, | |
| 190 | − { 0x3086, 0x0227 }, | |
| 191 | − { 0x3087, 0x5901 }, | |
| 192 | − { 0x3088, 0xe255 }, | |
| 193 | − { 0x3089, 0x030d }, | |
| 194 | − { 0x308a, 0x0255 }, | |
| 195 | − { 0x308b, 0x2c01 }, | |
| 196 | − { 0x308c, 0xe255 }, | |
| 197 | − { 0x308d, 0x4342 }, | |
| 198 | − { 0x308e, 0xe255 }, | |
| 199 | − { 0x308f, 0x73c0 }, | |
| 200 | − { 0x3090, 0x4255 }, | |
| 201 | − { 0x3091, 0x0c00 }, | |
| 202 | − { 0x3092, 0x0227 }, | |
| 203 | − { 0x3093, 0x1f01 }, | |
| 204 | − { 0x3094, 0x0227 }, | |
| 205 | − { 0x3095, 0x1e01 }, | |
| 206 | − { 0x3096, 0x0227 }, | |
| 207 | − { 0x3097, 0xfa00 }, | |
| 208 | − { 0x3098, 0x0000 }, | |
| 209 | − { 0x3099, 0xf000 }, | |
| 210 | − { 0x309a, 0x0000 }, | |
| 211 | − { 0x309b, 0xf000 }, | |
| 212 | − { 0x309c, 0x0000 }, | |
| 213 | − { 0x309d, 0xf000 }, | |
| 214 | − { 0x309e, 0x0000 }, | |
| 215 | − { 0x309f, 0xf000 }, | |
| 216 | − { 0x30a0, 0x0000 }, | |
| 217 | − { 0x30a1, 0xf000 }, | |
| 218 | − { 0x30a2, 0x0000 }, | |
| 219 | − { 0x30a3, 0xf000 }, | |
| 220 | − { 0x30a4, 0x0000 }, | |
| 221 | − { 0x30a5, 0xf000 }, | |
| 222 | − { 0x30a6, 0x0000 }, | |
| 223 | − { 0x30a7, 0xf000 }, | |
| 224 | − { 0x30a8, 0x0000 }, | |
| 225 | − { 0x30a9, 0xf000 }, | |
| 226 | − { 0x30aa, 0x0000 }, | |
| 227 | − { 0x30ab, 0xf000 }, | |
| 228 | − { 0x30ac, 0x0000 }, | |
| 229 | − { 0x30ad, 0xf000 }, | |
| 230 | − { 0x30ae, 0x0000 }, | |
| 231 | − { 0x30af, 0xf000 }, | |
| 232 | − { 0x30b0, 0x0227 }, | |
| 233 | − { 0x30b1, 0x1a01 }, | |
| 234 | − { 0x30b2, 0x0227 }, | |
| 235 | − { 0x30b3, 0x1e00 }, | |
| 236 | − { 0x30b4, 0x0227 }, | |
| 237 | − { 0x30b5, 0x1f00 }, | |
| 238 | − { 0x30b6, 0x6227 }, | |
| 239 | − { 0x30b7, 0xf800 }, | |
| 240 | − { 0x30b8, 0x0000 }, | |
| 241 | − { 0x30b9, 0xf000 }, | |
| 242 | − { 0x30ba, 0x0000 }, | |
| 243 | − { 0x30bb, 0xf000 }, | |
| 244 | − { 0x30bc, 0x0000 }, | |
| 245 | − { 0x30bd, 0xf000 }, | |
| 246 | − { 0x30be, 0x0000 }, | |
| 247 | − { 0x30bf, 0xf000 }, | |
| 248 | − { 0x30c0, 0x2228 }, | |
| 249 | − { 0x30c1, 0x3a03 }, | |
| 250 | − { 0x30c2, 0x0228 }, | |
| 251 | − { 0x30c3, 0x0801 }, | |
| 252 | − { 0x30c4, 0x6255 }, | |
| 253 | − { 0x30c5, 0x0c06 }, | |
| 254 | − { 0x30c6, 0x0228 }, | |
| 255 | − { 0x30c7, 0x5901 }, | |
| 256 | − { 0x30c8, 0xe255 }, | |
| 257 | − { 0x30c9, 0x030d }, | |
| 258 | − { 0x30ca, 0x0255 }, | |
| 259 | − { 0x30cb, 0x2c01 }, | |
| 260 | − { 0x30cc, 0xe255 }, | |
| 261 | − { 0x30cd, 0x4342 }, | |
| 262 | − { 0x30ce, 0xe255 }, | |
| 263 | − { 0x30cf, 0x73c0 }, | |
| 264 | − { 0x30d0, 0x4255 }, | |
| 265 | − { 0x30d1, 0x0c00 }, | |
| 266 | − { 0x30d2, 0x0228 }, | |
| 267 | − { 0x30d3, 0x1f01 }, | |
| 268 | − { 0x30d4, 0x0228 }, | |
| 269 | − { 0x30d5, 0x1e01 }, | |
| 270 | − { 0x30d6, 0x0228 }, | |
| 271 | − { 0x30d7, 0xfa00 }, | |
| 272 | − { 0x30d8, 0x0000 }, | |
| 273 | − { 0x30d9, 0xf000 }, | |
| 274 | − { 0x30da, 0x0000 }, | |
| 275 | − { 0x30db, 0xf000 }, | |
| 276 | − { 0x30dc, 0x0000 }, | |
| 277 | − { 0x30dd, 0xf000 }, | |
| 278 | − { 0x30de, 0x0000 }, | |
| 279 | − { 0x30df, 0xf000 }, | |
| 280 | − { 0x30e0, 0x0000 }, | |
| 281 | − { 0x30e1, 0xf000 }, | |
| 282 | − { 0x30e2, 0x0000 }, | |
| 283 | − { 0x30e3, 0xf000 }, | |
| 284 | − { 0x30e4, 0x0000 }, | |
| 285 | − { 0x30e5, 0xf000 }, | |
| 286 | − { 0x30e6, 0x0000 }, | |
| 287 | − { 0x30e7, 0xf000 }, | |
| 288 | − { 0x30e8, 0x0000 }, | |
| 289 | − { 0x30e9, 0xf000 }, | |
| 290 | − { 0x30ea, 0x0000 }, | |
| 291 | − { 0x30eb, 0xf000 }, | |
| 292 | − { 0x30ec, 0x0000 }, | |
| 293 | − { 0x30ed, 0xf000 }, | |
| 294 | − { 0x30ee, 0x0000 }, | |
| 295 | − { 0x30ef, 0xf000 }, | |
| 296 | − { 0x30f0, 0x0228 }, | |
| 297 | − { 0x30f1, 0x1a01 }, | |
| 298 | − { 0x30f2, 0x0228 }, | |
| 299 | − { 0x30f3, 0x1e00 }, | |
| 300 | − { 0x30f4, 0x0228 }, | |
| 301 | − { 0x30f5, 0x1f00 }, | |
| 302 | − { 0x30f6, 0x6228 }, | |
| 303 | − { 0x30f7, 0xf800 }, | |
| 304 | − { 0x30f8, 0x0000 }, | |
| 305 | − { 0x30f9, 0xf000 }, | |
| 306 | − { 0x30fa, 0x0000 }, | |
| 307 | − { 0x30fb, 0xf000 }, | |
| 308 | − { 0x30fc, 0x0000 }, | |
| 309 | − { 0x30fd, 0xf000 }, | |
| 310 | − { 0x30fe, 0x0000 }, | |
| 311 | − { 0x30ff, 0xf000 }, | |
| 312 | − { 0x3100, 0x222b }, | |
| 313 | − { 0x3101, 0x3a03 }, | |
| 314 | − { 0x3102, 0x222b }, | |
| 315 | − { 0x3103, 0x5803 }, | |
| 316 | − { 0x3104, 0xe26f }, | |
| 317 | − { 0x3105, 0x030d }, | |
| 318 | − { 0x3106, 0x626f }, | |
| 319 | − { 0x3107, 0x2c01 }, | |
| 320 | − { 0x3108, 0xe26f }, | |
| 321 | − { 0x3109, 0x4342 }, | |
| 322 | − { 0x310a, 0xe26f }, | |
| 323 | − { 0x310b, 0x73c0 }, | |
| 324 | − { 0x310c, 0x026f }, | |
| 325 | − { 0x310d, 0x0c00 }, | |
| 326 | − { 0x310e, 0x022b }, | |
| 327 | − { 0x310f, 0x1f01 }, | |
| 328 | − { 0x3110, 0x022b }, | |
| 329 | − { 0x3111, 0x1e01 }, | |
| 330 | − { 0x3112, 0x022b }, | |
| 331 | − { 0x3113, 0xfa00 }, | |
| 332 | − { 0x3114, 0x0000 }, | |
| 333 | − { 0x3115, 0xf000 }, | |
| 334 | − { 0x3116, 0x0000 }, | |
| 335 | − { 0x3117, 0xf000 }, | |
| 336 | − { 0x3118, 0x0000 }, | |
| 337 | − { 0x3119, 0xf000 }, | |
| 338 | − { 0x311a, 0x0000 }, | |
| 339 | − { 0x311b, 0xf000 }, | |
| 340 | − { 0x311c, 0x0000 }, | |
| 341 | − { 0x311d, 0xf000 }, | |
| 342 | − { 0x311e, 0x0000 }, | |
| 343 | − { 0x311f, 0xf000 }, | |
| 344 | − { 0x3120, 0x022b }, | |
| 345 | − { 0x3121, 0x0a01 }, | |
| 346 | − { 0x3122, 0x022b }, | |
| 347 | − { 0x3123, 0x1e00 }, | |
| 348 | − { 0x3124, 0x022b }, | |
| 349 | − { 0x3125, 0x1f00 }, | |
| 350 | − { 0x3126, 0x622b }, | |
| 351 | − { 0x3127, 0xf800 }, | |
| 352 | − { 0x3128, 0x0000 }, | |
| 353 | − { 0x3129, 0xf000 }, | |
| 354 | − { 0x312a, 0x0000 }, | |
| 355 | − { 0x312b, 0xf000 }, | |
| 356 | − { 0x312c, 0x0000 }, | |
| 357 | − { 0x312d, 0xf000 }, | |
| 358 | − { 0x312e, 0x0000 }, | |
| 359 | − { 0x312f, 0xf000 }, | |
| 360 | − { 0x3130, 0x0000 }, | |
| 361 | − { 0x3131, 0xf000 }, | |
| 362 | − { 0x3132, 0x0000 }, | |
| 363 | − { 0x3133, 0xf000 }, | |
| 364 | − { 0x3134, 0x0000 }, | |
| 365 | − { 0x3135, 0xf000 }, | |
| 366 | − { 0x3136, 0x0000 }, | |
| 367 | − { 0x3137, 0xf000 }, | |
| 368 | − { 0x3138, 0x0000 }, | |
| 369 | − { 0x3139, 0xf000 }, | |
| 370 | − { 0x313a, 0x0000 }, | |
| 371 | − { 0x313b, 0xf000 }, | |
| 372 | − { 0x313c, 0x0000 }, | |
| 373 | − { 0x313d, 0xf000 }, | |
| 374 | − { 0x313e, 0x0000 }, | |
| 375 | − { 0x313f, 0xf000 }, | |
| 376 | − { 0x3140, 0x0000 }, | |
| 377 | − { 0x3141, 0xf000 }, | |
| 378 | − { 0x3142, 0x0000 }, | |
| 379 | − { 0x3143, 0xf000 }, | |
| 380 | − { 0x3144, 0x0000 }, | |
| 381 | − { 0x3145, 0xf000 }, | |
| 382 | − { 0x3146, 0x0000 }, | |
| 383 | − { 0x3147, 0xf000 }, | |
| 384 | − { 0x3148, 0x0000 }, | |
| 385 | − { 0x3149, 0xf000 }, | |
| 386 | − { 0x314a, 0x0000 }, | |
| 387 | − { 0x314b, 0xf000 }, | |
| 388 | − { 0x314c, 0x0000 }, | |
| 389 | − { 0x314d, 0xf000 }, | |
| 390 | − { 0x314e, 0x0000 }, | |
| 391 | − { 0x314f, 0xf000 }, | |
| 392 | − { 0x3150, 0x0000 }, | |
| 393 | − { 0x3151, 0xf000 }, | |
| 394 | − { 0x3152, 0x0000 }, | |
| 395 | − { 0x3153, 0xf000 }, | |
| 396 | − { 0x3154, 0x0000 }, | |
| 397 | − { 0x3155, 0xf000 }, | |
| 398 | − { 0x3156, 0x0000 }, | |
| 399 | − { 0x3157, 0xf000 }, | |
| 400 | − { 0x3158, 0x0000 }, | |
| 401 | − { 0x3159, 0xf000 }, | |
| 402 | − { 0x315a, 0x0000 }, | |
| 403 | − { 0x315b, 0xf000 }, | |
| 404 | − { 0x315c, 0x0000 }, | |
| 405 | − { 0x315d, 0xf000 }, | |
| 406 | − { 0x315e, 0x0000 }, | |
| 407 | − { 0x315f, 0xf000 }, | |
| 408 | − { 0x3160, 0x0000 }, | |
| 409 | − { 0x3161, 0xf000 }, | |
| 410 | − { 0x3162, 0x0000 }, | |
| 411 | − { 0x3163, 0xf000 }, | |
| 412 | − { 0x3164, 0x0000 }, | |
| 413 | − { 0x3165, 0xf000 }, | |
| 414 | − { 0x3166, 0x0000 }, | |
| 415 | − { 0x3167, 0xf000 }, | |
| 416 | − { 0x3168, 0x0000 }, | |
| 417 | − { 0x3169, 0xf000 }, | |
| 418 | − { 0x316a, 0x0000 }, | |
| 419 | − { 0x316b, 0xf000 }, | |
| 420 | − { 0x316c, 0x0000 }, | |
| 421 | − { 0x316d, 0xf000 }, | |
| 422 | − { 0x316e, 0x0000 }, | |
| 423 | − { 0x316f, 0xf000 }, | |
| 424 | − { 0x3170, 0x0000 }, | |
| 425 | − { 0x3171, 0xf000 }, | |
| 426 | − { 0x3172, 0x0000 }, | |
| 427 | − { 0x3173, 0xf000 }, | |
| 428 | − { 0x3174, 0x0000 }, | |
| 429 | − { 0x3175, 0xf000 }, | |
| 430 | − { 0x3176, 0x0000 }, | |
| 431 | − { 0x3177, 0xf000 }, | |
| 432 | − { 0x3178, 0x0000 }, | |
| 433 | − { 0x3179, 0xf000 }, | |
| 434 | − { 0x317a, 0x0000 }, | |
| 435 | − { 0x317b, 0xf000 }, | |
| 436 | − { 0x317c, 0x0000 }, | |
| 437 | − { 0x317d, 0xf000 }, | |
| 438 | − { 0x317e, 0x0000 }, | |
| 439 | − { 0x317f, 0xf000 }, | |
| 440 | − { 0x3180, 0x2001 }, | |
| 441 | − { 0x3181, 0xf101 }, | |
| 442 | − { 0x3182, 0x0000 }, | |
| 443 | − { 0x3183, 0xf000 }, | |
| 444 | − { 0x3184, 0x0000 }, | |
| 445 | − { 0x3185, 0xf000 }, | |
| 446 | − { 0x3186, 0x0000 }, | |
| 447 | − { 0x3187, 0xf000 }, | |
| 448 | − { 0x3188, 0x0000 }, | |
| 449 | − { 0x3189, 0xf000 }, | |
| 450 | − { 0x318a, 0x0000 }, | |
| 451 | − { 0x318b, 0xf000 }, | |
| 452 | − { 0x318c, 0x0000 }, | |
| 453 | − { 0x318d, 0xf000 }, | |
| 454 | − { 0x318e, 0x0000 }, | |
| 455 | − { 0x318f, 0xf000 }, | |
| 456 | − { 0x3190, 0x0000 }, | |
| 457 | − { 0x3191, 0xf000 }, | |
| 458 | − { 0x3192, 0x0000 }, | |
| 459 | − { 0x3193, 0xf000 }, | |
| 460 | − { 0x3194, 0x0000 }, | |
| 461 | − { 0x3195, 0xf000 }, | |
| 462 | − { 0x3196, 0x0000 }, | |
| 463 | − { 0x3197, 0xf000 }, | |
| 464 | − { 0x3198, 0x0000 }, | |
| 465 | − { 0x3199, 0xf000 }, | |
| 466 | − { 0x319a, 0x0000 }, | |
| 467 | − { 0x319b, 0xf000 }, | |
| 468 | − { 0x319c, 0x0000 }, | |
| 469 | − { 0x319d, 0xf000 }, | |
| 470 | − { 0x319e, 0x0000 }, | |
| 471 | − { 0x319f, 0xf000 }, | |
| 472 | − { 0x31a0, 0x0000 }, | |
| 473 | − { 0x31a1, 0xf000 }, | |
| 474 | − { 0x31a2, 0x0000 }, | |
| 475 | − { 0x31a3, 0xf000 }, | |
| 476 | − { 0x31a4, 0x0000 }, | |
| 477 | − { 0x31a5, 0xf000 }, | |
| 478 | − { 0x31a6, 0x0000 }, | |
| 479 | − { 0x31a7, 0xf000 }, | |
| 480 | − { 0x31a8, 0x0000 }, | |
| 481 | − { 0x31a9, 0xf000 }, | |
| 482 | − { 0x31aa, 0x0000 }, | |
| 483 | − { 0x31ab, 0xf000 }, | |
| 484 | − { 0x31ac, 0x0000 }, | |
| 485 | − { 0x31ad, 0xf000 }, | |
| 486 | − { 0x31ae, 0x0000 }, | |
| 487 | − { 0x31af, 0xf000 }, | |
| 488 | − { 0x31b0, 0x0000 }, | |
| 489 | − { 0x31b1, 0xf000 }, | |
| 490 | − { 0x31b2, 0x0000 }, | |
| 491 | − { 0x31b3, 0xf000 }, | |
| 492 | − { 0x31b4, 0x0000 }, | |
| 493 | − { 0x31b5, 0xf000 }, | |
| 494 | − { 0x31b6, 0x0000 }, | |
| 495 | − { 0x31b7, 0xf000 }, | |
| 496 | − { 0x31b8, 0x0000 }, | |
| 497 | − { 0x31b9, 0xf000 }, | |
| 498 | − { 0x31ba, 0x0000 }, | |
| 499 | − { 0x31bb, 0xf000 }, | |
| 500 | − { 0x31bc, 0x0000 }, | |
| 501 | − { 0x31bd, 0xf000 }, | |
| 502 | − { 0x31be, 0x0000 }, | |
| 503 | − { 0x31bf, 0xf000 }, | |
| 504 | − { 0x31c0, 0x0000 }, | |
| 505 | − { 0x31c1, 0xf000 }, | |
| 506 | − { 0x31c2, 0x0000 }, | |
| 507 | − { 0x31c3, 0xf000 }, | |
| 508 | − { 0x31c4, 0x0000 }, | |
| 509 | − { 0x31c5, 0xf000 }, | |
| 510 | − { 0x31c6, 0x0000 }, | |
| 511 | − { 0x31c7, 0xf000 }, | |
| 512 | − { 0x31c8, 0x0000 }, | |
| 513 | − { 0x31c9, 0xf000 }, | |
| 514 | − { 0x31ca, 0x0000 }, | |
| 515 | − { 0x31cb, 0xf000 }, | |
| 516 | − { 0x31cc, 0x0000 }, | |
| 517 | − { 0x31cd, 0xf000 }, | |
| 518 | − { 0x31ce, 0x0000 }, | |
| 519 | − { 0x31cf, 0xf000 }, | |
| 520 | − { 0x31d0, 0x0000 }, | |
| 521 | − { 0x31d1, 0xf000 }, | |
| 522 | − { 0x31d2, 0x0000 }, | |
| 523 | − { 0x31d3, 0xf000 }, | |
| 524 | − { 0x31d4, 0x0000 }, | |
| 525 | − { 0x31d5, 0xf000 }, | |
| 526 | − { 0x31d6, 0x0000 }, | |
| 527 | − { 0x31d7, 0xf000 }, | |
| 528 | − { 0x31d8, 0x0000 }, | |
| 529 | − { 0x31d9, 0xf000 }, | |
| 530 | − { 0x31da, 0x0000 }, | |
| 531 | − { 0x31db, 0xf000 }, | |
| 532 | − { 0x31dc, 0x0000 }, | |
| 533 | − { 0x31dd, 0xf000 }, | |
| 534 | − { 0x31de, 0x0000 }, | |
| 535 | − { 0x31df, 0xf000 }, | |
| 536 | − { 0x31e0, 0x0000 }, | |
| 537 | − { 0x31e1, 0xf000 }, | |
| 538 | − { 0x31e2, 0x0000 }, | |
| 539 | − { 0x31e3, 0xf000 }, | |
| 540 | − { 0x31e4, 0x0000 }, | |
| 541 | − { 0x31e5, 0xf000 }, | |
| 542 | − { 0x31e6, 0x0000 }, | |
| 543 | − { 0x31e7, 0xf000 }, | |
| 544 | − { 0x31e8, 0x0000 }, | |
| 545 | − { 0x31e9, 0xf000 }, | |
| 546 | − { 0x31ea, 0x0000 }, | |
| 547 | − { 0x31eb, 0xf000 }, | |
| 548 | − { 0x31ec, 0x0000 }, | |
| 549 | − { 0x31ed, 0xf000 }, | |
| 550 | − { 0x31ee, 0x0000 }, | |
| 551 | − { 0x31ef, 0xf000 }, | |
| 552 | − { 0x31f0, 0x0000 }, | |
| 553 | − { 0x31f1, 0xf000 }, | |
| 554 | − { 0x31f2, 0x0000 }, | |
| 555 | − { 0x31f3, 0xf000 }, | |
| 556 | − { 0x31f4, 0x0000 }, | |
| 557 | − { 0x31f5, 0xf000 }, | |
| 558 | − { 0x31f6, 0x0000 }, | |
| 559 | − { 0x31f7, 0xf000 }, | |
| 560 | − { 0x31f8, 0x0000 }, | |
| 561 | − { 0x31f9, 0xf000 }, | |
| 562 | − { 0x31fa, 0x0000 }, | |
| 563 | − { 0x31fb, 0xf000 }, | |
| 564 | − { 0x31fc, 0x0000 }, | |
| 565 | − { 0x31fd, 0xf000 }, | |
| 566 | − { 0x31fe, 0x0000 }, | |
| 567 | − { 0x31ff, 0xf000 }, | |
| 568 | − { 0x024d, 0xff50 }, | |
| 569 | − { 0x0252, 0xff50 }, | |
| 570 | − { 0x0259, 0x0112 }, | |
| 571 | − { 0x025e, 0x0112 }, | |
| 572 | − { 0x101, 0x0304 }, | |
| 573 | 56 | { 0x80, 0x0000 }, |
| 574 | 57 | }; |
| 575 | 58 | |
| @@ -208,7 +208,7 @@ static unsigned long exynos5250_dwmmc_caps[4] = { · 207 unmodified lines | ||
| 208 | 208 | MMC_CAP_CMD23, |
| 209 | 209 | }; |
| 210 | 210 | |
| 211 | −static struct dw_mci_drv_data exynos5250_drv_data = { | |
| 211 | +static const struct dw_mci_drv_data exynos5250_drv_data = { | |
| 212 | 212 | .caps = exynos5250_dwmmc_caps, |
| 213 | 213 | .init = dw_mci_exynos_priv_init, |
| 214 | 214 | .setup_clock = dw_mci_exynos_setup_clock, |
| @@ -220,14 +220,14 @@ static struct dw_mci_drv_data exynos5250_drv_data = { · 5 unmodified lines | ||
| 220 | 220 | |
| 221 | 221 | static const struct of_device_id dw_mci_exynos_match[] = { |
| 222 | 222 | { .compatible = "samsung,exynos5250-dw-mshc", |
| 223 | − .data = (void *)&exynos5250_drv_data, }, | |
| 223 | + .data = &exynos5250_drv_data, }, | |
| 224 | 224 | {}, |
| 225 | 225 | }; |
| 226 | −MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match); | |
| 226 | +MODULE_DEVICE_TABLE(of, dw_mci_exynos_match); | |
| 227 | 227 | |
| 228 | 228 | int dw_mci_exynos_probe(struct platform_device *pdev) |
| 229 | 229 | { |
| 230 | − struct dw_mci_drv_data *drv_data; | |
| 230 | + const struct dw_mci_drv_data *drv_data; | |
| 231 | 231 | const struct of_device_id *match; |
| 232 | 232 | |
| 233 | 233 | match = of_match_node(dw_mci_exynos_match, pdev->dev.of_node); |
| @@ -24,7 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | #include "dw_mmc.h" |
| 25 | 25 | |
| 26 | 26 | int dw_mci_pltfm_register(struct platform_device *pdev, |
| 27 | − struct dw_mci_drv_data *drv_data) | |
| 27 | + const struct dw_mci_drv_data *drv_data) | |
| 28 | 28 | { |
| 29 | 29 | struct dw_mci *host; |
| 30 | 30 | struct resource *regs; |
| @@ -50,8 +50,8 @@ int dw_mci_pltfm_register(struct platform_device *pdev, · 19 unmodified lines | ||
| 50 | 50 | if (!host->regs) |
| 51 | 51 | return -ENOMEM; |
| 52 | 52 | |
| 53 | − if (host->drv_data->init) { | |
| 54 | − ret = host->drv_data->init(host); | |
| 53 | + if (drv_data && drv_data->init) { | |
| 54 | + ret = drv_data->init(host); | |
| 55 | 55 | if (ret) |
| 56 | 56 | return ret; |
| 57 | 57 | } |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #define _DW_MMC_PLTFM_H_ |
| 14 | 14 | |
| 15 | 15 | extern int dw_mci_pltfm_register(struct platform_device *pdev, |
| 16 | − struct dw_mci_drv_data *drv_data); | |
| 16 | + const struct dw_mci_drv_data *drv_data); | |
| 17 | 17 | extern int __devexit dw_mci_pltfm_remove(struct platform_device *pdev); |
| 18 | 18 | extern const struct dev_pm_ops dw_mci_pltfm_pmops; |
| 19 | 19 | |
| @@ -232,6 +232,7 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) · 231 unmodified lines | ||
| 232 | 232 | { |
| 233 | 233 | struct mmc_data *data; |
| 234 | 234 | struct dw_mci_slot *slot = mmc_priv(mmc); |
| 235 | + struct dw_mci_drv_data *drv_data = slot->host->drv_data; | |
| 235 | 236 | u32 cmdr; |
| 236 | 237 | cmd->error = -EINPROGRESS; |
| 237 | 238 | |
| @@ -261,8 +262,8 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) · 23 unmodified lines | ||
| 261 | 262 | cmdr |= SDMMC_CMD_DAT_WR; |
| 262 | 263 | } |
| 263 | 264 | |
| 264 | − if (slot->host->drv_data->prepare_command) | |
| 265 | − slot->host->drv_data->prepare_command(slot->host, &cmdr); | |
| 265 | + if (drv_data && drv_data->prepare_command) | |
| 266 | + drv_data->prepare_command(slot->host, &cmdr); | |
| 266 | 267 | |
| 267 | 268 | return cmdr; |
| 268 | 269 | } |
| @@ -434,7 +435,7 @@ static int dw_mci_idmac_init(struct dw_mci *host) · 165 unmodified lines | ||
| 434 | 435 | return 0; |
| 435 | 436 | } |
| 436 | 437 | |
| 437 | −static struct dw_mci_dma_ops dw_mci_idmac_ops = { | |
| 438 | +static const struct dw_mci_dma_ops dw_mci_idmac_ops = { | |
| 438 | 439 | .init = dw_mci_idmac_init, |
| 439 | 440 | .start = dw_mci_idmac_start_dma, |
| 440 | 441 | .stop = dw_mci_idmac_stop_dma, |
| @@ -772,6 +773,7 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) · 331 unmodified lines | ||
| 772 | 773 | static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
| 773 | 774 | { |
| 774 | 775 | struct dw_mci_slot *slot = mmc_priv(mmc); |
| 776 | + struct dw_mci_drv_data *drv_data = slot->host->drv_data; | |
| 775 | 777 | u32 regs; |
| 776 | 778 | |
| 777 | 779 | /* set default 1 bit mode */ |
| @@ -807,8 +809,8 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) · 29 unmodified lines | ||
| 807 | 809 | slot->clock = ios->clock; |
| 808 | 810 | } |
| 809 | 811 | |
| 810 | − if (slot->host->drv_data->set_ios) | |
| 811 | − slot->host->drv_data->set_ios(slot->host, ios); | |
| 812 | + if (drv_data && drv_data->set_ios) | |
| 813 | + drv_data->set_ios(slot->host, ios); | |
| 812 | 814 | |
| 813 | 815 | switch (ios->power_mode) { |
| 814 | 816 | case MMC_POWER_UP: |
| @@ -1815,6 +1817,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) · 1000 unmodified lines | ||
| 1815 | 1817 | { |
| 1816 | 1818 | struct mmc_host *mmc; |
| 1817 | 1819 | struct dw_mci_slot *slot; |
| 1820 | + struct dw_mci_drv_data *drv_data = host->drv_data; | |
| 1818 | 1821 | int ctrl_id, ret; |
| 1819 | 1822 | u8 bus_width; |
| 1820 | 1823 | |
| @@ -1854,8 +1857,8 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) · 33 unmodified lines | ||
| 1854 | 1857 | } else { |
| 1855 | 1858 | ctrl_id = to_platform_device(host->dev)->id; |
| 1856 | 1859 | } |
| 1857 | − if (host->drv_data && host->drv_data->caps) | |
| 1858 | − mmc->caps |= host->drv_data->caps[ctrl_id]; | |
| 1860 | + if (drv_data && drv_data->caps) | |
| 1861 | + mmc->caps |= drv_data->caps[ctrl_id]; | |
| 1859 | 1862 | |
| 1860 | 1863 | if (host->pdata->caps2) |
| 1861 | 1864 | mmc->caps2 = host->pdata->caps2; |
| @@ -1867,10 +1870,10 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) · 5 unmodified lines | ||
| 1867 | 1870 | else |
| 1868 | 1871 | bus_width = 1; |
| 1869 | 1872 | |
| 1870 | − if (host->drv_data->setup_bus) { | |
| 1873 | + if (drv_data && drv_data->setup_bus) { | |
| 1871 | 1874 | struct device_node *slot_np; |
| 1872 | 1875 | slot_np = dw_mci_of_find_slot_node(host->dev, slot->id); |
| 1873 | − ret = host->drv_data->setup_bus(host, slot_np, bus_width); | |
| 1876 | + ret = drv_data->setup_bus(host, slot_np, bus_width); | |
| 1874 | 1877 | if (ret) |
| 1875 | 1878 | goto err_setup_bus; |
| 1876 | 1879 | } |
| @@ -1968,7 +1971,7 @@ static void dw_mci_init_dma(struct dw_mci *host) · 91 unmodified lines | ||
| 1968 | 1971 | /* Determine which DMA interface to use */ |
| 1969 | 1972 | #ifdef CONFIG_MMC_DW_IDMAC |
| 1970 | 1973 | host->dma_ops = &dw_mci_idmac_ops; |
| 1971 | − dev_info(&host->dev, "Using internal DMA controller.\n"); | |
| 1974 | + dev_info(host->dev, "Using internal DMA controller.\n"); | |
| 1972 | 1975 | #endif |
| 1973 | 1976 | |
| 1974 | 1977 | if (!host->dma_ops) |
| @@ -2035,6 +2038,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) · 60 unmodified lines | ||
| 2035 | 2038 | struct dw_mci_board *pdata; |
| 2036 | 2039 | struct device *dev = host->dev; |
| 2037 | 2040 | struct device_node *np = dev->of_node; |
| 2041 | + struct dw_mci_drv_data *drv_data = host->drv_data; | |
| 2038 | 2042 | int idx, ret; |
| 2039 | 2043 | |
| 2040 | 2044 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); |
| @@ -2062,8 +2066,8 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) · 21 unmodified lines | ||
| 2062 | 2066 | |
| 2063 | 2067 | of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms); |
| 2064 | 2068 | |
| 2065 | − if (host->drv_data->parse_dt) { | |
| 2066 | − ret = host->drv_data->parse_dt(host); | |
| 2069 | + if (drv_data && drv_data->parse_dt) { | |
| 2070 | + ret = drv_data->parse_dt(host); | |
| 2067 | 2071 | if (ret) |
| 2068 | 2072 | return ERR_PTR(ret); |
| 2069 | 2073 | } |
| @@ -2080,6 +2084,7 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host) · 10 unmodified lines | ||
| 2080 | 2084 | |
| 2081 | 2085 | int dw_mci_probe(struct dw_mci *host) |
| 2082 | 2086 | { |
| 2087 | + struct dw_mci_drv_data *drv_data = host->drv_data; | |
| 2083 | 2088 | int width, i, ret = 0; |
| 2084 | 2089 | u32 fifo_size; |
| 2085 | 2090 | int init_slots = 0; |
| @@ -2127,8 +2132,8 @@ int dw_mci_probe(struct dw_mci *host) · 41 unmodified lines | ||
| 2127 | 2132 | else |
| 2128 | 2133 | host->bus_hz = clk_get_rate(host->ciu_clk); |
| 2129 | 2134 | |
| 2130 | − if (host->drv_data->setup_clock) { | |
| 2131 | − ret = host->drv_data->setup_clock(host); | |
| 2135 | + if (drv_data && drv_data->setup_clock) { | |
| 2136 | + ret = drv_data->setup_clock(host); | |
| 2132 | 2137 | if (ret) { |
| 2133 | 2138 | dev_err(host->dev, |
| 2134 | 2139 | "implementation specific clock setup failed\n"); |
| @@ -2228,6 +2233,21 @@ int dw_mci_probe(struct dw_mci *host) · 93 unmodified lines | ||
| 2228 | 2233 | else |
| 2229 | 2234 | host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1; |
| 2230 | 2235 | |
| 2236 | + /* | |
| 2237 | + * Enable interrupts for command done, data over, data empty, card det, | |
| 2238 | + * receive ready and error such as transmit, receive timeout, crc error | |
| 2239 | + */ | |
| 2240 | + mci_writel(host, RINTSTS, 0xFFFFFFFF); | |
| 2241 | + mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | | |
| 2242 | + SDMMC_INT_TXDR | SDMMC_INT_RXDR | | |
| 2243 | + DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); | |
| 2244 | + mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */ | |
| 2245 | + | |
| 2246 | + dev_info(host->dev, "DW MMC controller at irq %d, " | |
| 2247 | + "%d bit host data width, " | |
| 2248 | + "%u deep fifo\n", | |
| 2249 | + host->irq, width, fifo_size); | |
| 2250 | + | |
| 2231 | 2251 | /* We need at least one slot to succeed */ |
| 2232 | 2252 | for (i = 0; i < host->num_slots; i++) { |
| 2233 | 2253 | ret = dw_mci_init_slot(host, i); |
| @@ -2257,20 +2277,6 @@ int dw_mci_probe(struct dw_mci *host) · 23 unmodified lines | ||
| 2257 | 2277 | else |
| 2258 | 2278 | host->data_offset = DATA_240A_OFFSET; |
| 2259 | 2279 | |
| 2260 | − /* | |
| 2261 | − * Enable interrupts for command done, data over, data empty, card det, | |
| 2262 | − * receive ready and error such as transmit, receive timeout, crc error | |
| 2263 | − */ | |
| 2264 | − mci_writel(host, RINTSTS, 0xFFFFFFFF); | |
| 2265 | − mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | | |
| 2266 | − SDMMC_INT_TXDR | SDMMC_INT_RXDR | | |
| 2267 | − DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); | |
| 2268 | − mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */ | |
| 2269 | − | |
| 2270 | − dev_info(host->dev, "DW MMC controller at irq %d, " | |
| 2271 | − "%d bit host data width, " | |
| 2272 | − "%u deep fifo\n", | |
| 2273 | − host->irq, width, fifo_size); | |
| 2274 | 2280 | if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO) |
| 2275 | 2281 | dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n"); |
| 2276 | 2282 | |
| @@ -1134,4 +1134,4 @@ module_platform_driver(mxcmci_driver); · 1133 unmodified lines | ||
| 1134 | 1134 | MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver"); |
| 1135 | 1135 | MODULE_AUTHOR("Sascha Hauer, Pengutronix"); |
| 1136 | 1136 | MODULE_LICENSE("GPL"); |
| 1137 | −MODULE_ALIAS("platform:imx-mmc"); | |
| 1137 | +MODULE_ALIAS("platform:mxc-mmc"); | |
| @@ -178,7 +178,8 @@ struct omap_hsmmc_host { · 177 unmodified lines | ||
| 178 | 178 | |
| 179 | 179 | static int omap_hsmmc_card_detect(struct device *dev, int slot) |
| 180 | 180 | { |
| 181 | − struct omap_mmc_platform_data *mmc = dev->platform_data; | |
| 181 | + struct omap_hsmmc_host *host = dev_get_drvdata(dev); | |
| 182 | + struct omap_mmc_platform_data *mmc = host->pdata; | |
| 182 | 183 | |
| 183 | 184 | /* NOTE: assumes card detect signal is active-low */ |
| 184 | 185 | return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); |
| @@ -186,7 +187,8 @@ static int omap_hsmmc_card_detect(struct device *dev, int slot) · 1 unmodified line | ||
| 186 | 187 | |
| 187 | 188 | static int omap_hsmmc_get_wp(struct device *dev, int slot) |
| 188 | 189 | { |
| 189 | − struct omap_mmc_platform_data *mmc = dev->platform_data; | |
| 190 | + struct omap_hsmmc_host *host = dev_get_drvdata(dev); | |
| 191 | + struct omap_mmc_platform_data *mmc = host->pdata; | |
| 190 | 192 | |
| 191 | 193 | /* NOTE: assumes write protect signal is active-high */ |
| 192 | 194 | return gpio_get_value_cansleep(mmc->slots[0].gpio_wp); |
| @@ -194,7 +196,8 @@ static int omap_hsmmc_get_wp(struct device *dev, int slot) · 1 unmodified line | ||
| 194 | 196 | |
| 195 | 197 | static int omap_hsmmc_get_cover_state(struct device *dev, int slot) |
| 196 | 198 | { |
| 197 | − struct omap_mmc_platform_data *mmc = dev->platform_data; | |
| 199 | + struct omap_hsmmc_host *host = dev_get_drvdata(dev); | |
| 200 | + struct omap_mmc_platform_data *mmc = host->pdata; | |
| 198 | 201 | |
| 199 | 202 | /* NOTE: assumes card detect signal is active-low */ |
| 200 | 203 | return !gpio_get_value_cansleep(mmc->slots[0].switch_pin); |
| @@ -204,7 +207,8 @@ static int omap_hsmmc_get_cover_state(struct device *dev, int slot) · 3 unmodified lines | ||
| 204 | 207 | |
| 205 | 208 | static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) |
| 206 | 209 | { |
| 207 | − struct omap_mmc_platform_data *mmc = dev->platform_data; | |
| 210 | + struct omap_hsmmc_host *host = dev_get_drvdata(dev); | |
| 211 | + struct omap_mmc_platform_data *mmc = host->pdata; | |
| 208 | 212 | |
| 209 | 213 | disable_irq(mmc->slots[0].card_detect_irq); |
| 210 | 214 | return 0; |
| @@ -212,7 +216,8 @@ static int omap_hsmmc_suspend_cdirq(struct device *dev, int slot) · 1 unmodified line | ||
| 212 | 216 | |
| 213 | 217 | static int omap_hsmmc_resume_cdirq(struct device *dev, int slot) |
| 214 | 218 | { |
| 215 | − struct omap_mmc_platform_data *mmc = dev->platform_data; | |
| 219 | + struct omap_hsmmc_host *host = dev_get_drvdata(dev); | |
| 220 | + struct omap_mmc_platform_data *mmc = host->pdata; | |
| 216 | 221 | |
| 217 | 222 | enable_irq(mmc->slots[0].card_detect_irq); |
| 218 | 223 | return 0; |
| @@ -2009,9 +2014,9 @@ static int __devexit omap_hsmmc_remove(struct platform_device *pdev) · 1790 unmodified lines | ||
| 2009 | 2014 | clk_put(host->dbclk); |
| 2010 | 2015 | } |
| 2011 | 2016 | |
| 2012 | − mmc_free_host(host->mmc); | |
| 2017 | + omap_hsmmc_gpio_free(host->pdata); | |
| 2013 | 2018 | iounmap(host->base); |
| 2014 | − omap_hsmmc_gpio_free(pdev->dev.platform_data); | |
| 2019 | + mmc_free_host(host->mmc); | |
| 2015 | 2020 | |
| 2016 | 2021 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 2017 | 2022 | if (res) |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 20 | 20 | */ |
| 21 | 21 | |
| 22 | +#include <linux/err.h> | |
| 22 | 23 | #include <linux/io.h> |
| 23 | 24 | #include <linux/clk.h> |
| 24 | 25 | #include <linux/err.h> |
| @@ -84,30 +85,32 @@ static int __devinit sdhci_dove_probe(struct platform_device *pdev) · 59 unmodified lines | ||
| 84 | 85 | struct sdhci_dove_priv *priv; |
| 85 | 86 | int ret; |
| 86 | 87 | |
| 87 | − ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata); | |
| 88 | − if (ret) | |
| 89 | − goto sdhci_dove_register_fail; | |
| 90 | − | |
| 91 | 88 | priv = devm_kzalloc(&pdev->dev, sizeof(struct sdhci_dove_priv), |
| 92 | 89 | GFP_KERNEL); |
| 93 | 90 | if (!priv) { |
| 94 | 91 | dev_err(&pdev->dev, "unable to allocate private data"); |
| 95 | − ret = -ENOMEM; | |
| 96 | − goto sdhci_dove_allocate_fail; | |
| 92 | + return -ENOMEM; | |
| 97 | 93 | } |
| 98 | 94 | |
| 95 | + priv->clk = clk_get(&pdev->dev, NULL); | |
| 96 | + if (!IS_ERR(priv->clk)) | |
| 97 | + clk_prepare_enable(priv->clk); | |
| 98 | + | |
| 99 | + ret = sdhci_pltfm_register(pdev, &sdhci_dove_pdata); | |
| 100 | + if (ret) | |
| 101 | + goto sdhci_dove_register_fail; | |
| 102 | + | |
| 99 | 103 | host = platform_get_drvdata(pdev); |
| 100 | 104 | pltfm_host = sdhci_priv(host); |
| 101 | 105 | pltfm_host->priv = priv; |
| 102 | 106 | |
| 103 | − priv->clk = clk_get(&pdev->dev, NULL); | |
| 104 | − if (!IS_ERR(priv->clk)) | |
| 105 | − clk_prepare_enable(priv->clk); | |
| 106 | 107 | return 0; |
| 107 | 108 | |
| 108 | −sdhci_dove_allocate_fail: | |
| 109 | − sdhci_pltfm_unregister(pdev); | |
| 110 | 109 | sdhci_dove_register_fail: |
| 110 | + if (!IS_ERR(priv->clk)) { | |
| 111 | + clk_disable_unprepare(priv->clk); | |
| 112 | + clk_put(priv->clk); | |
| 113 | + } | |
| 111 | 114 | return ret; |
| 112 | 115 | } |
| 113 | 116 | |
| @@ -117,14 +120,13 @@ static int __devexit sdhci_dove_remove(struct platform_device *pdev) · 3 unmodified lines | ||
| 117 | 120 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
| 118 | 121 | struct sdhci_dove_priv *priv = pltfm_host->priv; |
| 119 | 122 | |
| 120 | − if (priv->clk) { | |
| 121 | − if (!IS_ERR(priv->clk)) { | |
| 122 | − clk_disable_unprepare(priv->clk); | |
| 123 | − clk_put(priv->clk); | |
| 124 | − } | |
| 125 | − devm_kfree(&pdev->dev, priv->clk); | |
| 123 | + sdhci_pltfm_unregister(pdev); | |
| 124 | + | |
| 125 | + if (!IS_ERR(priv->clk)) { | |
| 126 | + clk_disable_unprepare(priv->clk); | |
| 127 | + clk_put(priv->clk); | |
| 126 | 128 | } |
| 127 | − return sdhci_pltfm_unregister(pdev); | |
| 129 | + return 0; | |
| 128 | 130 | } |
| 129 | 131 | |
| 130 | 132 | static const struct of_device_id sdhci_dove_of_match_table[] __devinitdata = { |
| @@ -169,6 +169,16 @@ static void esdhc_of_resume(struct sdhci_host *host) · 168 unmodified lines | ||
| 169 | 169 | } |
| 170 | 170 | #endif |
| 171 | 171 | |
| 172 | +static void esdhc_of_platform_init(struct sdhci_host *host) | |
| 173 | +{ | |
| 174 | + u32 vvn; | |
| 175 | + | |
| 176 | + vvn = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS); | |
| 177 | + vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; | |
| 178 | + if (vvn == VENDOR_V_22) | |
| 179 | + host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; | |
| 180 | +} | |
| 181 | + | |
| 172 | 182 | static struct sdhci_ops sdhci_esdhc_ops = { |
| 173 | 183 | .read_l = esdhc_readl, |
| 174 | 184 | .read_w = esdhc_readw, |
| @@ -180,6 +190,7 @@ static struct sdhci_ops sdhci_esdhc_ops = { · 5 unmodified lines | ||
| 180 | 190 | .enable_dma = esdhc_of_enable_dma, |
| 181 | 191 | .get_max_clock = esdhc_of_get_max_clock, |
| 182 | 192 | .get_min_clock = esdhc_of_get_min_clock, |
| 193 | + .platform_init = esdhc_of_platform_init, | |
| 183 | 194 | #ifdef CONFIG_PM |
| 184 | 195 | .platform_suspend = esdhc_of_suspend, |
| 185 | 196 | .platform_resume = esdhc_of_resume, |
| @@ -1196,7 +1196,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( · 1195 unmodified lines | ||
| 1196 | 1196 | return ERR_PTR(-ENODEV); |
| 1197 | 1197 | } |
| 1198 | 1198 | |
| 1199 | − if (pci_resource_len(pdev, bar) != 0x100) { | |
| 1199 | + if (pci_resource_len(pdev, bar) < 0x100) { | |
| 1200 | 1200 | dev_err(&pdev->dev, "Invalid iomem size. You may " |
| 1201 | 1201 | "experience problems.\n"); |
| 1202 | 1202 | } |
| @@ -150,6 +150,13 @@ struct sdhci_host *sdhci_pltfm_init(struct platform_device *pdev, · 149 unmodified lines | ||
| 150 | 150 | goto err_remap; |
| 151 | 151 | } |
| 152 | 152 | |
| 153 | + /* | |
| 154 | + * Some platforms need to probe the controller to be able to | |
| 155 | + * determine which caps should be used. | |
| 156 | + */ | |
| 157 | + if (host->ops && host->ops->platform_init) | |
| 158 | + host->ops->platform_init(host); | |
| 159 | + | |
| 153 | 160 | platform_set_drvdata(pdev, host); |
| 154 | 161 | |
| 155 | 162 | return host; |
| @@ -211,8 +211,8 @@ static void sdhci_s3c_set_clock(struct sdhci_host *host, unsigned int clock) · 210 unmodified lines | ||
| 211 | 211 | if (ourhost->cur_clk != best_src) { |
| 212 | 212 | struct clk *clk = ourhost->clk_bus[best_src]; |
| 213 | 213 | |
| 214 | − clk_enable(clk); | |
| 215 | − clk_disable(ourhost->clk_bus[ourhost->cur_clk]); | |
| 214 | + clk_prepare_enable(clk); | |
| 215 | + clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]); | |
| 216 | 216 | |
| 217 | 217 | /* turn clock off to card before changing clock source */ |
| 218 | 218 | writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL); |
| @@ -373,18 +373,25 @@ static struct sdhci_ops sdhci_s3c_ops = { · 154 unmodified lines | ||
| 373 | 373 | static void sdhci_s3c_notify_change(struct platform_device *dev, int state) |
| 374 | 374 | { |
| 375 | 375 | struct sdhci_host *host = platform_get_drvdata(dev); |
| 376 | + struct sdhci_s3c *sc = sdhci_priv(host); | |
| 376 | 377 | unsigned long flags; |
| 377 | 378 | |
| 378 | 379 | if (host) { |
| 379 | 380 | spin_lock_irqsave(&host->lock, flags); |
| 380 | 381 | if (state) { |
| 381 | 382 | dev_dbg(&dev->dev, "card inserted.\n"); |
| 383 | +#ifdef CONFIG_PM_RUNTIME | |
| 384 | + clk_prepare_enable(sc->clk_io); | |
| 385 | +#endif | |
| 382 | 386 | host->flags &= ~SDHCI_DEVICE_DEAD; |
| 383 | 387 | host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION; |
| 384 | 388 | } else { |
| 385 | 389 | dev_dbg(&dev->dev, "card removed.\n"); |
| 386 | 390 | host->flags |= SDHCI_DEVICE_DEAD; |
| 387 | 391 | host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; |
| 392 | +#ifdef CONFIG_PM_RUNTIME | |
| 393 | + clk_disable_unprepare(sc->clk_io); | |
| 394 | +#endif | |
| 388 | 395 | } |
| 389 | 396 | tasklet_schedule(&host->card_tasklet); |
| 390 | 397 | spin_unlock_irqrestore(&host->lock, flags); |
| @@ -607,7 +614,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) · 216 unmodified lines | ||
| 607 | 614 | } |
| 608 | 615 | |
| 609 | 616 | /* enable the local io clock and keep it running for the moment. */ |
| 610 | − clk_enable(sc->clk_io); | |
| 617 | + clk_prepare_enable(sc->clk_io); | |
| 611 | 618 | |
| 612 | 619 | for (clks = 0, ptr = 0; ptr < MAX_BUS_CLK; ptr++) { |
| 613 | 620 | struct clk *clk; |
| @@ -638,7 +645,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) · 24 unmodified lines | ||
| 638 | 645 | } |
| 639 | 646 | |
| 640 | 647 | #ifndef CONFIG_PM_RUNTIME |
| 641 | − clk_enable(sc->clk_bus[sc->cur_clk]); | |
| 648 | + clk_prepare_enable(sc->clk_bus[sc->cur_clk]); | |
| 642 | 649 | #endif |
| 643 | 650 | |
| 644 | 651 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| @@ -747,13 +754,14 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) · 102 unmodified lines | ||
| 747 | 754 | sdhci_s3c_setup_card_detect_gpio(sc); |
| 748 | 755 | |
| 749 | 756 | #ifdef CONFIG_PM_RUNTIME |
| 750 | − clk_disable(sc->clk_io); | |
| 757 | + if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL) | |
| 758 | + clk_disable_unprepare(sc->clk_io); | |
| 751 | 759 | #endif |
| 752 | 760 | return 0; |
| 753 | 761 | |
| 754 | 762 | err_req_regs: |
| 755 | 763 | #ifndef CONFIG_PM_RUNTIME |
| 756 | − clk_disable(sc->clk_bus[sc->cur_clk]); | |
| 764 | + clk_disable_unprepare(sc->clk_bus[sc->cur_clk]); | |
| 757 | 765 | #endif |
| 758 | 766 | for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { |
| 759 | 767 | if (sc->clk_bus[ptr]) { |
| @@ -762,7 +770,7 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 762 | 770 | } |
| 763 | 771 | |
| 764 | 772 | err_no_busclks: |
| 765 | − clk_disable(sc->clk_io); | |
| 773 | + clk_disable_unprepare(sc->clk_io); | |
| 766 | 774 | clk_put(sc->clk_io); |
| 767 | 775 | |
| 768 | 776 | err_io_clk: |
| @@ -794,7 +802,8 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) · 25 unmodified lines | ||
| 794 | 802 | gpio_free(sc->ext_cd_gpio); |
| 795 | 803 | |
| 796 | 804 | #ifdef CONFIG_PM_RUNTIME |
| 797 | − clk_enable(sc->clk_io); | |
| 805 | + if (pdata->cd_type != S3C_SDHCI_CD_INTERNAL) | |
| 806 | + clk_prepare_enable(sc->clk_io); | |
| 798 | 807 | #endif |
| 799 | 808 | sdhci_remove_host(host, 1); |
| 800 | 809 | |
| @@ -802,14 +811,14 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) · 1 unmodified line | ||
| 802 | 811 | pm_runtime_disable(&pdev->dev); |
| 803 | 812 | |
| 804 | 813 | #ifndef CONFIG_PM_RUNTIME |
| 805 | − clk_disable(sc->clk_bus[sc->cur_clk]); | |
| 814 | + clk_disable_unprepare(sc->clk_bus[sc->cur_clk]); | |
| 806 | 815 | #endif |
| 807 | 816 | for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) { |
| 808 | 817 | if (sc->clk_bus[ptr]) { |
| 809 | 818 | clk_put(sc->clk_bus[ptr]); |
| 810 | 819 | } |
| 811 | 820 | } |
| 812 | − clk_disable(sc->clk_io); | |
| 821 | + clk_disable_unprepare(sc->clk_io); | |
| 813 | 822 | clk_put(sc->clk_io); |
| 814 | 823 | |
| 815 | 824 | if (pdev->dev.of_node) { |
| @@ -849,8 +858,8 @@ static int sdhci_s3c_runtime_suspend(struct device *dev) · 33 unmodified lines | ||
| 849 | 858 | |
| 850 | 859 | ret = sdhci_runtime_suspend_host(host); |
| 851 | 860 | |
| 852 | − clk_disable(ourhost->clk_bus[ourhost->cur_clk]); | |
| 853 | − clk_disable(busclk); | |
| 861 | + clk_disable_unprepare(ourhost->clk_bus[ourhost->cur_clk]); | |
| 862 | + clk_disable_unprepare(busclk); | |
| 854 | 863 | return ret; |
| 855 | 864 | } |
| 856 | 865 | |
| @@ -861,8 +870,8 @@ static int sdhci_s3c_runtime_resume(struct device *dev) · 4 unmodified lines | ||
| 861 | 870 | struct clk *busclk = ourhost->clk_io; |
| 862 | 871 | int ret; |
| 863 | 872 | |
| 864 | − clk_enable(busclk); | |
| 865 | − clk_enable(ourhost->clk_bus[ourhost->cur_clk]); | |
| 873 | + clk_prepare_enable(busclk); | |
| 874 | + clk_prepare_enable(ourhost->clk_bus[ourhost->cur_clk]); | |
| 866 | 875 | ret = sdhci_runtime_resume_host(host); |
| 867 | 876 | return ret; |
| 868 | 877 | } |
| @@ -1315,16 +1315,19 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) · 1314 unmodified lines | ||
| 1315 | 1315 | */ |
| 1316 | 1316 | if ((host->flags & SDHCI_NEEDS_RETUNING) && |
| 1317 | 1317 | !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) { |
| 1318 | − /* eMMC uses cmd21 while sd and sdio use cmd19 */ | |
| 1319 | − tuning_opcode = mmc->card->type == MMC_TYPE_MMC ? | |
| 1320 | − MMC_SEND_TUNING_BLOCK_HS200 : | |
| 1321 | − MMC_SEND_TUNING_BLOCK; | |
| 1322 | − spin_unlock_irqrestore(&host->lock, flags); | |
| 1323 | − sdhci_execute_tuning(mmc, tuning_opcode); | |
| 1324 | − spin_lock_irqsave(&host->lock, flags); | |
| 1325 | − | |
| 1326 | − /* Restore original mmc_request structure */ | |
| 1327 | − host->mrq = mrq; | |
| 1318 | + if (mmc->card) { | |
| 1319 | + /* eMMC uses cmd21 but sd and sdio use cmd19 */ | |
| 1320 | + tuning_opcode = | |
| 1321 | + mmc->card->type == MMC_TYPE_MMC ? | |
| 1322 | + MMC_SEND_TUNING_BLOCK_HS200 : | |
| 1323 | + MMC_SEND_TUNING_BLOCK; | |
| 1324 | + spin_unlock_irqrestore(&host->lock, flags); | |
| 1325 | + sdhci_execute_tuning(mmc, tuning_opcode); | |
| 1326 | + spin_lock_irqsave(&host->lock, flags); | |
| 1327 | + | |
| 1328 | + /* Restore original mmc_request structure */ | |
| 1329 | + host->mrq = mrq; | |
| 1330 | + } | |
| 1328 | 1331 | } |
| 1329 | 1332 | |
| 1330 | 1333 | if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23)) |
| @@ -2837,6 +2840,9 @@ int sdhci_add_host(struct sdhci_host *host) · 1506 unmodified lines | ||
| 2837 | 2840 | if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA)) |
| 2838 | 2841 | mmc->caps |= MMC_CAP_4_BIT_DATA; |
| 2839 | 2842 | |
| 2843 | + if (host->quirks2 & SDHCI_QUIRK2_HOST_NO_CMD23) | |
| 2844 | + mmc->caps &= ~MMC_CAP_CMD23; | |
| 2845 | + | |
| 2840 | 2846 | if (caps[0] & SDHCI_CAN_DO_HISPD) |
| 2841 | 2847 | mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; |
| 2842 | 2848 | |
| @@ -2846,9 +2852,12 @@ int sdhci_add_host(struct sdhci_host *host) · 3 unmodified lines | ||
| 2846 | 2852 | |
| 2847 | 2853 | /* If vqmmc regulator and no 1.8V signalling, then there's no UHS */ |
| 2848 | 2854 | host->vqmmc = regulator_get(mmc_dev(mmc), "vqmmc"); |
| 2849 | − if (IS_ERR(host->vqmmc)) { | |
| 2850 | − pr_info("%s: no vqmmc regulator found\n", mmc_hostname(mmc)); | |
| 2851 | − host->vqmmc = NULL; | |
| 2855 | + if (IS_ERR_OR_NULL(host->vqmmc)) { | |
| 2856 | + if (PTR_ERR(host->vqmmc) < 0) { | |
| 2857 | + pr_info("%s: no vqmmc regulator found\n", | |
| 2858 | + mmc_hostname(mmc)); | |
| 2859 | + host->vqmmc = NULL; | |
| 2860 | + } | |
| 2852 | 2861 | } |
| 2853 | 2862 | else if (regulator_is_supported_voltage(host->vqmmc, 1800000, 1800000)) |
| 2854 | 2863 | regulator_enable(host->vqmmc); |
| @@ -2904,9 +2913,12 @@ int sdhci_add_host(struct sdhci_host *host) · 49 unmodified lines | ||
| 2904 | 2913 | ocr_avail = 0; |
| 2905 | 2914 | |
| 2906 | 2915 | host->vmmc = regulator_get(mmc_dev(mmc), "vmmc"); |
| 2907 | − if (IS_ERR(host->vmmc)) { | |
| 2908 | − pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc)); | |
| 2909 | − host->vmmc = NULL; | |
| 2916 | + if (IS_ERR_OR_NULL(host->vmmc)) { | |
| 2917 | + if (PTR_ERR(host->vmmc) < 0) { | |
| 2918 | + pr_info("%s: no vmmc regulator found\n", | |
| 2919 | + mmc_hostname(mmc)); | |
| 2920 | + host->vmmc = NULL; | |
| 2921 | + } | |
| 2910 | 2922 | } else |
| 2911 | 2923 | regulator_enable(host->vmmc); |
| 2912 | 2924 | |
| @@ -278,6 +278,7 @@ struct sdhci_ops { · 277 unmodified lines | ||
| 278 | 278 | void (*hw_reset)(struct sdhci_host *host); |
| 279 | 279 | void (*platform_suspend)(struct sdhci_host *host); |
| 280 | 280 | void (*platform_resume)(struct sdhci_host *host); |
| 281 | + void (*platform_init)(struct sdhci_host *host); | |
| 281 | 282 | }; |
| 282 | 283 | |
| 283 | 284 | #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS |
| @@ -1104,7 +1104,6 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id) · 1103 unmodified lines | ||
| 1104 | 1104 | { |
| 1105 | 1105 | struct sh_mmcif_host *host = dev_id; |
| 1106 | 1106 | struct mmc_request *mrq = host->mrq; |
| 1107 | − struct mmc_data *data = mrq->data; | |
| 1108 | 1107 | |
| 1109 | 1108 | cancel_delayed_work_sync(&host->timeout_work); |
| 1110 | 1109 | |
| @@ -1152,13 +1151,14 @@ static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id) · 41 unmodified lines | ||
| 1152 | 1151 | case MMCIF_WAIT_FOR_READ_END: |
| 1153 | 1152 | case MMCIF_WAIT_FOR_WRITE_END: |
| 1154 | 1153 | if (host->sd_error) |
| 1155 | − data->error = sh_mmcif_error_manage(host); | |
| 1154 | + mrq->data->error = sh_mmcif_error_manage(host); | |
| 1156 | 1155 | break; |
| 1157 | 1156 | default: |
| 1158 | 1157 | BUG(); |
| 1159 | 1158 | } |
| 1160 | 1159 | |
| 1161 | 1160 | if (host->wait_for != MMCIF_WAIT_FOR_STOP) { |
| 1161 | + struct mmc_data *data = mrq->data; | |
| 1162 | 1162 | if (!mrq->cmd->error && data && !data->error) |
| 1163 | 1163 | data->bytes_xfered = |
| 1164 | 1164 | data->blocks * data->blksz; |
| @@ -1231,10 +1231,6 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) · 66 unmodified lines | ||
| 1231 | 1231 | host->sd_error = true; |
| 1232 | 1232 | dev_dbg(&host->pd->dev, "int err state = %08x\n", state); |
| 1233 | 1233 | } |
| 1234 | − if (host->state == STATE_IDLE) { | |
| 1235 | − dev_info(&host->pd->dev, "Spurious IRQ status 0x%x", state); | |
| 1236 | − return IRQ_HANDLED; | |
| 1237 | − } | |
| 1238 | 1234 | if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) { |
| 1239 | 1235 | if (!host->dma_active) |
| 1240 | 1236 | return IRQ_WAKE_THREAD; |
| @@ -1466,9 +1462,9 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev) · 225 unmodified lines | ||
| 1466 | 1462 | |
| 1467 | 1463 | platform_set_drvdata(pdev, NULL); |
| 1468 | 1464 | |
| 1465 | + clk_disable(host->hclk); | |
| 1469 | 1466 | mmc_free_host(host->mmc); |
| 1470 | 1467 | pm_runtime_put_sync(&pdev->dev); |
| 1471 | − clk_disable(host->hclk); | |
| 1472 | 1468 | pm_runtime_disable(&pdev->dev); |
| 1473 | 1469 | |
| 1474 | 1470 | return 0; |
| @@ -240,7 +240,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength) · 239 unmodified lines | ||
| 240 | 240 | |
| 241 | 241 | if (*(szlength) != '+') { |
| 242 | 242 | devlength = simple_strtoul(szlength, &buffer, 0); |
| 243 | − devlength = handle_unit(devlength, buffer) - devstart; | |
| 243 | + devlength = handle_unit(devlength, buffer); | |
| 244 | 244 | if (devlength < devstart) |
| 245 | 245 | goto err_out; |
| 246 | 246 | |
| @@ -2983,13 +2983,15 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, · 2982 unmodified lines | ||
| 2983 | 2983 | /* |
| 2984 | 2984 | * Field definitions are in the following datasheets: |
| 2985 | 2985 | * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32) |
| 2986 | − * New style (6 byte ID): Samsung K9GAG08U0F (p.44) | |
| 2986 | + * New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44) | |
| 2987 | 2987 | * Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22) |
| 2988 | 2988 | * |
| 2989 | − * Check for ID length, cell type, and Hynix/Samsung ID to decide what | |
| 2990 | − * to do. | |
| 2989 | + * Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung | |
| 2990 | + * ID to decide what to do. | |
| 2991 | 2991 | */ |
| 2992 | − if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG) { | |
| 2992 | + if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG && | |
| 2993 | + (chip->cellinfo & NAND_CI_CELLTYPE_MSK) && | |
| 2994 | + id_data[5] != 0x00) { | |
| 2993 | 2995 | /* Calc pagesize */ |
| 2994 | 2996 | mtd->writesize = 2048 << (extid & 0x03); |
| 2995 | 2997 | extid >>= 2; |
| @@ -121,7 +121,7 @@ static int parse_ofoldpart_partitions(struct mtd_info *master, · 120 unmodified lines | ||
| 121 | 121 | nr_parts = plen / sizeof(part[0]); |
| 122 | 122 | |
| 123 | 123 | *pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL); |
| 124 | − if (!pparts) | |
| 124 | + if (!*pparts) | |
| 125 | 125 | return -ENOMEM; |
| 126 | 126 | |
| 127 | 127 | names = of_get_property(dp, "partition-names", &plen); |
| @@ -3694,7 +3694,7 @@ static int flexonenand_check_blocks_erased(struct mtd_info *mtd, int start, int · 3693 unmodified lines | ||
| 3694 | 3694 | * flexonenand_set_boundary - Writes the SLC boundary |
| 3695 | 3695 | * @param mtd - mtd info structure |
| 3696 | 3696 | */ |
| 3697 | −int flexonenand_set_boundary(struct mtd_info *mtd, int die, | |
| 3697 | +static int flexonenand_set_boundary(struct mtd_info *mtd, int die, | |
| 3698 | 3698 | int boundary, int lock) |
| 3699 | 3699 | { |
| 3700 | 3700 | struct onenand_chip *this = mtd->priv; |
| @@ -498,7 +498,7 @@ out: · 497 unmodified lines | ||
| 498 | 498 | * @ubi: UBI device description object |
| 499 | 499 | * |
| 500 | 500 | * This function returns a physical eraseblock in case of success and a |
| 501 | − * negative error code in case of failure. Might sleep. | |
| 501 | + * negative error code in case of failure. | |
| 502 | 502 | */ |
| 503 | 503 | static int __wl_get_peb(struct ubi_device *ubi) |
| 504 | 504 | { |
| @@ -540,13 +540,6 @@ retry: · 35 unmodified lines | ||
| 540 | 540 | * ubi_wl_get_peb() after removing e from the pool. */ |
| 541 | 541 | prot_queue_add(ubi, e); |
| 542 | 542 | #endif |
| 543 | − err = ubi_self_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset, | |
| 544 | − ubi->peb_size - ubi->vid_hdr_aloffset); | |
| 545 | − if (err) { | |
| 546 | − ubi_err("new PEB %d does not contain all 0xFF bytes", e->pnum); | |
| 547 | − return err; | |
| 548 | − } | |
| 549 | − | |
| 550 | 543 | return e->pnum; |
| 551 | 544 | } |
| 552 | 545 | |
| @@ -679,17 +672,30 @@ static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) · 126 unmodified lines | ||
| 679 | 672 | #else |
| 680 | 673 | static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) |
| 681 | 674 | { |
| 682 | − return find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); | |
| 675 | + struct ubi_wl_entry *e; | |
| 676 | + | |
| 677 | + e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); | |
| 678 | + self_check_in_wl_tree(ubi, e, &ubi->free); | |
| 679 | + rb_erase(&e->u.rb, &ubi->free); | |
| 680 | + | |
| 681 | + return e; | |
| 683 | 682 | } |
| 684 | 683 | |
| 685 | 684 | int ubi_wl_get_peb(struct ubi_device *ubi) |
| 686 | 685 | { |
| 687 | − int peb; | |
| 686 | + int peb, err; | |
| 688 | 687 | |
| 689 | 688 | spin_lock(&ubi->wl_lock); |
| 690 | 689 | peb = __wl_get_peb(ubi); |
| 691 | 690 | spin_unlock(&ubi->wl_lock); |
| 692 | 691 | |
| 692 | + err = ubi_self_check_all_ff(ubi, peb, ubi->vid_hdr_aloffset, | |
| 693 | + ubi->peb_size - ubi->vid_hdr_aloffset); | |
| 694 | + if (err) { | |
| 695 | + ubi_err("new PEB %d does not contain all 0xFF bytes", peb); | |
| 696 | + return err; | |
| 697 | + } | |
| 698 | + | |
| 693 | 699 | return peb; |
| 694 | 700 | } |
| 695 | 701 | #endif |
| @@ -1379,6 +1379,8 @@ static void bond_compute_features(struct bonding *bond) · 1378 unmodified lines | ||
| 1379 | 1379 | struct net_device *bond_dev = bond->dev; |
| 1380 | 1380 | netdev_features_t vlan_features = BOND_VLAN_FEATURES; |
| 1381 | 1381 | unsigned short max_hard_header_len = ETH_HLEN; |
| 1382 | + unsigned int gso_max_size = GSO_MAX_SIZE; | |
| 1383 | + u16 gso_max_segs = GSO_MAX_SEGS; | |
| 1382 | 1384 | int i; |
| 1383 | 1385 | unsigned int flags, dst_release_flag = IFF_XMIT_DST_RELEASE; |
| 1384 | 1386 | |
| @@ -1394,11 +1396,16 @@ static void bond_compute_features(struct bonding *bond) · 9 unmodified lines | ||
| 1394 | 1396 | dst_release_flag &= slave->dev->priv_flags; |
| 1395 | 1397 | if (slave->dev->hard_header_len > max_hard_header_len) |
| 1396 | 1398 | max_hard_header_len = slave->dev->hard_header_len; |
| 1399 | + | |
| 1400 | + gso_max_size = min(gso_max_size, slave->dev->gso_max_size); | |
| 1401 | + gso_max_segs = min(gso_max_segs, slave->dev->gso_max_segs); | |
| 1397 | 1402 | } |
| 1398 | 1403 | |
| 1399 | 1404 | done: |
| 1400 | 1405 | bond_dev->vlan_features = vlan_features; |
| 1401 | 1406 | bond_dev->hard_header_len = max_hard_header_len; |
| 1407 | + bond_dev->gso_max_segs = gso_max_segs; | |
| 1408 | + netif_set_gso_max_size(bond_dev, gso_max_size); | |
| 1402 | 1409 | |
| 1403 | 1410 | flags = bond_dev->priv_flags & ~IFF_XMIT_DST_RELEASE; |
| 1404 | 1411 | bond_dev->priv_flags = flags | dst_release_flag; |
| @@ -3452,6 +3459,28 @@ static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count) · 2047 unmodified lines | ||
| 3452 | 3459 | |
| 3453 | 3460 | /*-------------------------- Device entry points ----------------------------*/ |
| 3454 | 3461 | |
| 3462 | +static void bond_work_init_all(struct bonding *bond) | |
| 3463 | +{ | |
| 3464 | + INIT_DELAYED_WORK(&bond->mcast_work, | |
| 3465 | + bond_resend_igmp_join_requests_delayed); | |
| 3466 | + INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor); | |
| 3467 | + INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor); | |
| 3468 | + if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) | |
| 3469 | + INIT_DELAYED_WORK(&bond->arp_work, bond_activebackup_arp_mon); | |
| 3470 | + else | |
| 3471 | + INIT_DELAYED_WORK(&bond->arp_work, bond_loadbalance_arp_mon); | |
| 3472 | + INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler); | |
| 3473 | +} | |
| 3474 | + | |
| 3475 | +static void bond_work_cancel_all(struct bonding *bond) | |
| 3476 | +{ | |
| 3477 | + cancel_delayed_work_sync(&bond->mii_work); | |
| 3478 | + cancel_delayed_work_sync(&bond->arp_work); | |
| 3479 | + cancel_delayed_work_sync(&bond->alb_work); | |
| 3480 | + cancel_delayed_work_sync(&bond->ad_work); | |
| 3481 | + cancel_delayed_work_sync(&bond->mcast_work); | |
| 3482 | +} | |
| 3483 | + | |
| 3455 | 3484 | static int bond_open(struct net_device *bond_dev) |
| 3456 | 3485 | { |
| 3457 | 3486 | struct bonding *bond = netdev_priv(bond_dev); |
| @@ -3474,41 +3503,27 @@ static int bond_open(struct net_device *bond_dev) · 16 unmodified lines | ||
| 3474 | 3503 | } |
| 3475 | 3504 | read_unlock(&bond->lock); |
| 3476 | 3505 | |
| 3477 | − INIT_DELAYED_WORK(&bond->mcast_work, bond_resend_igmp_join_requests_delayed); | |
| 3506 | + bond_work_init_all(bond); | |
| 3478 | 3507 | |
| 3479 | 3508 | if (bond_is_lb(bond)) { |
| 3480 | 3509 | /* bond_alb_initialize must be called before the timer |
| 3481 | 3510 | * is started. |
| 3482 | 3511 | */ |
| 3483 | − if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) { | |
| 3484 | − /* something went wrong - fail the open operation */ | |
| 3512 | + if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) | |
| 3485 | 3513 | return -ENOMEM; |
| 3486 | − } | |
| 3487 | − | |
| 3488 | − INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor); | |
| 3489 | 3514 | queue_delayed_work(bond->wq, &bond->alb_work, 0); |
| 3490 | 3515 | } |
| 3491 | 3516 | |
| 3492 | − if (bond->params.miimon) { /* link check interval, in milliseconds. */ | |
| 3493 | − INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor); | |
| 3517 | + if (bond->params.miimon) /* link check interval, in milliseconds. */ | |
| 3494 | 3518 | queue_delayed_work(bond->wq, &bond->mii_work, 0); |
| 3495 | − } | |
| 3496 | 3519 | |
| 3497 | 3520 | if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ |
| 3498 | − if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) | |
| 3499 | − INIT_DELAYED_WORK(&bond->arp_work, | |
| 3500 | − bond_activebackup_arp_mon); | |
| 3501 | − else | |
| 3502 | − INIT_DELAYED_WORK(&bond->arp_work, | |
| 3503 | − bond_loadbalance_arp_mon); | |
| 3504 | − | |
| 3505 | 3521 | queue_delayed_work(bond->wq, &bond->arp_work, 0); |
| 3506 | 3522 | if (bond->params.arp_validate) |
| 3507 | 3523 | bond->recv_probe = bond_arp_rcv; |
| 3508 | 3524 | } |
| 3509 | 3525 | |
| 3510 | 3526 | if (bond->params.mode == BOND_MODE_8023AD) { |
| 3511 | − INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler); | |
| 3512 | 3527 | queue_delayed_work(bond->wq, &bond->ad_work, 0); |
| 3513 | 3528 | /* register to receive LACPDUs */ |
| 3514 | 3529 | bond->recv_probe = bond_3ad_lacpdu_recv; |
| @@ -3523,34 +3538,10 @@ static int bond_close(struct net_device *bond_dev) · 8 unmodified lines | ||
| 3523 | 3538 | struct bonding *bond = netdev_priv(bond_dev); |
| 3524 | 3539 | |
| 3525 | 3540 | write_lock_bh(&bond->lock); |
| 3526 | − | |
| 3527 | 3541 | bond->send_peer_notif = 0; |
| 3528 | − | |
| 3529 | 3542 | write_unlock_bh(&bond->lock); |
| 3530 | 3543 | |
| 3531 | − if (bond->params.miimon) { /* link check interval, in milliseconds. */ | |
| 3532 | − cancel_delayed_work_sync(&bond->mii_work); | |
| 3533 | − } | |
| 3534 | − | |
| 3535 | − if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ | |
| 3536 | − cancel_delayed_work_sync(&bond->arp_work); | |
| 3537 | − } | |
| 3538 | − | |
| 3539 | − switch (bond->params.mode) { | |
| 3540 | − case BOND_MODE_8023AD: | |
| 3541 | − cancel_delayed_work_sync(&bond->ad_work); | |
| 3542 | − break; | |
| 3543 | − case BOND_MODE_TLB: | |
| 3544 | − case BOND_MODE_ALB: | |
| 3545 | − cancel_delayed_work_sync(&bond->alb_work); | |
| 3546 | − break; | |
| 3547 | − default: | |
| 3548 | − break; | |
| 3549 | − } | |
| 3550 | − | |
| 3551 | − if (delayed_work_pending(&bond->mcast_work)) | |
| 3552 | − cancel_delayed_work_sync(&bond->mcast_work); | |
| 3553 | − | |
| 3544 | + bond_work_cancel_all(bond); | |
| 3554 | 3545 | if (bond_is_lb(bond)) { |
| 3555 | 3546 | /* Must be called only after all |
| 3556 | 3547 | * slaves have been released |
| @@ -4429,26 +4420,6 @@ static void bond_setup(struct net_device *bond_dev) · 872 unmodified lines | ||
| 4429 | 4420 | bond_dev->features |= bond_dev->hw_features; |
| 4430 | 4421 | } |
| 4431 | 4422 | |
| 4432 | −static void bond_work_cancel_all(struct bonding *bond) | |
| 4433 | −{ | |
| 4434 | − if (bond->params.miimon && delayed_work_pending(&bond->mii_work)) | |
| 4435 | − cancel_delayed_work_sync(&bond->mii_work); | |
| 4436 | − | |
| 4437 | − if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work)) | |
| 4438 | − cancel_delayed_work_sync(&bond->arp_work); | |
| 4439 | − | |
| 4440 | − if (bond->params.mode == BOND_MODE_ALB && | |
| 4441 | − delayed_work_pending(&bond->alb_work)) | |
| 4442 | − cancel_delayed_work_sync(&bond->alb_work); | |
| 4443 | − | |
| 4444 | − if (bond->params.mode == BOND_MODE_8023AD && | |
| 4445 | − delayed_work_pending(&bond->ad_work)) | |
| 4446 | − cancel_delayed_work_sync(&bond->ad_work); | |
| 4447 | − | |
| 4448 | − if (delayed_work_pending(&bond->mcast_work)) | |
| 4449 | − cancel_delayed_work_sync(&bond->mcast_work); | |
| 4450 | −} | |
| 4451 | − | |
| 4452 | 4423 | /* |
| 4453 | 4424 | * Destroy a bonding device. |
| 4454 | 4425 | * Must be under rtnl_lock when this function is called. |
| @@ -4699,12 +4670,13 @@ static int bond_check_params(struct bond_params *params) · 244 unmodified lines | ||
| 4699 | 4670 | arp_ip_count++) { |
| 4700 | 4671 | /* not complete check, but should be good enough to |
| 4701 | 4672 | catch mistakes */ |
| 4702 | − if (!isdigit(arp_ip_target[arp_ip_count][0])) { | |
| 4673 | + __be32 ip = in_aton(arp_ip_target[arp_ip_count]); | |
| 4674 | + if (!isdigit(arp_ip_target[arp_ip_count][0]) || | |
| 4675 | + ip == 0 || ip == htonl(INADDR_BROADCAST)) { | |
| 4703 | 4676 | pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n", |
| 4704 | 4677 | arp_ip_target[arp_ip_count]); |
| 4705 | 4678 | arp_interval = 0; |
| 4706 | 4679 | } else { |
| 4707 | − __be32 ip = in_aton(arp_ip_target[arp_ip_count]); | |
| 4708 | 4680 | arp_target[arp_ip_count] = ip; |
| 4709 | 4681 | } |
| 4710 | 4682 | } |
| @@ -513,6 +513,8 @@ static ssize_t bonding_store_arp_interval(struct device *d, · 512 unmodified lines | ||
| 513 | 513 | int new_value, ret = count; |
| 514 | 514 | struct bonding *bond = to_bond(d); |
| 515 | 515 | |
| 516 | + if (!rtnl_trylock()) | |
| 517 | + return restart_syscall(); | |
| 516 | 518 | if (sscanf(buf, "%d", &new_value) != 1) { |
| 517 | 519 | pr_err("%s: no arp_interval value specified.\n", |
| 518 | 520 | bond->dev->name); |
| @@ -539,10 +541,6 @@ static ssize_t bonding_store_arp_interval(struct device *d, · 20 unmodified lines | ||
| 539 | 541 | pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n", |
| 540 | 542 | bond->dev->name, bond->dev->name); |
| 541 | 543 | bond->params.miimon = 0; |
| 542 | − if (delayed_work_pending(&bond->mii_work)) { | |
| 543 | − cancel_delayed_work(&bond->mii_work); | |
| 544 | − flush_workqueue(bond->wq); | |
| 545 | − } | |
| 546 | 544 | } |
| 547 | 545 | if (!bond->params.arp_targets[0]) { |
| 548 | 546 | pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n", |
| @@ -554,19 +552,12 @@ static ssize_t bonding_store_arp_interval(struct device *d, · 5 unmodified lines | ||
| 554 | 552 | * timer will get fired off when the open function |
| 555 | 553 | * is called. |
| 556 | 554 | */ |
| 557 | − if (!delayed_work_pending(&bond->arp_work)) { | |
| 558 | − if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) | |
| 559 | − INIT_DELAYED_WORK(&bond->arp_work, | |
| 560 | − bond_activebackup_arp_mon); | |
| 561 | − else | |
| 562 | − INIT_DELAYED_WORK(&bond->arp_work, | |
| 563 | − bond_loadbalance_arp_mon); | |
| 564 | − | |
| 565 | − queue_delayed_work(bond->wq, &bond->arp_work, 0); | |
| 566 | − } | |
| 555 | + cancel_delayed_work_sync(&bond->mii_work); | |
| 556 | + queue_delayed_work(bond->wq, &bond->arp_work, 0); | |
| 567 | 557 | } |
| 568 | 558 | |
| 569 | 559 | out: |
| 560 | + rtnl_unlock(); | |
| 570 | 561 | return ret; |
| 571 | 562 | } |
| 572 | 563 | static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR, |
| @@ -962,6 +953,8 @@ static ssize_t bonding_store_miimon(struct device *d, · 389 unmodified lines | ||
| 962 | 953 | int new_value, ret = count; |
| 963 | 954 | struct bonding *bond = to_bond(d); |
| 964 | 955 | |
| 956 | + if (!rtnl_trylock()) | |
| 957 | + return restart_syscall(); | |
| 965 | 958 | if (sscanf(buf, "%d", &new_value) != 1) { |
| 966 | 959 | pr_err("%s: no miimon value specified.\n", |
| 967 | 960 | bond->dev->name); |
| @@ -993,10 +986,6 @@ static ssize_t bonding_store_miimon(struct device *d, · 25 unmodified lines | ||
| 993 | 986 | bond->params.arp_validate = |
| 994 | 987 | BOND_ARP_VALIDATE_NONE; |
| 995 | 988 | } |
| 996 | − if (delayed_work_pending(&bond->arp_work)) { | |
| 997 | − cancel_delayed_work(&bond->arp_work); | |
| 998 | − flush_workqueue(bond->wq); | |
| 999 | − } | |
| 1000 | 989 | } |
| 1001 | 990 | |
| 1002 | 991 | if (bond->dev->flags & IFF_UP) { |
| @@ -1005,15 +994,12 @@ static ssize_t bonding_store_miimon(struct device *d, · 2 unmodified lines | ||
| 1005 | 994 | * timer will get fired off when the open function |
| 1006 | 995 | * is called. |
| 1007 | 996 | */ |
| 1008 | − if (!delayed_work_pending(&bond->mii_work)) { | |
| 1009 | − INIT_DELAYED_WORK(&bond->mii_work, | |
| 1010 | − bond_mii_monitor); | |
| 1011 | − queue_delayed_work(bond->wq, | |
| 1012 | − &bond->mii_work, 0); | |
| 1013 | − } | |
| 997 | + cancel_delayed_work_sync(&bond->arp_work); | |
| 998 | + queue_delayed_work(bond->wq, &bond->mii_work, 0); | |
| 1014 | 999 | } |
| 1015 | 1000 | } |
| 1016 | 1001 | out: |
| 1002 | + rtnl_unlock(); | |
| 1017 | 1003 | return ret; |
| 1018 | 1004 | } |
| 1019 | 1005 | static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, |
| @@ -1060,7 +1046,7 @@ static ssize_t bonding_store_primary(struct device *d, · 40 unmodified lines | ||
| 1060 | 1046 | goto out; |
| 1061 | 1047 | } |
| 1062 | 1048 | |
| 1063 | − sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ | |
| 1049 | + sscanf(buf, "%15s", ifname); /* IFNAMSIZ */ | |
| 1064 | 1050 | |
| 1065 | 1051 | /* check to see if we are clearing primary */ |
| 1066 | 1052 | if (!strlen(ifname) || buf[0] == '\n') { |
| @@ -1237,7 +1223,7 @@ static ssize_t bonding_store_active_slave(struct device *d, · 170 unmodified lines | ||
| 1237 | 1223 | goto out; |
| 1238 | 1224 | } |
| 1239 | 1225 | |
| 1240 | − sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ | |
| 1226 | + sscanf(buf, "%15s", ifname); /* IFNAMSIZ */ | |
| 1241 | 1227 | |
| 1242 | 1228 | /* check to see if we are clearing active */ |
| 1243 | 1229 | if (!strlen(ifname) || buf[0] == '\n') { |
| @@ -1582,6 +1568,7 @@ static ssize_t bonding_store_slaves_active(struct device *d, · 338 unmodified lines | ||
| 1582 | 1568 | goto out; |
| 1583 | 1569 | } |
| 1584 | 1570 | |
| 1571 | + read_lock(&bond->lock); | |
| 1585 | 1572 | bond_for_each_slave(bond, slave, i) { |
| 1586 | 1573 | if (!bond_is_active_slave(slave)) { |
| 1587 | 1574 | if (new_value) |
| @@ -1590,6 +1577,7 @@ static ssize_t bonding_store_slaves_active(struct device *d, · 2 unmodified lines | ||
| 1590 | 1577 | slave->inactive = 1; |
| 1591 | 1578 | } |
| 1592 | 1579 | } |
| 1580 | + read_unlock(&bond->lock); | |
| 1593 | 1581 | out: |
| 1594 | 1582 | return ret; |
| 1595 | 1583 | } |
| @@ -144,9 +144,22 @@ · 143 unmodified lines | ||
| 144 | 144 | |
| 145 | 145 | #define FLEXCAN_MB_CODE_MASK (0xf0ffffff) |
| 146 | 146 | |
| 147 | −/* FLEXCAN hardware feature flags */ | |
| 147 | +/* | |
| 148 | + * FLEXCAN hardware feature flags | |
| 149 | + * | |
| 150 | + * Below is some version info we got: | |
| 151 | + * SOC Version IP-Version Glitch- [TR]WRN_INT | |
| 152 | + * Filter? connected? | |
| 153 | + * MX25 FlexCAN2 03.00.00.00 no no | |
| 154 | + * MX28 FlexCAN2 03.00.04.00 yes yes | |
| 155 | + * MX35 FlexCAN2 03.00.00.00 no no | |
| 156 | + * MX53 FlexCAN2 03.00.00.00 yes no | |
| 157 | + * MX6s FlexCAN3 10.00.12.00 yes yes | |
| 158 | + * | |
| 159 | + * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. | |
| 160 | + */ | |
| 148 | 161 | #define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */ |
| 149 | −#define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* Broken error state handling */ | |
| 162 | +#define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* [TR]WRN_INT not connected */ | |
| 150 | 163 | |
| 151 | 164 | /* Structure of the message buffer */ |
| 152 | 165 | struct flexcan_mb { |
| @@ -205,7 +218,7 @@ static struct flexcan_devtype_data fsl_p1010_devtype_data = { · 52 unmodified lines | ||
| 205 | 218 | }; |
| 206 | 219 | static struct flexcan_devtype_data fsl_imx28_devtype_data; |
| 207 | 220 | static struct flexcan_devtype_data fsl_imx6q_devtype_data = { |
| 208 | − .features = FLEXCAN_HAS_V10_FEATURES | FLEXCAN_HAS_BROKEN_ERR_STATE, | |
| 221 | + .features = FLEXCAN_HAS_V10_FEATURES, | |
| 209 | 222 | }; |
| 210 | 223 | |
| 211 | 224 | static const struct can_bittiming_const flexcan_bittiming_const = { |
| @@ -30,9 +30,10 @@ · 29 unmodified lines | ||
| 30 | 30 | |
| 31 | 31 | #include "sja1000.h" |
| 32 | 32 | |
| 33 | −MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>"); | |
| 33 | +MODULE_AUTHOR("Stephane Grosjean <s.grosjean@peak-system.com>"); | |
| 34 | 34 | MODULE_DESCRIPTION("Socket-CAN driver for PEAK PCAN PCI family cards"); |
| 35 | 35 | MODULE_SUPPORTED_DEVICE("PEAK PCAN PCI/PCIe/PCIeC miniPCI CAN cards"); |
| 36 | +MODULE_SUPPORTED_DEVICE("PEAK PCAN miniPCIe/cPCI PC/104+ PCI/104e CAN Cards"); | |
| 36 | 37 | MODULE_LICENSE("GPL v2"); |
| 37 | 38 | |
| 38 | 39 | #define DRV_NAME "peak_pci" |
| @@ -64,7 +65,11 @@ struct peak_pci_chan { · 25 unmodified lines | ||
| 64 | 65 | #define PEAK_PCI_DEVICE_ID 0x0001 /* for PCI/PCIe slot cards */ |
| 65 | 66 | #define PEAK_PCIEC_DEVICE_ID 0x0002 /* for ExpressCard slot cards */ |
| 66 | 67 | #define PEAK_PCIE_DEVICE_ID 0x0003 /* for nextgen PCIe slot cards */ |
| 67 | −#define PEAK_MPCI_DEVICE_ID 0x0008 /* The miniPCI slot cards */ | |
| 68 | +#define PEAK_CPCI_DEVICE_ID 0x0004 /* for nextgen cPCI slot cards */ | |
| 69 | +#define PEAK_MPCI_DEVICE_ID 0x0005 /* for nextgen miniPCI slot cards */ | |
| 70 | +#define PEAK_PC_104P_DEVICE_ID 0x0006 /* PCAN-PC/104+ cards */ | |
| 71 | +#define PEAK_PCI_104E_DEVICE_ID 0x0007 /* PCAN-PCI/104 Express cards */ | |
| 72 | +#define PEAK_MPCIE_DEVICE_ID 0x0008 /* The miniPCIe slot cards */ | |
| 68 | 73 | |
| 69 | 74 | #define PEAK_PCI_CHAN_MAX 4 |
| 70 | 75 | |
| @@ -76,6 +81,10 @@ static DEFINE_PCI_DEVICE_TABLE(peak_pci_tbl) = { · 5 unmodified lines | ||
| 76 | 81 | {PEAK_PCI_VENDOR_ID, PEAK_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, |
| 77 | 82 | {PEAK_PCI_VENDOR_ID, PEAK_PCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, |
| 78 | 83 | {PEAK_PCI_VENDOR_ID, PEAK_MPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, |
| 84 | + {PEAK_PCI_VENDOR_ID, PEAK_MPCIE_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, | |
| 85 | + {PEAK_PCI_VENDOR_ID, PEAK_PC_104P_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, | |
| 86 | + {PEAK_PCI_VENDOR_ID, PEAK_PCI_104E_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, | |
| 87 | + {PEAK_PCI_VENDOR_ID, PEAK_CPCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, | |
| 79 | 88 | #ifdef CONFIG_CAN_PEAK_PCIEC |
| 80 | 89 | {PEAK_PCI_VENDOR_ID, PEAK_PCIEC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, |
| 81 | 90 | #endif |
| @@ -519,8 +519,10 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n, · 518 unmodified lines | ||
| 519 | 519 | mc->pdev->dev.can.state = new_state; |
| 520 | 520 | |
| 521 | 521 | if (status_len & PCAN_USB_STATUSLEN_TIMESTAMP) { |
| 522 | + struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb); | |
| 523 | + | |
| 522 | 524 | peak_usb_get_ts_tv(&mc->pdev->time_ref, mc->ts16, &tv); |
| 523 | − skb->tstamp = timeval_to_ktime(tv); | |
| 525 | + hwts->hwtstamp = timeval_to_ktime(tv); | |
| 524 | 526 | } |
| 525 | 527 | |
| 526 | 528 | netif_rx(skb); |
| @@ -605,6 +607,7 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len) · 78 unmodified lines | ||
| 605 | 607 | struct sk_buff *skb; |
| 606 | 608 | struct can_frame *cf; |
| 607 | 609 | struct timeval tv; |
| 610 | + struct skb_shared_hwtstamps *hwts; | |
| 608 | 611 | |
| 609 | 612 | skb = alloc_can_skb(mc->netdev, &cf); |
| 610 | 613 | if (!skb) |
| @@ -652,7 +655,8 @@ static int pcan_usb_decode_data(struct pcan_usb_msg_context *mc, u8 status_len) · 41 unmodified lines | ||
| 652 | 655 | |
| 653 | 656 | /* convert timestamp into kernel time */ |
| 654 | 657 | peak_usb_get_ts_tv(&mc->pdev->time_ref, mc->ts16, &tv); |
| 655 | − skb->tstamp = timeval_to_ktime(tv); | |
| 658 | + hwts = skb_hwtstamps(skb); | |
| 659 | + hwts->hwtstamp = timeval_to_ktime(tv); | |
| 656 | 660 | |
| 657 | 661 | /* push the skb */ |
| 658 | 662 | netif_rx(skb); |
| @@ -532,6 +532,7 @@ static int pcan_usb_pro_handle_canmsg(struct pcan_usb_pro_interface *usb_if, · 531 unmodified lines | ||
| 532 | 532 | struct can_frame *can_frame; |
| 533 | 533 | struct sk_buff *skb; |
| 534 | 534 | struct timeval tv; |
| 535 | + struct skb_shared_hwtstamps *hwts; | |
| 535 | 536 | |
| 536 | 537 | skb = alloc_can_skb(netdev, &can_frame); |
| 537 | 538 | if (!skb) |
| @@ -549,7 +550,8 @@ static int pcan_usb_pro_handle_canmsg(struct pcan_usb_pro_interface *usb_if, · 11 unmodified lines | ||
| 549 | 550 | memcpy(can_frame->data, rx->data, can_frame->can_dlc); |
| 550 | 551 | |
| 551 | 552 | peak_usb_get_ts_tv(&usb_if->time_ref, le32_to_cpu(rx->ts32), &tv); |
| 552 | − skb->tstamp = timeval_to_ktime(tv); | |
| 553 | + hwts = skb_hwtstamps(skb); | |
| 554 | + hwts->hwtstamp = timeval_to_ktime(tv); | |
| 553 | 555 | |
| 554 | 556 | netif_rx(skb); |
| 555 | 557 | netdev->stats.rx_packets++; |
| @@ -570,6 +572,7 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if, · 14 unmodified lines | ||
| 570 | 572 | u8 err_mask = 0; |
| 571 | 573 | struct sk_buff *skb; |
| 572 | 574 | struct timeval tv; |
| 575 | + struct skb_shared_hwtstamps *hwts; | |
| 573 | 576 | |
| 574 | 577 | /* nothing should be sent while in BUS_OFF state */ |
| 575 | 578 | if (dev->can.state == CAN_STATE_BUS_OFF) |
| @@ -664,7 +667,8 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if, · 88 unmodified lines | ||
| 664 | 667 | dev->can.state = new_state; |
| 665 | 668 | |
| 666 | 669 | peak_usb_get_ts_tv(&usb_if->time_ref, le32_to_cpu(er->ts32), &tv); |
| 667 | − skb->tstamp = timeval_to_ktime(tv); | |
| 670 | + hwts = skb_hwtstamps(skb); | |
| 671 | + hwts->hwtstamp = timeval_to_ktime(tv); | |
| 668 | 672 | netif_rx(skb); |
| 669 | 673 | netdev->stats.rx_packets++; |
| 670 | 674 | netdev->stats.rx_bytes += can_frame->can_dlc; |
| @@ -813,6 +813,7 @@ static int __init ne_drv_probe(struct platform_device *pdev) · 812 unmodified lines | ||
| 813 | 813 | dev->irq = irq[this_dev]; |
| 814 | 814 | dev->mem_end = bad[this_dev]; |
| 815 | 815 | } |
| 816 | + SET_NETDEV_DEV(dev, &pdev->dev); | |
| 816 | 817 | err = do_ne_probe(dev); |
| 817 | 818 | if (err) { |
| 818 | 819 | free_netdev(dev); |
| @@ -1702,7 +1702,7 @@ static int bnx2x_set_eee(struct net_device *dev, struct ethtool_eee *edata) · 1701 unmodified lines | ||
| 1702 | 1702 | SHMEM_EEE_ADV_STATUS_SHIFT); |
| 1703 | 1703 | if ((advertised != (eee_cfg & SHMEM_EEE_ADV_STATUS_MASK))) { |
| 1704 | 1704 | DP(BNX2X_MSG_ETHTOOL, |
| 1705 | − "Direct manipulation of EEE advertisment is not supported\n"); | |
| 1705 | + "Direct manipulation of EEE advertisement is not supported\n"); | |
| 1706 | 1706 | return -EINVAL; |
| 1707 | 1707 | } |
| 1708 | 1708 | |
| @@ -137,7 +137,16 @@ · 136 unmodified lines | ||
| 137 | 137 | #define LINK_20GTFD LINK_STATUS_SPEED_AND_DUPLEX_20GTFD |
| 138 | 138 | #define LINK_20GXFD LINK_STATUS_SPEED_AND_DUPLEX_20GXFD |
| 139 | 139 | |
| 140 | − | |
| 140 | +#define LINK_UPDATE_MASK \ | |
| 141 | + (LINK_STATUS_SPEED_AND_DUPLEX_MASK | \ | |
| 142 | + LINK_STATUS_LINK_UP | \ | |
| 143 | + LINK_STATUS_PHYSICAL_LINK_FLAG | \ | |
| 144 | + LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | \ | |
| 145 | + LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | \ | |
| 146 | + LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | \ | |
| 147 | + LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK | \ | |
| 148 | + LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE | \ | |
| 149 | + LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE) | |
| 141 | 150 | |
| 142 | 151 | #define SFP_EEPROM_CON_TYPE_ADDR 0x2 |
| 143 | 152 | #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7 |
| @@ -3295,6 +3304,21 @@ static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port) · 3151 unmodified lines | ||
| 3295 | 3304 | DEFAULT_PHY_DEV_ADDR); |
| 3296 | 3305 | } |
| 3297 | 3306 | |
| 3307 | +static void bnx2x_xgxs_specific_func(struct bnx2x_phy *phy, | |
| 3308 | + struct link_params *params, | |
| 3309 | + u32 action) | |
| 3310 | +{ | |
| 3311 | + struct bnx2x *bp = params->bp; | |
| 3312 | + switch (action) { | |
| 3313 | + case PHY_INIT: | |
| 3314 | + /* Set correct devad */ | |
| 3315 | + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + params->port*0x18, 0); | |
| 3316 | + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18, | |
| 3317 | + phy->def_md_devad); | |
| 3318 | + break; | |
| 3319 | + } | |
| 3320 | +} | |
| 3321 | + | |
| 3298 | 3322 | static void bnx2x_xgxs_deassert(struct link_params *params) |
| 3299 | 3323 | { |
| 3300 | 3324 | struct bnx2x *bp = params->bp; |
| @@ -3309,10 +3333,8 @@ static void bnx2x_xgxs_deassert(struct link_params *params) · 8 unmodified lines | ||
| 3309 | 3333 | REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val); |
| 3310 | 3334 | udelay(500); |
| 3311 | 3335 | REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); |
| 3312 | − | |
| 3313 | − REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + port*0x18, 0); | |
| 3314 | − REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, | |
| 3315 | − params->phy[INT_PHY].def_md_devad); | |
| 3336 | + bnx2x_xgxs_specific_func(¶ms->phy[INT_PHY], params, | |
| 3337 | + PHY_INIT); | |
| 3316 | 3338 | } |
| 3317 | 3339 | |
| 3318 | 3340 | static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy, |
| @@ -3545,14 +3567,11 @@ static void bnx2x_warpcore_set_lpi_passthrough(struct bnx2x_phy *phy, · 226 unmodified lines | ||
| 3545 | 3567 | static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, |
| 3546 | 3568 | struct link_params *params, |
| 3547 | 3569 | struct link_vars *vars) { |
| 3548 | − u16 val16 = 0, lane, i; | |
| 3570 | + u16 lane, i, cl72_ctrl, an_adv = 0; | |
| 3571 | + u16 ucode_ver; | |
| 3549 | 3572 | struct bnx2x *bp = params->bp; |
| 3550 | 3573 | static struct bnx2x_reg_set reg_set[] = { |
| 3551 | 3574 | {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7}, |
| 3552 | − {MDIO_AN_DEVAD, MDIO_WC_REG_PAR_DET_10G_CTRL, 0}, | |
| 3553 | − {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0}, | |
| 3554 | − {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0xff}, | |
| 3555 | − {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0x5555}, | |
| 3556 | 3575 | {MDIO_PMA_DEVAD, MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0x0}, |
| 3557 | 3576 | {MDIO_WC_DEVAD, MDIO_WC_REG_RX66_CONTROL, 0x7415}, |
| 3558 | 3577 | {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190}, |
| @@ -3565,12 +3584,19 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, · 6 unmodified lines | ||
| 3565 | 3584 | bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg, |
| 3566 | 3585 | reg_set[i].val); |
| 3567 | 3586 | |
| 3587 | + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | |
| 3588 | + MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &cl72_ctrl); | |
| 3589 | + cl72_ctrl &= 0xf8ff; | |
| 3590 | + cl72_ctrl |= 0x3800; | |
| 3591 | + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | |
| 3592 | + MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, cl72_ctrl); | |
| 3593 | + | |
| 3568 | 3594 | /* Check adding advertisement for 1G KX */ |
| 3569 | 3595 | if (((vars->line_speed == SPEED_AUTO_NEG) && |
| 3570 | 3596 | (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || |
| 3571 | 3597 | (vars->line_speed == SPEED_1000)) { |
| 3572 | 3598 | u32 addr = MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2; |
| 3573 | − val16 |= (1<<5); | |
| 3599 | + an_adv |= (1<<5); | |
| 3574 | 3600 | |
| 3575 | 3601 | /* Enable CL37 1G Parallel Detect */ |
| 3576 | 3602 | bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, addr, 0x1); |
| @@ -3580,11 +3606,14 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, · 3 unmodified lines | ||
| 3580 | 3606 | (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) || |
| 3581 | 3607 | (vars->line_speed == SPEED_10000)) { |
| 3582 | 3608 | /* Check adding advertisement for 10G KR */ |
| 3583 | − val16 |= (1<<7); | |
| 3609 | + an_adv |= (1<<7); | |
| 3584 | 3610 | /* Enable 10G Parallel Detect */ |
| 3611 | + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, | |
| 3612 | + MDIO_AER_BLOCK_AER_REG, 0); | |
| 3613 | + | |
| 3585 | 3614 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, |
| 3586 | 3615 | MDIO_WC_REG_PAR_DET_10G_CTRL, 1); |
| 3587 | − | |
| 3616 | + bnx2x_set_aer_mmd(params, phy); | |
| 3588 | 3617 | DP(NETIF_MSG_LINK, "Advertize 10G\n"); |
| 3589 | 3618 | } |
| 3590 | 3619 | |
| @@ -3604,7 +3633,7 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, · 13 unmodified lines | ||
| 3604 | 3633 | |
| 3605 | 3634 | /* Advertised speeds */ |
| 3606 | 3635 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, |
| 3607 | − MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16); | |
| 3636 | + MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, an_adv); | |
| 3608 | 3637 | |
| 3609 | 3638 | /* Advertised and set FEC (Forward Error Correction) */ |
| 3610 | 3639 | bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, |
| @@ -3628,9 +3657,10 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, · 17 unmodified lines | ||
| 3628 | 3657 | /* Set KR Autoneg Work-Around flag for Warpcore version older than D108 |
| 3629 | 3658 | */ |
| 3630 | 3659 | bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, |
| 3631 | − MDIO_WC_REG_UC_INFO_B1_VERSION, &val16); | |
| 3632 | − if (val16 < 0xd108) { | |
| 3633 | − DP(NETIF_MSG_LINK, "Enable AN KR work-around\n"); | |
| 3660 | + MDIO_WC_REG_UC_INFO_B1_VERSION, &ucode_ver); | |
| 3661 | + if (ucode_ver < 0xd108) { | |
| 3662 | + DP(NETIF_MSG_LINK, "Enable AN KR work-around. WC ver:0x%x\n", | |
| 3663 | + ucode_ver); | |
| 3634 | 3664 | vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY; |
| 3635 | 3665 | } |
| 3636 | 3666 | bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, |
| @@ -3651,21 +3681,16 @@ static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy, · 14 unmodified lines | ||
| 3651 | 3681 | struct link_vars *vars) |
| 3652 | 3682 | { |
| 3653 | 3683 | struct bnx2x *bp = params->bp; |
| 3654 | − u16 i; | |
| 3684 | + u16 val16, i, lane; | |
| 3655 | 3685 | static struct bnx2x_reg_set reg_set[] = { |
| 3656 | 3686 | /* Disable Autoneg */ |
| 3657 | 3687 | {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7}, |
| 3658 | − {MDIO_AN_DEVAD, MDIO_WC_REG_PAR_DET_10G_CTRL, 0}, | |
| 3659 | 3688 | {MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, |
| 3660 | 3689 | 0x3f00}, |
| 3661 | 3690 | {MDIO_AN_DEVAD, MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0}, |
| 3662 | 3691 | {MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0}, |
| 3663 | 3692 | {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL3_UP1, 0x1}, |
| 3664 | 3693 | {MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC7, 0xa}, |
| 3665 | − /* Disable CL36 PCS Tx */ | |
| 3666 | − {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0}, | |
| 3667 | − /* Double Wide Single Data Rate @ pll rate */ | |
| 3668 | − {MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF}, | |
| 3669 | 3694 | /* Leave cl72 training enable, needed for KR */ |
| 3670 | 3695 | {MDIO_PMA_DEVAD, |
| 3671 | 3696 | MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150, |
| @@ -3676,11 +3701,24 @@ static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy, · 4 unmodified lines | ||
| 3676 | 3701 | bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg, |
| 3677 | 3702 | reg_set[i].val); |
| 3678 | 3703 | |
| 3679 | − /* Leave CL72 enabled */ | |
| 3680 | − bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, | |
| 3681 | − MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, | |
| 3682 | − 0x3800); | |
| 3704 | + lane = bnx2x_get_warpcore_lane(phy, params); | |
| 3705 | + /* Global registers */ | |
| 3706 | + CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, | |
| 3707 | + MDIO_AER_BLOCK_AER_REG, 0); | |
| 3708 | + /* Disable CL36 PCS Tx */ | |
| 3709 | + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | |
| 3710 | + MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16); | |
| 3711 | + val16 &= ~(0x0011 << lane); | |
| 3712 | + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | |
| 3713 | + MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16); | |
| 3683 | 3714 | |
| 3715 | + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | |
| 3716 | + MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16); | |
| 3717 | + val16 |= (0x0303 << (lane << 1)); | |
| 3718 | + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | |
| 3719 | + MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16); | |
| 3720 | + /* Restore AER */ | |
| 3721 | + bnx2x_set_aer_mmd(params, phy); | |
| 3684 | 3722 | /* Set speed via PMA/PMD register */ |
| 3685 | 3723 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, |
| 3686 | 3724 | MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040); |
| @@ -4303,7 +4341,7 @@ static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy, · 616 unmodified lines | ||
| 4303 | 4341 | struct link_params *params) |
| 4304 | 4342 | { |
| 4305 | 4343 | struct bnx2x *bp = params->bp; |
| 4306 | − u16 val16; | |
| 4344 | + u16 val16, lane; | |
| 4307 | 4345 | bnx2x_sfp_e3_set_transmitter(params, phy, 0); |
| 4308 | 4346 | bnx2x_set_mdio_clk(bp, params->chip_id, params->port); |
| 4309 | 4347 | bnx2x_set_aer_mmd(params, phy); |
| @@ -4340,6 +4378,30 @@ static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy, · 30 unmodified lines | ||
| 4340 | 4378 | MDIO_WC_REG_XGXSBLK1_LANECTRL2, |
| 4341 | 4379 | val16 & 0xff00); |
| 4342 | 4380 | |
| 4381 | + lane = bnx2x_get_warpcore_lane(phy, params); | |
| 4382 | + /* Disable CL36 PCS Tx */ | |
| 4383 | + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | |
| 4384 | + MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16); | |
| 4385 | + val16 |= (0x11 << lane); | |
| 4386 | + if (phy->flags & FLAGS_WC_DUAL_MODE) | |
| 4387 | + val16 |= (0x22 << lane); | |
| 4388 | + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | |
| 4389 | + MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16); | |
| 4390 | + | |
| 4391 | + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, | |
| 4392 | + MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16); | |
| 4393 | + val16 &= ~(0x0303 << (lane << 1)); | |
| 4394 | + val16 |= (0x0101 << (lane << 1)); | |
| 4395 | + if (phy->flags & FLAGS_WC_DUAL_MODE) { | |
| 4396 | + val16 &= ~(0x0c0c << (lane << 1)); | |
| 4397 | + val16 |= (0x0404 << (lane << 1)); | |
| 4398 | + } | |
| 4399 | + | |
| 4400 | + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | |
| 4401 | + MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16); | |
| 4402 | + /* Restore AER */ | |
| 4403 | + bnx2x_set_aer_mmd(params, phy); | |
| 4404 | + | |
| 4343 | 4405 | } |
| 4344 | 4406 | |
| 4345 | 4407 | static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy, |
| @@ -6296,15 +6358,7 @@ static int bnx2x_update_link_down(struct link_params *params, · 1950 unmodified lines | ||
| 6296 | 6358 | vars->mac_type = MAC_TYPE_NONE; |
| 6297 | 6359 | |
| 6298 | 6360 | /* Update shared memory */ |
| 6299 | − vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK | | |
| 6300 | − LINK_STATUS_LINK_UP | | |
| 6301 | − LINK_STATUS_PHYSICAL_LINK_FLAG | | |
| 6302 | − LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | | |
| 6303 | − LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | | |
| 6304 | − LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | | |
| 6305 | − LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK | | |
| 6306 | − LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE | | |
| 6307 | − LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE); | |
| 6361 | + vars->link_status &= ~LINK_UPDATE_MASK; | |
| 6308 | 6362 | vars->line_speed = 0; |
| 6309 | 6363 | bnx2x_update_mng(params, vars->link_status); |
| 6310 | 6364 | |
| @@ -6452,6 +6506,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) · 141 unmodified lines | ||
| 6452 | 6506 | u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed; |
| 6453 | 6507 | u8 active_external_phy = INT_PHY; |
| 6454 | 6508 | vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG; |
| 6509 | + vars->link_status &= ~LINK_UPDATE_MASK; | |
| 6455 | 6510 | for (phy_index = INT_PHY; phy_index < params->num_phys; |
| 6456 | 6511 | phy_index++) { |
| 6457 | 6512 | phy_vars[phy_index].flow_ctrl = 0; |
| @@ -7579,7 +7634,7 @@ static void bnx2x_warpcore_power_module(struct link_params *params, · 1121 unmodified lines | ||
| 7579 | 7634 | static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, |
| 7580 | 7635 | struct link_params *params, |
| 7581 | 7636 | u16 addr, u8 byte_cnt, |
| 7582 | − u8 *o_buf) | |
| 7637 | + u8 *o_buf, u8 is_init) | |
| 7583 | 7638 | { |
| 7584 | 7639 | int rc = 0; |
| 7585 | 7640 | u8 i, j = 0, cnt = 0; |
| @@ -7596,10 +7651,10 @@ static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, · 10 unmodified lines | ||
| 7596 | 7651 | /* 4 byte aligned address */ |
| 7597 | 7652 | addr32 = addr & (~0x3); |
| 7598 | 7653 | do { |
| 7599 | − if (cnt == I2C_WA_PWR_ITER) { | |
| 7654 | + if ((!is_init) && (cnt == I2C_WA_PWR_ITER)) { | |
| 7600 | 7655 | bnx2x_warpcore_power_module(params, phy, 0); |
| 7601 | 7656 | /* Note that 100us are not enough here */ |
| 7602 | − usleep_range(1000,1000); | |
| 7657 | + usleep_range(1000, 2000); | |
| 7603 | 7658 | bnx2x_warpcore_power_module(params, phy, 1); |
| 7604 | 7659 | } |
| 7605 | 7660 | rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt, |
| @@ -7719,7 +7774,7 @@ int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, · 113 unmodified lines | ||
| 7719 | 7774 | break; |
| 7720 | 7775 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: |
| 7721 | 7776 | rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, params, addr, |
| 7722 | − byte_cnt, o_buf); | |
| 7777 | + byte_cnt, o_buf, 0); | |
| 7723 | 7778 | break; |
| 7724 | 7779 | } |
| 7725 | 7780 | return rc; |
| @@ -7923,6 +7978,7 @@ static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, · 197 unmodified lines | ||
| 7923 | 7978 | |
| 7924 | 7979 | { |
| 7925 | 7980 | u8 val; |
| 7981 | + int rc; | |
| 7926 | 7982 | struct bnx2x *bp = params->bp; |
| 7927 | 7983 | u16 timeout; |
| 7928 | 7984 | /* Initialization time after hot-plug may take up to 300ms for |
| @@ -7930,8 +7986,14 @@ static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, · 1 unmodified line | ||
| 7930 | 7986 | */ |
| 7931 | 7987 | |
| 7932 | 7988 | for (timeout = 0; timeout < 60; timeout++) { |
| 7933 | − if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val) | |
| 7934 | − == 0) { | |
| 7989 | + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) | |
| 7990 | + rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, | |
| 7991 | + params, 1, | |
| 7992 | + 1, &val, 1); | |
| 7993 | + else | |
| 7994 | + rc = bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, | |
| 7995 | + &val); | |
| 7996 | + if (rc == 0) { | |
| 7935 | 7997 | DP(NETIF_MSG_LINK, |
| 7936 | 7998 | "SFP+ module initialization took %d ms\n", |
| 7937 | 7999 | timeout * 5); |
| @@ -7939,7 +8001,8 @@ static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, · 1 unmodified line | ||
| 7939 | 8001 | } |
| 7940 | 8002 | usleep_range(5000, 10000); |
| 7941 | 8003 | } |
| 7942 | − return -EINVAL; | |
| 8004 | + rc = bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val); | |
| 8005 | + return rc; | |
| 7943 | 8006 | } |
| 7944 | 8007 | |
| 7945 | 8008 | static void bnx2x_8727_power_module(struct bnx2x *bp, |
| @@ -9878,7 +9941,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, · 1932 unmodified lines | ||
| 9878 | 9941 | else |
| 9879 | 9942 | rc = bnx2x_8483x_disable_eee(phy, params, vars); |
| 9880 | 9943 | if (rc) { |
| 9881 | − DP(NETIF_MSG_LINK, "Failed to set EEE advertisment\n"); | |
| 9944 | + DP(NETIF_MSG_LINK, "Failed to set EEE advertisement\n"); | |
| 9882 | 9945 | return rc; |
| 9883 | 9946 | } |
| 9884 | 9947 | } else { |
| @@ -10993,7 +11056,7 @@ static struct bnx2x_phy phy_xgxs = { · 1108 unmodified lines | ||
| 10993 | 11056 | .format_fw_ver = (format_fw_ver_t)NULL, |
| 10994 | 11057 | .hw_reset = (hw_reset_t)NULL, |
| 10995 | 11058 | .set_link_led = (set_link_led_t)NULL, |
| 10996 | − .phy_specific_func = (phy_specific_func_t)NULL | |
| 11059 | + .phy_specific_func = (phy_specific_func_t)bnx2x_xgxs_specific_func | |
| 10997 | 11060 | }; |
| 10998 | 11061 | static struct bnx2x_phy phy_warpcore = { |
| 10999 | 11062 | .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT, |
| @@ -11465,6 +11528,11 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, · 465 unmodified lines | ||
| 11465 | 11528 | phy->media_type = ETH_PHY_BASE_T; |
| 11466 | 11529 | break; |
| 11467 | 11530 | case PORT_HW_CFG_NET_SERDES_IF_XFI: |
| 11531 | + phy->supported &= (SUPPORTED_1000baseT_Full | | |
| 11532 | + SUPPORTED_10000baseT_Full | | |
| 11533 | + SUPPORTED_FIBRE | | |
| 11534 | + SUPPORTED_Pause | | |
| 11535 | + SUPPORTED_Asym_Pause); | |
| 11468 | 11536 | phy->media_type = ETH_PHY_XFP_FIBER; |
| 11469 | 11537 | break; |
| 11470 | 11538 | case PORT_HW_CFG_NET_SERDES_IF_SFI: |
| @@ -12919,7 +12987,7 @@ static u8 bnx2x_analyze_link_error(struct link_params *params, · 1448 unmodified lines | ||
| 12919 | 12987 | DP(NETIF_MSG_LINK, "Analyze TX Fault\n"); |
| 12920 | 12988 | break; |
| 12921 | 12989 | default: |
| 12922 | − DP(NETIF_MSG_LINK, "Analyze UNKOWN\n"); | |
| 12990 | + DP(NETIF_MSG_LINK, "Analyze UNKNOWN\n"); | |
| 12923 | 12991 | } |
| 12924 | 12992 | DP(NETIF_MSG_LINK, "Link changed:[%x %x]->%x\n", vars->link_up, |
| 12925 | 12993 | old_status, status); |
| @@ -6794,8 +6794,9 @@ static int bnx2x_init_hw_port(struct bnx2x *bp) · 6793 unmodified lines | ||
| 6794 | 6794 | |
| 6795 | 6795 | bnx2x_init_block(bp, BLOCK_DORQ, init_phase); |
| 6796 | 6796 | |
| 6797 | + bnx2x_init_block(bp, BLOCK_BRB1, init_phase); | |
| 6798 | + | |
| 6797 | 6799 | if (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) { |
| 6798 | − bnx2x_init_block(bp, BLOCK_BRB1, init_phase); | |
| 6799 | 6800 | |
| 6800 | 6801 | if (IS_MF(bp)) |
| 6801 | 6802 | low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246); |
| @@ -9544,10 +9545,13 @@ static int __devinit bnx2x_prev_unload_common(struct bnx2x *bp) · 2742 unmodified lines | ||
| 9544 | 9545 | */ |
| 9545 | 9546 | static void __devinit bnx2x_prev_interrupted_dmae(struct bnx2x *bp) |
| 9546 | 9547 | { |
| 9547 | − u32 val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS); | |
| 9548 | − if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) { | |
| 9549 | − BNX2X_ERR("was error bit was found to be set in pglueb upon startup. Clearing"); | |
| 9550 | − REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, 1 << BP_FUNC(bp)); | |
| 9548 | + if (!CHIP_IS_E1x(bp)) { | |
| 9549 | + u32 val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS); | |
| 9550 | + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) { | |
| 9551 | + BNX2X_ERR("was error bit was found to be set in pglueb upon startup. Clearing"); | |
| 9552 | + REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, | |
| 9553 | + 1 << BP_FUNC(bp)); | |
| 9554 | + } | |
| 9551 | 9555 | } |
| 9552 | 9556 | } |
| 9553 | 9557 | |
| @@ -11902,7 +11906,15 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, · 2348 unmodified lines | ||
| 11902 | 11906 | /* disable FCOE L2 queue for E1x */ |
| 11903 | 11907 | if (CHIP_IS_E1x(bp)) |
| 11904 | 11908 | bp->flags |= NO_FCOE_FLAG; |
| 11905 | − | |
| 11909 | + /* disable FCOE for 57840 device, until FW supports it */ | |
| 11910 | + switch (ent->driver_data) { | |
| 11911 | + case BCM57840_O: | |
| 11912 | + case BCM57840_4_10: | |
| 11913 | + case BCM57840_2_20: | |
| 11914 | + case BCM57840_MFO: | |
| 11915 | + case BCM57840_MF: | |
| 11916 | + bp->flags |= NO_FCOE_FLAG; | |
| 11917 | + } | |
| 11906 | 11918 | #endif |
| 11907 | 11919 | |
| 11908 | 11920 | |
| @@ -251,6 +251,8 @@ struct adapter_params { · 250 unmodified lines | ||
| 251 | 251 | unsigned char rev; /* chip revision */ |
| 252 | 252 | unsigned char offload; |
| 253 | 253 | |
| 254 | + unsigned char bypass; | |
| 255 | + | |
| 254 | 256 | unsigned int ofldq_wr_cred; |
| 255 | 257 | }; |
| 256 | 258 | |
| @@ -642,6 +644,23 @@ extern int dbfifo_int_thresh; · 385 unmodified lines | ||
| 642 | 644 | #define for_each_port(adapter, iter) \ |
| 643 | 645 | for (iter = 0; iter < (adapter)->params.nports; ++iter) |
| 644 | 646 | |
| 647 | +static inline int is_bypass(struct adapter *adap) | |
| 648 | +{ | |
| 649 | + return adap->params.bypass; | |
| 650 | +} | |
| 651 | + | |
| 652 | +static inline int is_bypass_device(int device) | |
| 653 | +{ | |
| 654 | + /* this should be set based upon device capabilities */ | |
| 655 | + switch (device) { | |
| 656 | + case 0x440b: | |
| 657 | + case 0x440c: | |
| 658 | + return 1; | |
| 659 | + default: | |
| 660 | + return 0; | |
| 661 | + } | |
| 662 | +} | |
| 663 | + | |
| 645 | 664 | static inline unsigned int core_ticks_per_usec(const struct adapter *adap) |
| 646 | 665 | { |
| 647 | 666 | return adap->params.vpd.cclk / 1000; |
| @@ -3415,16 +3415,6 @@ static int adap_init0_config(struct adapter *adapter, int reset) · 3414 unmodified lines | ||
| 3415 | 3415 | "mismatch: [fini] csum=%#x, computed csum=%#x\n", |
| 3416 | 3416 | finicsum, cfcsum); |
| 3417 | 3417 | |
| 3418 | − /* | |
| 3419 | − * If we're a pure NIC driver then disable all offloading facilities. | |
| 3420 | − * This will allow the firmware to optimize aspects of the hardware | |
| 3421 | − * configuration which will result in improved performance. | |
| 3422 | − */ | |
| 3423 | − caps_cmd.ofldcaps = 0; | |
| 3424 | − caps_cmd.iscsicaps = 0; | |
| 3425 | − caps_cmd.rdmacaps = 0; | |
| 3426 | − caps_cmd.fcoecaps = 0; | |
| 3427 | − | |
| 3428 | 3418 | /* |
| 3429 | 3419 | * And now tell the firmware to use the configuration we just loaded. |
| 3430 | 3420 | */ |
| @@ -3513,18 +3503,6 @@ static int adap_init0_no_config(struct adapter *adapter, int reset) · 82 unmodified lines | ||
| 3513 | 3503 | if (ret < 0) |
| 3514 | 3504 | goto bye; |
| 3515 | 3505 | |
| 3516 | −#ifndef CONFIG_CHELSIO_T4_OFFLOAD | |
| 3517 | − /* | |
| 3518 | − * If we're a pure NIC driver then disable all offloading facilities. | |
| 3519 | − * This will allow the firmware to optimize aspects of the hardware | |
| 3520 | − * configuration which will result in improved performance. | |
| 3521 | − */ | |
| 3522 | − caps_cmd.ofldcaps = 0; | |
| 3523 | − caps_cmd.iscsicaps = 0; | |
| 3524 | − caps_cmd.rdmacaps = 0; | |
| 3525 | − caps_cmd.fcoecaps = 0; | |
| 3526 | −#endif | |
| 3527 | − | |
| 3528 | 3506 | if (caps_cmd.niccaps & htons(FW_CAPS_CONFIG_NIC_VM)) { |
| 3529 | 3507 | if (!vf_acls) |
| 3530 | 3508 | caps_cmd.niccaps ^= htons(FW_CAPS_CONFIG_NIC_VM); |
| @@ -3745,6 +3723,7 @@ static int adap_init0(struct adapter *adap) · 214 unmodified lines | ||
| 3745 | 3723 | u32 v, port_vec; |
| 3746 | 3724 | enum dev_state state; |
| 3747 | 3725 | u32 params[7], val[7]; |
| 3726 | + struct fw_caps_config_cmd caps_cmd; | |
| 3748 | 3727 | int reset = 1, j; |
| 3749 | 3728 | |
| 3750 | 3729 | /* |
| @@ -3898,6 +3877,9 @@ static int adap_init0(struct adapter *adap) · 147 unmodified lines | ||
| 3898 | 3877 | goto bye; |
| 3899 | 3878 | } |
| 3900 | 3879 | |
| 3880 | + if (is_bypass_device(adap->pdev->device)) | |
| 3881 | + adap->params.bypass = 1; | |
| 3882 | + | |
| 3901 | 3883 | /* |
| 3902 | 3884 | * Grab some of our basic fundamental operating parameters. |
| 3903 | 3885 | */ |
| @@ -3940,13 +3922,12 @@ static int adap_init0(struct adapter *adap) · 36 unmodified lines | ||
| 3940 | 3922 | adap->tids.aftid_end = val[1]; |
| 3941 | 3923 | } |
| 3942 | 3924 | |
| 3943 | −#ifdef CONFIG_CHELSIO_T4_OFFLOAD | |
| 3944 | 3925 | /* |
| 3945 | 3926 | * Get device capabilities so we can determine what resources we need |
| 3946 | 3927 | * to manage. |
| 3947 | 3928 | */ |
| 3948 | 3929 | memset(&caps_cmd, 0, sizeof(caps_cmd)); |
| 3949 | − caps_cmd.op_to_write = htonl(V_FW_CMD_OP(FW_CAPS_CONFIG_CMD) | | |
| 3930 | + caps_cmd.op_to_write = htonl(FW_CMD_OP(FW_CAPS_CONFIG_CMD) | | |
| 3950 | 3931 | FW_CMD_REQUEST | FW_CMD_READ); |
| 3951 | 3932 | caps_cmd.retval_len16 = htonl(FW_LEN16(caps_cmd)); |
| 3952 | 3933 | ret = t4_wr_mbox(adap, adap->mbox, &caps_cmd, sizeof(caps_cmd), |
| @@ -3991,15 +3972,6 @@ static int adap_init0(struct adapter *adap) · 38 unmodified lines | ||
| 3991 | 3972 | adap->vres.ddp.size = val[4] - val[3] + 1; |
| 3992 | 3973 | adap->params.ofldq_wr_cred = val[5]; |
| 3993 | 3974 | |
| 3994 | − params[0] = FW_PARAM_PFVF(ETHOFLD_START); | |
| 3995 | − params[1] = FW_PARAM_PFVF(ETHOFLD_END); | |
| 3996 | − ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 2, | |
| 3997 | − params, val); | |
| 3998 | − if ((val[0] != val[1]) && (ret >= 0)) { | |
| 3999 | − adap->tids.uotid_base = val[0]; | |
| 4000 | − adap->tids.nuotids = val[1] - val[0] + 1; | |
| 4001 | − } | |
| 4002 | − | |
| 4003 | 3975 | adap->params.offload = 1; |
| 4004 | 3976 | } |
| 4005 | 3977 | if (caps_cmd.rdmacaps) { |
| @@ -4048,7 +4020,6 @@ static int adap_init0(struct adapter *adap) · 42 unmodified lines | ||
| 4048 | 4020 | } |
| 4049 | 4021 | #undef FW_PARAM_PFVF |
| 4050 | 4022 | #undef FW_PARAM_DEV |
| 4051 | −#endif /* CONFIG_CHELSIO_T4_OFFLOAD */ | |
| 4052 | 4023 | |
| 4053 | 4024 | /* |
| 4054 | 4025 | * These are finalized by FW initialization, load their values now. |
| @@ -102,6 +102,9 @@ struct tid_info { · 101 unmodified lines | ||
| 102 | 102 | unsigned int ftid_base; |
| 103 | 103 | unsigned int aftid_base; |
| 104 | 104 | unsigned int aftid_end; |
| 105 | + /* Server filter region */ | |
| 106 | + unsigned int sftid_base; | |
| 107 | + unsigned int nsftids; | |
| 105 | 108 | |
| 106 | 109 | spinlock_t atid_lock ____cacheline_aligned_in_smp; |
| 107 | 110 | union aopen_entry *afree; |
| @@ -2519,6 +2519,7 @@ int t4_fw_bye(struct adapter *adap, unsigned int mbox) · 2518 unmodified lines | ||
| 2519 | 2519 | { |
| 2520 | 2520 | struct fw_bye_cmd c; |
| 2521 | 2521 | |
| 2522 | + memset(&c, 0, sizeof(c)); | |
| 2522 | 2523 | INIT_CMD(c, BYE, WRITE); |
| 2523 | 2524 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); |
| 2524 | 2525 | } |
| @@ -2535,6 +2536,7 @@ int t4_early_init(struct adapter *adap, unsigned int mbox) · 10 unmodified lines | ||
| 2535 | 2536 | { |
| 2536 | 2537 | struct fw_initialize_cmd c; |
| 2537 | 2538 | |
| 2539 | + memset(&c, 0, sizeof(c)); | |
| 2538 | 2540 | INIT_CMD(c, INITIALIZE, WRITE); |
| 2539 | 2541 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); |
| 2540 | 2542 | } |
| @@ -2551,6 +2553,7 @@ int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset) · 10 unmodified lines | ||
| 2551 | 2553 | { |
| 2552 | 2554 | struct fw_reset_cmd c; |
| 2553 | 2555 | |
| 2556 | + memset(&c, 0, sizeof(c)); | |
| 2554 | 2557 | INIT_CMD(c, RESET, WRITE); |
| 2555 | 2558 | c.val = htonl(reset); |
| 2556 | 2559 | return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); |
| @@ -2828,7 +2831,7 @@ int t4_fixup_host_params(struct adapter *adap, unsigned int page_size, · 271 unmodified lines | ||
| 2828 | 2831 | HOSTPAGESIZEPF7(sge_hps)); |
| 2829 | 2832 | |
| 2830 | 2833 | t4_set_reg_field(adap, SGE_CONTROL, |
| 2831 | − INGPADBOUNDARY(INGPADBOUNDARY_MASK) | | |
| 2834 | + INGPADBOUNDARY_MASK | | |
| 2832 | 2835 | EGRSTATUSPAGESIZE_MASK, |
| 2833 | 2836 | INGPADBOUNDARY(fl_align_log - 5) | |
| 2834 | 2837 | EGRSTATUSPAGESIZE(stat_len != 64)); |
| @@ -3278,6 +3281,7 @@ int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid, · 443 unmodified lines | ||
| 3278 | 3281 | { |
| 3279 | 3282 | struct fw_vi_enable_cmd c; |
| 3280 | 3283 | |
| 3284 | + memset(&c, 0, sizeof(c)); | |
| 3281 | 3285 | c.op_to_viid = htonl(FW_CMD_OP(FW_VI_ENABLE_CMD) | FW_CMD_REQUEST | |
| 3282 | 3286 | FW_CMD_EXEC | FW_VI_ENABLE_CMD_VIID(viid)); |
| 3283 | 3287 | c.ien_to_len16 = htonl(FW_VI_ENABLE_CMD_LED | FW_LEN16(c)); |
| @@ -1353,8 +1353,11 @@ static int gfar_restore(struct device *dev) · 1352 unmodified lines | ||
| 1353 | 1353 | struct gfar_private *priv = dev_get_drvdata(dev); |
| 1354 | 1354 | struct net_device *ndev = priv->ndev; |
| 1355 | 1355 | |
| 1356 | − if (!netif_running(ndev)) | |
| 1356 | + if (!netif_running(ndev)) { | |
| 1357 | + netif_device_attach(ndev); | |
| 1358 | + | |
| 1357 | 1359 | return 0; |
| 1360 | + } | |
| 1358 | 1361 | |
| 1359 | 1362 | gfar_init_bds(ndev); |
| 1360 | 1363 | init_registers(ndev); |
| @@ -478,7 +478,7 @@ static int gianfar_ptp_probe(struct platform_device *dev) · 477 unmodified lines | ||
| 478 | 478 | pr_err("no resource\n"); |
| 479 | 479 | goto no_resource; |
| 480 | 480 | } |
| 481 | − if (request_resource(&ioport_resource, etsects->rsrc)) { | |
| 481 | + if (request_resource(&iomem_resource, etsects->rsrc)) { | |
| 482 | 482 | pr_err("resource busy\n"); |
| 483 | 483 | goto no_resource; |
| 484 | 484 | } |
| @@ -2673,6 +2673,9 @@ static int ixgbe_get_ts_info(struct net_device *dev, · 2672 unmodified lines | ||
| 2673 | 2673 | case ixgbe_mac_X540: |
| 2674 | 2674 | case ixgbe_mac_82599EB: |
| 2675 | 2675 | info->so_timestamping = |
| 2676 | + SOF_TIMESTAMPING_TX_SOFTWARE | | |
| 2677 | + SOF_TIMESTAMPING_RX_SOFTWARE | | |
| 2678 | + SOF_TIMESTAMPING_SOFTWARE | | |
| 2676 | 2679 | SOF_TIMESTAMPING_TX_HARDWARE | |
| 2677 | 2680 | SOF_TIMESTAMPING_RX_HARDWARE | |
| 2678 | 2681 | SOF_TIMESTAMPING_RAW_HARDWARE; |
| @@ -1860,10 +1860,14 @@ jme_open(struct net_device *netdev) · 1859 unmodified lines | ||
| 1860 | 1860 | jme_clear_pm(jme); |
| 1861 | 1861 | JME_NAPI_ENABLE(jme); |
| 1862 | 1862 | |
| 1863 | − tasklet_enable(&jme->linkch_task); | |
| 1864 | − tasklet_enable(&jme->txclean_task); | |
| 1865 | − tasklet_hi_enable(&jme->rxclean_task); | |
| 1866 | − tasklet_hi_enable(&jme->rxempty_task); | |
| 1863 | + tasklet_init(&jme->linkch_task, jme_link_change_tasklet, | |
| 1864 | + (unsigned long) jme); | |
| 1865 | + tasklet_init(&jme->txclean_task, jme_tx_clean_tasklet, | |
| 1866 | + (unsigned long) jme); | |
| 1867 | + tasklet_init(&jme->rxclean_task, jme_rx_clean_tasklet, | |
| 1868 | + (unsigned long) jme); | |
| 1869 | + tasklet_init(&jme->rxempty_task, jme_rx_empty_tasklet, | |
| 1870 | + (unsigned long) jme); | |
| 1867 | 1871 | |
| 1868 | 1872 | rc = jme_request_irq(jme); |
| 1869 | 1873 | if (rc) |
| @@ -1948,10 +1952,10 @@ jme_close(struct net_device *netdev) · 78 unmodified lines | ||
| 1948 | 1952 | |
| 1949 | 1953 | JME_NAPI_DISABLE(jme); |
| 1950 | 1954 | |
| 1951 | − tasklet_disable(&jme->linkch_task); | |
| 1952 | − tasklet_disable(&jme->txclean_task); | |
| 1953 | − tasklet_disable(&jme->rxclean_task); | |
| 1954 | − tasklet_disable(&jme->rxempty_task); | |
| 1955 | + tasklet_kill(&jme->linkch_task); | |
| 1956 | + tasklet_kill(&jme->txclean_task); | |
| 1957 | + tasklet_kill(&jme->rxclean_task); | |
| 1958 | + tasklet_kill(&jme->rxempty_task); | |
| 1955 | 1959 | |
| 1956 | 1960 | jme_disable_rx_engine(jme); |
| 1957 | 1961 | jme_disable_tx_engine(jme); |
| @@ -3079,22 +3083,6 @@ jme_init_one(struct pci_dev *pdev, · 1121 unmodified lines | ||
| 3079 | 3083 | tasklet_init(&jme->pcc_task, |
| 3080 | 3084 | jme_pcc_tasklet, |
| 3081 | 3085 | (unsigned long) jme); |
| 3082 | − tasklet_init(&jme->linkch_task, | |
| 3083 | − jme_link_change_tasklet, | |
| 3084 | − (unsigned long) jme); | |
| 3085 | − tasklet_init(&jme->txclean_task, | |
| 3086 | − jme_tx_clean_tasklet, | |
| 3087 | − (unsigned long) jme); | |
| 3088 | − tasklet_init(&jme->rxclean_task, | |
| 3089 | − jme_rx_clean_tasklet, | |
| 3090 | − (unsigned long) jme); | |
| 3091 | − tasklet_init(&jme->rxempty_task, | |
| 3092 | − jme_rx_empty_tasklet, | |
| 3093 | − (unsigned long) jme); | |
| 3094 | − tasklet_disable_nosync(&jme->linkch_task); | |
| 3095 | − tasklet_disable_nosync(&jme->txclean_task); | |
| 3096 | − tasklet_disable_nosync(&jme->rxclean_task); | |
| 3097 | − tasklet_disable_nosync(&jme->rxempty_task); | |
| 3098 | 3086 | jme->dpi.cur = PCC_P1; |
| 3099 | 3087 | |
| 3100 | 3088 | jme->reg_ghc = 0; |
| @@ -4026,7 +4026,7 @@ static void __devexit skge_remove(struct pci_dev *pdev) · 4025 unmodified lines | ||
| 4026 | 4026 | dev0 = hw->dev[0]; |
| 4027 | 4027 | unregister_netdev(dev0); |
| 4028 | 4028 | |
| 4029 | − tasklet_disable(&hw->phy_task); | |
| 4029 | + tasklet_kill(&hw->phy_task); | |
| 4030 | 4030 | |
| 4031 | 4031 | spin_lock_irq(&hw->hw_lock); |
| 4032 | 4032 | hw->intr_mask = 0; |
| @@ -237,7 +237,7 @@ static int mlx4_en_dcbnl_ieee_setmaxrate(struct net_device *dev, · 236 unmodified lines | ||
| 237 | 237 | if (err) |
| 238 | 238 | return err; |
| 239 | 239 | |
| 240 | − memcpy(priv->maxrate, tmp, sizeof(*priv->maxrate)); | |
| 240 | + memcpy(priv->maxrate, tmp, sizeof(priv->maxrate)); | |
| 241 | 241 | |
| 242 | 242 | return 0; |
| 243 | 243 | } |
| @@ -143,7 +143,6 @@ void mlx4_en_destroy_tx_ring(struct mlx4_en_priv *priv, · 142 unmodified lines | ||
| 143 | 143 | mlx4_bf_free(mdev->dev, &ring->bf); |
| 144 | 144 | mlx4_qp_remove(mdev->dev, &ring->qp); |
| 145 | 145 | mlx4_qp_free(mdev->dev, &ring->qp); |
| 146 | − mlx4_qp_release_range(mdev->dev, ring->qpn, 1); | |
| 147 | 146 | mlx4_en_unmap_buffer(&ring->wqres.buf); |
| 148 | 147 | mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size); |
| 149 | 148 | kfree(ring->bounce_buf); |
| @@ -712,7 +711,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) · 562 unmodified lines | ||
| 712 | 711 | if (bounce) |
| 713 | 712 | tx_desc = mlx4_en_bounce_to_desc(priv, ring, index, desc_size); |
| 714 | 713 | |
| 715 | − if (ring->bf_enabled && desc_size <= MAX_BF && !bounce && !vlan_tag) { | |
| 714 | + if (ring->bf_enabled && desc_size <= MAX_BF && !bounce && !vlan_tx_tag_present(skb)) { | |
| 716 | 715 | *(__be32 *) (&tx_desc->ctrl.vlan_tag) |= cpu_to_be32(ring->doorbell_qpn); |
| 717 | 716 | op_own |= htonl((bf_index & 0xffff) << 8); |
| 718 | 717 | /* Ensure new descirptor hits memory |
| @@ -329,9 +329,6 @@ int set_and_calc_slave_port_state(struct mlx4_dev *dev, int slave, · 328 unmodified lines | ||
| 329 | 329 | ctx = &priv->mfunc.master.slave_state[slave]; |
| 330 | 330 | spin_lock_irqsave(&ctx->lock, flags); |
| 331 | 331 | |
| 332 | − mlx4_dbg(dev, "%s: slave: %d, current state: %d new event :%d\n", | |
| 333 | − __func__, slave, cur_state, event); | |
| 334 | − | |
| 335 | 332 | switch (cur_state) { |
| 336 | 333 | case SLAVE_PORT_DOWN: |
| 337 | 334 | if (MLX4_PORT_STATE_DEV_EVENT_PORT_UP == event) |
| @@ -366,9 +363,6 @@ int set_and_calc_slave_port_state(struct mlx4_dev *dev, int slave, · 28 unmodified lines | ||
| 366 | 363 | goto out; |
| 367 | 364 | } |
| 368 | 365 | ret = mlx4_get_slave_port_state(dev, slave, port); |
| 369 | − mlx4_dbg(dev, "%s: slave: %d, current state: %d new event" | |
| 370 | − " :%d gen_event: %d\n", | |
| 371 | − __func__, slave, cur_state, event, *gen_event); | |
| 372 | 366 | |
| 373 | 367 | out: |
| 374 | 368 | spin_unlock_irqrestore(&ctx->lock, flags); |
| @@ -843,6 +837,18 @@ static void __iomem *mlx4_get_eq_uar(struct mlx4_dev *dev, struct mlx4_eq *eq) · 468 unmodified lines | ||
| 843 | 837 | return priv->eq_table.uar_map[index] + 0x800 + 8 * (eq->eqn % 4); |
| 844 | 838 | } |
| 845 | 839 | |
| 840 | +static void mlx4_unmap_uar(struct mlx4_dev *dev) | |
| 841 | +{ | |
| 842 | + struct mlx4_priv *priv = mlx4_priv(dev); | |
| 843 | + int i; | |
| 844 | + | |
| 845 | + for (i = 0; i < mlx4_num_eq_uar(dev); ++i) | |
| 846 | + if (priv->eq_table.uar_map[i]) { | |
| 847 | + iounmap(priv->eq_table.uar_map[i]); | |
| 848 | + priv->eq_table.uar_map[i] = NULL; | |
| 849 | + } | |
| 850 | +} | |
| 851 | + | |
| 846 | 852 | static int mlx4_create_eq(struct mlx4_dev *dev, int nent, |
| 847 | 853 | u8 intr, struct mlx4_eq *eq) |
| 848 | 854 | { |
| @@ -1207,6 +1213,7 @@ err_out_unmap: · 358 unmodified lines | ||
| 1207 | 1213 | mlx4_free_irqs(dev); |
| 1208 | 1214 | |
| 1209 | 1215 | err_out_bitmap: |
| 1216 | + mlx4_unmap_uar(dev); | |
| 1210 | 1217 | mlx4_bitmap_cleanup(&priv->eq_table.bitmap); |
| 1211 | 1218 | |
| 1212 | 1219 | err_out_free: |
| @@ -1231,10 +1238,7 @@ void mlx4_cleanup_eq_table(struct mlx4_dev *dev) · 18 unmodified lines | ||
| 1231 | 1238 | if (!mlx4_is_slave(dev)) |
| 1232 | 1239 | mlx4_unmap_clr_int(dev); |
| 1233 | 1240 | |
| 1234 | − for (i = 0; i < mlx4_num_eq_uar(dev); ++i) | |
| 1235 | − if (priv->eq_table.uar_map[i]) | |
| 1236 | − iounmap(priv->eq_table.uar_map[i]); | |
| 1237 | − | |
| 1241 | + mlx4_unmap_uar(dev); | |
| 1238 | 1242 | mlx4_bitmap_cleanup(&priv->eq_table.bitmap); |
| 1239 | 1243 | |
| 1240 | 1244 | kfree(priv->eq_table.uar_map); |
| @@ -1405,7 +1405,10 @@ unmap_bf: · 1404 unmodified lines | ||
| 1405 | 1405 | unmap_bf_area(dev); |
| 1406 | 1406 | |
| 1407 | 1407 | err_close: |
| 1408 | − mlx4_close_hca(dev); | |
| 1408 | + if (mlx4_is_slave(dev)) | |
| 1409 | + mlx4_slave_exit(dev); | |
| 1410 | + else | |
| 1411 | + mlx4_CLOSE_HCA(dev, 0); | |
| 1409 | 1412 | |
| 1410 | 1413 | err_free_icm: |
| 1411 | 1414 | if (!mlx4_is_slave(dev)) |
| @@ -330,9 +330,6 @@ static void update_pkey_index(struct mlx4_dev *dev, int slave, · 329 unmodified lines | ||
| 330 | 330 | |
| 331 | 331 | new_index = priv->virt2phys_pkey[slave][port - 1][orig_index]; |
| 332 | 332 | *(u8 *)(inbox->buf + 35) = new_index; |
| 333 | − | |
| 334 | − mlx4_dbg(dev, "port = %d, orig pkey index = %d, " | |
| 335 | − "new pkey index = %d\n", port, orig_index, new_index); | |
| 336 | 333 | } |
| 337 | 334 | |
| 338 | 335 | static void update_gid(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *inbox, |
| @@ -351,9 +348,6 @@ static void update_gid(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *inbox, · 12 unmodified lines | ||
| 351 | 348 | if (optpar & MLX4_QP_OPTPAR_ALT_ADDR_PATH) |
| 352 | 349 | qp_ctx->alt_path.mgid_index = slave & 0x7F; |
| 353 | 350 | } |
| 354 | − | |
| 355 | − mlx4_dbg(dev, "slave %d, new gid index: 0x%x ", | |
| 356 | − slave, qp_ctx->pri_path.mgid_index); | |
| 357 | 351 | } |
| 358 | 352 | |
| 359 | 353 | static int mpt_mask(struct mlx4_dev *dev) |
| @@ -5407,8 +5407,8 @@ static int netdev_close(struct net_device *dev) · 5406 unmodified lines | ||
| 5407 | 5407 | /* Delay for receive task to stop scheduling itself. */ |
| 5408 | 5408 | msleep(2000 / HZ); |
| 5409 | 5409 | |
| 5410 | − tasklet_disable(&hw_priv->rx_tasklet); | |
| 5411 | − tasklet_disable(&hw_priv->tx_tasklet); | |
| 5410 | + tasklet_kill(&hw_priv->rx_tasklet); | |
| 5411 | + tasklet_kill(&hw_priv->tx_tasklet); | |
| 5412 | 5412 | free_irq(dev->irq, hw_priv->dev); |
| 5413 | 5413 | |
| 5414 | 5414 | transmit_cleanup(hw_priv, 0); |
| @@ -5459,8 +5459,10 @@ static int prepare_hardware(struct net_device *dev) · 44 unmodified lines | ||
| 5459 | 5459 | rc = request_irq(dev->irq, netdev_intr, IRQF_SHARED, dev->name, dev); |
| 5460 | 5460 | if (rc) |
| 5461 | 5461 | return rc; |
| 5462 | − tasklet_enable(&hw_priv->rx_tasklet); | |
| 5463 | − tasklet_enable(&hw_priv->tx_tasklet); | |
| 5462 | + tasklet_init(&hw_priv->rx_tasklet, rx_proc_task, | |
| 5463 | + (unsigned long) hw_priv); | |
| 5464 | + tasklet_init(&hw_priv->tx_tasklet, tx_proc_task, | |
| 5465 | + (unsigned long) hw_priv); | |
| 5464 | 5466 | |
| 5465 | 5467 | hw->promiscuous = 0; |
| 5466 | 5468 | hw->all_multi = 0; |
| @@ -7033,16 +7035,6 @@ static int __devinit pcidev_init(struct pci_dev *pdev, · 1566 unmodified lines | ||
| 7033 | 7035 | spin_lock_init(&hw_priv->hwlock); |
| 7034 | 7036 | mutex_init(&hw_priv->lock); |
| 7035 | 7037 | |
| 7036 | − /* tasklet is enabled. */ | |
| 7037 | − tasklet_init(&hw_priv->rx_tasklet, rx_proc_task, | |
| 7038 | − (unsigned long) hw_priv); | |
| 7039 | − tasklet_init(&hw_priv->tx_tasklet, tx_proc_task, | |
| 7040 | − (unsigned long) hw_priv); | |
| 7041 | − | |
| 7042 | − /* tasklet_enable will decrement the atomic counter. */ | |
| 7043 | − tasklet_disable(&hw_priv->rx_tasklet); | |
| 7044 | − tasklet_disable(&hw_priv->tx_tasklet); | |
| 7045 | − | |
| 7046 | 7038 | for (i = 0; i < TOTAL_PORT_NUM; i++) |
| 7047 | 7039 | init_waitqueue_head(&hw_priv->counter[i].counter); |
| 7048 | 7040 | |
| @@ -1524,6 +1524,7 @@ static int lpc_eth_drv_remove(struct platform_device *pdev) · 1523 unmodified lines | ||
| 1524 | 1524 | pldat->dma_buff_base_p); |
| 1525 | 1525 | free_irq(ndev->irq, ndev); |
| 1526 | 1526 | iounmap(pldat->net_base); |
| 1527 | + mdiobus_unregister(pldat->mii_bus); | |
| 1527 | 1528 | mdiobus_free(pldat->mii_bus); |
| 1528 | 1529 | clk_disable(pldat->clk); |
| 1529 | 1530 | clk_put(pldat->clk); |
| @@ -338,26 +338,6 @@ static void pch_gbe_wait_clr_bit(void *reg, u32 bit) · 337 unmodified lines | ||
| 338 | 338 | pr_err("Error: busy bit is not cleared\n"); |
| 339 | 339 | } |
| 340 | 340 | |
| 341 | −/** | |
| 342 | − * pch_gbe_wait_clr_bit_irq - Wait to clear a bit for interrupt context | |
| 343 | − * @reg: Pointer of register | |
| 344 | − * @busy: Busy bit | |
| 345 | − */ | |
| 346 | −static int pch_gbe_wait_clr_bit_irq(void *reg, u32 bit) | |
| 347 | −{ | |
| 348 | − u32 tmp; | |
| 349 | − int ret = -1; | |
| 350 | − /* wait busy */ | |
| 351 | − tmp = 20; | |
| 352 | − while ((ioread32(reg) & bit) && --tmp) | |
| 353 | − udelay(5); | |
| 354 | − if (!tmp) | |
| 355 | − pr_err("Error: busy bit is not cleared\n"); | |
| 356 | − else | |
| 357 | − ret = 0; | |
| 358 | − return ret; | |
| 359 | −} | |
| 360 | − | |
| 361 | 341 | /** |
| 362 | 342 | * pch_gbe_mac_mar_set - Set MAC address register |
| 363 | 343 | * @hw: Pointer to the HW structure |
| @@ -409,15 +389,20 @@ static void pch_gbe_mac_reset_hw(struct pch_gbe_hw *hw) · 45 unmodified lines | ||
| 409 | 389 | return; |
| 410 | 390 | } |
| 411 | 391 | |
| 412 | −static void pch_gbe_mac_reset_rx(struct pch_gbe_hw *hw) | |
| 392 | +static void pch_gbe_disable_mac_rx(struct pch_gbe_hw *hw) | |
| 413 | 393 | { |
| 414 | − /* Read the MAC addresses. and store to the private data */ | |
| 415 | − pch_gbe_mac_read_mac_addr(hw); | |
| 416 | − iowrite32(PCH_GBE_RX_RST, &hw->reg->RESET); | |
| 417 | − pch_gbe_wait_clr_bit_irq(&hw->reg->RESET, PCH_GBE_RX_RST); | |
| 418 | − /* Setup the MAC addresses */ | |
| 419 | − pch_gbe_mac_mar_set(hw, hw->mac.addr, 0); | |
| 420 | − return; | |
| 394 | + u32 rctl; | |
| 395 | + /* Disables Receive MAC */ | |
| 396 | + rctl = ioread32(&hw->reg->MAC_RX_EN); | |
| 397 | + iowrite32((rctl & ~PCH_GBE_MRE_MAC_RX_EN), &hw->reg->MAC_RX_EN); | |
| 398 | +} | |
| 399 | + | |
| 400 | +static void pch_gbe_enable_mac_rx(struct pch_gbe_hw *hw) | |
| 401 | +{ | |
| 402 | + u32 rctl; | |
| 403 | + /* Enables Receive MAC */ | |
| 404 | + rctl = ioread32(&hw->reg->MAC_RX_EN); | |
| 405 | + iowrite32((rctl | PCH_GBE_MRE_MAC_RX_EN), &hw->reg->MAC_RX_EN); | |
| 421 | 406 | } |
| 422 | 407 | |
| 423 | 408 | /** |
| @@ -913,7 +898,7 @@ static void pch_gbe_setup_rctl(struct pch_gbe_adapter *adapter) · 489 unmodified lines | ||
| 913 | 898 | static void pch_gbe_configure_rx(struct pch_gbe_adapter *adapter) |
| 914 | 899 | { |
| 915 | 900 | struct pch_gbe_hw *hw = &adapter->hw; |
| 916 | − u32 rdba, rdlen, rctl, rxdma; | |
| 901 | + u32 rdba, rdlen, rxdma; | |
| 917 | 902 | |
| 918 | 903 | pr_debug("dma adr = 0x%08llx size = 0x%08x\n", |
| 919 | 904 | (unsigned long long)adapter->rx_ring->dma, |
| @@ -921,9 +906,7 @@ static void pch_gbe_configure_rx(struct pch_gbe_adapter *adapter) · 1 unmodified line | ||
| 921 | 906 | |
| 922 | 907 | pch_gbe_mac_force_mac_fc(hw); |
| 923 | 908 | |
| 924 | − /* Disables Receive MAC */ | |
| 925 | − rctl = ioread32(&hw->reg->MAC_RX_EN); | |
| 926 | − iowrite32((rctl & ~PCH_GBE_MRE_MAC_RX_EN), &hw->reg->MAC_RX_EN); | |
| 909 | + pch_gbe_disable_mac_rx(hw); | |
| 927 | 910 | |
| 928 | 911 | /* Disables Receive DMA */ |
| 929 | 912 | rxdma = ioread32(&hw->reg->DMA_CTRL); |
| @@ -1316,38 +1299,17 @@ void pch_gbe_update_stats(struct pch_gbe_adapter *adapter) · 386 unmodified lines | ||
| 1316 | 1299 | spin_unlock_irqrestore(&adapter->stats_lock, flags); |
| 1317 | 1300 | } |
| 1318 | 1301 | |
| 1319 | −static void pch_gbe_stop_receive(struct pch_gbe_adapter *adapter) | |
| 1302 | +static void pch_gbe_disable_dma_rx(struct pch_gbe_hw *hw) | |
| 1320 | 1303 | { |
| 1321 | − struct pch_gbe_hw *hw = &adapter->hw; | |
| 1322 | 1304 | u32 rxdma; |
| 1323 | − u16 value; | |
| 1324 | − int ret; | |
| 1325 | 1305 | |
| 1326 | 1306 | /* Disable Receive DMA */ |
| 1327 | 1307 | rxdma = ioread32(&hw->reg->DMA_CTRL); |
| 1328 | 1308 | rxdma &= ~PCH_GBE_RX_DMA_EN; |
| 1329 | 1309 | iowrite32(rxdma, &hw->reg->DMA_CTRL); |
| 1330 | − /* Wait Rx DMA BUS is IDLE */ | |
| 1331 | − ret = pch_gbe_wait_clr_bit_irq(&hw->reg->RX_DMA_ST, PCH_GBE_IDLE_CHECK); | |
| 1332 | − if (ret) { | |
| 1333 | − /* Disable Bus master */ | |
| 1334 | − pci_read_config_word(adapter->pdev, PCI_COMMAND, &value); | |
| 1335 | − value &= ~PCI_COMMAND_MASTER; | |
| 1336 | − pci_write_config_word(adapter->pdev, PCI_COMMAND, value); | |
| 1337 | − /* Stop Receive */ | |
| 1338 | − pch_gbe_mac_reset_rx(hw); | |
| 1339 | − /* Enable Bus master */ | |
| 1340 | − value |= PCI_COMMAND_MASTER; | |
| 1341 | − pci_write_config_word(adapter->pdev, PCI_COMMAND, value); | |
| 1342 | − } else { | |
| 1343 | − /* Stop Receive */ | |
| 1344 | − pch_gbe_mac_reset_rx(hw); | |
| 1345 | − } | |
| 1346 | − /* reprogram multicast address register after reset */ | |
| 1347 | − pch_gbe_set_multi(adapter->netdev); | |
| 1348 | 1310 | } |
| 1349 | 1311 | |
| 1350 | −static void pch_gbe_start_receive(struct pch_gbe_hw *hw) | |
| 1312 | +static void pch_gbe_enable_dma_rx(struct pch_gbe_hw *hw) | |
| 1351 | 1313 | { |
| 1352 | 1314 | u32 rxdma; |
| 1353 | 1315 | |
| @@ -1355,9 +1317,6 @@ static void pch_gbe_start_receive(struct pch_gbe_hw *hw) · 1 unmodified line | ||
| 1355 | 1317 | rxdma = ioread32(&hw->reg->DMA_CTRL); |
| 1356 | 1318 | rxdma |= PCH_GBE_RX_DMA_EN; |
| 1357 | 1319 | iowrite32(rxdma, &hw->reg->DMA_CTRL); |
| 1358 | − /* Enables Receive */ | |
| 1359 | − iowrite32(PCH_GBE_MRE_MAC_RX_EN, &hw->reg->MAC_RX_EN); | |
| 1360 | − return; | |
| 1361 | 1320 | } |
| 1362 | 1321 | |
| 1363 | 1322 | /** |
| @@ -1393,7 +1352,7 @@ static irqreturn_t pch_gbe_intr(int irq, void *data) · 29 unmodified lines | ||
| 1393 | 1352 | int_en = ioread32(&hw->reg->INT_EN); |
| 1394 | 1353 | iowrite32((int_en & ~PCH_GBE_INT_RX_FIFO_ERR), |
| 1395 | 1354 | &hw->reg->INT_EN); |
| 1396 | − pch_gbe_stop_receive(adapter); | |
| 1355 | + pch_gbe_disable_dma_rx(&adapter->hw); | |
| 1397 | 1356 | int_st |= ioread32(&hw->reg->INT_ST); |
| 1398 | 1357 | int_st = int_st & ioread32(&hw->reg->INT_EN); |
| 1399 | 1358 | } |
| @@ -1971,12 +1930,12 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter) · 571 unmodified lines | ||
| 1971 | 1930 | struct net_device *netdev = adapter->netdev; |
| 1972 | 1931 | struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring; |
| 1973 | 1932 | struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring; |
| 1974 | − int err; | |
| 1933 | + int err = -EINVAL; | |
| 1975 | 1934 | |
| 1976 | 1935 | /* Ensure we have a valid MAC */ |
| 1977 | 1936 | if (!is_valid_ether_addr(adapter->hw.mac.addr)) { |
| 1978 | 1937 | pr_err("Error: Invalid MAC address\n"); |
| 1979 | − return -EINVAL; | |
| 1938 | + goto out; | |
| 1980 | 1939 | } |
| 1981 | 1940 | |
| 1982 | 1941 | /* hardware has been reset, we need to reload some things */ |
| @@ -1989,18 +1948,19 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter) · 6 unmodified lines | ||
| 1989 | 1948 | |
| 1990 | 1949 | err = pch_gbe_request_irq(adapter); |
| 1991 | 1950 | if (err) { |
| 1992 | − pr_err("Error: can't bring device up\n"); | |
| 1993 | − return err; | |
| 1951 | + pr_err("Error: can't bring device up - irq request failed\n"); | |
| 1952 | + goto out; | |
| 1994 | 1953 | } |
| 1995 | 1954 | err = pch_gbe_alloc_rx_buffers_pool(adapter, rx_ring, rx_ring->count); |
| 1996 | 1955 | if (err) { |
| 1997 | − pr_err("Error: can't bring device up\n"); | |
| 1998 | − return err; | |
| 1956 | + pr_err("Error: can't bring device up - alloc rx buffers pool failed\n"); | |
| 1957 | + goto freeirq; | |
| 1999 | 1958 | } |
| 2000 | 1959 | pch_gbe_alloc_tx_buffers(adapter, tx_ring); |
| 2001 | 1960 | pch_gbe_alloc_rx_buffers(adapter, rx_ring, rx_ring->count); |
| 2002 | 1961 | adapter->tx_queue_len = netdev->tx_queue_len; |
| 2003 | − pch_gbe_start_receive(&adapter->hw); | |
| 1962 | + pch_gbe_enable_dma_rx(&adapter->hw); | |
| 1963 | + pch_gbe_enable_mac_rx(&adapter->hw); | |
| 2004 | 1964 | |
| 2005 | 1965 | mod_timer(&adapter->watchdog_timer, jiffies); |
| 2006 | 1966 | |
| @@ -2009,6 +1969,11 @@ int pch_gbe_up(struct pch_gbe_adapter *adapter) · 2 unmodified lines | ||
| 2009 | 1969 | netif_start_queue(adapter->netdev); |
| 2010 | 1970 | |
| 2011 | 1971 | return 0; |
| 1972 | + | |
| 1973 | +freeirq: | |
| 1974 | + pch_gbe_free_irq(adapter); | |
| 1975 | +out: | |
| 1976 | + return err; | |
| 2012 | 1977 | } |
| 2013 | 1978 | |
| 2014 | 1979 | /** |
| @@ -2405,7 +2370,6 @@ static int pch_gbe_napi_poll(struct napi_struct *napi, int budget) · 390 unmodified lines | ||
| 2405 | 2370 | int work_done = 0; |
| 2406 | 2371 | bool poll_end_flag = false; |
| 2407 | 2372 | bool cleaned = false; |
| 2408 | − u32 int_en; | |
| 2409 | 2373 | |
| 2410 | 2374 | pr_debug("budget : %d\n", budget); |
| 2411 | 2375 | |
| @@ -2422,19 +2386,13 @@ static int pch_gbe_napi_poll(struct napi_struct *napi, int budget) · 10 unmodified lines | ||
| 2422 | 2386 | |
| 2423 | 2387 | if (poll_end_flag) { |
| 2424 | 2388 | napi_complete(napi); |
| 2425 | − if (adapter->rx_stop_flag) { | |
| 2426 | − adapter->rx_stop_flag = false; | |
| 2427 | − pch_gbe_start_receive(&adapter->hw); | |
| 2428 | − } | |
| 2429 | 2389 | pch_gbe_irq_enable(adapter); |
| 2430 | − } else | |
| 2431 | − if (adapter->rx_stop_flag) { | |
| 2432 | − adapter->rx_stop_flag = false; | |
| 2433 | − pch_gbe_start_receive(&adapter->hw); | |
| 2434 | − int_en = ioread32(&adapter->hw.reg->INT_EN); | |
| 2435 | − iowrite32((int_en | PCH_GBE_INT_RX_FIFO_ERR), | |
| 2436 | − &adapter->hw.reg->INT_EN); | |
| 2437 | − } | |
| 2390 | + } | |
| 2391 | + | |
| 2392 | + if (adapter->rx_stop_flag) { | |
| 2393 | + adapter->rx_stop_flag = false; | |
| 2394 | + pch_gbe_enable_dma_rx(&adapter->hw); | |
| 2395 | + } | |
| 2438 | 2396 | |
| 2439 | 2397 | pr_debug("poll_end_flag : %d work_done : %d budget : %d\n", |
| 2440 | 2398 | poll_end_flag, work_done, budget); |
| @@ -2525,6 +2525,13 @@ static int ql_alloc_net_req_rsp_queues(struct ql3_adapter *qdev) · 2524 unmodified lines | ||
| 2525 | 2525 | qdev->req_q_size = |
| 2526 | 2526 | (u32) (NUM_REQ_Q_ENTRIES * sizeof(struct ob_mac_iocb_req)); |
| 2527 | 2527 | |
| 2528 | + qdev->rsp_q_size = NUM_RSP_Q_ENTRIES * sizeof(struct net_rsp_iocb); | |
| 2529 | + | |
| 2530 | + /* The barrier is required to ensure request and response queue | |
| 2531 | + * addr writes to the registers. | |
| 2532 | + */ | |
| 2533 | + wmb(); | |
| 2534 | + | |
| 2528 | 2535 | qdev->req_q_virt_addr = |
| 2529 | 2536 | pci_alloc_consistent(qdev->pdev, |
| 2530 | 2537 | (size_t) qdev->req_q_size, |
| @@ -2536,8 +2543,6 @@ static int ql_alloc_net_req_rsp_queues(struct ql3_adapter *qdev) · 5 unmodified lines | ||
| 2536 | 2543 | return -ENOMEM; |
| 2537 | 2544 | } |
| 2538 | 2545 | |
| 2539 | − qdev->rsp_q_size = NUM_RSP_Q_ENTRIES * sizeof(struct net_rsp_iocb); | |
| 2540 | − | |
| 2541 | 2546 | qdev->rsp_q_virt_addr = |
| 2542 | 2547 | pci_alloc_consistent(qdev->pdev, |
| 2543 | 2548 | (size_t) qdev->rsp_q_size, |
| @@ -979,17 +979,6 @@ static void cp_init_hw (struct cp_private *cp) · 978 unmodified lines | ||
| 979 | 979 | cpw32_f (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0))); |
| 980 | 980 | cpw32_f (MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4))); |
| 981 | 981 | |
| 982 | − cpw32_f(HiTxRingAddr, 0); | |
| 983 | − cpw32_f(HiTxRingAddr + 4, 0); | |
| 984 | − | |
| 985 | − ring_dma = cp->ring_dma; | |
| 986 | − cpw32_f(RxRingAddr, ring_dma & 0xffffffff); | |
| 987 | − cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16); | |
| 988 | − | |
| 989 | − ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE; | |
| 990 | − cpw32_f(TxRingAddr, ring_dma & 0xffffffff); | |
| 991 | − cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16); | |
| 992 | − | |
| 993 | 982 | cp_start_hw(cp); |
| 994 | 983 | cpw8(TxThresh, 0x06); /* XXX convert magic num to a constant */ |
| 995 | 984 | |
| @@ -1003,6 +992,17 @@ static void cp_init_hw (struct cp_private *cp) · 7 unmodified lines | ||
| 1003 | 992 | |
| 1004 | 993 | cpw8(Config5, cpr8(Config5) & PMEStatus); |
| 1005 | 994 | |
| 995 | + cpw32_f(HiTxRingAddr, 0); | |
| 996 | + cpw32_f(HiTxRingAddr + 4, 0); | |
| 997 | + | |
| 998 | + ring_dma = cp->ring_dma; | |
| 999 | + cpw32_f(RxRingAddr, ring_dma & 0xffffffff); | |
| 1000 | + cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16); | |
| 1001 | + | |
| 1002 | + ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE; | |
| 1003 | + cpw32_f(TxRingAddr, ring_dma & 0xffffffff); | |
| 1004 | + cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16); | |
| 1005 | + | |
| 1006 | 1006 | cpw16(MultiIntr, 0); |
| 1007 | 1007 | |
| 1008 | 1008 | cpw8_f(Cfg9346, Cfg9346_Lock); |
| @@ -1060,17 +1060,22 @@ static int cp_init_rings (struct cp_private *cp) · 51 unmodified lines | ||
| 1060 | 1060 | |
| 1061 | 1061 | static int cp_alloc_rings (struct cp_private *cp) |
| 1062 | 1062 | { |
| 1063 | + struct device *d = &cp->pdev->dev; | |
| 1063 | 1064 | void *mem; |
| 1065 | + int rc; | |
| 1064 | 1066 | |
| 1065 | − mem = dma_alloc_coherent(&cp->pdev->dev, CP_RING_BYTES, | |
| 1066 | − &cp->ring_dma, GFP_KERNEL); | |
| 1067 | + mem = dma_alloc_coherent(d, CP_RING_BYTES, &cp->ring_dma, GFP_KERNEL); | |
| 1067 | 1068 | if (!mem) |
| 1068 | 1069 | return -ENOMEM; |
| 1069 | 1070 | |
| 1070 | 1071 | cp->rx_ring = mem; |
| 1071 | 1072 | cp->tx_ring = &cp->rx_ring[CP_RX_RING_SIZE]; |
| 1072 | 1073 | |
| 1073 | − return cp_init_rings(cp); | |
| 1074 | + rc = cp_init_rings(cp); | |
| 1075 | + if (rc < 0) | |
| 1076 | + dma_free_coherent(d, CP_RING_BYTES, cp->rx_ring, cp->ring_dma); | |
| 1077 | + | |
| 1078 | + return rc; | |
| 1074 | 1079 | } |
| 1075 | 1080 | |
| 1076 | 1081 | static void cp_clean_rings (struct cp_private *cp) |
| @@ -3827,6 +3827,8 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) · 3826 unmodified lines | ||
| 3827 | 3827 | void __iomem *ioaddr = tp->mmio_addr; |
| 3828 | 3828 | |
| 3829 | 3829 | switch (tp->mac_version) { |
| 3830 | + case RTL_GIGA_MAC_VER_25: | |
| 3831 | + case RTL_GIGA_MAC_VER_26: | |
| 3830 | 3832 | case RTL_GIGA_MAC_VER_29: |
| 3831 | 3833 | case RTL_GIGA_MAC_VER_30: |
| 3832 | 3834 | case RTL_GIGA_MAC_VER_32: |
| @@ -4519,6 +4521,9 @@ static void rtl_set_rx_mode(struct net_device *dev) · 686 unmodified lines | ||
| 4519 | 4521 | mc_filter[1] = swab32(data); |
| 4520 | 4522 | } |
| 4521 | 4523 | |
| 4524 | + if (tp->mac_version == RTL_GIGA_MAC_VER_35) | |
| 4525 | + mc_filter[1] = mc_filter[0] = 0xffffffff; | |
| 4526 | + | |
| 4522 | 4527 | RTL_W32(MAR0 + 4, mc_filter[1]); |
| 4523 | 4528 | RTL_W32(MAR0 + 0, mc_filter[0]); |
| 4524 | 4529 | |
| @@ -2479,7 +2479,7 @@ static int sis900_resume(struct pci_dev *pci_dev) · 2478 unmodified lines | ||
| 2479 | 2479 | netif_start_queue(net_dev); |
| 2480 | 2480 | |
| 2481 | 2481 | /* Workaround for EDB */ |
| 2482 | − sis900_set_mode(ioaddr, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED); | |
| 2482 | + sis900_set_mode(sis_priv, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED); | |
| 2483 | 2483 | |
| 2484 | 2484 | /* Enable all known interrupts by setting the interrupt mask. */ |
| 2485 | 2485 | sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE); |
| @@ -2110,7 +2110,7 @@ static void __devinit smsc911x_read_mac_address(struct net_device *dev) · 2109 unmodified lines | ||
| 2110 | 2110 | static int __devinit smsc911x_init(struct net_device *dev) |
| 2111 | 2111 | { |
| 2112 | 2112 | struct smsc911x_data *pdata = netdev_priv(dev); |
| 2113 | − unsigned int byte_test; | |
| 2113 | + unsigned int byte_test, mask; | |
| 2114 | 2114 | unsigned int to = 100; |
| 2115 | 2115 | |
| 2116 | 2116 | SMSC_TRACE(pdata, probe, "Driver Parameters:"); |
| @@ -2130,9 +2130,22 @@ static int __devinit smsc911x_init(struct net_device *dev) · 13 unmodified lines | ||
| 2130 | 2130 | /* |
| 2131 | 2131 | * poll the READY bit in PMT_CTRL. Any other access to the device is |
| 2132 | 2132 | * forbidden while this bit isn't set. Try for 100ms |
| 2133 | + * | |
| 2134 | + * Note that this test is done before the WORD_SWAP register is | |
| 2135 | + * programmed. So in some configurations the READY bit is at 16 before | |
| 2136 | + * WORD_SWAP is written to. This issue is worked around by waiting | |
| 2137 | + * until either bit 0 or bit 16 gets set in PMT_CTRL. | |
| 2138 | + * | |
| 2139 | + * SMSC has confirmed that checking bit 16 (marked as reserved in | |
| 2140 | + * the datasheet) is fine since these bits "will either never be set | |
| 2141 | + * or can only go high after READY does (so also indicate the device | |
| 2142 | + * is ready)". | |
| 2133 | 2143 | */ |
| 2134 | − while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_) && --to) | |
| 2144 | + | |
| 2145 | + mask = PMT_CTRL_READY_ | swahw32(PMT_CTRL_READY_); | |
| 2146 | + while (!(smsc911x_reg_read(pdata, PMT_CTRL) & mask) && --to) | |
| 2135 | 2147 | udelay(1000); |
| 2148 | + | |
| 2136 | 2149 | if (to == 0) { |
| 2137 | 2150 | pr_err("Device not READY in 100ms aborting\n"); |
| 2138 | 2151 | return -ENODEV; |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | config NET_VENDOR_TI |
| 6 | 6 | bool "Texas Instruments (TI) devices" |
| 7 | 7 | default y |
| 8 | − depends on PCI || EISA || AR7 || (ARM && (ARCH_DAVINCI || ARCH_OMAP3)) | |
| 8 | + depends on PCI || EISA || AR7 || (ARM && (ARCH_DAVINCI || ARCH_OMAP3 || SOC_AM33XX)) | |
| 9 | 9 | ---help--- |
| 10 | 10 | If you have a network (Ethernet) card belonging to this class, say Y |
| 11 | 11 | and read the Ethernet-HOWTO, available from |
| @@ -917,7 +917,7 @@ static int tile_net_setup_interrupts(struct net_device *dev) · 916 unmodified lines | ||
| 917 | 917 | ingress_irq = rc; |
| 918 | 918 | tile_irq_activate(ingress_irq, TILE_IRQ_PERCPU); |
| 919 | 919 | rc = request_irq(ingress_irq, tile_net_handle_ingress_irq, |
| 920 | − 0, NULL, NULL); | |
| 920 | + 0, "tile_net", NULL); | |
| 921 | 921 | if (rc != 0) { |
| 922 | 922 | netdev_err(dev, "request_irq failed: %d\n", rc); |
| 923 | 923 | destroy_irq(ingress_irq); |
| @@ -1334,11 +1334,11 @@ static int tso_count_edescs(struct sk_buff *skb) · 410 unmodified lines | ||
| 1334 | 1334 | { |
| 1335 | 1335 | struct skb_shared_info *sh = skb_shinfo(skb); |
| 1336 | 1336 | unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); |
| 1337 | − unsigned int data_len = skb->data_len + skb->hdr_len - sh_len; | |
| 1337 | + unsigned int data_len = skb->len - sh_len; | |
| 1338 | 1338 | unsigned int p_len = sh->gso_size; |
| 1339 | 1339 | long f_id = -1; /* id of the current fragment */ |
| 1340 | − long f_size = skb->hdr_len; /* size of the current fragment */ | |
| 1341 | − long f_used = sh_len; /* bytes used from the current fragment */ | |
| 1340 | + long f_size = skb_headlen(skb) - sh_len; /* current fragment size */ | |
| 1341 | + long f_used = 0; /* bytes used from the current fragment */ | |
| 1342 | 1342 | long n; /* size of the current piece of payload */ |
| 1343 | 1343 | int num_edescs = 0; |
| 1344 | 1344 | int segment; |
| @@ -1353,7 +1353,7 @@ static int tso_count_edescs(struct sk_buff *skb) · 8 unmodified lines | ||
| 1353 | 1353 | /* Advance as needed. */ |
| 1354 | 1354 | while (f_used >= f_size) { |
| 1355 | 1355 | f_id++; |
| 1356 | − f_size = sh->frags[f_id].size; | |
| 1356 | + f_size = skb_frag_size(&sh->frags[f_id]); | |
| 1357 | 1357 | f_used = 0; |
| 1358 | 1358 | } |
| 1359 | 1359 | |
| @@ -1384,13 +1384,13 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers, · 24 unmodified lines | ||
| 1384 | 1384 | struct iphdr *ih; |
| 1385 | 1385 | struct tcphdr *th; |
| 1386 | 1386 | unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); |
| 1387 | − unsigned int data_len = skb->data_len + skb->hdr_len - sh_len; | |
| 1387 | + unsigned int data_len = skb->len - sh_len; | |
| 1388 | 1388 | unsigned char *data = skb->data; |
| 1389 | 1389 | unsigned int ih_off, th_off, p_len; |
| 1390 | 1390 | unsigned int isum_seed, tsum_seed, id, seq; |
| 1391 | 1391 | long f_id = -1; /* id of the current fragment */ |
| 1392 | − long f_size = skb->hdr_len; /* size of the current fragment */ | |
| 1393 | − long f_used = sh_len; /* bytes used from the current fragment */ | |
| 1392 | + long f_size = skb_headlen(skb) - sh_len; /* current fragment size */ | |
| 1393 | + long f_used = 0; /* bytes used from the current fragment */ | |
| 1394 | 1394 | long n; /* size of the current piece of payload */ |
| 1395 | 1395 | int segment; |
| 1396 | 1396 | |
| @@ -1405,7 +1405,7 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers, · 8 unmodified lines | ||
| 1405 | 1405 | isum_seed = ((0xFFFF - ih->check) + |
| 1406 | 1406 | (0xFFFF - ih->tot_len) + |
| 1407 | 1407 | (0xFFFF - ih->id)); |
| 1408 | − tsum_seed = th->check + (0xFFFF ^ htons(sh_len + data_len)); | |
| 1408 | + tsum_seed = th->check + (0xFFFF ^ htons(skb->len)); | |
| 1409 | 1409 | id = ntohs(ih->id); |
| 1410 | 1410 | seq = ntohl(th->seq); |
| 1411 | 1411 | |
| @@ -1444,7 +1444,7 @@ static void tso_headers_prepare(struct sk_buff *skb, unsigned char *headers, · 32 unmodified lines | ||
| 1444 | 1444 | /* Advance as needed. */ |
| 1445 | 1445 | while (f_used >= f_size) { |
| 1446 | 1446 | f_id++; |
| 1447 | − f_size = sh->frags[f_id].size; | |
| 1447 | + f_size = skb_frag_size(&sh->frags[f_id]); | |
| 1448 | 1448 | f_used = 0; |
| 1449 | 1449 | } |
| 1450 | 1450 | |
| @@ -1478,14 +1478,14 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, · 27 unmodified lines | ||
| 1478 | 1478 | struct tile_net_priv *priv = netdev_priv(dev); |
| 1479 | 1479 | struct skb_shared_info *sh = skb_shinfo(skb); |
| 1480 | 1480 | unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb); |
| 1481 | − unsigned int data_len = skb->data_len + skb->hdr_len - sh_len; | |
| 1481 | + unsigned int data_len = skb->len - sh_len; | |
| 1482 | 1482 | unsigned int p_len = sh->gso_size; |
| 1483 | 1483 | gxio_mpipe_edesc_t edesc_head = { { 0 } }; |
| 1484 | 1484 | gxio_mpipe_edesc_t edesc_body = { { 0 } }; |
| 1485 | 1485 | long f_id = -1; /* id of the current fragment */ |
| 1486 | − long f_size = skb->hdr_len; /* size of the current fragment */ | |
| 1487 | − long f_used = sh_len; /* bytes used from the current fragment */ | |
| 1488 | − void *f_data = skb->data; | |
| 1486 | + long f_size = skb_headlen(skb) - sh_len; /* current fragment size */ | |
| 1487 | + long f_used = 0; /* bytes used from the current fragment */ | |
| 1488 | + void *f_data = skb->data + sh_len; | |
| 1489 | 1489 | long n; /* size of the current piece of payload */ |
| 1490 | 1490 | unsigned long tx_packets = 0, tx_bytes = 0; |
| 1491 | 1491 | unsigned int csum_start; |
| @@ -1516,15 +1516,18 @@ static void tso_egress(struct net_device *dev, gxio_mpipe_equeue_t *equeue, · 24 unmodified lines | ||
| 1516 | 1516 | |
| 1517 | 1517 | /* Egress the payload. */ |
| 1518 | 1518 | while (p_used < p_len) { |
| 1519 | + void *va; | |
| 1519 | 1520 | |
| 1520 | 1521 | /* Advance as needed. */ |
| 1521 | 1522 | while (f_used >= f_size) { |
| 1522 | 1523 | f_id++; |
| 1523 | − f_size = sh->frags[f_id].size; | |
| 1524 | − f_used = 0; | |
| 1524 | + f_size = skb_frag_size(&sh->frags[f_id]); | |
| 1525 | 1525 | f_data = tile_net_frag_buf(&sh->frags[f_id]); |
| 1526 | + f_used = 0; | |
16 more lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 177 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 190 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 131 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 827 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 112 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 326 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 158 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 262 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 164 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 237 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 588 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 221 lines aren’t shown here.
This diff is large: its 176 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 171 lines aren’t shown here.
This diff is large: its 119 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 225 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 144 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 284 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 253 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 120 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 142 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 222 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 143 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 193 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 151 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 4 lines aren’t shown here.
File renamed without changes.
This diff is large: its 156 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 132 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 145 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 211 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 153 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 178 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 128 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 250 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 139 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 444 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 566 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 148 lines aren’t shown here.
This diff is large: its 144 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 372 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 345 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.