diff options
79 files changed, 6981 insertions, 1310 deletions
diff --git a/Documentation/ABI/testing/dev-kmsg b/Documentation/ABI/testing/dev-kmsg new file mode 100644 index 000000000000..281ecc5f9709 --- /dev/null +++ b/Documentation/ABI/testing/dev-kmsg | |||
@@ -0,0 +1,90 @@ | |||
1 | What: /dev/kmsg | ||
2 | Date: Mai 2012 | ||
3 | KernelVersion: 3.5 | ||
4 | Contact: Kay Sievers <kay@vrfy.org> | ||
5 | Description: The /dev/kmsg character device node provides userspace access | ||
6 | to the kernel's printk buffer. | ||
7 | |||
8 | Injecting messages: | ||
9 | Every write() to the opened device node places a log entry in | ||
10 | the kernel's printk buffer. | ||
11 | |||
12 | The logged line can be prefixed with a <N> syslog prefix, which | ||
13 | carries the syslog priority and facility. The single decimal | ||
14 | prefix number is composed of the 3 lowest bits being the syslog | ||
15 | priority and the higher bits the syslog facility number. | ||
16 | |||
17 | If no prefix is given, the priority number is the default kernel | ||
18 | log priority and the facility number is set to LOG_USER (1). It | ||
19 | is not possible to inject messages from userspace with the | ||
20 | facility number LOG_KERN (0), to make sure that the origin of | ||
21 | the messages can always be reliably determined. | ||
22 | |||
23 | Accessing the buffer: | ||
24 | Every read() from the opened device node receives one record | ||
25 | of the kernel's printk buffer. | ||
26 | |||
27 | The first read() directly following an open() always returns | ||
28 | first message in the buffer; there is no kernel-internal | ||
29 | persistent state; many readers can concurrently open the device | ||
30 | and read from it, without affecting other readers. | ||
31 | |||
32 | Every read() will receive the next available record. If no more | ||
33 | records are available read() will block, or if O_NONBLOCK is | ||
34 | used -EAGAIN returned. | ||
35 | |||
36 | Messages in the record ring buffer get overwritten as whole, | ||
37 | there are never partial messages received by read(). | ||
38 | |||
39 | In case messages get overwritten in the circular buffer while | ||
40 | the device is kept open, the next read() will return -EPIPE, | ||
41 | and the seek position be updated to the next available record. | ||
42 | Subsequent reads() will return available records again. | ||
43 | |||
44 | Unlike the classic syslog() interface, the 64 bit record | ||
45 | sequence numbers allow to calculate the amount of lost | ||
46 | messages, in case the buffer gets overwritten. And they allow | ||
47 | to reconnect to the buffer and reconstruct the read position | ||
48 | if needed, without limiting the interface to a single reader. | ||
49 | |||
50 | The device supports seek with the following parameters: | ||
51 | SEEK_SET, 0 | ||
52 | seek to the first entry in the buffer | ||
53 | SEEK_END, 0 | ||
54 | seek after the last entry in the buffer | ||
55 | SEEK_DATA, 0 | ||
56 | seek after the last record available at the time | ||
57 | the last SYSLOG_ACTION_CLEAR was issued. | ||
58 | |||
59 | The output format consists of a prefix carrying the syslog | ||
60 | prefix including priority and facility, the 64 bit message | ||
61 | sequence number and the monotonic timestamp in microseconds. | ||
62 | The values are separated by a ','. Future extensions might | ||
63 | add more comma separated values before the terminating ';'. | ||
64 | Unknown values should be gracefully ignored. | ||
65 | |||
66 | The human readable text string starts directly after the ';' | ||
67 | and is terminated by a '\n'. Untrusted values derived from | ||
68 | hardware or other facilities are printed, therefore | ||
69 | all non-printable characters in the log message are escaped | ||
70 | by "\x00" C-style hex encoding. | ||
71 | |||
72 | A line starting with ' ', is a continuation line, adding | ||
73 | key/value pairs to the log message, which provide the machine | ||
74 | readable context of the message, for reliable processing in | ||
75 | userspace. | ||
76 | |||
77 | Example: | ||
78 | 7,160,424069;pci_root PNP0A03:00: host bridge window [io 0x0000-0x0cf7] (ignored) | ||
79 | SUBSYSTEM=acpi | ||
80 | DEVICE=+acpi:PNP0A03:00 | ||
81 | 6,339,5140900;NET: Registered protocol family 10 | ||
82 | 30,340,5690716;udevd[80]: starting version 181 | ||
83 | |||
84 | The DEVICE= key uniquely identifies devices the following way: | ||
85 | b12:8 - block dev_t | ||
86 | c127:3 - char dev_t | ||
87 | n8 - netdev ifindex | ||
88 | +sound:card0 - subsystem:devname | ||
89 | |||
90 | Users: dmesg(1), userspace kernel log consumers | ||
diff --git a/Documentation/ABI/testing/sysfs-class-extcon b/Documentation/ABI/testing/sysfs-class-extcon new file mode 100644 index 000000000000..20ab361bd8c6 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-extcon | |||
@@ -0,0 +1,97 @@ | |||
1 | What: /sys/class/extcon/.../ | ||
2 | Date: February 2012 | ||
3 | Contact: MyungJoo Ham <myungjoo.ham@samsung.com> | ||
4 | Description: | ||
5 | Provide a place in sysfs for the extcon objects. | ||
6 | This allows accessing extcon specific variables. | ||
7 | The name of extcon object denoted as ... is the name given | ||
8 | with extcon_dev_register. | ||
9 | |||
10 | One extcon device denotes a single external connector | ||
11 | port. An external connector may have multiple cables | ||
12 | attached simultaneously. Many of docks, cradles, and | ||
13 | accessory cables have such capability. For example, | ||
14 | the 30-pin port of Nuri board (/arch/arm/mach-exynos) | ||
15 | may have both HDMI and Charger attached, or analog audio, | ||
16 | video, and USB cables attached simulteneously. | ||
17 | |||
18 | If there are cables mutually exclusive with each other, | ||
19 | such binary relations may be expressed with extcon_dev's | ||
20 | mutually_exclusive array. | ||
21 | |||
22 | What: /sys/class/extcon/.../name | ||
23 | Date: February 2012 | ||
24 | Contact: MyungJoo Ham <myungjoo.ham@samsung.com> | ||
25 | Description: | ||
26 | The /sys/class/extcon/.../name shows the name of the extcon | ||
27 | object. If the extcon object has an optional callback | ||
28 | "show_name" defined, the callback will provide the name with | ||
29 | this sysfs node. | ||
30 | |||
31 | What: /sys/class/extcon/.../state | ||
32 | Date: February 2012 | ||
33 | Contact: MyungJoo Ham <myungjoo.ham@samsung.com> | ||
34 | Description: | ||
35 | The /sys/class/extcon/.../state shows and stores the cable | ||
36 | attach/detach information of the corresponding extcon object. | ||
37 | If the extcon object has an optional callback "show_state" | ||
38 | defined, the showing function is overriden with the optional | ||
39 | callback. | ||
40 | |||
41 | If the default callback for showing function is used, the | ||
42 | format is like this: | ||
43 | # cat state | ||
44 | USB_OTG=1 | ||
45 | HDMI=0 | ||
46 | TA=1 | ||
47 | EAR_JACK=0 | ||
48 | # | ||
49 | In this example, the extcon device have USB_OTG and TA | ||
50 | cables attached and HDMI and EAR_JACK cables detached. | ||
51 | |||
52 | In order to update the state of an extcon device, enter a hex | ||
53 | state number starting with 0x. | ||
54 | echo 0xHEX > state | ||
55 | |||
56 | This updates the whole state of the extcon dev. | ||
57 | Inputs of all the methods are required to meet the | ||
58 | mutually_exclusive contidions if they exist. | ||
59 | |||
60 | It is recommended to use this "global" state interface if | ||
61 | you need to enter the value atomically. The later state | ||
62 | interface associated with each cable cannot update | ||
63 | multiple cable states of an extcon device simultaneously. | ||
64 | |||
65 | What: /sys/class/extcon/.../cable.x/name | ||
66 | Date: February 2012 | ||
67 | Contact: MyungJoo Ham <myungjoo.ham@samsung.com> | ||
68 | Description: | ||
69 | The /sys/class/extcon/.../cable.x/name shows the name of cable | ||
70 | "x" (integer between 0 and 31) of an extcon device. | ||
71 | |||
72 | What: /sys/class/extcon/.../cable.x/state | ||
73 | Date: February 2012 | ||
74 | Contact: MyungJoo Ham <myungjoo.ham@samsung.com> | ||
75 | Description: | ||
76 | The /sys/class/extcon/.../cable.x/name shows and stores the | ||
77 | state of cable "x" (integer between 0 and 31) of an extcon | ||
78 | device. The state value is either 0 (detached) or 1 | ||
79 | (attached). | ||
80 | |||
81 | What: /sys/class/extcon/.../mutually_exclusive/... | ||
82 | Date: December 2011 | ||
83 | Contact: MyungJoo Ham <myungjoo.ham@samsung.com> | ||
84 | Description: | ||
85 | Shows the relations of mutually exclusiveness. For example, | ||
86 | if the mutually_exclusive array of extcon_dev is | ||
87 | {0x3, 0x5, 0xC, 0x0}, the, the output is: | ||
88 | # ls mutually_exclusive/ | ||
89 | 0x3 | ||
90 | 0x5 | ||
91 | 0xc | ||
92 | # | ||
93 | |||
94 | Note that mutually_exclusive is a sub-directory of the extcon | ||
95 | device and the file names under the mutually_exclusive | ||
96 | directory show the mutually-exclusive sets, not the contents | ||
97 | of the files. | ||
diff --git a/Documentation/HOWTO b/Documentation/HOWTO index f7ade3b3b40d..59c080f084ef 100644 --- a/Documentation/HOWTO +++ b/Documentation/HOWTO | |||
@@ -218,16 +218,16 @@ The development process | |||
218 | Linux kernel development process currently consists of a few different | 218 | Linux kernel development process currently consists of a few different |
219 | main kernel "branches" and lots of different subsystem-specific kernel | 219 | main kernel "branches" and lots of different subsystem-specific kernel |
220 | branches. These different branches are: | 220 | branches. These different branches are: |
221 | - main 2.6.x kernel tree | 221 | - main 3.x kernel tree |
222 | - 2.6.x.y -stable kernel tree | 222 | - 3.x.y -stable kernel tree |
223 | - 2.6.x -git kernel patches | 223 | - 3.x -git kernel patches |
224 | - subsystem specific kernel trees and patches | 224 | - subsystem specific kernel trees and patches |
225 | - the 2.6.x -next kernel tree for integration tests | 225 | - the 3.x -next kernel tree for integration tests |
226 | 226 | ||
227 | 2.6.x kernel tree | 227 | 3.x kernel tree |
228 | ----------------- | 228 | ----------------- |
229 | 2.6.x kernels are maintained by Linus Torvalds, and can be found on | 229 | 3.x kernels are maintained by Linus Torvalds, and can be found on |
230 | kernel.org in the pub/linux/kernel/v2.6/ directory. Its development | 230 | kernel.org in the pub/linux/kernel/v3.x/ directory. Its development |
231 | process is as follows: | 231 | process is as follows: |
232 | - As soon as a new kernel is released a two weeks window is open, | 232 | - As soon as a new kernel is released a two weeks window is open, |
233 | during this period of time maintainers can submit big diffs to | 233 | during this period of time maintainers can submit big diffs to |
@@ -262,20 +262,20 @@ mailing list about kernel releases: | |||
262 | released according to perceived bug status, not according to a | 262 | released according to perceived bug status, not according to a |
263 | preconceived timeline." | 263 | preconceived timeline." |
264 | 264 | ||
265 | 2.6.x.y -stable kernel tree | 265 | 3.x.y -stable kernel tree |
266 | --------------------------- | 266 | --------------------------- |
267 | Kernels with 4-part versions are -stable kernels. They contain | 267 | Kernels with 3-part versions are -stable kernels. They contain |
268 | relatively small and critical fixes for security problems or significant | 268 | relatively small and critical fixes for security problems or significant |
269 | regressions discovered in a given 2.6.x kernel. | 269 | regressions discovered in a given 3.x kernel. |
270 | 270 | ||
271 | This is the recommended branch for users who want the most recent stable | 271 | This is the recommended branch for users who want the most recent stable |
272 | kernel and are not interested in helping test development/experimental | 272 | kernel and are not interested in helping test development/experimental |
273 | versions. | 273 | versions. |
274 | 274 | ||
275 | If no 2.6.x.y kernel is available, then the highest numbered 2.6.x | 275 | If no 3.x.y kernel is available, then the highest numbered 3.x |
276 | kernel is the current stable kernel. | 276 | kernel is the current stable kernel. |
277 | 277 | ||
278 | 2.6.x.y are maintained by the "stable" team <stable@vger.kernel.org>, and | 278 | 3.x.y are maintained by the "stable" team <stable@vger.kernel.org>, and |
279 | are released as needs dictate. The normal release period is approximately | 279 | are released as needs dictate. The normal release period is approximately |
280 | two weeks, but it can be longer if there are no pressing problems. A | 280 | two weeks, but it can be longer if there are no pressing problems. A |
281 | security-related problem, instead, can cause a release to happen almost | 281 | security-related problem, instead, can cause a release to happen almost |
@@ -285,7 +285,7 @@ The file Documentation/stable_kernel_rules.txt in the kernel tree | |||
285 | documents what kinds of changes are acceptable for the -stable tree, and | 285 | documents what kinds of changes are acceptable for the -stable tree, and |
286 | how the release process works. | 286 | how the release process works. |
287 | 287 | ||
288 | 2.6.x -git patches | 288 | 3.x -git patches |
289 | ------------------ | 289 | ------------------ |
290 | These are daily snapshots of Linus' kernel tree which are managed in a | 290 | These are daily snapshots of Linus' kernel tree which are managed in a |
291 | git repository (hence the name.) These patches are usually released | 291 | git repository (hence the name.) These patches are usually released |
@@ -317,13 +317,13 @@ revisions to it, and maintainers can mark patches as under review, | |||
317 | accepted, or rejected. Most of these patchwork sites are listed at | 317 | accepted, or rejected. Most of these patchwork sites are listed at |
318 | http://patchwork.kernel.org/. | 318 | http://patchwork.kernel.org/. |
319 | 319 | ||
320 | 2.6.x -next kernel tree for integration tests | 320 | 3.x -next kernel tree for integration tests |
321 | --------------------------------------------- | 321 | --------------------------------------------- |
322 | Before updates from subsystem trees are merged into the mainline 2.6.x | 322 | Before updates from subsystem trees are merged into the mainline 3.x |
323 | tree, they need to be integration-tested. For this purpose, a special | 323 | tree, they need to be integration-tested. For this purpose, a special |
324 | testing repository exists into which virtually all subsystem trees are | 324 | testing repository exists into which virtually all subsystem trees are |
325 | pulled on an almost daily basis: | 325 | pulled on an almost daily basis: |
326 | http://git.kernel.org/?p=linux/kernel/git/sfr/linux-next.git | 326 | http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git |
327 | http://linux.f-seidel.de/linux-next/pmwiki/ | 327 | http://linux.f-seidel.de/linux-next/pmwiki/ |
328 | 328 | ||
329 | This way, the -next kernel gives a summary outlook onto what will be | 329 | This way, the -next kernel gives a summary outlook onto what will be |
diff --git a/Documentation/devices.txt b/Documentation/devices.txt index 00383186d8fb..5941f5136c6b 100644 --- a/Documentation/devices.txt +++ b/Documentation/devices.txt | |||
@@ -98,7 +98,8 @@ Your cooperation is appreciated. | |||
98 | 8 = /dev/random Nondeterministic random number gen. | 98 | 8 = /dev/random Nondeterministic random number gen. |
99 | 9 = /dev/urandom Faster, less secure random number gen. | 99 | 9 = /dev/urandom Faster, less secure random number gen. |
100 | 10 = /dev/aio Asynchronous I/O notification interface | 100 | 10 = /dev/aio Asynchronous I/O notification interface |
101 | 11 = /dev/kmsg Writes to this come out as printk's | 101 | 11 = /dev/kmsg Writes to this come out as printk's, reads |
102 | export the buffered printk records. | ||
102 | 12 = /dev/oldmem Used by crashdump kernels to access | 103 | 12 = /dev/oldmem Used by crashdump kernels to access |
103 | the memory of the kernel that crashed. | 104 | the memory of the kernel that crashed. |
104 | 105 | ||
diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-mc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-mc.txt new file mode 100644 index 000000000000..c25a0a55151d --- /dev/null +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-mc.txt | |||
@@ -0,0 +1,16 @@ | |||
1 | NVIDIA Tegra20 MC(Memory Controller) | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : "nvidia,tegra20-mc" | ||
5 | - reg : Should contain 2 register ranges(address and length); see the | ||
6 | example below. Note that the MC registers are interleaved with the | ||
7 | GART registers, and hence must be represented as multiple ranges. | ||
8 | - interrupts : Should contain MC General interrupt. | ||
9 | |||
10 | Example: | ||
11 | mc { | ||
12 | compatible = "nvidia,tegra20-mc"; | ||
13 | reg = <0x7000f000 0x024 | ||
14 | 0x7000f03c 0x3c4>; | ||
15 | interrupts = <0 77 0x04>; | ||
16 | }; | ||
diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-mc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-mc.txt new file mode 100644 index 000000000000..e47e73f612f4 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-mc.txt | |||
@@ -0,0 +1,18 @@ | |||
1 | NVIDIA Tegra30 MC(Memory Controller) | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : "nvidia,tegra30-mc" | ||
5 | - reg : Should contain 4 register ranges(address and length); see the | ||
6 | example below. Note that the MC registers are interleaved with the | ||
7 | SMMU registers, and hence must be represented as multiple ranges. | ||
8 | - interrupts : Should contain MC General interrupt. | ||
9 | |||
10 | Example: | ||
11 | mc { | ||
12 | compatible = "nvidia,tegra30-mc"; | ||
13 | reg = <0x7000f000 0x010 | ||
14 | 0x7000f03c 0x1b4 | ||
15 | 0x7000f200 0x028 | ||
16 | 0x7000f284 0x17c>; | ||
17 | interrupts = <0 77 0x04>; | ||
18 | }; | ||
diff --git a/Documentation/dynamic-debug-howto.txt b/Documentation/dynamic-debug-howto.txt index 74e6c7782678..6e1684981da2 100644 --- a/Documentation/dynamic-debug-howto.txt +++ b/Documentation/dynamic-debug-howto.txt | |||
@@ -2,17 +2,17 @@ | |||
2 | Introduction | 2 | Introduction |
3 | ============ | 3 | ============ |
4 | 4 | ||
5 | This document describes how to use the dynamic debug (ddebug) feature. | 5 | This document describes how to use the dynamic debug (dyndbg) feature. |
6 | 6 | ||
7 | Dynamic debug is designed to allow you to dynamically enable/disable kernel | 7 | Dynamic debug is designed to allow you to dynamically enable/disable |
8 | code to obtain additional kernel information. Currently, if | 8 | kernel code to obtain additional kernel information. Currently, if |
9 | CONFIG_DYNAMIC_DEBUG is set, then all pr_debug()/dev_dbg() calls can be | 9 | CONFIG_DYNAMIC_DEBUG is set, then all pr_debug()/dev_dbg() calls can |
10 | dynamically enabled per-callsite. | 10 | be dynamically enabled per-callsite. |
11 | 11 | ||
12 | Dynamic debug has even more useful features: | 12 | Dynamic debug has even more useful features: |
13 | 13 | ||
14 | * Simple query language allows turning on and off debugging statements by | 14 | * Simple query language allows turning on and off debugging |
15 | matching any combination of 0 or 1 of: | 15 | statements by matching any combination of 0 or 1 of: |
16 | 16 | ||
17 | - source filename | 17 | - source filename |
18 | - function name | 18 | - function name |
@@ -20,17 +20,19 @@ Dynamic debug has even more useful features: | |||
20 | - module name | 20 | - module name |
21 | - format string | 21 | - format string |
22 | 22 | ||
23 | * Provides a debugfs control file: <debugfs>/dynamic_debug/control which can be | 23 | * Provides a debugfs control file: <debugfs>/dynamic_debug/control |
24 | read to display the complete list of known debug statements, to help guide you | 24 | which can be read to display the complete list of known debug |
25 | statements, to help guide you | ||
25 | 26 | ||
26 | Controlling dynamic debug Behaviour | 27 | Controlling dynamic debug Behaviour |
27 | =================================== | 28 | =================================== |
28 | 29 | ||
29 | The behaviour of pr_debug()/dev_dbg()s are controlled via writing to a | 30 | The behaviour of pr_debug()/dev_dbg()s are controlled via writing to a |
30 | control file in the 'debugfs' filesystem. Thus, you must first mount the debugfs | 31 | control file in the 'debugfs' filesystem. Thus, you must first mount |
31 | filesystem, in order to make use of this feature. Subsequently, we refer to the | 32 | the debugfs filesystem, in order to make use of this feature. |
32 | control file as: <debugfs>/dynamic_debug/control. For example, if you want to | 33 | Subsequently, we refer to the control file as: |
33 | enable printing from source file 'svcsock.c', line 1603 you simply do: | 34 | <debugfs>/dynamic_debug/control. For example, if you want to enable |
35 | printing from source file 'svcsock.c', line 1603 you simply do: | ||
34 | 36 | ||
35 | nullarbor:~ # echo 'file svcsock.c line 1603 +p' > | 37 | nullarbor:~ # echo 'file svcsock.c line 1603 +p' > |
36 | <debugfs>/dynamic_debug/control | 38 | <debugfs>/dynamic_debug/control |
@@ -44,15 +46,15 @@ nullarbor:~ # echo 'file svcsock.c wtf 1 +p' > | |||
44 | Viewing Dynamic Debug Behaviour | 46 | Viewing Dynamic Debug Behaviour |
45 | =========================== | 47 | =========================== |
46 | 48 | ||
47 | You can view the currently configured behaviour of all the debug statements | 49 | You can view the currently configured behaviour of all the debug |
48 | via: | 50 | statements via: |
49 | 51 | ||
50 | nullarbor:~ # cat <debugfs>/dynamic_debug/control | 52 | nullarbor:~ # cat <debugfs>/dynamic_debug/control |
51 | # filename:lineno [module]function flags format | 53 | # filename:lineno [module]function flags format |
52 | /usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:323 [svcxprt_rdma]svc_rdma_cleanup - "SVCRDMA Module Removed, deregister RPC RDMA transport\012" | 54 | /usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:323 [svcxprt_rdma]svc_rdma_cleanup =_ "SVCRDMA Module Removed, deregister RPC RDMA transport\012" |
53 | /usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:341 [svcxprt_rdma]svc_rdma_init - "\011max_inline : %d\012" | 55 | /usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:341 [svcxprt_rdma]svc_rdma_init =_ "\011max_inline : %d\012" |
54 | /usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:340 [svcxprt_rdma]svc_rdma_init - "\011sq_depth : %d\012" | 56 | /usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:340 [svcxprt_rdma]svc_rdma_init =_ "\011sq_depth : %d\012" |
55 | /usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:338 [svcxprt_rdma]svc_rdma_init - "\011max_requests : %d\012" | 57 | /usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svc_rdma.c:338 [svcxprt_rdma]svc_rdma_init =_ "\011max_requests : %d\012" |
56 | ... | 58 | ... |
57 | 59 | ||
58 | 60 | ||
@@ -65,12 +67,12 @@ nullarbor:~ # grep -i rdma <debugfs>/dynamic_debug/control | wc -l | |||
65 | nullarbor:~ # grep -i tcp <debugfs>/dynamic_debug/control | wc -l | 67 | nullarbor:~ # grep -i tcp <debugfs>/dynamic_debug/control | wc -l |
66 | 42 | 68 | 42 |
67 | 69 | ||
68 | Note in particular that the third column shows the enabled behaviour | 70 | The third column shows the currently enabled flags for each debug |
69 | flags for each debug statement callsite (see below for definitions of the | 71 | statement callsite (see below for definitions of the flags). The |
70 | flags). The default value, no extra behaviour enabled, is "-". So | 72 | default value, with no flags enabled, is "=_". So you can view all |
71 | you can view all the debug statement callsites with any non-default flags: | 73 | the debug statement callsites with any non-default flags: |
72 | 74 | ||
73 | nullarbor:~ # awk '$3 != "-"' <debugfs>/dynamic_debug/control | 75 | nullarbor:~ # awk '$3 != "=_"' <debugfs>/dynamic_debug/control |
74 | # filename:lineno [module]function flags format | 76 | # filename:lineno [module]function flags format |
75 | /usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svcsock.c:1603 [sunrpc]svc_send p "svc_process: st_sendto returned %d\012" | 77 | /usr/src/packages/BUILD/sgi-enhancednfs-1.4/default/net/sunrpc/svcsock.c:1603 [sunrpc]svc_send p "svc_process: st_sendto returned %d\012" |
76 | 78 | ||
@@ -103,15 +105,14 @@ specifications, followed by a flags change specification. | |||
103 | 105 | ||
104 | command ::= match-spec* flags-spec | 106 | command ::= match-spec* flags-spec |
105 | 107 | ||
106 | The match-spec's are used to choose a subset of the known dprintk() | 108 | The match-spec's are used to choose a subset of the known pr_debug() |
107 | callsites to which to apply the flags-spec. Think of them as a query | 109 | callsites to which to apply the flags-spec. Think of them as a query |
108 | with implicit ANDs between each pair. Note that an empty list of | 110 | with implicit ANDs between each pair. Note that an empty list of |
109 | match-specs is possible, but is not very useful because it will not | 111 | match-specs will select all debug statement callsites. |
110 | match any debug statement callsites. | ||
111 | 112 | ||
112 | A match specification comprises a keyword, which controls the attribute | 113 | A match specification comprises a keyword, which controls the |
113 | of the callsite to be compared, and a value to compare against. Possible | 114 | attribute of the callsite to be compared, and a value to compare |
114 | keywords are: | 115 | against. Possible keywords are: |
115 | 116 | ||
116 | match-spec ::= 'func' string | | 117 | match-spec ::= 'func' string | |
117 | 'file' string | | 118 | 'file' string | |
@@ -164,15 +165,15 @@ format | |||
164 | characters (") or single quote characters ('). | 165 | characters (") or single quote characters ('). |
165 | Examples: | 166 | Examples: |
166 | 167 | ||
167 | format svcrdma: // many of the NFS/RDMA server dprintks | 168 | format svcrdma: // many of the NFS/RDMA server pr_debugs |
168 | format readahead // some dprintks in the readahead cache | 169 | format readahead // some pr_debugs in the readahead cache |
169 | format nfsd:\040SETATTR // one way to match a format with whitespace | 170 | format nfsd:\040SETATTR // one way to match a format with whitespace |
170 | format "nfsd: SETATTR" // a neater way to match a format with whitespace | 171 | format "nfsd: SETATTR" // a neater way to match a format with whitespace |
171 | format 'nfsd: SETATTR' // yet another way to match a format with whitespace | 172 | format 'nfsd: SETATTR' // yet another way to match a format with whitespace |
172 | 173 | ||
173 | line | 174 | line |
174 | The given line number or range of line numbers is compared | 175 | The given line number or range of line numbers is compared |
175 | against the line number of each dprintk() callsite. A single | 176 | against the line number of each pr_debug() callsite. A single |
176 | line number matches the callsite line number exactly. A | 177 | line number matches the callsite line number exactly. A |
177 | range of line numbers matches any callsite between the first | 178 | range of line numbers matches any callsite between the first |
178 | and last line number inclusive. An empty first number means | 179 | and last line number inclusive. An empty first number means |
@@ -188,51 +189,93 @@ The flags specification comprises a change operation followed | |||
188 | by one or more flag characters. The change operation is one | 189 | by one or more flag characters. The change operation is one |
189 | of the characters: | 190 | of the characters: |
190 | 191 | ||
191 | - | 192 | - remove the given flags |
192 | remove the given flags | 193 | + add the given flags |
193 | 194 | = set the flags to the given flags | |
194 | + | ||
195 | add the given flags | ||
196 | |||
197 | = | ||
198 | set the flags to the given flags | ||
199 | 195 | ||
200 | The flags are: | 196 | The flags are: |
201 | 197 | ||
202 | f | 198 | p enables the pr_debug() callsite. |
203 | Include the function name in the printed message | 199 | f Include the function name in the printed message |
204 | l | 200 | l Include line number in the printed message |
205 | Include line number in the printed message | 201 | m Include module name in the printed message |
206 | m | 202 | t Include thread ID in messages not generated from interrupt context |
207 | Include module name in the printed message | 203 | _ No flags are set. (Or'd with others on input) |
208 | p | 204 | |
209 | Causes a printk() message to be emitted to dmesg | 205 | For display, the flags are preceded by '=' |
210 | t | 206 | (mnemonic: what the flags are currently equal to). |
211 | Include thread ID in messages not generated from interrupt context | ||
212 | 207 | ||
213 | Note the regexp ^[-+=][flmpt]+$ matches a flags specification. | 208 | Note the regexp ^[-+=][flmpt_]+$ matches a flags specification. |
214 | Note also that there is no convenient syntax to remove all | 209 | To clear all flags at once, use "=_" or "-flmpt". |
215 | the flags at once, you need to use "-flmpt". | ||
216 | 210 | ||
217 | 211 | ||
218 | Debug messages during boot process | 212 | Debug messages during Boot Process |
219 | ================================== | 213 | ================================== |
220 | 214 | ||
221 | To be able to activate debug messages during the boot process, | 215 | To activate debug messages for core code and built-in modules during |
222 | even before userspace and debugfs exists, use the boot parameter: | 216 | the boot process, even before userspace and debugfs exists, use |
223 | ddebug_query="QUERY" | 217 | dyndbg="QUERY", module.dyndbg="QUERY", or ddebug_query="QUERY" |
218 | (ddebug_query is obsoleted by dyndbg, and deprecated). QUERY follows | ||
219 | the syntax described above, but must not exceed 1023 characters. Your | ||
220 | bootloader may impose lower limits. | ||
221 | |||
222 | These dyndbg params are processed just after the ddebug tables are | ||
223 | processed, as part of the arch_initcall. Thus you can enable debug | ||
224 | messages in all code run after this arch_initcall via this boot | ||
225 | parameter. | ||
224 | 226 | ||
225 | QUERY follows the syntax described above, but must not exceed 1023 | ||
226 | characters. The enablement of debug messages is done as an arch_initcall. | ||
227 | Thus you can enable debug messages in all code processed after this | ||
228 | arch_initcall via this boot parameter. | ||
229 | On an x86 system for example ACPI enablement is a subsys_initcall and | 227 | On an x86 system for example ACPI enablement is a subsys_initcall and |
230 | ddebug_query="file ec.c +p" | 228 | dyndbg="file ec.c +p" |
231 | will show early Embedded Controller transactions during ACPI setup if | 229 | will show early Embedded Controller transactions during ACPI setup if |
232 | your machine (typically a laptop) has an Embedded Controller. | 230 | your machine (typically a laptop) has an Embedded Controller. |
233 | PCI (or other devices) initialization also is a hot candidate for using | 231 | PCI (or other devices) initialization also is a hot candidate for using |
234 | this boot parameter for debugging purposes. | 232 | this boot parameter for debugging purposes. |
235 | 233 | ||
234 | If foo module is not built-in, foo.dyndbg will still be processed at | ||
235 | boot time, without effect, but will be reprocessed when module is | ||
236 | loaded later. dyndbg_query= and bare dyndbg= are only processed at | ||
237 | boot. | ||
238 | |||
239 | |||
240 | Debug Messages at Module Initialization Time | ||
241 | ============================================ | ||
242 | |||
243 | When "modprobe foo" is called, modprobe scans /proc/cmdline for | ||
244 | foo.params, strips "foo.", and passes them to the kernel along with | ||
245 | params given in modprobe args or /etc/modprob.d/*.conf files, | ||
246 | in the following order: | ||
247 | |||
248 | 1. # parameters given via /etc/modprobe.d/*.conf | ||
249 | options foo dyndbg=+pt | ||
250 | options foo dyndbg # defaults to +p | ||
251 | |||
252 | 2. # foo.dyndbg as given in boot args, "foo." is stripped and passed | ||
253 | foo.dyndbg=" func bar +p; func buz +mp" | ||
254 | |||
255 | 3. # args to modprobe | ||
256 | modprobe foo dyndbg==pmf # override previous settings | ||
257 | |||
258 | These dyndbg queries are applied in order, with last having final say. | ||
259 | This allows boot args to override or modify those from /etc/modprobe.d | ||
260 | (sensible, since 1 is system wide, 2 is kernel or boot specific), and | ||
261 | modprobe args to override both. | ||
262 | |||
263 | In the foo.dyndbg="QUERY" form, the query must exclude "module foo". | ||
264 | "foo" is extracted from the param-name, and applied to each query in | ||
265 | "QUERY", and only 1 match-spec of each type is allowed. | ||
266 | |||
267 | The dyndbg option is a "fake" module parameter, which means: | ||
268 | |||
269 | - modules do not need to define it explicitly | ||
270 | - every module gets it tacitly, whether they use pr_debug or not | ||
271 | - it doesnt appear in /sys/module/$module/parameters/ | ||
272 | To see it, grep the control file, or inspect /proc/cmdline. | ||
273 | |||
274 | For CONFIG_DYNAMIC_DEBUG kernels, any settings given at boot-time (or | ||
275 | enabled by -DDEBUG flag during compilation) can be disabled later via | ||
276 | the sysfs interface if the debug messages are no longer needed: | ||
277 | |||
278 | echo "module module_name -p" > <debugfs>/dynamic_debug/control | ||
236 | 279 | ||
237 | Examples | 280 | Examples |
238 | ======== | 281 | ======== |
@@ -260,3 +303,18 @@ nullarbor:~ # echo -n 'func svc_process -p' > | |||
260 | // enable messages for NFS calls READ, READLINK, READDIR and READDIR+. | 303 | // enable messages for NFS calls READ, READLINK, READDIR and READDIR+. |
261 | nullarbor:~ # echo -n 'format "nfsd: READ" +p' > | 304 | nullarbor:~ # echo -n 'format "nfsd: READ" +p' > |
262 | <debugfs>/dynamic_debug/control | 305 | <debugfs>/dynamic_debug/control |
306 | |||
307 | // enable all messages | ||
308 | nullarbor:~ # echo -n '+p' > <debugfs>/dynamic_debug/control | ||
309 | |||
310 | // add module, function to all enabled messages | ||
311 | nullarbor:~ # echo -n '+mf' > <debugfs>/dynamic_debug/control | ||
312 | |||
313 | // boot-args example, with newlines and comments for readability | ||
314 | Kernel command line: ... | ||
315 | // see whats going on in dyndbg=value processing | ||
316 | dynamic_debug.verbose=1 | ||
317 | // enable pr_debugs in 2 builtins, #cmt is stripped | ||
318 | dyndbg="module params +p #cmt ; module sys +p" | ||
319 | // enable pr_debugs in 2 functions in a module loaded later | ||
320 | pc87360.dyndbg="func pc87360_init_device +p; func pc87360_find +p" | ||
diff --git a/Documentation/extcon/porting-android-switch-class b/Documentation/extcon/porting-android-switch-class new file mode 100644 index 000000000000..eb0fa5f4fe88 --- /dev/null +++ b/Documentation/extcon/porting-android-switch-class | |||
@@ -0,0 +1,124 @@ | |||
1 | |||
2 | Staging/Android Switch Class Porting Guide | ||
3 | (linux/drivers/staging/android/switch) | ||
4 | (c) Copyright 2012 Samsung Electronics | ||
5 | |||
6 | AUTHORS | ||
7 | MyungJoo Ham <myungjoo.ham@samsung.com> | ||
8 | |||
9 | /***************************************************************** | ||
10 | * CHAPTER 1. * | ||
11 | * PORTING SWITCH CLASS DEVICE DRIVERS * | ||
12 | *****************************************************************/ | ||
13 | |||
14 | ****** STEP 1. Basic Functionality | ||
15 | No extcon extended feature, but switch features only. | ||
16 | |||
17 | - struct switch_dev (fed to switch_dev_register/unregister) | ||
18 | @name: no change | ||
19 | @dev: no change | ||
20 | @index: drop (not used in switch device driver side anyway) | ||
21 | @state: no change | ||
22 | If you have used @state with magic numbers, keep it | ||
23 | at this step. | ||
24 | @print_name: no change but type change (switch_dev->extcon_dev) | ||
25 | @print_state: no change but type change (switch_dev->extcon_dev) | ||
26 | |||
27 | - switch_dev_register(sdev, dev) | ||
28 | => extcon_dev_register(edev, dev) | ||
29 | : no change but type change (sdev->edev) | ||
30 | - switch_dev_unregister(sdev) | ||
31 | => extcon_dev_unregister(edev) | ||
32 | : no change but type change (sdev->edev) | ||
33 | - switch_get_state(sdev) | ||
34 | => extcon_get_state(edev) | ||
35 | : no change but type change (sdev->edev) and (return: int->u32) | ||
36 | - switch_set_state(sdev, state) | ||
37 | => extcon_set_state(edev, state) | ||
38 | : no change but type change (sdev->edev) and (state: int->u32) | ||
39 | |||
40 | With this changes, the ex-switch extcon class device works as it once | ||
41 | worked as switch class device. However, it will now have additional | ||
42 | interfaces (both ABI and in-kernel API) and different ABI locations. | ||
43 | However, if CONFIG_ANDROID is enabled without CONFIG_ANDROID_SWITCH, | ||
44 | /sys/class/switch/* will be symbolically linked to /sys/class/extcon/ | ||
45 | so that they are still compatible with legacy userspace processes. | ||
46 | |||
47 | ****** STEP 2. Multistate (no more magic numbers in state value) | ||
48 | Extcon's extended features for switch device drivers with | ||
49 | complex features usually required magic numbers in state | ||
50 | value of switch_dev. With extcon, such magic numbers that | ||
51 | support multiple cables ( | ||
52 | |||
53 | 1. Define cable names at edev->supported_cable. | ||
54 | 2. (Recommended) remove print_state callback. | ||
55 | 3. Use extcon_get_cable_state_(edev, index) or | ||
56 | extcon_get_cable_state(edev, cable_name) instead of | ||
57 | extcon_get_state(edev) if you intend to get a state of a specific | ||
58 | cable. Same for set_state. This way, you can remove the usage of | ||
59 | magic numbers in state value. | ||
60 | 4. Use extcon_update_state() if you are updating specific bits of | ||
61 | the state value. | ||
62 | |||
63 | Example: a switch device driver w/ magic numbers for two cables. | ||
64 | "0x00": no cables connected. | ||
65 | "0x01": cable 1 connected | ||
66 | "0x02": cable 2 connected | ||
67 | "0x03": cable 1 and 2 connected | ||
68 | 1. edev->supported_cable = {"1", "2", NULL}; | ||
69 | 2. edev->print_state = NULL; | ||
70 | 3. extcon_get_cable_state_(edev, 0) shows cable 1's state. | ||
71 | extcon_get_cable_state(edev, "1") shows cable 1's state. | ||
72 | extcon_set_cable_state_(edev, 1) sets cable 2's state. | ||
73 | extcon_set_cable_state(edev, "2") sets cable 2's state | ||
74 | 4. extcon_update_state(edev, 0x01, 0) sets the least bit's 0. | ||
75 | |||
76 | ****** STEP 3. Notify other device drivers | ||
77 | |||
78 | You can notify others of the cable attach/detach events with | ||
79 | notifier chains. | ||
80 | |||
81 | At the side of other device drivers (the extcon device itself | ||
82 | does not need to get notified of its own events), there are two | ||
83 | methods to register notifier_block for cable events: | ||
84 | (a) for a specific cable or (b) for every cable. | ||
85 | |||
86 | (a) extcon_register_interest(obj, extcon_name, cable_name, nb) | ||
87 | Example: want to get news of "MAX8997_MUIC"'s "USB" cable | ||
88 | |||
89 | obj = kzalloc(sizeof(struct extcon_specific_cable_nb), | ||
90 | GFP_KERNEL); | ||
91 | nb->notifier_call = the_callback_to_handle_usb; | ||
92 | |||
93 | extcon_register_intereset(obj, "MAX8997_MUIC", "USB", nb); | ||
94 | |||
95 | (b) extcon_register_notifier(edev, nb) | ||
96 | Call nb for any changes in edev. | ||
97 | |||
98 | Please note that in order to properly behave with method (a), | ||
99 | the extcon device driver should support multistate feature (STEP 2). | ||
100 | |||
101 | ****** STEP 4. Inter-cable relation (mutually exclusive) | ||
102 | |||
103 | You can provide inter-cable mutually exclusiveness information | ||
104 | for an extcon device. When cables A and B are declared to be mutually | ||
105 | exclusive, the two cables cannot be in ATTACHED state simulteneously. | ||
106 | |||
107 | |||
108 | /***************************************************************** | ||
109 | * CHAPTER 2. * | ||
110 | * PORTING USERSPACE w/ SWITCH CLASS DEVICE SUPPORT * | ||
111 | *****************************************************************/ | ||
112 | |||
113 | ****** ABI Location | ||
114 | |||
115 | If "CONFIG_ANDROID" is enabled and "CONFIG_ANDROID_SWITCH" is | ||
116 | disabled, /sys/class/switch/* are created as symbolic links to | ||
117 | /sys/class/extcon/*. Because CONFIG_ANDROID_SWITCH creates | ||
118 | /sys/class/switch directory, we disable symboling linking if | ||
119 | CONFIG_ANDROID_SWITCH is enabled. | ||
120 | |||
121 | The two files of switch class, name and state, are provided with | ||
122 | extcon, too. When the multistate support (STEP 2 of CHAPTER 1.) is | ||
123 | not enabled or print_state callback is supplied, the output of | ||
124 | state ABI is same with switch class. | ||
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index e4b57756b9f5..e9abede594e1 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -2,7 +2,14 @@ The following is a list of files and features that are going to be | |||
2 | removed in the kernel source tree. Every entry should contain what | 2 | removed in the kernel source tree. Every entry should contain what |
3 | exactly is going away, why it is happening, and who is going to be doing | 3 | exactly is going away, why it is happening, and who is going to be doing |
4 | the work. When the feature is removed from the kernel, it should also | 4 | the work. When the feature is removed from the kernel, it should also |
5 | be removed from this file. | 5 | be removed from this file. The suggested deprecation period is 3 releases. |
6 | |||
7 | --------------------------- | ||
8 | |||
9 | What: ddebug_query="query" boot cmdline param | ||
10 | When: v3.8 | ||
11 | Why: obsoleted by dyndbg="query" and module.dyndbg="query" | ||
12 | Who: Jim Cromie <jim.cromie@gmail.com>, Jason Baron <jbaron@redhat.com> | ||
6 | 13 | ||
7 | --------------------------- | 14 | --------------------------- |
8 | 15 | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index e275432ef2c7..62aba89b04a2 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -611,7 +611,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
611 | 611 | ||
612 | ddebug_query= [KNL,DYNAMIC_DEBUG] Enable debug messages at early boot | 612 | ddebug_query= [KNL,DYNAMIC_DEBUG] Enable debug messages at early boot |
613 | time. See Documentation/dynamic-debug-howto.txt for | 613 | time. See Documentation/dynamic-debug-howto.txt for |
614 | details. | 614 | details. Deprecated, see dyndbg. |
615 | 615 | ||
616 | debug [KNL] Enable kernel debugging (events log level). | 616 | debug [KNL] Enable kernel debugging (events log level). |
617 | 617 | ||
@@ -731,6 +731,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
731 | 731 | ||
732 | dscc4.setup= [NET] | 732 | dscc4.setup= [NET] |
733 | 733 | ||
734 | dyndbg[="val"] [KNL,DYNAMIC_DEBUG] | ||
735 | module.dyndbg[="val"] | ||
736 | Enable debug messages at boot time. See | ||
737 | Documentation/dynamic-debug-howto.txt for details. | ||
738 | |||
734 | earlycon= [KNL] Output early console device and options. | 739 | earlycon= [KNL] Output early console device and options. |
735 | uart[8250],io,<addr>[,options] | 740 | uart[8250],io,<addr>[,options] |
736 | uart[8250],mmio,<addr>[,options] | 741 | uart[8250],mmio,<addr>[,options] |
diff --git a/Documentation/memory-devices/ti-emif.txt b/Documentation/memory-devices/ti-emif.txt new file mode 100644 index 000000000000..f4ad9a7d0f4b --- /dev/null +++ b/Documentation/memory-devices/ti-emif.txt | |||
@@ -0,0 +1,57 @@ | |||
1 | TI EMIF SDRAM Controller Driver: | ||
2 | |||
3 | Author | ||
4 | ======== | ||
5 | Aneesh V <aneesh@ti.com> | ||
6 | |||
7 | Location | ||
8 | ============ | ||
9 | driver/memory/emif.c | ||
10 | |||
11 | Supported SoCs: | ||
12 | =================== | ||
13 | TI OMAP44xx | ||
14 | TI OMAP54xx | ||
15 | |||
16 | Menuconfig option: | ||
17 | ========================== | ||
18 | Device Drivers | ||
19 | Memory devices | ||
20 | Texas Instruments EMIF driver | ||
21 | |||
22 | Description | ||
23 | =========== | ||
24 | This driver is for the EMIF module available in Texas Instruments | ||
25 | SoCs. EMIF is an SDRAM controller that, based on its revision, | ||
26 | supports one or more of DDR2, DDR3, and LPDDR2 SDRAM protocols. | ||
27 | This driver takes care of only LPDDR2 memories presently. The | ||
28 | functions of the driver includes re-configuring AC timing | ||
29 | parameters and other settings during frequency, voltage and | ||
30 | temperature changes | ||
31 | |||
32 | Platform Data (see include/linux/platform_data/emif_plat.h): | ||
33 | ===================================================================== | ||
34 | DDR device details and other board dependent and SoC dependent | ||
35 | information can be passed through platform data (struct emif_platform_data) | ||
36 | - DDR device details: 'struct ddr_device_info' | ||
37 | - Device AC timings: 'struct lpddr2_timings' and 'struct lpddr2_min_tck' | ||
38 | - Custom configurations: customizable policy options through | ||
39 | 'struct emif_custom_configs' | ||
40 | - IP revision | ||
41 | - PHY type | ||
42 | |||
43 | Interface to the external world: | ||
44 | ================================ | ||
45 | EMIF driver registers notifiers for voltage and frequency changes | ||
46 | affecting EMIF and takes appropriate actions when these are invoked. | ||
47 | - freq_pre_notify_handling() | ||
48 | - freq_post_notify_handling() | ||
49 | - volt_notify_handling() | ||
50 | |||
51 | Debugfs | ||
52 | ======== | ||
53 | The driver creates two debugfs entries per device. | ||
54 | - regcache_dump : dump of register values calculated and saved for all | ||
55 | frequencies used so far. | ||
56 | - mr4 : last polled value of MR4 register in the LPDDR2 device. MR4 | ||
57 | indicates the current temperature level of the device. | ||
diff --git a/Documentation/zh_CN/magic-number.txt b/Documentation/zh_CN/magic-number.txt index f606ba8598cf..4263022f5002 100644 --- a/Documentation/zh_CN/magic-number.txt +++ b/Documentation/zh_CN/magic-number.txt | |||
@@ -160,7 +160,7 @@ QUEUE_MAGIC_USED 0xf7e1cc33 queue_entry drivers/scsi/arm/queue.c | |||
160 | HTB_CMAGIC 0xFEFAFEF1 htb_class net/sched/sch_htb.c | 160 | HTB_CMAGIC 0xFEFAFEF1 htb_class net/sched/sch_htb.c |
161 | NMI_MAGIC 0x48414d4d455201 nmi_s arch/mips/include/asm/sn/nmi.h | 161 | NMI_MAGIC 0x48414d4d455201 nmi_s arch/mips/include/asm/sn/nmi.h |
162 | 162 | ||
163 | 请注意,在声音记忆管理中仍然有每一些被定义的驱动魔术值。查看include/sound/sndmagic.h来获取他们完整的列表信息。很多OSS声音驱动拥有自己从声卡PCI ID构建的魔术值-他们也没有被列在这里。 | 163 | 请注意,在声音记忆管理中仍然有一些特殊的为每个驱动定义的魔术值。查看include/sound/sndmagic.h来获取他们完整的列表信息。很多OSS声音驱动拥有自己从声卡PCI ID构建的魔术值-他们也没有被列在这里。 |
164 | 164 | ||
165 | IrDA子系统也使用了大量的自己的魔术值,查看include/net/irda/irda.h来获取他们完整的信息。 | 165 | IrDA子系统也使用了大量的自己的魔术值,查看include/net/irda/irda.h来获取他们完整的信息。 |
166 | 166 | ||
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index fb05b123218f..1a6de0a7d8eb 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c | |||
@@ -271,7 +271,8 @@ int alloc_bootmem_huge_page(struct hstate *hstate) | |||
271 | 271 | ||
272 | unsigned long gpage_npages[MMU_PAGE_COUNT]; | 272 | unsigned long gpage_npages[MMU_PAGE_COUNT]; |
273 | 273 | ||
274 | static int __init do_gpage_early_setup(char *param, char *val) | 274 | static int __init do_gpage_early_setup(char *param, char *val, |
275 | const char *unused) | ||
275 | { | 276 | { |
276 | static phys_addr_t size; | 277 | static phys_addr_t size; |
277 | unsigned long npages; | 278 | unsigned long npages; |
diff --git a/drivers/Kconfig b/drivers/Kconfig index d236aef7e59f..63b81826cb55 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig | |||
@@ -140,4 +140,8 @@ source "drivers/virt/Kconfig" | |||
140 | 140 | ||
141 | source "drivers/devfreq/Kconfig" | 141 | source "drivers/devfreq/Kconfig" |
142 | 142 | ||
143 | source "drivers/extcon/Kconfig" | ||
144 | |||
145 | source "drivers/memory/Kconfig" | ||
146 | |||
143 | endmenu | 147 | endmenu |
diff --git a/drivers/Makefile b/drivers/Makefile index 95952c82bf16..265b506a15be 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -134,3 +134,5 @@ obj-$(CONFIG_VIRT_DRIVERS) += virt/ | |||
134 | obj-$(CONFIG_HYPERV) += hv/ | 134 | obj-$(CONFIG_HYPERV) += hv/ |
135 | 135 | ||
136 | obj-$(CONFIG_PM_DEVFREQ) += devfreq/ | 136 | obj-$(CONFIG_PM_DEVFREQ) += devfreq/ |
137 | obj-$(CONFIG_EXTCON) += extcon/ | ||
138 | obj-$(CONFIG_MEMORY) += memory/ | ||
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 4a29763b8eb4..a12808259dfb 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c | |||
@@ -720,21 +720,21 @@ static int acpi_pci_link_add(struct acpi_device *device) | |||
720 | acpi_device_bid(device)); | 720 | acpi_device_bid(device)); |
721 | for (i = 0; i < link->irq.possible_count; i++) { | 721 | for (i = 0; i < link->irq.possible_count; i++) { |
722 | if (link->irq.active == link->irq.possible[i]) { | 722 | if (link->irq.active == link->irq.possible[i]) { |
723 | printk(" *%d", link->irq.possible[i]); | 723 | printk(KERN_CONT " *%d", link->irq.possible[i]); |
724 | found = 1; | 724 | found = 1; |
725 | } else | 725 | } else |
726 | printk(" %d", link->irq.possible[i]); | 726 | printk(KERN_CONT " %d", link->irq.possible[i]); |
727 | } | 727 | } |
728 | 728 | ||
729 | printk(")"); | 729 | printk(KERN_CONT ")"); |
730 | 730 | ||
731 | if (!found) | 731 | if (!found) |
732 | printk(" *%d", link->irq.active); | 732 | printk(KERN_CONT " *%d", link->irq.active); |
733 | 733 | ||
734 | if (!link->device->status.enabled) | 734 | if (!link->device->status.enabled) |
735 | printk(", disabled."); | 735 | printk(KERN_CONT ", disabled."); |
736 | 736 | ||
737 | printk("\n"); | 737 | printk(KERN_CONT "\n"); |
738 | 738 | ||
739 | list_add_tail(&link->list, &acpi_link_list); | 739 | list_add_tail(&link->list, &acpi_link_list); |
740 | 740 | ||
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index eb6fd233764b..06527c526618 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -887,7 +887,7 @@ int __init acpi_sleep_init(void) | |||
887 | status = acpi_get_sleep_type_data(i, &type_a, &type_b); | 887 | status = acpi_get_sleep_type_data(i, &type_a, &type_b); |
888 | if (ACPI_SUCCESS(status)) { | 888 | if (ACPI_SUCCESS(status)) { |
889 | sleep_states[i] = 1; | 889 | sleep_states[i] = 1; |
890 | printk(" S%d", i); | 890 | printk(KERN_CONT " S%d", i); |
891 | } | 891 | } |
892 | } | 892 | } |
893 | 893 | ||
@@ -901,7 +901,7 @@ int __init acpi_sleep_init(void) | |||
901 | hibernation_set_ops(old_suspend_ordering ? | 901 | hibernation_set_ops(old_suspend_ordering ? |
902 | &acpi_hibernation_ops_old : &acpi_hibernation_ops); | 902 | &acpi_hibernation_ops_old : &acpi_hibernation_ops); |
903 | sleep_states[ACPI_STATE_S4] = 1; | 903 | sleep_states[ACPI_STATE_S4] = 1; |
904 | printk(" S4"); | 904 | printk(KERN_CONT " S4"); |
905 | if (!nosigcheck) { | 905 | if (!nosigcheck) { |
906 | acpi_get_table(ACPI_SIG_FACS, 1, | 906 | acpi_get_table(ACPI_SIG_FACS, 1, |
907 | (struct acpi_table_header **)&facs); | 907 | (struct acpi_table_header **)&facs); |
@@ -914,11 +914,11 @@ int __init acpi_sleep_init(void) | |||
914 | status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b); | 914 | status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b); |
915 | if (ACPI_SUCCESS(status)) { | 915 | if (ACPI_SUCCESS(status)) { |
916 | sleep_states[ACPI_STATE_S5] = 1; | 916 | sleep_states[ACPI_STATE_S5] = 1; |
917 | printk(" S5"); | 917 | printk(KERN_CONT " S5"); |
918 | pm_power_off_prepare = acpi_power_off_prepare; | 918 | pm_power_off_prepare = acpi_power_off_prepare; |
919 | pm_power_off = acpi_power_off; | 919 | pm_power_off = acpi_power_off; |
920 | } | 920 | } |
921 | printk(")\n"); | 921 | printk(KERN_CONT ")\n"); |
922 | /* | 922 | /* |
923 | * Register the tts_notifier to reboot notifier list so that the _TTS | 923 | * Register the tts_notifier to reboot notifier list so that the _TTS |
924 | * object can also be evaluated when the system enters S5. | 924 | * object can also be evaluated when the system enters S5. |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 26a06b801b5b..2bcef657a60c 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -21,8 +21,7 @@ | |||
21 | #include "power/power.h" | 21 | #include "power/power.h" |
22 | 22 | ||
23 | /* /sys/devices/system */ | 23 | /* /sys/devices/system */ |
24 | /* FIXME: make static after drivers/base/sys.c is deleted */ | 24 | static struct kset *system_kset; |
25 | struct kset *system_kset; | ||
26 | 25 | ||
27 | #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) | 26 | #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) |
28 | 27 | ||
diff --git a/drivers/base/core.c b/drivers/base/core.c index e28ce9898af4..346be8b78b24 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
26 | #include <linux/async.h> | 26 | #include <linux/async.h> |
27 | #include <linux/pm_runtime.h> | 27 | #include <linux/pm_runtime.h> |
28 | #include <linux/netdevice.h> | ||
28 | 29 | ||
29 | #include "base.h" | 30 | #include "base.h" |
30 | #include "power/power.h" | 31 | #include "power/power.h" |
@@ -65,7 +66,7 @@ static inline int device_is_not_partition(struct device *dev) | |||
65 | * @dev: struct device to get the name of | 66 | * @dev: struct device to get the name of |
66 | * | 67 | * |
67 | * Will return the device's driver's name if it is bound to a device. If | 68 | * Will return the device's driver's name if it is bound to a device. If |
68 | * the device is not bound to a device, it will return the name of the bus | 69 | * the device is not bound to a driver, it will return the name of the bus |
69 | * it is attached to. If it is not attached to a bus either, an empty | 70 | * it is attached to. If it is not attached to a bus either, an empty |
70 | * string will be returned. | 71 | * string will be returned. |
71 | */ | 72 | */ |
@@ -878,8 +879,8 @@ EXPORT_SYMBOL_GPL(dev_set_name); | |||
878 | * to NULL prevents an entry from being created. class->dev_kobj must | 879 | * to NULL prevents an entry from being created. class->dev_kobj must |
879 | * be set (or cleared) before any devices are registered to the class | 880 | * be set (or cleared) before any devices are registered to the class |
880 | * otherwise device_create_sys_dev_entry() and | 881 | * otherwise device_create_sys_dev_entry() and |
881 | * device_remove_sys_dev_entry() will disagree about the the presence | 882 | * device_remove_sys_dev_entry() will disagree about the presence of |
882 | * of the link. | 883 | * the link. |
883 | */ | 884 | */ |
884 | static struct kobject *device_to_dev_kobj(struct device *dev) | 885 | static struct kobject *device_to_dev_kobj(struct device *dev) |
885 | { | 886 | { |
@@ -1843,15 +1844,60 @@ void device_shutdown(void) | |||
1843 | */ | 1844 | */ |
1844 | 1845 | ||
1845 | #ifdef CONFIG_PRINTK | 1846 | #ifdef CONFIG_PRINTK |
1846 | |||
1847 | int __dev_printk(const char *level, const struct device *dev, | 1847 | int __dev_printk(const char *level, const struct device *dev, |
1848 | struct va_format *vaf) | 1848 | struct va_format *vaf) |
1849 | { | 1849 | { |
1850 | char dict[128]; | ||
1851 | size_t dictlen = 0; | ||
1852 | const char *subsys; | ||
1853 | |||
1850 | if (!dev) | 1854 | if (!dev) |
1851 | return printk("%s(NULL device *): %pV", level, vaf); | 1855 | return printk("%s(NULL device *): %pV", level, vaf); |
1852 | 1856 | ||
1853 | return printk("%s%s %s: %pV", | 1857 | if (dev->class) |
1854 | level, dev_driver_string(dev), dev_name(dev), vaf); | 1858 | subsys = dev->class->name; |
1859 | else if (dev->bus) | ||
1860 | subsys = dev->bus->name; | ||
1861 | else | ||
1862 | goto skip; | ||
1863 | |||
1864 | dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen, | ||
1865 | "SUBSYSTEM=%s", subsys); | ||
1866 | |||
1867 | /* | ||
1868 | * Add device identifier DEVICE=: | ||
1869 | * b12:8 block dev_t | ||
1870 | * c127:3 char dev_t | ||
1871 | * n8 netdev ifindex | ||
1872 | * +sound:card0 subsystem:devname | ||
1873 | */ | ||
1874 | if (MAJOR(dev->devt)) { | ||
1875 | char c; | ||
1876 | |||
1877 | if (strcmp(subsys, "block") == 0) | ||
1878 | c = 'b'; | ||
1879 | else | ||
1880 | c = 'c'; | ||
1881 | dictlen++; | ||
1882 | dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen, | ||
1883 | "DEVICE=%c%u:%u", | ||
1884 | c, MAJOR(dev->devt), MINOR(dev->devt)); | ||
1885 | } else if (strcmp(subsys, "net") == 0) { | ||
1886 | struct net_device *net = to_net_dev(dev); | ||
1887 | |||
1888 | dictlen++; | ||
1889 | dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen, | ||
1890 | "DEVICE=n%u", net->ifindex); | ||
1891 | } else { | ||
1892 | dictlen++; | ||
1893 | dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen, | ||
1894 | "DEVICE=+%s:%s", subsys, dev_name(dev)); | ||
1895 | } | ||
1896 | skip: | ||
1897 | return printk_emit(0, level[1] - '0', | ||
1898 | dictlen ? dict : NULL, dictlen, | ||
1899 | "%s %s: %pV", | ||
1900 | dev_driver_string(dev), dev_name(dev), vaf); | ||
1855 | } | 1901 | } |
1856 | EXPORT_SYMBOL(__dev_printk); | 1902 | EXPORT_SYMBOL(__dev_printk); |
1857 | 1903 | ||
diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 524bf96c289f..2360adb7a58f 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c | |||
@@ -309,6 +309,10 @@ EXPORT_SYMBOL_GPL(devres_remove); | |||
309 | * which @match returns 1. If @match is NULL, it's considered to | 309 | * which @match returns 1. If @match is NULL, it's considered to |
310 | * match all. If found, the resource is removed atomically and freed. | 310 | * match all. If found, the resource is removed atomically and freed. |
311 | * | 311 | * |
312 | * Note that the release function for the resource will not be called, | ||
313 | * only the devres-allocated data will be freed. The caller becomes | ||
314 | * responsible for freeing any other data. | ||
315 | * | ||
312 | * RETURNS: | 316 | * RETURNS: |
313 | * 0 if devres is found and freed, -ENOENT if not found. | 317 | * 0 if devres is found and freed, -ENOENT if not found. |
314 | */ | 318 | */ |
@@ -326,6 +330,37 @@ int devres_destroy(struct device *dev, dr_release_t release, | |||
326 | } | 330 | } |
327 | EXPORT_SYMBOL_GPL(devres_destroy); | 331 | EXPORT_SYMBOL_GPL(devres_destroy); |
328 | 332 | ||
333 | |||
334 | /** | ||
335 | * devres_release - Find a device resource and destroy it, calling release | ||
336 | * @dev: Device to find resource from | ||
337 | * @release: Look for resources associated with this release function | ||
338 | * @match: Match function (optional) | ||
339 | * @match_data: Data for the match function | ||
340 | * | ||
341 | * Find the latest devres of @dev associated with @release and for | ||
342 | * which @match returns 1. If @match is NULL, it's considered to | ||
343 | * match all. If found, the resource is removed atomically, the | ||
344 | * release function called and the resource freed. | ||
345 | * | ||
346 | * RETURNS: | ||
347 | * 0 if devres is found and freed, -ENOENT if not found. | ||
348 | */ | ||
349 | int devres_release(struct device *dev, dr_release_t release, | ||
350 | dr_match_t match, void *match_data) | ||
351 | { | ||
352 | void *res; | ||
353 | |||
354 | res = devres_remove(dev, release, match, match_data); | ||
355 | if (unlikely(!res)) | ||
356 | return -ENOENT; | ||
357 | |||
358 | (*release)(dev, res); | ||
359 | devres_free(res); | ||
360 | return 0; | ||
361 | } | ||
362 | EXPORT_SYMBOL_GPL(devres_release); | ||
363 | |||
329 | static int remove_nodes(struct device *dev, | 364 | static int remove_nodes(struct device *dev, |
330 | struct list_head *first, struct list_head *end, | 365 | struct list_head *first, struct list_head *end, |
331 | struct list_head *todo) | 366 | struct list_head *todo) |
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 8493536ea55b..765c3a28077a 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c | |||
@@ -7,9 +7,9 @@ | |||
7 | * devtmpfs, a tmpfs-based filesystem is created. Every driver-core | 7 | * devtmpfs, a tmpfs-based filesystem is created. Every driver-core |
8 | * device which requests a device node, will add a node in this | 8 | * device which requests a device node, will add a node in this |
9 | * filesystem. | 9 | * filesystem. |
10 | * By default, all devices are named after the the name of the | 10 | * By default, all devices are named after the name of the device, |
11 | * device, owned by root and have a default mode of 0600. Subsystems | 11 | * owned by root and have a default mode of 0600. Subsystems can |
12 | * can overwrite the default setting if needed. | 12 | * overwrite the default setting if needed. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c index 07cbbc6fddb4..05c64c11bad2 100644 --- a/drivers/base/dma-buf.c +++ b/drivers/base/dma-buf.c | |||
@@ -293,7 +293,7 @@ EXPORT_SYMBOL_GPL(dma_buf_unmap_attachment); | |||
293 | * cpu in the kernel context. Calls begin_cpu_access to allow exporter-specific | 293 | * cpu in the kernel context. Calls begin_cpu_access to allow exporter-specific |
294 | * preparations. Coherency is only guaranteed in the specified range for the | 294 | * preparations. Coherency is only guaranteed in the specified range for the |
295 | * specified access direction. | 295 | * specified access direction. |
296 | * @dma_buf: [in] buffer to prepare cpu access for. | 296 | * @dmabuf: [in] buffer to prepare cpu access for. |
297 | * @start: [in] start of range for cpu access. | 297 | * @start: [in] start of range for cpu access. |
298 | * @len: [in] length of range for cpu access. | 298 | * @len: [in] length of range for cpu access. |
299 | * @direction: [in] length of range for cpu access. | 299 | * @direction: [in] length of range for cpu access. |
@@ -320,7 +320,7 @@ EXPORT_SYMBOL_GPL(dma_buf_begin_cpu_access); | |||
320 | * cpu in the kernel context. Calls end_cpu_access to allow exporter-specific | 320 | * cpu in the kernel context. Calls end_cpu_access to allow exporter-specific |
321 | * actions. Coherency is only guaranteed in the specified range for the | 321 | * actions. Coherency is only guaranteed in the specified range for the |
322 | * specified access direction. | 322 | * specified access direction. |
323 | * @dma_buf: [in] buffer to complete cpu access for. | 323 | * @dmabuf: [in] buffer to complete cpu access for. |
324 | * @start: [in] start of range for cpu access. | 324 | * @start: [in] start of range for cpu access. |
325 | * @len: [in] length of range for cpu access. | 325 | * @len: [in] length of range for cpu access. |
326 | * @direction: [in] length of range for cpu access. | 326 | * @direction: [in] length of range for cpu access. |
@@ -340,7 +340,7 @@ EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access); | |||
340 | /** | 340 | /** |
341 | * dma_buf_kmap_atomic - Map a page of the buffer object into kernel address | 341 | * dma_buf_kmap_atomic - Map a page of the buffer object into kernel address |
342 | * space. The same restrictions as for kmap_atomic and friends apply. | 342 | * space. The same restrictions as for kmap_atomic and friends apply. |
343 | * @dma_buf: [in] buffer to map page from. | 343 | * @dmabuf: [in] buffer to map page from. |
344 | * @page_num: [in] page in PAGE_SIZE units to map. | 344 | * @page_num: [in] page in PAGE_SIZE units to map. |
345 | * | 345 | * |
346 | * This call must always succeed, any necessary preparations that might fail | 346 | * This call must always succeed, any necessary preparations that might fail |
@@ -356,7 +356,7 @@ EXPORT_SYMBOL_GPL(dma_buf_kmap_atomic); | |||
356 | 356 | ||
357 | /** | 357 | /** |
358 | * dma_buf_kunmap_atomic - Unmap a page obtained by dma_buf_kmap_atomic. | 358 | * dma_buf_kunmap_atomic - Unmap a page obtained by dma_buf_kmap_atomic. |
359 | * @dma_buf: [in] buffer to unmap page from. | 359 | * @dmabuf: [in] buffer to unmap page from. |
360 | * @page_num: [in] page in PAGE_SIZE units to unmap. | 360 | * @page_num: [in] page in PAGE_SIZE units to unmap. |
361 | * @vaddr: [in] kernel space pointer obtained from dma_buf_kmap_atomic. | 361 | * @vaddr: [in] kernel space pointer obtained from dma_buf_kmap_atomic. |
362 | * | 362 | * |
@@ -375,7 +375,7 @@ EXPORT_SYMBOL_GPL(dma_buf_kunmap_atomic); | |||
375 | /** | 375 | /** |
376 | * dma_buf_kmap - Map a page of the buffer object into kernel address space. The | 376 | * dma_buf_kmap - Map a page of the buffer object into kernel address space. The |
377 | * same restrictions as for kmap and friends apply. | 377 | * same restrictions as for kmap and friends apply. |
378 | * @dma_buf: [in] buffer to map page from. | 378 | * @dmabuf: [in] buffer to map page from. |
379 | * @page_num: [in] page in PAGE_SIZE units to map. | 379 | * @page_num: [in] page in PAGE_SIZE units to map. |
380 | * | 380 | * |
381 | * This call must always succeed, any necessary preparations that might fail | 381 | * This call must always succeed, any necessary preparations that might fail |
@@ -391,7 +391,7 @@ EXPORT_SYMBOL_GPL(dma_buf_kmap); | |||
391 | 391 | ||
392 | /** | 392 | /** |
393 | * dma_buf_kunmap - Unmap a page obtained by dma_buf_kmap. | 393 | * dma_buf_kunmap - Unmap a page obtained by dma_buf_kmap. |
394 | * @dma_buf: [in] buffer to unmap page from. | 394 | * @dmabuf: [in] buffer to unmap page from. |
395 | * @page_num: [in] page in PAGE_SIZE units to unmap. | 395 | * @page_num: [in] page in PAGE_SIZE units to unmap. |
396 | * @vaddr: [in] kernel space pointer obtained from dma_buf_kmap. | 396 | * @vaddr: [in] kernel space pointer obtained from dma_buf_kmap. |
397 | * | 397 | * |
diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 3ec3896c83a6..207c27ddf828 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c | |||
@@ -80,7 +80,7 @@ struct device *driver_find_device(struct device_driver *drv, | |||
80 | struct klist_iter i; | 80 | struct klist_iter i; |
81 | struct device *dev; | 81 | struct device *dev; |
82 | 82 | ||
83 | if (!drv) | 83 | if (!drv || !drv->p) |
84 | return NULL; | 84 | return NULL; |
85 | 85 | ||
86 | klist_iter_init_node(&drv->p->klist_devices, &i, | 86 | klist_iter_init_node(&drv->p->klist_devices, &i, |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index d6e9d081c8b1..67c3371723cc 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -807,44 +807,6 @@ static const struct file_operations oldmem_fops = { | |||
807 | }; | 807 | }; |
808 | #endif | 808 | #endif |
809 | 809 | ||
810 | static ssize_t kmsg_writev(struct kiocb *iocb, const struct iovec *iv, | ||
811 | unsigned long count, loff_t pos) | ||
812 | { | ||
813 | char *line, *p; | ||
814 | int i; | ||
815 | ssize_t ret = -EFAULT; | ||
816 | size_t len = iov_length(iv, count); | ||
817 | |||
818 | line = kmalloc(len + 1, GFP_KERNEL); | ||
819 | if (line == NULL) | ||
820 | return -ENOMEM; | ||
821 | |||
822 | /* | ||
823 | * copy all vectors into a single string, to ensure we do | ||
824 | * not interleave our log line with other printk calls | ||
825 | */ | ||
826 | p = line; | ||
827 | for (i = 0; i < count; i++) { | ||
828 | if (copy_from_user(p, iv[i].iov_base, iv[i].iov_len)) | ||
829 | goto out; | ||
830 | p += iv[i].iov_len; | ||
831 | } | ||
832 | p[0] = '\0'; | ||
833 | |||
834 | ret = printk("%s", line); | ||
835 | /* printk can add a prefix */ | ||
836 | if (ret > len) | ||
837 | ret = len; | ||
838 | out: | ||
839 | kfree(line); | ||
840 | return ret; | ||
841 | } | ||
842 | |||
843 | static const struct file_operations kmsg_fops = { | ||
844 | .aio_write = kmsg_writev, | ||
845 | .llseek = noop_llseek, | ||
846 | }; | ||
847 | |||
848 | static const struct memdev { | 810 | static const struct memdev { |
849 | const char *name; | 811 | const char *name; |
850 | umode_t mode; | 812 | umode_t mode; |
@@ -863,7 +825,9 @@ static const struct memdev { | |||
863 | [7] = { "full", 0666, &full_fops, NULL }, | 825 | [7] = { "full", 0666, &full_fops, NULL }, |
864 | [8] = { "random", 0666, &random_fops, NULL }, | 826 | [8] = { "random", 0666, &random_fops, NULL }, |
865 | [9] = { "urandom", 0666, &urandom_fops, NULL }, | 827 | [9] = { "urandom", 0666, &urandom_fops, NULL }, |
866 | [11] = { "kmsg", 0, &kmsg_fops, NULL }, | 828 | #ifdef CONFIG_PRINTK |
829 | [11] = { "kmsg", 0644, &kmsg_fops, NULL }, | ||
830 | #endif | ||
867 | #ifdef CONFIG_CRASH_DUMP | 831 | #ifdef CONFIG_CRASH_DUMP |
868 | [12] = { "oldmem", 0, &oldmem_fops, NULL }, | 832 | [12] = { "oldmem", 0, &oldmem_fops, NULL }, |
869 | #endif | 833 | #endif |
diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig new file mode 100644 index 000000000000..29c5cf852efc --- /dev/null +++ b/drivers/extcon/Kconfig | |||
@@ -0,0 +1,32 @@ | |||
1 | menuconfig EXTCON | ||
2 | tristate "External Connector Class (extcon) support" | ||
3 | help | ||
4 | Say Y here to enable external connector class (extcon) support. | ||
5 | This allows monitoring external connectors by userspace | ||
6 | via sysfs and uevent and supports external connectors with | ||
7 | multiple states; i.e., an extcon that may have multiple | ||
8 | cables attached. For example, an external connector of a device | ||
9 | may be used to connect an HDMI cable and a AC adaptor, and to | ||
10 | host USB ports. Many of 30-pin connectors including PDMI are | ||
11 | also good examples. | ||
12 | |||
13 | if EXTCON | ||
14 | |||
15 | comment "Extcon Device Drivers" | ||
16 | |||
17 | config EXTCON_GPIO | ||
18 | tristate "GPIO extcon support" | ||
19 | depends on GENERIC_GPIO | ||
20 | help | ||
21 | Say Y here to enable GPIO based extcon support. Note that GPIO | ||
22 | extcon supports single state per extcon instance. | ||
23 | |||
24 | config EXTCON_MAX8997 | ||
25 | tristate "MAX8997 EXTCON Support" | ||
26 | depends on MFD_MAX8997 | ||
27 | help | ||
28 | If you say yes here you get support for the MUIC device of | ||
29 | Maxim MAX8997 PMIC. The MAX8997 MUIC is a USB port accessory | ||
30 | detector and switch. | ||
31 | |||
32 | endif # MULTISTATE_SWITCH | ||
diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile new file mode 100644 index 000000000000..86020bdb6da0 --- /dev/null +++ b/drivers/extcon/Makefile | |||
@@ -0,0 +1,7 @@ | |||
1 | # | ||
2 | # Makefile for external connector class (extcon) devices | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_EXTCON) += extcon_class.o | ||
6 | obj-$(CONFIG_EXTCON_GPIO) += extcon_gpio.o | ||
7 | obj-$(CONFIG_EXTCON_MAX8997) += extcon-max8997.o | ||
diff --git a/drivers/misc/max8997-muic.c b/drivers/extcon/extcon-max8997.c index 2e7df9c56491..23416e443765 100644 --- a/drivers/misc/max8997-muic.c +++ b/drivers/extcon/extcon-max8997.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * max8997-muic.c - MAX8997 muic driver for the Maxim 8997 | 2 | * extcon-max8997.c - MAX8997 extcon driver to support MAX8997 MUIC |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Samsung Electrnoics | 4 | * Copyright (C) 2012 Samsung Electrnoics |
5 | * Donggeun Kim <dg77.kim@samsung.com> | 5 | * Donggeun Kim <dg77.kim@samsung.com> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -13,11 +13,6 @@ | |||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * GNU General Public License for more details. | 15 | * GNU General Public License for more details. |
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | 16 | */ |
22 | 17 | ||
23 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
@@ -30,6 +25,9 @@ | |||
30 | #include <linux/kobject.h> | 25 | #include <linux/kobject.h> |
31 | #include <linux/mfd/max8997.h> | 26 | #include <linux/mfd/max8997.h> |
32 | #include <linux/mfd/max8997-private.h> | 27 | #include <linux/mfd/max8997-private.h> |
28 | #include <linux/extcon.h> | ||
29 | |||
30 | #define DEV_NAME "max8997-muic" | ||
33 | 31 | ||
34 | /* MAX8997-MUIC STATUS1 register */ | 32 | /* MAX8997-MUIC STATUS1 register */ |
35 | #define STATUS1_ADC_SHIFT 0 | 33 | #define STATUS1_ADC_SHIFT 0 |
@@ -95,7 +93,6 @@ static struct max8997_muic_irq muic_irqs[] = { | |||
95 | 93 | ||
96 | struct max8997_muic_info { | 94 | struct max8997_muic_info { |
97 | struct device *dev; | 95 | struct device *dev; |
98 | struct max8997_dev *iodev; | ||
99 | struct i2c_client *muic; | 96 | struct i2c_client *muic; |
100 | struct max8997_muic_platform_data *muic_pdata; | 97 | struct max8997_muic_platform_data *muic_pdata; |
101 | 98 | ||
@@ -106,12 +103,28 @@ struct max8997_muic_info { | |||
106 | int pre_adc; | 103 | int pre_adc; |
107 | 104 | ||
108 | struct mutex mutex; | 105 | struct mutex mutex; |
106 | |||
107 | struct extcon_dev *edev; | ||
108 | }; | ||
109 | |||
110 | const char *max8997_extcon_cable[] = { | ||
111 | [0] = "USB", | ||
112 | [1] = "USB-Host", | ||
113 | [2] = "TA", | ||
114 | [3] = "Fast-charger", | ||
115 | [4] = "Slow-charger", | ||
116 | [5] = "Charge-downstream", | ||
117 | [6] = "MHL", | ||
118 | [7] = "Dock-desk", | ||
119 | [7] = "Dock-card", | ||
120 | [8] = "JIG", | ||
121 | |||
122 | NULL, | ||
109 | }; | 123 | }; |
110 | 124 | ||
111 | static int max8997_muic_handle_usb(struct max8997_muic_info *info, | 125 | static int max8997_muic_handle_usb(struct max8997_muic_info *info, |
112 | enum max8997_muic_usb_type usb_type, bool attached) | 126 | enum max8997_muic_usb_type usb_type, bool attached) |
113 | { | 127 | { |
114 | struct max8997_muic_platform_data *mdata = info->muic_pdata; | ||
115 | int ret = 0; | 128 | int ret = 0; |
116 | 129 | ||
117 | if (usb_type == MAX8997_USB_HOST) { | 130 | if (usb_type == MAX8997_USB_HOST) { |
@@ -125,25 +138,25 @@ static int max8997_muic_handle_usb(struct max8997_muic_info *info, | |||
125 | } | 138 | } |
126 | } | 139 | } |
127 | 140 | ||
128 | if (mdata->usb_callback) | 141 | switch (usb_type) { |
129 | mdata->usb_callback(usb_type, attached); | 142 | case MAX8997_USB_HOST: |
143 | extcon_set_cable_state(info->edev, "USB-Host", attached); | ||
144 | break; | ||
145 | case MAX8997_USB_DEVICE: | ||
146 | extcon_set_cable_state(info->edev, "USB", attached); | ||
147 | break; | ||
148 | default: | ||
149 | ret = -EINVAL; | ||
150 | break; | ||
151 | } | ||
152 | |||
130 | out: | 153 | out: |
131 | return ret; | 154 | return ret; |
132 | } | 155 | } |
133 | 156 | ||
134 | static void max8997_muic_handle_mhl(struct max8997_muic_info *info, | ||
135 | bool attached) | ||
136 | { | ||
137 | struct max8997_muic_platform_data *mdata = info->muic_pdata; | ||
138 | |||
139 | if (mdata->mhl_callback) | ||
140 | mdata->mhl_callback(attached); | ||
141 | } | ||
142 | |||
143 | static int max8997_muic_handle_dock(struct max8997_muic_info *info, | 157 | static int max8997_muic_handle_dock(struct max8997_muic_info *info, |
144 | int adc, bool attached) | 158 | int adc, bool attached) |
145 | { | 159 | { |
146 | struct max8997_muic_platform_data *mdata = info->muic_pdata; | ||
147 | int ret = 0; | 160 | int ret = 0; |
148 | 161 | ||
149 | /* switch to AUDIO */ | 162 | /* switch to AUDIO */ |
@@ -157,14 +170,13 @@ static int max8997_muic_handle_dock(struct max8997_muic_info *info, | |||
157 | 170 | ||
158 | switch (adc) { | 171 | switch (adc) { |
159 | case MAX8997_ADC_DESKDOCK: | 172 | case MAX8997_ADC_DESKDOCK: |
160 | if (mdata->deskdock_callback) | 173 | extcon_set_cable_state(info->edev, "Dock-desk", attached); |
161 | mdata->deskdock_callback(attached); | ||
162 | break; | 174 | break; |
163 | case MAX8997_ADC_CARDOCK: | 175 | case MAX8997_ADC_CARDOCK: |
164 | if (mdata->cardock_callback) | 176 | extcon_set_cable_state(info->edev, "Dock-card", attached); |
165 | mdata->cardock_callback(attached); | ||
166 | break; | 177 | break; |
167 | default: | 178 | default: |
179 | ret = -EINVAL; | ||
168 | break; | 180 | break; |
169 | } | 181 | } |
170 | out: | 182 | out: |
@@ -174,7 +186,6 @@ out: | |||
174 | static int max8997_muic_handle_jig_uart(struct max8997_muic_info *info, | 186 | static int max8997_muic_handle_jig_uart(struct max8997_muic_info *info, |
175 | bool attached) | 187 | bool attached) |
176 | { | 188 | { |
177 | struct max8997_muic_platform_data *mdata = info->muic_pdata; | ||
178 | int ret = 0; | 189 | int ret = 0; |
179 | 190 | ||
180 | /* switch to UART */ | 191 | /* switch to UART */ |
@@ -186,8 +197,7 @@ static int max8997_muic_handle_jig_uart(struct max8997_muic_info *info, | |||
186 | goto out; | 197 | goto out; |
187 | } | 198 | } |
188 | 199 | ||
189 | if (mdata->uart_callback) | 200 | extcon_set_cable_state(info->edev, "JIG", attached); |
190 | mdata->uart_callback(attached); | ||
191 | out: | 201 | out: |
192 | return ret; | 202 | return ret; |
193 | } | 203 | } |
@@ -201,7 +211,7 @@ static int max8997_muic_handle_adc_detach(struct max8997_muic_info *info) | |||
201 | ret = max8997_muic_handle_usb(info, MAX8997_USB_HOST, false); | 211 | ret = max8997_muic_handle_usb(info, MAX8997_USB_HOST, false); |
202 | break; | 212 | break; |
203 | case MAX8997_ADC_MHL: | 213 | case MAX8997_ADC_MHL: |
204 | max8997_muic_handle_mhl(info, false); | 214 | extcon_set_cable_state(info->edev, "MHL", false); |
205 | break; | 215 | break; |
206 | case MAX8997_ADC_JIG_USB_1: | 216 | case MAX8997_ADC_JIG_USB_1: |
207 | case MAX8997_ADC_JIG_USB_2: | 217 | case MAX8997_ADC_JIG_USB_2: |
@@ -230,7 +240,7 @@ static int max8997_muic_handle_adc(struct max8997_muic_info *info, int adc) | |||
230 | ret = max8997_muic_handle_usb(info, MAX8997_USB_HOST, true); | 240 | ret = max8997_muic_handle_usb(info, MAX8997_USB_HOST, true); |
231 | break; | 241 | break; |
232 | case MAX8997_ADC_MHL: | 242 | case MAX8997_ADC_MHL: |
233 | max8997_muic_handle_mhl(info, true); | 243 | extcon_set_cable_state(info->edev, "MHL", true); |
234 | break; | 244 | break; |
235 | case MAX8997_ADC_JIG_USB_1: | 245 | case MAX8997_ADC_JIG_USB_1: |
236 | case MAX8997_ADC_JIG_USB_2: | 246 | case MAX8997_ADC_JIG_USB_2: |
@@ -247,10 +257,40 @@ static int max8997_muic_handle_adc(struct max8997_muic_info *info, int adc) | |||
247 | ret = max8997_muic_handle_adc_detach(info); | 257 | ret = max8997_muic_handle_adc_detach(info); |
248 | break; | 258 | break; |
249 | default: | 259 | default: |
250 | break; | 260 | ret = -EINVAL; |
261 | goto out; | ||
251 | } | 262 | } |
252 | 263 | ||
253 | info->pre_adc = adc; | 264 | info->pre_adc = adc; |
265 | out: | ||
266 | return ret; | ||
267 | } | ||
268 | |||
269 | static int max8997_muic_handle_charger_type_detach( | ||
270 | struct max8997_muic_info *info) | ||
271 | { | ||
272 | int ret = 0; | ||
273 | |||
274 | switch (info->pre_charger_type) { | ||
275 | case MAX8997_CHARGER_TYPE_USB: | ||
276 | extcon_set_cable_state(info->edev, "USB", false); | ||
277 | break; | ||
278 | case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT: | ||
279 | extcon_set_cable_state(info->edev, "Charge-downstream", false); | ||
280 | break; | ||
281 | case MAX8997_CHARGER_TYPE_DEDICATED_CHG: | ||
282 | extcon_set_cable_state(info->edev, "TA", false); | ||
283 | break; | ||
284 | case MAX8997_CHARGER_TYPE_500MA: | ||
285 | extcon_set_cable_state(info->edev, "Slow-charger", false); | ||
286 | break; | ||
287 | case MAX8997_CHARGER_TYPE_1A: | ||
288 | extcon_set_cable_state(info->edev, "Fast-charger", false); | ||
289 | break; | ||
290 | default: | ||
291 | ret = -EINVAL; | ||
292 | break; | ||
293 | } | ||
254 | 294 | ||
255 | return ret; | 295 | return ret; |
256 | } | 296 | } |
@@ -258,7 +298,6 @@ static int max8997_muic_handle_adc(struct max8997_muic_info *info, int adc) | |||
258 | static int max8997_muic_handle_charger_type(struct max8997_muic_info *info, | 298 | static int max8997_muic_handle_charger_type(struct max8997_muic_info *info, |
259 | enum max8997_muic_charger_type charger_type) | 299 | enum max8997_muic_charger_type charger_type) |
260 | { | 300 | { |
261 | struct max8997_muic_platform_data *mdata = info->muic_pdata; | ||
262 | u8 adc; | 301 | u8 adc; |
263 | int ret; | 302 | int ret; |
264 | 303 | ||
@@ -270,30 +309,29 @@ static int max8997_muic_handle_charger_type(struct max8997_muic_info *info, | |||
270 | 309 | ||
271 | switch (charger_type) { | 310 | switch (charger_type) { |
272 | case MAX8997_CHARGER_TYPE_NONE: | 311 | case MAX8997_CHARGER_TYPE_NONE: |
273 | if (mdata->charger_callback) | 312 | ret = max8997_muic_handle_charger_type_detach(info); |
274 | mdata->charger_callback(false, charger_type); | ||
275 | if (info->pre_charger_type == MAX8997_CHARGER_TYPE_USB) { | ||
276 | max8997_muic_handle_usb(info, | ||
277 | MAX8997_USB_DEVICE, false); | ||
278 | } | ||
279 | break; | 313 | break; |
280 | case MAX8997_CHARGER_TYPE_USB: | 314 | case MAX8997_CHARGER_TYPE_USB: |
281 | if ((adc & STATUS1_ADC_MASK) == MAX8997_ADC_OPEN) { | 315 | if ((adc & STATUS1_ADC_MASK) == MAX8997_ADC_OPEN) { |
282 | max8997_muic_handle_usb(info, | 316 | max8997_muic_handle_usb(info, |
283 | MAX8997_USB_DEVICE, true); | 317 | MAX8997_USB_DEVICE, true); |
284 | } | 318 | } |
285 | if (mdata->charger_callback) | ||
286 | mdata->charger_callback(true, charger_type); | ||
287 | break; | 319 | break; |
288 | case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT: | 320 | case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT: |
321 | extcon_set_cable_state(info->edev, "Charge-downstream", true); | ||
322 | break; | ||
289 | case MAX8997_CHARGER_TYPE_DEDICATED_CHG: | 323 | case MAX8997_CHARGER_TYPE_DEDICATED_CHG: |
324 | extcon_set_cable_state(info->edev, "TA", true); | ||
325 | break; | ||
290 | case MAX8997_CHARGER_TYPE_500MA: | 326 | case MAX8997_CHARGER_TYPE_500MA: |
327 | extcon_set_cable_state(info->edev, "Slow-charger", true); | ||
328 | break; | ||
291 | case MAX8997_CHARGER_TYPE_1A: | 329 | case MAX8997_CHARGER_TYPE_1A: |
292 | if (mdata->charger_callback) | 330 | extcon_set_cable_state(info->edev, "Fast-charger", true); |
293 | mdata->charger_callback(true, charger_type); | ||
294 | break; | 331 | break; |
295 | default: | 332 | default: |
296 | break; | 333 | ret = -EINVAL; |
334 | goto out; | ||
297 | } | 335 | } |
298 | 336 | ||
299 | info->pre_charger_type = charger_type; | 337 | info->pre_charger_type = charger_type; |
@@ -305,18 +343,17 @@ static void max8997_muic_irq_work(struct work_struct *work) | |||
305 | { | 343 | { |
306 | struct max8997_muic_info *info = container_of(work, | 344 | struct max8997_muic_info *info = container_of(work, |
307 | struct max8997_muic_info, irq_work); | 345 | struct max8997_muic_info, irq_work); |
308 | struct max8997_platform_data *pdata = | 346 | struct max8997_dev *max8997 = i2c_get_clientdata(info->muic); |
309 | dev_get_platdata(info->iodev->dev); | 347 | u8 status[2]; |
310 | u8 status[3]; | ||
311 | u8 adc, chg_type; | 348 | u8 adc, chg_type; |
312 | 349 | ||
313 | int irq_type = info->irq - pdata->irq_base; | 350 | int irq_type = info->irq - max8997->irq_base; |
314 | int ret; | 351 | int ret; |
315 | 352 | ||
316 | mutex_lock(&info->mutex); | 353 | mutex_lock(&info->mutex); |
317 | 354 | ||
318 | ret = max8997_bulk_read(info->muic, MAX8997_MUIC_REG_STATUS1, | 355 | ret = max8997_bulk_read(info->muic, MAX8997_MUIC_REG_STATUS1, |
319 | 3, status); | 356 | 2, status); |
320 | if (ret) { | 357 | if (ret) { |
321 | dev_err(info->dev, "failed to read muic register\n"); | 358 | dev_err(info->dev, "failed to read muic register\n"); |
322 | mutex_unlock(&info->mutex); | 359 | mutex_unlock(&info->mutex); |
@@ -340,8 +377,8 @@ static void max8997_muic_irq_work(struct work_struct *work) | |||
340 | max8997_muic_handle_charger_type(info, chg_type); | 377 | max8997_muic_handle_charger_type(info, chg_type); |
341 | break; | 378 | break; |
342 | default: | 379 | default: |
343 | dev_info(info->dev, "misc interrupt: %s occurred\n", | 380 | dev_info(info->dev, "misc interrupt: irq %d occurred\n", |
344 | muic_irqs[irq_type].name); | 381 | irq_type); |
345 | break; | 382 | break; |
346 | } | 383 | } |
347 | 384 | ||
@@ -387,21 +424,10 @@ static void max8997_muic_detect_dev(struct max8997_muic_info *info) | |||
387 | max8997_muic_handle_charger_type(info, chg_type); | 424 | max8997_muic_handle_charger_type(info, chg_type); |
388 | } | 425 | } |
389 | 426 | ||
390 | static void max8997_initialize_device(struct max8997_muic_info *info) | ||
391 | { | ||
392 | struct max8997_muic_platform_data *mdata = info->muic_pdata; | ||
393 | int i; | ||
394 | |||
395 | for (i = 0; i < mdata->num_init_data; i++) { | ||
396 | max8997_write_reg(info->muic, mdata->init_data[i].addr, | ||
397 | mdata->init_data[i].data); | ||
398 | } | ||
399 | } | ||
400 | |||
401 | static int __devinit max8997_muic_probe(struct platform_device *pdev) | 427 | static int __devinit max8997_muic_probe(struct platform_device *pdev) |
402 | { | 428 | { |
403 | struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 429 | struct max8997_dev *max8997 = dev_get_drvdata(pdev->dev.parent); |
404 | struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev); | 430 | struct max8997_platform_data *pdata = dev_get_platdata(max8997->dev); |
405 | struct max8997_muic_info *info; | 431 | struct max8997_muic_info *info; |
406 | int ret, i; | 432 | int ret, i; |
407 | 433 | ||
@@ -412,16 +438,8 @@ static int __devinit max8997_muic_probe(struct platform_device *pdev) | |||
412 | goto err_kfree; | 438 | goto err_kfree; |
413 | } | 439 | } |
414 | 440 | ||
415 | if (!pdata->muic_pdata) { | ||
416 | dev_err(&pdev->dev, "failed to get platform_data\n"); | ||
417 | ret = -EINVAL; | ||
418 | goto err_pdata; | ||
419 | } | ||
420 | info->muic_pdata = pdata->muic_pdata; | ||
421 | |||
422 | info->dev = &pdev->dev; | 441 | info->dev = &pdev->dev; |
423 | info->iodev = iodev; | 442 | info->muic = max8997->muic; |
424 | info->muic = iodev->muic; | ||
425 | 443 | ||
426 | platform_set_drvdata(pdev, info); | 444 | platform_set_drvdata(pdev, info); |
427 | mutex_init(&info->mutex); | 445 | mutex_init(&info->mutex); |
@@ -444,18 +462,41 @@ static int __devinit max8997_muic_probe(struct platform_device *pdev) | |||
444 | } | 462 | } |
445 | } | 463 | } |
446 | 464 | ||
465 | /* External connector */ | ||
466 | info->edev = kzalloc(sizeof(struct extcon_dev), GFP_KERNEL); | ||
467 | if (!info->edev) { | ||
468 | dev_err(&pdev->dev, "failed to allocate memory for extcon\n"); | ||
469 | ret = -ENOMEM; | ||
470 | goto err_irq; | ||
471 | } | ||
472 | info->edev->name = DEV_NAME; | ||
473 | info->edev->supported_cable = max8997_extcon_cable; | ||
474 | ret = extcon_dev_register(info->edev, NULL); | ||
475 | if (ret) { | ||
476 | dev_err(&pdev->dev, "failed to register extcon device\n"); | ||
477 | goto err_extcon; | ||
478 | } | ||
479 | |||
447 | /* Initialize registers according to platform data */ | 480 | /* Initialize registers according to platform data */ |
448 | max8997_initialize_device(info); | 481 | if (pdata->muic_pdata) { |
482 | struct max8997_muic_platform_data *mdata = info->muic_pdata; | ||
483 | |||
484 | for (i = 0; i < mdata->num_init_data; i++) { | ||
485 | max8997_write_reg(info->muic, mdata->init_data[i].addr, | ||
486 | mdata->init_data[i].data); | ||
487 | } | ||
488 | } | ||
449 | 489 | ||
450 | /* Initial device detection */ | 490 | /* Initial device detection */ |
451 | max8997_muic_detect_dev(info); | 491 | max8997_muic_detect_dev(info); |
452 | 492 | ||
453 | return ret; | 493 | return ret; |
454 | 494 | ||
495 | err_extcon: | ||
496 | kfree(info->edev); | ||
455 | err_irq: | 497 | err_irq: |
456 | while (--i >= 0) | 498 | while (--i >= 0) |
457 | free_irq(pdata->irq_base + muic_irqs[i].irq, info); | 499 | free_irq(pdata->irq_base + muic_irqs[i].irq, info); |
458 | err_pdata: | ||
459 | kfree(info); | 500 | kfree(info); |
460 | err_kfree: | 501 | err_kfree: |
461 | return ret; | 502 | return ret; |
@@ -464,14 +505,15 @@ err_kfree: | |||
464 | static int __devexit max8997_muic_remove(struct platform_device *pdev) | 505 | static int __devexit max8997_muic_remove(struct platform_device *pdev) |
465 | { | 506 | { |
466 | struct max8997_muic_info *info = platform_get_drvdata(pdev); | 507 | struct max8997_muic_info *info = platform_get_drvdata(pdev); |
467 | struct max8997_platform_data *pdata = | 508 | struct max8997_dev *max8997 = i2c_get_clientdata(info->muic); |
468 | dev_get_platdata(info->iodev->dev); | ||
469 | int i; | 509 | int i; |
470 | 510 | ||
471 | for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) | 511 | for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) |
472 | free_irq(pdata->irq_base + muic_irqs[i].irq, info); | 512 | free_irq(max8997->irq_base + muic_irqs[i].irq, info); |
473 | cancel_work_sync(&info->irq_work); | 513 | cancel_work_sync(&info->irq_work); |
474 | 514 | ||
515 | extcon_dev_unregister(info->edev); | ||
516 | |||
475 | kfree(info); | 517 | kfree(info); |
476 | 518 | ||
477 | return 0; | 519 | return 0; |
@@ -479,7 +521,7 @@ static int __devexit max8997_muic_remove(struct platform_device *pdev) | |||
479 | 521 | ||
480 | static struct platform_driver max8997_muic_driver = { | 522 | static struct platform_driver max8997_muic_driver = { |
481 | .driver = { | 523 | .driver = { |
482 | .name = "max8997-muic", | 524 | .name = DEV_NAME, |
483 | .owner = THIS_MODULE, | 525 | .owner = THIS_MODULE, |
484 | }, | 526 | }, |
485 | .probe = max8997_muic_probe, | 527 | .probe = max8997_muic_probe, |
@@ -488,6 +530,6 @@ static struct platform_driver max8997_muic_driver = { | |||
488 | 530 | ||
489 | module_platform_driver(max8997_muic_driver); | 531 | module_platform_driver(max8997_muic_driver); |
490 | 532 | ||
491 | MODULE_DESCRIPTION("Maxim MAX8997 MUIC driver"); | 533 | MODULE_DESCRIPTION("Maxim MAX8997 Extcon driver"); |
492 | MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>"); | 534 | MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>"); |
493 | MODULE_LICENSE("GPL"); | 535 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/extcon/extcon_class.c b/drivers/extcon/extcon_class.c new file mode 100644 index 000000000000..f598a700ec15 --- /dev/null +++ b/drivers/extcon/extcon_class.c | |||
@@ -0,0 +1,832 @@ | |||
1 | /* | ||
2 | * drivers/extcon/extcon_class.c | ||
3 | * | ||
4 | * External connector (extcon) class driver | ||
5 | * | ||
6 | * Copyright (C) 2012 Samsung Electronics | ||
7 | * Author: Donggeun Kim <dg77.kim@samsung.com> | ||
8 | * Author: MyungJoo Ham <myungjoo.ham@samsung.com> | ||
9 | * | ||
10 | * based on android/drivers/switch/switch_class.c | ||
11 | * Copyright (C) 2008 Google, Inc. | ||
12 | * Author: Mike Lockwood <lockwood@android.com> | ||
13 | * | ||
14 | * This software is licensed under the terms of the GNU General Public | ||
15 | * License version 2, as published by the Free Software Foundation, and | ||
16 | * may be copied, distributed, and modified under those terms. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #include <linux/module.h> | ||
26 | #include <linux/types.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/device.h> | ||
29 | #include <linux/fs.h> | ||
30 | #include <linux/err.h> | ||
31 | #include <linux/extcon.h> | ||
32 | #include <linux/slab.h> | ||
33 | |||
34 | /* | ||
35 | * extcon_cable_name suggests the standard cable names for commonly used | ||
36 | * cable types. | ||
37 | * | ||
38 | * However, please do not use extcon_cable_name directly for extcon_dev | ||
39 | * struct's supported_cable pointer unless your device really supports | ||
40 | * every single port-type of the following cable names. Please choose cable | ||
41 | * names that are actually used in your extcon device. | ||
42 | */ | ||
43 | const char *extcon_cable_name[] = { | ||
44 | [EXTCON_USB] = "USB", | ||
45 | [EXTCON_USB_HOST] = "USB-Host", | ||
46 | [EXTCON_TA] = "TA", | ||
47 | [EXTCON_FAST_CHARGER] = "Fast-charger", | ||
48 | [EXTCON_SLOW_CHARGER] = "Slow-charger", | ||
49 | [EXTCON_CHARGE_DOWNSTREAM] = "Charge-downstream", | ||
50 | [EXTCON_HDMI] = "HDMI", | ||
51 | [EXTCON_MHL] = "MHL", | ||
52 | [EXTCON_DVI] = "DVI", | ||
53 | [EXTCON_VGA] = "VGA", | ||
54 | [EXTCON_DOCK] = "Dock", | ||
55 | [EXTCON_LINE_IN] = "Line-in", | ||
56 | [EXTCON_LINE_OUT] = "Line-out", | ||
57 | [EXTCON_MIC_IN] = "Microphone", | ||
58 | [EXTCON_HEADPHONE_OUT] = "Headphone", | ||
59 | [EXTCON_SPDIF_IN] = "SPDIF-in", | ||
60 | [EXTCON_SPDIF_OUT] = "SPDIF-out", | ||
61 | [EXTCON_VIDEO_IN] = "Video-in", | ||
62 | [EXTCON_VIDEO_OUT] = "Video-out", | ||
63 | [EXTCON_MECHANICAL] = "Mechanical", | ||
64 | |||
65 | NULL, | ||
66 | }; | ||
67 | |||
68 | struct class *extcon_class; | ||
69 | #if defined(CONFIG_ANDROID) | ||
70 | static struct class_compat *switch_class; | ||
71 | #endif /* CONFIG_ANDROID */ | ||
72 | |||
73 | static LIST_HEAD(extcon_dev_list); | ||
74 | static DEFINE_MUTEX(extcon_dev_list_lock); | ||
75 | |||
76 | /** | ||
77 | * check_mutually_exclusive - Check if new_state violates mutually_exclusive | ||
78 | * condition. | ||
79 | * @edev: the extcon device | ||
80 | * @new_state: new cable attach status for @edev | ||
81 | * | ||
82 | * Returns 0 if nothing violates. Returns the index + 1 for the first | ||
83 | * violated condition. | ||
84 | */ | ||
85 | static int check_mutually_exclusive(struct extcon_dev *edev, u32 new_state) | ||
86 | { | ||
87 | int i = 0; | ||
88 | |||
89 | if (!edev->mutually_exclusive) | ||
90 | return 0; | ||
91 | |||
92 | for (i = 0; edev->mutually_exclusive[i]; i++) { | ||
93 | int count = 0, j; | ||
94 | u32 correspondants = new_state & edev->mutually_exclusive[i]; | ||
95 | u32 exp = 1; | ||
96 | |||
97 | for (j = 0; j < 32; j++) { | ||
98 | if (exp & correspondants) | ||
99 | count++; | ||
100 | if (count > 1) | ||
101 | return i + 1; | ||
102 | exp <<= 1; | ||
103 | } | ||
104 | } | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static ssize_t state_show(struct device *dev, struct device_attribute *attr, | ||
110 | char *buf) | ||
111 | { | ||
112 | int i, count = 0; | ||
113 | struct extcon_dev *edev = (struct extcon_dev *) dev_get_drvdata(dev); | ||
114 | |||
115 | if (edev->print_state) { | ||
116 | int ret = edev->print_state(edev, buf); | ||
117 | |||
118 | if (ret >= 0) | ||
119 | return ret; | ||
120 | /* Use default if failed */ | ||
121 | } | ||
122 | |||
123 | if (edev->max_supported == 0) | ||
124 | return sprintf(buf, "%u\n", edev->state); | ||
125 | |||
126 | for (i = 0; i < SUPPORTED_CABLE_MAX; i++) { | ||
127 | if (!edev->supported_cable[i]) | ||
128 | break; | ||
129 | count += sprintf(buf + count, "%s=%d\n", | ||
130 | edev->supported_cable[i], | ||
131 | !!(edev->state & (1 << i))); | ||
132 | } | ||
133 | |||
134 | return count; | ||
135 | } | ||
136 | |||
137 | int extcon_set_state(struct extcon_dev *edev, u32 state); | ||
138 | static ssize_t state_store(struct device *dev, struct device_attribute *attr, | ||
139 | const char *buf, size_t count) | ||
140 | { | ||
141 | u32 state; | ||
142 | ssize_t ret = 0; | ||
143 | struct extcon_dev *edev = (struct extcon_dev *) dev_get_drvdata(dev); | ||
144 | |||
145 | ret = sscanf(buf, "0x%x", &state); | ||
146 | if (ret == 0) | ||
147 | ret = -EINVAL; | ||
148 | else | ||
149 | ret = extcon_set_state(edev, state); | ||
150 | |||
151 | if (ret < 0) | ||
152 | return ret; | ||
153 | |||
154 | return count; | ||
155 | } | ||
156 | |||
157 | static ssize_t name_show(struct device *dev, struct device_attribute *attr, | ||
158 | char *buf) | ||
159 | { | ||
160 | struct extcon_dev *edev = (struct extcon_dev *) dev_get_drvdata(dev); | ||
161 | |||
162 | /* Optional callback given by the user */ | ||
163 | if (edev->print_name) { | ||
164 | int ret = edev->print_name(edev, buf); | ||
165 | if (ret >= 0) | ||
166 | return ret; | ||
167 | } | ||
168 | |||
169 | return sprintf(buf, "%s\n", dev_name(edev->dev)); | ||
170 | } | ||
171 | |||
172 | static ssize_t cable_name_show(struct device *dev, | ||
173 | struct device_attribute *attr, char *buf) | ||
174 | { | ||
175 | struct extcon_cable *cable = container_of(attr, struct extcon_cable, | ||
176 | attr_name); | ||
177 | |||
178 | return sprintf(buf, "%s\n", | ||
179 | cable->edev->supported_cable[cable->cable_index]); | ||
180 | } | ||
181 | |||
182 | static ssize_t cable_state_show(struct device *dev, | ||
183 | struct device_attribute *attr, char *buf) | ||
184 | { | ||
185 | struct extcon_cable *cable = container_of(attr, struct extcon_cable, | ||
186 | attr_state); | ||
187 | |||
188 | return sprintf(buf, "%d\n", | ||
189 | extcon_get_cable_state_(cable->edev, | ||
190 | cable->cable_index)); | ||
191 | } | ||
192 | |||
193 | static ssize_t cable_state_store(struct device *dev, | ||
194 | struct device_attribute *attr, const char *buf, | ||
195 | size_t count) | ||
196 | { | ||
197 | struct extcon_cable *cable = container_of(attr, struct extcon_cable, | ||
198 | attr_state); | ||
199 | int ret, state; | ||
200 | |||
201 | ret = sscanf(buf, "%d", &state); | ||
202 | if (ret == 0) | ||
203 | ret = -EINVAL; | ||
204 | else | ||
205 | ret = extcon_set_cable_state_(cable->edev, cable->cable_index, | ||
206 | state); | ||
207 | |||
208 | if (ret < 0) | ||
209 | return ret; | ||
210 | return count; | ||
211 | } | ||
212 | |||
213 | /** | ||
214 | * extcon_update_state() - Update the cable attach states of the extcon device | ||
215 | * only for the masked bits. | ||
216 | * @edev: the extcon device | ||
217 | * @mask: the bit mask to designate updated bits. | ||
218 | * @state: new cable attach status for @edev | ||
219 | * | ||
220 | * Changing the state sends uevent with environment variable containing | ||
221 | * the name of extcon device (envp[0]) and the state output (envp[1]). | ||
222 | * Tizen uses this format for extcon device to get events from ports. | ||
223 | * Android uses this format as well. | ||
224 | * | ||
225 | * Note that the notifier provides which bits are changed in the state | ||
226 | * variable with the val parameter (second) to the callback. | ||
227 | */ | ||
228 | int extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state) | ||
229 | { | ||
230 | char name_buf[120]; | ||
231 | char state_buf[120]; | ||
232 | char *prop_buf; | ||
233 | char *envp[3]; | ||
234 | int env_offset = 0; | ||
235 | int length; | ||
236 | unsigned long flags; | ||
237 | |||
238 | spin_lock_irqsave(&edev->lock, flags); | ||
239 | |||
240 | if (edev->state != ((edev->state & ~mask) | (state & mask))) { | ||
241 | u32 old_state = edev->state; | ||
242 | |||
243 | if (check_mutually_exclusive(edev, (edev->state & ~mask) | | ||
244 | (state & mask))) { | ||
245 | spin_unlock_irqrestore(&edev->lock, flags); | ||
246 | return -EPERM; | ||
247 | } | ||
248 | |||
249 | edev->state &= ~mask; | ||
250 | edev->state |= state & mask; | ||
251 | |||
252 | raw_notifier_call_chain(&edev->nh, old_state, edev); | ||
253 | |||
254 | /* This could be in interrupt handler */ | ||
255 | prop_buf = (char *)get_zeroed_page(GFP_ATOMIC); | ||
256 | if (prop_buf) { | ||
257 | length = name_show(edev->dev, NULL, prop_buf); | ||
258 | if (length > 0) { | ||
259 | if (prop_buf[length - 1] == '\n') | ||
260 | prop_buf[length - 1] = 0; | ||
261 | snprintf(name_buf, sizeof(name_buf), | ||
262 | "NAME=%s", prop_buf); | ||
263 | envp[env_offset++] = name_buf; | ||
264 | } | ||
265 | length = state_show(edev->dev, NULL, prop_buf); | ||
266 | if (length > 0) { | ||
267 | if (prop_buf[length - 1] == '\n') | ||
268 | prop_buf[length - 1] = 0; | ||
269 | snprintf(state_buf, sizeof(state_buf), | ||
270 | "STATE=%s", prop_buf); | ||
271 | envp[env_offset++] = state_buf; | ||
272 | } | ||
273 | envp[env_offset] = NULL; | ||
274 | /* Unlock early before uevent */ | ||
275 | spin_unlock_irqrestore(&edev->lock, flags); | ||
276 | |||
277 | kobject_uevent_env(&edev->dev->kobj, KOBJ_CHANGE, envp); | ||
278 | free_page((unsigned long)prop_buf); | ||
279 | } else { | ||
280 | /* Unlock early before uevent */ | ||
281 | spin_unlock_irqrestore(&edev->lock, flags); | ||
282 | |||
283 | dev_err(edev->dev, "out of memory in extcon_set_state\n"); | ||
284 | kobject_uevent(&edev->dev->kobj, KOBJ_CHANGE); | ||
285 | } | ||
286 | } else { | ||
287 | /* No changes */ | ||
288 | spin_unlock_irqrestore(&edev->lock, flags); | ||
289 | } | ||
290 | |||
291 | return 0; | ||
292 | } | ||
293 | EXPORT_SYMBOL_GPL(extcon_update_state); | ||
294 | |||
295 | /** | ||
296 | * extcon_set_state() - Set the cable attach states of the extcon device. | ||
297 | * @edev: the extcon device | ||
298 | * @state: new cable attach status for @edev | ||
299 | * | ||
300 | * Note that notifier provides which bits are changed in the state | ||
301 | * variable with the val parameter (second) to the callback. | ||
302 | */ | ||
303 | int extcon_set_state(struct extcon_dev *edev, u32 state) | ||
304 | { | ||
305 | return extcon_update_state(edev, 0xffffffff, state); | ||
306 | } | ||
307 | EXPORT_SYMBOL_GPL(extcon_set_state); | ||
308 | |||
309 | /** | ||
310 | * extcon_find_cable_index() - Get the cable index based on the cable name. | ||
311 | * @edev: the extcon device that has the cable. | ||
312 | * @cable_name: cable name to be searched. | ||
313 | * | ||
314 | * Note that accessing a cable state based on cable_index is faster than | ||
315 | * cable_name because using cable_name induces a loop with strncmp(). | ||
316 | * Thus, when get/set_cable_state is repeatedly used, using cable_index | ||
317 | * is recommended. | ||
318 | */ | ||
319 | int extcon_find_cable_index(struct extcon_dev *edev, const char *cable_name) | ||
320 | { | ||
321 | int i; | ||
322 | |||
323 | if (edev->supported_cable) { | ||
324 | for (i = 0; edev->supported_cable[i]; i++) { | ||
325 | if (!strncmp(edev->supported_cable[i], | ||
326 | cable_name, CABLE_NAME_MAX)) | ||
327 | return i; | ||
328 | } | ||
329 | } | ||
330 | |||
331 | return -EINVAL; | ||
332 | } | ||
333 | EXPORT_SYMBOL_GPL(extcon_find_cable_index); | ||
334 | |||
335 | /** | ||
336 | * extcon_get_cable_state_() - Get the status of a specific cable. | ||
337 | * @edev: the extcon device that has the cable. | ||
338 | * @index: cable index that can be retrieved by extcon_find_cable_index(). | ||
339 | */ | ||
340 | int extcon_get_cable_state_(struct extcon_dev *edev, int index) | ||
341 | { | ||
342 | if (index < 0 || (edev->max_supported && edev->max_supported <= index)) | ||
343 | return -EINVAL; | ||
344 | |||
345 | return !!(edev->state & (1 << index)); | ||
346 | } | ||
347 | EXPORT_SYMBOL_GPL(extcon_get_cable_state_); | ||
348 | |||
349 | /** | ||
350 | * extcon_get_cable_state() - Get the status of a specific cable. | ||
351 | * @edev: the extcon device that has the cable. | ||
352 | * @cable_name: cable name. | ||
353 | * | ||
354 | * Note that this is slower than extcon_get_cable_state_. | ||
355 | */ | ||
356 | int extcon_get_cable_state(struct extcon_dev *edev, const char *cable_name) | ||
357 | { | ||
358 | return extcon_get_cable_state_(edev, extcon_find_cable_index | ||
359 | (edev, cable_name)); | ||
360 | } | ||
361 | EXPORT_SYMBOL_GPL(extcon_get_cable_state); | ||
362 | |||
363 | /** | ||
364 | * extcon_get_cable_state_() - Set the status of a specific cable. | ||
365 | * @edev: the extcon device that has the cable. | ||
366 | * @index: cable index that can be retrieved by extcon_find_cable_index(). | ||
367 | * @cable_state: the new cable status. The default semantics is | ||
368 | * true: attached / false: detached. | ||
369 | */ | ||
370 | int extcon_set_cable_state_(struct extcon_dev *edev, | ||
371 | int index, bool cable_state) | ||
372 | { | ||
373 | u32 state; | ||
374 | |||
375 | if (index < 0 || (edev->max_supported && edev->max_supported <= index)) | ||
376 | return -EINVAL; | ||
377 | |||
378 | state = cable_state ? (1 << index) : 0; | ||
379 | return extcon_update_state(edev, 1 << index, state); | ||
380 | } | ||
381 | EXPORT_SYMBOL_GPL(extcon_set_cable_state_); | ||
382 | |||
383 | /** | ||
384 | * extcon_get_cable_state() - Set the status of a specific cable. | ||
385 | * @edev: the extcon device that has the cable. | ||
386 | * @cable_name: cable name. | ||
387 | * @cable_state: the new cable status. The default semantics is | ||
388 | * true: attached / false: detached. | ||
389 | * | ||
390 | * Note that this is slower than extcon_set_cable_state_. | ||
391 | */ | ||
392 | int extcon_set_cable_state(struct extcon_dev *edev, | ||
393 | const char *cable_name, bool cable_state) | ||
394 | { | ||
395 | return extcon_set_cable_state_(edev, extcon_find_cable_index | ||
396 | (edev, cable_name), cable_state); | ||
397 | } | ||
398 | EXPORT_SYMBOL_GPL(extcon_set_cable_state); | ||
399 | |||
400 | /** | ||
401 | * extcon_get_extcon_dev() - Get the extcon device instance from the name | ||
402 | * @extcon_name: The extcon name provided with extcon_dev_register() | ||
403 | */ | ||
404 | struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name) | ||
405 | { | ||
406 | struct extcon_dev *sd; | ||
407 | |||
408 | mutex_lock(&extcon_dev_list_lock); | ||
409 | list_for_each_entry(sd, &extcon_dev_list, entry) { | ||
410 | if (!strcmp(sd->name, extcon_name)) | ||
411 | goto out; | ||
412 | } | ||
413 | sd = NULL; | ||
414 | out: | ||
415 | mutex_unlock(&extcon_dev_list_lock); | ||
416 | return sd; | ||
417 | } | ||
418 | EXPORT_SYMBOL_GPL(extcon_get_extcon_dev); | ||
419 | |||
420 | static int _call_per_cable(struct notifier_block *nb, unsigned long val, | ||
421 | void *ptr) | ||
422 | { | ||
423 | struct extcon_specific_cable_nb *obj = container_of(nb, | ||
424 | struct extcon_specific_cable_nb, internal_nb); | ||
425 | struct extcon_dev *edev = ptr; | ||
426 | |||
427 | if ((val & (1 << obj->cable_index)) != | ||
428 | (edev->state & (1 << obj->cable_index))) { | ||
429 | bool cable_state = true; | ||
430 | |||
431 | obj->previous_value = val; | ||
432 | |||
433 | if (val & (1 << obj->cable_index)) | ||
434 | cable_state = false; | ||
435 | |||
436 | return obj->user_nb->notifier_call(obj->user_nb, | ||
437 | cable_state, ptr); | ||
438 | } | ||
439 | |||
440 | return NOTIFY_OK; | ||
441 | } | ||
442 | |||
443 | /** | ||
444 | * extcon_register_interest() - Register a notifier for a state change of a | ||
445 | * specific cable, not a entier set of cables of a | ||
446 | * extcon device. | ||
447 | * @obj: an empty extcon_specific_cable_nb object to be returned. | ||
448 | * @extcon_name: the name of extcon device. | ||
449 | * @cable_name: the target cable name. | ||
450 | * @nb: the notifier block to get notified. | ||
451 | * | ||
452 | * Provide an empty extcon_specific_cable_nb. extcon_register_interest() sets | ||
453 | * the struct for you. | ||
454 | * | ||
455 | * extcon_register_interest is a helper function for those who want to get | ||
456 | * notification for a single specific cable's status change. If a user wants | ||
457 | * to get notification for any changes of all cables of a extcon device, | ||
458 | * he/she should use the general extcon_register_notifier(). | ||
459 | * | ||
460 | * Note that the second parameter given to the callback of nb (val) is | ||
461 | * "old_state", not the current state. The current state can be retrieved | ||
462 | * by looking at the third pameter (edev pointer)'s state value. | ||
463 | */ | ||
464 | int extcon_register_interest(struct extcon_specific_cable_nb *obj, | ||
465 | const char *extcon_name, const char *cable_name, | ||
466 | struct notifier_block *nb) | ||
467 | { | ||
468 | if (!obj || !extcon_name || !cable_name || !nb) | ||
469 | return -EINVAL; | ||
470 | |||
471 | obj->edev = extcon_get_extcon_dev(extcon_name); | ||
472 | if (!obj->edev) | ||
473 | return -ENODEV; | ||
474 | |||
475 | obj->cable_index = extcon_find_cable_index(obj->edev, cable_name); | ||
476 | if (obj->cable_index < 0) | ||
477 | return -ENODEV; | ||
478 | |||
479 | obj->user_nb = nb; | ||
480 | |||
481 | obj->internal_nb.notifier_call = _call_per_cable; | ||
482 | |||
483 | return raw_notifier_chain_register(&obj->edev->nh, &obj->internal_nb); | ||
484 | } | ||
485 | |||
486 | /** | ||
487 | * extcon_unregister_interest() - Unregister the notifier registered by | ||
488 | * extcon_register_interest(). | ||
489 | * @obj: the extcon_specific_cable_nb object returned by | ||
490 | * extcon_register_interest(). | ||
491 | */ | ||
492 | int extcon_unregister_interest(struct extcon_specific_cable_nb *obj) | ||
493 | { | ||
494 | if (!obj) | ||
495 | return -EINVAL; | ||
496 | |||
497 | return raw_notifier_chain_unregister(&obj->edev->nh, &obj->internal_nb); | ||
498 | } | ||
499 | |||
500 | /** | ||
501 | * extcon_register_notifier() - Register a notifee to get notified by | ||
502 | * any attach status changes from the extcon. | ||
503 | * @edev: the extcon device. | ||
504 | * @nb: a notifier block to be registered. | ||
505 | * | ||
506 | * Note that the second parameter given to the callback of nb (val) is | ||
507 | * "old_state", not the current state. The current state can be retrieved | ||
508 | * by looking at the third pameter (edev pointer)'s state value. | ||
509 | */ | ||
510 | int extcon_register_notifier(struct extcon_dev *edev, | ||
511 | struct notifier_block *nb) | ||
512 | { | ||
513 | return raw_notifier_chain_register(&edev->nh, nb); | ||
514 | } | ||
515 | EXPORT_SYMBOL_GPL(extcon_register_notifier); | ||
516 | |||
517 | /** | ||
518 | * extcon_unregister_notifier() - Unregister a notifee from the extcon device. | ||
519 | * @edev: the extcon device. | ||
520 | * @nb: a registered notifier block to be unregistered. | ||
521 | */ | ||
522 | int extcon_unregister_notifier(struct extcon_dev *edev, | ||
523 | struct notifier_block *nb) | ||
524 | { | ||
525 | return raw_notifier_chain_unregister(&edev->nh, nb); | ||
526 | } | ||
527 | EXPORT_SYMBOL_GPL(extcon_unregister_notifier); | ||
528 | |||
529 | static struct device_attribute extcon_attrs[] = { | ||
530 | __ATTR(state, S_IRUGO | S_IWUSR, state_show, state_store), | ||
531 | __ATTR_RO(name), | ||
532 | __ATTR_NULL, | ||
533 | }; | ||
534 | |||
535 | static int create_extcon_class(void) | ||
536 | { | ||
537 | if (!extcon_class) { | ||
538 | extcon_class = class_create(THIS_MODULE, "extcon"); | ||
539 | if (IS_ERR(extcon_class)) | ||
540 | return PTR_ERR(extcon_class); | ||
541 | extcon_class->dev_attrs = extcon_attrs; | ||
542 | |||
543 | #if defined(CONFIG_ANDROID) | ||
544 | switch_class = class_compat_register("switch"); | ||
545 | if (WARN(!switch_class, "cannot allocate")) | ||
546 | return -ENOMEM; | ||
547 | #endif /* CONFIG_ANDROID */ | ||
548 | } | ||
549 | |||
550 | return 0; | ||
551 | } | ||
552 | |||
553 | static void extcon_cleanup(struct extcon_dev *edev, bool skip) | ||
554 | { | ||
555 | mutex_lock(&extcon_dev_list_lock); | ||
556 | list_del(&edev->entry); | ||
557 | mutex_unlock(&extcon_dev_list_lock); | ||
558 | |||
559 | if (!skip && get_device(edev->dev)) { | ||
560 | int index; | ||
561 | |||
562 | if (edev->mutually_exclusive && edev->max_supported) { | ||
563 | for (index = 0; edev->mutually_exclusive[index]; | ||
564 | index++) | ||
565 | kfree(edev->d_attrs_muex[index].attr.name); | ||
566 | kfree(edev->d_attrs_muex); | ||
567 | kfree(edev->attrs_muex); | ||
568 | } | ||
569 | |||
570 | for (index = 0; index < edev->max_supported; index++) | ||
571 | kfree(edev->cables[index].attr_g.name); | ||
572 | |||
573 | if (edev->max_supported) { | ||
574 | kfree(edev->extcon_dev_type.groups); | ||
575 | kfree(edev->cables); | ||
576 | } | ||
577 | |||
578 | device_unregister(edev->dev); | ||
579 | put_device(edev->dev); | ||
580 | } | ||
581 | |||
582 | kfree(edev->dev); | ||
583 | } | ||
584 | |||
585 | static void extcon_dev_release(struct device *dev) | ||
586 | { | ||
587 | struct extcon_dev *edev = (struct extcon_dev *) dev_get_drvdata(dev); | ||
588 | |||
589 | extcon_cleanup(edev, true); | ||
590 | } | ||
591 | |||
592 | static const char *muex_name = "mutually_exclusive"; | ||
593 | static void dummy_sysfs_dev_release(struct device *dev) | ||
594 | { | ||
595 | } | ||
596 | |||
597 | /** | ||
598 | * extcon_dev_register() - Register a new extcon device | ||
599 | * @edev : the new extcon device (should be allocated before calling) | ||
600 | * @dev : the parent device for this extcon device. | ||
601 | * | ||
602 | * Among the members of edev struct, please set the "user initializing data" | ||
603 | * in any case and set the "optional callbacks" if required. However, please | ||
604 | * do not set the values of "internal data", which are initialized by | ||
605 | * this function. | ||
606 | */ | ||
607 | int extcon_dev_register(struct extcon_dev *edev, struct device *dev) | ||
608 | { | ||
609 | int ret, index = 0; | ||
610 | |||
611 | if (!extcon_class) { | ||
612 | ret = create_extcon_class(); | ||
613 | if (ret < 0) | ||
614 | return ret; | ||
615 | } | ||
616 | |||
617 | if (edev->supported_cable) { | ||
618 | /* Get size of array */ | ||
619 | for (index = 0; edev->supported_cable[index]; index++) | ||
620 | ; | ||
621 | edev->max_supported = index; | ||
622 | } else { | ||
623 | edev->max_supported = 0; | ||
624 | } | ||
625 | |||
626 | if (index > SUPPORTED_CABLE_MAX) { | ||
627 | dev_err(edev->dev, "extcon: maximum number of supported cables exceeded.\n"); | ||
628 | return -EINVAL; | ||
629 | } | ||
630 | |||
631 | edev->dev = kzalloc(sizeof(struct device), GFP_KERNEL); | ||
632 | if (!edev->dev) | ||
633 | return -ENOMEM; | ||
634 | edev->dev->parent = dev; | ||
635 | edev->dev->class = extcon_class; | ||
636 | edev->dev->release = extcon_dev_release; | ||
637 | |||
638 | dev_set_name(edev->dev, edev->name ? edev->name : dev_name(dev)); | ||
639 | |||
640 | if (edev->max_supported) { | ||
641 | char buf[10]; | ||
642 | char *str; | ||
643 | struct extcon_cable *cable; | ||
644 | |||
645 | edev->cables = kzalloc(sizeof(struct extcon_cable) * | ||
646 | edev->max_supported, GFP_KERNEL); | ||
647 | if (!edev->cables) { | ||
648 | ret = -ENOMEM; | ||
649 | goto err_sysfs_alloc; | ||
650 | } | ||
651 | for (index = 0; index < edev->max_supported; index++) { | ||
652 | cable = &edev->cables[index]; | ||
653 | |||
654 | snprintf(buf, 10, "cable.%d", index); | ||
655 | str = kzalloc(sizeof(char) * (strlen(buf) + 1), | ||
656 | GFP_KERNEL); | ||
657 | if (!str) { | ||
658 | for (index--; index >= 0; index--) { | ||
659 | cable = &edev->cables[index]; | ||
660 | kfree(cable->attr_g.name); | ||
661 | } | ||
662 | ret = -ENOMEM; | ||
663 | |||
664 | goto err_alloc_cables; | ||
665 | } | ||
666 | strcpy(str, buf); | ||
667 | |||
668 | cable->edev = edev; | ||
669 | cable->cable_index = index; | ||
670 | cable->attrs[0] = &cable->attr_name.attr; | ||
671 | cable->attrs[1] = &cable->attr_state.attr; | ||
672 | cable->attrs[2] = NULL; | ||
673 | cable->attr_g.name = str; | ||
674 | cable->attr_g.attrs = cable->attrs; | ||
675 | |||
676 | cable->attr_name.attr.name = "name"; | ||
677 | cable->attr_name.attr.mode = 0444; | ||
678 | cable->attr_name.show = cable_name_show; | ||
679 | |||
680 | cable->attr_state.attr.name = "state"; | ||
681 | cable->attr_state.attr.mode = 0644; | ||
682 | cable->attr_state.show = cable_state_show; | ||
683 | cable->attr_state.store = cable_state_store; | ||
684 | } | ||
685 | } | ||
686 | |||
687 | if (edev->max_supported && edev->mutually_exclusive) { | ||
688 | char buf[80]; | ||
689 | char *name; | ||
690 | |||
691 | /* Count the size of mutually_exclusive array */ | ||
692 | for (index = 0; edev->mutually_exclusive[index]; index++) | ||
693 | ; | ||
694 | |||
695 | edev->attrs_muex = kzalloc(sizeof(struct attribute *) * | ||
696 | (index + 1), GFP_KERNEL); | ||
697 | if (!edev->attrs_muex) { | ||
698 | ret = -ENOMEM; | ||
699 | goto err_muex; | ||
700 | } | ||
701 | |||
702 | edev->d_attrs_muex = kzalloc(sizeof(struct device_attribute) * | ||
703 | index, GFP_KERNEL); | ||
704 | if (!edev->d_attrs_muex) { | ||
705 | ret = -ENOMEM; | ||
706 | kfree(edev->attrs_muex); | ||
707 | goto err_muex; | ||
708 | } | ||
709 | |||
710 | for (index = 0; edev->mutually_exclusive[index]; index++) { | ||
711 | sprintf(buf, "0x%x", edev->mutually_exclusive[index]); | ||
712 | name = kzalloc(sizeof(char) * (strlen(buf) + 1), | ||
713 | GFP_KERNEL); | ||
714 | if (!name) { | ||
715 | for (index--; index >= 0; index--) { | ||
716 | kfree(edev->d_attrs_muex[index].attr. | ||
717 | name); | ||
718 | } | ||
719 | kfree(edev->d_attrs_muex); | ||
720 | kfree(edev->attrs_muex); | ||
721 | ret = -ENOMEM; | ||
722 | goto err_muex; | ||
723 | } | ||
724 | strcpy(name, buf); | ||
725 | edev->d_attrs_muex[index].attr.name = name; | ||
726 | edev->d_attrs_muex[index].attr.mode = 0000; | ||
727 | edev->attrs_muex[index] = &edev->d_attrs_muex[index] | ||
728 | .attr; | ||
729 | } | ||
730 | edev->attr_g_muex.name = muex_name; | ||
731 | edev->attr_g_muex.attrs = edev->attrs_muex; | ||
732 | |||
733 | } | ||
734 | |||
735 | if (edev->max_supported) { | ||
736 | edev->extcon_dev_type.groups = | ||
737 | kzalloc(sizeof(struct attribute_group *) * | ||
738 | (edev->max_supported + 2), GFP_KERNEL); | ||
739 | if (!edev->extcon_dev_type.groups) { | ||
740 | ret = -ENOMEM; | ||
741 | goto err_alloc_groups; | ||
742 | } | ||
743 | |||
744 | edev->extcon_dev_type.name = dev_name(edev->dev); | ||
745 | edev->extcon_dev_type.release = dummy_sysfs_dev_release; | ||
746 | |||
747 | for (index = 0; index < edev->max_supported; index++) | ||
748 | edev->extcon_dev_type.groups[index] = | ||
749 | &edev->cables[index].attr_g; | ||
750 | if (edev->mutually_exclusive) | ||
751 | edev->extcon_dev_type.groups[index] = | ||
752 | &edev->attr_g_muex; | ||
753 | |||
754 | edev->dev->type = &edev->extcon_dev_type; | ||
755 | } | ||
756 | |||
757 | ret = device_register(edev->dev); | ||
758 | if (ret) { | ||
759 | put_device(edev->dev); | ||
760 | goto err_dev; | ||
761 | } | ||
762 | #if defined(CONFIG_ANDROID) | ||
763 | if (switch_class) | ||
764 | ret = class_compat_create_link(switch_class, edev->dev, | ||
765 | dev); | ||
766 | #endif /* CONFIG_ANDROID */ | ||
767 | |||
768 | spin_lock_init(&edev->lock); | ||
769 | |||
770 | RAW_INIT_NOTIFIER_HEAD(&edev->nh); | ||
771 | |||
772 | dev_set_drvdata(edev->dev, edev); | ||
773 | edev->state = 0; | ||
774 | |||
775 | mutex_lock(&extcon_dev_list_lock); | ||
776 | list_add(&edev->entry, &extcon_dev_list); | ||
777 | mutex_unlock(&extcon_dev_list_lock); | ||
778 | |||
779 | return 0; | ||
780 | |||
781 | err_dev: | ||
782 | if (edev->max_supported) | ||
783 | kfree(edev->extcon_dev_type.groups); | ||
784 | err_alloc_groups: | ||
785 | if (edev->max_supported && edev->mutually_exclusive) { | ||
786 | for (index = 0; edev->mutually_exclusive[index]; index++) | ||
787 | kfree(edev->d_attrs_muex[index].attr.name); | ||
788 | kfree(edev->d_attrs_muex); | ||
789 | kfree(edev->attrs_muex); | ||
790 | } | ||
791 | err_muex: | ||
792 | for (index = 0; index < edev->max_supported; index++) | ||
793 | kfree(edev->cables[index].attr_g.name); | ||
794 | err_alloc_cables: | ||
795 | if (edev->max_supported) | ||
796 | kfree(edev->cables); | ||
797 | err_sysfs_alloc: | ||
798 | kfree(edev->dev); | ||
799 | return ret; | ||
800 | } | ||
801 | EXPORT_SYMBOL_GPL(extcon_dev_register); | ||
802 | |||
803 | /** | ||
804 | * extcon_dev_unregister() - Unregister the extcon device. | ||
805 | * @edev: the extcon device instance to be unregitered. | ||
806 | * | ||
807 | * Note that this does not call kfree(edev) because edev was not allocated | ||
808 | * by this class. | ||
809 | */ | ||
810 | void extcon_dev_unregister(struct extcon_dev *edev) | ||
811 | { | ||
812 | extcon_cleanup(edev, false); | ||
813 | } | ||
814 | EXPORT_SYMBOL_GPL(extcon_dev_unregister); | ||
815 | |||
816 | static int __init extcon_class_init(void) | ||
817 | { | ||
818 | return create_extcon_class(); | ||
819 | } | ||
820 | module_init(extcon_class_init); | ||
821 | |||
822 | static void __exit extcon_class_exit(void) | ||
823 | { | ||
824 | class_destroy(extcon_class); | ||
825 | } | ||
826 | module_exit(extcon_class_exit); | ||
827 | |||
828 | MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>"); | ||
829 | MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>"); | ||
830 | MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); | ||
831 | MODULE_DESCRIPTION("External connector (extcon) class driver"); | ||
832 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/extcon/extcon_gpio.c b/drivers/extcon/extcon_gpio.c new file mode 100644 index 000000000000..fe7a07b47336 --- /dev/null +++ b/drivers/extcon/extcon_gpio.c | |||
@@ -0,0 +1,169 @@ | |||
1 | /* | ||
2 | * drivers/extcon/extcon_gpio.c | ||
3 | * | ||
4 | * Single-state GPIO extcon driver based on extcon class | ||
5 | * | ||
6 | * Copyright (C) 2008 Google, Inc. | ||
7 | * Author: Mike Lockwood <lockwood@android.com> | ||
8 | * | ||
9 | * Modified by MyungJoo Ham <myungjoo.ham@samsung.com> to support extcon | ||
10 | * (originally switch class is supported) | ||
11 | * | ||
12 | * This software is licensed under the terms of the GNU General Public | ||
13 | * License version 2, as published by the Free Software Foundation, and | ||
14 | * may be copied, distributed, and modified under those terms. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/extcon.h> | ||
30 | #include <linux/workqueue.h> | ||
31 | #include <linux/gpio.h> | ||
32 | #include <linux/extcon.h> | ||
33 | #include <linux/extcon/extcon_gpio.h> | ||
34 | |||
35 | struct gpio_extcon_data { | ||
36 | struct extcon_dev edev; | ||
37 | unsigned gpio; | ||
38 | const char *state_on; | ||
39 | const char *state_off; | ||
40 | int irq; | ||
41 | struct delayed_work work; | ||
42 | unsigned long debounce_jiffies; | ||
43 | }; | ||
44 | |||
45 | static void gpio_extcon_work(struct work_struct *work) | ||
46 | { | ||
47 | int state; | ||
48 | struct gpio_extcon_data *data = | ||
49 | container_of(to_delayed_work(work), struct gpio_extcon_data, | ||
50 | work); | ||
51 | |||
52 | state = gpio_get_value(data->gpio); | ||
53 | extcon_set_state(&data->edev, state); | ||
54 | } | ||
55 | |||
56 | static irqreturn_t gpio_irq_handler(int irq, void *dev_id) | ||
57 | { | ||
58 | struct gpio_extcon_data *extcon_data = dev_id; | ||
59 | |||
60 | schedule_delayed_work(&extcon_data->work, | ||
61 | extcon_data->debounce_jiffies); | ||
62 | return IRQ_HANDLED; | ||
63 | } | ||
64 | |||
65 | static ssize_t extcon_gpio_print_state(struct extcon_dev *edev, char *buf) | ||
66 | { | ||
67 | struct gpio_extcon_data *extcon_data = | ||
68 | container_of(edev, struct gpio_extcon_data, edev); | ||
69 | const char *state; | ||
70 | if (extcon_get_state(edev)) | ||
71 | state = extcon_data->state_on; | ||
72 | else | ||
73 | state = extcon_data->state_off; | ||
74 | |||
75 | if (state) | ||
76 | return sprintf(buf, "%s\n", state); | ||
77 | return -EINVAL; | ||
78 | } | ||
79 | |||
80 | static int __devinit gpio_extcon_probe(struct platform_device *pdev) | ||
81 | { | ||
82 | struct gpio_extcon_platform_data *pdata = pdev->dev.platform_data; | ||
83 | struct gpio_extcon_data *extcon_data; | ||
84 | int ret = 0; | ||
85 | |||
86 | if (!pdata) | ||
87 | return -EBUSY; | ||
88 | if (!pdata->irq_flags) { | ||
89 | dev_err(&pdev->dev, "IRQ flag is not specified.\n"); | ||
90 | return -EINVAL; | ||
91 | } | ||
92 | |||
93 | extcon_data = devm_kzalloc(&pdev->dev, sizeof(struct gpio_extcon_data), | ||
94 | GFP_KERNEL); | ||
95 | if (!extcon_data) | ||
96 | return -ENOMEM; | ||
97 | |||
98 | extcon_data->edev.name = pdata->name; | ||
99 | extcon_data->gpio = pdata->gpio; | ||
100 | extcon_data->state_on = pdata->state_on; | ||
101 | extcon_data->state_off = pdata->state_off; | ||
102 | if (pdata->state_on && pdata->state_off) | ||
103 | extcon_data->edev.print_state = extcon_gpio_print_state; | ||
104 | extcon_data->debounce_jiffies = msecs_to_jiffies(pdata->debounce); | ||
105 | |||
106 | ret = extcon_dev_register(&extcon_data->edev, &pdev->dev); | ||
107 | if (ret < 0) | ||
108 | goto err_extcon_dev_register; | ||
109 | |||
110 | ret = gpio_request_one(extcon_data->gpio, GPIOF_DIR_IN, pdev->name); | ||
111 | if (ret < 0) | ||
112 | goto err_request_gpio; | ||
113 | |||
114 | INIT_DELAYED_WORK(&extcon_data->work, gpio_extcon_work); | ||
115 | |||
116 | extcon_data->irq = gpio_to_irq(extcon_data->gpio); | ||
117 | if (extcon_data->irq < 0) { | ||
118 | ret = extcon_data->irq; | ||
119 | goto err_detect_irq_num_failed; | ||
120 | } | ||
121 | |||
122 | ret = request_any_context_irq(extcon_data->irq, gpio_irq_handler, | ||
123 | pdata->irq_flags, pdev->name, | ||
124 | extcon_data); | ||
125 | if (ret < 0) | ||
126 | goto err_request_irq; | ||
127 | |||
128 | /* Perform initial detection */ | ||
129 | gpio_extcon_work(&extcon_data->work.work); | ||
130 | |||
131 | return 0; | ||
132 | |||
133 | err_request_irq: | ||
134 | err_detect_irq_num_failed: | ||
135 | gpio_free(extcon_data->gpio); | ||
136 | err_request_gpio: | ||
137 | extcon_dev_unregister(&extcon_data->edev); | ||
138 | err_extcon_dev_register: | ||
139 | devm_kfree(&pdev->dev, extcon_data); | ||
140 | |||
141 | return ret; | ||
142 | } | ||
143 | |||
144 | static int __devexit gpio_extcon_remove(struct platform_device *pdev) | ||
145 | { | ||
146 | struct gpio_extcon_data *extcon_data = platform_get_drvdata(pdev); | ||
147 | |||
148 | cancel_delayed_work_sync(&extcon_data->work); | ||
149 | gpio_free(extcon_data->gpio); | ||
150 | extcon_dev_unregister(&extcon_data->edev); | ||
151 | devm_kfree(&pdev->dev, extcon_data); | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | static struct platform_driver gpio_extcon_driver = { | ||
157 | .probe = gpio_extcon_probe, | ||
158 | .remove = __devexit_p(gpio_extcon_remove), | ||
159 | .driver = { | ||
160 | .name = "extcon-gpio", | ||
161 | .owner = THIS_MODULE, | ||
162 | }, | ||
163 | }; | ||
164 | |||
165 | module_platform_driver(gpio_extcon_driver); | ||
166 | |||
167 | MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>"); | ||
168 | MODULE_DESCRIPTION("GPIO extcon driver"); | ||
169 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c index 3dd29399cef5..8950f6261bbb 100644 --- a/drivers/gpio/devres.c +++ b/drivers/gpio/devres.c | |||
@@ -83,8 +83,7 @@ EXPORT_SYMBOL(devm_gpio_request); | |||
83 | void devm_gpio_free(struct device *dev, unsigned int gpio) | 83 | void devm_gpio_free(struct device *dev, unsigned int gpio) |
84 | { | 84 | { |
85 | 85 | ||
86 | WARN_ON(devres_destroy(dev, devm_gpio_release, devm_gpio_match, | 86 | WARN_ON(devres_release(dev, devm_gpio_release, devm_gpio_match, |
87 | &gpio)); | 87 | &gpio)); |
88 | gpio_free(gpio); | ||
89 | } | 88 | } |
90 | EXPORT_SYMBOL(devm_gpio_free); | 89 | EXPORT_SYMBOL(devm_gpio_free); |
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 9ffbfc575a0c..2b8b8d4558d2 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c | |||
@@ -46,40 +46,61 @@ struct vmbus_channel_message_table_entry { | |||
46 | * | 46 | * |
47 | * @icmsghdrp is of type &struct icmsg_hdr. | 47 | * @icmsghdrp is of type &struct icmsg_hdr. |
48 | * @negop is of type &struct icmsg_negotiate. | 48 | * @negop is of type &struct icmsg_negotiate. |
49 | * Set up and fill in default negotiate response message. This response can | 49 | * Set up and fill in default negotiate response message. |
50 | * come from both the vmbus driver and the hv_utils driver. The current api | 50 | * |
51 | * will respond properly to both Windows 2008 and Windows 2008-R2 operating | 51 | * The max_fw_version specifies the maximum framework version that |
52 | * systems. | 52 | * we can support and max _srv_version specifies the maximum service |
53 | * version we can support. A special value MAX_SRV_VER can be | ||
54 | * specified to indicate that we can handle the maximum version | ||
55 | * exposed by the host. | ||
53 | * | 56 | * |
54 | * Mainly used by Hyper-V drivers. | 57 | * Mainly used by Hyper-V drivers. |
55 | */ | 58 | */ |
56 | void vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, | 59 | void vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, |
57 | struct icmsg_negotiate *negop, u8 *buf) | 60 | struct icmsg_negotiate *negop, u8 *buf, |
61 | int max_fw_version, int max_srv_version) | ||
58 | { | 62 | { |
59 | if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { | 63 | int icframe_vercnt; |
60 | icmsghdrp->icmsgsize = 0x10; | 64 | int icmsg_vercnt; |
61 | 65 | int i; | |
62 | negop = (struct icmsg_negotiate *)&buf[ | 66 | |
63 | sizeof(struct vmbuspipe_hdr) + | 67 | icmsghdrp->icmsgsize = 0x10; |
64 | sizeof(struct icmsg_hdr)]; | 68 | |
65 | 69 | negop = (struct icmsg_negotiate *)&buf[ | |
66 | if (negop->icframe_vercnt == 2 && | 70 | sizeof(struct vmbuspipe_hdr) + |
67 | negop->icversion_data[1].major == 3) { | 71 | sizeof(struct icmsg_hdr)]; |
68 | negop->icversion_data[0].major = 3; | 72 | |
69 | negop->icversion_data[0].minor = 0; | 73 | icframe_vercnt = negop->icframe_vercnt; |
70 | negop->icversion_data[1].major = 3; | 74 | icmsg_vercnt = negop->icmsg_vercnt; |
71 | negop->icversion_data[1].minor = 0; | 75 | |
72 | } else { | 76 | /* |
73 | negop->icversion_data[0].major = 1; | 77 | * Select the framework version number we will |
74 | negop->icversion_data[0].minor = 0; | 78 | * support. |
75 | negop->icversion_data[1].major = 1; | 79 | */ |
76 | negop->icversion_data[1].minor = 0; | 80 | |
77 | } | 81 | for (i = 0; i < negop->icframe_vercnt; i++) { |
82 | if (negop->icversion_data[i].major <= max_fw_version) | ||
83 | icframe_vercnt = negop->icversion_data[i].major; | ||
84 | } | ||
78 | 85 | ||
79 | negop->icframe_vercnt = 1; | 86 | for (i = negop->icframe_vercnt; |
80 | negop->icmsg_vercnt = 1; | 87 | (i < negop->icframe_vercnt + negop->icmsg_vercnt); i++) { |
88 | if (negop->icversion_data[i].major <= max_srv_version) | ||
89 | icmsg_vercnt = negop->icversion_data[i].major; | ||
81 | } | 90 | } |
91 | |||
92 | /* | ||
93 | * Respond with the maximum framework and service | ||
94 | * version numbers we can support. | ||
95 | */ | ||
96 | negop->icframe_vercnt = 1; | ||
97 | negop->icmsg_vercnt = 1; | ||
98 | negop->icversion_data[0].major = icframe_vercnt; | ||
99 | negop->icversion_data[0].minor = 0; | ||
100 | negop->icversion_data[1].major = icmsg_vercnt; | ||
101 | negop->icversion_data[1].minor = 0; | ||
82 | } | 102 | } |
103 | |||
83 | EXPORT_SYMBOL_GPL(vmbus_prep_negotiate_resp); | 104 | EXPORT_SYMBOL_GPL(vmbus_prep_negotiate_resp); |
84 | 105 | ||
85 | /* | 106 | /* |
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index 15956bd48b48..86f8885aeb45 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c | |||
@@ -252,7 +252,7 @@ void hv_cleanup(void) | |||
252 | * | 252 | * |
253 | * This involves a hypercall. | 253 | * This involves a hypercall. |
254 | */ | 254 | */ |
255 | u16 hv_post_message(union hv_connection_id connection_id, | 255 | int hv_post_message(union hv_connection_id connection_id, |
256 | enum hv_message_type message_type, | 256 | enum hv_message_type message_type, |
257 | void *payload, size_t payload_size) | 257 | void *payload, size_t payload_size) |
258 | { | 258 | { |
diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c index 6186025209ce..0012eed6d872 100644 --- a/drivers/hv/hv_kvp.c +++ b/drivers/hv/hv_kvp.c | |||
@@ -394,7 +394,8 @@ void hv_kvp_onchannelcallback(void *context) | |||
394 | sizeof(struct vmbuspipe_hdr)]; | 394 | sizeof(struct vmbuspipe_hdr)]; |
395 | 395 | ||
396 | if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { | 396 | if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { |
397 | vmbus_prep_negotiate_resp(icmsghdrp, negop, recv_buffer); | 397 | vmbus_prep_negotiate_resp(icmsghdrp, negop, |
398 | recv_buffer, MAX_SRV_VER, MAX_SRV_VER); | ||
398 | } else { | 399 | } else { |
399 | kvp_msg = (struct hv_kvp_msg *)&recv_buffer[ | 400 | kvp_msg = (struct hv_kvp_msg *)&recv_buffer[ |
400 | sizeof(struct vmbuspipe_hdr) + | 401 | sizeof(struct vmbuspipe_hdr) + |
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c index dbb8b8eec210..d3ac6a40118b 100644 --- a/drivers/hv/hv_util.c +++ b/drivers/hv/hv_util.c | |||
@@ -70,7 +70,8 @@ static void shutdown_onchannelcallback(void *context) | |||
70 | sizeof(struct vmbuspipe_hdr)]; | 70 | sizeof(struct vmbuspipe_hdr)]; |
71 | 71 | ||
72 | if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { | 72 | if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { |
73 | vmbus_prep_negotiate_resp(icmsghdrp, negop, shut_txf_buf); | 73 | vmbus_prep_negotiate_resp(icmsghdrp, negop, |
74 | shut_txf_buf, MAX_SRV_VER, MAX_SRV_VER); | ||
74 | } else { | 75 | } else { |
75 | shutdown_msg = | 76 | shutdown_msg = |
76 | (struct shutdown_msg_data *)&shut_txf_buf[ | 77 | (struct shutdown_msg_data *)&shut_txf_buf[ |
@@ -195,7 +196,8 @@ static void timesync_onchannelcallback(void *context) | |||
195 | sizeof(struct vmbuspipe_hdr)]; | 196 | sizeof(struct vmbuspipe_hdr)]; |
196 | 197 | ||
197 | if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { | 198 | if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { |
198 | vmbus_prep_negotiate_resp(icmsghdrp, NULL, time_txf_buf); | 199 | vmbus_prep_negotiate_resp(icmsghdrp, NULL, time_txf_buf, |
200 | MAX_SRV_VER, MAX_SRV_VER); | ||
199 | } else { | 201 | } else { |
200 | timedatap = (struct ictimesync_data *)&time_txf_buf[ | 202 | timedatap = (struct ictimesync_data *)&time_txf_buf[ |
201 | sizeof(struct vmbuspipe_hdr) + | 203 | sizeof(struct vmbuspipe_hdr) + |
@@ -234,7 +236,8 @@ static void heartbeat_onchannelcallback(void *context) | |||
234 | sizeof(struct vmbuspipe_hdr)]; | 236 | sizeof(struct vmbuspipe_hdr)]; |
235 | 237 | ||
236 | if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { | 238 | if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { |
237 | vmbus_prep_negotiate_resp(icmsghdrp, NULL, hbeat_txf_buf); | 239 | vmbus_prep_negotiate_resp(icmsghdrp, NULL, |
240 | hbeat_txf_buf, MAX_SRV_VER, MAX_SRV_VER); | ||
238 | } else { | 241 | } else { |
239 | heartbeat_msg = | 242 | heartbeat_msg = |
240 | (struct heartbeat_msg_data *)&hbeat_txf_buf[ | 243 | (struct heartbeat_msg_data *)&hbeat_txf_buf[ |
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index 699f0d8e59ed..b9426a6592ee 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h | |||
@@ -495,7 +495,7 @@ extern int hv_init(void); | |||
495 | 495 | ||
496 | extern void hv_cleanup(void); | 496 | extern void hv_cleanup(void); |
497 | 497 | ||
498 | extern u16 hv_post_message(union hv_connection_id connection_id, | 498 | extern int hv_post_message(union hv_connection_id connection_id, |
499 | enum hv_message_type message_type, | 499 | enum hv_message_type message_type, |
500 | void *payload, size_t payload_size); | 500 | void *payload, size_t payload_size); |
501 | 501 | ||
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig new file mode 100644 index 000000000000..067f31174a0e --- /dev/null +++ b/drivers/memory/Kconfig | |||
@@ -0,0 +1,43 @@ | |||
1 | # | ||
2 | # Memory devices | ||
3 | # | ||
4 | |||
5 | menuconfig MEMORY | ||
6 | bool "Memory Controller drivers" | ||
7 | |||
8 | if MEMORY | ||
9 | |||
10 | config TI_EMIF | ||
11 | tristate "Texas Instruments EMIF driver" | ||
12 | depends on ARCH_OMAP2PLUS | ||
13 | select DDR | ||
14 | help | ||
15 | This driver is for the EMIF module available in Texas Instruments | ||
16 | SoCs. EMIF is an SDRAM controller that, based on its revision, | ||
17 | supports one or more of DDR2, DDR3, and LPDDR2 SDRAM protocols. | ||
18 | This driver takes care of only LPDDR2 memories presently. The | ||
19 | functions of the driver includes re-configuring AC timing | ||
20 | parameters and other settings during frequency, voltage and | ||
21 | temperature changes | ||
22 | |||
23 | config TEGRA20_MC | ||
24 | bool "Tegra20 Memory Controller(MC) driver" | ||
25 | default y | ||
26 | depends on ARCH_TEGRA_2x_SOC | ||
27 | help | ||
28 | This driver is for the Memory Controller(MC) module available | ||
29 | in Tegra20 SoCs, mainly for a address translation fault | ||
30 | analysis, especially for IOMMU/GART(Graphics Address | ||
31 | Relocation Table) module. | ||
32 | |||
33 | config TEGRA30_MC | ||
34 | bool "Tegra30 Memory Controller(MC) driver" | ||
35 | default y | ||
36 | depends on ARCH_TEGRA_3x_SOC | ||
37 | help | ||
38 | This driver is for the Memory Controller(MC) module available | ||
39 | in Tegra30 SoCs, mainly for a address translation fault | ||
40 | analysis, especially for IOMMU/SMMU(System Memory Management | ||
41 | Unit) module. | ||
42 | |||
43 | endif | ||
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile new file mode 100644 index 000000000000..42b3ce9d80fc --- /dev/null +++ b/drivers/memory/Makefile | |||
@@ -0,0 +1,7 @@ | |||
1 | # | ||
2 | # Makefile for memory devices | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_TI_EMIF) += emif.o | ||
6 | obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o | ||
7 | obj-$(CONFIG_TEGRA30_MC) += tegra30-mc.o | ||
diff --git a/drivers/memory/emif.c b/drivers/memory/emif.c new file mode 100644 index 000000000000..33a4396b24cb --- /dev/null +++ b/drivers/memory/emif.c | |||
@@ -0,0 +1,1670 @@ | |||
1 | /* | ||
2 | * EMIF driver | ||
3 | * | ||
4 | * Copyright (C) 2012 Texas Instruments, Inc. | ||
5 | * | ||
6 | * Aneesh V <aneesh@ti.com> | ||
7 | * Santosh Shilimkar <santosh.shilimkar@ti.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/reboot.h> | ||
15 | #include <linux/platform_data/emif_plat.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/debugfs.h> | ||
22 | #include <linux/seq_file.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/list.h> | ||
25 | #include <linux/spinlock.h> | ||
26 | #include <memory/jedec_ddr.h> | ||
27 | #include "emif.h" | ||
28 | |||
29 | /** | ||
30 | * struct emif_data - Per device static data for driver's use | ||
31 | * @duplicate: Whether the DDR devices attached to this EMIF | ||
32 | * instance are exactly same as that on EMIF1. In | ||
33 | * this case we can save some memory and processing | ||
34 | * @temperature_level: Maximum temperature of LPDDR2 devices attached | ||
35 | * to this EMIF - read from MR4 register. If there | ||
36 | * are two devices attached to this EMIF, this | ||
37 | * value is the maximum of the two temperature | ||
38 | * levels. | ||
39 | * @node: node in the device list | ||
40 | * @base: base address of memory-mapped IO registers. | ||
41 | * @dev: device pointer. | ||
42 | * @addressing table with addressing information from the spec | ||
43 | * @regs_cache: An array of 'struct emif_regs' that stores | ||
44 | * calculated register values for different | ||
45 | * frequencies, to avoid re-calculating them on | ||
46 | * each DVFS transition. | ||
47 | * @curr_regs: The set of register values used in the last | ||
48 | * frequency change (i.e. corresponding to the | ||
49 | * frequency in effect at the moment) | ||
50 | * @plat_data: Pointer to saved platform data. | ||
51 | * @debugfs_root: dentry to the root folder for EMIF in debugfs | ||
52 | */ | ||
53 | struct emif_data { | ||
54 | u8 duplicate; | ||
55 | u8 temperature_level; | ||
56 | u8 lpmode; | ||
57 | struct list_head node; | ||
58 | unsigned long irq_state; | ||
59 | void __iomem *base; | ||
60 | struct device *dev; | ||
61 | const struct lpddr2_addressing *addressing; | ||
62 | struct emif_regs *regs_cache[EMIF_MAX_NUM_FREQUENCIES]; | ||
63 | struct emif_regs *curr_regs; | ||
64 | struct emif_platform_data *plat_data; | ||
65 | struct dentry *debugfs_root; | ||
66 | }; | ||
67 | |||
68 | static struct emif_data *emif1; | ||
69 | static spinlock_t emif_lock; | ||
70 | static unsigned long irq_state; | ||
71 | static u32 t_ck; /* DDR clock period in ps */ | ||
72 | static LIST_HEAD(device_list); | ||
73 | |||
74 | static void do_emif_regdump_show(struct seq_file *s, struct emif_data *emif, | ||
75 | struct emif_regs *regs) | ||
76 | { | ||
77 | u32 type = emif->plat_data->device_info->type; | ||
78 | u32 ip_rev = emif->plat_data->ip_rev; | ||
79 | |||
80 | seq_printf(s, "EMIF register cache dump for %dMHz\n", | ||
81 | regs->freq/1000000); | ||
82 | |||
83 | seq_printf(s, "ref_ctrl_shdw\t: 0x%08x\n", regs->ref_ctrl_shdw); | ||
84 | seq_printf(s, "sdram_tim1_shdw\t: 0x%08x\n", regs->sdram_tim1_shdw); | ||
85 | seq_printf(s, "sdram_tim2_shdw\t: 0x%08x\n", regs->sdram_tim2_shdw); | ||
86 | seq_printf(s, "sdram_tim3_shdw\t: 0x%08x\n", regs->sdram_tim3_shdw); | ||
87 | |||
88 | if (ip_rev == EMIF_4D) { | ||
89 | seq_printf(s, "read_idle_ctrl_shdw_normal\t: 0x%08x\n", | ||
90 | regs->read_idle_ctrl_shdw_normal); | ||
91 | seq_printf(s, "read_idle_ctrl_shdw_volt_ramp\t: 0x%08x\n", | ||
92 | regs->read_idle_ctrl_shdw_volt_ramp); | ||
93 | } else if (ip_rev == EMIF_4D5) { | ||
94 | seq_printf(s, "dll_calib_ctrl_shdw_normal\t: 0x%08x\n", | ||
95 | regs->dll_calib_ctrl_shdw_normal); | ||
96 | seq_printf(s, "dll_calib_ctrl_shdw_volt_ramp\t: 0x%08x\n", | ||
97 | regs->dll_calib_ctrl_shdw_volt_ramp); | ||
98 | } | ||
99 | |||
100 | if (type == DDR_TYPE_LPDDR2_S2 || type == DDR_TYPE_LPDDR2_S4) { | ||
101 | seq_printf(s, "ref_ctrl_shdw_derated\t: 0x%08x\n", | ||
102 | regs->ref_ctrl_shdw_derated); | ||
103 | seq_printf(s, "sdram_tim1_shdw_derated\t: 0x%08x\n", | ||
104 | regs->sdram_tim1_shdw_derated); | ||
105 | seq_printf(s, "sdram_tim3_shdw_derated\t: 0x%08x\n", | ||
106 | regs->sdram_tim3_shdw_derated); | ||
107 | } | ||
108 | } | ||
109 | |||
110 | static int emif_regdump_show(struct seq_file *s, void *unused) | ||
111 | { | ||
112 | struct emif_data *emif = s->private; | ||
113 | struct emif_regs **regs_cache; | ||
114 | int i; | ||
115 | |||
116 | if (emif->duplicate) | ||
117 | regs_cache = emif1->regs_cache; | ||
118 | else | ||
119 | regs_cache = emif->regs_cache; | ||
120 | |||
121 | for (i = 0; i < EMIF_MAX_NUM_FREQUENCIES && regs_cache[i]; i++) { | ||
122 | do_emif_regdump_show(s, emif, regs_cache[i]); | ||
123 | seq_printf(s, "\n"); | ||
124 | } | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int emif_regdump_open(struct inode *inode, struct file *file) | ||
130 | { | ||
131 | return single_open(file, emif_regdump_show, inode->i_private); | ||
132 | } | ||
133 | |||
134 | static const struct file_operations emif_regdump_fops = { | ||
135 | .open = emif_regdump_open, | ||
136 | .read = seq_read, | ||
137 | .release = single_release, | ||
138 | }; | ||
139 | |||
140 | static int emif_mr4_show(struct seq_file *s, void *unused) | ||
141 | { | ||
142 | struct emif_data *emif = s->private; | ||
143 | |||
144 | seq_printf(s, "MR4=%d\n", emif->temperature_level); | ||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | static int emif_mr4_open(struct inode *inode, struct file *file) | ||
149 | { | ||
150 | return single_open(file, emif_mr4_show, inode->i_private); | ||
151 | } | ||
152 | |||
153 | static const struct file_operations emif_mr4_fops = { | ||
154 | .open = emif_mr4_open, | ||
155 | .read = seq_read, | ||
156 | .release = single_release, | ||
157 | }; | ||
158 | |||
159 | static int __init_or_module emif_debugfs_init(struct emif_data *emif) | ||
160 | { | ||
161 | struct dentry *dentry; | ||
162 | int ret; | ||
163 | |||
164 | dentry = debugfs_create_dir(dev_name(emif->dev), NULL); | ||
165 | if (IS_ERR(dentry)) { | ||
166 | ret = PTR_ERR(dentry); | ||
167 | goto err0; | ||
168 | } | ||
169 | emif->debugfs_root = dentry; | ||
170 | |||
171 | dentry = debugfs_create_file("regcache_dump", S_IRUGO, | ||
172 | emif->debugfs_root, emif, &emif_regdump_fops); | ||
173 | if (IS_ERR(dentry)) { | ||
174 | ret = PTR_ERR(dentry); | ||
175 | goto err1; | ||
176 | } | ||
177 | |||
178 | dentry = debugfs_create_file("mr4", S_IRUGO, | ||
179 | emif->debugfs_root, emif, &emif_mr4_fops); | ||
180 | if (IS_ERR(dentry)) { | ||
181 | ret = PTR_ERR(dentry); | ||
182 | goto err1; | ||
183 | } | ||
184 | |||
185 | return 0; | ||
186 | err1: | ||
187 | debugfs_remove_recursive(emif->debugfs_root); | ||
188 | err0: | ||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | static void __exit emif_debugfs_exit(struct emif_data *emif) | ||
193 | { | ||
194 | debugfs_remove_recursive(emif->debugfs_root); | ||
195 | emif->debugfs_root = NULL; | ||
196 | } | ||
197 | |||
198 | /* | ||
199 | * Calculate the period of DDR clock from frequency value | ||
200 | */ | ||
201 | static void set_ddr_clk_period(u32 freq) | ||
202 | { | ||
203 | /* Divide 10^12 by frequency to get period in ps */ | ||
204 | t_ck = (u32)DIV_ROUND_UP_ULL(1000000000000ull, freq); | ||
205 | } | ||
206 | |||
207 | /* | ||
208 | * Get bus width used by EMIF. Note that this may be different from the | ||
209 | * bus width of the DDR devices used. For instance two 16-bit DDR devices | ||
210 | * may be connected to a given CS of EMIF. In this case bus width as far | ||
211 | * as EMIF is concerned is 32, where as the DDR bus width is 16 bits. | ||
212 | */ | ||
213 | static u32 get_emif_bus_width(struct emif_data *emif) | ||
214 | { | ||
215 | u32 width; | ||
216 | void __iomem *base = emif->base; | ||
217 | |||
218 | width = (readl(base + EMIF_SDRAM_CONFIG) & NARROW_MODE_MASK) | ||
219 | >> NARROW_MODE_SHIFT; | ||
220 | width = width == 0 ? 32 : 16; | ||
221 | |||
222 | return width; | ||
223 | } | ||
224 | |||
225 | /* | ||
226 | * Get the CL from SDRAM_CONFIG register | ||
227 | */ | ||
228 | static u32 get_cl(struct emif_data *emif) | ||
229 | { | ||
230 | u32 cl; | ||
231 | void __iomem *base = emif->base; | ||
232 | |||
233 | cl = (readl(base + EMIF_SDRAM_CONFIG) & CL_MASK) >> CL_SHIFT; | ||
234 | |||
235 | return cl; | ||
236 | } | ||
237 | |||
238 | static void set_lpmode(struct emif_data *emif, u8 lpmode) | ||
239 | { | ||
240 | u32 temp; | ||
241 | void __iomem *base = emif->base; | ||
242 | |||
243 | temp = readl(base + EMIF_POWER_MANAGEMENT_CONTROL); | ||
244 | temp &= ~LP_MODE_MASK; | ||
245 | temp |= (lpmode << LP_MODE_SHIFT); | ||
246 | writel(temp, base + EMIF_POWER_MANAGEMENT_CONTROL); | ||
247 | } | ||
248 | |||
249 | static void do_freq_update(void) | ||
250 | { | ||
251 | struct emif_data *emif; | ||
252 | |||
253 | /* | ||
254 | * Workaround for errata i728: Disable LPMODE during FREQ_UPDATE | ||
255 | * | ||
256 | * i728 DESCRIPTION: | ||
257 | * The EMIF automatically puts the SDRAM into self-refresh mode | ||
258 | * after the EMIF has not performed accesses during | ||
259 | * EMIF_PWR_MGMT_CTRL[7:4] REG_SR_TIM number of DDR clock cycles | ||
260 | * and the EMIF_PWR_MGMT_CTRL[10:8] REG_LP_MODE bit field is set | ||
261 | * to 0x2. If during a small window the following three events | ||
262 | * occur: | ||
263 | * - The SR_TIMING counter expires | ||
264 | * - And frequency change is requested | ||
265 | * - And OCP access is requested | ||
266 | * Then it causes instable clock on the DDR interface. | ||
267 | * | ||
268 | * WORKAROUND | ||
269 | * To avoid the occurrence of the three events, the workaround | ||
270 | * is to disable the self-refresh when requesting a frequency | ||
271 | * change. Before requesting a frequency change the software must | ||
272 | * program EMIF_PWR_MGMT_CTRL[10:8] REG_LP_MODE to 0x0. When the | ||
273 | * frequency change has been done, the software can reprogram | ||
274 | * EMIF_PWR_MGMT_CTRL[10:8] REG_LP_MODE to 0x2 | ||
275 | */ | ||
276 | list_for_each_entry(emif, &device_list, node) { | ||
277 | if (emif->lpmode == EMIF_LP_MODE_SELF_REFRESH) | ||
278 | set_lpmode(emif, EMIF_LP_MODE_DISABLE); | ||
279 | } | ||
280 | |||
281 | /* | ||
282 | * TODO: Do FREQ_UPDATE here when an API | ||
283 | * is available for this as part of the new | ||
284 | * clock framework | ||
285 | */ | ||
286 | |||
287 | list_for_each_entry(emif, &device_list, node) { | ||
288 | if (emif->lpmode == EMIF_LP_MODE_SELF_REFRESH) | ||
289 | set_lpmode(emif, EMIF_LP_MODE_SELF_REFRESH); | ||
290 | } | ||
291 | } | ||
292 | |||
293 | /* Find addressing table entry based on the device's type and density */ | ||
294 | static const struct lpddr2_addressing *get_addressing_table( | ||
295 | const struct ddr_device_info *device_info) | ||
296 | { | ||
297 | u32 index, type, density; | ||
298 | |||
299 | type = device_info->type; | ||
300 | density = device_info->density; | ||
301 | |||
302 | switch (type) { | ||
303 | case DDR_TYPE_LPDDR2_S4: | ||
304 | index = density - 1; | ||
305 | break; | ||
306 | case DDR_TYPE_LPDDR2_S2: | ||
307 | switch (density) { | ||
308 | case DDR_DENSITY_1Gb: | ||
309 | case DDR_DENSITY_2Gb: | ||
310 | index = density + 3; | ||
311 | break; | ||
312 | default: | ||
313 | index = density - 1; | ||
314 | } | ||
315 | break; | ||
316 | default: | ||
317 | return NULL; | ||
318 | } | ||
319 | |||
320 | return &lpddr2_jedec_addressing_table[index]; | ||
321 | } | ||
322 | |||
323 | /* | ||
324 | * Find the the right timing table from the array of timing | ||
325 | * tables of the device using DDR clock frequency | ||
326 | */ | ||
327 | static const struct lpddr2_timings *get_timings_table(struct emif_data *emif, | ||
328 | u32 freq) | ||
329 | { | ||
330 | u32 i, min, max, freq_nearest; | ||
331 | const struct lpddr2_timings *timings = NULL; | ||
332 | const struct lpddr2_timings *timings_arr = emif->plat_data->timings; | ||
333 | struct device *dev = emif->dev; | ||
334 | |||
335 | /* Start with a very high frequency - 1GHz */ | ||
336 | freq_nearest = 1000000000; | ||
337 | |||
338 | /* | ||
339 | * Find the timings table such that: | ||
340 | * 1. the frequency range covers the required frequency(safe) AND | ||
341 | * 2. the max_freq is closest to the required frequency(optimal) | ||
342 | */ | ||
343 | for (i = 0; i < emif->plat_data->timings_arr_size; i++) { | ||
344 | max = timings_arr[i].max_freq; | ||
345 | min = timings_arr[i].min_freq; | ||
346 | if ((freq >= min) && (freq <= max) && (max < freq_nearest)) { | ||
347 | freq_nearest = max; | ||
348 | timings = &timings_arr[i]; | ||
349 | } | ||
350 | } | ||
351 | |||
352 | if (!timings) | ||
353 | dev_err(dev, "%s: couldn't find timings for - %dHz\n", | ||
354 | __func__, freq); | ||
355 | |||
356 | dev_dbg(dev, "%s: timings table: freq %d, speed bin freq %d\n", | ||
357 | __func__, freq, freq_nearest); | ||
358 | |||
359 | return timings; | ||
360 | } | ||
361 | |||
362 | static u32 get_sdram_ref_ctrl_shdw(u32 freq, | ||
363 | const struct lpddr2_addressing *addressing) | ||
364 | { | ||
365 | u32 ref_ctrl_shdw = 0, val = 0, freq_khz, t_refi; | ||
366 | |||
367 | /* Scale down frequency and t_refi to avoid overflow */ | ||
368 | freq_khz = freq / 1000; | ||
369 | t_refi = addressing->tREFI_ns / 100; | ||
370 | |||
371 | /* | ||
372 | * refresh rate to be set is 'tREFI(in us) * freq in MHz | ||
373 | * division by 10000 to account for change in units | ||
374 | */ | ||
375 | val = t_refi * freq_khz / 10000; | ||
376 | ref_ctrl_shdw |= val << REFRESH_RATE_SHIFT; | ||
377 | |||
378 | return ref_ctrl_shdw; | ||
379 | } | ||
380 | |||
381 | static u32 get_sdram_tim_1_shdw(const struct lpddr2_timings *timings, | ||
382 | const struct lpddr2_min_tck *min_tck, | ||
383 | const struct lpddr2_addressing *addressing) | ||
384 | { | ||
385 | u32 tim1 = 0, val = 0; | ||
386 | |||
387 | val = max(min_tck->tWTR, DIV_ROUND_UP(timings->tWTR, t_ck)) - 1; | ||
388 | tim1 |= val << T_WTR_SHIFT; | ||
389 | |||
390 | if (addressing->num_banks == B8) | ||
391 | val = DIV_ROUND_UP(timings->tFAW, t_ck*4); | ||
392 | else | ||
393 | val = max(min_tck->tRRD, DIV_ROUND_UP(timings->tRRD, t_ck)); | ||
394 | tim1 |= (val - 1) << T_RRD_SHIFT; | ||
395 | |||
396 | val = DIV_ROUND_UP(timings->tRAS_min + timings->tRPab, t_ck) - 1; | ||
397 | tim1 |= val << T_RC_SHIFT; | ||
398 | |||
399 | val = max(min_tck->tRASmin, DIV_ROUND_UP(timings->tRAS_min, t_ck)); | ||
400 | tim1 |= (val - 1) << T_RAS_SHIFT; | ||
401 | |||
402 | val = max(min_tck->tWR, DIV_ROUND_UP(timings->tWR, t_ck)) - 1; | ||
403 | tim1 |= val << T_WR_SHIFT; | ||
404 | |||
405 | val = max(min_tck->tRCD, DIV_ROUND_UP(timings->tRCD, t_ck)) - 1; | ||
406 | tim1 |= val << T_RCD_SHIFT; | ||
407 | |||
408 | val = max(min_tck->tRPab, DIV_ROUND_UP(timings->tRPab, t_ck)) - 1; | ||
409 | tim1 |= val << T_RP_SHIFT; | ||
410 | |||
411 | return tim1; | ||
412 | } | ||
413 | |||
414 | static u32 get_sdram_tim_1_shdw_derated(const struct lpddr2_timings *timings, | ||
415 | const struct lpddr2_min_tck *min_tck, | ||
416 | const struct lpddr2_addressing *addressing) | ||
417 | { | ||
418 | u32 tim1 = 0, val = 0; | ||
419 | |||
420 | val = max(min_tck->tWTR, DIV_ROUND_UP(timings->tWTR, t_ck)) - 1; | ||
421 | tim1 = val << T_WTR_SHIFT; | ||
422 | |||
423 | /* | ||
424 | * tFAW is approximately 4 times tRRD. So add 1875*4 = 7500ps | ||
425 | * to tFAW for de-rating | ||
426 | */ | ||
427 | if (addressing->num_banks == B8) { | ||
428 | val = DIV_ROUND_UP(timings->tFAW + 7500, 4 * t_ck) - 1; | ||
429 | } else { | ||
430 | val = DIV_ROUND_UP(timings->tRRD + 1875, t_ck); | ||
431 | val = max(min_tck->tRRD, val) - 1; | ||
432 | } | ||
433 | tim1 |= val << T_RRD_SHIFT; | ||
434 | |||
435 | val = DIV_ROUND_UP(timings->tRAS_min + timings->tRPab + 1875, t_ck); | ||
436 | tim1 |= (val - 1) << T_RC_SHIFT; | ||
437 | |||
438 | val = DIV_ROUND_UP(timings->tRAS_min + 1875, t_ck); | ||
439 | val = max(min_tck->tRASmin, val) - 1; | ||
440 | tim1 |= val << T_RAS_SHIFT; | ||
441 | |||
442 | val = max(min_tck->tWR, DIV_ROUND_UP(timings->tWR, t_ck)) - 1; | ||
443 | tim1 |= val << T_WR_SHIFT; | ||
444 | |||
445 | val = max(min_tck->tRCD, DIV_ROUND_UP(timings->tRCD + 1875, t_ck)); | ||
446 | tim1 |= (val - 1) << T_RCD_SHIFT; | ||
447 | |||
448 | val = max(min_tck->tRPab, DIV_ROUND_UP(timings->tRPab + 1875, t_ck)); | ||
449 | tim1 |= (val - 1) << T_RP_SHIFT; | ||
450 | |||
451 | return tim1; | ||
452 | } | ||
453 | |||
454 | static u32 get_sdram_tim_2_shdw(const struct lpddr2_timings *timings, | ||
455 | const struct lpddr2_min_tck *min_tck, | ||
456 | const struct lpddr2_addressing *addressing, | ||
457 | u32 type) | ||
458 | { | ||
459 | u32 tim2 = 0, val = 0; | ||
460 | |||
461 | val = min_tck->tCKE - 1; | ||
462 | tim2 |= val << T_CKE_SHIFT; | ||
463 | |||
464 | val = max(min_tck->tRTP, DIV_ROUND_UP(timings->tRTP, t_ck)) - 1; | ||
465 | tim2 |= val << T_RTP_SHIFT; | ||
466 | |||
467 | /* tXSNR = tRFCab_ps + 10 ns(tRFCab_ps for LPDDR2). */ | ||
468 | val = DIV_ROUND_UP(addressing->tRFCab_ps + 10000, t_ck) - 1; | ||
469 | tim2 |= val << T_XSNR_SHIFT; | ||
470 | |||
471 | /* XSRD same as XSNR for LPDDR2 */ | ||
472 | tim2 |= val << T_XSRD_SHIFT; | ||
473 | |||
474 | val = max(min_tck->tXP, DIV_ROUND_UP(timings->tXP, t_ck)) - 1; | ||
475 | tim2 |= val << T_XP_SHIFT; | ||
476 | |||
477 | return tim2; | ||
478 | } | ||
479 | |||
480 | static u32 get_sdram_tim_3_shdw(const struct lpddr2_timings *timings, | ||
481 | const struct lpddr2_min_tck *min_tck, | ||
482 | const struct lpddr2_addressing *addressing, | ||
483 | u32 type, u32 ip_rev, u32 derated) | ||
484 | { | ||
485 | u32 tim3 = 0, val = 0, t_dqsck; | ||
486 | |||
487 | val = timings->tRAS_max_ns / addressing->tREFI_ns - 1; | ||
488 | val = val > 0xF ? 0xF : val; | ||
489 | tim3 |= val << T_RAS_MAX_SHIFT; | ||
490 | |||
491 | val = DIV_ROUND_UP(addressing->tRFCab_ps, t_ck) - 1; | ||
492 | tim3 |= val << T_RFC_SHIFT; | ||
493 | |||
494 | t_dqsck = (derated == EMIF_DERATED_TIMINGS) ? | ||
495 | timings->tDQSCK_max_derated : timings->tDQSCK_max; | ||
496 | if (ip_rev == EMIF_4D5) | ||
497 | val = DIV_ROUND_UP(t_dqsck + 1000, t_ck) - 1; | ||
498 | else | ||
499 | val = DIV_ROUND_UP(t_dqsck, t_ck) - 1; | ||
500 | |||
501 | tim3 |= val << T_TDQSCKMAX_SHIFT; | ||
502 | |||
503 | val = DIV_ROUND_UP(timings->tZQCS, t_ck) - 1; | ||
504 | tim3 |= val << ZQ_ZQCS_SHIFT; | ||
505 | |||
506 | val = DIV_ROUND_UP(timings->tCKESR, t_ck); | ||
507 | val = max(min_tck->tCKESR, val) - 1; | ||
508 | tim3 |= val << T_CKESR_SHIFT; | ||
509 | |||
510 | if (ip_rev == EMIF_4D5) { | ||
511 | tim3 |= (EMIF_T_CSTA - 1) << T_CSTA_SHIFT; | ||
512 | |||
513 | val = DIV_ROUND_UP(EMIF_T_PDLL_UL, 128) - 1; | ||
514 | tim3 |= val << T_PDLL_UL_SHIFT; | ||
515 | } | ||
516 | |||
517 | return tim3; | ||
518 | } | ||
519 | |||
520 | static u32 get_zq_config_reg(const struct lpddr2_addressing *addressing, | ||
521 | bool cs1_used, bool cal_resistors_per_cs) | ||
522 | { | ||
523 | u32 zq = 0, val = 0; | ||
524 | |||
525 | val = EMIF_ZQCS_INTERVAL_US * 1000 / addressing->tREFI_ns; | ||
526 | zq |= val << ZQ_REFINTERVAL_SHIFT; | ||
527 | |||
528 | val = DIV_ROUND_UP(T_ZQCL_DEFAULT_NS, T_ZQCS_DEFAULT_NS) - 1; | ||
529 | zq |= val << ZQ_ZQCL_MULT_SHIFT; | ||
530 | |||
531 | val = DIV_ROUND_UP(T_ZQINIT_DEFAULT_NS, T_ZQCL_DEFAULT_NS) - 1; | ||
532 | zq |= val << ZQ_ZQINIT_MULT_SHIFT; | ||
533 | |||
534 | zq |= ZQ_SFEXITEN_ENABLE << ZQ_SFEXITEN_SHIFT; | ||
535 | |||
536 | if (cal_resistors_per_cs) | ||
537 | zq |= ZQ_DUALCALEN_ENABLE << ZQ_DUALCALEN_SHIFT; | ||
538 | else | ||
539 | zq |= ZQ_DUALCALEN_DISABLE << ZQ_DUALCALEN_SHIFT; | ||
540 | |||
541 | zq |= ZQ_CS0EN_MASK; /* CS0 is used for sure */ | ||
542 | |||
543 | val = cs1_used ? 1 : 0; | ||
544 | zq |= val << ZQ_CS1EN_SHIFT; | ||
545 | |||
546 | return zq; | ||
547 | } | ||
548 | |||
549 | static u32 get_temp_alert_config(const struct lpddr2_addressing *addressing, | ||
550 | const struct emif_custom_configs *custom_configs, bool cs1_used, | ||
551 | u32 sdram_io_width, u32 emif_bus_width) | ||
552 | { | ||
553 | u32 alert = 0, interval, devcnt; | ||
554 | |||
555 | if (custom_configs && (custom_configs->mask & | ||
556 | EMIF_CUSTOM_CONFIG_TEMP_ALERT_POLL_INTERVAL)) | ||
557 | interval = custom_configs->temp_alert_poll_interval_ms; | ||
558 | else | ||
559 | interval = TEMP_ALERT_POLL_INTERVAL_DEFAULT_MS; | ||
560 | |||
561 | interval *= 1000000; /* Convert to ns */ | ||
562 | interval /= addressing->tREFI_ns; /* Convert to refresh cycles */ | ||
563 | alert |= (interval << TA_REFINTERVAL_SHIFT); | ||
564 | |||
565 | /* | ||
566 | * sdram_io_width is in 'log2(x) - 1' form. Convert emif_bus_width | ||
567 | * also to this form and subtract to get TA_DEVCNT, which is | ||
568 | * in log2(x) form. | ||
569 | */ | ||
570 | emif_bus_width = __fls(emif_bus_width) - 1; | ||
571 | devcnt = emif_bus_width - sdram_io_width; | ||
572 | alert |= devcnt << TA_DEVCNT_SHIFT; | ||
573 | |||
574 | /* DEVWDT is in 'log2(x) - 3' form */ | ||
575 | alert |= (sdram_io_width - 2) << TA_DEVWDT_SHIFT; | ||
576 | |||
577 | alert |= 1 << TA_SFEXITEN_SHIFT; | ||
578 | alert |= 1 << TA_CS0EN_SHIFT; | ||
579 | alert |= (cs1_used ? 1 : 0) << TA_CS1EN_SHIFT; | ||
580 | |||
581 | return alert; | ||
582 | } | ||
583 | |||
584 | static u32 get_read_idle_ctrl_shdw(u8 volt_ramp) | ||
585 | { | ||
586 | u32 idle = 0, val = 0; | ||
587 | |||
588 | /* | ||
589 | * Maximum value in normal conditions and increased frequency | ||
590 | * when voltage is ramping | ||
591 | */ | ||
592 | if (volt_ramp) | ||
593 | val = READ_IDLE_INTERVAL_DVFS / t_ck / 64 - 1; | ||
594 | else | ||
595 | val = 0x1FF; | ||
596 | |||
597 | /* | ||
598 | * READ_IDLE_CTRL register in EMIF4D has same offset and fields | ||
599 | * as DLL_CALIB_CTRL in EMIF4D5, so use the same shifts | ||
600 | */ | ||
601 | idle |= val << DLL_CALIB_INTERVAL_SHIFT; | ||
602 | idle |= EMIF_READ_IDLE_LEN_VAL << ACK_WAIT_SHIFT; | ||
603 | |||
604 | return idle; | ||
605 | } | ||
606 | |||
607 | static u32 get_dll_calib_ctrl_shdw(u8 volt_ramp) | ||
608 | { | ||
609 | u32 calib = 0, val = 0; | ||
610 | |||
611 | if (volt_ramp == DDR_VOLTAGE_RAMPING) | ||
612 | val = DLL_CALIB_INTERVAL_DVFS / t_ck / 16 - 1; | ||
613 | else | ||
614 | val = 0; /* Disabled when voltage is stable */ | ||
615 | |||
616 | calib |= val << DLL_CALIB_INTERVAL_SHIFT; | ||
617 | calib |= DLL_CALIB_ACK_WAIT_VAL << ACK_WAIT_SHIFT; | ||
618 | |||
619 | return calib; | ||
620 | } | ||
621 | |||
622 | static u32 get_ddr_phy_ctrl_1_attilaphy_4d(const struct lpddr2_timings *timings, | ||
623 | u32 freq, u8 RL) | ||
624 | { | ||
625 | u32 phy = EMIF_DDR_PHY_CTRL_1_BASE_VAL_ATTILAPHY, val = 0; | ||
626 | |||
627 | val = RL + DIV_ROUND_UP(timings->tDQSCK_max, t_ck) - 1; | ||
628 | phy |= val << READ_LATENCY_SHIFT_4D; | ||
629 | |||
630 | if (freq <= 100000000) | ||
631 | val = EMIF_DLL_SLAVE_DLY_CTRL_100_MHZ_AND_LESS_ATTILAPHY; | ||
632 | else if (freq <= 200000000) | ||
633 | val = EMIF_DLL_SLAVE_DLY_CTRL_200_MHZ_ATTILAPHY; | ||
634 | else | ||
635 | val = EMIF_DLL_SLAVE_DLY_CTRL_400_MHZ_ATTILAPHY; | ||
636 | |||
637 | phy |= val << DLL_SLAVE_DLY_CTRL_SHIFT_4D; | ||
638 | |||
639 | return phy; | ||
640 | } | ||
641 | |||
642 | static u32 get_phy_ctrl_1_intelliphy_4d5(u32 freq, u8 cl) | ||
643 | { | ||
644 | u32 phy = EMIF_DDR_PHY_CTRL_1_BASE_VAL_INTELLIPHY, half_delay; | ||
645 | |||
646 | /* | ||
647 | * DLL operates at 266 MHz. If DDR frequency is near 266 MHz, | ||
648 | * half-delay is not needed else set half-delay | ||
649 | */ | ||
650 | if (freq >= 265000000 && freq < 267000000) | ||
651 | half_delay = 0; | ||
652 | else | ||
653 | half_delay = 1; | ||
654 | |||
655 | phy |= half_delay << DLL_HALF_DELAY_SHIFT_4D5; | ||
656 | phy |= ((cl + DIV_ROUND_UP(EMIF_PHY_TOTAL_READ_LATENCY_INTELLIPHY_PS, | ||
657 | t_ck) - 1) << READ_LATENCY_SHIFT_4D5); | ||
658 | |||
659 | return phy; | ||
660 | } | ||
661 | |||
662 | static u32 get_ext_phy_ctrl_2_intelliphy_4d5(void) | ||
663 | { | ||
664 | u32 fifo_we_slave_ratio; | ||
665 | |||
666 | fifo_we_slave_ratio = DIV_ROUND_CLOSEST( | ||
667 | EMIF_INTELLI_PHY_DQS_GATE_OPENING_DELAY_PS * 256 , t_ck); | ||
668 | |||
669 | return fifo_we_slave_ratio | fifo_we_slave_ratio << 11 | | ||
670 | fifo_we_slave_ratio << 22; | ||
671 | } | ||
672 | |||
673 | static u32 get_ext_phy_ctrl_3_intelliphy_4d5(void) | ||
674 | { | ||
675 | u32 fifo_we_slave_ratio; | ||
676 | |||
677 | fifo_we_slave_ratio = DIV_ROUND_CLOSEST( | ||
678 | EMIF_INTELLI_PHY_DQS_GATE_OPENING_DELAY_PS * 256 , t_ck); | ||
679 | |||
680 | return fifo_we_slave_ratio >> 10 | fifo_we_slave_ratio << 1 | | ||
681 | fifo_we_slave_ratio << 12 | fifo_we_slave_ratio << 23; | ||
682 | } | ||
683 | |||
684 | static u32 get_ext_phy_ctrl_4_intelliphy_4d5(void) | ||
685 | { | ||
686 | u32 fifo_we_slave_ratio; | ||
687 | |||
688 | fifo_we_slave_ratio = DIV_ROUND_CLOSEST( | ||
689 | EMIF_INTELLI_PHY_DQS_GATE_OPENING_DELAY_PS * 256 , t_ck); | ||
690 | |||
691 | return fifo_we_slave_ratio >> 9 | fifo_we_slave_ratio << 2 | | ||
692 | fifo_we_slave_ratio << 13; | ||
693 | } | ||
694 | |||
695 | static u32 get_pwr_mgmt_ctrl(u32 freq, struct emif_data *emif, u32 ip_rev) | ||
696 | { | ||
697 | u32 pwr_mgmt_ctrl = 0, timeout; | ||
698 | u32 lpmode = EMIF_LP_MODE_SELF_REFRESH; | ||
699 | u32 timeout_perf = EMIF_LP_MODE_TIMEOUT_PERFORMANCE; | ||
700 | u32 timeout_pwr = EMIF_LP_MODE_TIMEOUT_POWER; | ||
701 | u32 freq_threshold = EMIF_LP_MODE_FREQ_THRESHOLD; | ||
702 | |||
703 | struct emif_custom_configs *cust_cfgs = emif->plat_data->custom_configs; | ||
704 | |||
705 | if (cust_cfgs && (cust_cfgs->mask & EMIF_CUSTOM_CONFIG_LPMODE)) { | ||
706 | lpmode = cust_cfgs->lpmode; | ||
707 | timeout_perf = cust_cfgs->lpmode_timeout_performance; | ||
708 | timeout_pwr = cust_cfgs->lpmode_timeout_power; | ||
709 | freq_threshold = cust_cfgs->lpmode_freq_threshold; | ||
710 | } | ||
711 | |||
712 | /* Timeout based on DDR frequency */ | ||
713 | timeout = freq >= freq_threshold ? timeout_perf : timeout_pwr; | ||
714 | |||
715 | /* The value to be set in register is "log2(timeout) - 3" */ | ||
716 | if (timeout < 16) { | ||
717 | timeout = 0; | ||
718 | } else { | ||
719 | timeout = __fls(timeout) - 3; | ||
720 | if (timeout & (timeout - 1)) | ||
721 | timeout++; | ||
722 | } | ||
723 | |||
724 | switch (lpmode) { | ||
725 | case EMIF_LP_MODE_CLOCK_STOP: | ||
726 | pwr_mgmt_ctrl = (timeout << CS_TIM_SHIFT) | | ||
727 | SR_TIM_MASK | PD_TIM_MASK; | ||
728 | break; | ||
729 | case EMIF_LP_MODE_SELF_REFRESH: | ||
730 | /* Workaround for errata i735 */ | ||
731 | if (timeout < 6) | ||
732 | timeout = 6; | ||
733 | |||
734 | pwr_mgmt_ctrl = (timeout << SR_TIM_SHIFT) | | ||
735 | CS_TIM_MASK | PD_TIM_MASK; | ||
736 | break; | ||
737 | case EMIF_LP_MODE_PWR_DN: | ||
738 | pwr_mgmt_ctrl = (timeout << PD_TIM_SHIFT) | | ||
739 | CS_TIM_MASK | SR_TIM_MASK; | ||
740 | break; | ||
741 | case EMIF_LP_MODE_DISABLE: | ||
742 | default: | ||
743 | pwr_mgmt_ctrl = CS_TIM_MASK | | ||
744 | PD_TIM_MASK | SR_TIM_MASK; | ||
745 | } | ||
746 | |||
747 | /* No CS_TIM in EMIF_4D5 */ | ||
748 | if (ip_rev == EMIF_4D5) | ||
749 | pwr_mgmt_ctrl &= ~CS_TIM_MASK; | ||
750 | |||
751 | pwr_mgmt_ctrl |= lpmode << LP_MODE_SHIFT; | ||
752 | |||
753 | return pwr_mgmt_ctrl; | ||
754 | } | ||
755 | |||
756 | /* | ||
757 | * Get the temperature level of the EMIF instance: | ||
758 | * Reads the MR4 register of attached SDRAM parts to find out the temperature | ||
759 | * level. If there are two parts attached(one on each CS), then the temperature | ||
760 | * level for the EMIF instance is the higher of the two temperatures. | ||
761 | */ | ||
762 | static void get_temperature_level(struct emif_data *emif) | ||
763 | { | ||
764 | u32 temp, temperature_level; | ||
765 | void __iomem *base; | ||
766 | |||
767 | base = emif->base; | ||
768 | |||
769 | /* Read mode register 4 */ | ||
770 | writel(DDR_MR4, base + EMIF_LPDDR2_MODE_REG_CONFIG); | ||
771 | temperature_level = readl(base + EMIF_LPDDR2_MODE_REG_DATA); | ||
772 | temperature_level = (temperature_level & MR4_SDRAM_REF_RATE_MASK) >> | ||
773 | MR4_SDRAM_REF_RATE_SHIFT; | ||
774 | |||
775 | if (emif->plat_data->device_info->cs1_used) { | ||
776 | writel(DDR_MR4 | CS_MASK, base + EMIF_LPDDR2_MODE_REG_CONFIG); | ||
777 | temp = readl(base + EMIF_LPDDR2_MODE_REG_DATA); | ||
778 | temp = (temp & MR4_SDRAM_REF_RATE_MASK) | ||
779 | >> MR4_SDRAM_REF_RATE_SHIFT; | ||
780 | temperature_level = max(temp, temperature_level); | ||
781 | } | ||
782 | |||
783 | /* treat everything less than nominal(3) in MR4 as nominal */ | ||
784 | if (unlikely(temperature_level < SDRAM_TEMP_NOMINAL)) | ||
785 | temperature_level = SDRAM_TEMP_NOMINAL; | ||
786 | |||
787 | /* if we get reserved value in MR4 persist with the existing value */ | ||
788 | if (likely(temperature_level != SDRAM_TEMP_RESERVED_4)) | ||
789 | emif->temperature_level = temperature_level; | ||
790 | } | ||
791 | |||
792 | /* | ||
793 | * Program EMIF shadow registers that are not dependent on temperature | ||
794 | * or voltage | ||
795 | */ | ||
796 | static void setup_registers(struct emif_data *emif, struct emif_regs *regs) | ||
797 | { | ||
798 | void __iomem *base = emif->base; | ||
799 | |||
800 | writel(regs->sdram_tim2_shdw, base + EMIF_SDRAM_TIMING_2_SHDW); | ||
801 | writel(regs->phy_ctrl_1_shdw, base + EMIF_DDR_PHY_CTRL_1_SHDW); | ||
802 | |||
803 | /* Settings specific for EMIF4D5 */ | ||
804 | if (emif->plat_data->ip_rev != EMIF_4D5) | ||
805 | return; | ||
806 | writel(regs->ext_phy_ctrl_2_shdw, base + EMIF_EXT_PHY_CTRL_2_SHDW); | ||
807 | writel(regs->ext_phy_ctrl_3_shdw, base + EMIF_EXT_PHY_CTRL_3_SHDW); | ||
808 | writel(regs->ext_phy_ctrl_4_shdw, base + EMIF_EXT_PHY_CTRL_4_SHDW); | ||
809 | } | ||
810 | |||
811 | /* | ||
812 | * When voltage ramps dll calibration and forced read idle should | ||
813 | * happen more often | ||
814 | */ | ||
815 | static void setup_volt_sensitive_regs(struct emif_data *emif, | ||
816 | struct emif_regs *regs, u32 volt_state) | ||
817 | { | ||
818 | u32 calib_ctrl; | ||
819 | void __iomem *base = emif->base; | ||
820 | |||
821 | /* | ||
822 | * EMIF_READ_IDLE_CTRL in EMIF4D refers to the same register as | ||
823 | * EMIF_DLL_CALIB_CTRL in EMIF4D5 and dll_calib_ctrl_shadow_* | ||
824 | * is an alias of the respective read_idle_ctrl_shdw_* (members of | ||
825 | * a union). So, the below code takes care of both cases | ||
826 | */ | ||
827 | if (volt_state == DDR_VOLTAGE_RAMPING) | ||
828 | calib_ctrl = regs->dll_calib_ctrl_shdw_volt_ramp; | ||
829 | else | ||
830 | calib_ctrl = regs->dll_calib_ctrl_shdw_normal; | ||
831 | |||
832 | writel(calib_ctrl, base + EMIF_DLL_CALIB_CTRL_SHDW); | ||
833 | } | ||
834 | |||
835 | /* | ||
836 | * setup_temperature_sensitive_regs() - set the timings for temperature | ||
837 | * sensitive registers. This happens once at initialisation time based | ||
838 | * on the temperature at boot time and subsequently based on the temperature | ||
839 | * alert interrupt. Temperature alert can happen when the temperature | ||
840 | * increases or drops. So this function can have the effect of either | ||
841 | * derating the timings or going back to nominal values. | ||
842 | */ | ||
843 | static void setup_temperature_sensitive_regs(struct emif_data *emif, | ||
844 | struct emif_regs *regs) | ||
845 | { | ||
846 | u32 tim1, tim3, ref_ctrl, type; | ||
847 | void __iomem *base = emif->base; | ||
848 | u32 temperature; | ||
849 | |||
850 | type = emif->plat_data->device_info->type; | ||
851 | |||
852 | tim1 = regs->sdram_tim1_shdw; | ||
853 | tim3 = regs->sdram_tim3_shdw; | ||
854 | ref_ctrl = regs->ref_ctrl_shdw; | ||
855 | |||
856 | /* No de-rating for non-lpddr2 devices */ | ||
857 | if (type != DDR_TYPE_LPDDR2_S2 && type != DDR_TYPE_LPDDR2_S4) | ||
858 | goto out; | ||
859 | |||
860 | temperature = emif->temperature_level; | ||
861 | if (temperature == SDRAM_TEMP_HIGH_DERATE_REFRESH) { | ||
862 | ref_ctrl = regs->ref_ctrl_shdw_derated; | ||
863 | } else if (temperature == SDRAM_TEMP_HIGH_DERATE_REFRESH_AND_TIMINGS) { | ||
864 | tim1 = regs->sdram_tim1_shdw_derated; | ||
865 | tim3 = regs->sdram_tim3_shdw_derated; | ||
866 | ref_ctrl = regs->ref_ctrl_shdw_derated; | ||
867 | } | ||
868 | |||
869 | out: | ||
870 | writel(tim1, base + EMIF_SDRAM_TIMING_1_SHDW); | ||
871 | writel(tim3, base + EMIF_SDRAM_TIMING_3_SHDW); | ||
872 | writel(ref_ctrl, base + EMIF_SDRAM_REFRESH_CTRL_SHDW); | ||
873 | } | ||
874 | |||
875 | static irqreturn_t handle_temp_alert(void __iomem *base, struct emif_data *emif) | ||
876 | { | ||
877 | u32 old_temp_level; | ||
878 | irqreturn_t ret = IRQ_HANDLED; | ||
879 | |||
880 | spin_lock_irqsave(&emif_lock, irq_state); | ||
881 | old_temp_level = emif->temperature_level; | ||
882 | get_temperature_level(emif); | ||
883 | |||
884 | if (unlikely(emif->temperature_level == old_temp_level)) { | ||
885 | goto out; | ||
886 | } else if (!emif->curr_regs) { | ||
887 | dev_err(emif->dev, "temperature alert before registers are calculated, not de-rating timings\n"); | ||
888 | goto out; | ||
889 | } | ||
890 | |||
891 | if (emif->temperature_level < old_temp_level || | ||
892 | emif->temperature_level == SDRAM_TEMP_VERY_HIGH_SHUTDOWN) { | ||
893 | /* | ||
894 | * Temperature coming down - defer handling to thread OR | ||
895 | * Temperature far too high - do kernel_power_off() from | ||
896 | * thread context | ||
897 | */ | ||
898 | ret = IRQ_WAKE_THREAD; | ||
899 | } else { | ||
900 | /* Temperature is going up - handle immediately */ | ||
901 | setup_temperature_sensitive_regs(emif, emif->curr_regs); | ||
902 | do_freq_update(); | ||
903 | } | ||
904 | |||
905 | out: | ||
906 | spin_unlock_irqrestore(&emif_lock, irq_state); | ||
907 | return ret; | ||
908 | } | ||
909 | |||
910 | static irqreturn_t emif_interrupt_handler(int irq, void *dev_id) | ||
911 | { | ||
912 | u32 interrupts; | ||
913 | struct emif_data *emif = dev_id; | ||
914 | void __iomem *base = emif->base; | ||
915 | struct device *dev = emif->dev; | ||
916 | irqreturn_t ret = IRQ_HANDLED; | ||
917 | |||
918 | /* Save the status and clear it */ | ||
919 | interrupts = readl(base + EMIF_SYSTEM_OCP_INTERRUPT_STATUS); | ||
920 | writel(interrupts, base + EMIF_SYSTEM_OCP_INTERRUPT_STATUS); | ||
921 | |||
922 | /* | ||
923 | * Handle temperature alert | ||
924 | * Temperature alert should be same for all ports | ||
925 | * So, it's enough to process it only for one of the ports | ||
926 | */ | ||
927 | if (interrupts & TA_SYS_MASK) | ||
928 | ret = handle_temp_alert(base, emif); | ||
929 | |||
930 | if (interrupts & ERR_SYS_MASK) | ||
931 | dev_err(dev, "Access error from SYS port - %x\n", interrupts); | ||
932 | |||
933 | if (emif->plat_data->hw_caps & EMIF_HW_CAPS_LL_INTERFACE) { | ||
934 | /* Save the status and clear it */ | ||
935 | interrupts = readl(base + EMIF_LL_OCP_INTERRUPT_STATUS); | ||
936 | writel(interrupts, base + EMIF_LL_OCP_INTERRUPT_STATUS); | ||
937 | |||
938 | if (interrupts & ERR_LL_MASK) | ||
939 | dev_err(dev, "Access error from LL port - %x\n", | ||
940 | interrupts); | ||
941 | } | ||
942 | |||
943 | return ret; | ||
944 | } | ||
945 | |||
946 | static irqreturn_t emif_threaded_isr(int irq, void *dev_id) | ||
947 | { | ||
948 | struct emif_data *emif = dev_id; | ||
949 | |||
950 | if (emif->temperature_level == SDRAM_TEMP_VERY_HIGH_SHUTDOWN) { | ||
951 | dev_emerg(emif->dev, "SDRAM temperature exceeds operating limit.. Needs shut down!!!\n"); | ||
952 | kernel_power_off(); | ||
953 | return IRQ_HANDLED; | ||
954 | } | ||
955 | |||
956 | spin_lock_irqsave(&emif_lock, irq_state); | ||
957 | |||
958 | if (emif->curr_regs) { | ||
959 | setup_temperature_sensitive_regs(emif, emif->curr_regs); | ||
960 | do_freq_update(); | ||
961 | } else { | ||
962 | dev_err(emif->dev, "temperature alert before registers are calculated, not de-rating timings\n"); | ||
963 | } | ||
964 | |||
965 | spin_unlock_irqrestore(&emif_lock, irq_state); | ||
966 | |||
967 | return IRQ_HANDLED; | ||
968 | } | ||
969 | |||
970 | static void clear_all_interrupts(struct emif_data *emif) | ||
971 | { | ||
972 | void __iomem *base = emif->base; | ||
973 | |||
974 | writel(readl(base + EMIF_SYSTEM_OCP_INTERRUPT_STATUS), | ||
975 | base + EMIF_SYSTEM_OCP_INTERRUPT_STATUS); | ||
976 | if (emif->plat_data->hw_caps & EMIF_HW_CAPS_LL_INTERFACE) | ||
977 | writel(readl(base + EMIF_LL_OCP_INTERRUPT_STATUS), | ||
978 | base + EMIF_LL_OCP_INTERRUPT_STATUS); | ||
979 | } | ||
980 | |||
981 | static void disable_and_clear_all_interrupts(struct emif_data *emif) | ||
982 | { | ||
983 | void __iomem *base = emif->base; | ||
984 | |||
985 | /* Disable all interrupts */ | ||
986 | writel(readl(base + EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_SET), | ||
987 | base + EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_CLEAR); | ||
988 | if (emif->plat_data->hw_caps & EMIF_HW_CAPS_LL_INTERFACE) | ||
989 | writel(readl(base + EMIF_LL_OCP_INTERRUPT_ENABLE_SET), | ||
990 | base + EMIF_LL_OCP_INTERRUPT_ENABLE_CLEAR); | ||
991 | |||
992 | /* Clear all interrupts */ | ||
993 | clear_all_interrupts(emif); | ||
994 | } | ||
995 | |||
996 | static int __init_or_module setup_interrupts(struct emif_data *emif, u32 irq) | ||
997 | { | ||
998 | u32 interrupts, type; | ||
999 | void __iomem *base = emif->base; | ||
1000 | |||
1001 | type = emif->plat_data->device_info->type; | ||
1002 | |||
1003 | clear_all_interrupts(emif); | ||
1004 | |||
1005 | /* Enable interrupts for SYS interface */ | ||
1006 | interrupts = EN_ERR_SYS_MASK; | ||
1007 | if (type == DDR_TYPE_LPDDR2_S2 || type == DDR_TYPE_LPDDR2_S4) | ||
1008 | interrupts |= EN_TA_SYS_MASK; | ||
1009 | writel(interrupts, base + EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_SET); | ||
1010 | |||
1011 | /* Enable interrupts for LL interface */ | ||
1012 | if (emif->plat_data->hw_caps & EMIF_HW_CAPS_LL_INTERFACE) { | ||
1013 | /* TA need not be enabled for LL */ | ||
1014 | interrupts = EN_ERR_LL_MASK; | ||
1015 | writel(interrupts, base + EMIF_LL_OCP_INTERRUPT_ENABLE_SET); | ||
1016 | } | ||
1017 | |||
1018 | /* setup IRQ handlers */ | ||
1019 | return devm_request_threaded_irq(emif->dev, irq, | ||
1020 | emif_interrupt_handler, | ||
1021 | emif_threaded_isr, | ||
1022 | 0, dev_name(emif->dev), | ||
1023 | emif); | ||
1024 | |||
1025 | } | ||
1026 | |||
1027 | static void __init_or_module emif_onetime_settings(struct emif_data *emif) | ||
1028 | { | ||
1029 | u32 pwr_mgmt_ctrl, zq, temp_alert_cfg; | ||
1030 | void __iomem *base = emif->base; | ||
1031 | const struct lpddr2_addressing *addressing; | ||
1032 | const struct ddr_device_info *device_info; | ||
1033 | |||
1034 | device_info = emif->plat_data->device_info; | ||
1035 | addressing = get_addressing_table(device_info); | ||
1036 | |||
1037 | /* | ||
1038 | * Init power management settings | ||
1039 | * We don't know the frequency yet. Use a high frequency | ||
1040 | * value for a conservative timeout setting | ||
1041 | */ | ||
1042 | pwr_mgmt_ctrl = get_pwr_mgmt_ctrl(1000000000, emif, | ||
1043 | emif->plat_data->ip_rev); | ||
1044 | emif->lpmode = (pwr_mgmt_ctrl & LP_MODE_MASK) >> LP_MODE_SHIFT; | ||
1045 | writel(pwr_mgmt_ctrl, base + EMIF_POWER_MANAGEMENT_CONTROL); | ||
1046 | |||
1047 | /* Init ZQ calibration settings */ | ||
1048 | zq = get_zq_config_reg(addressing, device_info->cs1_used, | ||
1049 | device_info->cal_resistors_per_cs); | ||
1050 | writel(zq, base + EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG); | ||
1051 | |||
1052 | /* Check temperature level temperature level*/ | ||
1053 | get_temperature_level(emif); | ||
1054 | if (emif->temperature_level == SDRAM_TEMP_VERY_HIGH_SHUTDOWN) | ||
1055 | dev_emerg(emif->dev, "SDRAM temperature exceeds operating limit.. Needs shut down!!!\n"); | ||
1056 | |||
1057 | /* Init temperature polling */ | ||
1058 | temp_alert_cfg = get_temp_alert_config(addressing, | ||
1059 | emif->plat_data->custom_configs, device_info->cs1_used, | ||
1060 | device_info->io_width, get_emif_bus_width(emif)); | ||
1061 | writel(temp_alert_cfg, base + EMIF_TEMPERATURE_ALERT_CONFIG); | ||
1062 | |||
1063 | /* | ||
1064 | * Program external PHY control registers that are not frequency | ||
1065 | * dependent | ||
1066 | */ | ||
1067 | if (emif->plat_data->phy_type != EMIF_PHY_TYPE_INTELLIPHY) | ||
1068 | return; | ||
1069 | writel(EMIF_EXT_PHY_CTRL_1_VAL, base + EMIF_EXT_PHY_CTRL_1_SHDW); | ||
1070 | writel(EMIF_EXT_PHY_CTRL_5_VAL, base + EMIF_EXT_PHY_CTRL_5_SHDW); | ||
1071 | writel(EMIF_EXT_PHY_CTRL_6_VAL, base + EMIF_EXT_PHY_CTRL_6_SHDW); | ||
1072 | writel(EMIF_EXT_PHY_CTRL_7_VAL, base + EMIF_EXT_PHY_CTRL_7_SHDW); | ||
1073 | writel(EMIF_EXT_PHY_CTRL_8_VAL, base + EMIF_EXT_PHY_CTRL_8_SHDW); | ||
1074 | writel(EMIF_EXT_PHY_CTRL_9_VAL, base + EMIF_EXT_PHY_CTRL_9_SHDW); | ||
1075 | writel(EMIF_EXT_PHY_CTRL_10_VAL, base + EMIF_EXT_PHY_CTRL_10_SHDW); | ||
1076 | writel(EMIF_EXT_PHY_CTRL_11_VAL, base + EMIF_EXT_PHY_CTRL_11_SHDW); | ||
1077 | writel(EMIF_EXT_PHY_CTRL_12_VAL, base + EMIF_EXT_PHY_CTRL_12_SHDW); | ||
1078 | writel(EMIF_EXT_PHY_CTRL_13_VAL, base + EMIF_EXT_PHY_CTRL_13_SHDW); | ||
1079 | writel(EMIF_EXT_PHY_CTRL_14_VAL, base + EMIF_EXT_PHY_CTRL_14_SHDW); | ||
1080 | writel(EMIF_EXT_PHY_CTRL_15_VAL, base + EMIF_EXT_PHY_CTRL_15_SHDW); | ||
1081 | writel(EMIF_EXT_PHY_CTRL_16_VAL, base + EMIF_EXT_PHY_CTRL_16_SHDW); | ||
1082 | writel(EMIF_EXT_PHY_CTRL_17_VAL, base + EMIF_EXT_PHY_CTRL_17_SHDW); | ||
1083 | writel(EMIF_EXT_PHY_CTRL_18_VAL, base + EMIF_EXT_PHY_CTRL_18_SHDW); | ||
1084 | writel(EMIF_EXT_PHY_CTRL_19_VAL, base + EMIF_EXT_PHY_CTRL_19_SHDW); | ||
1085 | writel(EMIF_EXT_PHY_CTRL_20_VAL, base + EMIF_EXT_PHY_CTRL_20_SHDW); | ||
1086 | writel(EMIF_EXT_PHY_CTRL_21_VAL, base + EMIF_EXT_PHY_CTRL_21_SHDW); | ||
1087 | writel(EMIF_EXT_PHY_CTRL_22_VAL, base + EMIF_EXT_PHY_CTRL_22_SHDW); | ||
1088 | writel(EMIF_EXT_PHY_CTRL_23_VAL, base + EMIF_EXT_PHY_CTRL_23_SHDW); | ||
1089 | writel(EMIF_EXT_PHY_CTRL_24_VAL, base + EMIF_EXT_PHY_CTRL_24_SHDW); | ||
1090 | } | ||
1091 | |||
1092 | static void get_default_timings(struct emif_data *emif) | ||
1093 | { | ||
1094 | struct emif_platform_data *pd = emif->plat_data; | ||
1095 | |||
1096 | pd->timings = lpddr2_jedec_timings; | ||
1097 | pd->timings_arr_size = ARRAY_SIZE(lpddr2_jedec_timings); | ||
1098 | |||
1099 | dev_warn(emif->dev, "%s: using default timings\n", __func__); | ||
1100 | } | ||
1101 | |||
1102 | static int is_dev_data_valid(u32 type, u32 density, u32 io_width, u32 phy_type, | ||
1103 | u32 ip_rev, struct device *dev) | ||
1104 | { | ||
1105 | int valid; | ||
1106 | |||
1107 | valid = (type == DDR_TYPE_LPDDR2_S4 || | ||
1108 | type == DDR_TYPE_LPDDR2_S2) | ||
1109 | && (density >= DDR_DENSITY_64Mb | ||
1110 | && density <= DDR_DENSITY_8Gb) | ||
1111 | && (io_width >= DDR_IO_WIDTH_8 | ||
1112 | && io_width <= DDR_IO_WIDTH_32); | ||
1113 | |||
1114 | /* Combinations of EMIF and PHY revisions that we support today */ | ||
1115 | switch (ip_rev) { | ||
1116 | case EMIF_4D: | ||
1117 | valid = valid && (phy_type == EMIF_PHY_TYPE_ATTILAPHY); | ||
1118 | break; | ||
1119 | case EMIF_4D5: | ||
1120 | valid = valid && (phy_type == EMIF_PHY_TYPE_INTELLIPHY); | ||
1121 | break; | ||
1122 | default: | ||
1123 | valid = 0; | ||
1124 | } | ||
1125 | |||
1126 | if (!valid) | ||
1127 | dev_err(dev, "%s: invalid DDR details\n", __func__); | ||
1128 | return valid; | ||
1129 | } | ||
1130 | |||
1131 | static int is_custom_config_valid(struct emif_custom_configs *cust_cfgs, | ||
1132 | struct device *dev) | ||
1133 | { | ||
1134 | int valid = 1; | ||
1135 | |||
1136 | if ((cust_cfgs->mask & EMIF_CUSTOM_CONFIG_LPMODE) && | ||
1137 | (cust_cfgs->lpmode != EMIF_LP_MODE_DISABLE)) | ||
1138 | valid = cust_cfgs->lpmode_freq_threshold && | ||
1139 | cust_cfgs->lpmode_timeout_performance && | ||
1140 | cust_cfgs->lpmode_timeout_power; | ||
1141 | |||
1142 | if (cust_cfgs->mask & EMIF_CUSTOM_CONFIG_TEMP_ALERT_POLL_INTERVAL) | ||
1143 | valid = valid && cust_cfgs->temp_alert_poll_interval_ms; | ||
1144 | |||
1145 | if (!valid) | ||
1146 | dev_warn(dev, "%s: invalid custom configs\n", __func__); | ||
1147 | |||
1148 | return valid; | ||
1149 | } | ||
1150 | |||
1151 | static struct emif_data *__init_or_module get_device_details( | ||
1152 | struct platform_device *pdev) | ||
1153 | { | ||
1154 | u32 size; | ||
1155 | struct emif_data *emif = NULL; | ||
1156 | struct ddr_device_info *dev_info; | ||
1157 | struct emif_custom_configs *cust_cfgs; | ||
1158 | struct emif_platform_data *pd; | ||
1159 | struct device *dev; | ||
1160 | void *temp; | ||
1161 | |||
1162 | pd = pdev->dev.platform_data; | ||
1163 | dev = &pdev->dev; | ||
1164 | |||
1165 | if (!(pd && pd->device_info && is_dev_data_valid(pd->device_info->type, | ||
1166 | pd->device_info->density, pd->device_info->io_width, | ||
1167 | pd->phy_type, pd->ip_rev, dev))) { | ||
1168 | dev_err(dev, "%s: invalid device data\n", __func__); | ||
1169 | goto error; | ||
1170 | } | ||
1171 | |||
1172 | emif = devm_kzalloc(dev, sizeof(*emif), GFP_KERNEL); | ||
1173 | temp = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); | ||
1174 | dev_info = devm_kzalloc(dev, sizeof(*dev_info), GFP_KERNEL); | ||
1175 | |||
1176 | if (!emif || !pd || !dev_info) { | ||
1177 | dev_err(dev, "%s:%d: allocation error\n", __func__, __LINE__); | ||
1178 | goto error; | ||
1179 | } | ||
1180 | |||
1181 | memcpy(temp, pd, sizeof(*pd)); | ||
1182 | pd = temp; | ||
1183 | memcpy(dev_info, pd->device_info, sizeof(*dev_info)); | ||
1184 | |||
1185 | pd->device_info = dev_info; | ||
1186 | emif->plat_data = pd; | ||
1187 | emif->dev = dev; | ||
1188 | emif->temperature_level = SDRAM_TEMP_NOMINAL; | ||
1189 | |||
1190 | /* | ||
1191 | * For EMIF instances other than EMIF1 see if the devices connected | ||
1192 | * are exactly same as on EMIF1(which is typically the case). If so, | ||
1193 | * mark it as a duplicate of EMIF1 and skip copying timings data. | ||
1194 | * This will save some memory and some computation later. | ||
1195 | */ | ||
1196 | emif->duplicate = emif1 && (memcmp(dev_info, | ||
1197 | emif1->plat_data->device_info, | ||
1198 | sizeof(struct ddr_device_info)) == 0); | ||
1199 | |||
1200 | if (emif->duplicate) { | ||
1201 | pd->timings = NULL; | ||
1202 | pd->min_tck = NULL; | ||
1203 | goto out; | ||
1204 | } else if (emif1) { | ||
1205 | dev_warn(emif->dev, "%s: Non-symmetric DDR geometry\n", | ||
1206 | __func__); | ||
1207 | } | ||
1208 | |||
1209 | /* | ||
1210 | * Copy custom configs - ignore allocation error, if any, as | ||
1211 | * custom_configs is not very critical | ||
1212 | */ | ||
1213 | cust_cfgs = pd->custom_configs; | ||
1214 | if (cust_cfgs && is_custom_config_valid(cust_cfgs, dev)) { | ||
1215 | temp = devm_kzalloc(dev, sizeof(*cust_cfgs), GFP_KERNEL); | ||
1216 | if (temp) | ||
1217 | memcpy(temp, cust_cfgs, sizeof(*cust_cfgs)); | ||
1218 | else | ||
1219 | dev_warn(dev, "%s:%d: allocation error\n", __func__, | ||
1220 | __LINE__); | ||
1221 | pd->custom_configs = temp; | ||
1222 | } | ||
1223 | |||
1224 | /* | ||
1225 | * Copy timings and min-tck values from platform data. If it is not | ||
1226 | * available or if memory allocation fails, use JEDEC defaults | ||
1227 | */ | ||
1228 | size = sizeof(struct lpddr2_timings) * pd->timings_arr_size; | ||
1229 | if (pd->timings) { | ||
1230 | temp = devm_kzalloc(dev, size, GFP_KERNEL); | ||
1231 | if (temp) { | ||
1232 | memcpy(temp, pd->timings, sizeof(*pd->timings)); | ||
1233 | pd->timings = temp; | ||
1234 | } else { | ||
1235 | dev_warn(dev, "%s:%d: allocation error\n", __func__, | ||
1236 | __LINE__); | ||
1237 | get_default_timings(emif); | ||
1238 | } | ||
1239 | } else { | ||
1240 | get_default_timings(emif); | ||
1241 | } | ||
1242 | |||
1243 | if (pd->min_tck) { | ||
1244 | temp = devm_kzalloc(dev, sizeof(*pd->min_tck), GFP_KERNEL); | ||
1245 | if (temp) { | ||
1246 | memcpy(temp, pd->min_tck, sizeof(*pd->min_tck)); | ||
1247 | pd->min_tck = temp; | ||
1248 | } else { | ||
1249 | dev_warn(dev, "%s:%d: allocation error\n", __func__, | ||
1250 | __LINE__); | ||
1251 | pd->min_tck = &lpddr2_jedec_min_tck; | ||
1252 | } | ||
1253 | } else { | ||
1254 | pd->min_tck = &lpddr2_jedec_min_tck; | ||
1255 | } | ||
1256 | |||
1257 | out: | ||
1258 | return emif; | ||
1259 | |||
1260 | error: | ||
1261 | return NULL; | ||
1262 | } | ||
1263 | |||
1264 | static int __init_or_module emif_probe(struct platform_device *pdev) | ||
1265 | { | ||
1266 | struct emif_data *emif; | ||
1267 | struct resource *res; | ||
1268 | int irq; | ||
1269 | |||
1270 | emif = get_device_details(pdev); | ||
1271 | if (!emif) { | ||
1272 | pr_err("%s: error getting device data\n", __func__); | ||
1273 | goto error; | ||
1274 | } | ||
1275 | |||
1276 | list_add(&emif->node, &device_list); | ||
1277 | emif->addressing = get_addressing_table(emif->plat_data->device_info); | ||
1278 | |||
1279 | /* Save pointers to each other in emif and device structures */ | ||
1280 | emif->dev = &pdev->dev; | ||
1281 | platform_set_drvdata(pdev, emif); | ||
1282 | |||
1283 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1284 | if (!res) { | ||
1285 | dev_err(emif->dev, "%s: error getting memory resource\n", | ||
1286 | __func__); | ||
1287 | goto error; | ||
1288 | } | ||
1289 | |||
1290 | emif->base = devm_request_and_ioremap(emif->dev, res); | ||
1291 | if (!emif->base) { | ||
1292 | dev_err(emif->dev, "%s: devm_request_and_ioremap() failed\n", | ||
1293 | __func__); | ||
1294 | goto error; | ||
1295 | } | ||
1296 | |||
1297 | irq = platform_get_irq(pdev, 0); | ||
1298 | if (irq < 0) { | ||
1299 | dev_err(emif->dev, "%s: error getting IRQ resource - %d\n", | ||
1300 | __func__, irq); | ||
1301 | goto error; | ||
1302 | } | ||
1303 | |||
1304 | emif_onetime_settings(emif); | ||
1305 | emif_debugfs_init(emif); | ||
1306 | disable_and_clear_all_interrupts(emif); | ||
1307 | setup_interrupts(emif, irq); | ||
1308 | |||
1309 | /* One-time actions taken on probing the first device */ | ||
1310 | if (!emif1) { | ||
1311 | emif1 = emif; | ||
1312 | spin_lock_init(&emif_lock); | ||
1313 | |||
1314 | /* | ||
1315 | * TODO: register notifiers for frequency and voltage | ||
1316 | * change here once the respective frameworks are | ||
1317 | * available | ||
1318 | */ | ||
1319 | } | ||
1320 | |||
1321 | dev_info(&pdev->dev, "%s: device configured with addr = %p and IRQ%d\n", | ||
1322 | __func__, emif->base, irq); | ||
1323 | |||
1324 | return 0; | ||
1325 | error: | ||
1326 | return -ENODEV; | ||
1327 | } | ||
1328 | |||
1329 | static int __exit emif_remove(struct platform_device *pdev) | ||
1330 | { | ||
1331 | struct emif_data *emif = platform_get_drvdata(pdev); | ||
1332 | |||
1333 | emif_debugfs_exit(emif); | ||
1334 | |||
1335 | return 0; | ||
1336 | } | ||
1337 | |||
1338 | static void emif_shutdown(struct platform_device *pdev) | ||
1339 | { | ||
1340 | struct emif_data *emif = platform_get_drvdata(pdev); | ||
1341 | |||
1342 | disable_and_clear_all_interrupts(emif); | ||
1343 | } | ||
1344 | |||
1345 | static int get_emif_reg_values(struct emif_data *emif, u32 freq, | ||
1346 | struct emif_regs *regs) | ||
1347 | { | ||
1348 | u32 cs1_used, ip_rev, phy_type; | ||
1349 | u32 cl, type; | ||
1350 | const struct lpddr2_timings *timings; | ||
1351 | const struct lpddr2_min_tck *min_tck; | ||
1352 | const struct ddr_device_info *device_info; | ||
1353 | const struct lpddr2_addressing *addressing; | ||
1354 | struct emif_data *emif_for_calc; | ||
1355 | struct device *dev; | ||
1356 | const struct emif_custom_configs *custom_configs; | ||
1357 | |||
1358 | dev = emif->dev; | ||
1359 | /* | ||
1360 | * If the devices on this EMIF instance is duplicate of EMIF1, | ||
1361 | * use EMIF1 details for the calculation | ||
1362 | */ | ||
1363 | emif_for_calc = emif->duplicate ? emif1 : emif; | ||
1364 | timings = get_timings_table(emif_for_calc, freq); | ||
1365 | addressing = emif_for_calc->addressing; | ||
1366 | if (!timings || !addressing) { | ||
1367 | dev_err(dev, "%s: not enough data available for %dHz", | ||
1368 | __func__, freq); | ||
1369 | return -1; | ||
1370 | } | ||
1371 | |||
1372 | device_info = emif_for_calc->plat_data->device_info; | ||
1373 | type = device_info->type; | ||
1374 | cs1_used = device_info->cs1_used; | ||
1375 | ip_rev = emif_for_calc->plat_data->ip_rev; | ||
1376 | phy_type = emif_for_calc->plat_data->phy_type; | ||
1377 | |||
1378 | min_tck = emif_for_calc->plat_data->min_tck; | ||
1379 | custom_configs = emif_for_calc->plat_data->custom_configs; | ||
1380 | |||
1381 | set_ddr_clk_period(freq); | ||
1382 | |||
1383 | regs->ref_ctrl_shdw = get_sdram_ref_ctrl_shdw(freq, addressing); | ||
1384 | regs->sdram_tim1_shdw = get_sdram_tim_1_shdw(timings, min_tck, | ||
1385 | addressing); | ||
1386 | regs->sdram_tim2_shdw = get_sdram_tim_2_shdw(timings, min_tck, | ||
1387 | addressing, type); | ||
1388 | regs->sdram_tim3_shdw = get_sdram_tim_3_shdw(timings, min_tck, | ||
1389 | addressing, type, ip_rev, EMIF_NORMAL_TIMINGS); | ||
1390 | |||
1391 | cl = get_cl(emif); | ||
1392 | |||
1393 | if (phy_type == EMIF_PHY_TYPE_ATTILAPHY && ip_rev == EMIF_4D) { | ||
1394 | regs->phy_ctrl_1_shdw = get_ddr_phy_ctrl_1_attilaphy_4d( | ||
1395 | timings, freq, cl); | ||
1396 | } else if (phy_type == EMIF_PHY_TYPE_INTELLIPHY && ip_rev == EMIF_4D5) { | ||
1397 | regs->phy_ctrl_1_shdw = get_phy_ctrl_1_intelliphy_4d5(freq, cl); | ||
1398 | regs->ext_phy_ctrl_2_shdw = get_ext_phy_ctrl_2_intelliphy_4d5(); | ||
1399 | regs->ext_phy_ctrl_3_shdw = get_ext_phy_ctrl_3_intelliphy_4d5(); | ||
1400 | regs->ext_phy_ctrl_4_shdw = get_ext_phy_ctrl_4_intelliphy_4d5(); | ||
1401 | } else { | ||
1402 | return -1; | ||
1403 | } | ||
1404 | |||
1405 | /* Only timeout values in pwr_mgmt_ctrl_shdw register */ | ||
1406 | regs->pwr_mgmt_ctrl_shdw = | ||
1407 | get_pwr_mgmt_ctrl(freq, emif_for_calc, ip_rev) & | ||
1408 | (CS_TIM_MASK | SR_TIM_MASK | PD_TIM_MASK); | ||
1409 | |||
1410 | if (ip_rev & EMIF_4D) { | ||
1411 | regs->read_idle_ctrl_shdw_normal = | ||
1412 | get_read_idle_ctrl_shdw(DDR_VOLTAGE_STABLE); | ||
1413 | |||
1414 | regs->read_idle_ctrl_shdw_volt_ramp = | ||
1415 | get_read_idle_ctrl_shdw(DDR_VOLTAGE_RAMPING); | ||
1416 | } else if (ip_rev & EMIF_4D5) { | ||
1417 | regs->dll_calib_ctrl_shdw_normal = | ||
1418 | get_dll_calib_ctrl_shdw(DDR_VOLTAGE_STABLE); | ||
1419 | |||
1420 | regs->dll_calib_ctrl_shdw_volt_ramp = | ||
1421 | get_dll_calib_ctrl_shdw(DDR_VOLTAGE_RAMPING); | ||
1422 | } | ||
1423 | |||
1424 | if (type == DDR_TYPE_LPDDR2_S2 || type == DDR_TYPE_LPDDR2_S4) { | ||
1425 | regs->ref_ctrl_shdw_derated = get_sdram_ref_ctrl_shdw(freq / 4, | ||
1426 | addressing); | ||
1427 | |||
1428 | regs->sdram_tim1_shdw_derated = | ||
1429 | get_sdram_tim_1_shdw_derated(timings, min_tck, | ||
1430 | addressing); | ||
1431 | |||
1432 | regs->sdram_tim3_shdw_derated = get_sdram_tim_3_shdw(timings, | ||
1433 | min_tck, addressing, type, ip_rev, | ||
1434 | EMIF_DERATED_TIMINGS); | ||
1435 | } | ||
1436 | |||
1437 | regs->freq = freq; | ||
1438 | |||
1439 | return 0; | ||
1440 | } | ||
1441 | |||
1442 | /* | ||
1443 | * get_regs() - gets the cached emif_regs structure for a given EMIF instance | ||
1444 | * given frequency(freq): | ||
1445 | * | ||
1446 | * As an optimisation, every EMIF instance other than EMIF1 shares the | ||
1447 | * register cache with EMIF1 if the devices connected on this instance | ||
1448 | * are same as that on EMIF1(indicated by the duplicate flag) | ||
1449 | * | ||
1450 | * If we do not have an entry corresponding to the frequency given, we | ||
1451 | * allocate a new entry and calculate the values | ||
1452 | * | ||
1453 | * Upon finding the right reg dump, save it in curr_regs. It can be | ||
1454 | * directly used for thermal de-rating and voltage ramping changes. | ||
1455 | */ | ||
1456 | static struct emif_regs *get_regs(struct emif_data *emif, u32 freq) | ||
1457 | { | ||
1458 | int i; | ||
1459 | struct emif_regs **regs_cache; | ||
1460 | struct emif_regs *regs = NULL; | ||
1461 | struct device *dev; | ||
1462 | |||
1463 | dev = emif->dev; | ||
1464 | if (emif->curr_regs && emif->curr_regs->freq == freq) { | ||
1465 | dev_dbg(dev, "%s: using curr_regs - %u Hz", __func__, freq); | ||
1466 | return emif->curr_regs; | ||
1467 | } | ||
1468 | |||
1469 | if (emif->duplicate) | ||
1470 | regs_cache = emif1->regs_cache; | ||
1471 | else | ||
1472 | regs_cache = emif->regs_cache; | ||
1473 | |||
1474 | for (i = 0; i < EMIF_MAX_NUM_FREQUENCIES && regs_cache[i]; i++) { | ||
1475 | if (regs_cache[i]->freq == freq) { | ||
1476 | regs = regs_cache[i]; | ||
1477 | dev_dbg(dev, | ||
1478 | "%s: reg dump found in reg cache for %u Hz\n", | ||
1479 | __func__, freq); | ||
1480 | break; | ||
1481 | } | ||
1482 | } | ||
1483 | |||
1484 | /* | ||
1485 | * If we don't have an entry for this frequency in the cache create one | ||
1486 | * and calculate the values | ||
1487 | */ | ||
1488 | if (!regs) { | ||
1489 | regs = devm_kzalloc(emif->dev, sizeof(*regs), GFP_ATOMIC); | ||
1490 | if (!regs) | ||
1491 | return NULL; | ||
1492 | |||
1493 | if (get_emif_reg_values(emif, freq, regs)) { | ||
1494 | devm_kfree(emif->dev, regs); | ||
1495 | return NULL; | ||
1496 | } | ||
1497 | |||
1498 | /* | ||
1499 | * Now look for an un-used entry in the cache and save the | ||
1500 | * newly created struct. If there are no free entries | ||
1501 | * over-write the last entry | ||
1502 | */ | ||
1503 | for (i = 0; i < EMIF_MAX_NUM_FREQUENCIES && regs_cache[i]; i++) | ||
1504 | ; | ||
1505 | |||
1506 | if (i >= EMIF_MAX_NUM_FREQUENCIES) { | ||
1507 | dev_warn(dev, "%s: regs_cache full - reusing a slot!!\n", | ||
1508 | __func__); | ||
1509 | i = EMIF_MAX_NUM_FREQUENCIES - 1; | ||
1510 | devm_kfree(emif->dev, regs_cache[i]); | ||
1511 | } | ||
1512 | regs_cache[i] = regs; | ||
1513 | } | ||
1514 | |||
1515 | return regs; | ||
1516 | } | ||
1517 | |||
1518 | static void do_volt_notify_handling(struct emif_data *emif, u32 volt_state) | ||
1519 | { | ||
1520 | dev_dbg(emif->dev, "%s: voltage notification : %d", __func__, | ||
1521 | volt_state); | ||
1522 | |||
1523 | if (!emif->curr_regs) { | ||
1524 | dev_err(emif->dev, | ||
1525 | "%s: volt-notify before registers are ready: %d\n", | ||
1526 | __func__, volt_state); | ||
1527 | return; | ||
1528 | } | ||
1529 | |||
1530 | setup_volt_sensitive_regs(emif, emif->curr_regs, volt_state); | ||
1531 | } | ||
1532 | |||
1533 | /* | ||
1534 | * TODO: voltage notify handling should be hooked up to | ||
1535 | * regulator framework as soon as the necessary support | ||
1536 | * is available in mainline kernel. This function is un-used | ||
1537 | * right now. | ||
1538 | */ | ||
1539 | static void __attribute__((unused)) volt_notify_handling(u32 volt_state) | ||
1540 | { | ||
1541 | struct emif_data *emif; | ||
1542 | |||
1543 | spin_lock_irqsave(&emif_lock, irq_state); | ||
1544 | |||
1545 | list_for_each_entry(emif, &device_list, node) | ||
1546 | do_volt_notify_handling(emif, volt_state); | ||
1547 | do_freq_update(); | ||
1548 | |||
1549 | spin_unlock_irqrestore(&emif_lock, irq_state); | ||
1550 | } | ||
1551 | |||
1552 | static void do_freq_pre_notify_handling(struct emif_data *emif, u32 new_freq) | ||
1553 | { | ||
1554 | struct emif_regs *regs; | ||
1555 | |||
1556 | regs = get_regs(emif, new_freq); | ||
1557 | if (!regs) | ||
1558 | return; | ||
1559 | |||
1560 | emif->curr_regs = regs; | ||
1561 | |||
1562 | /* | ||
1563 | * Update the shadow registers: | ||
1564 | * Temperature and voltage-ramp sensitive settings are also configured | ||
1565 | * in terms of DDR cycles. So, we need to update them too when there | ||
1566 | * is a freq change | ||
1567 | */ | ||
1568 | dev_dbg(emif->dev, "%s: setting up shadow registers for %uHz", | ||
1569 | __func__, new_freq); | ||
1570 | setup_registers(emif, regs); | ||
1571 | setup_temperature_sensitive_regs(emif, regs); | ||
1572 | setup_volt_sensitive_regs(emif, regs, DDR_VOLTAGE_STABLE); | ||
1573 | |||
1574 | /* | ||
1575 | * Part of workaround for errata i728. See do_freq_update() | ||
1576 | * for more details | ||
1577 | */ | ||
1578 | if (emif->lpmode == EMIF_LP_MODE_SELF_REFRESH) | ||
1579 | set_lpmode(emif, EMIF_LP_MODE_DISABLE); | ||
1580 | } | ||
1581 | |||
1582 | /* | ||
1583 | * TODO: frequency notify handling should be hooked up to | ||
1584 | * clock framework as soon as the necessary support is | ||
1585 | * available in mainline kernel. This function is un-used | ||
1586 | * right now. | ||
1587 | */ | ||
1588 | static void __attribute__((unused)) freq_pre_notify_handling(u32 new_freq) | ||
1589 | { | ||
1590 | struct emif_data *emif; | ||
1591 | |||
1592 | /* | ||
1593 | * NOTE: we are taking the spin-lock here and releases it | ||
1594 | * only in post-notifier. This doesn't look good and | ||
1595 | * Sparse complains about it, but this seems to be | ||
1596 | * un-avoidable. We need to lock a sequence of events | ||
1597 | * that is split between EMIF and clock framework. | ||
1598 | * | ||
1599 | * 1. EMIF driver updates EMIF timings in shadow registers in the | ||
1600 | * frequency pre-notify callback from clock framework | ||
1601 | * 2. clock framework sets up the registers for the new frequency | ||
1602 | * 3. clock framework initiates a hw-sequence that updates | ||
1603 | * the frequency EMIF timings synchronously. | ||
1604 | * | ||
1605 | * All these 3 steps should be performed as an atomic operation | ||
1606 | * vis-a-vis similar sequence in the EMIF interrupt handler | ||
1607 | * for temperature events. Otherwise, there could be race | ||
1608 | * conditions that could result in incorrect EMIF timings for | ||
1609 | * a given frequency | ||
1610 | */ | ||
1611 | spin_lock_irqsave(&emif_lock, irq_state); | ||
1612 | |||
1613 | list_for_each_entry(emif, &device_list, node) | ||
1614 | do_freq_pre_notify_handling(emif, new_freq); | ||
1615 | } | ||
1616 | |||
1617 | static void do_freq_post_notify_handling(struct emif_data *emif) | ||
1618 | { | ||
1619 | /* | ||
1620 | * Part of workaround for errata i728. See do_freq_update() | ||
1621 | * for more details | ||
1622 | */ | ||
1623 | if (emif->lpmode == EMIF_LP_MODE_SELF_REFRESH) | ||
1624 | set_lpmode(emif, EMIF_LP_MODE_SELF_REFRESH); | ||
1625 | } | ||
1626 | |||
1627 | /* | ||
1628 | * TODO: frequency notify handling should be hooked up to | ||
1629 | * clock framework as soon as the necessary support is | ||
1630 | * available in mainline kernel. This function is un-used | ||
1631 | * right now. | ||
1632 | */ | ||
1633 | static void __attribute__((unused)) freq_post_notify_handling(void) | ||
1634 | { | ||
1635 | struct emif_data *emif; | ||
1636 | |||
1637 | list_for_each_entry(emif, &device_list, node) | ||
1638 | do_freq_post_notify_handling(emif); | ||
1639 | |||
1640 | /* | ||
1641 | * Lock is done in pre-notify handler. See freq_pre_notify_handling() | ||
1642 | * for more details | ||
1643 | */ | ||
1644 | spin_unlock_irqrestore(&emif_lock, irq_state); | ||
1645 | } | ||
1646 | |||
1647 | static struct platform_driver emif_driver = { | ||
1648 | .remove = __exit_p(emif_remove), | ||
1649 | .shutdown = emif_shutdown, | ||
1650 | .driver = { | ||
1651 | .name = "emif", | ||
1652 | }, | ||
1653 | }; | ||
1654 | |||
1655 | static int __init_or_module emif_register(void) | ||
1656 | { | ||
1657 | return platform_driver_probe(&emif_driver, emif_probe); | ||
1658 | } | ||
1659 | |||
1660 | static void __exit emif_unregister(void) | ||
1661 | { | ||
1662 | platform_driver_unregister(&emif_driver); | ||
1663 | } | ||
1664 | |||
1665 | module_init(emif_register); | ||
1666 | module_exit(emif_unregister); | ||
1667 | MODULE_DESCRIPTION("TI EMIF SDRAM Controller Driver"); | ||
1668 | MODULE_LICENSE("GPL"); | ||
1669 | MODULE_ALIAS("platform:emif"); | ||
1670 | MODULE_AUTHOR("Texas Instruments Inc"); | ||
diff --git a/drivers/memory/emif.h b/drivers/memory/emif.h new file mode 100644 index 000000000000..bfe08bae961a --- /dev/null +++ b/drivers/memory/emif.h | |||
@@ -0,0 +1,589 @@ | |||
1 | /* | ||
2 | * Defines for the EMIF driver | ||
3 | * | ||
4 | * Copyright (C) 2012 Texas Instruments, Inc. | ||
5 | * | ||
6 | * Benoit Cousson (b-cousson@ti.com) | ||
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 __EMIF_H | ||
13 | #define __EMIF_H | ||
14 | |||
15 | /* | ||
16 | * Maximum number of different frequencies supported by EMIF driver | ||
17 | * Determines the number of entries in the pointer array for register | ||
18 | * cache | ||
19 | */ | ||
20 | #define EMIF_MAX_NUM_FREQUENCIES 6 | ||
21 | |||
22 | /* State of the core voltage */ | ||
23 | #define DDR_VOLTAGE_STABLE 0 | ||
24 | #define DDR_VOLTAGE_RAMPING 1 | ||
25 | |||
26 | /* Defines for timing De-rating */ | ||
27 | #define EMIF_NORMAL_TIMINGS 0 | ||
28 | #define EMIF_DERATED_TIMINGS 1 | ||
29 | |||
30 | /* Length of the forced read idle period in terms of cycles */ | ||
31 | #define EMIF_READ_IDLE_LEN_VAL 5 | ||
32 | |||
33 | /* | ||
34 | * forced read idle interval to be used when voltage | ||
35 | * is changed as part of DVFS/DPS - 1ms | ||
36 | */ | ||
37 | #define READ_IDLE_INTERVAL_DVFS (1*1000000) | ||
38 | |||
39 | /* | ||
40 | * Forced read idle interval to be used when voltage is stable | ||
41 | * 50us - or maximum value will do | ||
42 | */ | ||
43 | #define READ_IDLE_INTERVAL_NORMAL (50*1000000) | ||
44 | |||
45 | /* DLL calibration interval when voltage is NOT stable - 1us */ | ||
46 | #define DLL_CALIB_INTERVAL_DVFS (1*1000000) | ||
47 | |||
48 | #define DLL_CALIB_ACK_WAIT_VAL 5 | ||
49 | |||
50 | /* Interval between ZQCS commands - hw team recommended value */ | ||
51 | #define EMIF_ZQCS_INTERVAL_US (50*1000) | ||
52 | /* Enable ZQ Calibration on exiting Self-refresh */ | ||
53 | #define ZQ_SFEXITEN_ENABLE 1 | ||
54 | /* | ||
55 | * ZQ Calibration simultaneously on both chip-selects: | ||
56 | * Needs one calibration resistor per CS | ||
57 | */ | ||
58 | #define ZQ_DUALCALEN_DISABLE 0 | ||
59 | #define ZQ_DUALCALEN_ENABLE 1 | ||
60 | |||
61 | #define T_ZQCS_DEFAULT_NS 90 | ||
62 | #define T_ZQCL_DEFAULT_NS 360 | ||
63 | #define T_ZQINIT_DEFAULT_NS 1000 | ||
64 | |||
65 | /* DPD_EN */ | ||
66 | #define DPD_DISABLE 0 | ||
67 | #define DPD_ENABLE 1 | ||
68 | |||
69 | /* | ||
70 | * Default values for the low-power entry to be used if not provided by user. | ||
71 | * OMAP4/5 has a hw bug(i735) due to which this value can not be less than 512 | ||
72 | * Timeout values are in DDR clock 'cycles' and frequency threshold in Hz | ||
73 | */ | ||
74 | #define EMIF_LP_MODE_TIMEOUT_PERFORMANCE 2048 | ||
75 | #define EMIF_LP_MODE_TIMEOUT_POWER 512 | ||
76 | #define EMIF_LP_MODE_FREQ_THRESHOLD 400000000 | ||
77 | |||
78 | /* DDR_PHY_CTRL_1 values for EMIF4D - ATTILA PHY combination */ | ||
79 | #define EMIF_DDR_PHY_CTRL_1_BASE_VAL_ATTILAPHY 0x049FF000 | ||
80 | #define EMIF_DLL_SLAVE_DLY_CTRL_400_MHZ_ATTILAPHY 0x41 | ||
81 | #define EMIF_DLL_SLAVE_DLY_CTRL_200_MHZ_ATTILAPHY 0x80 | ||
82 | #define EMIF_DLL_SLAVE_DLY_CTRL_100_MHZ_AND_LESS_ATTILAPHY 0xFF | ||
83 | |||
84 | /* DDR_PHY_CTRL_1 values for EMIF4D5 INTELLIPHY combination */ | ||
85 | #define EMIF_DDR_PHY_CTRL_1_BASE_VAL_INTELLIPHY 0x0E084200 | ||
86 | #define EMIF_PHY_TOTAL_READ_LATENCY_INTELLIPHY_PS 10000 | ||
87 | |||
88 | /* TEMP_ALERT_CONFIG - corresponding to temp gradient 5 C/s */ | ||
89 | #define TEMP_ALERT_POLL_INTERVAL_DEFAULT_MS 360 | ||
90 | |||
91 | #define EMIF_T_CSTA 3 | ||
92 | #define EMIF_T_PDLL_UL 128 | ||
93 | |||
94 | /* External PHY control registers magic values */ | ||
95 | #define EMIF_EXT_PHY_CTRL_1_VAL 0x04020080 | ||
96 | #define EMIF_EXT_PHY_CTRL_5_VAL 0x04010040 | ||
97 | #define EMIF_EXT_PHY_CTRL_6_VAL 0x01004010 | ||
98 | #define EMIF_EXT_PHY_CTRL_7_VAL 0x00001004 | ||
99 | #define EMIF_EXT_PHY_CTRL_8_VAL 0x04010040 | ||
100 | #define EMIF_EXT_PHY_CTRL_9_VAL 0x01004010 | ||
101 | #define EMIF_EXT_PHY_CTRL_10_VAL 0x00001004 | ||
102 | #define EMIF_EXT_PHY_CTRL_11_VAL 0x00000000 | ||
103 | #define EMIF_EXT_PHY_CTRL_12_VAL 0x00000000 | ||
104 | #define EMIF_EXT_PHY_CTRL_13_VAL 0x00000000 | ||
105 | #define EMIF_EXT_PHY_CTRL_14_VAL 0x80080080 | ||
106 | #define EMIF_EXT_PHY_CTRL_15_VAL 0x00800800 | ||
107 | #define EMIF_EXT_PHY_CTRL_16_VAL 0x08102040 | ||
108 | #define EMIF_EXT_PHY_CTRL_17_VAL 0x00000001 | ||
109 | #define EMIF_EXT_PHY_CTRL_18_VAL 0x540A8150 | ||
110 | #define EMIF_EXT_PHY_CTRL_19_VAL 0xA81502A0 | ||
111 | #define EMIF_EXT_PHY_CTRL_20_VAL 0x002A0540 | ||
112 | #define EMIF_EXT_PHY_CTRL_21_VAL 0x00000000 | ||
113 | #define EMIF_EXT_PHY_CTRL_22_VAL 0x00000000 | ||
114 | #define EMIF_EXT_PHY_CTRL_23_VAL 0x00000000 | ||
115 | #define EMIF_EXT_PHY_CTRL_24_VAL 0x00000077 | ||
116 | |||
117 | #define EMIF_INTELLI_PHY_DQS_GATE_OPENING_DELAY_PS 1200 | ||
118 | |||
119 | /* Registers offset */ | ||
120 | #define EMIF_MODULE_ID_AND_REVISION 0x0000 | ||
121 | #define EMIF_STATUS 0x0004 | ||
122 | #define EMIF_SDRAM_CONFIG 0x0008 | ||
123 | #define EMIF_SDRAM_CONFIG_2 0x000c | ||
124 | #define EMIF_SDRAM_REFRESH_CONTROL 0x0010 | ||
125 | #define EMIF_SDRAM_REFRESH_CTRL_SHDW 0x0014 | ||
126 | #define EMIF_SDRAM_TIMING_1 0x0018 | ||
127 | #define EMIF_SDRAM_TIMING_1_SHDW 0x001c | ||
128 | #define EMIF_SDRAM_TIMING_2 0x0020 | ||
129 | #define EMIF_SDRAM_TIMING_2_SHDW 0x0024 | ||
130 | #define EMIF_SDRAM_TIMING_3 0x0028 | ||
131 | #define EMIF_SDRAM_TIMING_3_SHDW 0x002c | ||
132 | #define EMIF_LPDDR2_NVM_TIMING 0x0030 | ||
133 | #define EMIF_LPDDR2_NVM_TIMING_SHDW 0x0034 | ||
134 | #define EMIF_POWER_MANAGEMENT_CONTROL 0x0038 | ||
135 | #define EMIF_POWER_MANAGEMENT_CTRL_SHDW 0x003c | ||
136 | #define EMIF_LPDDR2_MODE_REG_DATA 0x0040 | ||
137 | #define EMIF_LPDDR2_MODE_REG_CONFIG 0x0050 | ||
138 | #define EMIF_OCP_CONFIG 0x0054 | ||
139 | #define EMIF_OCP_CONFIG_VALUE_1 0x0058 | ||
140 | #define EMIF_OCP_CONFIG_VALUE_2 0x005c | ||
141 | #define EMIF_IODFT_TEST_LOGIC_GLOBAL_CONTROL 0x0060 | ||
142 | #define EMIF_IODFT_TEST_LOGIC_CTRL_MISR_RESULT 0x0064 | ||
143 | #define EMIF_IODFT_TEST_LOGIC_ADDRESS_MISR_RESULT 0x0068 | ||
144 | #define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_1 0x006c | ||
145 | #define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_2 0x0070 | ||
146 | #define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_3 0x0074 | ||
147 | #define EMIF_PERFORMANCE_COUNTER_1 0x0080 | ||
148 | #define EMIF_PERFORMANCE_COUNTER_2 0x0084 | ||
149 | #define EMIF_PERFORMANCE_COUNTER_CONFIG 0x0088 | ||
150 | #define EMIF_PERFORMANCE_COUNTER_MASTER_REGION_SELECT 0x008c | ||
151 | #define EMIF_PERFORMANCE_COUNTER_TIME 0x0090 | ||
152 | #define EMIF_MISC_REG 0x0094 | ||
153 | #define EMIF_DLL_CALIB_CTRL 0x0098 | ||
154 | #define EMIF_DLL_CALIB_CTRL_SHDW 0x009c | ||
155 | #define EMIF_END_OF_INTERRUPT 0x00a0 | ||
156 | #define EMIF_SYSTEM_OCP_INTERRUPT_RAW_STATUS 0x00a4 | ||
157 | #define EMIF_LL_OCP_INTERRUPT_RAW_STATUS 0x00a8 | ||
158 | #define EMIF_SYSTEM_OCP_INTERRUPT_STATUS 0x00ac | ||
159 | #define EMIF_LL_OCP_INTERRUPT_STATUS 0x00b0 | ||
160 | #define EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_SET 0x00b4 | ||
161 | #define EMIF_LL_OCP_INTERRUPT_ENABLE_SET 0x00b8 | ||
162 | #define EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_CLEAR 0x00bc | ||
163 | #define EMIF_LL_OCP_INTERRUPT_ENABLE_CLEAR 0x00c0 | ||
164 | #define EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG 0x00c8 | ||
165 | #define EMIF_TEMPERATURE_ALERT_CONFIG 0x00cc | ||
166 | #define EMIF_OCP_ERROR_LOG 0x00d0 | ||
167 | #define EMIF_READ_WRITE_LEVELING_RAMP_WINDOW 0x00d4 | ||
168 | #define EMIF_READ_WRITE_LEVELING_RAMP_CONTROL 0x00d8 | ||
169 | #define EMIF_READ_WRITE_LEVELING_CONTROL 0x00dc | ||
170 | #define EMIF_DDR_PHY_CTRL_1 0x00e4 | ||
171 | #define EMIF_DDR_PHY_CTRL_1_SHDW 0x00e8 | ||
172 | #define EMIF_DDR_PHY_CTRL_2 0x00ec | ||
173 | #define EMIF_PRIORITY_TO_CLASS_OF_SERVICE_MAPPING 0x0100 | ||
174 | #define EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_1_MAPPING 0x0104 | ||
175 | #define EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_2_MAPPING 0x0108 | ||
176 | #define EMIF_READ_WRITE_EXECUTION_THRESHOLD 0x0120 | ||
177 | #define EMIF_COS_CONFIG 0x0124 | ||
178 | #define EMIF_PHY_STATUS_1 0x0140 | ||
179 | #define EMIF_PHY_STATUS_2 0x0144 | ||
180 | #define EMIF_PHY_STATUS_3 0x0148 | ||
181 | #define EMIF_PHY_STATUS_4 0x014c | ||
182 | #define EMIF_PHY_STATUS_5 0x0150 | ||
183 | #define EMIF_PHY_STATUS_6 0x0154 | ||
184 | #define EMIF_PHY_STATUS_7 0x0158 | ||
185 | #define EMIF_PHY_STATUS_8 0x015c | ||
186 | #define EMIF_PHY_STATUS_9 0x0160 | ||
187 | #define EMIF_PHY_STATUS_10 0x0164 | ||
188 | #define EMIF_PHY_STATUS_11 0x0168 | ||
189 | #define EMIF_PHY_STATUS_12 0x016c | ||
190 | #define EMIF_PHY_STATUS_13 0x0170 | ||
191 | #define EMIF_PHY_STATUS_14 0x0174 | ||
192 | #define EMIF_PHY_STATUS_15 0x0178 | ||
193 | #define EMIF_PHY_STATUS_16 0x017c | ||
194 | #define EMIF_PHY_STATUS_17 0x0180 | ||
195 | #define EMIF_PHY_STATUS_18 0x0184 | ||
196 | #define EMIF_PHY_STATUS_19 0x0188 | ||
197 | #define EMIF_PHY_STATUS_20 0x018c | ||
198 | #define EMIF_PHY_STATUS_21 0x0190 | ||
199 | #define EMIF_EXT_PHY_CTRL_1 0x0200 | ||
200 | #define EMIF_EXT_PHY_CTRL_1_SHDW 0x0204 | ||
201 | #define EMIF_EXT_PHY_CTRL_2 0x0208 | ||
202 | #define EMIF_EXT_PHY_CTRL_2_SHDW 0x020c | ||
203 | #define EMIF_EXT_PHY_CTRL_3 0x0210 | ||
204 | #define EMIF_EXT_PHY_CTRL_3_SHDW 0x0214 | ||
205 | #define EMIF_EXT_PHY_CTRL_4 0x0218 | ||
206 | #define EMIF_EXT_PHY_CTRL_4_SHDW 0x021c | ||
207 | #define EMIF_EXT_PHY_CTRL_5 0x0220 | ||
208 | #define EMIF_EXT_PHY_CTRL_5_SHDW 0x0224 | ||
209 | #define EMIF_EXT_PHY_CTRL_6 0x0228 | ||
210 | #define EMIF_EXT_PHY_CTRL_6_SHDW 0x022c | ||
211 | #define EMIF_EXT_PHY_CTRL_7 0x0230 | ||
212 | #define EMIF_EXT_PHY_CTRL_7_SHDW 0x0234 | ||
213 | #define EMIF_EXT_PHY_CTRL_8 0x0238 | ||
214 | #define EMIF_EXT_PHY_CTRL_8_SHDW 0x023c | ||
215 | #define EMIF_EXT_PHY_CTRL_9 0x0240 | ||
216 | #define EMIF_EXT_PHY_CTRL_9_SHDW 0x0244 | ||
217 | #define EMIF_EXT_PHY_CTRL_10 0x0248 | ||
218 | #define EMIF_EXT_PHY_CTRL_10_SHDW 0x024c | ||
219 | #define EMIF_EXT_PHY_CTRL_11 0x0250 | ||
220 | #define EMIF_EXT_PHY_CTRL_11_SHDW 0x0254 | ||
221 | #define EMIF_EXT_PHY_CTRL_12 0x0258 | ||
222 | #define EMIF_EXT_PHY_CTRL_12_SHDW 0x025c | ||
223 | #define EMIF_EXT_PHY_CTRL_13 0x0260 | ||
224 | #define EMIF_EXT_PHY_CTRL_13_SHDW 0x0264 | ||
225 | #define EMIF_EXT_PHY_CTRL_14 0x0268 | ||
226 | #define EMIF_EXT_PHY_CTRL_14_SHDW 0x026c | ||
227 | #define EMIF_EXT_PHY_CTRL_15 0x0270 | ||
228 | #define EMIF_EXT_PHY_CTRL_15_SHDW 0x0274 | ||
229 | #define EMIF_EXT_PHY_CTRL_16 0x0278 | ||
230 | #define EMIF_EXT_PHY_CTRL_16_SHDW 0x027c | ||
231 | #define EMIF_EXT_PHY_CTRL_17 0x0280 | ||
232 | #define EMIF_EXT_PHY_CTRL_17_SHDW 0x0284 | ||
233 | #define EMIF_EXT_PHY_CTRL_18 0x0288 | ||
234 | #define EMIF_EXT_PHY_CTRL_18_SHDW 0x028c | ||
235 | #define EMIF_EXT_PHY_CTRL_19 0x0290 | ||
236 | #define EMIF_EXT_PHY_CTRL_19_SHDW 0x0294 | ||
237 | #define EMIF_EXT_PHY_CTRL_20 0x0298 | ||
238 | #define EMIF_EXT_PHY_CTRL_20_SHDW 0x029c | ||
239 | #define EMIF_EXT_PHY_CTRL_21 0x02a0 | ||
240 | #define EMIF_EXT_PHY_CTRL_21_SHDW 0x02a4 | ||
241 | #define EMIF_EXT_PHY_CTRL_22 0x02a8 | ||
242 | #define EMIF_EXT_PHY_CTRL_22_SHDW 0x02ac | ||
243 | #define EMIF_EXT_PHY_CTRL_23 0x02b0 | ||
244 | #define EMIF_EXT_PHY_CTRL_23_SHDW 0x02b4 | ||
245 | #define EMIF_EXT_PHY_CTRL_24 0x02b8 | ||
246 | #define EMIF_EXT_PHY_CTRL_24_SHDW 0x02bc | ||
247 | #define EMIF_EXT_PHY_CTRL_25 0x02c0 | ||
248 | #define EMIF_EXT_PHY_CTRL_25_SHDW 0x02c4 | ||
249 | #define EMIF_EXT_PHY_CTRL_26 0x02c8 | ||
250 | #define EMIF_EXT_PHY_CTRL_26_SHDW 0x02cc | ||
251 | #define EMIF_EXT_PHY_CTRL_27 0x02d0 | ||
252 | #define EMIF_EXT_PHY_CTRL_27_SHDW 0x02d4 | ||
253 | #define EMIF_EXT_PHY_CTRL_28 0x02d8 | ||
254 | #define EMIF_EXT_PHY_CTRL_28_SHDW 0x02dc | ||
255 | #define EMIF_EXT_PHY_CTRL_29 0x02e0 | ||
256 | #define EMIF_EXT_PHY_CTRL_29_SHDW 0x02e4 | ||
257 | #define EMIF_EXT_PHY_CTRL_30 0x02e8 | ||
258 | #define EMIF_EXT_PHY_CTRL_30_SHDW 0x02ec | ||
259 | |||
260 | /* Registers shifts and masks */ | ||
261 | |||
262 | /* EMIF_MODULE_ID_AND_REVISION */ | ||
263 | #define SCHEME_SHIFT 30 | ||
264 | #define SCHEME_MASK (0x3 << 30) | ||
265 | #define MODULE_ID_SHIFT 16 | ||
266 | #define MODULE_ID_MASK (0xfff << 16) | ||
267 | #define RTL_VERSION_SHIFT 11 | ||
268 | #define RTL_VERSION_MASK (0x1f << 11) | ||
269 | #define MAJOR_REVISION_SHIFT 8 | ||
270 | #define MAJOR_REVISION_MASK (0x7 << 8) | ||
271 | #define MINOR_REVISION_SHIFT 0 | ||
272 | #define MINOR_REVISION_MASK (0x3f << 0) | ||
273 | |||
274 | /* STATUS */ | ||
275 | #define BE_SHIFT 31 | ||
276 | #define BE_MASK (1 << 31) | ||
277 | #define DUAL_CLK_MODE_SHIFT 30 | ||
278 | #define DUAL_CLK_MODE_MASK (1 << 30) | ||
279 | #define FAST_INIT_SHIFT 29 | ||
280 | #define FAST_INIT_MASK (1 << 29) | ||
281 | #define RDLVLGATETO_SHIFT 6 | ||
282 | #define RDLVLGATETO_MASK (1 << 6) | ||
283 | #define RDLVLTO_SHIFT 5 | ||
284 | #define RDLVLTO_MASK (1 << 5) | ||
285 | #define WRLVLTO_SHIFT 4 | ||
286 | #define WRLVLTO_MASK (1 << 4) | ||
287 | #define PHY_DLL_READY_SHIFT 2 | ||
288 | #define PHY_DLL_READY_MASK (1 << 2) | ||
289 | |||
290 | /* SDRAM_CONFIG */ | ||
291 | #define SDRAM_TYPE_SHIFT 29 | ||
292 | #define SDRAM_TYPE_MASK (0x7 << 29) | ||
293 | #define IBANK_POS_SHIFT 27 | ||
294 | #define IBANK_POS_MASK (0x3 << 27) | ||
295 | #define DDR_TERM_SHIFT 24 | ||
296 | #define DDR_TERM_MASK (0x7 << 24) | ||
297 | #define DDR2_DDQS_SHIFT 23 | ||
298 | #define DDR2_DDQS_MASK (1 << 23) | ||
299 | #define DYN_ODT_SHIFT 21 | ||
300 | #define DYN_ODT_MASK (0x3 << 21) | ||
301 | #define DDR_DISABLE_DLL_SHIFT 20 | ||
302 | #define DDR_DISABLE_DLL_MASK (1 << 20) | ||
303 | #define SDRAM_DRIVE_SHIFT 18 | ||
304 | #define SDRAM_DRIVE_MASK (0x3 << 18) | ||
305 | #define CWL_SHIFT 16 | ||
306 | #define CWL_MASK (0x3 << 16) | ||
307 | #define NARROW_MODE_SHIFT 14 | ||
308 | #define NARROW_MODE_MASK (0x3 << 14) | ||
309 | #define CL_SHIFT 10 | ||
310 | #define CL_MASK (0xf << 10) | ||
311 | #define ROWSIZE_SHIFT 7 | ||
312 | #define ROWSIZE_MASK (0x7 << 7) | ||
313 | #define IBANK_SHIFT 4 | ||
314 | #define IBANK_MASK (0x7 << 4) | ||
315 | #define EBANK_SHIFT 3 | ||
316 | #define EBANK_MASK (1 << 3) | ||
317 | #define PAGESIZE_SHIFT 0 | ||
318 | #define PAGESIZE_MASK (0x7 << 0) | ||
319 | |||
320 | /* SDRAM_CONFIG_2 */ | ||
321 | #define CS1NVMEN_SHIFT 30 | ||
322 | #define CS1NVMEN_MASK (1 << 30) | ||
323 | #define EBANK_POS_SHIFT 27 | ||
324 | #define EBANK_POS_MASK (1 << 27) | ||
325 | #define RDBNUM_SHIFT 4 | ||
326 | #define RDBNUM_MASK (0x3 << 4) | ||
327 | #define RDBSIZE_SHIFT 0 | ||
328 | #define RDBSIZE_MASK (0x7 << 0) | ||
329 | |||
330 | /* SDRAM_REFRESH_CONTROL */ | ||
331 | #define INITREF_DIS_SHIFT 31 | ||
332 | #define INITREF_DIS_MASK (1 << 31) | ||
333 | #define SRT_SHIFT 29 | ||
334 | #define SRT_MASK (1 << 29) | ||
335 | #define ASR_SHIFT 28 | ||
336 | #define ASR_MASK (1 << 28) | ||
337 | #define PASR_SHIFT 24 | ||
338 | #define PASR_MASK (0x7 << 24) | ||
339 | #define REFRESH_RATE_SHIFT 0 | ||
340 | #define REFRESH_RATE_MASK (0xffff << 0) | ||
341 | |||
342 | /* SDRAM_TIMING_1 */ | ||
343 | #define T_RTW_SHIFT 29 | ||
344 | #define T_RTW_MASK (0x7 << 29) | ||
345 | #define T_RP_SHIFT 25 | ||
346 | #define T_RP_MASK (0xf << 25) | ||
347 | #define T_RCD_SHIFT 21 | ||
348 | #define T_RCD_MASK (0xf << 21) | ||
349 | #define T_WR_SHIFT 17 | ||
350 | #define T_WR_MASK (0xf << 17) | ||
351 | #define T_RAS_SHIFT 12 | ||
352 | #define T_RAS_MASK (0x1f << 12) | ||
353 | #define T_RC_SHIFT 6 | ||
354 | #define T_RC_MASK (0x3f << 6) | ||
355 | #define T_RRD_SHIFT 3 | ||
356 | #define T_RRD_MASK (0x7 << 3) | ||
357 | #define T_WTR_SHIFT 0 | ||
358 | #define T_WTR_MASK (0x7 << 0) | ||
359 | |||
360 | /* SDRAM_TIMING_2 */ | ||
361 | #define T_XP_SHIFT 28 | ||
362 | #define T_XP_MASK (0x7 << 28) | ||
363 | #define T_ODT_SHIFT 25 | ||
364 | #define T_ODT_MASK (0x7 << 25) | ||
365 | #define T_XSNR_SHIFT 16 | ||
366 | #define T_XSNR_MASK (0x1ff << 16) | ||
367 | #define T_XSRD_SHIFT 6 | ||
368 | #define T_XSRD_MASK (0x3ff << 6) | ||
369 | #define T_RTP_SHIFT 3 | ||
370 | #define T_RTP_MASK (0x7 << 3) | ||
371 | #define T_CKE_SHIFT 0 | ||
372 | #define T_CKE_MASK (0x7 << 0) | ||
373 | |||
374 | /* SDRAM_TIMING_3 */ | ||
375 | #define T_PDLL_UL_SHIFT 28 | ||
376 | #define T_PDLL_UL_MASK (0xf << 28) | ||
377 | #define T_CSTA_SHIFT 24 | ||
378 | #define T_CSTA_MASK (0xf << 24) | ||
379 | #define T_CKESR_SHIFT 21 | ||
380 | #define T_CKESR_MASK (0x7 << 21) | ||
381 | #define ZQ_ZQCS_SHIFT 15 | ||
382 | #define ZQ_ZQCS_MASK (0x3f << 15) | ||
383 | #define T_TDQSCKMAX_SHIFT 13 | ||
384 | #define T_TDQSCKMAX_MASK (0x3 << 13) | ||
385 | #define T_RFC_SHIFT 4 | ||
386 | #define T_RFC_MASK (0x1ff << 4) | ||
387 | #define T_RAS_MAX_SHIFT 0 | ||
388 | #define T_RAS_MAX_MASK (0xf << 0) | ||
389 | |||
390 | /* POWER_MANAGEMENT_CONTROL */ | ||
391 | #define PD_TIM_SHIFT 12 | ||
392 | #define PD_TIM_MASK (0xf << 12) | ||
393 | #define DPD_EN_SHIFT 11 | ||
394 | #define DPD_EN_MASK (1 << 11) | ||
395 | #define LP_MODE_SHIFT 8 | ||
396 | #define LP_MODE_MASK (0x7 << 8) | ||
397 | #define SR_TIM_SHIFT 4 | ||
398 | #define SR_TIM_MASK (0xf << 4) | ||
399 | #define CS_TIM_SHIFT 0 | ||
400 | #define CS_TIM_MASK (0xf << 0) | ||
401 | |||
402 | /* LPDDR2_MODE_REG_DATA */ | ||
403 | #define VALUE_0_SHIFT 0 | ||
404 | #define VALUE_0_MASK (0x7f << 0) | ||
405 | |||
406 | /* LPDDR2_MODE_REG_CONFIG */ | ||
407 | #define CS_SHIFT 31 | ||
408 | #define CS_MASK (1 << 31) | ||
409 | #define REFRESH_EN_SHIFT 30 | ||
410 | #define REFRESH_EN_MASK (1 << 30) | ||
411 | #define ADDRESS_SHIFT 0 | ||
412 | #define ADDRESS_MASK (0xff << 0) | ||
413 | |||
414 | /* OCP_CONFIG */ | ||
415 | #define SYS_THRESH_MAX_SHIFT 24 | ||
416 | #define SYS_THRESH_MAX_MASK (0xf << 24) | ||
417 | #define MPU_THRESH_MAX_SHIFT 20 | ||
418 | #define MPU_THRESH_MAX_MASK (0xf << 20) | ||
419 | #define LL_THRESH_MAX_SHIFT 16 | ||
420 | #define LL_THRESH_MAX_MASK (0xf << 16) | ||
421 | |||
422 | /* PERFORMANCE_COUNTER_1 */ | ||
423 | #define COUNTER1_SHIFT 0 | ||
424 | #define COUNTER1_MASK (0xffffffff << 0) | ||
425 | |||
426 | /* PERFORMANCE_COUNTER_2 */ | ||
427 | #define COUNTER2_SHIFT 0 | ||
428 | #define COUNTER2_MASK (0xffffffff << 0) | ||
429 | |||
430 | /* PERFORMANCE_COUNTER_CONFIG */ | ||
431 | #define CNTR2_MCONNID_EN_SHIFT 31 | ||
432 | #define CNTR2_MCONNID_EN_MASK (1 << 31) | ||
433 | #define CNTR2_REGION_EN_SHIFT 30 | ||
434 | #define CNTR2_REGION_EN_MASK (1 << 30) | ||
435 | #define CNTR2_CFG_SHIFT 16 | ||
436 | #define CNTR2_CFG_MASK (0xf << 16) | ||
437 | #define CNTR1_MCONNID_EN_SHIFT 15 | ||
438 | #define CNTR1_MCONNID_EN_MASK (1 << 15) | ||
439 | #define CNTR1_REGION_EN_SHIFT 14 | ||
440 | #define CNTR1_REGION_EN_MASK (1 << 14) | ||
441 | #define CNTR1_CFG_SHIFT 0 | ||
442 | #define CNTR1_CFG_MASK (0xf << 0) | ||
443 | |||
444 | /* PERFORMANCE_COUNTER_MASTER_REGION_SELECT */ | ||
445 | #define MCONNID2_SHIFT 24 | ||
446 | #define MCONNID2_MASK (0xff << 24) | ||
447 | #define REGION_SEL2_SHIFT 16 | ||
448 | #define REGION_SEL2_MASK (0x3 << 16) | ||
449 | #define MCONNID1_SHIFT 8 | ||
450 | #define MCONNID1_MASK (0xff << 8) | ||
451 | #define REGION_SEL1_SHIFT 0 | ||
452 | #define REGION_SEL1_MASK (0x3 << 0) | ||
453 | |||
454 | /* PERFORMANCE_COUNTER_TIME */ | ||
455 | #define TOTAL_TIME_SHIFT 0 | ||
456 | #define TOTAL_TIME_MASK (0xffffffff << 0) | ||
457 | |||
458 | /* DLL_CALIB_CTRL */ | ||
459 | #define ACK_WAIT_SHIFT 16 | ||
460 | #define ACK_WAIT_MASK (0xf << 16) | ||
461 | #define DLL_CALIB_INTERVAL_SHIFT 0 | ||
462 | #define DLL_CALIB_INTERVAL_MASK (0x1ff << 0) | ||
463 | |||
464 | /* END_OF_INTERRUPT */ | ||
465 | #define EOI_SHIFT 0 | ||
466 | #define EOI_MASK (1 << 0) | ||
467 | |||
468 | /* SYSTEM_OCP_INTERRUPT_RAW_STATUS */ | ||
469 | #define DNV_SYS_SHIFT 2 | ||
470 | #define DNV_SYS_MASK (1 << 2) | ||
471 | #define TA_SYS_SHIFT 1 | ||
472 | #define TA_SYS_MASK (1 << 1) | ||
473 | #define ERR_SYS_SHIFT 0 | ||
474 | #define ERR_SYS_MASK (1 << 0) | ||
475 | |||
476 | /* LOW_LATENCY_OCP_INTERRUPT_RAW_STATUS */ | ||
477 | #define DNV_LL_SHIFT 2 | ||
478 | #define DNV_LL_MASK (1 << 2) | ||
479 | #define TA_LL_SHIFT 1 | ||
480 | #define TA_LL_MASK (1 << 1) | ||
481 | #define ERR_LL_SHIFT 0 | ||
482 | #define ERR_LL_MASK (1 << 0) | ||
483 | |||
484 | /* SYSTEM_OCP_INTERRUPT_ENABLE_SET */ | ||
485 | #define EN_DNV_SYS_SHIFT 2 | ||
486 | #define EN_DNV_SYS_MASK (1 << 2) | ||
487 | #define EN_TA_SYS_SHIFT 1 | ||
488 | #define EN_TA_SYS_MASK (1 << 1) | ||
489 | #define EN_ERR_SYS_SHIFT 0 | ||
490 | #define EN_ERR_SYS_MASK (1 << 0) | ||
491 | |||
492 | /* LOW_LATENCY_OCP_INTERRUPT_ENABLE_SET */ | ||
493 | #define EN_DNV_LL_SHIFT 2 | ||
494 | #define EN_DNV_LL_MASK (1 << 2) | ||
495 | #define EN_TA_LL_SHIFT 1 | ||
496 | #define EN_TA_LL_MASK (1 << 1) | ||
497 | #define EN_ERR_LL_SHIFT 0 | ||
498 | #define EN_ERR_LL_MASK (1 << 0) | ||
499 | |||
500 | /* SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG */ | ||
501 | #define ZQ_CS1EN_SHIFT 31 | ||
502 | #define ZQ_CS1EN_MASK (1 << 31) | ||
503 | #define ZQ_CS0EN_SHIFT 30 | ||
504 | #define ZQ_CS0EN_MASK (1 << 30) | ||
505 | #define ZQ_DUALCALEN_SHIFT 29 | ||
506 | #define ZQ_DUALCALEN_MASK (1 << 29) | ||
507 | #define ZQ_SFEXITEN_SHIFT 28 | ||
508 | #define ZQ_SFEXITEN_MASK (1 << 28) | ||
509 | #define ZQ_ZQINIT_MULT_SHIFT 18 | ||
510 | #define ZQ_ZQINIT_MULT_MASK (0x3 << 18) | ||
511 | #define ZQ_ZQCL_MULT_SHIFT 16 | ||
512 | #define ZQ_ZQCL_MULT_MASK (0x3 << 16) | ||
513 | #define ZQ_REFINTERVAL_SHIFT 0 | ||
514 | #define ZQ_REFINTERVAL_MASK (0xffff << 0) | ||
515 | |||
516 | /* TEMPERATURE_ALERT_CONFIG */ | ||
517 | #define TA_CS1EN_SHIFT 31 | ||
518 | #define TA_CS1EN_MASK (1 << 31) | ||
519 | #define TA_CS0EN_SHIFT 30 | ||
520 | #define TA_CS0EN_MASK (1 << 30) | ||
521 | #define TA_SFEXITEN_SHIFT 28 | ||
522 | #define TA_SFEXITEN_MASK (1 << 28) | ||
523 | #define TA_DEVWDT_SHIFT 26 | ||
524 | #define TA_DEVWDT_MASK (0x3 << 26) | ||
525 | #define TA_DEVCNT_SHIFT 24 | ||
526 | #define TA_DEVCNT_MASK (0x3 << 24) | ||
527 | #define TA_REFINTERVAL_SHIFT 0 | ||
528 | #define TA_REFINTERVAL_MASK (0x3fffff << 0) | ||
529 | |||
530 | /* OCP_ERROR_LOG */ | ||
531 | #define MADDRSPACE_SHIFT 14 | ||
532 | #define MADDRSPACE_MASK (0x3 << 14) | ||
533 | #define MBURSTSEQ_SHIFT 11 | ||
534 | #define MBURSTSEQ_MASK (0x7 << 11) | ||
535 | #define MCMD_SHIFT 8 | ||
536 | #define MCMD_MASK (0x7 << 8) | ||
537 | #define MCONNID_SHIFT 0 | ||
538 | #define MCONNID_MASK (0xff << 0) | ||
539 | |||
540 | /* DDR_PHY_CTRL_1 - EMIF4D */ | ||
541 | #define DLL_SLAVE_DLY_CTRL_SHIFT_4D 4 | ||
542 | #define DLL_SLAVE_DLY_CTRL_MASK_4D (0xFF << 4) | ||
543 | #define READ_LATENCY_SHIFT_4D 0 | ||
544 | #define READ_LATENCY_MASK_4D (0xf << 0) | ||
545 | |||
546 | /* DDR_PHY_CTRL_1 - EMIF4D5 */ | ||
547 | #define DLL_HALF_DELAY_SHIFT_4D5 21 | ||
548 | #define DLL_HALF_DELAY_MASK_4D5 (1 << 21) | ||
549 | #define READ_LATENCY_SHIFT_4D5 0 | ||
550 | #define READ_LATENCY_MASK_4D5 (0x1f << 0) | ||
551 | |||
552 | /* DDR_PHY_CTRL_1_SHDW */ | ||
553 | #define DDR_PHY_CTRL_1_SHDW_SHIFT 5 | ||
554 | #define DDR_PHY_CTRL_1_SHDW_MASK (0x7ffffff << 5) | ||
555 | #define READ_LATENCY_SHDW_SHIFT 0 | ||
556 | #define READ_LATENCY_SHDW_MASK (0x1f << 0) | ||
557 | |||
558 | #ifndef __ASSEMBLY__ | ||
559 | /* | ||
560 | * Structure containing shadow of important registers in EMIF | ||
561 | * The calculation function fills in this structure to be later used for | ||
562 | * initialisation and DVFS | ||
563 | */ | ||
564 | struct emif_regs { | ||
565 | u32 freq; | ||
566 | u32 ref_ctrl_shdw; | ||
567 | u32 ref_ctrl_shdw_derated; | ||
568 | u32 sdram_tim1_shdw; | ||
569 | u32 sdram_tim1_shdw_derated; | ||
570 | u32 sdram_tim2_shdw; | ||
571 | u32 sdram_tim3_shdw; | ||
572 | u32 sdram_tim3_shdw_derated; | ||
573 | u32 pwr_mgmt_ctrl_shdw; | ||
574 | union { | ||
575 | u32 read_idle_ctrl_shdw_normal; | ||
576 | u32 dll_calib_ctrl_shdw_normal; | ||
577 | }; | ||
578 | union { | ||
579 | u32 read_idle_ctrl_shdw_volt_ramp; | ||
580 | u32 dll_calib_ctrl_shdw_volt_ramp; | ||
581 | }; | ||
582 | |||
583 | u32 phy_ctrl_1_shdw; | ||
584 | u32 ext_phy_ctrl_2_shdw; | ||
585 | u32 ext_phy_ctrl_3_shdw; | ||
586 | u32 ext_phy_ctrl_4_shdw; | ||
587 | }; | ||
588 | #endif /* __ASSEMBLY__ */ | ||
589 | #endif /* __EMIF_H */ | ||
diff --git a/drivers/memory/tegra20-mc.c b/drivers/memory/tegra20-mc.c new file mode 100644 index 000000000000..3ed49c1c2b91 --- /dev/null +++ b/drivers/memory/tegra20-mc.c | |||
@@ -0,0 +1,257 @@ | |||
1 | /* | ||
2 | * Tegra20 Memory Controller | ||
3 | * | ||
4 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along with | ||
16 | * this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/ratelimit.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/io.h> | ||
26 | |||
27 | #define DRV_NAME "tegra20-mc" | ||
28 | |||
29 | #define MC_INTSTATUS 0x0 | ||
30 | #define MC_INTMASK 0x4 | ||
31 | |||
32 | #define MC_INT_ERR_SHIFT 6 | ||
33 | #define MC_INT_ERR_MASK (0x1f << MC_INT_ERR_SHIFT) | ||
34 | #define MC_INT_DECERR_EMEM BIT(MC_INT_ERR_SHIFT) | ||
35 | #define MC_INT_INVALID_GART_PAGE BIT(MC_INT_ERR_SHIFT + 1) | ||
36 | #define MC_INT_SECURITY_VIOLATION BIT(MC_INT_ERR_SHIFT + 2) | ||
37 | #define MC_INT_ARBITRATION_EMEM BIT(MC_INT_ERR_SHIFT + 3) | ||
38 | |||
39 | #define MC_GART_ERROR_REQ 0x30 | ||
40 | #define MC_DECERR_EMEM_OTHERS_STATUS 0x58 | ||
41 | #define MC_SECURITY_VIOLATION_STATUS 0x74 | ||
42 | |||
43 | #define SECURITY_VIOLATION_TYPE BIT(30) /* 0=TRUSTZONE, 1=CARVEOUT */ | ||
44 | |||
45 | #define MC_CLIENT_ID_MASK 0x3f | ||
46 | |||
47 | #define NUM_MC_REG_BANKS 2 | ||
48 | |||
49 | struct tegra20_mc { | ||
50 | void __iomem *regs[NUM_MC_REG_BANKS]; | ||
51 | struct device *dev; | ||
52 | }; | ||
53 | |||
54 | static inline u32 mc_readl(struct tegra20_mc *mc, u32 offs) | ||
55 | { | ||
56 | u32 val = 0; | ||
57 | |||
58 | if (offs < 0x24) | ||
59 | val = readl(mc->regs[0] + offs); | ||
60 | if (offs < 0x400) | ||
61 | val = readl(mc->regs[1] + offs - 0x3c); | ||
62 | |||
63 | return val; | ||
64 | } | ||
65 | |||
66 | static inline void mc_writel(struct tegra20_mc *mc, u32 val, u32 offs) | ||
67 | { | ||
68 | if (offs < 0x24) { | ||
69 | writel(val, mc->regs[0] + offs); | ||
70 | return; | ||
71 | } | ||
72 | if (offs < 0x400) { | ||
73 | writel(val, mc->regs[1] + offs - 0x3c); | ||
74 | return; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | static const char * const tegra20_mc_client[] = { | ||
79 | "cbr_display0a", | ||
80 | "cbr_display0ab", | ||
81 | "cbr_display0b", | ||
82 | "cbr_display0bb", | ||
83 | "cbr_display0c", | ||
84 | "cbr_display0cb", | ||
85 | "cbr_display1b", | ||
86 | "cbr_display1bb", | ||
87 | "cbr_eppup", | ||
88 | "cbr_g2pr", | ||
89 | "cbr_g2sr", | ||
90 | "cbr_mpeunifbr", | ||
91 | "cbr_viruv", | ||
92 | "csr_avpcarm7r", | ||
93 | "csr_displayhc", | ||
94 | "csr_displayhcb", | ||
95 | "csr_fdcdrd", | ||
96 | "csr_g2dr", | ||
97 | "csr_host1xdmar", | ||
98 | "csr_host1xr", | ||
99 | "csr_idxsrd", | ||
100 | "csr_mpcorer", | ||
101 | "csr_mpe_ipred", | ||
102 | "csr_mpeamemrd", | ||
103 | "csr_mpecsrd", | ||
104 | "csr_ppcsahbdmar", | ||
105 | "csr_ppcsahbslvr", | ||
106 | "csr_texsrd", | ||
107 | "csr_vdebsevr", | ||
108 | "csr_vdember", | ||
109 | "csr_vdemcer", | ||
110 | "csr_vdetper", | ||
111 | "cbw_eppu", | ||
112 | "cbw_eppv", | ||
113 | "cbw_eppy", | ||
114 | "cbw_mpeunifbw", | ||
115 | "cbw_viwsb", | ||
116 | "cbw_viwu", | ||
117 | "cbw_viwv", | ||
118 | "cbw_viwy", | ||
119 | "ccw_g2dw", | ||
120 | "csw_avpcarm7w", | ||
121 | "csw_fdcdwr", | ||
122 | "csw_host1xw", | ||
123 | "csw_ispw", | ||
124 | "csw_mpcorew", | ||
125 | "csw_mpecswr", | ||
126 | "csw_ppcsahbdmaw", | ||
127 | "csw_ppcsahbslvw", | ||
128 | "csw_vdebsevw", | ||
129 | "csw_vdembew", | ||
130 | "csw_vdetpmw", | ||
131 | }; | ||
132 | |||
133 | static void tegra20_mc_decode(struct tegra20_mc *mc, int n) | ||
134 | { | ||
135 | u32 addr, req; | ||
136 | const char *client = "Unknown"; | ||
137 | int idx, cid; | ||
138 | const struct reg_info { | ||
139 | u32 offset; | ||
140 | u32 write_bit; /* 0=READ, 1=WRITE */ | ||
141 | int cid_shift; | ||
142 | char *message; | ||
143 | } reg[] = { | ||
144 | { | ||
145 | .offset = MC_DECERR_EMEM_OTHERS_STATUS, | ||
146 | .write_bit = 31, | ||
147 | .message = "MC_DECERR", | ||
148 | }, | ||
149 | { | ||
150 | .offset = MC_GART_ERROR_REQ, | ||
151 | .cid_shift = 1, | ||
152 | .message = "MC_GART_ERR", | ||
153 | |||
154 | }, | ||
155 | { | ||
156 | .offset = MC_SECURITY_VIOLATION_STATUS, | ||
157 | .write_bit = 31, | ||
158 | .message = "MC_SECURITY_ERR", | ||
159 | }, | ||
160 | }; | ||
161 | |||
162 | idx = n - MC_INT_ERR_SHIFT; | ||
163 | if ((idx < 0) || (idx >= ARRAY_SIZE(reg))) { | ||
164 | dev_err_ratelimited(mc->dev, "Unknown interrupt status %08lx\n", | ||
165 | BIT(n)); | ||
166 | return; | ||
167 | } | ||
168 | |||
169 | req = mc_readl(mc, reg[idx].offset); | ||
170 | cid = (req >> reg[idx].cid_shift) & MC_CLIENT_ID_MASK; | ||
171 | if (cid < ARRAY_SIZE(tegra20_mc_client)) | ||
172 | client = tegra20_mc_client[cid]; | ||
173 | |||
174 | addr = mc_readl(mc, reg[idx].offset + sizeof(u32)); | ||
175 | |||
176 | dev_err_ratelimited(mc->dev, "%s (0x%08x): 0x%08x %s (%s %s)\n", | ||
177 | reg[idx].message, req, addr, client, | ||
178 | (req & BIT(reg[idx].write_bit)) ? "write" : "read", | ||
179 | (reg[idx].offset == MC_SECURITY_VIOLATION_STATUS) ? | ||
180 | ((req & SECURITY_VIOLATION_TYPE) ? | ||
181 | "carveout" : "trustzone") : ""); | ||
182 | } | ||
183 | |||
184 | static const struct of_device_id tegra20_mc_of_match[] __devinitconst = { | ||
185 | { .compatible = "nvidia,tegra20-mc", }, | ||
186 | {}, | ||
187 | }; | ||
188 | |||
189 | static irqreturn_t tegra20_mc_isr(int irq, void *data) | ||
190 | { | ||
191 | u32 stat, mask, bit; | ||
192 | struct tegra20_mc *mc = data; | ||
193 | |||
194 | stat = mc_readl(mc, MC_INTSTATUS); | ||
195 | mask = mc_readl(mc, MC_INTMASK); | ||
196 | mask &= stat; | ||
197 | if (!mask) | ||
198 | return IRQ_NONE; | ||
199 | while ((bit = ffs(mask)) != 0) | ||
200 | tegra20_mc_decode(mc, bit - 1); | ||
201 | mc_writel(mc, stat, MC_INTSTATUS); | ||
202 | return IRQ_HANDLED; | ||
203 | } | ||
204 | |||
205 | static int __devinit tegra20_mc_probe(struct platform_device *pdev) | ||
206 | { | ||
207 | struct resource *irq; | ||
208 | struct tegra20_mc *mc; | ||
209 | int i, err; | ||
210 | u32 intmask; | ||
211 | |||
212 | mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL); | ||
213 | if (!mc) | ||
214 | return -ENOMEM; | ||
215 | mc->dev = &pdev->dev; | ||
216 | |||
217 | for (i = 0; i < ARRAY_SIZE(mc->regs); i++) { | ||
218 | struct resource *res; | ||
219 | |||
220 | res = platform_get_resource(pdev, IORESOURCE_MEM, i); | ||
221 | if (!res) | ||
222 | return -ENODEV; | ||
223 | mc->regs[i] = devm_request_and_ioremap(&pdev->dev, res); | ||
224 | if (!mc->regs[i]) | ||
225 | return -EBUSY; | ||
226 | } | ||
227 | |||
228 | irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
229 | if (!irq) | ||
230 | return -ENODEV; | ||
231 | err = devm_request_irq(&pdev->dev, irq->start, tegra20_mc_isr, | ||
232 | IRQF_SHARED, dev_name(&pdev->dev), mc); | ||
233 | if (err) | ||
234 | return -ENODEV; | ||
235 | |||
236 | platform_set_drvdata(pdev, mc); | ||
237 | |||
238 | intmask = MC_INT_INVALID_GART_PAGE | | ||
239 | MC_INT_DECERR_EMEM | MC_INT_SECURITY_VIOLATION; | ||
240 | mc_writel(mc, intmask, MC_INTMASK); | ||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | static struct platform_driver tegra20_mc_driver = { | ||
245 | .probe = tegra20_mc_probe, | ||
246 | .driver = { | ||
247 | .name = DRV_NAME, | ||
248 | .owner = THIS_MODULE, | ||
249 | .of_match_table = tegra20_mc_of_match, | ||
250 | }, | ||
251 | }; | ||
252 | module_platform_driver(tegra20_mc_driver); | ||
253 | |||
254 | MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>"); | ||
255 | MODULE_DESCRIPTION("Tegra20 MC driver"); | ||
256 | MODULE_LICENSE("GPL v2"); | ||
257 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/memory/tegra30-mc.c b/drivers/memory/tegra30-mc.c new file mode 100644 index 000000000000..e56ff04eb5cc --- /dev/null +++ b/drivers/memory/tegra30-mc.c | |||
@@ -0,0 +1,382 @@ | |||
1 | /* | ||
2 | * Tegra30 Memory Controller | ||
3 | * | ||
4 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along with | ||
16 | * this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/ratelimit.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/io.h> | ||
26 | |||
27 | #define DRV_NAME "tegra30-mc" | ||
28 | |||
29 | #define MC_INTSTATUS 0x0 | ||
30 | #define MC_INTMASK 0x4 | ||
31 | |||
32 | #define MC_INT_ERR_SHIFT 6 | ||
33 | #define MC_INT_ERR_MASK (0x1f << MC_INT_ERR_SHIFT) | ||
34 | #define MC_INT_DECERR_EMEM BIT(MC_INT_ERR_SHIFT) | ||
35 | #define MC_INT_SECURITY_VIOLATION BIT(MC_INT_ERR_SHIFT + 2) | ||
36 | #define MC_INT_ARBITRATION_EMEM BIT(MC_INT_ERR_SHIFT + 3) | ||
37 | #define MC_INT_INVALID_SMMU_PAGE BIT(MC_INT_ERR_SHIFT + 4) | ||
38 | |||
39 | #define MC_ERR_STATUS 0x8 | ||
40 | #define MC_ERR_ADR 0xc | ||
41 | |||
42 | #define MC_ERR_TYPE_SHIFT 28 | ||
43 | #define MC_ERR_TYPE_MASK (7 << MC_ERR_TYPE_SHIFT) | ||
44 | #define MC_ERR_TYPE_DECERR_EMEM 2 | ||
45 | #define MC_ERR_TYPE_SECURITY_TRUSTZONE 3 | ||
46 | #define MC_ERR_TYPE_SECURITY_CARVEOUT 4 | ||
47 | #define MC_ERR_TYPE_INVALID_SMMU_PAGE 6 | ||
48 | |||
49 | #define MC_ERR_INVALID_SMMU_PAGE_SHIFT 25 | ||
50 | #define MC_ERR_INVALID_SMMU_PAGE_MASK (7 << MC_ERR_INVALID_SMMU_PAGE_SHIFT) | ||
51 | #define MC_ERR_RW_SHIFT 16 | ||
52 | #define MC_ERR_RW BIT(MC_ERR_RW_SHIFT) | ||
53 | #define MC_ERR_SECURITY BIT(MC_ERR_RW_SHIFT + 1) | ||
54 | |||
55 | #define SECURITY_VIOLATION_TYPE BIT(30) /* 0=TRUSTZONE, 1=CARVEOUT */ | ||
56 | |||
57 | #define MC_EMEM_ARB_CFG 0x90 | ||
58 | #define MC_EMEM_ARB_OUTSTANDING_REQ 0x94 | ||
59 | #define MC_EMEM_ARB_TIMING_RCD 0x98 | ||
60 | #define MC_EMEM_ARB_TIMING_RP 0x9c | ||
61 | #define MC_EMEM_ARB_TIMING_RC 0xa0 | ||
62 | #define MC_EMEM_ARB_TIMING_RAS 0xa4 | ||
63 | #define MC_EMEM_ARB_TIMING_FAW 0xa8 | ||
64 | #define MC_EMEM_ARB_TIMING_RRD 0xac | ||
65 | #define MC_EMEM_ARB_TIMING_RAP2PRE 0xb0 | ||
66 | #define MC_EMEM_ARB_TIMING_WAP2PRE 0xb4 | ||
67 | #define MC_EMEM_ARB_TIMING_R2R 0xb8 | ||
68 | #define MC_EMEM_ARB_TIMING_W2W 0xbc | ||
69 | #define MC_EMEM_ARB_TIMING_R2W 0xc0 | ||
70 | #define MC_EMEM_ARB_TIMING_W2R 0xc4 | ||
71 | |||
72 | #define MC_EMEM_ARB_DA_TURNS 0xd0 | ||
73 | #define MC_EMEM_ARB_DA_COVERS 0xd4 | ||
74 | #define MC_EMEM_ARB_MISC0 0xd8 | ||
75 | #define MC_EMEM_ARB_MISC1 0xdc | ||
76 | |||
77 | #define MC_EMEM_ARB_RING3_THROTTLE 0xe4 | ||
78 | #define MC_EMEM_ARB_OVERRIDE 0xe8 | ||
79 | |||
80 | #define MC_TIMING_CONTROL 0xfc | ||
81 | |||
82 | #define MC_CLIENT_ID_MASK 0x7f | ||
83 | |||
84 | #define NUM_MC_REG_BANKS 4 | ||
85 | |||
86 | struct tegra30_mc { | ||
87 | void __iomem *regs[NUM_MC_REG_BANKS]; | ||
88 | struct device *dev; | ||
89 | u32 ctx[0]; | ||
90 | }; | ||
91 | |||
92 | static inline u32 mc_readl(struct tegra30_mc *mc, u32 offs) | ||
93 | { | ||
94 | u32 val = 0; | ||
95 | |||
96 | if (offs < 0x10) | ||
97 | val = readl(mc->regs[0] + offs); | ||
98 | if (offs < 0x1f0) | ||
99 | val = readl(mc->regs[1] + offs - 0x3c); | ||
100 | if (offs < 0x228) | ||
101 | val = readl(mc->regs[2] + offs - 0x200); | ||
102 | if (offs < 0x400) | ||
103 | val = readl(mc->regs[3] + offs - 0x284); | ||
104 | |||
105 | return val; | ||
106 | } | ||
107 | |||
108 | static inline void mc_writel(struct tegra30_mc *mc, u32 val, u32 offs) | ||
109 | { | ||
110 | if (offs < 0x10) { | ||
111 | writel(val, mc->regs[0] + offs); | ||
112 | return; | ||
113 | } | ||
114 | if (offs < 0x1f0) { | ||
115 | writel(val, mc->regs[1] + offs - 0x3c); | ||
116 | return; | ||
117 | } | ||
118 | if (offs < 0x228) { | ||
119 | writel(val, mc->regs[2] + offs - 0x200); | ||
120 | return; | ||
121 | } | ||
122 | if (offs < 0x400) { | ||
123 | writel(val, mc->regs[3] + offs - 0x284); | ||
124 | return; | ||
125 | } | ||
126 | } | ||
127 | |||
128 | static const char * const tegra30_mc_client[] = { | ||
129 | "csr_ptcr", | ||
130 | "cbr_display0a", | ||
131 | "cbr_display0ab", | ||
132 | "cbr_display0b", | ||
133 | "cbr_display0bb", | ||
134 | "cbr_display0c", | ||
135 | "cbr_display0cb", | ||
136 | "cbr_display1b", | ||
137 | "cbr_display1bb", | ||
138 | "cbr_eppup", | ||
139 | "cbr_g2pr", | ||
140 | "cbr_g2sr", | ||
141 | "cbr_mpeunifbr", | ||
142 | "cbr_viruv", | ||
143 | "csr_afir", | ||
144 | "csr_avpcarm7r", | ||
145 | "csr_displayhc", | ||
146 | "csr_displayhcb", | ||
147 | "csr_fdcdrd", | ||
148 | "csr_fdcdrd2", | ||
149 | "csr_g2dr", | ||
150 | "csr_hdar", | ||
151 | "csr_host1xdmar", | ||
152 | "csr_host1xr", | ||
153 | "csr_idxsrd", | ||
154 | "csr_idxsrd2", | ||
155 | "csr_mpe_ipred", | ||
156 | "csr_mpeamemrd", | ||
157 | "csr_mpecsrd", | ||
158 | "csr_ppcsahbdmar", | ||
159 | "csr_ppcsahbslvr", | ||
160 | "csr_satar", | ||
161 | "csr_texsrd", | ||
162 | "csr_texsrd2", | ||
163 | "csr_vdebsevr", | ||
164 | "csr_vdember", | ||
165 | "csr_vdemcer", | ||
166 | "csr_vdetper", | ||
167 | "csr_mpcorelpr", | ||
168 | "csr_mpcorer", | ||
169 | "cbw_eppu", | ||
170 | "cbw_eppv", | ||
171 | "cbw_eppy", | ||
172 | "cbw_mpeunifbw", | ||
173 | "cbw_viwsb", | ||
174 | "cbw_viwu", | ||
175 | "cbw_viwv", | ||
176 | "cbw_viwy", | ||
177 | "ccw_g2dw", | ||
178 | "csw_afiw", | ||
179 | "csw_avpcarm7w", | ||
180 | "csw_fdcdwr", | ||
181 | "csw_fdcdwr2", | ||
182 | "csw_hdaw", | ||
183 | "csw_host1xw", | ||
184 | "csw_ispw", | ||
185 | "csw_mpcorelpw", | ||
186 | "csw_mpcorew", | ||
187 | "csw_mpecswr", | ||
188 | "csw_ppcsahbdmaw", | ||
189 | "csw_ppcsahbslvw", | ||
190 | "csw_sataw", | ||
191 | "csw_vdebsevw", | ||
192 | "csw_vdedbgw", | ||
193 | "csw_vdembew", | ||
194 | "csw_vdetpmw", | ||
195 | }; | ||
196 | |||
197 | static void tegra30_mc_decode(struct tegra30_mc *mc, int n) | ||
198 | { | ||
199 | u32 err, addr; | ||
200 | const char * const mc_int_err[] = { | ||
201 | "MC_DECERR", | ||
202 | "Unknown", | ||
203 | "MC_SECURITY_ERR", | ||
204 | "MC_ARBITRATION_EMEM", | ||
205 | "MC_SMMU_ERR", | ||
206 | }; | ||
207 | const char * const err_type[] = { | ||
208 | "Unknown", | ||
209 | "Unknown", | ||
210 | "DECERR_EMEM", | ||
211 | "SECURITY_TRUSTZONE", | ||
212 | "SECURITY_CARVEOUT", | ||
213 | "Unknown", | ||
214 | "INVALID_SMMU_PAGE", | ||
215 | "Unknown", | ||
216 | }; | ||
217 | char attr[6]; | ||
218 | int cid, perm, type, idx; | ||
219 | const char *client = "Unknown"; | ||
220 | |||
221 | idx = n - MC_INT_ERR_SHIFT; | ||
222 | if ((idx < 0) || (idx >= ARRAY_SIZE(mc_int_err)) || (idx == 1)) { | ||
223 | dev_err_ratelimited(mc->dev, "Unknown interrupt status %08lx\n", | ||
224 | BIT(n)); | ||
225 | return; | ||
226 | } | ||
227 | |||
228 | err = readl(mc + MC_ERR_STATUS); | ||
229 | |||
230 | type = (err & MC_ERR_TYPE_MASK) >> MC_ERR_TYPE_SHIFT; | ||
231 | perm = (err & MC_ERR_INVALID_SMMU_PAGE_MASK) >> | ||
232 | MC_ERR_INVALID_SMMU_PAGE_SHIFT; | ||
233 | if (type == MC_ERR_TYPE_INVALID_SMMU_PAGE) | ||
234 | sprintf(attr, "%c-%c-%c", | ||
235 | (perm & BIT(2)) ? 'R' : '-', | ||
236 | (perm & BIT(1)) ? 'W' : '-', | ||
237 | (perm & BIT(0)) ? 'S' : '-'); | ||
238 | else | ||
239 | attr[0] = '\0'; | ||
240 | |||
241 | cid = err & MC_CLIENT_ID_MASK; | ||
242 | if (cid < ARRAY_SIZE(tegra30_mc_client)) | ||
243 | client = tegra30_mc_client[cid]; | ||
244 | |||
245 | addr = readl(mc + MC_ERR_ADR); | ||
246 | |||
247 | dev_err_ratelimited(mc->dev, "%s (0x%08x): 0x%08x %s (%s %s %s %s)\n", | ||
248 | mc_int_err[idx], err, addr, client, | ||
249 | (err & MC_ERR_SECURITY) ? "secure" : "non-secure", | ||
250 | (err & MC_ERR_RW) ? "write" : "read", | ||
251 | err_type[type], attr); | ||
252 | } | ||
253 | |||
254 | static const u32 tegra30_mc_ctx[] = { | ||
255 | MC_EMEM_ARB_CFG, | ||
256 | MC_EMEM_ARB_OUTSTANDING_REQ, | ||
257 | MC_EMEM_ARB_TIMING_RCD, | ||
258 | MC_EMEM_ARB_TIMING_RP, | ||
259 | MC_EMEM_ARB_TIMING_RC, | ||
260 | MC_EMEM_ARB_TIMING_RAS, | ||
261 | MC_EMEM_ARB_TIMING_FAW, | ||
262 | MC_EMEM_ARB_TIMING_RRD, | ||
263 | MC_EMEM_ARB_TIMING_RAP2PRE, | ||
264 | MC_EMEM_ARB_TIMING_WAP2PRE, | ||
265 | MC_EMEM_ARB_TIMING_R2R, | ||
266 | MC_EMEM_ARB_TIMING_W2W, | ||
267 | MC_EMEM_ARB_TIMING_R2W, | ||
268 | MC_EMEM_ARB_TIMING_W2R, | ||
269 | MC_EMEM_ARB_DA_TURNS, | ||
270 | MC_EMEM_ARB_DA_COVERS, | ||
271 | MC_EMEM_ARB_MISC0, | ||
272 | MC_EMEM_ARB_MISC1, | ||
273 | MC_EMEM_ARB_RING3_THROTTLE, | ||
274 | MC_EMEM_ARB_OVERRIDE, | ||
275 | MC_INTMASK, | ||
276 | }; | ||
277 | |||
278 | static int tegra30_mc_suspend(struct device *dev) | ||
279 | { | ||
280 | int i; | ||
281 | struct tegra30_mc *mc = dev_get_drvdata(dev); | ||
282 | |||
283 | for (i = 0; i < ARRAY_SIZE(tegra30_mc_ctx); i++) | ||
284 | mc->ctx[i] = mc_readl(mc, tegra30_mc_ctx[i]); | ||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | static int tegra30_mc_resume(struct device *dev) | ||
289 | { | ||
290 | int i; | ||
291 | struct tegra30_mc *mc = dev_get_drvdata(dev); | ||
292 | |||
293 | for (i = 0; i < ARRAY_SIZE(tegra30_mc_ctx); i++) | ||
294 | mc_writel(mc, mc->ctx[i], tegra30_mc_ctx[i]); | ||
295 | |||
296 | mc_writel(mc, 1, MC_TIMING_CONTROL); | ||
297 | /* Read-back to ensure that write reached */ | ||
298 | mc_readl(mc, MC_TIMING_CONTROL); | ||
299 | return 0; | ||
300 | } | ||
301 | |||
302 | static UNIVERSAL_DEV_PM_OPS(tegra30_mc_pm, | ||
303 | tegra30_mc_suspend, | ||
304 | tegra30_mc_resume, NULL); | ||
305 | |||
306 | static const struct of_device_id tegra30_mc_of_match[] __devinitconst = { | ||
307 | { .compatible = "nvidia,tegra30-mc", }, | ||
308 | {}, | ||
309 | }; | ||
310 | |||
311 | static irqreturn_t tegra30_mc_isr(int irq, void *data) | ||
312 | { | ||
313 | u32 stat, mask, bit; | ||
314 | struct tegra30_mc *mc = data; | ||
315 | |||
316 | stat = mc_readl(mc, MC_INTSTATUS); | ||
317 | mask = mc_readl(mc, MC_INTMASK); | ||
318 | mask &= stat; | ||
319 | if (!mask) | ||
320 | return IRQ_NONE; | ||
321 | while ((bit = ffs(mask)) != 0) | ||
322 | tegra30_mc_decode(mc, bit - 1); | ||
323 | mc_writel(mc, stat, MC_INTSTATUS); | ||
324 | return IRQ_HANDLED; | ||
325 | } | ||
326 | |||
327 | static int __devinit tegra30_mc_probe(struct platform_device *pdev) | ||
328 | { | ||
329 | struct resource *irq; | ||
330 | struct tegra30_mc *mc; | ||
331 | size_t bytes; | ||
332 | int err, i; | ||
333 | u32 intmask; | ||
334 | |||
335 | bytes = sizeof(*mc) + sizeof(u32) * ARRAY_SIZE(tegra30_mc_ctx); | ||
336 | mc = devm_kzalloc(&pdev->dev, bytes, GFP_KERNEL); | ||
337 | if (!mc) | ||
338 | return -ENOMEM; | ||
339 | mc->dev = &pdev->dev; | ||
340 | |||
341 | for (i = 0; i < ARRAY_SIZE(mc->regs); i++) { | ||
342 | struct resource *res; | ||
343 | |||
344 | res = platform_get_resource(pdev, IORESOURCE_MEM, i); | ||
345 | if (!res) | ||
346 | return -ENODEV; | ||
347 | mc->regs[i] = devm_request_and_ioremap(&pdev->dev, res); | ||
348 | if (!mc->regs[i]) | ||
349 | return -EBUSY; | ||
350 | } | ||
351 | |||
352 | irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
353 | if (!irq) | ||
354 | return -ENODEV; | ||
355 | err = devm_request_irq(&pdev->dev, irq->start, tegra30_mc_isr, | ||
356 | IRQF_SHARED, dev_name(&pdev->dev), mc); | ||
357 | if (err) | ||
358 | return -ENODEV; | ||
359 | |||
360 | platform_set_drvdata(pdev, mc); | ||
361 | |||
362 | intmask = MC_INT_INVALID_SMMU_PAGE | | ||
363 | MC_INT_DECERR_EMEM | MC_INT_SECURITY_VIOLATION; | ||
364 | mc_writel(mc, intmask, MC_INTMASK); | ||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | static struct platform_driver tegra30_mc_driver = { | ||
369 | .probe = tegra30_mc_probe, | ||
370 | .driver = { | ||
371 | .name = DRV_NAME, | ||
372 | .owner = THIS_MODULE, | ||
373 | .of_match_table = tegra30_mc_of_match, | ||
374 | .pm = &tegra30_mc_pm, | ||
375 | }, | ||
376 | }; | ||
377 | module_platform_driver(tegra30_mc_driver); | ||
378 | |||
379 | MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>"); | ||
380 | MODULE_DESCRIPTION("Tegra30 MC driver"); | ||
381 | MODULE_LICENSE("GPL v2"); | ||
382 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 968469555956..757fbd0f2a14 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -508,14 +508,6 @@ config USB_SWITCH_FSA9480 | |||
508 | stereo and mono audio, video, microphone and UART data to use | 508 | stereo and mono audio, video, microphone and UART data to use |
509 | a common connector port. | 509 | a common connector port. |
510 | 510 | ||
511 | config MAX8997_MUIC | ||
512 | tristate "MAX8997 MUIC Support" | ||
513 | depends on MFD_MAX8997 | ||
514 | help | ||
515 | If you say yes here you get support for the MUIC device of | ||
516 | Maxim MAX8997 PMIC. | ||
517 | The MAX8997 MUIC is a USB port accessory detector and switch. | ||
518 | |||
519 | source "drivers/misc/c2port/Kconfig" | 511 | source "drivers/misc/c2port/Kconfig" |
520 | source "drivers/misc/eeprom/Kconfig" | 512 | source "drivers/misc/eeprom/Kconfig" |
521 | source "drivers/misc/cb710/Kconfig" | 513 | source "drivers/misc/cb710/Kconfig" |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 509d0569dc04..162861788c6d 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
@@ -50,4 +50,3 @@ obj-y += lis3lv02d/ | |||
50 | obj-y += carma/ | 50 | obj-y += carma/ |
51 | obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o | 51 | obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o |
52 | obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/ | 52 | obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/ |
53 | obj-$(CONFIG_MAX8997_MUIC) += max8997-muic.o | ||
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index 402956321d33..5abffe58a9d2 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c | |||
@@ -2075,7 +2075,7 @@ struct parport *parport_pc_probe_port(unsigned long int base, | |||
2075 | 2075 | ||
2076 | printk(KERN_INFO "%s: PC-style at 0x%lx", p->name, p->base); | 2076 | printk(KERN_INFO "%s: PC-style at 0x%lx", p->name, p->base); |
2077 | if (p->base_hi && priv->ecr) | 2077 | if (p->base_hi && priv->ecr) |
2078 | printk(" (0x%lx)", p->base_hi); | 2078 | printk(KERN_CONT " (0x%lx)", p->base_hi); |
2079 | if (p->irq == PARPORT_IRQ_AUTO) { | 2079 | if (p->irq == PARPORT_IRQ_AUTO) { |
2080 | p->irq = PARPORT_IRQ_NONE; | 2080 | p->irq = PARPORT_IRQ_NONE; |
2081 | parport_irq_probe(p); | 2081 | parport_irq_probe(p); |
@@ -2086,7 +2086,7 @@ struct parport *parport_pc_probe_port(unsigned long int base, | |||
2086 | p->irq = PARPORT_IRQ_NONE; | 2086 | p->irq = PARPORT_IRQ_NONE; |
2087 | } | 2087 | } |
2088 | if (p->irq != PARPORT_IRQ_NONE) { | 2088 | if (p->irq != PARPORT_IRQ_NONE) { |
2089 | printk(", irq %d", p->irq); | 2089 | printk(KERN_CONT ", irq %d", p->irq); |
2090 | priv->ctr_writable |= 0x10; | 2090 | priv->ctr_writable |= 0x10; |
2091 | 2091 | ||
2092 | if (p->dma == PARPORT_DMA_AUTO) { | 2092 | if (p->dma == PARPORT_DMA_AUTO) { |
@@ -2110,21 +2110,21 @@ struct parport *parport_pc_probe_port(unsigned long int base, | |||
2110 | /* p->ops->ecp_read_data = parport_pc_ecp_read_block_pio; */ | 2110 | /* p->ops->ecp_read_data = parport_pc_ecp_read_block_pio; */ |
2111 | #endif /* IEEE 1284 support */ | 2111 | #endif /* IEEE 1284 support */ |
2112 | if (p->dma != PARPORT_DMA_NONE) { | 2112 | if (p->dma != PARPORT_DMA_NONE) { |
2113 | printk(", dma %d", p->dma); | 2113 | printk(KERN_CONT ", dma %d", p->dma); |
2114 | p->modes |= PARPORT_MODE_DMA; | 2114 | p->modes |= PARPORT_MODE_DMA; |
2115 | } else | 2115 | } else |
2116 | printk(", using FIFO"); | 2116 | printk(KERN_CONT ", using FIFO"); |
2117 | } else | 2117 | } else |
2118 | /* We can't use the DMA channel after all. */ | 2118 | /* We can't use the DMA channel after all. */ |
2119 | p->dma = PARPORT_DMA_NONE; | 2119 | p->dma = PARPORT_DMA_NONE; |
2120 | #endif /* Allowed to use FIFO/DMA */ | 2120 | #endif /* Allowed to use FIFO/DMA */ |
2121 | 2121 | ||
2122 | printk(" ["); | 2122 | printk(KERN_CONT " ["); |
2123 | 2123 | ||
2124 | #define printmode(x) \ | 2124 | #define printmode(x) \ |
2125 | {\ | 2125 | {\ |
2126 | if (p->modes & PARPORT_MODE_##x) {\ | 2126 | if (p->modes & PARPORT_MODE_##x) {\ |
2127 | printk("%s%s", f ? "," : "", #x);\ | 2127 | printk(KERN_CONT "%s%s", f ? "," : "", #x);\ |
2128 | f++;\ | 2128 | f++;\ |
2129 | } \ | 2129 | } \ |
2130 | } | 2130 | } |
@@ -2140,9 +2140,9 @@ struct parport *parport_pc_probe_port(unsigned long int base, | |||
2140 | } | 2140 | } |
2141 | #undef printmode | 2141 | #undef printmode |
2142 | #ifndef CONFIG_PARPORT_1284 | 2142 | #ifndef CONFIG_PARPORT_1284 |
2143 | printk("(,...)"); | 2143 | printk(KERN_CONT "(,...)"); |
2144 | #endif /* CONFIG_PARPORT_1284 */ | 2144 | #endif /* CONFIG_PARPORT_1284 */ |
2145 | printk("]\n"); | 2145 | printk(KERN_CONT "]\n"); |
2146 | if (probedirq != PARPORT_IRQ_NONE) | 2146 | if (probedirq != PARPORT_IRQ_NONE) |
2147 | printk(KERN_INFO "%s: irq %d detected\n", p->name, probedirq); | 2147 | printk(KERN_INFO "%s: irq %d detected\n", p->name, probedirq); |
2148 | 2148 | ||
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index eb1dee26bda3..c706635f3f82 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig | |||
@@ -53,8 +53,6 @@ config ANDROID_LOW_MEMORY_KILLER | |||
53 | ---help--- | 53 | ---help--- |
54 | Register processes to be killed when memory is low | 54 | Register processes to be killed when memory is low |
55 | 55 | ||
56 | source "drivers/staging/android/switch/Kconfig" | ||
57 | |||
58 | config ANDROID_INTF_ALARM | 56 | config ANDROID_INTF_ALARM |
59 | bool "Android alarm driver" | 57 | bool "Android alarm driver" |
60 | depends on RTC_CLASS | 58 | depends on RTC_CLASS |
@@ -80,7 +78,6 @@ config ANDROID_ALARM_OLDDRV_COMPAT | |||
80 | Provides preprocessor alias to aid compatability with | 78 | Provides preprocessor alias to aid compatability with |
81 | older out-of-tree drivers that use the Android Alarm | 79 | older out-of-tree drivers that use the Android Alarm |
82 | in-kernel API. This will be removed eventually. | 80 | in-kernel API. This will be removed eventually. |
83 | |||
84 | endif # if ANDROID | 81 | endif # if ANDROID |
85 | 82 | ||
86 | endmenu | 83 | endmenu |
diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile index 9b6c9ed91f69..045d17bde524 100644 --- a/drivers/staging/android/Makefile +++ b/drivers/staging/android/Makefile | |||
@@ -6,6 +6,5 @@ obj-$(CONFIG_ANDROID_RAM_CONSOLE) += ram_console.o | |||
6 | obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o | 6 | obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o |
7 | obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o | 7 | obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o |
8 | obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o | 8 | obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o |
9 | obj-$(CONFIG_ANDROID_SWITCH) += switch/ | ||
10 | obj-$(CONFIG_ANDROID_INTF_ALARM) += alarm.o | 9 | obj-$(CONFIG_ANDROID_INTF_ALARM) += alarm.o |
11 | obj-$(CONFIG_ANDROID_INTF_ALARM_DEV) += alarm-dev.o | 10 | obj-$(CONFIG_ANDROID_INTF_ALARM_DEV) += alarm-dev.o |
diff --git a/drivers/staging/android/switch/Kconfig b/drivers/staging/android/switch/Kconfig deleted file mode 100644 index 36846f62f4bc..000000000000 --- a/drivers/staging/android/switch/Kconfig +++ /dev/null | |||
@@ -1,11 +0,0 @@ | |||
1 | menuconfig ANDROID_SWITCH | ||
2 | tristate "Android Switch class support" | ||
3 | help | ||
4 | Say Y here to enable Android switch class support. This allows | ||
5 | monitoring switches by userspace via sysfs and uevent. | ||
6 | |||
7 | config ANDROID_SWITCH_GPIO | ||
8 | tristate "Android GPIO Switch support" | ||
9 | depends on GENERIC_GPIO && ANDROID_SWITCH | ||
10 | help | ||
11 | Say Y here to enable GPIO based switch support. | ||
diff --git a/drivers/staging/android/switch/Makefile b/drivers/staging/android/switch/Makefile deleted file mode 100644 index d76bfdcedfaf..000000000000 --- a/drivers/staging/android/switch/Makefile +++ /dev/null | |||
@@ -1,4 +0,0 @@ | |||
1 | # Android Switch Class Driver | ||
2 | obj-$(CONFIG_ANDROID_SWITCH) += switch_class.o | ||
3 | obj-$(CONFIG_ANDROID_SWITCH_GPIO) += switch_gpio.o | ||
4 | |||
diff --git a/drivers/staging/android/switch/switch.h b/drivers/staging/android/switch/switch.h deleted file mode 100644 index 4fcb3109875a..000000000000 --- a/drivers/staging/android/switch/switch.h +++ /dev/null | |||
@@ -1,53 +0,0 @@ | |||
1 | /* | ||
2 | * Switch class driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Google, Inc. | ||
5 | * Author: Mike Lockwood <lockwood@android.com> | ||
6 | * | ||
7 | * This software is licensed under the terms of the GNU General Public | ||
8 | * License version 2, as published by the Free Software Foundation, and | ||
9 | * may be copied, distributed, and modified under those terms. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #ifndef __LINUX_SWITCH_H__ | ||
19 | #define __LINUX_SWITCH_H__ | ||
20 | |||
21 | struct switch_dev { | ||
22 | const char *name; | ||
23 | struct device *dev; | ||
24 | int index; | ||
25 | int state; | ||
26 | |||
27 | ssize_t (*print_name)(struct switch_dev *sdev, char *buf); | ||
28 | ssize_t (*print_state)(struct switch_dev *sdev, char *buf); | ||
29 | }; | ||
30 | |||
31 | struct gpio_switch_platform_data { | ||
32 | const char *name; | ||
33 | unsigned gpio; | ||
34 | |||
35 | /* if NULL, switch_dev.name will be printed */ | ||
36 | const char *name_on; | ||
37 | const char *name_off; | ||
38 | /* if NULL, "0" or "1" will be printed */ | ||
39 | const char *state_on; | ||
40 | const char *state_off; | ||
41 | }; | ||
42 | |||
43 | extern int switch_dev_register(struct switch_dev *sdev); | ||
44 | extern void switch_dev_unregister(struct switch_dev *sdev); | ||
45 | |||
46 | static inline int switch_get_state(struct switch_dev *sdev) | ||
47 | { | ||
48 | return sdev->state; | ||
49 | } | ||
50 | |||
51 | extern void switch_set_state(struct switch_dev *sdev, int state); | ||
52 | |||
53 | #endif /* __LINUX_SWITCH_H__ */ | ||
diff --git a/drivers/staging/android/switch/switch_class.c b/drivers/staging/android/switch/switch_class.c deleted file mode 100644 index 74680446fc66..000000000000 --- a/drivers/staging/android/switch/switch_class.c +++ /dev/null | |||
@@ -1,174 +0,0 @@ | |||
1 | /* | ||
2 | * switch_class.c | ||
3 | * | ||
4 | * Copyright (C) 2008 Google, Inc. | ||
5 | * Author: Mike Lockwood <lockwood@android.com> | ||
6 | * | ||
7 | * This software is licensed under the terms of the GNU General Public | ||
8 | * License version 2, as published by the Free Software Foundation, and | ||
9 | * may be copied, distributed, and modified under those terms. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #include <linux/module.h> | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/device.h> | ||
22 | #include <linux/fs.h> | ||
23 | #include <linux/err.h> | ||
24 | #include "switch.h" | ||
25 | |||
26 | struct class *switch_class; | ||
27 | static atomic_t device_count; | ||
28 | |||
29 | static ssize_t state_show(struct device *dev, struct device_attribute *attr, | ||
30 | char *buf) | ||
31 | { | ||
32 | struct switch_dev *sdev = (struct switch_dev *) | ||
33 | dev_get_drvdata(dev); | ||
34 | |||
35 | if (sdev->print_state) { | ||
36 | int ret = sdev->print_state(sdev, buf); | ||
37 | if (ret >= 0) | ||
38 | return ret; | ||
39 | } | ||
40 | return sprintf(buf, "%d\n", sdev->state); | ||
41 | } | ||
42 | |||
43 | static ssize_t name_show(struct device *dev, struct device_attribute *attr, | ||
44 | char *buf) | ||
45 | { | ||
46 | struct switch_dev *sdev = (struct switch_dev *) | ||
47 | dev_get_drvdata(dev); | ||
48 | |||
49 | if (sdev->print_name) { | ||
50 | int ret = sdev->print_name(sdev, buf); | ||
51 | if (ret >= 0) | ||
52 | return ret; | ||
53 | } | ||
54 | return sprintf(buf, "%s\n", sdev->name); | ||
55 | } | ||
56 | |||
57 | static DEVICE_ATTR(state, S_IRUGO | S_IWUSR, state_show, NULL); | ||
58 | static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, name_show, NULL); | ||
59 | |||
60 | void switch_set_state(struct switch_dev *sdev, int state) | ||
61 | { | ||
62 | char name_buf[120]; | ||
63 | char state_buf[120]; | ||
64 | char *prop_buf; | ||
65 | char *envp[3]; | ||
66 | int env_offset = 0; | ||
67 | int length; | ||
68 | |||
69 | if (sdev->state != state) { | ||
70 | sdev->state = state; | ||
71 | |||
72 | prop_buf = (char *)get_zeroed_page(GFP_KERNEL); | ||
73 | if (prop_buf) { | ||
74 | length = name_show(sdev->dev, NULL, prop_buf); | ||
75 | if (length > 0) { | ||
76 | if (prop_buf[length - 1] == '\n') | ||
77 | prop_buf[length - 1] = 0; | ||
78 | snprintf(name_buf, sizeof(name_buf), | ||
79 | "SWITCH_NAME=%s", prop_buf); | ||
80 | envp[env_offset++] = name_buf; | ||
81 | } | ||
82 | length = state_show(sdev->dev, NULL, prop_buf); | ||
83 | if (length > 0) { | ||
84 | if (prop_buf[length - 1] == '\n') | ||
85 | prop_buf[length - 1] = 0; | ||
86 | snprintf(state_buf, sizeof(state_buf), | ||
87 | "SWITCH_STATE=%s", prop_buf); | ||
88 | envp[env_offset++] = state_buf; | ||
89 | } | ||
90 | envp[env_offset] = NULL; | ||
91 | kobject_uevent_env(&sdev->dev->kobj, KOBJ_CHANGE, envp); | ||
92 | free_page((unsigned long)prop_buf); | ||
93 | } else { | ||
94 | printk(KERN_ERR "out of memory in switch_set_state\n"); | ||
95 | kobject_uevent(&sdev->dev->kobj, KOBJ_CHANGE); | ||
96 | } | ||
97 | } | ||
98 | } | ||
99 | EXPORT_SYMBOL_GPL(switch_set_state); | ||
100 | |||
101 | static int create_switch_class(void) | ||
102 | { | ||
103 | if (!switch_class) { | ||
104 | switch_class = class_create(THIS_MODULE, "switch"); | ||
105 | if (IS_ERR(switch_class)) | ||
106 | return PTR_ERR(switch_class); | ||
107 | atomic_set(&device_count, 0); | ||
108 | } | ||
109 | |||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | int switch_dev_register(struct switch_dev *sdev) | ||
114 | { | ||
115 | int ret; | ||
116 | |||
117 | if (!switch_class) { | ||
118 | ret = create_switch_class(); | ||
119 | if (ret < 0) | ||
120 | return ret; | ||
121 | } | ||
122 | |||
123 | sdev->index = atomic_inc_return(&device_count); | ||
124 | sdev->dev = device_create(switch_class, NULL, | ||
125 | MKDEV(0, sdev->index), NULL, sdev->name); | ||
126 | if (IS_ERR(sdev->dev)) | ||
127 | return PTR_ERR(sdev->dev); | ||
128 | |||
129 | ret = device_create_file(sdev->dev, &dev_attr_state); | ||
130 | if (ret < 0) | ||
131 | goto err_create_file_1; | ||
132 | ret = device_create_file(sdev->dev, &dev_attr_name); | ||
133 | if (ret < 0) | ||
134 | goto err_create_file_2; | ||
135 | |||
136 | dev_set_drvdata(sdev->dev, sdev); | ||
137 | sdev->state = 0; | ||
138 | return 0; | ||
139 | |||
140 | err_create_file_2: | ||
141 | device_remove_file(sdev->dev, &dev_attr_state); | ||
142 | err_create_file_1: | ||
143 | device_destroy(switch_class, MKDEV(0, sdev->index)); | ||
144 | printk(KERN_ERR "switch: Failed to register driver %s\n", sdev->name); | ||
145 | |||
146 | return ret; | ||
147 | } | ||
148 | EXPORT_SYMBOL_GPL(switch_dev_register); | ||
149 | |||
150 | void switch_dev_unregister(struct switch_dev *sdev) | ||
151 | { | ||
152 | device_remove_file(sdev->dev, &dev_attr_name); | ||
153 | device_remove_file(sdev->dev, &dev_attr_state); | ||
154 | device_destroy(switch_class, MKDEV(0, sdev->index)); | ||
155 | dev_set_drvdata(sdev->dev, NULL); | ||
156 | } | ||
157 | EXPORT_SYMBOL_GPL(switch_dev_unregister); | ||
158 | |||
159 | static int __init switch_class_init(void) | ||
160 | { | ||
161 | return create_switch_class(); | ||
162 | } | ||
163 | |||
164 | static void __exit switch_class_exit(void) | ||
165 | { | ||
166 | class_destroy(switch_class); | ||
167 | } | ||
168 | |||
169 | module_init(switch_class_init); | ||
170 | module_exit(switch_class_exit); | ||
171 | |||
172 | MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>"); | ||
173 | MODULE_DESCRIPTION("Switch class driver"); | ||
174 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/staging/android/switch/switch_gpio.c b/drivers/staging/android/switch/switch_gpio.c deleted file mode 100644 index 38b2c2f6004e..000000000000 --- a/drivers/staging/android/switch/switch_gpio.c +++ /dev/null | |||
@@ -1,172 +0,0 @@ | |||
1 | /* | ||
2 | * switch_gpio.c | ||
3 | * | ||
4 | * Copyright (C) 2008 Google, Inc. | ||
5 | * Author: Mike Lockwood <lockwood@android.com> | ||
6 | * | ||
7 | * This software is licensed under the terms of the GNU General Public | ||
8 | * License version 2, as published by the Free Software Foundation, and | ||
9 | * may be copied, distributed, and modified under those terms. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #include <linux/module.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/workqueue.h> | ||
25 | #include <linux/gpio.h> | ||
26 | #include "switch.h" | ||
27 | |||
28 | struct gpio_switch_data { | ||
29 | struct switch_dev sdev; | ||
30 | unsigned gpio; | ||
31 | const char *name_on; | ||
32 | const char *name_off; | ||
33 | const char *state_on; | ||
34 | const char *state_off; | ||
35 | int irq; | ||
36 | struct work_struct work; | ||
37 | }; | ||
38 | |||
39 | static void gpio_switch_work(struct work_struct *work) | ||
40 | { | ||
41 | int state; | ||
42 | struct gpio_switch_data *data = | ||
43 | container_of(work, struct gpio_switch_data, work); | ||
44 | |||
45 | state = gpio_get_value(data->gpio); | ||
46 | switch_set_state(&data->sdev, state); | ||
47 | } | ||
48 | |||
49 | static irqreturn_t gpio_irq_handler(int irq, void *dev_id) | ||
50 | { | ||
51 | struct gpio_switch_data *switch_data = | ||
52 | (struct gpio_switch_data *)dev_id; | ||
53 | |||
54 | schedule_work(&switch_data->work); | ||
55 | return IRQ_HANDLED; | ||
56 | } | ||
57 | |||
58 | static ssize_t switch_gpio_print_state(struct switch_dev *sdev, char *buf) | ||
59 | { | ||
60 | struct gpio_switch_data *switch_data = | ||
61 | container_of(sdev, struct gpio_switch_data, sdev); | ||
62 | const char *state; | ||
63 | if (switch_get_state(sdev)) | ||
64 | state = switch_data->state_on; | ||
65 | else | ||
66 | state = switch_data->state_off; | ||
67 | |||
68 | if (state) | ||
69 | return sprintf(buf, "%s\n", state); | ||
70 | return -1; | ||
71 | } | ||
72 | |||
73 | static int gpio_switch_probe(struct platform_device *pdev) | ||
74 | { | ||
75 | struct gpio_switch_platform_data *pdata = pdev->dev.platform_data; | ||
76 | struct gpio_switch_data *switch_data; | ||
77 | int ret = 0; | ||
78 | |||
79 | if (!pdata) | ||
80 | return -EBUSY; | ||
81 | |||
82 | switch_data = kzalloc(sizeof(struct gpio_switch_data), GFP_KERNEL); | ||
83 | if (!switch_data) | ||
84 | return -ENOMEM; | ||
85 | |||
86 | switch_data->sdev.name = pdata->name; | ||
87 | switch_data->gpio = pdata->gpio; | ||
88 | switch_data->name_on = pdata->name_on; | ||
89 | switch_data->name_off = pdata->name_off; | ||
90 | switch_data->state_on = pdata->state_on; | ||
91 | switch_data->state_off = pdata->state_off; | ||
92 | switch_data->sdev.print_state = switch_gpio_print_state; | ||
93 | |||
94 | ret = switch_dev_register(&switch_data->sdev); | ||
95 | if (ret < 0) | ||
96 | goto err_switch_dev_register; | ||
97 | |||
98 | ret = gpio_request(switch_data->gpio, pdev->name); | ||
99 | if (ret < 0) | ||
100 | goto err_request_gpio; | ||
101 | |||
102 | ret = gpio_direction_input(switch_data->gpio); | ||
103 | if (ret < 0) | ||
104 | goto err_set_gpio_input; | ||
105 | |||
106 | INIT_WORK(&switch_data->work, gpio_switch_work); | ||
107 | |||
108 | switch_data->irq = gpio_to_irq(switch_data->gpio); | ||
109 | if (switch_data->irq < 0) { | ||
110 | ret = switch_data->irq; | ||
111 | goto err_detect_irq_num_failed; | ||
112 | } | ||
113 | |||
114 | ret = request_irq(switch_data->irq, gpio_irq_handler, | ||
115 | IRQF_TRIGGER_LOW, pdev->name, switch_data); | ||
116 | if (ret < 0) | ||
117 | goto err_request_irq; | ||
118 | |||
119 | /* Perform initial detection */ | ||
120 | gpio_switch_work(&switch_data->work); | ||
121 | |||
122 | return 0; | ||
123 | |||
124 | err_request_irq: | ||
125 | err_detect_irq_num_failed: | ||
126 | err_set_gpio_input: | ||
127 | gpio_free(switch_data->gpio); | ||
128 | err_request_gpio: | ||
129 | switch_dev_unregister(&switch_data->sdev); | ||
130 | err_switch_dev_register: | ||
131 | kfree(switch_data); | ||
132 | |||
133 | return ret; | ||
134 | } | ||
135 | |||
136 | static int __devexit gpio_switch_remove(struct platform_device *pdev) | ||
137 | { | ||
138 | struct gpio_switch_data *switch_data = platform_get_drvdata(pdev); | ||
139 | |||
140 | cancel_work_sync(&switch_data->work); | ||
141 | gpio_free(switch_data->gpio); | ||
142 | switch_dev_unregister(&switch_data->sdev); | ||
143 | kfree(switch_data); | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | static struct platform_driver gpio_switch_driver = { | ||
149 | .probe = gpio_switch_probe, | ||
150 | .remove = __devexit_p(gpio_switch_remove), | ||
151 | .driver = { | ||
152 | .name = "switch-gpio", | ||
153 | .owner = THIS_MODULE, | ||
154 | }, | ||
155 | }; | ||
156 | |||
157 | static int __init gpio_switch_init(void) | ||
158 | { | ||
159 | return platform_driver_register(&gpio_switch_driver); | ||
160 | } | ||
161 | |||
162 | static void __exit gpio_switch_exit(void) | ||
163 | { | ||
164 | platform_driver_unregister(&gpio_switch_driver); | ||
165 | } | ||
166 | |||
167 | module_init(gpio_switch_init); | ||
168 | module_exit(gpio_switch_exit); | ||
169 | |||
170 | MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>"); | ||
171 | MODULE_DESCRIPTION("GPIO Switch driver"); | ||
172 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c index b98371d93a92..42202cd83158 100644 --- a/drivers/uio/uio_pdrv_genirq.c +++ b/drivers/uio/uio_pdrv_genirq.c | |||
@@ -146,6 +146,14 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev) | |||
146 | priv->flags = 0; /* interrupt is enabled to begin with */ | 146 | priv->flags = 0; /* interrupt is enabled to begin with */ |
147 | priv->pdev = pdev; | 147 | priv->pdev = pdev; |
148 | 148 | ||
149 | if (!uioinfo->irq) { | ||
150 | ret = platform_get_irq(pdev, 0); | ||
151 | if (ret < 0) { | ||
152 | dev_err(&pdev->dev, "failed to get IRQ\n"); | ||
153 | goto bad0; | ||
154 | } | ||
155 | uioinfo->irq = ret; | ||
156 | } | ||
149 | uiomem = &uioinfo->mem[0]; | 157 | uiomem = &uioinfo->mem[0]; |
150 | 158 | ||
151 | for (i = 0; i < pdev->num_resources; ++i) { | 159 | for (i = 0; i < pdev->num_resources; ++i) { |
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 566d9f94f735..9a56e3adf476 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -73,7 +73,7 @@ set_bConfigurationValue(struct device *dev, struct device_attribute *attr, | |||
73 | return (value < 0) ? value : count; | 73 | return (value < 0) ? value : count; |
74 | } | 74 | } |
75 | 75 | ||
76 | static DEVICE_ATTR(bConfigurationValue, S_IRUGO | S_IWUSR, | 76 | static DEVICE_ATTR_IGNORE_LOCKDEP(bConfigurationValue, S_IRUGO | S_IWUSR, |
77 | show_bConfigurationValue, set_bConfigurationValue); | 77 | show_bConfigurationValue, set_bConfigurationValue); |
78 | 78 | ||
79 | /* String fields */ | 79 | /* String fields */ |
@@ -595,7 +595,7 @@ static ssize_t usb_dev_authorized_store(struct device *dev, | |||
595 | return result < 0? result : size; | 595 | return result < 0? result : size; |
596 | } | 596 | } |
597 | 597 | ||
598 | static DEVICE_ATTR(authorized, 0644, | 598 | static DEVICE_ATTR_IGNORE_LOCKDEP(authorized, 0644, |
599 | usb_dev_authorized_show, usb_dev_authorized_store); | 599 | usb_dev_authorized_show, usb_dev_authorized_store); |
600 | 600 | ||
601 | /* "Safely remove a device" */ | 601 | /* "Safely remove a device" */ |
@@ -618,7 +618,7 @@ static ssize_t usb_remove_store(struct device *dev, | |||
618 | usb_unlock_device(udev); | 618 | usb_unlock_device(udev); |
619 | return rc; | 619 | return rc; |
620 | } | 620 | } |
621 | static DEVICE_ATTR(remove, 0200, NULL, usb_remove_store); | 621 | static DEVICE_ATTR_IGNORE_LOCKDEP(remove, 0200, NULL, usb_remove_store); |
622 | 622 | ||
623 | 623 | ||
624 | static struct attribute *dev_attrs[] = { | 624 | static struct attribute *dev_attrs[] = { |
diff --git a/drivers/w1/slaves/w1_ds2408.c b/drivers/w1/slaves/w1_ds2408.c index 7c8cdb8aed26..8e813eed0f0a 100644 --- a/drivers/w1/slaves/w1_ds2408.c +++ b/drivers/w1/slaves/w1_ds2408.c | |||
@@ -332,7 +332,6 @@ static struct bin_attribute w1_f29_sysfs_bin_files[NB_SYSFS_BIN_FILES] = { | |||
332 | }, | 332 | }, |
333 | .size = 1, | 333 | .size = 1, |
334 | .read = w1_f29_read_cond_search_mask, | 334 | .read = w1_f29_read_cond_search_mask, |
335 | .write = 0, | ||
336 | }, | 335 | }, |
337 | { | 336 | { |
338 | .attr = { | 337 | .attr = { |
@@ -341,7 +340,6 @@ static struct bin_attribute w1_f29_sysfs_bin_files[NB_SYSFS_BIN_FILES] = { | |||
341 | }, | 340 | }, |
342 | .size = 1, | 341 | .size = 1, |
343 | .read = w1_f29_read_cond_search_polarity, | 342 | .read = w1_f29_read_cond_search_polarity, |
344 | .write = 0, | ||
345 | }, | 343 | }, |
346 | { | 344 | { |
347 | .attr = { | 345 | .attr = { |
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 9761950697b4..2f2e894ea0c8 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c | |||
@@ -1027,7 +1027,7 @@ static int __init w1_init(void) | |||
1027 | retval = driver_register(&w1_slave_driver); | 1027 | retval = driver_register(&w1_slave_driver); |
1028 | if (retval) { | 1028 | if (retval) { |
1029 | printk(KERN_ERR | 1029 | printk(KERN_ERR |
1030 | "Failed to register master driver. err=%d.\n", | 1030 | "Failed to register slave driver. err=%d.\n", |
1031 | retval); | 1031 | retval); |
1032 | goto err_out_master_unregister; | 1032 | goto err_out_master_unregister; |
1033 | } | 1033 | } |
diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c index 3135b2c63998..e10acc237733 100644 --- a/drivers/w1/w1_io.c +++ b/drivers/w1/w1_io.c | |||
@@ -31,6 +31,9 @@ | |||
31 | static int w1_delay_parm = 1; | 31 | static int w1_delay_parm = 1; |
32 | module_param_named(delay_coef, w1_delay_parm, int, 0); | 32 | module_param_named(delay_coef, w1_delay_parm, int, 0); |
33 | 33 | ||
34 | static int w1_disable_irqs = 0; | ||
35 | module_param_named(disable_irqs, w1_disable_irqs, int, 0); | ||
36 | |||
34 | static u8 w1_crc8_table[] = { | 37 | static u8 w1_crc8_table[] = { |
35 | 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, | 38 | 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, |
36 | 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, | 39 | 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, |
@@ -79,6 +82,10 @@ static u8 w1_touch_bit(struct w1_master *dev, int bit) | |||
79 | */ | 82 | */ |
80 | static void w1_write_bit(struct w1_master *dev, int bit) | 83 | static void w1_write_bit(struct w1_master *dev, int bit) |
81 | { | 84 | { |
85 | unsigned long flags = 0; | ||
86 | |||
87 | if(w1_disable_irqs) local_irq_save(flags); | ||
88 | |||
82 | if (bit) { | 89 | if (bit) { |
83 | dev->bus_master->write_bit(dev->bus_master->data, 0); | 90 | dev->bus_master->write_bit(dev->bus_master->data, 0); |
84 | w1_delay(6); | 91 | w1_delay(6); |
@@ -90,6 +97,8 @@ static void w1_write_bit(struct w1_master *dev, int bit) | |||
90 | dev->bus_master->write_bit(dev->bus_master->data, 1); | 97 | dev->bus_master->write_bit(dev->bus_master->data, 1); |
91 | w1_delay(10); | 98 | w1_delay(10); |
92 | } | 99 | } |
100 | |||
101 | if(w1_disable_irqs) local_irq_restore(flags); | ||
93 | } | 102 | } |
94 | 103 | ||
95 | /** | 104 | /** |
@@ -158,7 +167,7 @@ EXPORT_SYMBOL_GPL(w1_write_8); | |||
158 | static u8 w1_read_bit(struct w1_master *dev) | 167 | static u8 w1_read_bit(struct w1_master *dev) |
159 | { | 168 | { |
160 | int result; | 169 | int result; |
161 | unsigned long flags; | 170 | unsigned long flags = 0; |
162 | 171 | ||
163 | /* sample timing is critical here */ | 172 | /* sample timing is critical here */ |
164 | local_irq_save(flags); | 173 | local_irq_save(flags); |
@@ -318,6 +327,9 @@ EXPORT_SYMBOL_GPL(w1_read_block); | |||
318 | int w1_reset_bus(struct w1_master *dev) | 327 | int w1_reset_bus(struct w1_master *dev) |
319 | { | 328 | { |
320 | int result; | 329 | int result; |
330 | unsigned long flags = 0; | ||
331 | |||
332 | if(w1_disable_irqs) local_irq_save(flags); | ||
321 | 333 | ||
322 | if (dev->bus_master->reset_bus) | 334 | if (dev->bus_master->reset_bus) |
323 | result = dev->bus_master->reset_bus(dev->bus_master->data) & 0x1; | 335 | result = dev->bus_master->reset_bus(dev->bus_master->data) & 0x1; |
@@ -330,19 +342,21 @@ int w1_reset_bus(struct w1_master *dev) | |||
330 | * cpu for such a short amount of time AND get it back in | 342 | * cpu for such a short amount of time AND get it back in |
331 | * the maximum amount of time. | 343 | * the maximum amount of time. |
332 | */ | 344 | */ |
333 | w1_delay(480); | 345 | w1_delay(500); |
334 | dev->bus_master->write_bit(dev->bus_master->data, 1); | 346 | dev->bus_master->write_bit(dev->bus_master->data, 1); |
335 | w1_delay(70); | 347 | w1_delay(70); |
336 | 348 | ||
337 | result = dev->bus_master->read_bit(dev->bus_master->data) & 0x1; | 349 | result = dev->bus_master->read_bit(dev->bus_master->data) & 0x1; |
338 | /* minmum 70 (above) + 410 = 480 us | 350 | /* minmum 70 (above) + 430 = 500 us |
339 | * There aren't any timing requirements between a reset and | 351 | * There aren't any timing requirements between a reset and |
340 | * the following transactions. Sleeping is safe here. | 352 | * the following transactions. Sleeping is safe here. |
341 | */ | 353 | */ |
342 | /* w1_delay(410); min required time */ | 354 | /* w1_delay(430); min required time */ |
343 | msleep(1); | 355 | msleep(1); |
344 | } | 356 | } |
345 | 357 | ||
358 | if(w1_disable_irqs) local_irq_restore(flags); | ||
359 | |||
346 | return result; | 360 | return result; |
347 | } | 361 | } |
348 | EXPORT_SYMBOL_GPL(w1_reset_bus); | 362 | EXPORT_SYMBOL_GPL(w1_reset_bus); |
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 35a36d39fa2c..e6bb9b2a4cbe 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -132,6 +132,24 @@ static void sysfs_unlink_sibling(struct sysfs_dirent *sd) | |||
132 | rb_erase(&sd->s_rb, &sd->s_parent->s_dir.children); | 132 | rb_erase(&sd->s_rb, &sd->s_parent->s_dir.children); |
133 | } | 133 | } |
134 | 134 | ||
135 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
136 | |||
137 | /* Test for attributes that want to ignore lockdep for read-locking */ | ||
138 | static bool ignore_lockdep(struct sysfs_dirent *sd) | ||
139 | { | ||
140 | return sysfs_type(sd) == SYSFS_KOBJ_ATTR && | ||
141 | sd->s_attr.attr->ignore_lockdep; | ||
142 | } | ||
143 | |||
144 | #else | ||
145 | |||
146 | static inline bool ignore_lockdep(struct sysfs_dirent *sd) | ||
147 | { | ||
148 | return true; | ||
149 | } | ||
150 | |||
151 | #endif | ||
152 | |||
135 | /** | 153 | /** |
136 | * sysfs_get_active - get an active reference to sysfs_dirent | 154 | * sysfs_get_active - get an active reference to sysfs_dirent |
137 | * @sd: sysfs_dirent to get an active reference to | 155 | * @sd: sysfs_dirent to get an active reference to |
@@ -155,15 +173,17 @@ struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd) | |||
155 | return NULL; | 173 | return NULL; |
156 | 174 | ||
157 | t = atomic_cmpxchg(&sd->s_active, v, v + 1); | 175 | t = atomic_cmpxchg(&sd->s_active, v, v + 1); |
158 | if (likely(t == v)) { | 176 | if (likely(t == v)) |
159 | rwsem_acquire_read(&sd->dep_map, 0, 1, _RET_IP_); | 177 | break; |
160 | return sd; | ||
161 | } | ||
162 | if (t < 0) | 178 | if (t < 0) |
163 | return NULL; | 179 | return NULL; |
164 | 180 | ||
165 | cpu_relax(); | 181 | cpu_relax(); |
166 | } | 182 | } |
183 | |||
184 | if (likely(!ignore_lockdep(sd))) | ||
185 | rwsem_acquire_read(&sd->dep_map, 0, 1, _RET_IP_); | ||
186 | return sd; | ||
167 | } | 187 | } |
168 | 188 | ||
169 | /** | 189 | /** |
@@ -180,7 +200,8 @@ void sysfs_put_active(struct sysfs_dirent *sd) | |||
180 | if (unlikely(!sd)) | 200 | if (unlikely(!sd)) |
181 | return; | 201 | return; |
182 | 202 | ||
183 | rwsem_release(&sd->dep_map, 1, _RET_IP_); | 203 | if (likely(!ignore_lockdep(sd))) |
204 | rwsem_release(&sd->dep_map, 1, _RET_IP_); | ||
184 | v = atomic_dec_return(&sd->s_active); | 205 | v = atomic_dec_return(&sd->s_active); |
185 | if (likely(v != SD_DEACTIVATED_BIAS)) | 206 | if (likely(v != SD_DEACTIVATED_BIAS)) |
186 | return; | 207 | return; |
@@ -858,7 +879,6 @@ int sysfs_rename(struct sysfs_dirent *sd, | |||
858 | struct sysfs_dirent *new_parent_sd, const void *new_ns, | 879 | struct sysfs_dirent *new_parent_sd, const void *new_ns, |
859 | const char *new_name) | 880 | const char *new_name) |
860 | { | 881 | { |
861 | const char *dup_name = NULL; | ||
862 | int error; | 882 | int error; |
863 | 883 | ||
864 | mutex_lock(&sysfs_mutex); | 884 | mutex_lock(&sysfs_mutex); |
@@ -875,11 +895,11 @@ int sysfs_rename(struct sysfs_dirent *sd, | |||
875 | /* rename sysfs_dirent */ | 895 | /* rename sysfs_dirent */ |
876 | if (strcmp(sd->s_name, new_name) != 0) { | 896 | if (strcmp(sd->s_name, new_name) != 0) { |
877 | error = -ENOMEM; | 897 | error = -ENOMEM; |
878 | new_name = dup_name = kstrdup(new_name, GFP_KERNEL); | 898 | new_name = kstrdup(new_name, GFP_KERNEL); |
879 | if (!new_name) | 899 | if (!new_name) |
880 | goto out; | 900 | goto out; |
881 | 901 | ||
882 | dup_name = sd->s_name; | 902 | kfree(sd->s_name); |
883 | sd->s_name = new_name; | 903 | sd->s_name = new_name; |
884 | } | 904 | } |
885 | 905 | ||
@@ -895,7 +915,6 @@ int sysfs_rename(struct sysfs_dirent *sd, | |||
895 | error = 0; | 915 | error = 0; |
896 | out: | 916 | out: |
897 | mutex_unlock(&sysfs_mutex); | 917 | mutex_unlock(&sysfs_mutex); |
898 | kfree(dup_name); | ||
899 | return error; | 918 | return error; |
900 | } | 919 | } |
901 | 920 | ||
diff --git a/include/linux/device.h b/include/linux/device.h index 5ad17cccdd71..e04f5776f6d0 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
24 | #include <linux/pm.h> | 24 | #include <linux/pm.h> |
25 | #include <linux/atomic.h> | 25 | #include <linux/atomic.h> |
26 | #include <linux/ratelimit.h> | ||
26 | #include <asm/device.h> | 27 | #include <asm/device.h> |
27 | 28 | ||
28 | struct device; | 29 | struct device; |
@@ -502,7 +503,10 @@ ssize_t device_store_int(struct device *dev, struct device_attribute *attr, | |||
502 | { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) } | 503 | { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) } |
503 | #define DEVICE_INT_ATTR(_name, _mode, _var) \ | 504 | #define DEVICE_INT_ATTR(_name, _mode, _var) \ |
504 | struct dev_ext_attribute dev_attr_##_name = \ | 505 | struct dev_ext_attribute dev_attr_##_name = \ |
505 | { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) } | 506 | { __ATTR(_name, _mode, device_show_int, device_store_int), &(_var) } |
507 | #define DEVICE_ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) \ | ||
508 | struct device_attribute dev_attr_##_name = \ | ||
509 | __ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) | ||
506 | 510 | ||
507 | extern int device_create_file(struct device *device, | 511 | extern int device_create_file(struct device *device, |
508 | const struct device_attribute *entry); | 512 | const struct device_attribute *entry); |
@@ -541,6 +545,8 @@ extern void *devres_remove(struct device *dev, dr_release_t release, | |||
541 | dr_match_t match, void *match_data); | 545 | dr_match_t match, void *match_data); |
542 | extern int devres_destroy(struct device *dev, dr_release_t release, | 546 | extern int devres_destroy(struct device *dev, dr_release_t release, |
543 | dr_match_t match, void *match_data); | 547 | dr_match_t match, void *match_data); |
548 | extern int devres_release(struct device *dev, dr_release_t release, | ||
549 | dr_match_t match, void *match_data); | ||
544 | 550 | ||
545 | /* devres group */ | 551 | /* devres group */ |
546 | extern void * __must_check devres_open_group(struct device *dev, void *id, | 552 | extern void * __must_check devres_open_group(struct device *dev, void *id, |
@@ -931,6 +937,32 @@ int _dev_info(const struct device *dev, const char *fmt, ...) | |||
931 | 937 | ||
932 | #endif | 938 | #endif |
933 | 939 | ||
940 | #define dev_level_ratelimited(dev_level, dev, fmt, ...) \ | ||
941 | do { \ | ||
942 | static DEFINE_RATELIMIT_STATE(_rs, \ | ||
943 | DEFAULT_RATELIMIT_INTERVAL, \ | ||
944 | DEFAULT_RATELIMIT_BURST); \ | ||
945 | if (__ratelimit(&_rs)) \ | ||
946 | dev_level(dev, fmt, ##__VA_ARGS__); \ | ||
947 | } while (0) | ||
948 | |||
949 | #define dev_emerg_ratelimited(dev, fmt, ...) \ | ||
950 | dev_level_ratelimited(dev_emerg, dev, fmt, ##__VA_ARGS__) | ||
951 | #define dev_alert_ratelimited(dev, fmt, ...) \ | ||
952 | dev_level_ratelimited(dev_alert, dev, fmt, ##__VA_ARGS__) | ||
953 | #define dev_crit_ratelimited(dev, fmt, ...) \ | ||
954 | dev_level_ratelimited(dev_crit, dev, fmt, ##__VA_ARGS__) | ||
955 | #define dev_err_ratelimited(dev, fmt, ...) \ | ||
956 | dev_level_ratelimited(dev_err, dev, fmt, ##__VA_ARGS__) | ||
957 | #define dev_warn_ratelimited(dev, fmt, ...) \ | ||
958 | dev_level_ratelimited(dev_warn, dev, fmt, ##__VA_ARGS__) | ||
959 | #define dev_notice_ratelimited(dev, fmt, ...) \ | ||
960 | dev_level_ratelimited(dev_notice, dev, fmt, ##__VA_ARGS__) | ||
961 | #define dev_info_ratelimited(dev, fmt, ...) \ | ||
962 | dev_level_ratelimited(dev_info, dev, fmt, ##__VA_ARGS__) | ||
963 | #define dev_dbg_ratelimited(dev, fmt, ...) \ | ||
964 | dev_level_ratelimited(dev_dbg, dev, fmt, ##__VA_ARGS__) | ||
965 | |||
934 | /* | 966 | /* |
935 | * Stupid hackaround for existing uses of non-printk uses dev_info | 967 | * Stupid hackaround for existing uses of non-printk uses dev_info |
936 | * | 968 | * |
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index 7e3c53a900d8..c18257b0fa72 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h | |||
@@ -17,8 +17,8 @@ struct _ddebug { | |||
17 | const char *format; | 17 | const char *format; |
18 | unsigned int lineno:18; | 18 | unsigned int lineno:18; |
19 | /* | 19 | /* |
20 | * The flags field controls the behaviour at the callsite. | 20 | * The flags field controls the behaviour at the callsite. |
21 | * The bits here are changed dynamically when the user | 21 | * The bits here are changed dynamically when the user |
22 | * writes commands to <debugfs>/dynamic_debug/control | 22 | * writes commands to <debugfs>/dynamic_debug/control |
23 | */ | 23 | */ |
24 | #define _DPRINTK_FLAGS_NONE 0 | 24 | #define _DPRINTK_FLAGS_NONE 0 |
@@ -44,6 +44,9 @@ extern int ddebug_remove_module(const char *mod_name); | |||
44 | extern __printf(2, 3) | 44 | extern __printf(2, 3) |
45 | int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...); | 45 | int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...); |
46 | 46 | ||
47 | extern int ddebug_dyndbg_module_param_cb(char *param, char *val, | ||
48 | const char *modname); | ||
49 | |||
47 | struct device; | 50 | struct device; |
48 | 51 | ||
49 | extern __printf(3, 4) | 52 | extern __printf(3, 4) |
@@ -94,11 +97,26 @@ do { \ | |||
94 | 97 | ||
95 | #else | 98 | #else |
96 | 99 | ||
100 | #include <linux/string.h> | ||
101 | #include <linux/errno.h> | ||
102 | |||
97 | static inline int ddebug_remove_module(const char *mod) | 103 | static inline int ddebug_remove_module(const char *mod) |
98 | { | 104 | { |
99 | return 0; | 105 | return 0; |
100 | } | 106 | } |
101 | 107 | ||
108 | static inline int ddebug_dyndbg_module_param_cb(char *param, char *val, | ||
109 | const char *modname) | ||
110 | { | ||
111 | if (strstr(param, "dyndbg")) { | ||
112 | /* avoid pr_warn(), which wants pr_fmt() fully defined */ | ||
113 | printk(KERN_WARNING "dyndbg param is supported only in " | ||
114 | "CONFIG_DYNAMIC_DEBUG builds\n"); | ||
115 | return 0; /* allow and ignore */ | ||
116 | } | ||
117 | return -EINVAL; | ||
118 | } | ||
119 | |||
102 | #define dynamic_pr_debug(fmt, ...) \ | 120 | #define dynamic_pr_debug(fmt, ...) \ |
103 | do { if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); } while (0) | 121 | do { if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); } while (0) |
104 | #define dynamic_dev_dbg(dev, fmt, ...) \ | 122 | #define dynamic_dev_dbg(dev, fmt, ...) \ |
diff --git a/include/linux/extcon.h b/include/linux/extcon.h new file mode 100644 index 000000000000..cdd401477656 --- /dev/null +++ b/include/linux/extcon.h | |||
@@ -0,0 +1,324 @@ | |||
1 | /* | ||
2 | * External connector (extcon) class driver | ||
3 | * | ||
4 | * Copyright (C) 2012 Samsung Electronics | ||
5 | * Author: Donggeun Kim <dg77.kim@samsung.com> | ||
6 | * Author: MyungJoo Ham <myungjoo.ham@samsung.com> | ||
7 | * | ||
8 | * based on switch class driver | ||
9 | * Copyright (C) 2008 Google, Inc. | ||
10 | * Author: Mike Lockwood <lockwood@android.com> | ||
11 | * | ||
12 | * This software is licensed under the terms of the GNU General Public | ||
13 | * License version 2, as published by the Free Software Foundation, and | ||
14 | * may be copied, distributed, and modified under those terms. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #ifndef __LINUX_EXTCON_H__ | ||
24 | #define __LINUX_EXTCON_H__ | ||
25 | |||
26 | #include <linux/notifier.h> | ||
27 | |||
28 | #define SUPPORTED_CABLE_MAX 32 | ||
29 | #define CABLE_NAME_MAX 30 | ||
30 | |||
31 | /* | ||
32 | * The standard cable name is to help support general notifier | ||
33 | * and notifee device drivers to share the common names. | ||
34 | * Please use standard cable names unless your notifier device has | ||
35 | * a very unique and abnormal cable or | ||
36 | * the cable type is supposed to be used with only one unique | ||
37 | * pair of notifier/notifee devices. | ||
38 | * | ||
39 | * Please add any other "standard" cables used with extcon dev. | ||
40 | * | ||
41 | * You may add a dot and number to specify version or specification | ||
42 | * of the specific cable if it is required. (e.g., "Fast-charger.18" | ||
43 | * and "Fast-charger.10" for 1.8A and 1.0A chargers) | ||
44 | * However, the notifee and notifier should be able to handle such | ||
45 | * string and if the notifee can negotiate the protocol or idenify, | ||
46 | * you don't need such convention. This convention is helpful when | ||
47 | * notifier can distinguish but notifiee cannot. | ||
48 | */ | ||
49 | enum extcon_cable_name { | ||
50 | EXTCON_USB = 0, | ||
51 | EXTCON_USB_HOST, | ||
52 | EXTCON_TA, /* Travel Adaptor */ | ||
53 | EXTCON_FAST_CHARGER, | ||
54 | EXTCON_SLOW_CHARGER, | ||
55 | EXTCON_CHARGE_DOWNSTREAM, /* Charging an external device */ | ||
56 | EXTCON_HDMI, | ||
57 | EXTCON_MHL, | ||
58 | EXTCON_DVI, | ||
59 | EXTCON_VGA, | ||
60 | EXTCON_DOCK, | ||
61 | EXTCON_LINE_IN, | ||
62 | EXTCON_LINE_OUT, | ||
63 | EXTCON_MIC_IN, | ||
64 | EXTCON_HEADPHONE_OUT, | ||
65 | EXTCON_SPDIF_IN, | ||
66 | EXTCON_SPDIF_OUT, | ||
67 | EXTCON_VIDEO_IN, | ||
68 | EXTCON_VIDEO_OUT, | ||
69 | EXTCON_MECHANICAL, | ||
70 | }; | ||
71 | extern const char *extcon_cable_name[]; | ||
72 | |||
73 | struct extcon_cable; | ||
74 | |||
75 | /** | ||
76 | * struct extcon_dev - An extcon device represents one external connector. | ||
77 | * @name The name of this extcon device. Parent device name is used | ||
78 | * if NULL. | ||
79 | * @supported_cable Array of supported cable name ending with NULL. | ||
80 | * If supported_cable is NULL, cable name related APIs | ||
81 | * are disabled. | ||
82 | * @mutually_exclusive Array of mutually exclusive set of cables that cannot | ||
83 | * be attached simultaneously. The array should be | ||
84 | * ending with NULL or be NULL (no mutually exclusive | ||
85 | * cables). For example, if it is { 0x7, 0x30, 0}, then, | ||
86 | * {0, 1}, {0, 1, 2}, {0, 2}, {1, 2}, or {4, 5} cannot | ||
87 | * be attached simulataneously. {0x7, 0} is equivalent to | ||
88 | * {0x3, 0x6, 0x5, 0}. If it is {0xFFFFFFFF, 0}, there | ||
89 | * can be no simultaneous connections. | ||
90 | * @print_name An optional callback to override the method to print the | ||
91 | * name of the extcon device. | ||
92 | * @print_state An optional callback to override the method to print the | ||
93 | * status of the extcon device. | ||
94 | * @dev Device of this extcon. Do not provide at register-time. | ||
95 | * @state Attach/detach state of this extcon. Do not provide at | ||
96 | * register-time | ||
97 | * @nh Notifier for the state change events from this extcon | ||
98 | * @entry To support list of extcon devices so that uses can search | ||
99 | * for extcon devices based on the extcon name. | ||
100 | * @lock | ||
101 | * @max_supported Internal value to store the number of cables. | ||
102 | * @extcon_dev_type Device_type struct to provide attribute_groups | ||
103 | * customized for each extcon device. | ||
104 | * @cables Sysfs subdirectories. Each represents one cable. | ||
105 | * | ||
106 | * In most cases, users only need to provide "User initializing data" of | ||
107 | * this struct when registering an extcon. In some exceptional cases, | ||
108 | * optional callbacks may be needed. However, the values in "internal data" | ||
109 | * are overwritten by register function. | ||
110 | */ | ||
111 | struct extcon_dev { | ||
112 | /* --- Optional user initializing data --- */ | ||
113 | const char *name; | ||
114 | const char **supported_cable; | ||
115 | const u32 *mutually_exclusive; | ||
116 | |||
117 | /* --- Optional callbacks to override class functions --- */ | ||
118 | ssize_t (*print_name)(struct extcon_dev *edev, char *buf); | ||
119 | ssize_t (*print_state)(struct extcon_dev *edev, char *buf); | ||
120 | |||
121 | /* --- Internal data. Please do not set. --- */ | ||
122 | struct device *dev; | ||
123 | u32 state; | ||
124 | struct raw_notifier_head nh; | ||
125 | struct list_head entry; | ||
126 | spinlock_t lock; /* could be called by irq handler */ | ||
127 | int max_supported; | ||
128 | |||
129 | /* /sys/class/extcon/.../cable.n/... */ | ||
130 | struct device_type extcon_dev_type; | ||
131 | struct extcon_cable *cables; | ||
132 | /* /sys/class/extcon/.../mutually_exclusive/... */ | ||
133 | struct attribute_group attr_g_muex; | ||
134 | struct attribute **attrs_muex; | ||
135 | struct device_attribute *d_attrs_muex; | ||
136 | }; | ||
137 | |||
138 | /** | ||
139 | * struct extcon_cable - An internal data for each cable of extcon device. | ||
140 | * @edev The extcon device | ||
141 | * @cable_index Index of this cable in the edev | ||
142 | * @attr_g Attribute group for the cable | ||
143 | * @attr_name "name" sysfs entry | ||
144 | * @attr_state "state" sysfs entry | ||
145 | * @attrs Array pointing to attr_name and attr_state for attr_g | ||
146 | */ | ||
147 | struct extcon_cable { | ||
148 | struct extcon_dev *edev; | ||
149 | int cable_index; | ||
150 | |||
151 | struct attribute_group attr_g; | ||
152 | struct device_attribute attr_name; | ||
153 | struct device_attribute attr_state; | ||
154 | |||
155 | struct attribute *attrs[3]; /* to be fed to attr_g.attrs */ | ||
156 | }; | ||
157 | |||
158 | /** | ||
159 | * struct extcon_specific_cable_nb - An internal data for | ||
160 | * extcon_register_interest(). | ||
161 | * @internal_nb a notifier block bridging extcon notifier and cable notifier. | ||
162 | * @user_nb user provided notifier block for events from a specific cable. | ||
163 | * @cable_index the target cable. | ||
164 | * @edev the target extcon device. | ||
165 | * @previous_value the saved previous event value. | ||
166 | */ | ||
167 | struct extcon_specific_cable_nb { | ||
168 | struct notifier_block internal_nb; | ||
169 | struct notifier_block *user_nb; | ||
170 | int cable_index; | ||
171 | struct extcon_dev *edev; | ||
172 | unsigned long previous_value; | ||
173 | }; | ||
174 | |||
175 | #if IS_ENABLED(CONFIG_EXTCON) | ||
176 | |||
177 | /* | ||
178 | * Following APIs are for notifiers or configurations. | ||
179 | * Notifiers are the external port and connection devices. | ||
180 | */ | ||
181 | extern int extcon_dev_register(struct extcon_dev *edev, struct device *dev); | ||
182 | extern void extcon_dev_unregister(struct extcon_dev *edev); | ||
183 | extern struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name); | ||
184 | |||
185 | /* | ||
186 | * get/set/update_state access the 32b encoded state value, which represents | ||
187 | * states of all possible cables of the multistate port. For example, if one | ||
188 | * calls extcon_set_state(edev, 0x7), it may mean that all the three cables | ||
189 | * are attached to the port. | ||
190 | */ | ||
191 | static inline u32 extcon_get_state(struct extcon_dev *edev) | ||
192 | { | ||
193 | return edev->state; | ||
194 | } | ||
195 | |||
196 | extern int extcon_set_state(struct extcon_dev *edev, u32 state); | ||
197 | extern int extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state); | ||
198 | |||
199 | /* | ||
200 | * get/set_cable_state access each bit of the 32b encoded state value. | ||
201 | * They are used to access the status of each cable based on the cable_name | ||
202 | * or cable_index, which is retrived by extcon_find_cable_index | ||
203 | */ | ||
204 | extern int extcon_find_cable_index(struct extcon_dev *sdev, | ||
205 | const char *cable_name); | ||
206 | extern int extcon_get_cable_state_(struct extcon_dev *edev, int cable_index); | ||
207 | extern int extcon_set_cable_state_(struct extcon_dev *edev, int cable_index, | ||
208 | bool cable_state); | ||
209 | |||
210 | extern int extcon_get_cable_state(struct extcon_dev *edev, | ||
211 | const char *cable_name); | ||
212 | extern int extcon_set_cable_state(struct extcon_dev *edev, | ||
213 | const char *cable_name, bool cable_state); | ||
214 | |||
215 | /* | ||
216 | * Following APIs are for notifiees (those who want to be notified) | ||
217 | * to register a callback for events from a specific cable of the extcon. | ||
218 | * Notifiees are the connected device drivers wanting to get notified by | ||
219 | * a specific external port of a connection device. | ||
220 | */ | ||
221 | extern int extcon_register_interest(struct extcon_specific_cable_nb *obj, | ||
222 | const char *extcon_name, | ||
223 | const char *cable_name, | ||
224 | struct notifier_block *nb); | ||
225 | extern int extcon_unregister_interest(struct extcon_specific_cable_nb *nb); | ||
226 | |||
227 | /* | ||
228 | * Following APIs are to monitor every action of a notifier. | ||
229 | * Registerer gets notified for every external port of a connection device. | ||
230 | * Probably this could be used to debug an action of notifier; however, | ||
231 | * we do not recommend to use this at normal 'notifiee' device drivers who | ||
232 | * want to be notified by a specific external port of the notifier. | ||
233 | */ | ||
234 | extern int extcon_register_notifier(struct extcon_dev *edev, | ||
235 | struct notifier_block *nb); | ||
236 | extern int extcon_unregister_notifier(struct extcon_dev *edev, | ||
237 | struct notifier_block *nb); | ||
238 | #else /* CONFIG_EXTCON */ | ||
239 | static inline int extcon_dev_register(struct extcon_dev *edev, | ||
240 | struct device *dev) | ||
241 | { | ||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | static inline void extcon_dev_unregister(struct extcon_dev *edev) { } | ||
246 | |||
247 | static inline u32 extcon_get_state(struct extcon_dev *edev) | ||
248 | { | ||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | static inline int extcon_set_state(struct extcon_dev *edev, u32 state) | ||
253 | { | ||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | static inline int extcon_update_state(struct extcon_dev *edev, u32 mask, | ||
258 | u32 state) | ||
259 | { | ||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | static inline int extcon_find_cable_index(struct extcon_dev *edev, | ||
264 | const char *cable_name) | ||
265 | { | ||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | static inline int extcon_get_cable_state_(struct extcon_dev *edev, | ||
270 | int cable_index) | ||
271 | { | ||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | static inline int extcon_set_cable_state_(struct extcon_dev *edev, | ||
276 | int cable_index, bool cable_state) | ||
277 | { | ||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | static inline int extcon_get_cable_state(struct extcon_dev *edev, | ||
282 | const char *cable_name) | ||
283 | { | ||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | static inline int extcon_set_cable_state(struct extcon_dev *edev, | ||
288 | const char *cable_name, int state) | ||
289 | { | ||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | static inline struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name) | ||
294 | { | ||
295 | return NULL; | ||
296 | } | ||
297 | |||
298 | static inline int extcon_register_notifier(struct extcon_dev *edev, | ||
299 | struct notifier_block *nb) | ||
300 | { | ||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | static inline int extcon_unregister_notifier(struct extcon_dev *edev, | ||
305 | struct notifier_block *nb) | ||
306 | { | ||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | static inline int extcon_register_interest(struct extcon_specific_cable_nb *obj, | ||
311 | const char *extcon_name, | ||
312 | const char *cable_name, | ||
313 | struct notifier_block *nb) | ||
314 | { | ||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | static inline int extcon_unregister_interest(struct extcon_specific_cable_nb | ||
319 | *obj) | ||
320 | { | ||
321 | return 0; | ||
322 | } | ||
323 | #endif /* CONFIG_EXTCON */ | ||
324 | #endif /* __LINUX_EXTCON_H__ */ | ||
diff --git a/include/linux/extcon/extcon_gpio.h b/include/linux/extcon/extcon_gpio.h new file mode 100644 index 000000000000..a2129b73dcb1 --- /dev/null +++ b/include/linux/extcon/extcon_gpio.h | |||
@@ -0,0 +1,52 @@ | |||
1 | /* | ||
2 | * External connector (extcon) class generic GPIO driver | ||
3 | * | ||
4 | * Copyright (C) 2012 Samsung Electronics | ||
5 | * Author: MyungJoo Ham <myungjoo.ham@samsung.com> | ||
6 | * | ||
7 | * based on switch class driver | ||
8 | * Copyright (C) 2008 Google, Inc. | ||
9 | * Author: Mike Lockwood <lockwood@android.com> | ||
10 | * | ||
11 | * This software is licensed under the terms of the GNU General Public | ||
12 | * License version 2, as published by the Free Software Foundation, and | ||
13 | * may be copied, distributed, and modified under those terms. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | */ | ||
21 | #ifndef __EXTCON_GPIO_H__ | ||
22 | #define __EXTCON_GPIO_H__ __FILE__ | ||
23 | |||
24 | #include <linux/extcon.h> | ||
25 | |||
26 | /** | ||
27 | * struct gpio_extcon_platform_data - A simple GPIO-controlled extcon device. | ||
28 | * @name The name of this GPIO extcon device. | ||
29 | * @gpio Corresponding GPIO. | ||
30 | * @debounce Debounce time for GPIO IRQ in ms. | ||
31 | * @irq_flags IRQ Flags (e.g., IRQF_TRIGGER_LOW). | ||
32 | * @state_on print_state is overriden with state_on if attached. If Null, | ||
33 | * default method of extcon class is used. | ||
34 | * @state_off print_state is overriden with state_on if dettached. If Null, | ||
35 | * default method of extcon class is used. | ||
36 | * | ||
37 | * Note that in order for state_on or state_off to be valid, both state_on | ||
38 | * and state_off should be not NULL. If at least one of them is NULL, | ||
39 | * the print_state is not overriden. | ||
40 | */ | ||
41 | struct gpio_extcon_platform_data { | ||
42 | const char *name; | ||
43 | unsigned gpio; | ||
44 | unsigned long debounce; | ||
45 | unsigned long irq_flags; | ||
46 | |||
47 | /* if NULL, "0" or "1" will be printed */ | ||
48 | const char *state_on; | ||
49 | const char *state_off; | ||
50 | }; | ||
51 | |||
52 | #endif /* __EXTCON_GPIO_H__ */ | ||
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 6af8738ae7e9..68ed7f7e1fc9 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h | |||
@@ -1062,8 +1062,10 @@ struct hyperv_service_callback { | |||
1062 | void (*callback) (void *context); | 1062 | void (*callback) (void *context); |
1063 | }; | 1063 | }; |
1064 | 1064 | ||
1065 | #define MAX_SRV_VER 0x7ffffff | ||
1065 | extern void vmbus_prep_negotiate_resp(struct icmsg_hdr *, | 1066 | extern void vmbus_prep_negotiate_resp(struct icmsg_hdr *, |
1066 | struct icmsg_negotiate *, u8 *); | 1067 | struct icmsg_negotiate *, u8 *, int, |
1068 | int); | ||
1067 | 1069 | ||
1068 | int hv_kvp_init(struct hv_util_service *); | 1070 | int hv_kvp_init(struct hv_util_service *); |
1069 | void hv_kvp_deinit(void); | 1071 | void hv_kvp_deinit(void); |
diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h index 28726dd540f2..b40c08cd30bc 100644 --- a/include/linux/mfd/max8997.h +++ b/include/linux/mfd/max8997.h | |||
@@ -99,34 +99,11 @@ struct max8997_muic_reg_data { | |||
99 | 99 | ||
100 | /** | 100 | /** |
101 | * struct max8997_muic_platform_data | 101 | * struct max8997_muic_platform_data |
102 | * @usb_callback: callback function for USB | ||
103 | * inform callee of USB type (HOST or DEVICE) | ||
104 | * and attached state(true or false) | ||
105 | * @charger_callback: callback function for charger | ||
106 | * inform callee of charger_type | ||
107 | * and attached state(true or false) | ||
108 | * @deskdock_callback: callback function for desk dock | ||
109 | * inform callee of attached state(true or false) | ||
110 | * @cardock_callback: callback function for car dock | ||
111 | * inform callee of attached state(true or false) | ||
112 | * @mhl_callback: callback function for MHL (Mobile High-definition Link) | ||
113 | * inform callee of attached state(true or false) | ||
114 | * @uart_callback: callback function for JIG UART | ||
115 | * inform callee of attached state(true or false) | ||
116 | * @init_data: array of max8997_muic_reg_data | 102 | * @init_data: array of max8997_muic_reg_data |
117 | * used for initializing registers of MAX8997 MUIC device | 103 | * used for initializing registers of MAX8997 MUIC device |
118 | * @num_init_data: array size of init_data | 104 | * @num_init_data: array size of init_data |
119 | */ | 105 | */ |
120 | struct max8997_muic_platform_data { | 106 | struct max8997_muic_platform_data { |
121 | void (*usb_callback)(enum max8997_muic_usb_type usb_type, | ||
122 | bool attached); | ||
123 | void (*charger_callback)(bool attached, | ||
124 | enum max8997_muic_charger_type charger_type); | ||
125 | void (*deskdock_callback) (bool attached); | ||
126 | void (*cardock_callback) (bool attached); | ||
127 | void (*mhl_callback) (bool attached); | ||
128 | void (*uart_callback) (bool attached); | ||
129 | |||
130 | struct max8997_muic_reg_data *init_data; | 107 | struct max8997_muic_reg_data *init_data; |
131 | int num_init_data; | 108 | int num_init_data; |
132 | }; | 109 | }; |
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index ea36486378d8..1b14d25162cb 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h | |||
@@ -320,7 +320,8 @@ extern int parse_args(const char *name, | |||
320 | unsigned num, | 320 | unsigned num, |
321 | s16 level_min, | 321 | s16 level_min, |
322 | s16 level_max, | 322 | s16 level_max, |
323 | int (*unknown)(char *param, char *val)); | 323 | int (*unknown)(char *param, char *val, |
324 | const char *doing)); | ||
324 | 325 | ||
325 | /* Called by module remove. */ | 326 | /* Called by module remove. */ |
326 | #ifdef CONFIG_SYSFS | 327 | #ifdef CONFIG_SYSFS |
diff --git a/include/linux/platform_data/emif_plat.h b/include/linux/platform_data/emif_plat.h new file mode 100644 index 000000000000..03378ca84061 --- /dev/null +++ b/include/linux/platform_data/emif_plat.h | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | * Definitions for TI EMIF device platform data | ||
3 | * | ||
4 | * Copyright (C) 2012 Texas Instruments, Inc. | ||
5 | * | ||
6 | * Aneesh V <aneesh@ti.com> | ||
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 __EMIF_PLAT_H | ||
13 | #define __EMIF_PLAT_H | ||
14 | |||
15 | /* Low power modes - EMIF_PWR_MGMT_CTRL */ | ||
16 | #define EMIF_LP_MODE_DISABLE 0 | ||
17 | #define EMIF_LP_MODE_CLOCK_STOP 1 | ||
18 | #define EMIF_LP_MODE_SELF_REFRESH 2 | ||
19 | #define EMIF_LP_MODE_PWR_DN 4 | ||
20 | |||
21 | /* Hardware capabilities */ | ||
22 | #define EMIF_HW_CAPS_LL_INTERFACE 0x00000001 | ||
23 | |||
24 | /* | ||
25 | * EMIF IP Revisions | ||
26 | * EMIF4D - Used in OMAP4 | ||
27 | * EMIF4D5 - Used in OMAP5 | ||
28 | */ | ||
29 | #define EMIF_4D 1 | ||
30 | #define EMIF_4D5 2 | ||
31 | |||
32 | /* | ||
33 | * PHY types | ||
34 | * ATTILAPHY - Used in OMAP4 | ||
35 | * INTELLIPHY - Used in OMAP5 | ||
36 | */ | ||
37 | #define EMIF_PHY_TYPE_ATTILAPHY 1 | ||
38 | #define EMIF_PHY_TYPE_INTELLIPHY 2 | ||
39 | |||
40 | /* Custom config requests */ | ||
41 | #define EMIF_CUSTOM_CONFIG_LPMODE 0x00000001 | ||
42 | #define EMIF_CUSTOM_CONFIG_TEMP_ALERT_POLL_INTERVAL 0x00000002 | ||
43 | |||
44 | #ifndef __ASSEMBLY__ | ||
45 | /** | ||
46 | * struct ddr_device_info - All information about the DDR device except AC | ||
47 | * timing parameters | ||
48 | * @type: Device type (LPDDR2-S4, LPDDR2-S2 etc) | ||
49 | * @density: Device density | ||
50 | * @io_width: Bus width | ||
51 | * @cs1_used: Whether there is a DDR device attached to the second | ||
52 | * chip-select(CS1) of this EMIF instance | ||
53 | * @cal_resistors_per_cs: Whether there is one calibration resistor per | ||
54 | * chip-select or whether it's a single one for both | ||
55 | * @manufacturer: Manufacturer name string | ||
56 | */ | ||
57 | struct ddr_device_info { | ||
58 | u32 type; | ||
59 | u32 density; | ||
60 | u32 io_width; | ||
61 | u32 cs1_used; | ||
62 | u32 cal_resistors_per_cs; | ||
63 | char manufacturer[10]; | ||
64 | }; | ||
65 | |||
66 | /** | ||
67 | * struct emif_custom_configs - Custom configuration parameters/policies | ||
68 | * passed from the platform layer | ||
69 | * @mask: Mask to indicate which configs are requested | ||
70 | * @lpmode: LPMODE to be used in PWR_MGMT_CTRL register | ||
71 | * @lpmode_timeout_performance: Timeout before LPMODE entry when higher | ||
72 | * performance is desired at the cost of power (typically | ||
73 | * at higher OPPs) | ||
74 | * @lpmode_timeout_power: Timeout before LPMODE entry when better power | ||
75 | * savings is desired and performance is not important | ||
76 | * (typically at lower loads indicated by lower OPPs) | ||
77 | * @lpmode_freq_threshold: The DDR frequency threshold to identify between | ||
78 | * the above two cases: | ||
79 | * timeout = (freq >= lpmode_freq_threshold) ? | ||
80 | * lpmode_timeout_performance : | ||
81 | * lpmode_timeout_power; | ||
82 | * @temp_alert_poll_interval_ms: LPDDR2 MR4 polling interval at nominal | ||
83 | * temperature(in milliseconds). When temperature is high | ||
84 | * polling is done 4 times as frequently. | ||
85 | */ | ||
86 | struct emif_custom_configs { | ||
87 | u32 mask; | ||
88 | u32 lpmode; | ||
89 | u32 lpmode_timeout_performance; | ||
90 | u32 lpmode_timeout_power; | ||
91 | u32 lpmode_freq_threshold; | ||
92 | u32 temp_alert_poll_interval_ms; | ||
93 | }; | ||
94 | |||
95 | /** | ||
96 | * struct emif_platform_data - Platform data passed on EMIF platform | ||
97 | * device creation. Used by the driver. | ||
98 | * @hw_caps: Hw capabilities of the EMIF IP in the respective SoC | ||
99 | * @device_info: Device info structure containing information such | ||
100 | * as type, bus width, density etc | ||
101 | * @timings: Timings information from device datasheet passed | ||
102 | * as an array of 'struct lpddr2_timings'. Can be NULL | ||
103 | * if if default timings are ok | ||
104 | * @timings_arr_size: Size of the timings array. Depends on the number | ||
105 | * of different frequencies for which timings data | ||
106 | * is provided | ||
107 | * @min_tck: Minimum value of some timing parameters in terms | ||
108 | * of number of cycles. Can be NULL if default values | ||
109 | * are ok | ||
110 | * @custom_configs: Custom configurations requested by SoC or board | ||
111 | * code and the data for them. Can be NULL if default | ||
112 | * configurations done by the driver are ok. See | ||
113 | * documentation for 'struct emif_custom_configs' for | ||
114 | * more details | ||
115 | */ | ||
116 | struct emif_platform_data { | ||
117 | u32 hw_caps; | ||
118 | struct ddr_device_info *device_info; | ||
119 | const struct lpddr2_timings *timings; | ||
120 | u32 timings_arr_size; | ||
121 | const struct lpddr2_min_tck *min_tck; | ||
122 | struct emif_custom_configs *custom_configs; | ||
123 | u32 ip_rev; | ||
124 | u32 phy_type; | ||
125 | }; | ||
126 | #endif /* __ASSEMBLY__ */ | ||
127 | |||
128 | #endif /* __LINUX_EMIF_H */ | ||
diff --git a/include/linux/printk.h b/include/linux/printk.h index 0525927f203f..1bec2f7a2d42 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h | |||
@@ -95,8 +95,19 @@ extern int printk_needs_cpu(int cpu); | |||
95 | extern void printk_tick(void); | 95 | extern void printk_tick(void); |
96 | 96 | ||
97 | #ifdef CONFIG_PRINTK | 97 | #ifdef CONFIG_PRINTK |
98 | asmlinkage __printf(5, 0) | ||
99 | int vprintk_emit(int facility, int level, | ||
100 | const char *dict, size_t dictlen, | ||
101 | const char *fmt, va_list args); | ||
102 | |||
98 | asmlinkage __printf(1, 0) | 103 | asmlinkage __printf(1, 0) |
99 | int vprintk(const char *fmt, va_list args); | 104 | int vprintk(const char *fmt, va_list args); |
105 | |||
106 | asmlinkage __printf(5, 6) __cold | ||
107 | asmlinkage int printk_emit(int facility, int level, | ||
108 | const char *dict, size_t dictlen, | ||
109 | const char *fmt, ...); | ||
110 | |||
100 | asmlinkage __printf(1, 2) __cold | 111 | asmlinkage __printf(1, 2) __cold |
101 | int printk(const char *fmt, ...); | 112 | int printk(const char *fmt, ...); |
102 | 113 | ||
@@ -289,6 +300,8 @@ extern void dump_stack(void) __cold; | |||
289 | no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) | 300 | no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) |
290 | #endif | 301 | #endif |
291 | 302 | ||
303 | extern const struct file_operations kmsg_fops; | ||
304 | |||
292 | enum { | 305 | enum { |
293 | DUMP_PREFIX_NONE, | 306 | DUMP_PREFIX_NONE, |
294 | DUMP_PREFIX_ADDRESS, | 307 | DUMP_PREFIX_ADDRESS, |
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 0010009b2f00..381f06db2fe5 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h | |||
@@ -27,6 +27,7 @@ struct attribute { | |||
27 | const char *name; | 27 | const char *name; |
28 | umode_t mode; | 28 | umode_t mode; |
29 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 29 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
30 | bool ignore_lockdep:1; | ||
30 | struct lock_class_key *key; | 31 | struct lock_class_key *key; |
31 | struct lock_class_key skey; | 32 | struct lock_class_key skey; |
32 | #endif | 33 | #endif |
@@ -80,6 +81,17 @@ struct attribute_group { | |||
80 | 81 | ||
81 | #define __ATTR_NULL { .attr = { .name = NULL } } | 82 | #define __ATTR_NULL { .attr = { .name = NULL } } |
82 | 83 | ||
84 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
85 | #define __ATTR_IGNORE_LOCKDEP(_name, _mode, _show, _store) { \ | ||
86 | .attr = {.name = __stringify(_name), .mode = _mode, \ | ||
87 | .ignore_lockdep = true }, \ | ||
88 | .show = _show, \ | ||
89 | .store = _store, \ | ||
90 | } | ||
91 | #else | ||
92 | #define __ATTR_IGNORE_LOCKDEP __ATTR | ||
93 | #endif | ||
94 | |||
83 | #define attr_name(_attr) (_attr).attr.name | 95 | #define attr_name(_attr) (_attr).attr.name |
84 | 96 | ||
85 | struct file; | 97 | struct file; |
diff --git a/include/memory/jedec_ddr.h b/include/memory/jedec_ddr.h new file mode 100644 index 000000000000..ddad0f870e5d --- /dev/null +++ b/include/memory/jedec_ddr.h | |||
@@ -0,0 +1,175 @@ | |||
1 | /* | ||
2 | * Definitions for DDR memories based on JEDEC specs | ||
3 | * | ||
4 | * Copyright (C) 2012 Texas Instruments, Inc. | ||
5 | * | ||
6 | * Aneesh V <aneesh@ti.com> | ||
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 __LINUX_JEDEC_DDR_H | ||
13 | #define __LINUX_JEDEC_DDR_H | ||
14 | |||
15 | #include <linux/types.h> | ||
16 | |||
17 | /* DDR Densities */ | ||
18 | #define DDR_DENSITY_64Mb 1 | ||
19 | #define DDR_DENSITY_128Mb 2 | ||
20 | #define DDR_DENSITY_256Mb 3 | ||
21 | #define DDR_DENSITY_512Mb 4 | ||
22 | #define DDR_DENSITY_1Gb 5 | ||
23 | #define DDR_DENSITY_2Gb 6 | ||
24 | #define DDR_DENSITY_4Gb 7 | ||
25 | #define DDR_DENSITY_8Gb 8 | ||
26 | #define DDR_DENSITY_16Gb 9 | ||
27 | #define DDR_DENSITY_32Gb 10 | ||
28 | |||
29 | /* DDR type */ | ||
30 | #define DDR_TYPE_DDR2 1 | ||
31 | #define DDR_TYPE_DDR3 2 | ||
32 | #define DDR_TYPE_LPDDR2_S4 3 | ||
33 | #define DDR_TYPE_LPDDR2_S2 4 | ||
34 | #define DDR_TYPE_LPDDR2_NVM 5 | ||
35 | |||
36 | /* DDR IO width */ | ||
37 | #define DDR_IO_WIDTH_4 1 | ||
38 | #define DDR_IO_WIDTH_8 2 | ||
39 | #define DDR_IO_WIDTH_16 3 | ||
40 | #define DDR_IO_WIDTH_32 4 | ||
41 | |||
42 | /* Number of Row bits */ | ||
43 | #define R9 9 | ||
44 | #define R10 10 | ||
45 | #define R11 11 | ||
46 | #define R12 12 | ||
47 | #define R13 13 | ||
48 | #define R14 14 | ||
49 | #define R15 15 | ||
50 | #define R16 16 | ||
51 | |||
52 | /* Number of Column bits */ | ||
53 | #define C7 7 | ||
54 | #define C8 8 | ||
55 | #define C9 9 | ||
56 | #define C10 10 | ||
57 | #define C11 11 | ||
58 | #define C12 12 | ||
59 | |||
60 | /* Number of Banks */ | ||
61 | #define B1 0 | ||
62 | #define B2 1 | ||
63 | #define B4 2 | ||
64 | #define B8 3 | ||
65 | |||
66 | /* Refresh rate in nano-seconds */ | ||
67 | #define T_REFI_15_6 15600 | ||
68 | #define T_REFI_7_8 7800 | ||
69 | #define T_REFI_3_9 3900 | ||
70 | |||
71 | /* tRFC values */ | ||
72 | #define T_RFC_90 90000 | ||
73 | #define T_RFC_110 110000 | ||
74 | #define T_RFC_130 130000 | ||
75 | #define T_RFC_160 160000 | ||
76 | #define T_RFC_210 210000 | ||
77 | #define T_RFC_300 300000 | ||
78 | #define T_RFC_350 350000 | ||
79 | |||
80 | /* Mode register numbers */ | ||
81 | #define DDR_MR0 0 | ||
82 | #define DDR_MR1 1 | ||
83 | #define DDR_MR2 2 | ||
84 | #define DDR_MR3 3 | ||
85 | #define DDR_MR4 4 | ||
86 | #define DDR_MR5 5 | ||
87 | #define DDR_MR6 6 | ||
88 | #define DDR_MR7 7 | ||
89 | #define DDR_MR8 8 | ||
90 | #define DDR_MR9 9 | ||
91 | #define DDR_MR10 10 | ||
92 | #define DDR_MR11 11 | ||
93 | #define DDR_MR16 16 | ||
94 | #define DDR_MR17 17 | ||
95 | #define DDR_MR18 18 | ||
96 | |||
97 | /* | ||
98 | * LPDDR2 related defines | ||
99 | */ | ||
100 | |||
101 | /* MR4 register fields */ | ||
102 | #define MR4_SDRAM_REF_RATE_SHIFT 0 | ||
103 | #define MR4_SDRAM_REF_RATE_MASK 7 | ||
104 | #define MR4_TUF_SHIFT 7 | ||
105 | #define MR4_TUF_MASK (1 << 7) | ||
106 | |||
107 | /* MR4 SDRAM Refresh Rate field values */ | ||
108 | #define SDRAM_TEMP_NOMINAL 0x3 | ||
109 | #define SDRAM_TEMP_RESERVED_4 0x4 | ||
110 | #define SDRAM_TEMP_HIGH_DERATE_REFRESH 0x5 | ||
111 | #define SDRAM_TEMP_HIGH_DERATE_REFRESH_AND_TIMINGS 0x6 | ||
112 | #define SDRAM_TEMP_VERY_HIGH_SHUTDOWN 0x7 | ||
113 | |||
114 | #define NUM_DDR_ADDR_TABLE_ENTRIES 11 | ||
115 | #define NUM_DDR_TIMING_TABLE_ENTRIES 4 | ||
116 | |||
117 | /* Structure for DDR addressing info from the JEDEC spec */ | ||
118 | struct lpddr2_addressing { | ||
119 | u32 num_banks; | ||
120 | u32 tREFI_ns; | ||
121 | u32 tRFCab_ps; | ||
122 | }; | ||
123 | |||
124 | /* | ||
125 | * Structure for timings from the LPDDR2 datasheet | ||
126 | * All parameters are in pico seconds(ps) unless explicitly indicated | ||
127 | * with a suffix like tRAS_max_ns below | ||
128 | */ | ||
129 | struct lpddr2_timings { | ||
130 | u32 max_freq; | ||
131 | u32 min_freq; | ||
132 | u32 tRPab; | ||
133 | u32 tRCD; | ||
134 | u32 tWR; | ||
135 | u32 tRAS_min; | ||
136 | u32 tRRD; | ||
137 | u32 tWTR; | ||
138 | u32 tXP; | ||
139 | u32 tRTP; | ||
140 | u32 tCKESR; | ||
141 | u32 tDQSCK_max; | ||
142 | u32 tDQSCK_max_derated; | ||
143 | u32 tFAW; | ||
144 | u32 tZQCS; | ||
145 | u32 tZQCL; | ||
146 | u32 tZQinit; | ||
147 | u32 tRAS_max_ns; | ||
148 | }; | ||
149 | |||
150 | /* | ||
151 | * Min value for some parameters in terms of number of tCK cycles(nCK) | ||
152 | * Please set to zero parameters that are not valid for a given memory | ||
153 | * type | ||
154 | */ | ||
155 | struct lpddr2_min_tck { | ||
156 | u32 tRPab; | ||
157 | u32 tRCD; | ||
158 | u32 tWR; | ||
159 | u32 tRASmin; | ||
160 | u32 tRRD; | ||
161 | u32 tWTR; | ||
162 | u32 tXP; | ||
163 | u32 tRTP; | ||
164 | u32 tCKE; | ||
165 | u32 tCKESR; | ||
166 | u32 tFAW; | ||
167 | }; | ||
168 | |||
169 | extern const struct lpddr2_addressing | ||
170 | lpddr2_jedec_addressing_table[NUM_DDR_ADDR_TABLE_ENTRIES]; | ||
171 | extern const struct lpddr2_timings | ||
172 | lpddr2_jedec_timings[NUM_DDR_TIMING_TABLE_ENTRIES]; | ||
173 | extern const struct lpddr2_min_tck lpddr2_jedec_min_tck; | ||
174 | |||
175 | #endif /* __LINUX_JEDEC_DDR_H */ | ||
diff --git a/init/main.c b/init/main.c index cb54cd3dbf05..1ca6b32c4828 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -226,7 +226,7 @@ static int __init loglevel(char *str) | |||
226 | early_param("loglevel", loglevel); | 226 | early_param("loglevel", loglevel); |
227 | 227 | ||
228 | /* Change NUL term back to "=", to make "param" the whole string. */ | 228 | /* Change NUL term back to "=", to make "param" the whole string. */ |
229 | static int __init repair_env_string(char *param, char *val) | 229 | static int __init repair_env_string(char *param, char *val, const char *unused) |
230 | { | 230 | { |
231 | if (val) { | 231 | if (val) { |
232 | /* param=val or param="val"? */ | 232 | /* param=val or param="val"? */ |
@@ -246,9 +246,9 @@ static int __init repair_env_string(char *param, char *val) | |||
246 | * Unknown boot options get handed to init, unless they look like | 246 | * Unknown boot options get handed to init, unless they look like |
247 | * unused parameters (modprobe will find them in /proc/cmdline). | 247 | * unused parameters (modprobe will find them in /proc/cmdline). |
248 | */ | 248 | */ |
249 | static int __init unknown_bootoption(char *param, char *val) | 249 | static int __init unknown_bootoption(char *param, char *val, const char *unused) |
250 | { | 250 | { |
251 | repair_env_string(param, val); | 251 | repair_env_string(param, val, unused); |
252 | 252 | ||
253 | /* Handle obsolete-style parameters */ | 253 | /* Handle obsolete-style parameters */ |
254 | if (obsolete_checksetup(param)) | 254 | if (obsolete_checksetup(param)) |
@@ -385,7 +385,7 @@ static noinline void __init_refok rest_init(void) | |||
385 | } | 385 | } |
386 | 386 | ||
387 | /* Check for early params. */ | 387 | /* Check for early params. */ |
388 | static int __init do_early_param(char *param, char *val) | 388 | static int __init do_early_param(char *param, char *val, const char *unused) |
389 | { | 389 | { |
390 | const struct obs_kernel_param *p; | 390 | const struct obs_kernel_param *p; |
391 | 391 | ||
@@ -725,14 +725,14 @@ static initcall_t *initcall_levels[] __initdata = { | |||
725 | }; | 725 | }; |
726 | 726 | ||
727 | static char *initcall_level_names[] __initdata = { | 727 | static char *initcall_level_names[] __initdata = { |
728 | "early parameters", | 728 | "early", |
729 | "core parameters", | 729 | "core", |
730 | "postcore parameters", | 730 | "postcore", |
731 | "arch parameters", | 731 | "arch", |
732 | "subsys parameters", | 732 | "subsys", |
733 | "fs parameters", | 733 | "fs", |
734 | "device parameters", | 734 | "device", |
735 | "late parameters", | 735 | "late", |
736 | }; | 736 | }; |
737 | 737 | ||
738 | static void __init do_initcall_level(int level) | 738 | static void __init do_initcall_level(int level) |
@@ -745,7 +745,7 @@ static void __init do_initcall_level(int level) | |||
745 | static_command_line, __start___param, | 745 | static_command_line, __start___param, |
746 | __stop___param - __start___param, | 746 | __stop___param - __start___param, |
747 | level, level, | 747 | level, level, |
748 | repair_env_string); | 748 | &repair_env_string); |
749 | 749 | ||
750 | for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) | 750 | for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) |
751 | do_one_initcall(*fn); | 751 | do_one_initcall(*fn); |
@@ -755,8 +755,13 @@ static void __init do_initcalls(void) | |||
755 | { | 755 | { |
756 | int level; | 756 | int level; |
757 | 757 | ||
758 | for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++) | 758 | for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++) { |
759 | pr_info("initlevel:%d=%s, %d registered initcalls\n", | ||
760 | level, initcall_level_names[level], | ||
761 | (int) (initcall_levels[level+1] | ||
762 | - initcall_levels[level])); | ||
759 | do_initcall_level(level); | 763 | do_initcall_level(level); |
764 | } | ||
760 | } | 765 | } |
761 | 766 | ||
762 | /* | 767 | /* |
diff --git a/kernel/module.c b/kernel/module.c index 78ac6ec1e425..a4e60973ca73 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -2953,7 +2953,7 @@ static struct module *load_module(void __user *umod, | |||
2953 | 2953 | ||
2954 | /* Module is ready to execute: parsing args may do that. */ | 2954 | /* Module is ready to execute: parsing args may do that. */ |
2955 | err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, | 2955 | err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, |
2956 | -32768, 32767, NULL); | 2956 | -32768, 32767, &ddebug_dyndbg_module_param_cb); |
2957 | if (err < 0) | 2957 | if (err < 0) |
2958 | goto unlink; | 2958 | goto unlink; |
2959 | 2959 | ||
diff --git a/kernel/params.c b/kernel/params.c index f37d82631347..ed35345be536 100644 --- a/kernel/params.c +++ b/kernel/params.c | |||
@@ -85,11 +85,13 @@ bool parameq(const char *a, const char *b) | |||
85 | 85 | ||
86 | static int parse_one(char *param, | 86 | static int parse_one(char *param, |
87 | char *val, | 87 | char *val, |
88 | const char *doing, | ||
88 | const struct kernel_param *params, | 89 | const struct kernel_param *params, |
89 | unsigned num_params, | 90 | unsigned num_params, |
90 | s16 min_level, | 91 | s16 min_level, |
91 | s16 max_level, | 92 | s16 max_level, |
92 | int (*handle_unknown)(char *param, char *val)) | 93 | int (*handle_unknown)(char *param, char *val, |
94 | const char *doing)) | ||
93 | { | 95 | { |
94 | unsigned int i; | 96 | unsigned int i; |
95 | int err; | 97 | int err; |
@@ -104,8 +106,8 @@ static int parse_one(char *param, | |||
104 | if (!val && params[i].ops->set != param_set_bool | 106 | if (!val && params[i].ops->set != param_set_bool |
105 | && params[i].ops->set != param_set_bint) | 107 | && params[i].ops->set != param_set_bint) |
106 | return -EINVAL; | 108 | return -EINVAL; |
107 | pr_debug("They are equal! Calling %p\n", | 109 | pr_debug("handling %s with %p\n", param, |
108 | params[i].ops->set); | 110 | params[i].ops->set); |
109 | mutex_lock(¶m_lock); | 111 | mutex_lock(¶m_lock); |
110 | err = params[i].ops->set(val, ¶ms[i]); | 112 | err = params[i].ops->set(val, ¶ms[i]); |
111 | mutex_unlock(¶m_lock); | 113 | mutex_unlock(¶m_lock); |
@@ -114,11 +116,11 @@ static int parse_one(char *param, | |||
114 | } | 116 | } |
115 | 117 | ||
116 | if (handle_unknown) { | 118 | if (handle_unknown) { |
117 | pr_debug("Unknown argument: calling %p\n", handle_unknown); | 119 | pr_debug("doing %s: %s='%s'\n", doing, param, val); |
118 | return handle_unknown(param, val); | 120 | return handle_unknown(param, val, doing); |
119 | } | 121 | } |
120 | 122 | ||
121 | pr_debug("Unknown argument `%s'\n", param); | 123 | pr_debug("Unknown argument '%s'\n", param); |
122 | return -ENOENT; | 124 | return -ENOENT; |
123 | } | 125 | } |
124 | 126 | ||
@@ -175,49 +177,47 @@ static char *next_arg(char *args, char **param, char **val) | |||
175 | } | 177 | } |
176 | 178 | ||
177 | /* Args looks like "foo=bar,bar2 baz=fuz wiz". */ | 179 | /* Args looks like "foo=bar,bar2 baz=fuz wiz". */ |
178 | int parse_args(const char *name, | 180 | int parse_args(const char *doing, |
179 | char *args, | 181 | char *args, |
180 | const struct kernel_param *params, | 182 | const struct kernel_param *params, |
181 | unsigned num, | 183 | unsigned num, |
182 | s16 min_level, | 184 | s16 min_level, |
183 | s16 max_level, | 185 | s16 max_level, |
184 | int (*unknown)(char *param, char *val)) | 186 | int (*unknown)(char *param, char *val, const char *doing)) |
185 | { | 187 | { |
186 | char *param, *val; | 188 | char *param, *val; |
187 | 189 | ||
188 | pr_debug("Parsing ARGS: %s\n", args); | ||
189 | |||
190 | /* Chew leading spaces */ | 190 | /* Chew leading spaces */ |
191 | args = skip_spaces(args); | 191 | args = skip_spaces(args); |
192 | 192 | ||
193 | if (*args) | ||
194 | pr_debug("doing %s, parsing ARGS: '%s'\n", doing, args); | ||
195 | |||
193 | while (*args) { | 196 | while (*args) { |
194 | int ret; | 197 | int ret; |
195 | int irq_was_disabled; | 198 | int irq_was_disabled; |
196 | 199 | ||
197 | args = next_arg(args, ¶m, &val); | 200 | args = next_arg(args, ¶m, &val); |
198 | irq_was_disabled = irqs_disabled(); | 201 | irq_was_disabled = irqs_disabled(); |
199 | ret = parse_one(param, val, params, num, | 202 | ret = parse_one(param, val, doing, params, num, |
200 | min_level, max_level, unknown); | 203 | min_level, max_level, unknown); |
201 | if (irq_was_disabled && !irqs_disabled()) { | 204 | if (irq_was_disabled && !irqs_disabled()) |
202 | printk(KERN_WARNING "parse_args(): option '%s' enabled " | 205 | pr_warn("%s: option '%s' enabled irq's!\n", |
203 | "irq's!\n", param); | 206 | doing, param); |
204 | } | 207 | |
205 | switch (ret) { | 208 | switch (ret) { |
206 | case -ENOENT: | 209 | case -ENOENT: |
207 | printk(KERN_ERR "%s: Unknown parameter `%s'\n", | 210 | pr_err("%s: Unknown parameter `%s'\n", doing, param); |
208 | name, param); | ||
209 | return ret; | 211 | return ret; |
210 | case -ENOSPC: | 212 | case -ENOSPC: |
211 | printk(KERN_ERR | 213 | pr_err("%s: `%s' too large for parameter `%s'\n", |
212 | "%s: `%s' too large for parameter `%s'\n", | 214 | doing, val ?: "", param); |
213 | name, val ?: "", param); | ||
214 | return ret; | 215 | return ret; |
215 | case 0: | 216 | case 0: |
216 | break; | 217 | break; |
217 | default: | 218 | default: |
218 | printk(KERN_ERR | 219 | pr_err("%s: `%s' invalid for parameter `%s'\n", |
219 | "%s: `%s' invalid for parameter `%s'\n", | 220 | doing, val ?: "", param); |
220 | name, val ?: "", param); | ||
221 | return ret; | 221 | return ret; |
222 | } | 222 | } |
223 | } | 223 | } |
@@ -263,8 +263,7 @@ STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, strict_strtoul); | |||
263 | int param_set_charp(const char *val, const struct kernel_param *kp) | 263 | int param_set_charp(const char *val, const struct kernel_param *kp) |
264 | { | 264 | { |
265 | if (strlen(val) > 1024) { | 265 | if (strlen(val) > 1024) { |
266 | printk(KERN_ERR "%s: string parameter too long\n", | 266 | pr_err("%s: string parameter too long\n", kp->name); |
267 | kp->name); | ||
268 | return -ENOSPC; | 267 | return -ENOSPC; |
269 | } | 268 | } |
270 | 269 | ||
@@ -400,8 +399,7 @@ static int param_array(const char *name, | |||
400 | int len; | 399 | int len; |
401 | 400 | ||
402 | if (*num == max) { | 401 | if (*num == max) { |
403 | printk(KERN_ERR "%s: can only take %i arguments\n", | 402 | pr_err("%s: can only take %i arguments\n", name, max); |
404 | name, max); | ||
405 | return -EINVAL; | 403 | return -EINVAL; |
406 | } | 404 | } |
407 | len = strcspn(val, ","); | 405 | len = strcspn(val, ","); |
@@ -420,8 +418,7 @@ static int param_array(const char *name, | |||
420 | } while (save == ','); | 418 | } while (save == ','); |
421 | 419 | ||
422 | if (*num < min) { | 420 | if (*num < min) { |
423 | printk(KERN_ERR "%s: needs at least %i arguments\n", | 421 | pr_err("%s: needs at least %i arguments\n", name, min); |
424 | name, min); | ||
425 | return -EINVAL; | 422 | return -EINVAL; |
426 | } | 423 | } |
427 | return 0; | 424 | return 0; |
@@ -480,7 +477,7 @@ int param_set_copystring(const char *val, const struct kernel_param *kp) | |||
480 | const struct kparam_string *kps = kp->str; | 477 | const struct kparam_string *kps = kp->str; |
481 | 478 | ||
482 | if (strlen(val)+1 > kps->maxlen) { | 479 | if (strlen(val)+1 > kps->maxlen) { |
483 | printk(KERN_ERR "%s: string doesn't fit in %u chars.\n", | 480 | pr_err("%s: string doesn't fit in %u chars.\n", |
484 | kp->name, kps->maxlen-1); | 481 | kp->name, kps->maxlen-1); |
485 | return -ENOSPC; | 482 | return -ENOSPC; |
486 | } | 483 | } |
@@ -750,11 +747,8 @@ static struct module_kobject * __init locate_module_kobject(const char *name) | |||
750 | #endif | 747 | #endif |
751 | if (err) { | 748 | if (err) { |
752 | kobject_put(&mk->kobj); | 749 | kobject_put(&mk->kobj); |
753 | printk(KERN_ERR | 750 | pr_crit("Adding module '%s' to sysfs failed (%d), the system may be unstable.\n", |
754 | "Module '%s' failed add to sysfs, error number %d\n", | ||
755 | name, err); | 751 | name, err); |
756 | printk(KERN_ERR | ||
757 | "The system will be unstable now.\n"); | ||
758 | return NULL; | 752 | return NULL; |
759 | } | 753 | } |
760 | 754 | ||
diff --git a/kernel/printk.c b/kernel/printk.c index b663c2c95d39..32462d2b364a 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/cpu.h> | 41 | #include <linux/cpu.h> |
42 | #include <linux/notifier.h> | 42 | #include <linux/notifier.h> |
43 | #include <linux/rculist.h> | 43 | #include <linux/rculist.h> |
44 | #include <linux/poll.h> | ||
44 | 45 | ||
45 | #include <asm/uaccess.h> | 46 | #include <asm/uaccess.h> |
46 | 47 | ||
@@ -54,8 +55,6 @@ void asmlinkage __attribute__((weak)) early_printk(const char *fmt, ...) | |||
54 | { | 55 | { |
55 | } | 56 | } |
56 | 57 | ||
57 | #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) | ||
58 | |||
59 | /* printk's without a loglevel use this.. */ | 58 | /* printk's without a loglevel use this.. */ |
60 | #define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL | 59 | #define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL |
61 | 60 | ||
@@ -99,24 +98,6 @@ EXPORT_SYMBOL_GPL(console_drivers); | |||
99 | static int console_locked, console_suspended; | 98 | static int console_locked, console_suspended; |
100 | 99 | ||
101 | /* | 100 | /* |
102 | * logbuf_lock protects log_buf, log_start, log_end, con_start and logged_chars | ||
103 | * It is also used in interesting ways to provide interlocking in | ||
104 | * console_unlock();. | ||
105 | */ | ||
106 | static DEFINE_RAW_SPINLOCK(logbuf_lock); | ||
107 | |||
108 | #define LOG_BUF_MASK (log_buf_len-1) | ||
109 | #define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK]) | ||
110 | |||
111 | /* | ||
112 | * The indices into log_buf are not constrained to log_buf_len - they | ||
113 | * must be masked before subscripting | ||
114 | */ | ||
115 | static unsigned log_start; /* Index into log_buf: next char to be read by syslog() */ | ||
116 | static unsigned con_start; /* Index into log_buf: next char to be sent to consoles */ | ||
117 | static unsigned log_end; /* Index into log_buf: most-recently-written-char + 1 */ | ||
118 | |||
119 | /* | ||
120 | * If exclusive_console is non-NULL then only this console is to be printed to. | 101 | * If exclusive_console is non-NULL then only this console is to be printed to. |
121 | */ | 102 | */ |
122 | static struct console *exclusive_console; | 103 | static struct console *exclusive_console; |
@@ -145,13 +126,491 @@ EXPORT_SYMBOL(console_set_on_cmdline); | |||
145 | /* Flag: console code may call schedule() */ | 126 | /* Flag: console code may call schedule() */ |
146 | static int console_may_schedule; | 127 | static int console_may_schedule; |
147 | 128 | ||
129 | /* | ||
130 | * The printk log buffer consists of a chain of concatenated variable | ||
131 | * length records. Every record starts with a record header, containing | ||
132 | * the overall length of the record. | ||
133 | * | ||
134 | * The heads to the first and last entry in the buffer, as well as the | ||
135 | * sequence numbers of these both entries are maintained when messages | ||
136 | * are stored.. | ||
137 | * | ||
138 | * If the heads indicate available messages, the length in the header | ||
139 | * tells the start next message. A length == 0 for the next message | ||
140 | * indicates a wrap-around to the beginning of the buffer. | ||
141 | * | ||
142 | * Every record carries the monotonic timestamp in microseconds, as well as | ||
143 | * the standard userspace syslog level and syslog facility. The usual | ||
144 | * kernel messages use LOG_KERN; userspace-injected messages always carry | ||
145 | * a matching syslog facility, by default LOG_USER. The origin of every | ||
146 | * message can be reliably determined that way. | ||
147 | * | ||
148 | * The human readable log message directly follows the message header. The | ||
149 | * length of the message text is stored in the header, the stored message | ||
150 | * is not terminated. | ||
151 | * | ||
152 | * Optionally, a message can carry a dictionary of properties (key/value pairs), | ||
153 | * to provide userspace with a machine-readable message context. | ||
154 | * | ||
155 | * Examples for well-defined, commonly used property names are: | ||
156 | * DEVICE=b12:8 device identifier | ||
157 | * b12:8 block dev_t | ||
158 | * c127:3 char dev_t | ||
159 | * n8 netdev ifindex | ||
160 | * +sound:card0 subsystem:devname | ||
161 | * SUBSYSTEM=pci driver-core subsystem name | ||
162 | * | ||
163 | * Valid characters in property names are [a-zA-Z0-9.-_]. The plain text value | ||
164 | * follows directly after a '=' character. Every property is terminated by | ||
165 | * a '\0' character. The last property is not terminated. | ||
166 | * | ||
167 | * Example of a message structure: | ||
168 | * 0000 ff 8f 00 00 00 00 00 00 monotonic time in nsec | ||
169 | * 0008 34 00 record is 52 bytes long | ||
170 | * 000a 0b 00 text is 11 bytes long | ||
171 | * 000c 1f 00 dictionary is 23 bytes long | ||
172 | * 000e 03 00 LOG_KERN (facility) LOG_ERR (level) | ||
173 | * 0010 69 74 27 73 20 61 20 6c "it's a l" | ||
174 | * 69 6e 65 "ine" | ||
175 | * 001b 44 45 56 49 43 "DEVIC" | ||
176 | * 45 3d 62 38 3a 32 00 44 "E=b8:2\0D" | ||
177 | * 52 49 56 45 52 3d 62 75 "RIVER=bu" | ||
178 | * 67 "g" | ||
179 | * 0032 00 00 00 padding to next message header | ||
180 | * | ||
181 | * The 'struct log' buffer header must never be directly exported to | ||
182 | * userspace, it is a kernel-private implementation detail that might | ||
183 | * need to be changed in the future, when the requirements change. | ||
184 | * | ||
185 | * /dev/kmsg exports the structured data in the following line format: | ||
186 | * "level,sequnum,timestamp;<message text>\n" | ||
187 | * | ||
188 | * The optional key/value pairs are attached as continuation lines starting | ||
189 | * with a space character and terminated by a newline. All possible | ||
190 | * non-prinatable characters are escaped in the "\xff" notation. | ||
191 | * | ||
192 | * Users of the export format should ignore possible additional values | ||
193 | * separated by ',', and find the message after the ';' character. | ||
194 | */ | ||
195 | |||
196 | struct log { | ||
197 | u64 ts_nsec; /* timestamp in nanoseconds */ | ||
198 | u16 len; /* length of entire record */ | ||
199 | u16 text_len; /* length of text buffer */ | ||
200 | u16 dict_len; /* length of dictionary buffer */ | ||
201 | u16 level; /* syslog level + facility */ | ||
202 | }; | ||
203 | |||
204 | /* | ||
205 | * The logbuf_lock protects kmsg buffer, indices, counters. It is also | ||
206 | * used in interesting ways to provide interlocking in console_unlock(); | ||
207 | */ | ||
208 | static DEFINE_RAW_SPINLOCK(logbuf_lock); | ||
209 | |||
210 | /* the next printk record to read by syslog(READ) or /proc/kmsg */ | ||
211 | static u64 syslog_seq; | ||
212 | static u32 syslog_idx; | ||
213 | |||
214 | /* index and sequence number of the first record stored in the buffer */ | ||
215 | static u64 log_first_seq; | ||
216 | static u32 log_first_idx; | ||
217 | |||
218 | /* index and sequence number of the next record to store in the buffer */ | ||
219 | static u64 log_next_seq; | ||
148 | #ifdef CONFIG_PRINTK | 220 | #ifdef CONFIG_PRINTK |
221 | static u32 log_next_idx; | ||
222 | |||
223 | /* the next printk record to read after the last 'clear' command */ | ||
224 | static u64 clear_seq; | ||
225 | static u32 clear_idx; | ||
226 | |||
227 | #define LOG_LINE_MAX 1024 | ||
149 | 228 | ||
150 | static char __log_buf[__LOG_BUF_LEN]; | 229 | /* record buffer */ |
230 | #if !defined(CONFIG_64BIT) || defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) | ||
231 | #define LOG_ALIGN 4 | ||
232 | #else | ||
233 | #define LOG_ALIGN 8 | ||
234 | #endif | ||
235 | #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) | ||
236 | static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN); | ||
151 | static char *log_buf = __log_buf; | 237 | static char *log_buf = __log_buf; |
152 | static int log_buf_len = __LOG_BUF_LEN; | 238 | static u32 log_buf_len = __LOG_BUF_LEN; |
153 | static unsigned logged_chars; /* Number of chars produced since last read+clear operation */ | 239 | |
154 | static int saved_console_loglevel = -1; | 240 | /* cpu currently holding logbuf_lock */ |
241 | static volatile unsigned int logbuf_cpu = UINT_MAX; | ||
242 | |||
243 | /* human readable text of the record */ | ||
244 | static char *log_text(const struct log *msg) | ||
245 | { | ||
246 | return (char *)msg + sizeof(struct log); | ||
247 | } | ||
248 | |||
249 | /* optional key/value pair dictionary attached to the record */ | ||
250 | static char *log_dict(const struct log *msg) | ||
251 | { | ||
252 | return (char *)msg + sizeof(struct log) + msg->text_len; | ||
253 | } | ||
254 | |||
255 | /* get record by index; idx must point to valid msg */ | ||
256 | static struct log *log_from_idx(u32 idx) | ||
257 | { | ||
258 | struct log *msg = (struct log *)(log_buf + idx); | ||
259 | |||
260 | /* | ||
261 | * A length == 0 record is the end of buffer marker. Wrap around and | ||
262 | * read the message at the start of the buffer. | ||
263 | */ | ||
264 | if (!msg->len) | ||
265 | return (struct log *)log_buf; | ||
266 | return msg; | ||
267 | } | ||
268 | |||
269 | /* get next record; idx must point to valid msg */ | ||
270 | static u32 log_next(u32 idx) | ||
271 | { | ||
272 | struct log *msg = (struct log *)(log_buf + idx); | ||
273 | |||
274 | /* length == 0 indicates the end of the buffer; wrap */ | ||
275 | /* | ||
276 | * A length == 0 record is the end of buffer marker. Wrap around and | ||
277 | * read the message at the start of the buffer as *this* one, and | ||
278 | * return the one after that. | ||
279 | */ | ||
280 | if (!msg->len) { | ||
281 | msg = (struct log *)log_buf; | ||
282 | return msg->len; | ||
283 | } | ||
284 | return idx + msg->len; | ||
285 | } | ||
286 | |||
287 | /* insert record into the buffer, discard old ones, update heads */ | ||
288 | static void log_store(int facility, int level, | ||
289 | const char *dict, u16 dict_len, | ||
290 | const char *text, u16 text_len) | ||
291 | { | ||
292 | struct log *msg; | ||
293 | u32 size, pad_len; | ||
294 | |||
295 | /* number of '\0' padding bytes to next message */ | ||
296 | size = sizeof(struct log) + text_len + dict_len; | ||
297 | pad_len = (-size) & (LOG_ALIGN - 1); | ||
298 | size += pad_len; | ||
299 | |||
300 | while (log_first_seq < log_next_seq) { | ||
301 | u32 free; | ||
302 | |||
303 | if (log_next_idx > log_first_idx) | ||
304 | free = max(log_buf_len - log_next_idx, log_first_idx); | ||
305 | else | ||
306 | free = log_first_idx - log_next_idx; | ||
307 | |||
308 | if (free > size + sizeof(struct log)) | ||
309 | break; | ||
310 | |||
311 | /* drop old messages until we have enough contiuous space */ | ||
312 | log_first_idx = log_next(log_first_idx); | ||
313 | log_first_seq++; | ||
314 | } | ||
315 | |||
316 | if (log_next_idx + size + sizeof(struct log) >= log_buf_len) { | ||
317 | /* | ||
318 | * This message + an additional empty header does not fit | ||
319 | * at the end of the buffer. Add an empty header with len == 0 | ||
320 | * to signify a wrap around. | ||
321 | */ | ||
322 | memset(log_buf + log_next_idx, 0, sizeof(struct log)); | ||
323 | log_next_idx = 0; | ||
324 | } | ||
325 | |||
326 | /* fill message */ | ||
327 | msg = (struct log *)(log_buf + log_next_idx); | ||
328 | memcpy(log_text(msg), text, text_len); | ||
329 | msg->text_len = text_len; | ||
330 | memcpy(log_dict(msg), dict, dict_len); | ||
331 | msg->dict_len = dict_len; | ||
332 | msg->level = (facility << 3) | (level & 7); | ||
333 | msg->ts_nsec = local_clock(); | ||
334 | memset(log_dict(msg) + dict_len, 0, pad_len); | ||
335 | msg->len = sizeof(struct log) + text_len + dict_len + pad_len; | ||
336 | |||
337 | /* insert message */ | ||
338 | log_next_idx += msg->len; | ||
339 | log_next_seq++; | ||
340 | } | ||
341 | |||
342 | /* /dev/kmsg - userspace message inject/listen interface */ | ||
343 | struct devkmsg_user { | ||
344 | u64 seq; | ||
345 | u32 idx; | ||
346 | struct mutex lock; | ||
347 | char buf[8192]; | ||
348 | }; | ||
349 | |||
350 | static ssize_t devkmsg_writev(struct kiocb *iocb, const struct iovec *iv, | ||
351 | unsigned long count, loff_t pos) | ||
352 | { | ||
353 | char *buf, *line; | ||
354 | int i; | ||
355 | int level = default_message_loglevel; | ||
356 | int facility = 1; /* LOG_USER */ | ||
357 | size_t len = iov_length(iv, count); | ||
358 | ssize_t ret = len; | ||
359 | |||
360 | if (len > LOG_LINE_MAX) | ||
361 | return -EINVAL; | ||
362 | buf = kmalloc(len+1, GFP_KERNEL); | ||
363 | if (buf == NULL) | ||
364 | return -ENOMEM; | ||
365 | |||
366 | line = buf; | ||
367 | for (i = 0; i < count; i++) { | ||
368 | if (copy_from_user(line, iv[i].iov_base, iv[i].iov_len)) | ||
369 | goto out; | ||
370 | line += iv[i].iov_len; | ||
371 | } | ||
372 | |||
373 | /* | ||
374 | * Extract and skip the syslog prefix <[0-9]*>. Coming from userspace | ||
375 | * the decimal value represents 32bit, the lower 3 bit are the log | ||
376 | * level, the rest are the log facility. | ||
377 | * | ||
378 | * If no prefix or no userspace facility is specified, we | ||
379 | * enforce LOG_USER, to be able to reliably distinguish | ||
380 | * kernel-generated messages from userspace-injected ones. | ||
381 | */ | ||
382 | line = buf; | ||
383 | if (line[0] == '<') { | ||
384 | char *endp = NULL; | ||
385 | |||
386 | i = simple_strtoul(line+1, &endp, 10); | ||
387 | if (endp && endp[0] == '>') { | ||
388 | level = i & 7; | ||
389 | if (i >> 3) | ||
390 | facility = i >> 3; | ||
391 | endp++; | ||
392 | len -= endp - line; | ||
393 | line = endp; | ||
394 | } | ||
395 | } | ||
396 | line[len] = '\0'; | ||
397 | |||
398 | printk_emit(facility, level, NULL, 0, "%s", line); | ||
399 | out: | ||
400 | kfree(buf); | ||
401 | return ret; | ||
402 | } | ||
403 | |||
404 | static ssize_t devkmsg_read(struct file *file, char __user *buf, | ||
405 | size_t count, loff_t *ppos) | ||
406 | { | ||
407 | struct devkmsg_user *user = file->private_data; | ||
408 | struct log *msg; | ||
409 | u64 ts_usec; | ||
410 | size_t i; | ||
411 | size_t len; | ||
412 | ssize_t ret; | ||
413 | |||
414 | if (!user) | ||
415 | return -EBADF; | ||
416 | |||
417 | mutex_lock(&user->lock); | ||
418 | raw_spin_lock(&logbuf_lock); | ||
419 | while (user->seq == log_next_seq) { | ||
420 | if (file->f_flags & O_NONBLOCK) { | ||
421 | ret = -EAGAIN; | ||
422 | raw_spin_unlock(&logbuf_lock); | ||
423 | goto out; | ||
424 | } | ||
425 | |||
426 | raw_spin_unlock(&logbuf_lock); | ||
427 | ret = wait_event_interruptible(log_wait, | ||
428 | user->seq != log_next_seq); | ||
429 | if (ret) | ||
430 | goto out; | ||
431 | raw_spin_lock(&logbuf_lock); | ||
432 | } | ||
433 | |||
434 | if (user->seq < log_first_seq) { | ||
435 | /* our last seen message is gone, return error and reset */ | ||
436 | user->idx = log_first_idx; | ||
437 | user->seq = log_first_seq; | ||
438 | ret = -EPIPE; | ||
439 | raw_spin_unlock(&logbuf_lock); | ||
440 | goto out; | ||
441 | } | ||
442 | |||
443 | msg = log_from_idx(user->idx); | ||
444 | ts_usec = msg->ts_nsec; | ||
445 | do_div(ts_usec, 1000); | ||
446 | len = sprintf(user->buf, "%u,%llu,%llu;", | ||
447 | msg->level, user->seq, ts_usec); | ||
448 | |||
449 | /* escape non-printable characters */ | ||
450 | for (i = 0; i < msg->text_len; i++) { | ||
451 | unsigned char c = log_text(msg)[i]; | ||
452 | |||
453 | if (c < ' ' || c >= 128) | ||
454 | len += sprintf(user->buf + len, "\\x%02x", c); | ||
455 | else | ||
456 | user->buf[len++] = c; | ||
457 | } | ||
458 | user->buf[len++] = '\n'; | ||
459 | |||
460 | if (msg->dict_len) { | ||
461 | bool line = true; | ||
462 | |||
463 | for (i = 0; i < msg->dict_len; i++) { | ||
464 | unsigned char c = log_dict(msg)[i]; | ||
465 | |||
466 | if (line) { | ||
467 | user->buf[len++] = ' '; | ||
468 | line = false; | ||
469 | } | ||
470 | |||
471 | if (c == '\0') { | ||
472 | user->buf[len++] = '\n'; | ||
473 | line = true; | ||
474 | continue; | ||
475 | } | ||
476 | |||
477 | if (c < ' ' || c >= 128) { | ||
478 | len += sprintf(user->buf + len, "\\x%02x", c); | ||
479 | continue; | ||
480 | } | ||
481 | |||
482 | user->buf[len++] = c; | ||
483 | } | ||
484 | user->buf[len++] = '\n'; | ||
485 | } | ||
486 | |||
487 | user->idx = log_next(user->idx); | ||
488 | user->seq++; | ||
489 | raw_spin_unlock(&logbuf_lock); | ||
490 | |||
491 | if (len > count) { | ||
492 | ret = -EINVAL; | ||
493 | goto out; | ||
494 | } | ||
495 | |||
496 | if (copy_to_user(buf, user->buf, len)) { | ||
497 | ret = -EFAULT; | ||
498 | goto out; | ||
499 | } | ||
500 | ret = len; | ||
501 | out: | ||
502 | mutex_unlock(&user->lock); | ||
503 | return ret; | ||
504 | } | ||
505 | |||
506 | static loff_t devkmsg_llseek(struct file *file, loff_t offset, int whence) | ||
507 | { | ||
508 | struct devkmsg_user *user = file->private_data; | ||
509 | loff_t ret = 0; | ||
510 | |||
511 | if (!user) | ||
512 | return -EBADF; | ||
513 | if (offset) | ||
514 | return -ESPIPE; | ||
515 | |||
516 | raw_spin_lock(&logbuf_lock); | ||
517 | switch (whence) { | ||
518 | case SEEK_SET: | ||
519 | /* the first record */ | ||
520 | user->idx = log_first_idx; | ||
521 | user->seq = log_first_seq; | ||
522 | break; | ||
523 | case SEEK_DATA: | ||
524 | /* | ||
525 | * The first record after the last SYSLOG_ACTION_CLEAR, | ||
526 | * like issued by 'dmesg -c'. Reading /dev/kmsg itself | ||
527 | * changes no global state, and does not clear anything. | ||
528 | */ | ||
529 | user->idx = clear_idx; | ||
530 | user->seq = clear_seq; | ||
531 | break; | ||
532 | case SEEK_END: | ||
533 | /* after the last record */ | ||
534 | user->idx = log_next_idx; | ||
535 | user->seq = log_next_seq; | ||
536 | break; | ||
537 | default: | ||
538 | ret = -EINVAL; | ||
539 | } | ||
540 | raw_spin_unlock(&logbuf_lock); | ||
541 | return ret; | ||
542 | } | ||
543 | |||
544 | static unsigned int devkmsg_poll(struct file *file, poll_table *wait) | ||
545 | { | ||
546 | struct devkmsg_user *user = file->private_data; | ||
547 | int ret = 0; | ||
548 | |||
549 | if (!user) | ||
550 | return POLLERR|POLLNVAL; | ||
551 | |||
552 | poll_wait(file, &log_wait, wait); | ||
553 | |||
554 | raw_spin_lock(&logbuf_lock); | ||
555 | if (user->seq < log_next_seq) { | ||
556 | /* return error when data has vanished underneath us */ | ||
557 | if (user->seq < log_first_seq) | ||
558 | ret = POLLIN|POLLRDNORM|POLLERR|POLLPRI; | ||
559 | ret = POLLIN|POLLRDNORM; | ||
560 | } | ||
561 | raw_spin_unlock(&logbuf_lock); | ||
562 | |||
563 | return ret; | ||
564 | } | ||
565 | |||
566 | static int devkmsg_open(struct inode *inode, struct file *file) | ||
567 | { | ||
568 | struct devkmsg_user *user; | ||
569 | int err; | ||
570 | |||
571 | /* write-only does not need any file context */ | ||
572 | if ((file->f_flags & O_ACCMODE) == O_WRONLY) | ||
573 | return 0; | ||
574 | |||
575 | err = security_syslog(SYSLOG_ACTION_READ_ALL); | ||
576 | if (err) | ||
577 | return err; | ||
578 | |||
579 | user = kmalloc(sizeof(struct devkmsg_user), GFP_KERNEL); | ||
580 | if (!user) | ||
581 | return -ENOMEM; | ||
582 | |||
583 | mutex_init(&user->lock); | ||
584 | |||
585 | raw_spin_lock(&logbuf_lock); | ||
586 | user->idx = log_first_idx; | ||
587 | user->seq = log_first_seq; | ||
588 | raw_spin_unlock(&logbuf_lock); | ||
589 | |||
590 | file->private_data = user; | ||
591 | return 0; | ||
592 | } | ||
593 | |||
594 | static int devkmsg_release(struct inode *inode, struct file *file) | ||
595 | { | ||
596 | struct devkmsg_user *user = file->private_data; | ||
597 | |||
598 | if (!user) | ||
599 | return 0; | ||
600 | |||
601 | mutex_destroy(&user->lock); | ||
602 | kfree(user); | ||
603 | return 0; | ||
604 | } | ||
605 | |||
606 | const struct file_operations kmsg_fops = { | ||
607 | .open = devkmsg_open, | ||
608 | .read = devkmsg_read, | ||
609 | .aio_write = devkmsg_writev, | ||
610 | .llseek = devkmsg_llseek, | ||
611 | .poll = devkmsg_poll, | ||
612 | .release = devkmsg_release, | ||
613 | }; | ||
155 | 614 | ||
156 | #ifdef CONFIG_KEXEC | 615 | #ifdef CONFIG_KEXEC |
157 | /* | 616 | /* |
@@ -165,9 +624,9 @@ static int saved_console_loglevel = -1; | |||
165 | void log_buf_kexec_setup(void) | 624 | void log_buf_kexec_setup(void) |
166 | { | 625 | { |
167 | VMCOREINFO_SYMBOL(log_buf); | 626 | VMCOREINFO_SYMBOL(log_buf); |
168 | VMCOREINFO_SYMBOL(log_end); | ||
169 | VMCOREINFO_SYMBOL(log_buf_len); | 627 | VMCOREINFO_SYMBOL(log_buf_len); |
170 | VMCOREINFO_SYMBOL(logged_chars); | 628 | VMCOREINFO_SYMBOL(log_first_idx); |
629 | VMCOREINFO_SYMBOL(log_next_idx); | ||
171 | } | 630 | } |
172 | #endif | 631 | #endif |
173 | 632 | ||
@@ -191,7 +650,6 @@ early_param("log_buf_len", log_buf_len_setup); | |||
191 | void __init setup_log_buf(int early) | 650 | void __init setup_log_buf(int early) |
192 | { | 651 | { |
193 | unsigned long flags; | 652 | unsigned long flags; |
194 | unsigned start, dest_idx, offset; | ||
195 | char *new_log_buf; | 653 | char *new_log_buf; |
196 | int free; | 654 | int free; |
197 | 655 | ||
@@ -219,20 +677,8 @@ void __init setup_log_buf(int early) | |||
219 | log_buf_len = new_log_buf_len; | 677 | log_buf_len = new_log_buf_len; |
220 | log_buf = new_log_buf; | 678 | log_buf = new_log_buf; |
221 | new_log_buf_len = 0; | 679 | new_log_buf_len = 0; |
222 | free = __LOG_BUF_LEN - log_end; | 680 | free = __LOG_BUF_LEN - log_next_idx; |
223 | 681 | memcpy(log_buf, __log_buf, __LOG_BUF_LEN); | |
224 | offset = start = min(con_start, log_start); | ||
225 | dest_idx = 0; | ||
226 | while (start != log_end) { | ||
227 | unsigned log_idx_mask = start & (__LOG_BUF_LEN - 1); | ||
228 | |||
229 | log_buf[dest_idx] = __log_buf[log_idx_mask]; | ||
230 | start++; | ||
231 | dest_idx++; | ||
232 | } | ||
233 | log_start -= offset; | ||
234 | con_start -= offset; | ||
235 | log_end -= offset; | ||
236 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | 682 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
237 | 683 | ||
238 | pr_info("log_buf_len: %d\n", log_buf_len); | 684 | pr_info("log_buf_len: %d\n", log_buf_len); |
@@ -332,11 +778,202 @@ static int check_syslog_permissions(int type, bool from_file) | |||
332 | return 0; | 778 | return 0; |
333 | } | 779 | } |
334 | 780 | ||
781 | #if defined(CONFIG_PRINTK_TIME) | ||
782 | static bool printk_time = 1; | ||
783 | #else | ||
784 | static bool printk_time; | ||
785 | #endif | ||
786 | module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR); | ||
787 | |||
788 | static size_t print_prefix(const struct log *msg, bool syslog, char *buf) | ||
789 | { | ||
790 | size_t len = 0; | ||
791 | |||
792 | if (syslog) { | ||
793 | if (buf) { | ||
794 | len += sprintf(buf, "<%u>", msg->level); | ||
795 | } else { | ||
796 | len += 3; | ||
797 | if (msg->level > 9) | ||
798 | len++; | ||
799 | if (msg->level > 99) | ||
800 | len++; | ||
801 | } | ||
802 | } | ||
803 | |||
804 | if (printk_time) { | ||
805 | if (buf) { | ||
806 | unsigned long long ts = msg->ts_nsec; | ||
807 | unsigned long rem_nsec = do_div(ts, 1000000000); | ||
808 | |||
809 | len += sprintf(buf + len, "[%5lu.%06lu] ", | ||
810 | (unsigned long) ts, rem_nsec / 1000); | ||
811 | } else { | ||
812 | len += 15; | ||
813 | } | ||
814 | } | ||
815 | |||
816 | return len; | ||
817 | } | ||
818 | |||
819 | static size_t msg_print_text(const struct log *msg, bool syslog, | ||
820 | char *buf, size_t size) | ||
821 | { | ||
822 | const char *text = log_text(msg); | ||
823 | size_t text_size = msg->text_len; | ||
824 | size_t len = 0; | ||
825 | |||
826 | do { | ||
827 | const char *next = memchr(text, '\n', text_size); | ||
828 | size_t text_len; | ||
829 | |||
830 | if (next) { | ||
831 | text_len = next - text; | ||
832 | next++; | ||
833 | text_size -= next - text; | ||
834 | } else { | ||
835 | text_len = text_size; | ||
836 | } | ||
837 | |||
838 | if (buf) { | ||
839 | if (print_prefix(msg, syslog, NULL) + | ||
840 | text_len + 1>= size - len) | ||
841 | break; | ||
842 | |||
843 | len += print_prefix(msg, syslog, buf + len); | ||
844 | memcpy(buf + len, text, text_len); | ||
845 | len += text_len; | ||
846 | buf[len++] = '\n'; | ||
847 | } else { | ||
848 | /* SYSLOG_ACTION_* buffer size only calculation */ | ||
849 | len += print_prefix(msg, syslog, NULL); | ||
850 | len += text_len + 1; | ||
851 | } | ||
852 | |||
853 | text = next; | ||
854 | } while (text); | ||
855 | |||
856 | return len; | ||
857 | } | ||
858 | |||
859 | static int syslog_print(char __user *buf, int size) | ||
860 | { | ||
861 | char *text; | ||
862 | struct log *msg; | ||
863 | int len; | ||
864 | |||
865 | text = kmalloc(LOG_LINE_MAX, GFP_KERNEL); | ||
866 | if (!text) | ||
867 | return -ENOMEM; | ||
868 | |||
869 | raw_spin_lock_irq(&logbuf_lock); | ||
870 | if (syslog_seq < log_first_seq) { | ||
871 | /* messages are gone, move to first one */ | ||
872 | syslog_seq = log_first_seq; | ||
873 | syslog_idx = log_first_idx; | ||
874 | } | ||
875 | msg = log_from_idx(syslog_idx); | ||
876 | len = msg_print_text(msg, true, text, LOG_LINE_MAX); | ||
877 | syslog_idx = log_next(syslog_idx); | ||
878 | syslog_seq++; | ||
879 | raw_spin_unlock_irq(&logbuf_lock); | ||
880 | |||
881 | if (len > 0 && copy_to_user(buf, text, len)) | ||
882 | len = -EFAULT; | ||
883 | |||
884 | kfree(text); | ||
885 | return len; | ||
886 | } | ||
887 | |||
888 | static int syslog_print_all(char __user *buf, int size, bool clear) | ||
889 | { | ||
890 | char *text; | ||
891 | int len = 0; | ||
892 | |||
893 | text = kmalloc(LOG_LINE_MAX, GFP_KERNEL); | ||
894 | if (!text) | ||
895 | return -ENOMEM; | ||
896 | |||
897 | raw_spin_lock_irq(&logbuf_lock); | ||
898 | if (buf) { | ||
899 | u64 next_seq; | ||
900 | u64 seq; | ||
901 | u32 idx; | ||
902 | |||
903 | if (clear_seq < log_first_seq) { | ||
904 | /* messages are gone, move to first available one */ | ||
905 | clear_seq = log_first_seq; | ||
906 | clear_idx = log_first_idx; | ||
907 | } | ||
908 | |||
909 | /* | ||
910 | * Find first record that fits, including all following records, | ||
911 | * into the user-provided buffer for this dump. | ||
912 | */ | ||
913 | seq = clear_seq; | ||
914 | idx = clear_idx; | ||
915 | while (seq < log_next_seq) { | ||
916 | struct log *msg = log_from_idx(idx); | ||
917 | |||
918 | len += msg_print_text(msg, true, NULL, 0); | ||
919 | idx = log_next(idx); | ||
920 | seq++; | ||
921 | } | ||
922 | seq = clear_seq; | ||
923 | idx = clear_idx; | ||
924 | while (len > size && seq < log_next_seq) { | ||
925 | struct log *msg = log_from_idx(idx); | ||
926 | |||
927 | len -= msg_print_text(msg, true, NULL, 0); | ||
928 | idx = log_next(idx); | ||
929 | seq++; | ||
930 | } | ||
931 | |||
932 | /* last message in this dump */ | ||
933 | next_seq = log_next_seq; | ||
934 | |||
935 | len = 0; | ||
936 | while (len >= 0 && seq < next_seq) { | ||
937 | struct log *msg = log_from_idx(idx); | ||
938 | int textlen; | ||
939 | |||
940 | textlen = msg_print_text(msg, true, text, LOG_LINE_MAX); | ||
941 | if (textlen < 0) { | ||
942 | len = textlen; | ||
943 | break; | ||
944 | } | ||
945 | idx = log_next(idx); | ||
946 | seq++; | ||
947 | |||
948 | raw_spin_unlock_irq(&logbuf_lock); | ||
949 | if (copy_to_user(buf + len, text, textlen)) | ||
950 | len = -EFAULT; | ||
951 | else | ||
952 | len += textlen; | ||
953 | raw_spin_lock_irq(&logbuf_lock); | ||
954 | |||
955 | if (seq < log_first_seq) { | ||
956 | /* messages are gone, move to next one */ | ||
957 | seq = log_first_seq; | ||
958 | idx = log_first_idx; | ||
959 | } | ||
960 | } | ||
961 | } | ||
962 | |||
963 | if (clear) { | ||
964 | clear_seq = log_next_seq; | ||
965 | clear_idx = log_next_idx; | ||
966 | } | ||
967 | raw_spin_unlock_irq(&logbuf_lock); | ||
968 | |||
969 | kfree(text); | ||
970 | return len; | ||
971 | } | ||
972 | |||
335 | int do_syslog(int type, char __user *buf, int len, bool from_file) | 973 | int do_syslog(int type, char __user *buf, int len, bool from_file) |
336 | { | 974 | { |
337 | unsigned i, j, limit, count; | 975 | bool clear = false; |
338 | int do_clear = 0; | 976 | static int saved_console_loglevel = -1; |
339 | char c; | ||
340 | int error; | 977 | int error; |
341 | 978 | ||
342 | error = check_syslog_permissions(type, from_file); | 979 | error = check_syslog_permissions(type, from_file); |
@@ -364,28 +1001,14 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) | |||
364 | goto out; | 1001 | goto out; |
365 | } | 1002 | } |
366 | error = wait_event_interruptible(log_wait, | 1003 | error = wait_event_interruptible(log_wait, |
367 | (log_start - log_end)); | 1004 | syslog_seq != log_next_seq); |
368 | if (error) | 1005 | if (error) |
369 | goto out; | 1006 | goto out; |
370 | i = 0; | 1007 | error = syslog_print(buf, len); |
371 | raw_spin_lock_irq(&logbuf_lock); | ||
372 | while (!error && (log_start != log_end) && i < len) { | ||
373 | c = LOG_BUF(log_start); | ||
374 | log_start++; | ||
375 | raw_spin_unlock_irq(&logbuf_lock); | ||
376 | error = __put_user(c,buf); | ||
377 | buf++; | ||
378 | i++; | ||
379 | cond_resched(); | ||
380 | raw_spin_lock_irq(&logbuf_lock); | ||
381 | } | ||
382 | raw_spin_unlock_irq(&logbuf_lock); | ||
383 | if (!error) | ||
384 | error = i; | ||
385 | break; | 1008 | break; |
386 | /* Read/clear last kernel messages */ | 1009 | /* Read/clear last kernel messages */ |
387 | case SYSLOG_ACTION_READ_CLEAR: | 1010 | case SYSLOG_ACTION_READ_CLEAR: |
388 | do_clear = 1; | 1011 | clear = true; |
389 | /* FALL THRU */ | 1012 | /* FALL THRU */ |
390 | /* Read last kernel messages */ | 1013 | /* Read last kernel messages */ |
391 | case SYSLOG_ACTION_READ_ALL: | 1014 | case SYSLOG_ACTION_READ_ALL: |
@@ -399,52 +1022,11 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) | |||
399 | error = -EFAULT; | 1022 | error = -EFAULT; |
400 | goto out; | 1023 | goto out; |
401 | } | 1024 | } |
402 | count = len; | 1025 | error = syslog_print_all(buf, len, clear); |
403 | if (count > log_buf_len) | ||
404 | count = log_buf_len; | ||
405 | raw_spin_lock_irq(&logbuf_lock); | ||
406 | if (count > logged_chars) | ||
407 | count = logged_chars; | ||
408 | if (do_clear) | ||
409 | logged_chars = 0; | ||
410 | limit = log_end; | ||
411 | /* | ||
412 | * __put_user() could sleep, and while we sleep | ||
413 | * printk() could overwrite the messages | ||
414 | * we try to copy to user space. Therefore | ||
415 | * the messages are copied in reverse. <manfreds> | ||
416 | */ | ||
417 | for (i = 0; i < count && !error; i++) { | ||
418 | j = limit-1-i; | ||
419 | if (j + log_buf_len < log_end) | ||
420 | break; | ||
421 | c = LOG_BUF(j); | ||
422 | raw_spin_unlock_irq(&logbuf_lock); | ||
423 | error = __put_user(c,&buf[count-1-i]); | ||
424 | cond_resched(); | ||
425 | raw_spin_lock_irq(&logbuf_lock); | ||
426 | } | ||
427 | raw_spin_unlock_irq(&logbuf_lock); | ||
428 | if (error) | ||
429 | break; | ||
430 | error = i; | ||
431 | if (i != count) { | ||
432 | int offset = count-error; | ||
433 | /* buffer overflow during copy, correct user buffer. */ | ||
434 | for (i = 0; i < error; i++) { | ||
435 | if (__get_user(c,&buf[i+offset]) || | ||
436 | __put_user(c,&buf[i])) { | ||
437 | error = -EFAULT; | ||
438 | break; | ||
439 | } | ||
440 | cond_resched(); | ||
441 | } | ||
442 | } | ||
443 | break; | 1026 | break; |
444 | /* Clear ring buffer */ | 1027 | /* Clear ring buffer */ |
445 | case SYSLOG_ACTION_CLEAR: | 1028 | case SYSLOG_ACTION_CLEAR: |
446 | logged_chars = 0; | 1029 | syslog_print_all(NULL, 0, true); |
447 | break; | ||
448 | /* Disable logging to console */ | 1030 | /* Disable logging to console */ |
449 | case SYSLOG_ACTION_CONSOLE_OFF: | 1031 | case SYSLOG_ACTION_CONSOLE_OFF: |
450 | if (saved_console_loglevel == -1) | 1032 | if (saved_console_loglevel == -1) |
@@ -472,7 +1054,35 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) | |||
472 | break; | 1054 | break; |
473 | /* Number of chars in the log buffer */ | 1055 | /* Number of chars in the log buffer */ |
474 | case SYSLOG_ACTION_SIZE_UNREAD: | 1056 | case SYSLOG_ACTION_SIZE_UNREAD: |
475 | error = log_end - log_start; | 1057 | raw_spin_lock_irq(&logbuf_lock); |
1058 | if (syslog_seq < log_first_seq) { | ||
1059 | /* messages are gone, move to first one */ | ||
1060 | syslog_seq = log_first_seq; | ||
1061 | syslog_idx = log_first_idx; | ||
1062 | } | ||
1063 | if (from_file) { | ||
1064 | /* | ||
1065 | * Short-cut for poll(/"proc/kmsg") which simply checks | ||
1066 | * for pending data, not the size; return the count of | ||
1067 | * records, not the length. | ||
1068 | */ | ||
1069 | error = log_next_idx - syslog_idx; | ||
1070 | } else { | ||
1071 | u64 seq; | ||
1072 | u32 idx; | ||
1073 | |||
1074 | error = 0; | ||
1075 | seq = syslog_seq; | ||
1076 | idx = syslog_idx; | ||
1077 | while (seq < log_next_seq) { | ||
1078 | struct log *msg = log_from_idx(idx); | ||
1079 | |||
1080 | error += msg_print_text(msg, true, NULL, 0); | ||
1081 | idx = log_next(idx); | ||
1082 | seq++; | ||
1083 | } | ||
1084 | } | ||
1085 | raw_spin_unlock_irq(&logbuf_lock); | ||
476 | break; | 1086 | break; |
477 | /* Size of the log buffer */ | 1087 | /* Size of the log buffer */ |
478 | case SYSLOG_ACTION_SIZE_BUFFER: | 1088 | case SYSLOG_ACTION_SIZE_BUFFER: |
@@ -501,29 +1111,11 @@ void kdb_syslog_data(char *syslog_data[4]) | |||
501 | { | 1111 | { |
502 | syslog_data[0] = log_buf; | 1112 | syslog_data[0] = log_buf; |
503 | syslog_data[1] = log_buf + log_buf_len; | 1113 | syslog_data[1] = log_buf + log_buf_len; |
504 | syslog_data[2] = log_buf + log_end - | 1114 | syslog_data[2] = log_buf + log_first_idx; |
505 | (logged_chars < log_buf_len ? logged_chars : log_buf_len); | 1115 | syslog_data[3] = log_buf + log_next_idx; |
506 | syslog_data[3] = log_buf + log_end; | ||
507 | } | 1116 | } |
508 | #endif /* CONFIG_KGDB_KDB */ | 1117 | #endif /* CONFIG_KGDB_KDB */ |
509 | 1118 | ||
510 | /* | ||
511 | * Call the console drivers on a range of log_buf | ||
512 | */ | ||
513 | static void __call_console_drivers(unsigned start, unsigned end) | ||
514 | { | ||
515 | struct console *con; | ||
516 | |||
517 | for_each_console(con) { | ||
518 | if (exclusive_console && con != exclusive_console) | ||
519 | continue; | ||
520 | if ((con->flags & CON_ENABLED) && con->write && | ||
521 | (cpu_online(smp_processor_id()) || | ||
522 | (con->flags & CON_ANYTIME))) | ||
523 | con->write(con, &LOG_BUF(start), end - start); | ||
524 | } | ||
525 | } | ||
526 | |||
527 | static bool __read_mostly ignore_loglevel; | 1119 | static bool __read_mostly ignore_loglevel; |
528 | 1120 | ||
529 | static int __init ignore_loglevel_setup(char *str) | 1121 | static int __init ignore_loglevel_setup(char *str) |
@@ -540,142 +1132,33 @@ MODULE_PARM_DESC(ignore_loglevel, "ignore loglevel setting, to" | |||
540 | "print all kernel messages to the console."); | 1132 | "print all kernel messages to the console."); |
541 | 1133 | ||
542 | /* | 1134 | /* |
543 | * Write out chars from start to end - 1 inclusive | ||
544 | */ | ||
545 | static void _call_console_drivers(unsigned start, | ||
546 | unsigned end, int msg_log_level) | ||
547 | { | ||
548 | trace_console(&LOG_BUF(0), start, end, log_buf_len); | ||
549 | |||
550 | if ((msg_log_level < console_loglevel || ignore_loglevel) && | ||
551 | console_drivers && start != end) { | ||
552 | if ((start & LOG_BUF_MASK) > (end & LOG_BUF_MASK)) { | ||
553 | /* wrapped write */ | ||
554 | __call_console_drivers(start & LOG_BUF_MASK, | ||
555 | log_buf_len); | ||
556 | __call_console_drivers(0, end & LOG_BUF_MASK); | ||
557 | } else { | ||
558 | __call_console_drivers(start, end); | ||
559 | } | ||
560 | } | ||
561 | } | ||
562 | |||
563 | /* | ||
564 | * Parse the syslog header <[0-9]*>. The decimal value represents 32bit, the | ||
565 | * lower 3 bit are the log level, the rest are the log facility. In case | ||
566 | * userspace passes usual userspace syslog messages to /dev/kmsg or | ||
567 | * /dev/ttyprintk, the log prefix might contain the facility. Printk needs | ||
568 | * to extract the correct log level for in-kernel processing, and not mangle | ||
569 | * the original value. | ||
570 | * | ||
571 | * If a prefix is found, the length of the prefix is returned. If 'level' is | ||
572 | * passed, it will be filled in with the log level without a possible facility | ||
573 | * value. If 'special' is passed, the special printk prefix chars are accepted | ||
574 | * and returned. If no valid header is found, 0 is returned and the passed | ||
575 | * variables are not touched. | ||
576 | */ | ||
577 | static size_t log_prefix(const char *p, unsigned int *level, char *special) | ||
578 | { | ||
579 | unsigned int lev = 0; | ||
580 | char sp = '\0'; | ||
581 | size_t len; | ||
582 | |||
583 | if (p[0] != '<' || !p[1]) | ||
584 | return 0; | ||
585 | if (p[2] == '>') { | ||
586 | /* usual single digit level number or special char */ | ||
587 | switch (p[1]) { | ||
588 | case '0' ... '7': | ||
589 | lev = p[1] - '0'; | ||
590 | break; | ||
591 | case 'c': /* KERN_CONT */ | ||
592 | case 'd': /* KERN_DEFAULT */ | ||
593 | sp = p[1]; | ||
594 | break; | ||
595 | default: | ||
596 | return 0; | ||
597 | } | ||
598 | len = 3; | ||
599 | } else { | ||
600 | /* multi digit including the level and facility number */ | ||
601 | char *endp = NULL; | ||
602 | |||
603 | lev = (simple_strtoul(&p[1], &endp, 10) & 7); | ||
604 | if (endp == NULL || endp[0] != '>') | ||
605 | return 0; | ||
606 | len = (endp + 1) - p; | ||
607 | } | ||
608 | |||
609 | /* do not accept special char if not asked for */ | ||
610 | if (sp && !special) | ||
611 | return 0; | ||
612 | |||
613 | if (special) { | ||
614 | *special = sp; | ||
615 | /* return special char, do not touch level */ | ||
616 | if (sp) | ||
617 | return len; | ||
618 | } | ||
619 | |||
620 | if (level) | ||
621 | *level = lev; | ||
622 | return len; | ||
623 | } | ||
624 | |||
625 | /* | ||
626 | * Call the console drivers, asking them to write out | 1135 | * Call the console drivers, asking them to write out |
627 | * log_buf[start] to log_buf[end - 1]. | 1136 | * log_buf[start] to log_buf[end - 1]. |
628 | * The console_lock must be held. | 1137 | * The console_lock must be held. |
629 | */ | 1138 | */ |
630 | static void call_console_drivers(unsigned start, unsigned end) | 1139 | static void call_console_drivers(int level, const char *text, size_t len) |
631 | { | 1140 | { |
632 | unsigned cur_index, start_print; | 1141 | struct console *con; |
633 | static int msg_level = -1; | ||
634 | 1142 | ||
635 | BUG_ON(((int)(start - end)) > 0); | 1143 | trace_console(text, 0, len, len); |
636 | 1144 | ||
637 | cur_index = start; | 1145 | if (level >= console_loglevel && !ignore_loglevel) |
638 | start_print = start; | 1146 | return; |
639 | while (cur_index != end) { | 1147 | if (!console_drivers) |
640 | if (msg_level < 0 && ((end - cur_index) > 2)) { | 1148 | return; |
641 | /* strip log prefix */ | ||
642 | cur_index += log_prefix(&LOG_BUF(cur_index), &msg_level, NULL); | ||
643 | start_print = cur_index; | ||
644 | } | ||
645 | while (cur_index != end) { | ||
646 | char c = LOG_BUF(cur_index); | ||
647 | |||
648 | cur_index++; | ||
649 | if (c == '\n') { | ||
650 | if (msg_level < 0) { | ||
651 | /* | ||
652 | * printk() has already given us loglevel tags in | ||
653 | * the buffer. This code is here in case the | ||
654 | * log buffer has wrapped right round and scribbled | ||
655 | * on those tags | ||
656 | */ | ||
657 | msg_level = default_message_loglevel; | ||
658 | } | ||
659 | _call_console_drivers(start_print, cur_index, msg_level); | ||
660 | msg_level = -1; | ||
661 | start_print = cur_index; | ||
662 | break; | ||
663 | } | ||
664 | } | ||
665 | } | ||
666 | _call_console_drivers(start_print, end, msg_level); | ||
667 | } | ||
668 | 1149 | ||
669 | static void emit_log_char(char c) | 1150 | for_each_console(con) { |
670 | { | 1151 | if (exclusive_console && con != exclusive_console) |
671 | LOG_BUF(log_end) = c; | 1152 | continue; |
672 | log_end++; | 1153 | if (!(con->flags & CON_ENABLED)) |
673 | if (log_end - log_start > log_buf_len) | 1154 | continue; |
674 | log_start = log_end - log_buf_len; | 1155 | if (!con->write) |
675 | if (log_end - con_start > log_buf_len) | 1156 | continue; |
676 | con_start = log_end - log_buf_len; | 1157 | if (!cpu_online(smp_processor_id()) && |
677 | if (logged_chars < log_buf_len) | 1158 | !(con->flags & CON_ANYTIME)) |
678 | logged_chars++; | 1159 | continue; |
1160 | con->write(con, text, len); | ||
1161 | } | ||
679 | } | 1162 | } |
680 | 1163 | ||
681 | /* | 1164 | /* |
@@ -700,16 +1183,6 @@ static void zap_locks(void) | |||
700 | sema_init(&console_sem, 1); | 1183 | sema_init(&console_sem, 1); |
701 | } | 1184 | } |
702 | 1185 | ||
703 | #if defined(CONFIG_PRINTK_TIME) | ||
704 | static bool printk_time = 1; | ||
705 | #else | ||
706 | static bool printk_time = 0; | ||
707 | #endif | ||
708 | module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR); | ||
709 | |||
710 | static bool always_kmsg_dump; | ||
711 | module_param_named(always_kmsg_dump, always_kmsg_dump, bool, S_IRUGO | S_IWUSR); | ||
712 | |||
713 | /* Check if we have any console registered that can be called early in boot. */ | 1186 | /* Check if we have any console registered that can be called early in boot. */ |
714 | static int have_callable_console(void) | 1187 | static int have_callable_console(void) |
715 | { | 1188 | { |
@@ -722,51 +1195,6 @@ static int have_callable_console(void) | |||
722 | return 0; | 1195 | return 0; |
723 | } | 1196 | } |
724 | 1197 | ||
725 | /** | ||
726 | * printk - print a kernel message | ||
727 | * @fmt: format string | ||
728 | * | ||
729 | * This is printk(). It can be called from any context. We want it to work. | ||
730 | * | ||
731 | * We try to grab the console_lock. If we succeed, it's easy - we log the output and | ||
732 | * call the console drivers. If we fail to get the semaphore we place the output | ||
733 | * into the log buffer and return. The current holder of the console_sem will | ||
734 | * notice the new output in console_unlock(); and will send it to the | ||
735 | * consoles before releasing the lock. | ||
736 | * | ||
737 | * One effect of this deferred printing is that code which calls printk() and | ||
738 | * then changes console_loglevel may break. This is because console_loglevel | ||
739 | * is inspected when the actual printing occurs. | ||
740 | * | ||
741 | * See also: | ||
742 | * printf(3) | ||
743 | * | ||
744 | * See the vsnprintf() documentation for format string extensions over C99. | ||
745 | */ | ||
746 | |||
747 | asmlinkage int printk(const char *fmt, ...) | ||
748 | { | ||
749 | va_list args; | ||
750 | int r; | ||
751 | |||
752 | #ifdef CONFIG_KGDB_KDB | ||
753 | if (unlikely(kdb_trap_printk)) { | ||
754 | va_start(args, fmt); | ||
755 | r = vkdb_printf(fmt, args); | ||
756 | va_end(args); | ||
757 | return r; | ||
758 | } | ||
759 | #endif | ||
760 | va_start(args, fmt); | ||
761 | r = vprintk(fmt, args); | ||
762 | va_end(args); | ||
763 | |||
764 | return r; | ||
765 | } | ||
766 | |||
767 | /* cpu currently holding logbuf_lock */ | ||
768 | static volatile unsigned int printk_cpu = UINT_MAX; | ||
769 | |||
770 | /* | 1198 | /* |
771 | * Can we actually use the console at this time on this cpu? | 1199 | * Can we actually use the console at this time on this cpu? |
772 | * | 1200 | * |
@@ -810,17 +1238,12 @@ static int console_trylock_for_printk(unsigned int cpu) | |||
810 | retval = 0; | 1238 | retval = 0; |
811 | } | 1239 | } |
812 | } | 1240 | } |
813 | printk_cpu = UINT_MAX; | 1241 | logbuf_cpu = UINT_MAX; |
814 | if (wake) | 1242 | if (wake) |
815 | up(&console_sem); | 1243 | up(&console_sem); |
816 | raw_spin_unlock(&logbuf_lock); | 1244 | raw_spin_unlock(&logbuf_lock); |
817 | return retval; | 1245 | return retval; |
818 | } | 1246 | } |
819 | static const char recursion_bug_msg [] = | ||
820 | KERN_CRIT "BUG: recent printk recursion!\n"; | ||
821 | static int recursion_bug; | ||
822 | static int new_text_line = 1; | ||
823 | static char printk_buf[1024]; | ||
824 | 1247 | ||
825 | int printk_delay_msec __read_mostly; | 1248 | int printk_delay_msec __read_mostly; |
826 | 1249 | ||
@@ -836,15 +1259,23 @@ static inline void printk_delay(void) | |||
836 | } | 1259 | } |
837 | } | 1260 | } |
838 | 1261 | ||
839 | asmlinkage int vprintk(const char *fmt, va_list args) | 1262 | asmlinkage int vprintk_emit(int facility, int level, |
1263 | const char *dict, size_t dictlen, | ||
1264 | const char *fmt, va_list args) | ||
840 | { | 1265 | { |
841 | int printed_len = 0; | 1266 | static int recursion_bug; |
842 | int current_log_level = default_message_loglevel; | 1267 | static char cont_buf[LOG_LINE_MAX]; |
1268 | static size_t cont_len; | ||
1269 | static int cont_level; | ||
1270 | static struct task_struct *cont_task; | ||
1271 | static char textbuf[LOG_LINE_MAX]; | ||
1272 | char *text = textbuf; | ||
1273 | size_t text_len; | ||
843 | unsigned long flags; | 1274 | unsigned long flags; |
844 | int this_cpu; | 1275 | int this_cpu; |
845 | char *p; | 1276 | bool newline = false; |
846 | size_t plen; | 1277 | bool prefix = false; |
847 | char special; | 1278 | int printed_len = 0; |
848 | 1279 | ||
849 | boot_delay_msec(); | 1280 | boot_delay_msec(); |
850 | printk_delay(); | 1281 | printk_delay(); |
@@ -856,7 +1287,7 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
856 | /* | 1287 | /* |
857 | * Ouch, printk recursed into itself! | 1288 | * Ouch, printk recursed into itself! |
858 | */ | 1289 | */ |
859 | if (unlikely(printk_cpu == this_cpu)) { | 1290 | if (unlikely(logbuf_cpu == this_cpu)) { |
860 | /* | 1291 | /* |
861 | * If a crash is occurring during printk() on this CPU, | 1292 | * If a crash is occurring during printk() on this CPU, |
862 | * then try to get the crash message out but make sure | 1293 | * then try to get the crash message out but make sure |
@@ -873,97 +1304,110 @@ asmlinkage int vprintk(const char *fmt, va_list args) | |||
873 | 1304 | ||
874 | lockdep_off(); | 1305 | lockdep_off(); |
875 | raw_spin_lock(&logbuf_lock); | 1306 | raw_spin_lock(&logbuf_lock); |
876 | printk_cpu = this_cpu; | 1307 | logbuf_cpu = this_cpu; |
877 | 1308 | ||
878 | if (recursion_bug) { | 1309 | if (recursion_bug) { |
1310 | static const char recursion_msg[] = | ||
1311 | "BUG: recent printk recursion!"; | ||
1312 | |||
879 | recursion_bug = 0; | 1313 | recursion_bug = 0; |
880 | strcpy(printk_buf, recursion_bug_msg); | 1314 | printed_len += strlen(recursion_msg); |
881 | printed_len = strlen(recursion_bug_msg); | 1315 | /* emit KERN_CRIT message */ |
1316 | log_store(0, 2, NULL, 0, recursion_msg, printed_len); | ||
882 | } | 1317 | } |
883 | /* Emit the output into the temporary buffer */ | ||
884 | printed_len += vscnprintf(printk_buf + printed_len, | ||
885 | sizeof(printk_buf) - printed_len, fmt, args); | ||
886 | 1318 | ||
887 | p = printk_buf; | 1319 | /* |
1320 | * The printf needs to come first; we need the syslog | ||
1321 | * prefix which might be passed-in as a parameter. | ||
1322 | */ | ||
1323 | text_len = vscnprintf(text, sizeof(textbuf), fmt, args); | ||
888 | 1324 | ||
889 | /* Read log level and handle special printk prefix */ | 1325 | /* mark and strip a trailing newline */ |
890 | plen = log_prefix(p, ¤t_log_level, &special); | 1326 | if (text_len && text[text_len-1] == '\n') { |
891 | if (plen) { | 1327 | text_len--; |
892 | p += plen; | 1328 | newline = true; |
1329 | } | ||
893 | 1330 | ||
894 | switch (special) { | 1331 | /* strip syslog prefix and extract log level or control flags */ |
895 | case 'c': /* Strip <c> KERN_CONT, continue line */ | 1332 | if (text[0] == '<' && text[1] && text[2] == '>') { |
896 | plen = 0; | 1333 | switch (text[1]) { |
897 | break; | 1334 | case '0' ... '7': |
898 | case 'd': /* Strip <d> KERN_DEFAULT, start new line */ | 1335 | if (level == -1) |
899 | plen = 0; | 1336 | level = text[1] - '0'; |
900 | default: | 1337 | case 'd': /* KERN_DEFAULT */ |
901 | if (!new_text_line) { | 1338 | prefix = true; |
902 | emit_log_char('\n'); | 1339 | case 'c': /* KERN_CONT */ |
903 | new_text_line = 1; | 1340 | text += 3; |
904 | } | 1341 | text_len -= 3; |
905 | } | 1342 | } |
906 | } | 1343 | } |
907 | 1344 | ||
908 | /* | 1345 | if (level == -1) |
909 | * Copy the output into log_buf. If the caller didn't provide | 1346 | level = default_message_loglevel; |
910 | * the appropriate log prefix, we insert them here | ||
911 | */ | ||
912 | for (; *p; p++) { | ||
913 | if (new_text_line) { | ||
914 | new_text_line = 0; | ||
915 | |||
916 | if (plen) { | ||
917 | /* Copy original log prefix */ | ||
918 | int i; | ||
919 | |||
920 | for (i = 0; i < plen; i++) | ||
921 | emit_log_char(printk_buf[i]); | ||
922 | printed_len += plen; | ||
923 | } else { | ||
924 | /* Add log prefix */ | ||
925 | emit_log_char('<'); | ||
926 | emit_log_char(current_log_level + '0'); | ||
927 | emit_log_char('>'); | ||
928 | printed_len += 3; | ||
929 | } | ||
930 | 1347 | ||
931 | if (printk_time) { | 1348 | if (dict) { |
932 | /* Add the current time stamp */ | 1349 | prefix = true; |
933 | char tbuf[50], *tp; | 1350 | newline = true; |
934 | unsigned tlen; | 1351 | } |
935 | unsigned long long t; | ||
936 | unsigned long nanosec_rem; | ||
937 | |||
938 | t = cpu_clock(printk_cpu); | ||
939 | nanosec_rem = do_div(t, 1000000000); | ||
940 | tlen = sprintf(tbuf, "[%5lu.%06lu] ", | ||
941 | (unsigned long) t, | ||
942 | nanosec_rem / 1000); | ||
943 | |||
944 | for (tp = tbuf; tp < tbuf + tlen; tp++) | ||
945 | emit_log_char(*tp); | ||
946 | printed_len += tlen; | ||
947 | } | ||
948 | 1352 | ||
949 | if (!*p) | 1353 | if (!newline) { |
950 | break; | 1354 | if (cont_len && (prefix || cont_task != current)) { |
1355 | /* | ||
1356 | * Flush earlier buffer, which is either from a | ||
1357 | * different thread, or when we got a new prefix. | ||
1358 | */ | ||
1359 | log_store(facility, cont_level, NULL, 0, cont_buf, cont_len); | ||
1360 | cont_len = 0; | ||
951 | } | 1361 | } |
952 | 1362 | ||
953 | emit_log_char(*p); | 1363 | if (!cont_len) { |
954 | if (*p == '\n') | 1364 | cont_level = level; |
955 | new_text_line = 1; | 1365 | cont_task = current; |
1366 | } | ||
1367 | |||
1368 | /* buffer or append to earlier buffer from the same thread */ | ||
1369 | if (cont_len + text_len > sizeof(cont_buf)) | ||
1370 | text_len = sizeof(cont_buf) - cont_len; | ||
1371 | memcpy(cont_buf + cont_len, text, text_len); | ||
1372 | cont_len += text_len; | ||
1373 | } else { | ||
1374 | if (cont_len && cont_task == current) { | ||
1375 | if (prefix) { | ||
1376 | /* | ||
1377 | * New prefix from the same thread; flush. We | ||
1378 | * either got no earlier newline, or we race | ||
1379 | * with an interrupt. | ||
1380 | */ | ||
1381 | log_store(facility, cont_level, | ||
1382 | NULL, 0, cont_buf, cont_len); | ||
1383 | cont_len = 0; | ||
1384 | } | ||
1385 | |||
1386 | /* append to the earlier buffer and flush */ | ||
1387 | if (cont_len + text_len > sizeof(cont_buf)) | ||
1388 | text_len = sizeof(cont_buf) - cont_len; | ||
1389 | memcpy(cont_buf + cont_len, text, text_len); | ||
1390 | cont_len += text_len; | ||
1391 | log_store(facility, cont_level, | ||
1392 | NULL, 0, cont_buf, cont_len); | ||
1393 | cont_len = 0; | ||
1394 | cont_task = NULL; | ||
1395 | printed_len = cont_len; | ||
1396 | } else { | ||
1397 | /* ordinary single and terminated line */ | ||
1398 | log_store(facility, level, | ||
1399 | dict, dictlen, text, text_len); | ||
1400 | printed_len = text_len; | ||
1401 | } | ||
956 | } | 1402 | } |
957 | 1403 | ||
958 | /* | 1404 | /* |
959 | * Try to acquire and then immediately release the | 1405 | * Try to acquire and then immediately release the console semaphore. |
960 | * console semaphore. The release will do all the | 1406 | * The release will print out buffers and wake up /dev/kmsg and syslog() |
961 | * actual magic (print out buffers, wake up klogd, | 1407 | * users. |
962 | * etc). | ||
963 | * | 1408 | * |
964 | * The console_trylock_for_printk() function | 1409 | * The console_trylock_for_printk() function will release 'logbuf_lock' |
965 | * will release 'logbuf_lock' regardless of whether it | 1410 | * regardless of whether it actually gets the console semaphore or not. |
966 | * actually gets the semaphore or not. | ||
967 | */ | 1411 | */ |
968 | if (console_trylock_for_printk(this_cpu)) | 1412 | if (console_trylock_for_printk(this_cpu)) |
969 | console_unlock(); | 1413 | console_unlock(); |
@@ -974,16 +1418,81 @@ out_restore_irqs: | |||
974 | 1418 | ||
975 | return printed_len; | 1419 | return printed_len; |
976 | } | 1420 | } |
977 | EXPORT_SYMBOL(printk); | 1421 | EXPORT_SYMBOL(vprintk_emit); |
978 | EXPORT_SYMBOL(vprintk); | ||
979 | 1422 | ||
980 | #else | 1423 | asmlinkage int vprintk(const char *fmt, va_list args) |
1424 | { | ||
1425 | return vprintk_emit(0, -1, NULL, 0, fmt, args); | ||
1426 | } | ||
1427 | EXPORT_SYMBOL(vprintk); | ||
981 | 1428 | ||
982 | static void call_console_drivers(unsigned start, unsigned end) | 1429 | asmlinkage int printk_emit(int facility, int level, |
1430 | const char *dict, size_t dictlen, | ||
1431 | const char *fmt, ...) | ||
983 | { | 1432 | { |
1433 | va_list args; | ||
1434 | int r; | ||
1435 | |||
1436 | va_start(args, fmt); | ||
1437 | r = vprintk_emit(facility, level, dict, dictlen, fmt, args); | ||
1438 | va_end(args); | ||
1439 | |||
1440 | return r; | ||
984 | } | 1441 | } |
1442 | EXPORT_SYMBOL(printk_emit); | ||
985 | 1443 | ||
1444 | /** | ||
1445 | * printk - print a kernel message | ||
1446 | * @fmt: format string | ||
1447 | * | ||
1448 | * This is printk(). It can be called from any context. We want it to work. | ||
1449 | * | ||
1450 | * We try to grab the console_lock. If we succeed, it's easy - we log the | ||
1451 | * output and call the console drivers. If we fail to get the semaphore, we | ||
1452 | * place the output into the log buffer and return. The current holder of | ||
1453 | * the console_sem will notice the new output in console_unlock(); and will | ||
1454 | * send it to the consoles before releasing the lock. | ||
1455 | * | ||
1456 | * One effect of this deferred printing is that code which calls printk() and | ||
1457 | * then changes console_loglevel may break. This is because console_loglevel | ||
1458 | * is inspected when the actual printing occurs. | ||
1459 | * | ||
1460 | * See also: | ||
1461 | * printf(3) | ||
1462 | * | ||
1463 | * See the vsnprintf() documentation for format string extensions over C99. | ||
1464 | */ | ||
1465 | asmlinkage int printk(const char *fmt, ...) | ||
1466 | { | ||
1467 | va_list args; | ||
1468 | int r; | ||
1469 | |||
1470 | #ifdef CONFIG_KGDB_KDB | ||
1471 | if (unlikely(kdb_trap_printk)) { | ||
1472 | va_start(args, fmt); | ||
1473 | r = vkdb_printf(fmt, args); | ||
1474 | va_end(args); | ||
1475 | return r; | ||
1476 | } | ||
986 | #endif | 1477 | #endif |
1478 | va_start(args, fmt); | ||
1479 | r = vprintk_emit(0, -1, NULL, 0, fmt, args); | ||
1480 | va_end(args); | ||
1481 | |||
1482 | return r; | ||
1483 | } | ||
1484 | EXPORT_SYMBOL(printk); | ||
1485 | |||
1486 | #else | ||
1487 | |||
1488 | #define LOG_LINE_MAX 0 | ||
1489 | static struct log *log_from_idx(u32 idx) { return NULL; } | ||
1490 | static u32 log_next(u32 idx) { return 0; } | ||
1491 | static void call_console_drivers(int level, const char *text, size_t len) {} | ||
1492 | static size_t msg_print_text(const struct log *msg, bool syslog, | ||
1493 | char *buf, size_t size) { return 0; } | ||
1494 | |||
1495 | #endif /* CONFIG_PRINTK */ | ||
987 | 1496 | ||
988 | static int __add_preferred_console(char *name, int idx, char *options, | 1497 | static int __add_preferred_console(char *name, int idx, char *options, |
989 | char *brl_options) | 1498 | char *brl_options) |
@@ -1217,7 +1726,7 @@ int is_console_locked(void) | |||
1217 | } | 1726 | } |
1218 | 1727 | ||
1219 | /* | 1728 | /* |
1220 | * Delayed printk facility, for scheduler-internal messages: | 1729 | * Delayed printk version, for scheduler-internal messages: |
1221 | */ | 1730 | */ |
1222 | #define PRINTK_BUF_SIZE 512 | 1731 | #define PRINTK_BUF_SIZE 512 |
1223 | 1732 | ||
@@ -1253,6 +1762,10 @@ void wake_up_klogd(void) | |||
1253 | this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP); | 1762 | this_cpu_or(printk_pending, PRINTK_PENDING_WAKEUP); |
1254 | } | 1763 | } |
1255 | 1764 | ||
1765 | /* the next printk record to write to the console */ | ||
1766 | static u64 console_seq; | ||
1767 | static u32 console_idx; | ||
1768 | |||
1256 | /** | 1769 | /** |
1257 | * console_unlock - unlock the console system | 1770 | * console_unlock - unlock the console system |
1258 | * | 1771 | * |
@@ -1263,15 +1776,16 @@ void wake_up_klogd(void) | |||
1263 | * by printk(). If this is the case, console_unlock(); emits | 1776 | * by printk(). If this is the case, console_unlock(); emits |
1264 | * the output prior to releasing the lock. | 1777 | * the output prior to releasing the lock. |
1265 | * | 1778 | * |
1266 | * If there is output waiting for klogd, we wake it up. | 1779 | * If there is output waiting, we wake /dev/kmsg and syslog() users. |
1267 | * | 1780 | * |
1268 | * console_unlock(); may be called from any context. | 1781 | * console_unlock(); may be called from any context. |
1269 | */ | 1782 | */ |
1270 | void console_unlock(void) | 1783 | void console_unlock(void) |
1271 | { | 1784 | { |
1785 | static u64 seen_seq; | ||
1272 | unsigned long flags; | 1786 | unsigned long flags; |
1273 | unsigned _con_start, _log_end; | 1787 | bool wake_klogd = false; |
1274 | unsigned wake_klogd = 0, retry = 0; | 1788 | bool retry; |
1275 | 1789 | ||
1276 | if (console_suspended) { | 1790 | if (console_suspended) { |
1277 | up(&console_sem); | 1791 | up(&console_sem); |
@@ -1281,17 +1795,38 @@ void console_unlock(void) | |||
1281 | console_may_schedule = 0; | 1795 | console_may_schedule = 0; |
1282 | 1796 | ||
1283 | again: | 1797 | again: |
1284 | for ( ; ; ) { | 1798 | for (;;) { |
1799 | struct log *msg; | ||
1800 | static char text[LOG_LINE_MAX]; | ||
1801 | size_t len; | ||
1802 | int level; | ||
1803 | |||
1285 | raw_spin_lock_irqsave(&logbuf_lock, flags); | 1804 | raw_spin_lock_irqsave(&logbuf_lock, flags); |
1286 | wake_klogd |= log_start - log_end; | 1805 | if (seen_seq != log_next_seq) { |
1287 | if (con_start == log_end) | 1806 | wake_klogd = true; |
1288 | break; /* Nothing to print */ | 1807 | seen_seq = log_next_seq; |
1289 | _con_start = con_start; | 1808 | } |
1290 | _log_end = log_end; | 1809 | |
1291 | con_start = log_end; /* Flush */ | 1810 | if (console_seq < log_first_seq) { |
1811 | /* messages are gone, move to first one */ | ||
1812 | console_seq = log_first_seq; | ||
1813 | console_idx = log_first_idx; | ||
1814 | } | ||
1815 | |||
1816 | if (console_seq == log_next_seq) | ||
1817 | break; | ||
1818 | |||
1819 | msg = log_from_idx(console_idx); | ||
1820 | level = msg->level & 7; | ||
1821 | |||
1822 | len = msg_print_text(msg, false, text, sizeof(text)); | ||
1823 | |||
1824 | console_idx = log_next(console_idx); | ||
1825 | console_seq++; | ||
1292 | raw_spin_unlock(&logbuf_lock); | 1826 | raw_spin_unlock(&logbuf_lock); |
1827 | |||
1293 | stop_critical_timings(); /* don't trace print latency */ | 1828 | stop_critical_timings(); /* don't trace print latency */ |
1294 | call_console_drivers(_con_start, _log_end); | 1829 | call_console_drivers(level, text, len); |
1295 | start_critical_timings(); | 1830 | start_critical_timings(); |
1296 | local_irq_restore(flags); | 1831 | local_irq_restore(flags); |
1297 | } | 1832 | } |
@@ -1312,8 +1847,7 @@ again: | |||
1312 | * flush, no worries. | 1847 | * flush, no worries. |
1313 | */ | 1848 | */ |
1314 | raw_spin_lock(&logbuf_lock); | 1849 | raw_spin_lock(&logbuf_lock); |
1315 | if (con_start != log_end) | 1850 | retry = console_seq != log_next_seq; |
1316 | retry = 1; | ||
1317 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | 1851 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
1318 | 1852 | ||
1319 | if (retry && console_trylock()) | 1853 | if (retry && console_trylock()) |
@@ -1549,7 +2083,8 @@ void register_console(struct console *newcon) | |||
1549 | * for us. | 2083 | * for us. |
1550 | */ | 2084 | */ |
1551 | raw_spin_lock_irqsave(&logbuf_lock, flags); | 2085 | raw_spin_lock_irqsave(&logbuf_lock, flags); |
1552 | con_start = log_start; | 2086 | console_seq = syslog_seq; |
2087 | console_idx = syslog_idx; | ||
1553 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | 2088 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); |
1554 | /* | 2089 | /* |
1555 | * We're about to replay the log buffer. Only do this to the | 2090 | * We're about to replay the log buffer. Only do this to the |
@@ -1758,6 +2293,9 @@ int kmsg_dump_unregister(struct kmsg_dumper *dumper) | |||
1758 | } | 2293 | } |
1759 | EXPORT_SYMBOL_GPL(kmsg_dump_unregister); | 2294 | EXPORT_SYMBOL_GPL(kmsg_dump_unregister); |
1760 | 2295 | ||
2296 | static bool always_kmsg_dump; | ||
2297 | module_param_named(always_kmsg_dump, always_kmsg_dump, bool, S_IRUGO | S_IWUSR); | ||
2298 | |||
1761 | /** | 2299 | /** |
1762 | * kmsg_dump - dump kernel log to kernel message dumpers. | 2300 | * kmsg_dump - dump kernel log to kernel message dumpers. |
1763 | * @reason: the reason (oops, panic etc) for dumping | 2301 | * @reason: the reason (oops, panic etc) for dumping |
@@ -1767,8 +2305,7 @@ EXPORT_SYMBOL_GPL(kmsg_dump_unregister); | |||
1767 | */ | 2305 | */ |
1768 | void kmsg_dump(enum kmsg_dump_reason reason) | 2306 | void kmsg_dump(enum kmsg_dump_reason reason) |
1769 | { | 2307 | { |
1770 | unsigned long end; | 2308 | u64 idx; |
1771 | unsigned chars; | ||
1772 | struct kmsg_dumper *dumper; | 2309 | struct kmsg_dumper *dumper; |
1773 | const char *s1, *s2; | 2310 | const char *s1, *s2; |
1774 | unsigned long l1, l2; | 2311 | unsigned long l1, l2; |
@@ -1780,24 +2317,27 @@ void kmsg_dump(enum kmsg_dump_reason reason) | |||
1780 | /* Theoretically, the log could move on after we do this, but | 2317 | /* Theoretically, the log could move on after we do this, but |
1781 | there's not a lot we can do about that. The new messages | 2318 | there's not a lot we can do about that. The new messages |
1782 | will overwrite the start of what we dump. */ | 2319 | will overwrite the start of what we dump. */ |
2320 | |||
1783 | raw_spin_lock_irqsave(&logbuf_lock, flags); | 2321 | raw_spin_lock_irqsave(&logbuf_lock, flags); |
1784 | end = log_end & LOG_BUF_MASK; | 2322 | if (syslog_seq < log_first_seq) |
1785 | chars = logged_chars; | 2323 | idx = syslog_idx; |
1786 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | 2324 | else |
2325 | idx = log_first_idx; | ||
1787 | 2326 | ||
1788 | if (chars > end) { | 2327 | if (idx > log_next_idx) { |
1789 | s1 = log_buf + log_buf_len - chars + end; | 2328 | s1 = log_buf; |
1790 | l1 = chars - end; | 2329 | l1 = log_next_idx; |
1791 | 2330 | ||
1792 | s2 = log_buf; | 2331 | s2 = log_buf + idx; |
1793 | l2 = end; | 2332 | l2 = log_buf_len - idx; |
1794 | } else { | 2333 | } else { |
1795 | s1 = ""; | 2334 | s1 = ""; |
1796 | l1 = 0; | 2335 | l1 = 0; |
1797 | 2336 | ||
1798 | s2 = log_buf + end - chars; | 2337 | s2 = log_buf + idx; |
1799 | l2 = chars; | 2338 | l2 = log_next_idx - idx; |
1800 | } | 2339 | } |
2340 | raw_spin_unlock_irqrestore(&logbuf_lock, flags); | ||
1801 | 2341 | ||
1802 | rcu_read_lock(); | 2342 | rcu_read_lock(); |
1803 | list_for_each_entry_rcu(dumper, &dump_list, list) | 2343 | list_for_each_entry_rcu(dumper, &dump_list, list) |
diff --git a/lib/Kconfig b/lib/Kconfig index 4a8aba2e5cc0..0e25c03939e3 100644 --- a/lib/Kconfig +++ b/lib/Kconfig | |||
@@ -353,6 +353,14 @@ config CORDIC | |||
353 | This option provides an implementation of the CORDIC algorithm; | 353 | This option provides an implementation of the CORDIC algorithm; |
354 | calculations are in fixed point. Module will be called cordic. | 354 | calculations are in fixed point. Module will be called cordic. |
355 | 355 | ||
356 | config DDR | ||
357 | bool "JEDEC DDR data" | ||
358 | help | ||
359 | Data from JEDEC specs for DDR SDRAM memories, | ||
360 | particularly the AC timing parameters and addressing | ||
361 | information. This data is useful for drivers handling | ||
362 | DDR SDRAM controllers. | ||
363 | |||
356 | config MPILIB | 364 | config MPILIB |
357 | tristate | 365 | tristate |
358 | select CLZ_TAB | 366 | select CLZ_TAB |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 6777153f18f3..e11934177030 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -3,12 +3,16 @@ config PRINTK_TIME | |||
3 | bool "Show timing information on printks" | 3 | bool "Show timing information on printks" |
4 | depends on PRINTK | 4 | depends on PRINTK |
5 | help | 5 | help |
6 | Selecting this option causes timing information to be | 6 | Selecting this option causes time stamps of the printk() |
7 | included in printk output. This allows you to measure | 7 | messages to be added to the output of the syslog() system |
8 | the interval between kernel operations, including bootup | 8 | call and at the console. |
9 | operations. This is useful for identifying long delays | 9 | |
10 | in kernel startup. Or add printk.time=1 at boot-time. | 10 | The timestamp is always recorded internally, and exported |
11 | See Documentation/kernel-parameters.txt | 11 | to /dev/kmsg. This flag just specifies if the timestamp should |
12 | be included, not that the timestamp is recorded. | ||
13 | |||
14 | The behavior is also controlled by the kernel command line | ||
15 | parameter printk.time=1. See Documentation/kernel-parameters.txt | ||
12 | 16 | ||
13 | config DEFAULT_MESSAGE_LOGLEVEL | 17 | config DEFAULT_MESSAGE_LOGLEVEL |
14 | int "Default message log level (1-7)" | 18 | int "Default message log level (1-7)" |
@@ -1205,8 +1209,13 @@ config DYNAMIC_DEBUG | |||
1205 | otherwise be available at runtime. These messages can then be | 1209 | otherwise be available at runtime. These messages can then be |
1206 | enabled/disabled based on various levels of scope - per source file, | 1210 | enabled/disabled based on various levels of scope - per source file, |
1207 | function, module, format string, and line number. This mechanism | 1211 | function, module, format string, and line number. This mechanism |
1208 | implicitly enables all pr_debug() and dev_dbg() calls. The impact of | 1212 | implicitly compiles in all pr_debug() and dev_dbg() calls, which |
1209 | this compile option is a larger kernel text size of about 2%. | 1213 | enlarges the kernel text size by about 2%. |
1214 | |||
1215 | If a source file is compiled with DEBUG flag set, any | ||
1216 | pr_debug() calls in it are enabled by default, but can be | ||
1217 | disabled at runtime as below. Note that DEBUG flag is | ||
1218 | turned on by many CONFIG_*DEBUG* options. | ||
1210 | 1219 | ||
1211 | Usage: | 1220 | Usage: |
1212 | 1221 | ||
@@ -1223,16 +1232,16 @@ config DYNAMIC_DEBUG | |||
1223 | lineno : line number of the debug statement | 1232 | lineno : line number of the debug statement |
1224 | module : module that contains the debug statement | 1233 | module : module that contains the debug statement |
1225 | function : function that contains the debug statement | 1234 | function : function that contains the debug statement |
1226 | flags : 'p' means the line is turned 'on' for printing | 1235 | flags : '=p' means the line is turned 'on' for printing |
1227 | format : the format used for the debug statement | 1236 | format : the format used for the debug statement |
1228 | 1237 | ||
1229 | From a live system: | 1238 | From a live system: |
1230 | 1239 | ||
1231 | nullarbor:~ # cat <debugfs>/dynamic_debug/control | 1240 | nullarbor:~ # cat <debugfs>/dynamic_debug/control |
1232 | # filename:lineno [module]function flags format | 1241 | # filename:lineno [module]function flags format |
1233 | fs/aio.c:222 [aio]__put_ioctx - "__put_ioctx:\040freeing\040%p\012" | 1242 | fs/aio.c:222 [aio]__put_ioctx =_ "__put_ioctx:\040freeing\040%p\012" |
1234 | fs/aio.c:248 [aio]ioctx_alloc - "ENOMEM:\040nr_events\040too\040high\012" | 1243 | fs/aio.c:248 [aio]ioctx_alloc =_ "ENOMEM:\040nr_events\040too\040high\012" |
1235 | fs/aio.c:1770 [aio]sys_io_cancel - "calling\040cancel\012" | 1244 | fs/aio.c:1770 [aio]sys_io_cancel =_ "calling\040cancel\012" |
1236 | 1245 | ||
1237 | Example usage: | 1246 | Example usage: |
1238 | 1247 | ||
diff --git a/lib/Makefile b/lib/Makefile index 18515f0267c4..74290c9e2864 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
@@ -123,6 +123,8 @@ obj-$(CONFIG_SIGNATURE) += digsig.o | |||
123 | 123 | ||
124 | obj-$(CONFIG_CLZ_TAB) += clz_tab.o | 124 | obj-$(CONFIG_CLZ_TAB) += clz_tab.o |
125 | 125 | ||
126 | obj-$(CONFIG_DDR) += jedec_ddr_data.o | ||
127 | |||
126 | hostprogs-y := gen_crc32table | 128 | hostprogs-y := gen_crc32table |
127 | clean-files := crc32table.h | 129 | clean-files := crc32table.h |
128 | 130 | ||
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 310c753cf83e..7ca29a0a3019 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c | |||
@@ -107,20 +107,22 @@ static char *ddebug_describe_flags(struct _ddebug *dp, char *buf, | |||
107 | return buf; | 107 | return buf; |
108 | } | 108 | } |
109 | 109 | ||
110 | #define vpr_info_dq(q, msg) \ | 110 | #define vpr_info(fmt, ...) \ |
111 | do { \ | 111 | if (verbose) do { pr_info(fmt, ##__VA_ARGS__); } while (0) |
112 | if (verbose) \ | 112 | |
113 | /* trim last char off format print */ \ | 113 | #define vpr_info_dq(q, msg) \ |
114 | pr_info("%s: func=\"%s\" file=\"%s\" " \ | 114 | do { \ |
115 | "module=\"%s\" format=\"%.*s\" " \ | 115 | /* trim last char off format print */ \ |
116 | "lineno=%u-%u", \ | 116 | vpr_info("%s: func=\"%s\" file=\"%s\" " \ |
117 | msg, \ | 117 | "module=\"%s\" format=\"%.*s\" " \ |
118 | q->function ? q->function : "", \ | 118 | "lineno=%u-%u", \ |
119 | q->filename ? q->filename : "", \ | 119 | msg, \ |
120 | q->module ? q->module : "", \ | 120 | q->function ? q->function : "", \ |
121 | (int)(q->format ? strlen(q->format) - 1 : 0), \ | 121 | q->filename ? q->filename : "", \ |
122 | q->format ? q->format : "", \ | 122 | q->module ? q->module : "", \ |
123 | q->first_lineno, q->last_lineno); \ | 123 | (int)(q->format ? strlen(q->format) - 1 : 0), \ |
124 | q->format ? q->format : "", \ | ||
125 | q->first_lineno, q->last_lineno); \ | ||
124 | } while (0) | 126 | } while (0) |
125 | 127 | ||
126 | /* | 128 | /* |
@@ -180,12 +182,11 @@ static int ddebug_change(const struct ddebug_query *query, | |||
180 | if (newflags == dp->flags) | 182 | if (newflags == dp->flags) |
181 | continue; | 183 | continue; |
182 | dp->flags = newflags; | 184 | dp->flags = newflags; |
183 | if (verbose) | 185 | vpr_info("changed %s:%d [%s]%s =%s\n", |
184 | pr_info("changed %s:%d [%s]%s =%s\n", | 186 | trim_prefix(dp->filename), dp->lineno, |
185 | trim_prefix(dp->filename), dp->lineno, | 187 | dt->mod_name, dp->function, |
186 | dt->mod_name, dp->function, | 188 | ddebug_describe_flags(dp, flagbuf, |
187 | ddebug_describe_flags(dp, flagbuf, | 189 | sizeof(flagbuf))); |
188 | sizeof(flagbuf))); | ||
189 | } | 190 | } |
190 | } | 191 | } |
191 | mutex_unlock(&ddebug_lock); | 192 | mutex_unlock(&ddebug_lock); |
@@ -337,7 +338,7 @@ static int check_set(const char **dest, char *src, char *name) | |||
337 | * Returns 0 on success, <0 on error. | 338 | * Returns 0 on success, <0 on error. |
338 | */ | 339 | */ |
339 | static int ddebug_parse_query(char *words[], int nwords, | 340 | static int ddebug_parse_query(char *words[], int nwords, |
340 | struct ddebug_query *query) | 341 | struct ddebug_query *query, const char *modname) |
341 | { | 342 | { |
342 | unsigned int i; | 343 | unsigned int i; |
343 | int rc; | 344 | int rc; |
@@ -347,6 +348,10 @@ static int ddebug_parse_query(char *words[], int nwords, | |||
347 | return -EINVAL; | 348 | return -EINVAL; |
348 | memset(query, 0, sizeof(*query)); | 349 | memset(query, 0, sizeof(*query)); |
349 | 350 | ||
351 | if (modname) | ||
352 | /* support $modname.dyndbg=<multiple queries> */ | ||
353 | query->module = modname; | ||
354 | |||
350 | for (i = 0 ; i < nwords ; i += 2) { | 355 | for (i = 0 ; i < nwords ; i += 2) { |
351 | if (!strcmp(words[i], "func")) | 356 | if (!strcmp(words[i], "func")) |
352 | rc = check_set(&query->function, words[i+1], "func"); | 357 | rc = check_set(&query->function, words[i+1], "func"); |
@@ -410,8 +415,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, | |||
410 | default: | 415 | default: |
411 | return -EINVAL; | 416 | return -EINVAL; |
412 | } | 417 | } |
413 | if (verbose) | 418 | vpr_info("op='%c'\n", op); |
414 | pr_info("op='%c'\n", op); | ||
415 | 419 | ||
416 | for ( ; *str ; ++str) { | 420 | for ( ; *str ; ++str) { |
417 | for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) { | 421 | for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) { |
@@ -423,8 +427,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, | |||
423 | if (i < 0) | 427 | if (i < 0) |
424 | return -EINVAL; | 428 | return -EINVAL; |
425 | } | 429 | } |
426 | if (verbose) | 430 | vpr_info("flags=0x%x\n", flags); |
427 | pr_info("flags=0x%x\n", flags); | ||
428 | 431 | ||
429 | /* calculate final *flagsp, *maskp according to mask and op */ | 432 | /* calculate final *flagsp, *maskp according to mask and op */ |
430 | switch (op) { | 433 | switch (op) { |
@@ -441,12 +444,11 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, | |||
441 | *flagsp = 0; | 444 | *flagsp = 0; |
442 | break; | 445 | break; |
443 | } | 446 | } |
444 | if (verbose) | 447 | vpr_info("*flagsp=0x%x *maskp=0x%x\n", *flagsp, *maskp); |
445 | pr_info("*flagsp=0x%x *maskp=0x%x\n", *flagsp, *maskp); | ||
446 | return 0; | 448 | return 0; |
447 | } | 449 | } |
448 | 450 | ||
449 | static int ddebug_exec_query(char *query_string) | 451 | static int ddebug_exec_query(char *query_string, const char *modname) |
450 | { | 452 | { |
451 | unsigned int flags = 0, mask = 0; | 453 | unsigned int flags = 0, mask = 0; |
452 | struct ddebug_query query; | 454 | struct ddebug_query query; |
@@ -457,7 +459,7 @@ static int ddebug_exec_query(char *query_string) | |||
457 | nwords = ddebug_tokenize(query_string, words, MAXWORDS); | 459 | nwords = ddebug_tokenize(query_string, words, MAXWORDS); |
458 | if (nwords <= 0) | 460 | if (nwords <= 0) |
459 | return -EINVAL; | 461 | return -EINVAL; |
460 | if (ddebug_parse_query(words, nwords-1, &query)) | 462 | if (ddebug_parse_query(words, nwords-1, &query, modname)) |
461 | return -EINVAL; | 463 | return -EINVAL; |
462 | if (ddebug_parse_flags(words[nwords-1], &flags, &mask)) | 464 | if (ddebug_parse_flags(words[nwords-1], &flags, &mask)) |
463 | return -EINVAL; | 465 | return -EINVAL; |
@@ -473,7 +475,7 @@ static int ddebug_exec_query(char *query_string) | |||
473 | last error or number of matching callsites. Module name is either | 475 | last error or number of matching callsites. Module name is either |
474 | in param (for boot arg) or perhaps in query string. | 476 | in param (for boot arg) or perhaps in query string. |
475 | */ | 477 | */ |
476 | static int ddebug_exec_queries(char *query) | 478 | static int ddebug_exec_queries(char *query, const char *modname) |
477 | { | 479 | { |
478 | char *split; | 480 | char *split; |
479 | int i, errs = 0, exitcode = 0, rc, nfound = 0; | 481 | int i, errs = 0, exitcode = 0, rc, nfound = 0; |
@@ -487,10 +489,9 @@ static int ddebug_exec_queries(char *query) | |||
487 | if (!query || !*query || *query == '#') | 489 | if (!query || !*query || *query == '#') |
488 | continue; | 490 | continue; |
489 | 491 | ||
490 | if (verbose) | 492 | vpr_info("query %d: \"%s\"\n", i, query); |
491 | pr_info("query %d: \"%s\"\n", i, query); | ||
492 | 493 | ||
493 | rc = ddebug_exec_query(query); | 494 | rc = ddebug_exec_query(query, modname); |
494 | if (rc < 0) { | 495 | if (rc < 0) { |
495 | errs++; | 496 | errs++; |
496 | exitcode = rc; | 497 | exitcode = rc; |
@@ -498,7 +499,7 @@ static int ddebug_exec_queries(char *query) | |||
498 | nfound += rc; | 499 | nfound += rc; |
499 | i++; | 500 | i++; |
500 | } | 501 | } |
501 | pr_info("processed %d queries, with %d matches, %d errs\n", | 502 | vpr_info("processed %d queries, with %d matches, %d errs\n", |
502 | i, nfound, errs); | 503 | i, nfound, errs); |
503 | 504 | ||
504 | if (exitcode) | 505 | if (exitcode) |
@@ -653,10 +654,9 @@ static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf, | |||
653 | return -EFAULT; | 654 | return -EFAULT; |
654 | } | 655 | } |
655 | tmpbuf[len] = '\0'; | 656 | tmpbuf[len] = '\0'; |
656 | if (verbose) | 657 | vpr_info("read %d bytes from userspace\n", (int)len); |
657 | pr_info("read %d bytes from userspace\n", (int)len); | ||
658 | 658 | ||
659 | ret = ddebug_exec_queries(tmpbuf); | 659 | ret = ddebug_exec_queries(tmpbuf, NULL); |
660 | kfree(tmpbuf); | 660 | kfree(tmpbuf); |
661 | if (ret < 0) | 661 | if (ret < 0) |
662 | return ret; | 662 | return ret; |
@@ -717,8 +717,7 @@ static void *ddebug_proc_start(struct seq_file *m, loff_t *pos) | |||
717 | struct _ddebug *dp; | 717 | struct _ddebug *dp; |
718 | int n = *pos; | 718 | int n = *pos; |
719 | 719 | ||
720 | if (verbose) | 720 | vpr_info("called m=%p *pos=%lld\n", m, (unsigned long long)*pos); |
721 | pr_info("called m=%p *pos=%lld\n", m, (unsigned long long)*pos); | ||
722 | 721 | ||
723 | mutex_lock(&ddebug_lock); | 722 | mutex_lock(&ddebug_lock); |
724 | 723 | ||
@@ -742,9 +741,8 @@ static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos) | |||
742 | struct ddebug_iter *iter = m->private; | 741 | struct ddebug_iter *iter = m->private; |
743 | struct _ddebug *dp; | 742 | struct _ddebug *dp; |
744 | 743 | ||
745 | if (verbose) | 744 | vpr_info("called m=%p p=%p *pos=%lld\n", |
746 | pr_info("called m=%p p=%p *pos=%lld\n", | 745 | m, p, (unsigned long long)*pos); |
747 | m, p, (unsigned long long)*pos); | ||
748 | 746 | ||
749 | if (p == SEQ_START_TOKEN) | 747 | if (p == SEQ_START_TOKEN) |
750 | dp = ddebug_iter_first(iter); | 748 | dp = ddebug_iter_first(iter); |
@@ -766,8 +764,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p) | |||
766 | struct _ddebug *dp = p; | 764 | struct _ddebug *dp = p; |
767 | char flagsbuf[10]; | 765 | char flagsbuf[10]; |
768 | 766 | ||
769 | if (verbose) | 767 | vpr_info("called m=%p p=%p\n", m, p); |
770 | pr_info("called m=%p p=%p\n", m, p); | ||
771 | 768 | ||
772 | if (p == SEQ_START_TOKEN) { | 769 | if (p == SEQ_START_TOKEN) { |
773 | seq_puts(m, | 770 | seq_puts(m, |
@@ -791,8 +788,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p) | |||
791 | */ | 788 | */ |
792 | static void ddebug_proc_stop(struct seq_file *m, void *p) | 789 | static void ddebug_proc_stop(struct seq_file *m, void *p) |
793 | { | 790 | { |
794 | if (verbose) | 791 | vpr_info("called m=%p p=%p\n", m, p); |
795 | pr_info("called m=%p p=%p\n", m, p); | ||
796 | mutex_unlock(&ddebug_lock); | 792 | mutex_unlock(&ddebug_lock); |
797 | } | 793 | } |
798 | 794 | ||
@@ -815,8 +811,7 @@ static int ddebug_proc_open(struct inode *inode, struct file *file) | |||
815 | struct ddebug_iter *iter; | 811 | struct ddebug_iter *iter; |
816 | int err; | 812 | int err; |
817 | 813 | ||
818 | if (verbose) | 814 | vpr_info("called\n"); |
819 | pr_info("called\n"); | ||
820 | 815 | ||
821 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); | 816 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); |
822 | if (iter == NULL) | 817 | if (iter == NULL) |
@@ -866,12 +861,51 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n, | |||
866 | list_add_tail(&dt->link, &ddebug_tables); | 861 | list_add_tail(&dt->link, &ddebug_tables); |
867 | mutex_unlock(&ddebug_lock); | 862 | mutex_unlock(&ddebug_lock); |
868 | 863 | ||
869 | if (verbose) | 864 | vpr_info("%u debug prints in module %s\n", n, dt->mod_name); |
870 | pr_info("%u debug prints in module %s\n", n, dt->mod_name); | ||
871 | return 0; | 865 | return 0; |
872 | } | 866 | } |
873 | EXPORT_SYMBOL_GPL(ddebug_add_module); | 867 | EXPORT_SYMBOL_GPL(ddebug_add_module); |
874 | 868 | ||
869 | /* helper for ddebug_dyndbg_(boot|module)_param_cb */ | ||
870 | static int ddebug_dyndbg_param_cb(char *param, char *val, | ||
871 | const char *modname, int on_err) | ||
872 | { | ||
873 | char *sep; | ||
874 | |||
875 | sep = strchr(param, '.'); | ||
876 | if (sep) { | ||
877 | /* needed only for ddebug_dyndbg_boot_param_cb */ | ||
878 | *sep = '\0'; | ||
879 | modname = param; | ||
880 | param = sep + 1; | ||
881 | } | ||
882 | if (strcmp(param, "dyndbg")) | ||
883 | return on_err; /* determined by caller */ | ||
884 | |||
885 | ddebug_exec_queries((val ? val : "+p"), modname); | ||
886 | |||
887 | return 0; /* query failure shouldnt stop module load */ | ||
888 | } | ||
889 | |||
890 | /* handle both dyndbg and $module.dyndbg params at boot */ | ||
891 | static int ddebug_dyndbg_boot_param_cb(char *param, char *val, | ||
892 | const char *unused) | ||
893 | { | ||
894 | vpr_info("%s=\"%s\"\n", param, val); | ||
895 | return ddebug_dyndbg_param_cb(param, val, NULL, 0); | ||
896 | } | ||
897 | |||
898 | /* | ||
899 | * modprobe foo finds foo.params in boot-args, strips "foo.", and | ||
900 | * passes them to load_module(). This callback gets unknown params, | ||
901 | * processes dyndbg params, rejects others. | ||
902 | */ | ||
903 | int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module) | ||
904 | { | ||
905 | vpr_info("module: %s %s=\"%s\"\n", module, param, val); | ||
906 | return ddebug_dyndbg_param_cb(param, val, module, -ENOENT); | ||
907 | } | ||
908 | |||
875 | static void ddebug_table_free(struct ddebug_table *dt) | 909 | static void ddebug_table_free(struct ddebug_table *dt) |
876 | { | 910 | { |
877 | list_del_init(&dt->link); | 911 | list_del_init(&dt->link); |
@@ -888,8 +922,7 @@ int ddebug_remove_module(const char *mod_name) | |||
888 | struct ddebug_table *dt, *nextdt; | 922 | struct ddebug_table *dt, *nextdt; |
889 | int ret = -ENOENT; | 923 | int ret = -ENOENT; |
890 | 924 | ||
891 | if (verbose) | 925 | vpr_info("removing module \"%s\"\n", mod_name); |
892 | pr_info("removing module \"%s\"\n", mod_name); | ||
893 | 926 | ||
894 | mutex_lock(&ddebug_lock); | 927 | mutex_lock(&ddebug_lock); |
895 | list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) { | 928 | list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) { |
@@ -940,8 +973,10 @@ static int __init dynamic_debug_init(void) | |||
940 | { | 973 | { |
941 | struct _ddebug *iter, *iter_start; | 974 | struct _ddebug *iter, *iter_start; |
942 | const char *modname = NULL; | 975 | const char *modname = NULL; |
976 | char *cmdline; | ||
943 | int ret = 0; | 977 | int ret = 0; |
944 | int n = 0; | 978 | int n = 0, entries = 0, modct = 0; |
979 | int verbose_bytes = 0; | ||
945 | 980 | ||
946 | if (__start___verbose == __stop___verbose) { | 981 | if (__start___verbose == __stop___verbose) { |
947 | pr_warn("_ddebug table is empty in a " | 982 | pr_warn("_ddebug table is empty in a " |
@@ -952,10 +987,15 @@ static int __init dynamic_debug_init(void) | |||
952 | modname = iter->modname; | 987 | modname = iter->modname; |
953 | iter_start = iter; | 988 | iter_start = iter; |
954 | for (; iter < __stop___verbose; iter++) { | 989 | for (; iter < __stop___verbose; iter++) { |
990 | entries++; | ||
991 | verbose_bytes += strlen(iter->modname) + strlen(iter->function) | ||
992 | + strlen(iter->filename) + strlen(iter->format); | ||
993 | |||
955 | if (strcmp(modname, iter->modname)) { | 994 | if (strcmp(modname, iter->modname)) { |
995 | modct++; | ||
956 | ret = ddebug_add_module(iter_start, n, modname); | 996 | ret = ddebug_add_module(iter_start, n, modname); |
957 | if (ret) | 997 | if (ret) |
958 | goto out_free; | 998 | goto out_err; |
959 | n = 0; | 999 | n = 0; |
960 | modname = iter->modname; | 1000 | modname = iter->modname; |
961 | iter_start = iter; | 1001 | iter_start = iter; |
@@ -964,29 +1004,45 @@ static int __init dynamic_debug_init(void) | |||
964 | } | 1004 | } |
965 | ret = ddebug_add_module(iter_start, n, modname); | 1005 | ret = ddebug_add_module(iter_start, n, modname); |
966 | if (ret) | 1006 | if (ret) |
967 | goto out_free; | 1007 | goto out_err; |
1008 | |||
1009 | ddebug_init_success = 1; | ||
1010 | vpr_info("%d modules, %d entries and %d bytes in ddebug tables," | ||
1011 | " %d bytes in (readonly) verbose section\n", | ||
1012 | modct, entries, (int)( modct * sizeof(struct ddebug_table)), | ||
1013 | verbose_bytes + (int)(__stop___verbose - __start___verbose)); | ||
968 | 1014 | ||
969 | /* ddebug_query boot param got passed -> set it up */ | 1015 | /* apply ddebug_query boot param, dont unload tables on err */ |
970 | if (ddebug_setup_string[0] != '\0') { | 1016 | if (ddebug_setup_string[0] != '\0') { |
971 | ret = ddebug_exec_queries(ddebug_setup_string); | 1017 | pr_warn("ddebug_query param name is deprecated," |
1018 | " change it to dyndbg\n"); | ||
1019 | ret = ddebug_exec_queries(ddebug_setup_string, NULL); | ||
972 | if (ret < 0) | 1020 | if (ret < 0) |
973 | pr_warn("Invalid ddebug boot param %s", | 1021 | pr_warn("Invalid ddebug boot param %s", |
974 | ddebug_setup_string); | 1022 | ddebug_setup_string); |
975 | else | 1023 | else |
976 | pr_info("%d changes by ddebug_query\n", ret); | 1024 | pr_info("%d changes by ddebug_query\n", ret); |
977 | |||
978 | /* keep tables even on ddebug_query parse error */ | ||
979 | ret = 0; | ||
980 | } | 1025 | } |
1026 | /* now that ddebug tables are loaded, process all boot args | ||
1027 | * again to find and activate queries given in dyndbg params. | ||
1028 | * While this has already been done for known boot params, it | ||
1029 | * ignored the unknown ones (dyndbg in particular). Reusing | ||
1030 | * parse_args avoids ad-hoc parsing. This will also attempt | ||
1031 | * to activate queries for not-yet-loaded modules, which is | ||
1032 | * slightly noisy if verbose, but harmless. | ||
1033 | */ | ||
1034 | cmdline = kstrdup(saved_command_line, GFP_KERNEL); | ||
1035 | parse_args("dyndbg params", cmdline, NULL, | ||
1036 | 0, 0, 0, &ddebug_dyndbg_boot_param_cb); | ||
1037 | kfree(cmdline); | ||
1038 | return 0; | ||
981 | 1039 | ||
982 | out_free: | 1040 | out_err: |
983 | if (ret) | 1041 | ddebug_remove_all_tables(); |
984 | ddebug_remove_all_tables(); | ||
985 | else | ||
986 | ddebug_init_success = 1; | ||
987 | return 0; | 1042 | return 0; |
988 | } | 1043 | } |
989 | /* Allow early initialization for boot messages via boot param */ | 1044 | /* Allow early initialization for boot messages via boot param */ |
990 | arch_initcall(dynamic_debug_init); | 1045 | early_initcall(dynamic_debug_init); |
1046 | |||
991 | /* Debugfs setup must be done later */ | 1047 | /* Debugfs setup must be done later */ |
992 | module_init(dynamic_debug_init_debugfs); | 1048 | fs_initcall(dynamic_debug_init_debugfs); |
diff --git a/lib/jedec_ddr_data.c b/lib/jedec_ddr_data.c new file mode 100644 index 000000000000..6d2cbf1d567f --- /dev/null +++ b/lib/jedec_ddr_data.c | |||
@@ -0,0 +1,135 @@ | |||
1 | /* | ||
2 | * DDR addressing details and AC timing parameters from JEDEC specs | ||
3 | * | ||
4 | * Copyright (C) 2012 Texas Instruments, Inc. | ||
5 | * | ||
6 | * Aneesh V <aneesh@ti.com> | ||
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 | |||
13 | #include <memory/jedec_ddr.h> | ||
14 | #include <linux/module.h> | ||
15 | |||
16 | /* LPDDR2 addressing details from JESD209-2 section 2.4 */ | ||
17 | const struct lpddr2_addressing | ||
18 | lpddr2_jedec_addressing_table[NUM_DDR_ADDR_TABLE_ENTRIES] = { | ||
19 | {B4, T_REFI_15_6, T_RFC_90}, /* 64M */ | ||
20 | {B4, T_REFI_15_6, T_RFC_90}, /* 128M */ | ||
21 | {B4, T_REFI_7_8, T_RFC_90}, /* 256M */ | ||
22 | {B4, T_REFI_7_8, T_RFC_90}, /* 512M */ | ||
23 | {B8, T_REFI_7_8, T_RFC_130}, /* 1GS4 */ | ||
24 | {B8, T_REFI_3_9, T_RFC_130}, /* 2GS4 */ | ||
25 | {B8, T_REFI_3_9, T_RFC_130}, /* 4G */ | ||
26 | {B8, T_REFI_3_9, T_RFC_210}, /* 8G */ | ||
27 | {B4, T_REFI_7_8, T_RFC_130}, /* 1GS2 */ | ||
28 | {B4, T_REFI_3_9, T_RFC_130}, /* 2GS2 */ | ||
29 | }; | ||
30 | EXPORT_SYMBOL_GPL(lpddr2_jedec_addressing_table); | ||
31 | |||
32 | /* LPDDR2 AC timing parameters from JESD209-2 section 12 */ | ||
33 | const struct lpddr2_timings | ||
34 | lpddr2_jedec_timings[NUM_DDR_TIMING_TABLE_ENTRIES] = { | ||
35 | /* Speed bin 400(200 MHz) */ | ||
36 | [0] = { | ||
37 | .max_freq = 200000000, | ||
38 | .min_freq = 10000000, | ||
39 | .tRPab = 21000, | ||
40 | .tRCD = 18000, | ||
41 | .tWR = 15000, | ||
42 | .tRAS_min = 42000, | ||
43 | .tRRD = 10000, | ||
44 | .tWTR = 10000, | ||
45 | .tXP = 7500, | ||
46 | .tRTP = 7500, | ||
47 | .tCKESR = 15000, | ||
48 | .tDQSCK_max = 5500, | ||
49 | .tFAW = 50000, | ||
50 | .tZQCS = 90000, | ||
51 | .tZQCL = 360000, | ||
52 | .tZQinit = 1000000, | ||
53 | .tRAS_max_ns = 70000, | ||
54 | .tDQSCK_max_derated = 6000, | ||
55 | }, | ||
56 | /* Speed bin 533(266 MHz) */ | ||
57 | [1] = { | ||
58 | .max_freq = 266666666, | ||
59 | .min_freq = 10000000, | ||
60 | .tRPab = 21000, | ||
61 | .tRCD = 18000, | ||
62 | .tWR = 15000, | ||
63 | .tRAS_min = 42000, | ||
64 | .tRRD = 10000, | ||
65 | .tWTR = 7500, | ||
66 | .tXP = 7500, | ||
67 | .tRTP = 7500, | ||
68 | .tCKESR = 15000, | ||
69 | .tDQSCK_max = 5500, | ||
70 | .tFAW = 50000, | ||
71 | .tZQCS = 90000, | ||
72 | .tZQCL = 360000, | ||
73 | .tZQinit = 1000000, | ||
74 | .tRAS_max_ns = 70000, | ||
75 | .tDQSCK_max_derated = 6000, | ||
76 | }, | ||
77 | /* Speed bin 800(400 MHz) */ | ||
78 | [2] = { | ||
79 | .max_freq = 400000000, | ||
80 | .min_freq = 10000000, | ||
81 | .tRPab = 21000, | ||
82 | .tRCD = 18000, | ||
83 | .tWR = 15000, | ||
84 | .tRAS_min = 42000, | ||
85 | .tRRD = 10000, | ||
86 | .tWTR = 7500, | ||
87 | .tXP = 7500, | ||
88 | .tRTP = 7500, | ||
89 | .tCKESR = 15000, | ||
90 | .tDQSCK_max = 5500, | ||
91 | .tFAW = 50000, | ||
92 | .tZQCS = 90000, | ||
93 | .tZQCL = 360000, | ||
94 | .tZQinit = 1000000, | ||
95 | .tRAS_max_ns = 70000, | ||
96 | .tDQSCK_max_derated = 6000, | ||
97 | }, | ||
98 | /* Speed bin 1066(533 MHz) */ | ||
99 | [3] = { | ||
100 | .max_freq = 533333333, | ||
101 | .min_freq = 10000000, | ||
102 | .tRPab = 21000, | ||
103 | .tRCD = 18000, | ||
104 | .tWR = 15000, | ||
105 | .tRAS_min = 42000, | ||
106 | .tRRD = 10000, | ||
107 | .tWTR = 7500, | ||
108 | .tXP = 7500, | ||
109 | .tRTP = 7500, | ||
110 | .tCKESR = 15000, | ||
111 | .tDQSCK_max = 5500, | ||
112 | .tFAW = 50000, | ||
113 | .tZQCS = 90000, | ||
114 | .tZQCL = 360000, | ||
115 | .tZQinit = 1000000, | ||
116 | .tRAS_max_ns = 70000, | ||
117 | .tDQSCK_max_derated = 5620, | ||
118 | }, | ||
119 | }; | ||
120 | EXPORT_SYMBOL_GPL(lpddr2_jedec_timings); | ||
121 | |||
122 | const struct lpddr2_min_tck lpddr2_jedec_min_tck = { | ||
123 | .tRPab = 3, | ||
124 | .tRCD = 3, | ||
125 | .tWR = 3, | ||
126 | .tRASmin = 3, | ||
127 | .tRRD = 2, | ||
128 | .tWTR = 2, | ||
129 | .tXP = 2, | ||
130 | .tRTP = 2, | ||
131 | .tCKE = 3, | ||
132 | .tCKESR = 3, | ||
133 | .tFAW = 8 | ||
134 | }; | ||
135 | EXPORT_SYMBOL_GPL(lpddr2_jedec_min_tck); | ||
diff --git a/lib/kobject.c b/lib/kobject.c index aeefa8bc8b1c..e07ee1fcd6f1 100644 --- a/lib/kobject.c +++ b/lib/kobject.c | |||
@@ -47,13 +47,11 @@ static int populate_dir(struct kobject *kobj) | |||
47 | static int create_dir(struct kobject *kobj) | 47 | static int create_dir(struct kobject *kobj) |
48 | { | 48 | { |
49 | int error = 0; | 49 | int error = 0; |
50 | if (kobject_name(kobj)) { | 50 | error = sysfs_create_dir(kobj); |
51 | error = sysfs_create_dir(kobj); | 51 | if (!error) { |
52 | if (!error) { | 52 | error = populate_dir(kobj); |
53 | error = populate_dir(kobj); | 53 | if (error) |
54 | if (error) | 54 | sysfs_remove_dir(kobj); |
55 | sysfs_remove_dir(kobj); | ||
56 | } | ||
57 | } | 55 | } |
58 | return error; | 56 | return error; |
59 | } | 57 | } |
@@ -634,7 +632,7 @@ struct kobject *kobject_create(void) | |||
634 | /** | 632 | /** |
635 | * kobject_create_and_add - create a struct kobject dynamically and register it with sysfs | 633 | * kobject_create_and_add - create a struct kobject dynamically and register it with sysfs |
636 | * | 634 | * |
637 | * @name: the name for the kset | 635 | * @name: the name for the kobject |
638 | * @parent: the parent kobject of this kobject, if any. | 636 | * @parent: the parent kobject of this kobject, if any. |
639 | * | 637 | * |
640 | * This function creates a kobject structure dynamically and registers it | 638 | * This function creates a kobject structure dynamically and registers it |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 918330f71dba..9f389e50ed18 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -4763,12 +4763,12 @@ void __init free_area_init_nodes(unsigned long *max_zone_pfn) | |||
4763 | for (i = 0; i < MAX_NR_ZONES; i++) { | 4763 | for (i = 0; i < MAX_NR_ZONES; i++) { |
4764 | if (i == ZONE_MOVABLE) | 4764 | if (i == ZONE_MOVABLE) |
4765 | continue; | 4765 | continue; |
4766 | printk(" %-8s ", zone_names[i]); | 4766 | printk(KERN_CONT " %-8s ", zone_names[i]); |
4767 | if (arch_zone_lowest_possible_pfn[i] == | 4767 | if (arch_zone_lowest_possible_pfn[i] == |
4768 | arch_zone_highest_possible_pfn[i]) | 4768 | arch_zone_highest_possible_pfn[i]) |
4769 | printk("empty\n"); | 4769 | printk(KERN_CONT "empty\n"); |
4770 | else | 4770 | else |
4771 | printk("%0#10lx -> %0#10lx\n", | 4771 | printk(KERN_CONT "%0#10lx -> %0#10lx\n", |
4772 | arch_zone_lowest_possible_pfn[i], | 4772 | arch_zone_lowest_possible_pfn[i], |
4773 | arch_zone_highest_possible_pfn[i]); | 4773 | arch_zone_highest_possible_pfn[i]); |
4774 | } | 4774 | } |