History

Merge tag 'char-misc-4.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc

Pull char/misc updates from Greg KH: "Here is the big set of char/misc driver patches for 4.17-rc1. There are a lot of little things in here, nothing huge, but all important to the different hardware types involved: - thunderbolt driver updates - parport updates (people still care...) - nvmem driver updates - mei updates (as always) - hwtracing driver updates - hyperv driver updates - extcon driver updates - ... and a handful of even smaller driver subsystem and individual driver updates All of these have been in linux-next with no reported issues" * tag 'char-misc-4.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (149 commits) hwtracing: Add HW tracing support menu intel_th: Add ACPI glue layer intel_th: Allow forcing host mode through drvdata intel_th: Pick up irq number from resources intel_th: Don't touch switch routing in host mode intel_th: Use correct method of finding hub intel_th: Add SPDX GPL-2.0 header to replace GPLv2 boilerplate stm class: Make dummy's master/channel ranges configurable stm class: Add SPDX GPL-2.0 header to replace GPLv2 boilerplate MAINTAINERS: Bestow upon myself the care for drivers/hwtracing hv: add SPDX license id to Kconfig hv: add SPDX license to trace Drivers: hv: vmbus: do not mark HV_PCIE as perf_device Drivers: hv: vmbus: respect what we get from hv_get_synint_state() /dev/mem: Avoid overwriting "err" in read_mem() eeprom: at24: use SPDX identifier instead of GPL boiler-plate eeprom: at24: simplify the i2c functionality checking eeprom: at24: fix a line break eeprom: at24: tweak newlines eeprom: at24: refactor at24_probe() ...

Linus Torvalds committed 8 years ago

Commit 06dd3df2 parents 38047d5 86f690e141 files · +3377 −1207Browse files

Unified · Split

141 files
  1. Documentation/ABI/stable/sysfs-bus-vmbus +7 −0
  2. Documentation/ABI/testing/sysfs-bus-thunderbolt +33 −0
  3. Documentation/ABI/testing/sysfs-class-mei +9 −0
  4. Documentation/ABI/testing/sysfs-driver-fsi-master-gpio +10 −0
  5. Documentation/admin-guide/thunderbolt.rst +10 −5
  6. Documentation/devicetree/bindings/connector/samsung,usb-connector-11pin.txt +49 −0
  7. Documentation/devicetree/bindings/connector/usb-connector.txt +75 −0
  8. Documentation/devicetree/bindings/fsi/fsi.txt +151 −0
  9. Documentation/devicetree/bindings/mfd/aspeed-lpc.txt +41 −0
  10. Documentation/devicetree/bindings/nvmem/imx-ocotp.txt +19 −4
  11. Documentation/devicetree/bindings/nvmem/snvs-lpgpr.txt +2 −1
  12. Documentation/driver-api/uio-howto.rst +5 −0
  13. MAINTAINERS +6 −1
  14. arch/x86/entry/entry_32.S +3 −0
  15. arch/x86/entry/entry_64.S +3 −0
  16. arch/x86/include/asm/hardirq.h +1 −0
  17. arch/x86/include/asm/irq_vectors.h +2 −1
  18. arch/x86/include/asm/mshyperv.h +13 −0
  19. arch/x86/include/uapi/asm/hyperv.h +3 −0
  20. arch/x86/kernel/cpu/mshyperv.c +40 −0
  21. arch/x86/kernel/irq.c +7 −0
  22. block/genhd.c +11 −8
  23. drivers/Kconfig +1 −3
  24. drivers/char/Kconfig +1 −1
  25. drivers/char/mem.c +3 −3
  26. drivers/char/xillybus/xillybus_pcie.c +0 −1
  27. drivers/extcon/extcon-gpio.c +45 −58
  28. drivers/extcon/extcon-intel-cht-wc.c +7 −4
  29. drivers/extcon/extcon-intel-int3496.c +5 −4
  30. drivers/extcon/extcon.c +34 −10
  31. drivers/fpga/altera-cvp.c +0 −2
  32. drivers/fsi/Kconfig +1 −0
  33. drivers/fsi/fsi-core.c +120 −9
  34. drivers/fsi/fsi-master-gpio.c +87 −2
  35. drivers/fsi/fsi-master-hub.c +23 −4
  36. drivers/fsi/fsi-master.h +17 −0
  37. drivers/gpu/drm/bridge/sil-sii8620.c +94 −3
  38. drivers/hv/Kconfig +2 −0
  39. drivers/hv/Makefile +1 −0
  40. drivers/hv/channel_mgmt.c +3 −5
  41. drivers/hv/hv.c +58 −6
  42. drivers/hv/hv_balloon.c +83 −38
  43. drivers/hv/hv_trace.c +2 −0
  44. drivers/hv/hv_trace.h +2 −0
  45. drivers/hv/hv_trace_balloon.h +48 −0
  46. drivers/hv/hyperv_vmbus.h +3 −1
  47. drivers/hwtracing/Kconfig +7 −0
  48. drivers/hwtracing/coresight/coresight-cpu-debug.c +1 −1
  49. drivers/hwtracing/coresight/coresight-etm4x-sysfs.c +2 −2
  50. drivers/hwtracing/intel_th/Kconfig +12 −0
  51. drivers/hwtracing/intel_th/Makefile +3 −0
  52. drivers/hwtracing/intel_th/acpi.c +79 −0
  53. drivers/hwtracing/intel_th/core.c +18 −13
  54. drivers/hwtracing/intel_th/debug.c +1 −9
  55. drivers/hwtracing/intel_th/debug.h +1 −9
  56. drivers/hwtracing/intel_th/gth.c +1 −9
  57. drivers/hwtracing/intel_th/gth.h +1 −9
  58. drivers/hwtracing/intel_th/intel_th.h +4 −10
  59. drivers/hwtracing/intel_th/msu.c +1 −9
  60. drivers/hwtracing/intel_th/msu.h +1 −9
  61. drivers/hwtracing/intel_th/pci.c +1 −9
  62. drivers/hwtracing/intel_th/pti.c +1 −9
  63. drivers/hwtracing/intel_th/pti.h +1 −9
  64. drivers/hwtracing/intel_th/sth.c +1 −9
  65. drivers/hwtracing/intel_th/sth.h +1 −9
  66. drivers/hwtracing/stm/console.c +1 −9
  67. drivers/hwtracing/stm/core.c +1 −9
  68. drivers/hwtracing/stm/dummy_stm.c +22 −12
  69. drivers/hwtracing/stm/heartbeat.c +1 −9
  70. drivers/hwtracing/stm/policy.c +1 −9
  71. drivers/hwtracing/stm/stm.h +1 −9
  72. drivers/mcb/mcb-pci.c +1 −0
  73. drivers/misc/Kconfig +0 −1
  74. drivers/misc/Makefile +1 −19
  75. drivers/misc/aspeed-lpc-ctrl.c +39 −5
  76. drivers/misc/cardreader/rts5260.c +6 −6
  77. drivers/misc/eeprom/at24.c +156 −137
  78. drivers/misc/eeprom/at25.c +1 −1
  79. drivers/misc/lkdtm/Makefile +20 −0
  80. drivers/misc/lkdtm/bugs.c +0 −0
  81. drivers/misc/lkdtm/core.c +0 −0
  82. drivers/misc/lkdtm/heap.c +0 −0
  83. drivers/misc/lkdtm/lkdtm.h +0 −0
  84. drivers/misc/lkdtm/perms.c +0 −0
  85. drivers/misc/lkdtm/refcount.c +1 −0
  86. drivers/misc/lkdtm/rodata.c +0 −0
  87. drivers/misc/lkdtm/usercopy.c +0 −0
  88. drivers/misc/mei/bus.c +51 −32
  89. drivers/misc/mei/client.c +50 −37
  90. drivers/misc/mei/debugfs.c +4 −3
  91. drivers/misc/mei/init.c +1 −0
  92. drivers/misc/mei/main.c +65 −1
  93. drivers/misc/mei/mei_dev.h +8 −2
  94. drivers/misc/mic/bus/vop_bus.c +4 −2
  95. drivers/misc/ocxl/pci.c +1 −1
  96. drivers/nvmem/Kconfig +2 −2
  97. drivers/nvmem/bcm-ocotp.c +2 −13
  98. drivers/nvmem/core.c +67 −3
  99. drivers/nvmem/imx-iim.c +3 −15
  100. drivers/nvmem/imx-ocotp.c +2 −16
  101. drivers/nvmem/lpc18xx_otp.c +2 −14
  102. drivers/nvmem/meson-efuse.c +2 −14
  103. drivers/nvmem/meson-mx-efuse.c +2 −14
  104. drivers/nvmem/mtk-efuse.c +2 −14
  105. drivers/nvmem/qfprom.c +2 −14
  106. drivers/nvmem/rockchip-efuse.c +10 −22
  107. drivers/nvmem/snvs_lpgpr.c +28 −25
  108. drivers/nvmem/sunxi_sid.c +50 −21
  109. drivers/nvmem/uniphier-efuse.c +2 −14
  110. drivers/nvmem/vf610-ocotp.c +5 −19
  111. drivers/parport/parport_ax88796.c +3 −5
  112. drivers/parport/parport_pc.c +4 −0
  113. drivers/parport/parport_serial.c +46 −76
  114. drivers/pps/clients/pps_parport.c +18 −3
  115. drivers/pps/generators/pps_gen_parport.c +9 −3
  116. drivers/siox/siox-core.c +1 −1
  117. drivers/slimbus/core.c +1 −1
  118. drivers/thunderbolt/dma_port.c +13 −15
  119. drivers/thunderbolt/domain.c +129 −1
  120. drivers/thunderbolt/icm.c +685 −79
  121. drivers/thunderbolt/nhi.c +4 −1
  122. drivers/thunderbolt/nhi.h +5 −0
  123. drivers/thunderbolt/switch.c +60 −1
  124. drivers/thunderbolt/tb.h +14 −0
  125. drivers/thunderbolt/tb_msgs.h +179 −1
  126. drivers/thunderbolt/xdomain.c +35 −12
  127. drivers/uio/uio_hv_generic.c +89 −0
  128. drivers/w1/w1.c +1 −0
  129. fs/char_dev.c +5 −5
  130. include/linux/extcon.h +6 −0
  131. include/linux/extcon/extcon-gpio.h +0 −47
  132. include/linux/hyperv.h +1 −1
  133. include/linux/nvmem-provider.h +42 −0
  134. include/linux/pci_ids.h +2 −0
  135. include/linux/stm.h +1 −9
  136. include/linux/thunderbolt.h +19 −0
  137. include/uapi/linux/stm.h +4 −9
  138. lib/devres.c +38 −40
  139. tools/hv/hv_fcopy_daemon.c +3 −1
  140. tools/hv/hv_kvp_daemon.c +65 −73
  141. tools/hv/hv_vss_daemon.c +1 −0
Documentation/ABI/stable/sysfs-bus-vmbus+7−0
@@ -132,3 +132,10 @@ KernelVersion: 4.16 · 131 unmodified lines
132Contact: Stephen Hemminger <sthemmin@microsoft.com>132Contact: Stephen Hemminger <sthemmin@microsoft.com>
133Description: Monitor bit associated with channel133Description: Monitor bit associated with channel
134Users: Debugging tools and userspace drivers134Users: Debugging tools and userspace drivers
135
136What: /sys/bus/vmbus/devices/vmbus_*/channels/NN/ring
137Date: January. 2018
138KernelVersion: 4.16
139Contact: Stephen Hemminger <sthemmin@microsoft.com>
140Description: Binary file created by uio_hv_generic for ring buffer
141Users: Userspace drivers
Documentation/ABI/testing/sysfs-bus-thunderbolt+33−0
@@ -1,3 +1,26 @@
1What: /sys/bus/thunderbolt/devices/.../domainX/boot_acl
2Date: Jun 2018
3KernelVersion: 4.17
4Contact: thunderbolt-software@lists.01.org
5Description: Holds a comma separated list of device unique_ids that
6 are allowed to be connected automatically during system
7 startup (e.g boot devices). The list always contains
8 maximum supported number of unique_ids where unused
9 entries are empty. This allows the userspace software
10 to determine how many entries the controller supports.
11 If there are multiple controllers, each controller has
12 its own ACL list and size may be different between the
13 controllers.
14
15 System BIOS may have an option "Preboot ACL" or similar
16 that needs to be selected before this list is taken into
17 consideration.
18
19 Software always updates a full list in each write.
20
21 If a device is authorized automatically during boot its
22 boot attribute is set to 1.
23
1What: /sys/bus/thunderbolt/devices/.../domainX/security24What: /sys/bus/thunderbolt/devices/.../domainX/security
2Date: Sep 201725Date: Sep 2017
3KernelVersion: 4.1326KernelVersion: 4.13
@@ -12,6 +35,9 @@ Description: This attribute holds current Thunderbolt security level · 8 unmodified lines
12 minimum. User needs to authorize each device.35 minimum. User needs to authorize each device.
13 dponly: Automatically tunnel Display port (and USB). No36 dponly: Automatically tunnel Display port (and USB). No
14 PCIe tunnels are created.37 PCIe tunnels are created.
38 usbonly: Automatically tunnel USB controller of the
39 connected Thunderbolt dock (and Display Port). All
40 PCIe links downstream of the dock are removed.
15 41
16What: /sys/bus/thunderbolt/devices/.../authorized42What: /sys/bus/thunderbolt/devices/.../authorized
17Date: Sep 201743Date: Sep 2017
@@ -38,6 +64,13 @@ Description: This attribute is used to authorize Thunderbolt devices · 20 unmodified lines
38 the device did not contain a key at all, and64 the device did not contain a key at all, and
39 EKEYREJECTED if the challenge response did not match.65 EKEYREJECTED if the challenge response did not match.
40 66
67What: /sys/bus/thunderbolt/devices/.../boot
68Date: Jun 2018
69KernelVersion: 4.17
70Contact: thunderbolt-software@lists.01.org
71Description: This attribute contains 1 if Thunderbolt device was already
72 authorized on boot and 0 otherwise.
73
41What: /sys/bus/thunderbolt/devices/.../key74What: /sys/bus/thunderbolt/devices/.../key
42Date: Sep 201775Date: Sep 2017
43KernelVersion: 4.1376KernelVersion: 4.13
Documentation/ABI/testing/sysfs-class-mei+9−0
@@ -45,3 +45,12 @@ Contact: Tomas Winkler <tomas.winkler@intel.com> · 44 unmodified lines
45Description: Display the driver HBM protocol version.45Description: Display the driver HBM protocol version.
46 46
47 The HBM protocol version supported by the driver.47 The HBM protocol version supported by the driver.
48
49What: /sys/class/mei/meiN/tx_queue_limit
50Date: Jan 2018
51KernelVersion: 4.16
52Contact: Tomas Winkler <tomas.winkler@intel.com>
53Description: Configure tx queue limit
54
55 Set maximal number of pending writes
56 per opened session.
Documentation/ABI/testing/sysfs-driver-fsi-master-gpio+10−0
@@ -0,0 +1,10 @@
1What: /sys/bus/platform/devices/[..]/fsi-master-gpio/external_mode
2Date: Feb 2018
3KernelVersion: 4.17
4Contact: jk@ozlabs.org
5Description:
6 Controls access arbitration for GPIO-based FSI master. A
7 value of 0 (the default) sets normal mode, where the
8 driver performs FSI bus transactions, 1 sets external mode,
9 where the FSI bus is driven externally (for example, by
10 a debug device).
Documentation/admin-guide/thunderbolt.rst+10−5
@@ -21,11 +21,11 @@ vulnerable to DMA attacks. · 20 unmodified lines
21Security levels and how to use them21Security levels and how to use them
22-----------------------------------22-----------------------------------
23Starting with Intel Falcon Ridge Thunderbolt controller there are 423Starting with Intel Falcon Ridge Thunderbolt controller there are 4
24security levels available. The reason for these is the fact that the24security levels available. Intel Titan Ridge added one more security level
25connected devices can be DMA masters and thus read contents of the host25(usbonly). The reason for these is the fact that the connected devices can
26memory without CPU and OS knowing about it. There are ways to prevent26be DMA masters and thus read contents of the host memory without CPU and OS
27this by setting up an IOMMU but it is not always available for various27knowing about it. There are ways to prevent this by setting up an IOMMU but
28reasons.28it is not always available for various reasons.
29 29
30The security levels are as follows:30The security levels are as follows:
31 31
@@ -52,6 +52,11 @@ The security levels are as follows: · 20 unmodified lines
52 USB. No PCIe tunneling is done. In BIOS settings this is52 USB. No PCIe tunneling is done. In BIOS settings this is
53 typically called *Display Port Only*.53 typically called *Display Port Only*.
54 54
55 usbonly
56 The firmware automatically creates tunnels for the USB controller and
57 Display Port in a dock. All PCIe links downstream of the dock are
58 removed.
59
55The current security level can be read from60The current security level can be read from
56``/sys/bus/thunderbolt/devices/domainX/security`` where ``domainX`` is61``/sys/bus/thunderbolt/devices/domainX/security`` where ``domainX`` is
57the Thunderbolt domain the host controller manages. There is typically62the Thunderbolt domain the host controller manages. There is typically
Documentation/devicetree/bindings/connector/samsung,usb-connector-11pin.txt+49−0
@@ -0,0 +1,49 @@
1Samsung micro-USB 11-pin connector
2==================================
3
4Samsung micro-USB 11-pin connector is an extension of micro-USB connector.
5It is present in multiple Samsung mobile devices.
6It has additional pins to route MHL traffic simultanously with USB.
7
8The bindings are superset of usb-connector bindings for micro-USB connector[1].
9
10Required properties:
11- compatible: must be: "samsung,usb-connector-11pin", "usb-b-connector",
12- type: must be "micro".
13
14Required nodes:
15- any data bus to the connector should be modeled using the OF graph bindings
16 specified in bindings/graph.txt, unless the bus is between parent node and
17 the connector. Since single connector can have multpile data buses every bus
18 has assigned OF graph port number as follows:
19 0: High Speed (HS),
20 3: Mobile High-Definition Link (MHL), specific to 11-pin Samsung micro-USB.
21
22[1]: bindings/connector/usb-connector.txt
23
24Example
25-------
26
27Micro-USB connector with HS lines routed via controller (MUIC) and MHL lines
28connected to HDMI-MHL bridge (sii8620):
29
30muic-max77843@66 {
31 ...
32 usb_con: connector {
33 compatible = "samsung,usb-connector-11pin", "usb-b-connector";
34 label = "micro-USB";
35 type = "micro";
36
37 ports {
38 #address-cells = <1>;
39 #size-cells = <0>;
40
41 port@3 {
42 reg = <3>;
43 usb_con_mhl: endpoint {
44 remote-endpoint = <&sii8620_mhl>;
45 };
46 };
47 };
48 };
49};
Documentation/devicetree/bindings/connector/usb-connector.txt+75−0
@@ -0,0 +1,75 @@
1USB Connector
2=============
3
4USB connector node represents physical USB connector. It should be
5a child of USB interface controller.
6
7Required properties:
8- compatible: describes type of the connector, must be one of:
9 "usb-a-connector",
10 "usb-b-connector",
11 "usb-c-connector".
12
13Optional properties:
14- label: symbolic name for the connector,
15- type: size of the connector, should be specified in case of USB-A, USB-B
16 non-fullsize connectors: "mini", "micro".
17
18Required nodes:
19- any data bus to the connector should be modeled using the OF graph bindings
20 specified in bindings/graph.txt, unless the bus is between parent node and
21 the connector. Since single connector can have multpile data buses every bus
22 has assigned OF graph port number as follows:
23 0: High Speed (HS), present in all connectors,
24 1: Super Speed (SS), present in SS capable connectors,
25 2: Sideband use (SBU), present in USB-C.
26
27Examples
28--------
29
301. Micro-USB connector with HS lines routed via controller (MUIC):
31
32muic-max77843@66 {
33 ...
34 usb_con: connector {
35 compatible = "usb-b-connector";
36 label = "micro-USB";
37 type = "micro";
38 };
39};
40
412. USB-C connector attached to CC controller (s2mm005), HS lines routed
42to companion PMIC (max77865), SS lines to USB3 PHY and SBU to DisplayPort.
43DisplayPort video lines are routed to the connector via SS mux in USB3 PHY.
44
45ccic: s2mm005@33 {
46 ...
47 usb_con: connector {
48 compatible = "usb-c-connector";
49 label = "USB-C";
50
51 ports {
52 #address-cells = <1>;
53 #size-cells = <0>;
54
55 port@0 {
56 reg = <0>;
57 usb_con_hs: endpoint {
58 remote-endpoint = <&max77865_usbc_hs>;
59 };
60 };
61 port@1 {
62 reg = <1>;
63 usb_con_ss: endpoint {
64 remote-endpoint = <&usbdrd_phy_ss>;
65 };
66 };
67 port@2 {
68 reg = <2>;
69 usb_con_sbu: endpoint {
70 remote-endpoint = <&dp_aux>;
71 };
72 };
73 };
74 };
75};
Documentation/devicetree/bindings/fsi/fsi.txt+151−0
@@ -0,0 +1,151 @@
1FSI bus & engine generic device tree bindings
2=============================================
3
4The FSI bus is probe-able, so the OS is able to enumerate FSI slaves, and
5engines within those slaves. However, we have a facility to match devicetree
6nodes to probed engines. This allows for fsi engines to expose non-probeable
7busses, which are then exposed by the device tree. For example, an FSI engine
8that is an I2C master - the I2C bus can be described by the device tree under
9the engine's device tree node.
10
11FSI masters may require their own DT nodes (to describe the master HW itself);
12that requirement is defined by the master's implementation, and is described by
13the fsi-master-* binding specifications.
14
15Under the masters' nodes, we can describe the bus topology using nodes to
16represent the FSI slaves and their slave engines. As a basic outline:
17
18 fsi-master {
19 /* top-level of FSI bus topology, bound to an FSI master driver and
20 * exposes an FSI bus */
21
22 fsi-slave@<link,id> {
23 /* this node defines the FSI slave device, and is handled
24 * entirely with FSI core code */
25
26 fsi-slave-engine@<addr> {
27 /* this node defines the engine endpoint & address range, which
28 * is bound to the relevant fsi device driver */
29 ...
30 };
31
32 fsi-slave-engine@<addr> {
33 ...
34 };
35
36 };
37 };
38
39Note that since the bus is probe-able, some (or all) of the topology may
40not be described; this binding only provides an optional facility for
41adding subordinate device tree nodes as children of FSI engines.
42
43FSI masters
44-----------
45
46FSI master nodes declare themselves as such with the "fsi-master" compatible
47value. It's likely that an implementation-specific compatible value will
48be needed as well, for example:
49
50 compatible = "fsi-master-gpio", "fsi-master";
51
52Since the master nodes describe the top-level of the FSI topology, they also
53need to declare the FSI-standard addressing scheme. This requires two cells for
54addresses (link index and slave ID), and no size:
55
56 #address-cells = <2>;
57 #size-cells = <0>;
58
59An optional boolean property can be added to indicate that a particular master
60should not scan for connected devices at initialization time. This is
61necessary in cases where a scan could cause arbitration issues with other
62masters that may be present on the bus.
63
64 no-scan-on-init;
65
66FSI slaves
67----------
68
69Slaves are identified by a (link-index, slave-id) pair, so require two cells
70for an address identifier. Since these are not a range, no size cells are
71required. For an example, a slave on link 1, with ID 2, could be represented
72as:
73
74 cfam@1,2 {
75 reg = <1 2>;
76 [...];
77 }
78
79Each slave provides an address-space, under which the engines are accessible.
80That address space has a maximum of 23 bits, so we use one cell to represent
81addresses and sizes in the slave address space:
82
83 #address-cells = <1>;
84 #size-cells = <1>;
85
86
87FSI engines (devices)
88---------------------
89
90Engines are identified by their address under the slaves' address spaces. We
91use a single cell for address and size. Engine nodes represent the endpoint
92FSI device, and are passed to those FSI device drivers' ->probe() functions.
93
94For example, for a slave using a single 0x400-byte page starting at address
950xc00:
96
97 engine@c00 {
98 reg = <0xc00 0x400>;
99 };
100
101
102Full example
103------------
104
105Here's an example that illustrates:
106 - an FSI master
107 - connected to an FSI slave
108 - that contains an engine that is an I2C master
109 - connected to an I2C EEPROM
110
111The FSI master may be connected to additional slaves, and slaves may have
112additional engines, but they don't necessarily need to be describe in the
113device tree if no extra platform information is required.
114
115 /* The GPIO-based FSI master node, describing the top level of the
116 * FSI bus
117 */
118 gpio-fsi {
119 compatible = "fsi-master-gpio", "fsi-master";
120 #address-cells = <2>;
121 #size-cells = <0>;
122
123 /* A FSI slave (aka. CFAM) at link 0, ID 0. */
124 cfam@0,0 {
125 reg = <0 0>;
126 #address-cells = <1>;
127 #size-cells = <1>;
128
129 /* FSI engine at 0xc00, using a single page. In this example,
130 * it's an I2C master controller, so subnodes describe the
131 * I2C bus.
132 */
133 i2c-controller@c00 {
134 reg = <0xc00 0x400>;
135
136 /* Engine-specific data. In this case, we're describing an
137 * I2C bus, so we're conforming to the generic I2C binding
138 */
139 compatible = "some-vendor,fsi-i2c-controller";
140 #address-cells = <1>;
141 #size-cells = <1>;
142
143 /* I2C endpoint device: an Atmel EEPROM */
144 eeprom@50 {
145 compatible = "atmel,24c256";
146 reg = <0x50>;
147 pagesize = <64>;
148 };
149 };
150 };
151 };
Documentation/devicetree/bindings/mfd/aspeed-lpc.txt+41−0
@@ -109,9 +109,50 @@ lpc: lpc@1e789000 { · 108 unmodified lines
109 };109 };
110};110};
111 111
112BMC Node Children
113==================
114
115
112Host Node Children116Host Node Children
113==================117==================
114 118
119LPC Host Interface Controller
120-------------------
121
122The LPC Host Interface Controller manages functions exposed to the host such as
123LPC firmware hub cycles, configuration of the LPC-to-AHB mapping, UART
124management and bus snoop configuration.
125
126Required properties:
127
128- compatible: One of:
129 "aspeed,ast2400-lpc-ctrl";
130 "aspeed,ast2500-lpc-ctrl";
131
132- reg: contains offset/length values of the host interface controller
133 memory regions
134
135- clocks: contains a phandle to the syscon node describing the clocks.
136 There should then be one cell representing the clock to use
137
138- memory-region: A phandle to a reserved_memory region to be used for the LPC
139 to AHB mapping
140
141- flash: A phandle to the SPI flash controller containing the flash to
142 be exposed over the LPC to AHB mapping
143
144Example:
145
146lpc-host@80 {
147 lpc_ctrl: lpc-ctrl@0 {
148 compatible = "aspeed,ast2500-lpc-ctrl";
149 reg = <0x0 0x80>;
150 clocks = <&syscon ASPEED_CLK_GATE_LCLK>;
151 memory-region = <&flash_memory>;
152 flash = <&spi>;
153 };
154};
155
115LPC Host Controller156LPC Host Controller
116-------------------157-------------------
117 158
Documentation/devicetree/bindings/nvmem/imx-ocotp.txt+19−4
@@ -11,17 +11,32 @@ Required properties: · 10 unmodified lines
11 "fsl,imx6ul-ocotp" (i.MX6UL),11 "fsl,imx6ul-ocotp" (i.MX6UL),
12 "fsl,imx7d-ocotp" (i.MX7D/S),12 "fsl,imx7d-ocotp" (i.MX7D/S),
13 followed by "syscon".13 followed by "syscon".
14- #address-cells : Should be 1
15- #size-cells : Should be 1
14- reg: Should contain the register base and length.16- reg: Should contain the register base and length.
15- clocks: Should contain a phandle pointing to the gated peripheral clock.17- clocks: Should contain a phandle pointing to the gated peripheral clock.
16 18
17Optional properties:19Optional properties:
18- read-only: disable write access20- read-only: disable write access
19 21
20Example:22Optional Child nodes:
23
24- Data cells of ocotp:
25 Detailed bindings are described in bindings/nvmem/nvmem.txt
21 26
27Example:
22 ocotp: ocotp@21bc000 {28 ocotp: ocotp@21bc000 {
23 compatible = "fsl,imx6q-ocotp", "syscon";29 #address-cells = <1>;
30 #size-cells = <1>;
31 compatible = "fsl,imx6sx-ocotp", "syscon";
24 reg = <0x021bc000 0x4000>;32 reg = <0x021bc000 0x4000>;
25 clocks = <&clks IMX6QDL_CLK_IIM>;33 clocks = <&clks IMX6SX_CLK_OCOTP>;
26 read-only;34
35 tempmon_calib: calib@38 {
36 reg = <0x38 4>;
37 };
38
39 tempmon_temp_grade: temp-grade@20 {
40 reg = <0x20 4>;
41 };
27 };42 };
Documentation/devicetree/bindings/nvmem/snvs-lpgpr.txt+2−1
@@ -1,5 +1,5 @@
1Device tree bindings for Low Power General Purpose Register found in i.MX6Q/D1Device tree bindings for Low Power General Purpose Register found in i.MX6Q/D
2Secure Non-Volatile Storage.2and i.MX7 Secure Non-Volatile Storage.
3 3
4This DT node should be represented as a sub-node of a "syscon",4This DT node should be represented as a sub-node of a "syscon",
5"simple-mfd" node.5"simple-mfd" node.
@@ -8,6 +8,7 @@ Required properties: · 2 unmodified lines
8- compatible: should be one of the fallowing variants:8- compatible: should be one of the fallowing variants:
9 "fsl,imx6q-snvs-lpgpr" for Freescale i.MX6Q/D/DL/S9 "fsl,imx6q-snvs-lpgpr" for Freescale i.MX6Q/D/DL/S
10 "fsl,imx6ul-snvs-lpgpr" for Freescale i.MX6UL10 "fsl,imx6ul-snvs-lpgpr" for Freescale i.MX6UL
11 "fsl,imx7d-snvs-lpgpr" for Freescale i.MX7D/S
11 12
12Example:13Example:
13snvs: snvs@020cc000 {14snvs: snvs@020cc000 {
Documentation/driver-api/uio-howto.rst+5−0
@@ -709,6 +709,11 @@ The vmbus device regions are mapped into uio device resources: · 708 unmodified lines
709 3) Network receive buffer region709 3) Network receive buffer region
710 4) Network send buffer region710 4) Network send buffer region
711 711
712If a subchannel is created by a request to host, then the uio_hv_generic
713device driver will create a sysfs binary file for the per-channel ring buffer.
714For example:
715 /sys/bus/vmbus/devices/3811fe4d-0fa0-4b62-981a-74fc1084c757/channels/21/ring
716
712Further information717Further information
713===================718===================
714 719
MAINTAINERS+6−1
@@ -6212,6 +6212,11 @@ F: Documentation/hw_random.txt · 6211 unmodified lines
6212F: drivers/char/hw_random/6212F: drivers/char/hw_random/
6213F: include/linux/hw_random.h6213F: include/linux/hw_random.h
6214 6214
6215HARDWARE TRACING FACILITIES
6216M: Alexander Shishkin <alexander.shishkin@linux.intel.com>
6217S: Maintained
6218F: drivers/hwtracing/
6219
6215HARDWARE SPINLOCK CORE6220HARDWARE SPINLOCK CORE
6216M: Ohad Ben-Cohen <ohad@wizery.com>6221M: Ohad Ben-Cohen <ohad@wizery.com>
6217M: Bjorn Andersson <bjorn.andersson@linaro.org>6222M: Bjorn Andersson <bjorn.andersson@linaro.org>
@@ -8140,7 +8145,7 @@ F: drivers/*/*/*pasemi* · 1922 unmodified lines
8140LINUX KERNEL DUMP TEST MODULE (LKDTM)8145LINUX KERNEL DUMP TEST MODULE (LKDTM)
8141M: Kees Cook <keescook@chromium.org>8146M: Kees Cook <keescook@chromium.org>
8142S: Maintained8147S: Maintained
8143F: drivers/misc/lkdtm*8148F: drivers/misc/lkdtm/*
8144 8149
8145LINUX KERNEL MEMORY CONSISTENCY MODEL (LKMM)8150LINUX KERNEL MEMORY CONSISTENCY MODEL (LKMM)
8146M: Alan Stern <stern@rowland.harvard.edu>8151M: Alan Stern <stern@rowland.harvard.edu>
arch/x86/entry/entry_32.S+3−0
@@ -902,6 +902,9 @@ BUILD_INTERRUPT3(hyperv_callback_vector, HYPERVISOR_CALLBACK_VECTOR, · 901 unmodified lines
902BUILD_INTERRUPT3(hyperv_reenlightenment_vector, HYPERV_REENLIGHTENMENT_VECTOR,902BUILD_INTERRUPT3(hyperv_reenlightenment_vector, HYPERV_REENLIGHTENMENT_VECTOR,
903 hyperv_reenlightenment_intr)903 hyperv_reenlightenment_intr)
904 904
905BUILD_INTERRUPT3(hv_stimer0_callback_vector, HYPERV_STIMER0_VECTOR,
906 hv_stimer0_vector_handler)
907
905#endif /* CONFIG_HYPERV */908#endif /* CONFIG_HYPERV */
906 909
907ENTRY(page_fault)910ENTRY(page_fault)
arch/x86/entry/entry_64.S+3−0
@@ -1140,6 +1140,9 @@ apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \ · 1139 unmodified lines
1140 1140
1141apicinterrupt3 HYPERV_REENLIGHTENMENT_VECTOR \1141apicinterrupt3 HYPERV_REENLIGHTENMENT_VECTOR \
1142 hyperv_reenlightenment_vector hyperv_reenlightenment_intr1142 hyperv_reenlightenment_vector hyperv_reenlightenment_intr
1143
1144apicinterrupt3 HYPERV_STIMER0_VECTOR \
1145 hv_stimer0_callback_vector hv_stimer0_vector_handler
1143#endif /* CONFIG_HYPERV */1146#endif /* CONFIG_HYPERV */
1144 1147
1145idtentry debug do_debug has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK1148idtentry debug do_debug has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK
arch/x86/include/asm/hardirq.h+1−0
@@ -40,6 +40,7 @@ typedef struct { · 39 unmodified lines
40#endif40#endif
41#if IS_ENABLED(CONFIG_HYPERV)41#if IS_ENABLED(CONFIG_HYPERV)
42 unsigned int irq_hv_reenlightenment_count;42 unsigned int irq_hv_reenlightenment_count;
43 unsigned int hyperv_stimer0_count;
43#endif44#endif
44} ____cacheline_aligned irq_cpustat_t;45} ____cacheline_aligned irq_cpustat_t;
45 46
arch/x86/include/asm/irq_vectors.h+2−1
@@ -106,9 +106,10 @@ · 105 unmodified lines
106 106
107#if IS_ENABLED(CONFIG_HYPERV)107#if IS_ENABLED(CONFIG_HYPERV)
108#define HYPERV_REENLIGHTENMENT_VECTOR 0xee108#define HYPERV_REENLIGHTENMENT_VECTOR 0xee
109#define HYPERV_STIMER0_VECTOR 0xed
109#endif110#endif
110 111
111#define LOCAL_TIMER_VECTOR 0xed112#define LOCAL_TIMER_VECTOR 0xec
112 113
113#define NR_VECTORS 256114#define NR_VECTORS 256
114 115
arch/x86/include/asm/mshyperv.h+13−0
@@ -173,6 +173,19 @@ void hv_remove_kexec_handler(void); · 172 unmodified lines
173void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs));173void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs));
174void hv_remove_crash_handler(void);174void hv_remove_crash_handler(void);
175 175
176/*
177 * Routines for stimer0 Direct Mode handling.
178 * On x86/x64, there are no percpu actions to take.
179 */
180void hv_stimer0_vector_handler(struct pt_regs *regs);
181void hv_stimer0_callback_vector(void);
182int hv_setup_stimer0_irq(int *irq, int *vector, void (*handler)(void));
183void hv_remove_stimer0_irq(int irq);
184
185static inline void hv_enable_stimer0_percpu_irq(int irq) {}
186static inline void hv_disable_stimer0_percpu_irq(int irq) {}
187
188
176#if IS_ENABLED(CONFIG_HYPERV)189#if IS_ENABLED(CONFIG_HYPERV)
177extern struct clocksource *hyperv_cs;190extern struct clocksource *hyperv_cs;
178extern void *hv_hypercall_pg;191extern void *hv_hypercall_pg;
arch/x86/include/uapi/asm/hyperv.h+3−0
@@ -77,6 +77,9 @@ · 76 unmodified lines
77/* Crash MSR available */77/* Crash MSR available */
78#define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE (1 << 10)78#define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE (1 << 10)
79 79
80/* stimer Direct Mode is available */
81#define HV_X64_STIMER_DIRECT_MODE_AVAILABLE (1 << 19)
82
80/*83/*
81 * Feature identification: EBX indicates which flags were specified at84 * Feature identification: EBX indicates which flags were specified at
82 * partition creation. The format is the same as the partition creation85 * partition creation. The format is the same as the partition creation
arch/x86/kernel/cpu/mshyperv.c+40−0
@@ -37,6 +37,7 @@ EXPORT_SYMBOL_GPL(ms_hyperv); · 36 unmodified lines
37 37
38#if IS_ENABLED(CONFIG_HYPERV)38#if IS_ENABLED(CONFIG_HYPERV)
39static void (*vmbus_handler)(void);39static void (*vmbus_handler)(void);
40static void (*hv_stimer0_handler)(void);
40static void (*hv_kexec_handler)(void);41static void (*hv_kexec_handler)(void);
41static void (*hv_crash_handler)(struct pt_regs *regs);42static void (*hv_crash_handler)(struct pt_regs *regs);
42 43
@@ -69,6 +70,41 @@ void hv_remove_vmbus_irq(void) · 26 unmodified lines
69EXPORT_SYMBOL_GPL(hv_setup_vmbus_irq);70EXPORT_SYMBOL_GPL(hv_setup_vmbus_irq);
70EXPORT_SYMBOL_GPL(hv_remove_vmbus_irq);71EXPORT_SYMBOL_GPL(hv_remove_vmbus_irq);
71 72
73/*
74 * Routines to do per-architecture handling of stimer0
75 * interrupts when in Direct Mode
76 */
77
78__visible void __irq_entry hv_stimer0_vector_handler(struct pt_regs *regs)
79{
80 struct pt_regs *old_regs = set_irq_regs(regs);
81
82 entering_irq();
83 inc_irq_stat(hyperv_stimer0_count);
84 if (hv_stimer0_handler)
85 hv_stimer0_handler();
86 ack_APIC_irq();
87
88 exiting_irq();
89 set_irq_regs(old_regs);
90}
91
92int hv_setup_stimer0_irq(int *irq, int *vector, void (*handler)(void))
93{
94 *vector = HYPERV_STIMER0_VECTOR;
95 *irq = 0; /* Unused on x86/x64 */
96 hv_stimer0_handler = handler;
97 return 0;
98}
99EXPORT_SYMBOL_GPL(hv_setup_stimer0_irq);
100
101void hv_remove_stimer0_irq(int irq)
102{
103 /* We have no way to deallocate the interrupt gate */
104 hv_stimer0_handler = NULL;
105}
106EXPORT_SYMBOL_GPL(hv_remove_stimer0_irq);
107
72void hv_setup_kexec_handler(void (*handler)(void))108void hv_setup_kexec_handler(void (*handler)(void))
73{109{
74 hv_kexec_handler = handler;110 hv_kexec_handler = handler;
@@ -257,6 +293,10 @@ static void __init ms_hyperv_init_platform(void) · 182 unmodified lines
257 alloc_intr_gate(HYPERV_REENLIGHTENMENT_VECTOR,293 alloc_intr_gate(HYPERV_REENLIGHTENMENT_VECTOR,
258 hyperv_reenlightenment_vector);294 hyperv_reenlightenment_vector);
259 295
296 /* Setup the IDT for stimer0 */
297 if (ms_hyperv.misc_features & HV_X64_STIMER_DIRECT_MODE_AVAILABLE)
298 alloc_intr_gate(HYPERV_STIMER0_VECTOR,
299 hv_stimer0_callback_vector);
260#endif300#endif
261}301}
262 302
arch/x86/kernel/irq.c+7−0
@@ -150,6 +150,13 @@ int arch_show_interrupts(struct seq_file *p, int prec) · 149 unmodified lines
150 irq_stats(j)->irq_hv_reenlightenment_count);150 irq_stats(j)->irq_hv_reenlightenment_count);
151 seq_puts(p, " Hyper-V reenlightenment interrupts\n");151 seq_puts(p, " Hyper-V reenlightenment interrupts\n");
152 }152 }
153 if (test_bit(HYPERV_STIMER0_VECTOR, system_vectors)) {
154 seq_printf(p, "%*s: ", prec, "HVS");
155 for_each_online_cpu(j)
156 seq_printf(p, "%10u ",
157 irq_stats(j)->hyperv_stimer0_count);
158 seq_puts(p, " Hyper-V stimer0 interrupts\n");
159 }
153#endif160#endif
154 seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));161 seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count));
155#if defined(CONFIG_X86_IO_APIC)162#if defined(CONFIG_X86_IO_APIC)
block/genhd.c+11−8
@@ -308,19 +308,22 @@ void blkdev_show(struct seq_file *seqf, off_t offset) · 307 unmodified lines
308/**308/**
309 * register_blkdev - register a new block device309 * register_blkdev - register a new block device
310 *310 *
311 * @major: the requested major device number [1..255]. If @major = 0, try to311 * @major: the requested major device number [1..BLKDEV_MAJOR_MAX-1]. If
312 * allocate any unused major number.312 * @major = 0, try to allocate any unused major number.
313 * @name: the name of the new block device as a zero terminated string313 * @name: the name of the new block device as a zero terminated string
314 *314 *
315 * The @name must be unique within the system.315 * The @name must be unique within the system.
316 *316 *
317 * The return value depends on the @major input parameter:317 * The return value depends on the @major input parameter:
318 *318 *
319 * - if a major device number was requested in range [1..255] then the319 * - if a major device number was requested in range [1..BLKDEV_MAJOR_MAX-1]
320 * function returns zero on success, or a negative error code320 * then the function returns zero on success, or a negative error code
321 * - if any unused major number was requested with @major = 0 parameter321 * - if any unused major number was requested with @major = 0 parameter
322 * then the return value is the allocated major number in range322 * then the return value is the allocated major number in range
323 * [1..255] or a negative error code otherwise323 * [1..BLKDEV_MAJOR_MAX-1] or a negative error code otherwise
324 *
325 * See Documentation/admin-guide/devices.txt for the list of allocated
326 * major numbers.
324 */327 */
325int register_blkdev(unsigned int major, const char *name)328int register_blkdev(unsigned int major, const char *name)
326{329{
@@ -347,8 +350,8 @@ int register_blkdev(unsigned int major, const char *name) · 20 unmodified lines
347 }350 }
348 351
349 if (major >= BLKDEV_MAJOR_MAX) {352 if (major >= BLKDEV_MAJOR_MAX) {
350 pr_err("register_blkdev: major requested (%d) is greater than the maximum (%d) for %s\n",353 pr_err("register_blkdev: major requested (%u) is greater than the maximum (%u) for %s\n",
351 major, BLKDEV_MAJOR_MAX, name);354 major, BLKDEV_MAJOR_MAX-1, name);
352 355
353 ret = -EINVAL;356 ret = -EINVAL;
354 goto out;357 goto out;
@@ -375,7 +378,7 @@ int register_blkdev(unsigned int major, const char *name) · 20 unmodified lines
375 ret = -EBUSY;378 ret = -EBUSY;
376 379
377 if (ret < 0) {380 if (ret < 0) {
378 printk("register_blkdev: cannot get major %d for %s\n",381 printk("register_blkdev: cannot get major %u for %s\n",
379 major, name);382 major, name);
380 kfree(p);383 kfree(p);
381 }384 }
drivers/Kconfig+1−3
@@ -199,9 +199,7 @@ source "drivers/dax/Kconfig" · 198 unmodified lines
199 199
200source "drivers/nvmem/Kconfig"200source "drivers/nvmem/Kconfig"
201 201
202source "drivers/hwtracing/stm/Kconfig"202source "drivers/hwtracing/Kconfig"
203
204source "drivers/hwtracing/intel_th/Kconfig"
205 203
206source "drivers/fpga/Kconfig"204source "drivers/fpga/Kconfig"
207 205
drivers/char/Kconfig+1−1
@@ -236,7 +236,7 @@ source "drivers/char/hw_random/Kconfig" · 235 unmodified lines
236 236
237config NVRAM237config NVRAM
238 tristate "/dev/nvram support"238 tristate "/dev/nvram support"
239 depends on ATARI || X86 || (ARM && RTC_DRV_CMOS) || GENERIC_NVRAM239 depends on ATARI || X86 || GENERIC_NVRAM
240 ---help---240 ---help---
241 If you say Y here and create a character special file /dev/nvram241 If you say Y here and create a character special file /dev/nvram
242 with major number 10 and minor number 144 using mknod ("man mknod"),242 with major number 10 and minor number 144 using mknod ("man mknod"),
drivers/char/mem.c+3−3
@@ -137,7 +137,7 @@ static ssize_t read_mem(struct file *file, char __user *buf, · 136 unmodified lines
137 137
138 while (count > 0) {138 while (count > 0) {
139 unsigned long remaining;139 unsigned long remaining;
140 int allowed;140 int allowed, probe;
141 141
142 sz = size_inside_page(p, count);142 sz = size_inside_page(p, count);
143 143
@@ -160,9 +160,9 @@ static ssize_t read_mem(struct file *file, char __user *buf, · 16 unmodified lines
160 if (!ptr)160 if (!ptr)
161 goto failed;161 goto failed;
162 162
163 err = probe_kernel_read(bounce, ptr, sz);163 probe = probe_kernel_read(bounce, ptr, sz);
164 unxlate_dev_mem_ptr(p, ptr);164 unxlate_dev_mem_ptr(p, ptr);
165 if (err)165 if (probe)
166 goto failed;166 goto failed;
167 167
168 remaining = copy_to_user(buf, bounce, sz);168 remaining = copy_to_user(buf, bounce, sz);
drivers/char/xillybus/xillybus_pcie.c+0−1
@@ -24,7 +24,6 @@ MODULE_LICENSE("GPL v2"); · 23 unmodified lines
24 24
25#define PCI_DEVICE_ID_XILLYBUS 0xebeb25#define PCI_DEVICE_ID_XILLYBUS 0xebeb
26 26
27#define PCI_VENDOR_ID_ALTERA 0x1172
28#define PCI_VENDOR_ID_ACTEL 0x11aa27#define PCI_VENDOR_ID_ACTEL 0x11aa
29#define PCI_VENDOR_ID_LATTICE 0x120428#define PCI_VENDOR_ID_LATTICE 0x1204
30 29
drivers/extcon/extcon-gpio.c+45−58
@@ -18,8 +18,6 @@ · 17 unmodified lines
18 */18 */
19 19
20#include <linux/extcon-provider.h>20#include <linux/extcon-provider.h>
21#include <linux/extcon/extcon-gpio.h>
22#include <linux/gpio.h>
23#include <linux/gpio/consumer.h>21#include <linux/gpio/consumer.h>
24#include <linux/init.h>22#include <linux/init.h>
25#include <linux/interrupt.h>23#include <linux/interrupt.h>
@@ -29,14 +27,30 @@ · 3 unmodified lines
29#include <linux/slab.h>27#include <linux/slab.h>
30#include <linux/workqueue.h>28#include <linux/workqueue.h>
31 29
30/**
31 * struct gpio_extcon_data - A simple GPIO-controlled extcon device state container.
32 * @edev: Extcon device.
33 * @irq: Interrupt line for the external connector.
34 * @work: Work fired by the interrupt.
35 * @debounce_jiffies: Number of jiffies to wait for the GPIO to stabilize, from the debounce
36 * value.
37 * @gpiod: GPIO descriptor for this external connector.
38 * @extcon_id: The unique id of specific external connector.
39 * @debounce: Debounce time for GPIO IRQ in ms.
40 * @irq_flags: IRQ Flags (e.g., IRQF_TRIGGER_LOW).
41 * @check_on_resume: Boolean describing whether to check the state of gpio
42 * while resuming from sleep.
43 */
32struct gpio_extcon_data {44struct gpio_extcon_data {
33 struct extcon_dev *edev;45 struct extcon_dev *edev;
34 int irq;46 int irq;
35 struct delayed_work work;47 struct delayed_work work;
36 unsigned long debounce_jiffies;48 unsigned long debounce_jiffies;
37 49 struct gpio_desc *gpiod;
38 struct gpio_desc *id_gpiod;50 unsigned int extcon_id;
39 struct gpio_extcon_pdata *pdata;51 unsigned long debounce;
52 unsigned long irq_flags;
53 bool check_on_resume;
40};54};
41 55
42static void gpio_extcon_work(struct work_struct *work)56static void gpio_extcon_work(struct work_struct *work)
@@ -46,11 +60,8 @@ static void gpio_extcon_work(struct work_struct *work) · 3 unmodified lines
46 container_of(to_delayed_work(work), struct gpio_extcon_data,60 container_of(to_delayed_work(work), struct gpio_extcon_data,
47 work);61 work);
48 62
49 state = gpiod_get_value_cansleep(data->id_gpiod);63 state = gpiod_get_value_cansleep(data->gpiod);
50 if (data->pdata->gpio_active_low)64 extcon_set_state_sync(data->edev, data->extcon_id, state);
51 state = !state;
52
53 extcon_set_state_sync(data->edev, data->pdata->extcon_id, state);
54}65}
55 66
56static irqreturn_t gpio_irq_handler(int irq, void *dev_id)67static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
@@ -62,65 +73,41 @@ static irqreturn_t gpio_irq_handler(int irq, void *dev_id) · 5 unmodified lines
62 return IRQ_HANDLED;73 return IRQ_HANDLED;
63}74}
64 75
65static int gpio_extcon_init(struct device *dev, struct gpio_extcon_data *data)
66{
67 struct gpio_extcon_pdata *pdata = data->pdata;
68 int ret;
69
70 ret = devm_gpio_request_one(dev, pdata->gpio, GPIOF_DIR_IN,
71 dev_name(dev));
72 if (ret < 0)
73 return ret;
74
75 data->id_gpiod = gpio_to_desc(pdata->gpio);
76 if (!data->id_gpiod)
77 return -EINVAL;
78
79 if (pdata->debounce) {
80 ret = gpiod_set_debounce(data->id_gpiod,
81 pdata->debounce * 1000);
82 if (ret < 0)
83 data->debounce_jiffies =
84 msecs_to_jiffies(pdata->debounce);
85 }
86
87 data->irq = gpiod_to_irq(data->id_gpiod);
88 if (data->irq < 0)
89 return data->irq;
90
91 return 0;
92}
93
94static int gpio_extcon_probe(struct platform_device *pdev)76static int gpio_extcon_probe(struct platform_device *pdev)
95{77{
96 struct gpio_extcon_pdata *pdata = dev_get_platdata(&pdev->dev);
97 struct gpio_extcon_data *data;78 struct gpio_extcon_data *data;
79 struct device *dev = &pdev->dev;
98 int ret;80 int ret;
99 81
100 if (!pdata)82 data = devm_kzalloc(dev, sizeof(struct gpio_extcon_data), GFP_KERNEL);
101 return -EBUSY;
102 if (!pdata->irq_flags || pdata->extcon_id > EXTCON_NONE)
103 return -EINVAL;
104
105 data = devm_kzalloc(&pdev->dev, sizeof(struct gpio_extcon_data),
106 GFP_KERNEL);
107 if (!data)83 if (!data)
108 return -ENOMEM;84 return -ENOMEM;
109 data->pdata = pdata;
110 85
111 /* Initialize the gpio */86 /*
112 ret = gpio_extcon_init(&pdev->dev, data);87 * FIXME: extcon_id represents the unique identifier of external
113 if (ret < 0)88 * connectors such as EXTCON_USB, EXTCON_DISP_HDMI and so on. extcon_id
114 return ret;89 * is necessary to register the extcon device. But, it's not yet
90 * developed to get the extcon id from device-tree or others.
91 * On later, it have to be solved.
92 */
93 if (!data->irq_flags || data->extcon_id > EXTCON_NONE)
94 return -EINVAL;
95
96 data->gpiod = devm_gpiod_get(dev, "extcon", GPIOD_IN);
97 if (IS_ERR(data->gpiod))
98 return PTR_ERR(data->gpiod);
99 data->irq = gpiod_to_irq(data->gpiod);
100 if (data->irq <= 0)
101 return data->irq;
115 102
116 /* Allocate the memory of extcon devie and register extcon device */103 /* Allocate the memory of extcon devie and register extcon device */
117 data->edev = devm_extcon_dev_allocate(&pdev->dev, &pdata->extcon_id);104 data->edev = devm_extcon_dev_allocate(dev, &data->extcon_id);
118 if (IS_ERR(data->edev)) {105 if (IS_ERR(data->edev)) {
119 dev_err(&pdev->dev, "failed to allocate extcon device\n");106 dev_err(dev, "failed to allocate extcon device\n");
120 return -ENOMEM;107 return -ENOMEM;
121 }108 }
122 109
123 ret = devm_extcon_dev_register(&pdev->dev, data->edev);110 ret = devm_extcon_dev_register(dev, data->edev);
124 if (ret < 0)111 if (ret < 0)
125 return ret;112 return ret;
126 113
@@ -130,8 +117,8 @@ static int gpio_extcon_probe(struct platform_device *pdev) · 3 unmodified lines
130 * Request the interrupt of gpio to detect whether external connector117 * Request the interrupt of gpio to detect whether external connector
131 * is attached or detached.118 * is attached or detached.
132 */119 */
133 ret = devm_request_any_context_irq(&pdev->dev, data->irq,120 ret = devm_request_any_context_irq(dev, data->irq,
134 gpio_irq_handler, pdata->irq_flags,121 gpio_irq_handler, data->irq_flags,
135 pdev->name, data);122 pdev->name, data);
136 if (ret < 0)123 if (ret < 0)
137 return ret;124 return ret;
@@ -158,7 +145,7 @@ static int gpio_extcon_resume(struct device *dev) · 20 unmodified lines
158 struct gpio_extcon_data *data;145 struct gpio_extcon_data *data;
159 146
160 data = dev_get_drvdata(dev);147 data = dev_get_drvdata(dev);
161 if (data->pdata->check_on_resume)148 if (data->check_on_resume)
162 queue_delayed_work(system_power_efficient_wq,149 queue_delayed_work(system_power_efficient_wq,
163 &data->work, data->debounce_jiffies);150 &data->work, data->debounce_jiffies);
164 151
drivers/extcon/extcon-intel-cht-wc.c+7−4
@@ -66,6 +66,8 @@ · 65 unmodified lines
66 66
67#define CHT_WC_VBUS_GPIO_CTLO 0x6e2d67#define CHT_WC_VBUS_GPIO_CTLO 0x6e2d
68#define CHT_WC_VBUS_GPIO_CTLO_OUTPUT BIT(0)68#define CHT_WC_VBUS_GPIO_CTLO_OUTPUT BIT(0)
69#define CHT_WC_VBUS_GPIO_CTLO_DRV_OD BIT(4)
70#define CHT_WC_VBUS_GPIO_CTLO_DIR_OUT BIT(5)
69 71
70enum cht_wc_usb_id {72enum cht_wc_usb_id {
71 USB_ID_OTG,73 USB_ID_OTG,
@@ -183,14 +185,15 @@ static void cht_wc_extcon_set_5v_boost(struct cht_wc_extcon_data *ext, · 111 unmodified lines
183{185{
184 int ret, val;186 int ret, val;
185 187
186 val = enable ? CHT_WC_VBUS_GPIO_CTLO_OUTPUT : 0;
187
188 /*188 /*
189 * The 5V boost converter is enabled through a gpio on the PMIC, since189 * The 5V boost converter is enabled through a gpio on the PMIC, since
190 * there currently is no gpio driver we access the gpio reg directly.190 * there currently is no gpio driver we access the gpio reg directly.
191 */191 */
192 ret = regmap_update_bits(ext->regmap, CHT_WC_VBUS_GPIO_CTLO,192 val = CHT_WC_VBUS_GPIO_CTLO_DRV_OD | CHT_WC_VBUS_GPIO_CTLO_DIR_OUT;
193 CHT_WC_VBUS_GPIO_CTLO_OUTPUT, val);193 if (enable)
194 val |= CHT_WC_VBUS_GPIO_CTLO_OUTPUT;
195
196 ret = regmap_write(ext->regmap, CHT_WC_VBUS_GPIO_CTLO, val);
194 if (ret)197 if (ret)
195 dev_err(ext->dev, "Error writing Vbus GPIO CTLO: %d\n", ret);198 dev_err(ext->dev, "Error writing Vbus GPIO CTLO: %d\n", ret);
196}199}
drivers/extcon/extcon-intel-int3496.c+5−4
@@ -50,7 +50,11 @@ static const struct acpi_gpio_params vbus_gpios = { INT3496_GPIO_VBUS_EN, 0, fal · 49 unmodified lines
50static const struct acpi_gpio_params mux_gpios = { INT3496_GPIO_USB_MUX, 0, false };50static const struct acpi_gpio_params mux_gpios = { INT3496_GPIO_USB_MUX, 0, false };
51 51
52static const struct acpi_gpio_mapping acpi_int3496_default_gpios[] = {52static const struct acpi_gpio_mapping acpi_int3496_default_gpios[] = {
53 { "id-gpios", &id_gpios, 1 },53 /*
54 * Some platforms have a bug in ACPI GPIO description making IRQ
55 * GPIO to be output only. Ask the GPIO core to ignore this limit.
56 */
57 { "id-gpios", &id_gpios, 1, ACPI_GPIO_QUIRK_NO_IO_RESTRICTION },
54 { "vbus-gpios", &vbus_gpios, 1 },58 { "vbus-gpios", &vbus_gpios, 1 },
55 { "mux-gpios", &mux_gpios, 1 },59 { "mux-gpios", &mux_gpios, 1 },
56 { },60 { },
@@ -112,9 +116,6 @@ static int int3496_probe(struct platform_device *pdev) · 55 unmodified lines
112 ret = PTR_ERR(data->gpio_usb_id);116 ret = PTR_ERR(data->gpio_usb_id);
113 dev_err(dev, "can't request USB ID GPIO: %d\n", ret);117 dev_err(dev, "can't request USB ID GPIO: %d\n", ret);
114 return ret;118 return ret;
115 } else if (gpiod_get_direction(data->gpio_usb_id) != GPIOF_DIR_IN) {
116 dev_warn(dev, FW_BUG "USB ID GPIO not in input mode, fixing\n");
117 gpiod_direction_input(data->gpio_usb_id);
118 }119 }
119 120
120 data->usb_id_irq = gpiod_to_irq(data->gpio_usb_id);121 data->usb_id_irq = gpiod_to_irq(data->gpio_usb_id);
drivers/extcon/extcon.c+34−10
@@ -1336,6 +1336,28 @@ void extcon_dev_unregister(struct extcon_dev *edev) · 1335 unmodified lines
1336EXPORT_SYMBOL_GPL(extcon_dev_unregister);1336EXPORT_SYMBOL_GPL(extcon_dev_unregister);
1337 1337
1338#ifdef CONFIG_OF1338#ifdef CONFIG_OF
1339
1340/*
1341 * extcon_find_edev_by_node - Find the extcon device from devicetree.
1342 * @node : OF node identifying edev
1343 *
1344 * Return the pointer of extcon device if success or ERR_PTR(err) if fail.
1345 */
1346struct extcon_dev *extcon_find_edev_by_node(struct device_node *node)
1347{
1348 struct extcon_dev *edev;
1349
1350 mutex_lock(&extcon_dev_list_lock);
1351 list_for_each_entry(edev, &extcon_dev_list, entry)
1352 if (edev->dev.parent && edev->dev.parent->of_node == node)
1353 goto out;
1354 edev = ERR_PTR(-EPROBE_DEFER);
1355out:
1356 mutex_unlock(&extcon_dev_list_lock);
1357
1358 return edev;
1359}
1360
1339/*1361/*
1340 * extcon_get_edev_by_phandle - Get the extcon device from devicetree.1362 * extcon_get_edev_by_phandle - Get the extcon device from devicetree.
1341 * @dev : the instance to the given device1363 * @dev : the instance to the given device
@@ -1363,25 +1385,27 @@ struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev, int index) · 21 unmodified lines
1363 return ERR_PTR(-ENODEV);1385 return ERR_PTR(-ENODEV);
1364 }1386 }
1365 1387
1366 mutex_lock(&extcon_dev_list_lock);1388 edev = extcon_find_edev_by_node(node);
1367 list_for_each_entry(edev, &extcon_dev_list, entry) {
1368 if (edev->dev.parent && edev->dev.parent->of_node == node) {
1369 mutex_unlock(&extcon_dev_list_lock);
1370 of_node_put(node);
1371 return edev;
1372 }
1373 }
1374 mutex_unlock(&extcon_dev_list_lock);
1375 of_node_put(node);1389 of_node_put(node);
1376 1390
1377 return ERR_PTR(-EPROBE_DEFER);1391 return edev;
1378}1392}
1393
1379#else1394#else
1395
1396struct extcon_dev *extcon_find_edev_by_node(struct device_node *node)
1397{
1398 return ERR_PTR(-ENOSYS);
1399}
1400
1380struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev, int index)1401struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev, int index)
1381{1402{
1382 return ERR_PTR(-ENOSYS);1403 return ERR_PTR(-ENOSYS);
1383}1404}
1405
1384#endif /* CONFIG_OF */1406#endif /* CONFIG_OF */
1407
1408EXPORT_SYMBOL_GPL(extcon_find_edev_by_node);
1385EXPORT_SYMBOL_GPL(extcon_get_edev_by_phandle);1409EXPORT_SYMBOL_GPL(extcon_get_edev_by_phandle);
1386 1410
1387/**1411/**
drivers/fpga/altera-cvp.c+0−2
@@ -384,8 +384,6 @@ static int altera_cvp_probe(struct pci_dev *pdev, · 383 unmodified lines
384 const struct pci_device_id *dev_id);384 const struct pci_device_id *dev_id);
385static void altera_cvp_remove(struct pci_dev *pdev);385static void altera_cvp_remove(struct pci_dev *pdev);
386 386
387#define PCI_VENDOR_ID_ALTERA 0x1172
388
389static struct pci_device_id altera_cvp_id_tbl[] = {387static struct pci_device_id altera_cvp_id_tbl[] = {
390 { PCI_VDEVICE(ALTERA, PCI_ANY_ID) },388 { PCI_VDEVICE(ALTERA, PCI_ANY_ID) },
391 { }389 { }
drivers/fsi/Kconfig+1−0
@@ -4,6 +4,7 @@ · 3 unmodified lines
4 4
5menuconfig FSI5menuconfig FSI
6 tristate "FSI support"6 tristate "FSI support"
7 depends on OF
7 select CRC48 select CRC4
8 ---help---9 ---help---
9 FSI - the FRU Support Interface - is a simple bus for low-level10 FSI - the FRU Support Interface - is a simple bus for low-level
drivers/fsi/fsi-core.c+120−9
@@ -18,6 +18,7 @@ · 17 unmodified lines
18#include <linux/fsi.h>18#include <linux/fsi.h>
19#include <linux/idr.h>19#include <linux/idr.h>
20#include <linux/module.h>20#include <linux/module.h>
21#include <linux/of.h>
21#include <linux/slab.h>22#include <linux/slab.h>
22#include <linux/bitops.h>23#include <linux/bitops.h>
23 24
@@ -142,6 +143,7 @@ static void fsi_device_release(struct device *_device) · 118 unmodified lines
142{143{
143 struct fsi_device *device = to_fsi_dev(_device);144 struct fsi_device *device = to_fsi_dev(_device);
144 145
146 of_node_put(device->dev.of_node);
145 kfree(device);147 kfree(device);
146}148}
147 149
@@ -205,7 +207,7 @@ static int fsi_slave_report_and_clear_errors(struct fsi_slave *slave) · 57 unmodified lines
205 if (rc)207 if (rc)
206 return rc;208 return rc;
207 209
208 dev_info(&slave->dev, "status: 0x%08x, sisc: 0x%08x\n",210 dev_dbg(&slave->dev, "status: 0x%08x, sisc: 0x%08x\n",
209 be32_to_cpu(stat), be32_to_cpu(irq));211 be32_to_cpu(stat), be32_to_cpu(irq));
210 212
211 /* clear interrupts */213 /* clear interrupts */
@@ -334,6 +336,57 @@ extern void fsi_slave_release_range(struct fsi_slave *slave, · 122 unmodified lines
334}336}
335EXPORT_SYMBOL_GPL(fsi_slave_release_range);337EXPORT_SYMBOL_GPL(fsi_slave_release_range);
336 338
339static bool fsi_device_node_matches(struct device *dev, struct device_node *np,
340 uint32_t addr, uint32_t size)
341{
342 unsigned int len, na, ns;
343 const __be32 *prop;
344 uint32_t psize;
345
346 na = of_n_addr_cells(np);
347 ns = of_n_size_cells(np);
348
349 if (na != 1 || ns != 1)
350 return false;
351
352 prop = of_get_property(np, "reg", &len);
353 if (!prop || len != 8)
354 return false;
355
356 if (of_read_number(prop, 1) != addr)
357 return false;
358
359 psize = of_read_number(prop + 1, 1);
360 if (psize != size) {
361 dev_warn(dev,
362 "node %s matches probed address, but not size (got 0x%x, expected 0x%x)",
363 of_node_full_name(np), psize, size);
364 }
365
366 return true;
367}
368
369/* Find a matching node for the slave engine at @address, using @size bytes
370 * of space. Returns NULL if not found, or a matching node with refcount
371 * already incremented.
372 */
373static struct device_node *fsi_device_find_of_node(struct fsi_device *dev)
374{
375 struct device_node *parent, *np;
376
377 parent = dev_of_node(&dev->slave->dev);
378 if (!parent)
379 return NULL;
380
381 for_each_child_of_node(parent, np) {
382 if (fsi_device_node_matches(&dev->dev, np,
383 dev->addr, dev->size))
384 return np;
385 }
386
387 return NULL;
388}
389
337static int fsi_slave_scan(struct fsi_slave *slave)390static int fsi_slave_scan(struct fsi_slave *slave)
338{391{
339 uint32_t engine_addr;392 uint32_t engine_addr;
@@ -402,6 +455,7 @@ static int fsi_slave_scan(struct fsi_slave *slave) · 62 unmodified lines
402 dev_set_name(&dev->dev, "%02x:%02x:%02x:%02x",455 dev_set_name(&dev->dev, "%02x:%02x:%02x:%02x",
403 slave->master->idx, slave->link,456 slave->master->idx, slave->link,
404 slave->id, i - 2);457 slave->id, i - 2);
458 dev->dev.of_node = fsi_device_find_of_node(dev);
405 459
406 rc = device_register(&dev->dev);460 rc = device_register(&dev->dev);
407 if (rc) {461 if (rc) {
@@ -558,9 +612,53 @@ static void fsi_slave_release(struct device *dev) · 150 unmodified lines
558{612{
559 struct fsi_slave *slave = to_fsi_slave(dev);613 struct fsi_slave *slave = to_fsi_slave(dev);
560 614
615 of_node_put(dev->of_node);
561 kfree(slave);616 kfree(slave);
562}617}
563 618
619static bool fsi_slave_node_matches(struct device_node *np,
620 int link, uint8_t id)
621{
622 unsigned int len, na, ns;
623 const __be32 *prop;
624
625 na = of_n_addr_cells(np);
626 ns = of_n_size_cells(np);
627
628 /* Ensure we have the correct format for addresses and sizes in
629 * reg properties
630 */
631 if (na != 2 || ns != 0)
632 return false;
633
634 prop = of_get_property(np, "reg", &len);
635 if (!prop || len != 8)
636 return false;
637
638 return (of_read_number(prop, 1) == link) &&
639 (of_read_number(prop + 1, 1) == id);
640}
641
642/* Find a matching node for the slave at (link, id). Returns NULL if none
643 * found, or a matching node with refcount already incremented.
644 */
645static struct device_node *fsi_slave_find_of_node(struct fsi_master *master,
646 int link, uint8_t id)
647{
648 struct device_node *parent, *np;
649
650 parent = dev_of_node(&master->dev);
651 if (!parent)
652 return NULL;
653
654 for_each_child_of_node(parent, np) {
655 if (fsi_slave_node_matches(np, link, id))
656 return np;
657 }
658
659 return NULL;
660}
661
564static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)662static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
565{663{
566 uint32_t chip_id, llmode;664 uint32_t chip_id, llmode;
@@ -589,7 +687,7 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id) · 22 unmodified lines
589 return -EIO;687 return -EIO;
590 }688 }
591 689
592 dev_info(&master->dev, "fsi: found chip %08x at %02x:%02x:%02x\n",690 dev_dbg(&master->dev, "fsi: found chip %08x at %02x:%02x:%02x\n",
593 chip_id, master->idx, link, id);691 chip_id, master->idx, link, id);
594 692
595 rc = fsi_slave_set_smode(master, link, id);693 rc = fsi_slave_set_smode(master, link, id);
@@ -623,6 +721,7 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id) · 27 unmodified lines
623 721
624 slave->master = master;722 slave->master = master;
625 slave->dev.parent = &master->dev;723 slave->dev.parent = &master->dev;
724 slave->dev.of_node = fsi_slave_find_of_node(master, link, id);
626 slave->dev.release = fsi_slave_release;725 slave->dev.release = fsi_slave_release;
627 slave->link = link;726 slave->link = link;
628 slave->id = id;727 slave->id = id;
@@ -656,10 +755,13 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id) · 27 unmodified lines
656/* FSI master support */755/* FSI master support */
657static int fsi_check_access(uint32_t addr, size_t size)756static int fsi_check_access(uint32_t addr, size_t size)
658{757{
659 if (size != 1 && size != 2 && size != 4)758 if (size == 4) {
660 return -EINVAL;759 if (addr & 0x3)
661 760 return -EINVAL;
662 if ((addr & 0x3) != (size & 0x3))761 } else if (size == 2) {
762 if (addr & 0x1)
763 return -EINVAL;
764 } else if (size != 1)
663 return -EINVAL;765 return -EINVAL;
664 766
665 return 0;767 return 0;
@@ -762,14 +864,20 @@ static void fsi_master_unscan(struct fsi_master *master) · 96 unmodified lines
762 device_for_each_child(&master->dev, NULL, fsi_master_remove_slave);864 device_for_each_child(&master->dev, NULL, fsi_master_remove_slave);
763}865}
764 866
867int fsi_master_rescan(struct fsi_master *master)
868{
869 fsi_master_unscan(master);
870 return fsi_master_scan(master);
871}
872EXPORT_SYMBOL_GPL(fsi_master_rescan);
873
765static ssize_t master_rescan_store(struct device *dev,874static ssize_t master_rescan_store(struct device *dev,
766 struct device_attribute *attr, const char *buf, size_t count)875 struct device_attribute *attr, const char *buf, size_t count)
767{876{
768 struct fsi_master *master = to_fsi_master(dev);877 struct fsi_master *master = to_fsi_master(dev);
769 int rc;878 int rc;
770 879
771 fsi_master_unscan(master);880 rc = fsi_master_rescan(master);
772 rc = fsi_master_scan(master);
773 if (rc < 0)881 if (rc < 0)
774 return rc;882 return rc;
775 883
@@ -793,6 +901,7 @@ static DEVICE_ATTR(break, 0200, NULL, master_break_store); · 17 unmodified lines
793int fsi_master_register(struct fsi_master *master)901int fsi_master_register(struct fsi_master *master)
794{902{
795 int rc;903 int rc;
904 struct device_node *np;
796 905
797 if (!master)906 if (!master)
798 return -EINVAL;907 return -EINVAL;
@@ -820,7 +929,9 @@ int fsi_master_register(struct fsi_master *master) · 21 unmodified lines
820 return rc;929 return rc;
821 }930 }
822 931
823 fsi_master_scan(master);932 np = dev_of_node(&master->dev);
933 if (!of_property_read_bool(np, "no-scan-on-init"))
934 fsi_master_scan(master);
824 935
825 return 0;936 return 0;
826}937}
drivers/fsi/fsi-master-gpio.c+87−2
@@ -9,6 +9,7 @@ · 8 unmodified lines
9#include <linux/gpio/consumer.h>9#include <linux/gpio/consumer.h>
10#include <linux/io.h>10#include <linux/io.h>
11#include <linux/module.h>11#include <linux/module.h>
12#include <linux/of.h>
12#include <linux/platform_device.h>13#include <linux/platform_device.h>
13#include <linux/slab.h>14#include <linux/slab.h>
14#include <linux/spinlock.h>15#include <linux/spinlock.h>
@@ -59,6 +60,7 @@ struct fsi_master_gpio { · 44 unmodified lines
59 struct gpio_desc *gpio_trans; /* Voltage translator */60 struct gpio_desc *gpio_trans; /* Voltage translator */
60 struct gpio_desc *gpio_enable; /* FSI enable */61 struct gpio_desc *gpio_enable; /* FSI enable */
61 struct gpio_desc *gpio_mux; /* Mux control */62 struct gpio_desc *gpio_mux; /* Mux control */
63 bool external_mode;
62};64};
63 65
64#define CREATE_TRACE_POINTS66#define CREATE_TRACE_POINTS
@@ -411,6 +413,12 @@ static int fsi_master_gpio_xfer(struct fsi_master_gpio *master, uint8_t slave, · 346 unmodified lines
411 int rc;413 int rc;
412 414
413 spin_lock_irqsave(&master->cmd_lock, flags);415 spin_lock_irqsave(&master->cmd_lock, flags);
416
417 if (master->external_mode) {
418 spin_unlock_irqrestore(&master->cmd_lock, flags);
419 return -EBUSY;
420 }
421
414 serial_out(master, cmd);422 serial_out(master, cmd);
415 echo_delay(master);423 echo_delay(master);
416 rc = poll_for_response(master, slave, resp_len, resp);424 rc = poll_for_response(master, slave, resp_len, resp);
@@ -461,12 +469,18 @@ static int fsi_master_gpio_term(struct fsi_master *_master, · 44 unmodified lines
461static int fsi_master_gpio_break(struct fsi_master *_master, int link)469static int fsi_master_gpio_break(struct fsi_master *_master, int link)
462{470{
463 struct fsi_master_gpio *master = to_fsi_master_gpio(_master);471 struct fsi_master_gpio *master = to_fsi_master_gpio(_master);
472 unsigned long flags;
464 473
465 if (link != 0)474 if (link != 0)
466 return -ENODEV;475 return -ENODEV;
467 476
468 trace_fsi_master_gpio_break(master);477 trace_fsi_master_gpio_break(master);
469 478
479 spin_lock_irqsave(&master->cmd_lock, flags);
480 if (master->external_mode) {
481 spin_unlock_irqrestore(&master->cmd_lock, flags);
482 return -EBUSY;
483 }
470 set_sda_output(master, 1);484 set_sda_output(master, 1);
471 sda_out(master, 1);485 sda_out(master, 1);
472 clock_toggle(master, FSI_PRE_BREAK_CLOCKS);486 clock_toggle(master, FSI_PRE_BREAK_CLOCKS);
@@ -475,6 +489,7 @@ static int fsi_master_gpio_break(struct fsi_master *_master, int link) · 2 unmodified lines
475 echo_delay(master);489 echo_delay(master);
476 sda_out(master, 1);490 sda_out(master, 1);
477 clock_toggle(master, FSI_POST_BREAK_CLOCKS);491 clock_toggle(master, FSI_POST_BREAK_CLOCKS);
492 spin_unlock_irqrestore(&master->cmd_lock, flags);
478 493
479 /* Wait for logic reset to take effect */494 /* Wait for logic reset to take effect */
480 udelay(200);495 udelay(200);
@@ -494,21 +509,84 @@ static void fsi_master_gpio_init(struct fsi_master_gpio *master) · 13 unmodified lines
494 clock_zeros(master, FSI_INIT_CLOCKS);509 clock_zeros(master, FSI_INIT_CLOCKS);
495}510}
496 511
512static void fsi_master_gpio_init_external(struct fsi_master_gpio *master)
513{
514 gpiod_direction_output(master->gpio_mux, 0);
515 gpiod_direction_output(master->gpio_trans, 0);
516 gpiod_direction_output(master->gpio_enable, 1);
517 gpiod_direction_input(master->gpio_clk);
518 gpiod_direction_input(master->gpio_data);
519}
520
497static int fsi_master_gpio_link_enable(struct fsi_master *_master, int link)521static int fsi_master_gpio_link_enable(struct fsi_master *_master, int link)
498{522{
499 struct fsi_master_gpio *master = to_fsi_master_gpio(_master);523 struct fsi_master_gpio *master = to_fsi_master_gpio(_master);
524 unsigned long flags;
525 int rc = -EBUSY;
500 526
501 if (link != 0)527 if (link != 0)
502 return -ENODEV;528 return -ENODEV;
503 gpiod_set_value(master->gpio_enable, 1);
504 529
505 return 0;530 spin_lock_irqsave(&master->cmd_lock, flags);
531 if (!master->external_mode) {
532 gpiod_set_value(master->gpio_enable, 1);
533 rc = 0;
534 }
535 spin_unlock_irqrestore(&master->cmd_lock, flags);
536
537 return rc;
538}
539
540static ssize_t external_mode_show(struct device *dev,
541 struct device_attribute *attr, char *buf)
542{
543 struct fsi_master_gpio *master = dev_get_drvdata(dev);
544
545 return snprintf(buf, PAGE_SIZE - 1, "%u\n",
546 master->external_mode ? 1 : 0);
506}547}
507 548
549static ssize_t external_mode_store(struct device *dev,
550 struct device_attribute *attr, const char *buf, size_t count)
551{
552 struct fsi_master_gpio *master = dev_get_drvdata(dev);
553 unsigned long flags, val;
554 bool external_mode;
555 int err;
556
557 err = kstrtoul(buf, 0, &val);
558 if (err)
559 return err;
560
561 external_mode = !!val;
562
563 spin_lock_irqsave(&master->cmd_lock, flags);
564
565 if (external_mode == master->external_mode) {
566 spin_unlock_irqrestore(&master->cmd_lock, flags);
567 return count;
568 }
569
570 master->external_mode = external_mode;
571 if (master->external_mode)
572 fsi_master_gpio_init_external(master);
573 else
574 fsi_master_gpio_init(master);
575 spin_unlock_irqrestore(&master->cmd_lock, flags);
576
577 fsi_master_rescan(&master->master);
578
579 return count;
580}
581
582static DEVICE_ATTR(external_mode, 0664,
583 external_mode_show, external_mode_store);
584
508static int fsi_master_gpio_probe(struct platform_device *pdev)585static int fsi_master_gpio_probe(struct platform_device *pdev)
509{586{
510 struct fsi_master_gpio *master;587 struct fsi_master_gpio *master;
511 struct gpio_desc *gpio;588 struct gpio_desc *gpio;
589 int rc;
512 590
513 master = devm_kzalloc(&pdev->dev, sizeof(*master), GFP_KERNEL);591 master = devm_kzalloc(&pdev->dev, sizeof(*master), GFP_KERNEL);
514 if (!master)592 if (!master)
@@ -516,6 +594,7 @@ static int fsi_master_gpio_probe(struct platform_device *pdev) · 1 unmodified line
516 594
517 master->dev = &pdev->dev;595 master->dev = &pdev->dev;
518 master->master.dev.parent = master->dev;596 master->master.dev.parent = master->dev;
597 master->master.dev.of_node = of_node_get(dev_of_node(master->dev));
519 598
520 gpio = devm_gpiod_get(&pdev->dev, "clock", 0);599 gpio = devm_gpiod_get(&pdev->dev, "clock", 0);
521 if (IS_ERR(gpio)) {600 if (IS_ERR(gpio)) {
@@ -565,6 +644,10 @@ static int fsi_master_gpio_probe(struct platform_device *pdev) · 43 unmodified lines
565 644
566 fsi_master_gpio_init(master);645 fsi_master_gpio_init(master);
567 646
647 rc = device_create_file(&pdev->dev, &dev_attr_external_mode);
648 if (rc)
649 return rc;
650
568 return fsi_master_register(&master->master);651 return fsi_master_register(&master->master);
569}652}
570 653
@@ -583,6 +666,8 @@ static int fsi_master_gpio_remove(struct platform_device *pdev) · 12 unmodified lines
583 devm_gpiod_put(&pdev->dev, master->gpio_mux);666 devm_gpiod_put(&pdev->dev, master->gpio_mux);
584 fsi_master_unregister(&master->master);667 fsi_master_unregister(&master->master);
585 668
669 of_node_put(master->master.dev.of_node);
670
586 return 0;671 return 0;
587}672}
588 673
drivers/fsi/fsi-master-hub.c+23−4
@@ -16,6 +16,7 @@ · 15 unmodified lines
16#include <linux/delay.h>16#include <linux/delay.h>
17#include <linux/fsi.h>17#include <linux/fsi.h>
18#include <linux/module.h>18#include <linux/module.h>
19#include <linux/of.h>
19#include <linux/slab.h>20#include <linux/slab.h>
20 21
21#include "fsi-master.h"22#include "fsi-master.h"
@@ -253,7 +254,7 @@ static int hub_master_probe(struct device *dev) · 231 unmodified lines
253 254
254 reg = be32_to_cpu(__reg);255 reg = be32_to_cpu(__reg);
255 links = (reg >> 8) & 0xff;256 links = (reg >> 8) & 0xff;
256 dev_info(dev, "hub version %08x (%d links)\n", reg, links);257 dev_dbg(dev, "hub version %08x (%d links)\n", reg, links);
257 258
258 rc = fsi_slave_claim_range(fsi_dev->slave, FSI_HUB_LINK_OFFSET,259 rc = fsi_slave_claim_range(fsi_dev->slave, FSI_HUB_LINK_OFFSET,
259 FSI_HUB_LINK_SIZE * links);260 FSI_HUB_LINK_SIZE * links);
@@ -274,6 +275,7 @@ static int hub_master_probe(struct device *dev) · 14 unmodified lines
274 275
275 hub->master.dev.parent = dev;276 hub->master.dev.parent = dev;
276 hub->master.dev.release = hub_master_release;277 hub->master.dev.release = hub_master_release;
278 hub->master.dev.of_node = of_node_get(dev_of_node(dev));
277 279
278 hub->master.n_links = links;280 hub->master.n_links = links;
279 hub->master.read = hub_master_read;281 hub->master.read = hub_master_read;
@@ -286,10 +288,19 @@ static int hub_master_probe(struct device *dev) · 6 unmodified lines
286 hub_master_init(hub);288 hub_master_init(hub);
287 289
288 rc = fsi_master_register(&hub->master);290 rc = fsi_master_register(&hub->master);
289 if (!rc)291 if (rc)
290 return 0;292 goto err_release;
293
294 /* At this point, fsi_master_register performs the device_initialize(),
295 * and holds the sole reference on master.dev. This means the device
296 * will be freed (via ->release) during any subsequent call to
297 * fsi_master_unregister. We add our own reference to it here, so we
298 * can perform cleanup (in _remove()) without it being freed before
299 * we're ready.
300 */
301 get_device(&hub->master.dev);
302 return 0;
291 303
292 kfree(hub);
293err_release:304err_release:
294 fsi_slave_release_range(fsi_dev->slave, FSI_HUB_LINK_OFFSET,305 fsi_slave_release_range(fsi_dev->slave, FSI_HUB_LINK_OFFSET,
295 FSI_HUB_LINK_SIZE * links);306 FSI_HUB_LINK_SIZE * links);
@@ -302,6 +313,14 @@ static int hub_master_remove(struct device *dev) · 6 unmodified lines
302 313
303 fsi_master_unregister(&hub->master);314 fsi_master_unregister(&hub->master);
304 fsi_slave_release_range(hub->upstream->slave, hub->addr, hub->size);315 fsi_slave_release_range(hub->upstream->slave, hub->addr, hub->size);
316 of_node_put(hub->master.dev.of_node);
317
318 /*
319 * master.dev will likely be ->release()ed after this, which free()s
320 * the hub
321 */
322 put_device(&hub->master.dev);
323
305 return 0;324 return 0;
306}325}
307 326
drivers/fsi/fsi-master.h+17−0
@@ -37,7 +37,24 @@ struct fsi_master { · 36 unmodified lines
37 37
38#define dev_to_fsi_master(d) container_of(d, struct fsi_master, dev)38#define dev_to_fsi_master(d) container_of(d, struct fsi_master, dev)
39 39
40/**
41 * fsi_master registration & lifetime: the fsi_master_register() and
42 * fsi_master_unregister() functions will take ownership of the master, and
43 * ->dev in particular. The registration path performs a get_device(), which
44 * takes the first reference on the device. Similarly, the unregistration path
45 * performs a put_device(), which may well drop the last reference.
46 *
47 * This means that master implementations *may* need to hold their own
48 * reference (via get_device()) on master->dev. In particular, if the device's
49 * ->release callback frees the fsi_master, then fsi_master_unregister will
50 * invoke this free if no other reference is held.
51 *
52 * The same applies for the error path of fsi_master_register; if the call
53 * fails, dev->release will have been invoked.
54 */
40extern int fsi_master_register(struct fsi_master *master);55extern int fsi_master_register(struct fsi_master *master);
41extern void fsi_master_unregister(struct fsi_master *master);56extern void fsi_master_unregister(struct fsi_master *master);
42 57
58extern int fsi_master_rescan(struct fsi_master *master);
59
43#endif /* DRIVERS_FSI_MASTER_H */60#endif /* DRIVERS_FSI_MASTER_H */
drivers/gpu/drm/bridge/sil-sii8620.c+94−3
@@ -17,6 +17,7 @@ · 16 unmodified lines
17 17
18#include <linux/clk.h>18#include <linux/clk.h>
19#include <linux/delay.h>19#include <linux/delay.h>
20#include <linux/extcon.h>
20#include <linux/gpio/consumer.h>21#include <linux/gpio/consumer.h>
21#include <linux/i2c.h>22#include <linux/i2c.h>
22#include <linux/interrupt.h>23#include <linux/interrupt.h>
@@ -25,6 +26,7 @@ · 2 unmodified lines
25#include <linux/list.h>26#include <linux/list.h>
26#include <linux/module.h>27#include <linux/module.h>
27#include <linux/mutex.h>28#include <linux/mutex.h>
29#include <linux/of_graph.h>
28#include <linux/regulator/consumer.h>30#include <linux/regulator/consumer.h>
29#include <linux/slab.h>31#include <linux/slab.h>
30 32
@@ -81,6 +83,10 @@ struct sii8620 { · 50 unmodified lines
81 struct edid *edid;83 struct edid *edid;
82 unsigned int gen2_write_burst:1;84 unsigned int gen2_write_burst:1;
83 enum sii8620_mt_state mt_state;85 enum sii8620_mt_state mt_state;
86 struct extcon_dev *extcon;
87 struct notifier_block extcon_nb;
88 struct work_struct extcon_wq;
89 int cable_state;
84 struct list_head mt_queue;90 struct list_head mt_queue;
85 struct {91 struct {
86 int r_size;92 int r_size;
@@ -2170,6 +2176,77 @@ static void sii8620_init_rcp_input_dev(struct sii8620 *ctx) · 2083 unmodified lines
2170 ctx->rc_dev = rc_dev;2176 ctx->rc_dev = rc_dev;
2171}2177}
2172 2178
2179static void sii8620_cable_out(struct sii8620 *ctx)
2180{
2181 disable_irq(to_i2c_client(ctx->dev)->irq);
2182 sii8620_hw_off(ctx);
2183}
2184
2185static void sii8620_extcon_work(struct work_struct *work)
2186{
2187 struct sii8620 *ctx =
2188 container_of(work, struct sii8620, extcon_wq);
2189 int state = extcon_get_state(ctx->extcon, EXTCON_DISP_MHL);
2190
2191 if (state == ctx->cable_state)
2192 return;
2193
2194 ctx->cable_state = state;
2195
2196 if (state > 0)
2197 sii8620_cable_in(ctx);
2198 else
2199 sii8620_cable_out(ctx);
2200}
2201
2202static int sii8620_extcon_notifier(struct notifier_block *self,
2203 unsigned long event, void *ptr)
2204{
2205 struct sii8620 *ctx =
2206 container_of(self, struct sii8620, extcon_nb);
2207
2208 schedule_work(&ctx->extcon_wq);
2209
2210 return NOTIFY_DONE;
2211}
2212
2213static int sii8620_extcon_init(struct sii8620 *ctx)
2214{
2215 struct extcon_dev *edev;
2216 struct device_node *musb, *muic;
2217 int ret;
2218
2219 /* get micro-USB connector node */
2220 musb = of_graph_get_remote_node(ctx->dev->of_node, 1, -1);
2221 /* next get micro-USB Interface Controller node */
2222 muic = of_get_next_parent(musb);
2223
2224 if (!muic) {
2225 dev_info(ctx->dev, "no extcon found, switching to 'always on' mode\n");
2226 return 0;
2227 }
2228
2229 edev = extcon_find_edev_by_node(muic);
2230 of_node_put(muic);
2231 if (IS_ERR(edev)) {
2232 if (PTR_ERR(edev) == -EPROBE_DEFER)
2233 return -EPROBE_DEFER;
2234 dev_err(ctx->dev, "Invalid or missing extcon\n");
2235 return PTR_ERR(edev);
2236 }
2237
2238 ctx->extcon = edev;
2239 ctx->extcon_nb.notifier_call = sii8620_extcon_notifier;
2240 INIT_WORK(&ctx->extcon_wq, sii8620_extcon_work);
2241 ret = extcon_register_notifier(edev, EXTCON_DISP_MHL, &ctx->extcon_nb);
2242 if (ret) {
2243 dev_err(ctx->dev, "failed to register notifier for MHL\n");
2244 return ret;
2245 }
2246
2247 return 0;
2248}
2249
2173static inline struct sii8620 *bridge_to_sii8620(struct drm_bridge *bridge)2250static inline struct sii8620 *bridge_to_sii8620(struct drm_bridge *bridge)
2174{2251{
2175 return container_of(bridge, struct sii8620, bridge);2252 return container_of(bridge, struct sii8620, bridge);
@@ -2302,13 +2379,20 @@ static int sii8620_probe(struct i2c_client *client, · 126 unmodified lines
2302 if (ret)2379 if (ret)
2303 return ret;2380 return ret;
2304 2381
2382 ret = sii8620_extcon_init(ctx);
2383 if (ret < 0) {
2384 dev_err(ctx->dev, "failed to initialize EXTCON\n");
2385 return ret;
2386 }
2387
2305 i2c_set_clientdata(client, ctx);2388 i2c_set_clientdata(client, ctx);
2306 2389
2307 ctx->bridge.funcs = &sii8620_bridge_funcs;2390 ctx->bridge.funcs = &sii8620_bridge_funcs;
2308 ctx->bridge.of_node = dev->of_node;2391 ctx->bridge.of_node = dev->of_node;
2309 drm_bridge_add(&ctx->bridge);2392 drm_bridge_add(&ctx->bridge);
2310 2393
2311 sii8620_cable_in(ctx);2394 if (!ctx->extcon)
2395 sii8620_cable_in(ctx);
2312 2396
2313 return 0;2397 return 0;
2314}2398}
@@ -2317,8 +2401,15 @@ static int sii8620_remove(struct i2c_client *client) · 2 unmodified lines
2317{2401{
2318 struct sii8620 *ctx = i2c_get_clientdata(client);2402 struct sii8620 *ctx = i2c_get_clientdata(client);
2319 2403
2320 disable_irq(to_i2c_client(ctx->dev)->irq);2404 if (ctx->extcon) {
2321 sii8620_hw_off(ctx);2405 extcon_unregister_notifier(ctx->extcon, EXTCON_DISP_MHL,
2406 &ctx->extcon_nb);
2407 flush_work(&ctx->extcon_wq);
2408 if (ctx->cable_state > 0)
2409 sii8620_cable_out(ctx);
2410 } else {
2411 sii8620_cable_out(ctx);
2412 }
2322 drm_bridge_remove(&ctx->bridge);2413 drm_bridge_remove(&ctx->bridge);
2323 2414
2324 return 0;2415 return 0;
drivers/hv/Kconfig+2−0
@@ -1,3 +1,5 @@
1# SPDX-License-Identifier: GPL-2.0
2
1menu "Microsoft Hyper-V guest support"3menu "Microsoft Hyper-V guest support"
2 4
3config HYPERV5config HYPERV
drivers/hv/Makefile+1−0
@@ -4,6 +4,7 @@ obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o · 3 unmodified lines
4obj-$(CONFIG_HYPERV_BALLOON) += hv_balloon.o4obj-$(CONFIG_HYPERV_BALLOON) += hv_balloon.o
5 5
6CFLAGS_hv_trace.o = -I$(src)6CFLAGS_hv_trace.o = -I$(src)
7CFLAGS_hv_balloon.o = -I$(src)
7 8
8hv_vmbus-y := vmbus_drv.o \9hv_vmbus-y := vmbus_drv.o \
9 hv.o connection.o channel.o \10 hv.o connection.o channel.o \
drivers/hv/channel_mgmt.c+3−5
@@ -71,7 +71,7 @@ static const struct vmbus_device vmbus_devs[] = { · 70 unmodified lines
71 /* PCIE */71 /* PCIE */
72 { .dev_type = HV_PCIE,72 { .dev_type = HV_PCIE,
73 HV_PCIE_GUID,73 HV_PCIE_GUID,
74 .perf_device = true,74 .perf_device = false,
75 },75 },
76 76
77 /* Synthetic Frame Buffer */77 /* Synthetic Frame Buffer */
@@ -596,10 +596,8 @@ static int next_numa_node_id; · 518 unmodified lines
596/*596/*
597 * Starting with Win8, we can statically distribute the incoming597 * Starting with Win8, we can statically distribute the incoming
598 * channel interrupt load by binding a channel to VCPU.598 * channel interrupt load by binding a channel to VCPU.
599 * We do this in a hierarchical fashion:599 * We distribute the interrupt loads to one or more NUMA nodes based on
600 * First distribute the primary channels across available NUMA nodes600 * the channel's affinity_policy.
601 * and then distribute the subchannels amongst the CPUs in the NUMA
602 * node assigned to the primary channel.
603 *601 *
604 * For pre-win8 hosts or non-performance critical channels we assign the602 * For pre-win8 hosts or non-performance critical channels we assign the
605 * first CPU in the first NUMA node.603 * first CPU in the first NUMA node.
drivers/hv/hv.c+58−6
@@ -27,7 +27,7 @@ · 26 unmodified lines
27#include <linux/vmalloc.h>27#include <linux/vmalloc.h>
28#include <linux/hyperv.h>28#include <linux/hyperv.h>
29#include <linux/version.h>29#include <linux/version.h>
30#include <linux/interrupt.h>30#include <linux/random.h>
31#include <linux/clockchips.h>31#include <linux/clockchips.h>
32#include <asm/hyperv.h>32#include <asm/hyperv.h>
33#include <asm/mshyperv.h>33#include <asm/mshyperv.h>
@@ -38,6 +38,17 @@ struct hv_context hv_context = { · 4 unmodified lines
38 .synic_initialized = false,38 .synic_initialized = false,
39};39};
40 40
41/*
42 * If false, we're using the old mechanism for stimer0 interrupts
43 * where it sends a VMbus message when it expires. The old
44 * mechanism is used when running on older versions of Hyper-V
45 * that don't support Direct Mode. While Hyper-V provides
46 * four stimer's per CPU, Linux uses only stimer0.
47 */
48static bool direct_mode_enabled;
49static int stimer0_irq;
50static int stimer0_vector;
51
41#define HV_TIMER_FREQUENCY (10 * 1000 * 1000) /* 100ns period */52#define HV_TIMER_FREQUENCY (10 * 1000 * 1000) /* 100ns period */
42#define HV_MAX_MAX_DELTA_TICKS 0xffffffff53#define HV_MAX_MAX_DELTA_TICKS 0xffffffff
43#define HV_MIN_DELTA_TICKS 154#define HV_MIN_DELTA_TICKS 1
@@ -53,6 +64,8 @@ int hv_init(void) · 9 unmodified lines
53 if (!hv_context.cpu_context)64 if (!hv_context.cpu_context)
54 return -ENOMEM;65 return -ENOMEM;
55 66
67 direct_mode_enabled = ms_hyperv.misc_features &
68 HV_X64_STIMER_DIRECT_MODE_AVAILABLE;
56 return 0;69 return 0;
57}70}
58 71
@@ -91,6 +104,21 @@ int hv_post_message(union hv_connection_id connection_id, · 32 unmodified lines
91 return status & 0xFFFF;104 return status & 0xFFFF;
92}105}
93 106
107/*
108 * ISR for when stimer0 is operating in Direct Mode. Direct Mode
109 * does not use VMbus or any VMbus messages, so process here and not
110 * in the VMbus driver code.
111 */
112
113static void hv_stimer0_isr(void)
114{
115 struct hv_per_cpu_context *hv_cpu;
116
117 hv_cpu = this_cpu_ptr(hv_context.cpu_context);
118 hv_cpu->clk_evt->event_handler(hv_cpu->clk_evt);
119 add_interrupt_randomness(stimer0_vector, 0);
120}
121
94static int hv_ce_set_next_event(unsigned long delta,122static int hv_ce_set_next_event(unsigned long delta,
95 struct clock_event_device *evt)123 struct clock_event_device *evt)
96{124{
@@ -108,6 +136,8 @@ static int hv_ce_shutdown(struct clock_event_device *evt) · 11 unmodified lines
108{136{
109 hv_init_timer(HV_X64_MSR_STIMER0_COUNT, 0);137 hv_init_timer(HV_X64_MSR_STIMER0_COUNT, 0);
110 hv_init_timer_config(HV_X64_MSR_STIMER0_CONFIG, 0);138 hv_init_timer_config(HV_X64_MSR_STIMER0_CONFIG, 0);
139 if (direct_mode_enabled)
140 hv_disable_stimer0_percpu_irq(stimer0_irq);
111 141
112 return 0;142 return 0;
113}143}
@@ -116,11 +146,26 @@ static int hv_ce_set_oneshot(struct clock_event_device *evt) · 2 unmodified lines
116{146{
117 union hv_timer_config timer_cfg;147 union hv_timer_config timer_cfg;
118 148
149 timer_cfg.as_uint64 = 0;
119 timer_cfg.enable = 1;150 timer_cfg.enable = 1;
120 timer_cfg.auto_enable = 1;151 timer_cfg.auto_enable = 1;
121 timer_cfg.sintx = VMBUS_MESSAGE_SINT;152 if (direct_mode_enabled) {
153 /*
154 * When it expires, the timer will directly interrupt
155 * on the specified hardware vector/IRQ.
156 */
157 timer_cfg.direct_mode = 1;
158 timer_cfg.apic_vector = stimer0_vector;
159 hv_enable_stimer0_percpu_irq(stimer0_irq);
160 } else {
161 /*
162 * When it expires, the timer will generate a VMbus message,
163 * to be handled by the normal VMbus interrupt handler.
164 */
165 timer_cfg.direct_mode = 0;
166 timer_cfg.sintx = VMBUS_MESSAGE_SINT;
167 }
122 hv_init_timer_config(HV_X64_MSR_STIMER0_CONFIG, timer_cfg.as_uint64);168 hv_init_timer_config(HV_X64_MSR_STIMER0_CONFIG, timer_cfg.as_uint64);
123
124 return 0;169 return 0;
125}170}
126 171
@@ -147,7 +192,7 @@ int hv_synic_alloc(void) · 20 unmodified lines
147 int cpu;192 int cpu;
148 193
149 hv_context.hv_numa_map = kzalloc(sizeof(struct cpumask) * nr_node_ids,194 hv_context.hv_numa_map = kzalloc(sizeof(struct cpumask) * nr_node_ids,
150 GFP_ATOMIC);195 GFP_KERNEL);
151 if (hv_context.hv_numa_map == NULL) {196 if (hv_context.hv_numa_map == NULL) {
152 pr_err("Unable to allocate NUMA map\n");197 pr_err("Unable to allocate NUMA map\n");
153 goto err;198 goto err;
@@ -191,6 +236,11 @@ int hv_synic_alloc(void) · 37 unmodified lines
191 INIT_LIST_HEAD(&hv_cpu->chan_list);236 INIT_LIST_HEAD(&hv_cpu->chan_list);
192 }237 }
193 238
239 if (direct_mode_enabled &&
240 hv_setup_stimer0_irq(&stimer0_irq, &stimer0_vector,
241 hv_stimer0_isr))
242 goto err;
243
194 return 0;244 return 0;
195err:245err:
196 return -ENOMEM;246 return -ENOMEM;
@@ -217,7 +267,7 @@ void hv_synic_free(void) · 20 unmodified lines
217}267}
218 268
219/*269/*
220 * hv_synic_init - Initialize the Synthethic Interrupt Controller.270 * hv_synic_init - Initialize the Synthetic Interrupt Controller.
221 *271 *
222 * If it is already initialized by another entity (ie x2v shim), we need to272 * If it is already initialized by another entity (ie x2v shim), we need to
223 * retrieve the initialized message and event pages. Otherwise, we create and273 * retrieve the initialized message and event pages. Otherwise, we create and
@@ -252,7 +302,6 @@ int hv_synic_init(unsigned int cpu) · 28 unmodified lines
252 hv_get_synint_state(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT,302 hv_get_synint_state(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT,
253 shared_sint.as_uint64);303 shared_sint.as_uint64);
254 304
255 shared_sint.as_uint64 = 0;
256 shared_sint.vector = HYPERVISOR_CALLBACK_VECTOR;305 shared_sint.vector = HYPERVISOR_CALLBACK_VECTOR;
257 shared_sint.masked = false;306 shared_sint.masked = false;
258 if (ms_hyperv.hints & HV_X64_DEPRECATING_AEOI_RECOMMENDED)307 if (ms_hyperv.hints & HV_X64_DEPRECATING_AEOI_RECOMMENDED)
@@ -292,6 +341,9 @@ void hv_synic_clockevents_cleanup(void) · 33 unmodified lines
292 if (!(ms_hyperv.features & HV_X64_MSR_SYNTIMER_AVAILABLE))341 if (!(ms_hyperv.features & HV_X64_MSR_SYNTIMER_AVAILABLE))
293 return;342 return;
294 343
344 if (direct_mode_enabled)
345 hv_remove_stimer0_irq(stimer0_irq);
346
295 for_each_present_cpu(cpu) {347 for_each_present_cpu(cpu) {
296 struct hv_per_cpu_context *hv_cpu348 struct hv_per_cpu_context *hv_cpu
297 = per_cpu_ptr(hv_context.cpu_context, cpu);349 = per_cpu_ptr(hv_context.cpu_context, cpu);
drivers/hv/hv_balloon.c+83−38
@@ -34,6 +34,9 @@ · 33 unmodified lines
34 34
35#include <linux/hyperv.h>35#include <linux/hyperv.h>
36 36
37#define CREATE_TRACE_POINTS
38#include "hv_trace_balloon.h"
39
37/*40/*
38 * We begin with definitions supporting the Dynamic Memory protocol41 * We begin with definitions supporting the Dynamic Memory protocol
39 * with the host.42 * with the host.
@@ -576,11 +579,65 @@ static struct hv_dynmem_device dm_device; · 536 unmodified lines
576static void post_status(struct hv_dynmem_device *dm);579static void post_status(struct hv_dynmem_device *dm);
577 580
578#ifdef CONFIG_MEMORY_HOTPLUG581#ifdef CONFIG_MEMORY_HOTPLUG
582static inline bool has_pfn_is_backed(struct hv_hotadd_state *has,
583 unsigned long pfn)
584{
585 struct hv_hotadd_gap *gap;
586
587 /* The page is not backed. */
588 if ((pfn < has->covered_start_pfn) || (pfn >= has->covered_end_pfn))
589 return false;
590
591 /* Check for gaps. */
592 list_for_each_entry(gap, &has->gap_list, list) {
593 if ((pfn >= gap->start_pfn) && (pfn < gap->end_pfn))
594 return false;
595 }
596
597 return true;
598}
599
600static unsigned long hv_page_offline_check(unsigned long start_pfn,
601 unsigned long nr_pages)
602{
603 unsigned long pfn = start_pfn, count = 0;
604 struct hv_hotadd_state *has;
605 bool found;
606
607 while (pfn < start_pfn + nr_pages) {
608 /*
609 * Search for HAS which covers the pfn and when we find one
610 * count how many consequitive PFNs are covered.
611 */
612 found = false;
613 list_for_each_entry(has, &dm_device.ha_region_list, list) {
614 while ((pfn >= has->start_pfn) &&
615 (pfn < has->end_pfn) &&
616 (pfn < start_pfn + nr_pages)) {
617 found = true;
618 if (has_pfn_is_backed(has, pfn))
619 count++;
620 pfn++;
621 }
622 }
623
624 /*
625 * This PFN is not in any HAS (e.g. we're offlining a region
626 * which was present at boot), no need to account for it. Go
627 * to the next one.
628 */
629 if (!found)
630 pfn++;
631 }
632
633 return count;
634}
635
579static int hv_memory_notifier(struct notifier_block *nb, unsigned long val,636static int hv_memory_notifier(struct notifier_block *nb, unsigned long val,
580 void *v)637 void *v)
581{638{
582 struct memory_notify *mem = (struct memory_notify *)v;639 struct memory_notify *mem = (struct memory_notify *)v;
583 unsigned long flags;640 unsigned long flags, pfn_count;
584 641
585 switch (val) {642 switch (val) {
586 case MEM_ONLINE:643 case MEM_ONLINE:
@@ -593,7 +650,19 @@ static int hv_memory_notifier(struct notifier_block *nb, unsigned long val, · 6 unmodified lines
593 650
594 case MEM_OFFLINE:651 case MEM_OFFLINE:
595 spin_lock_irqsave(&dm_device.ha_lock, flags);652 spin_lock_irqsave(&dm_device.ha_lock, flags);
596 dm_device.num_pages_onlined -= mem->nr_pages;653 pfn_count = hv_page_offline_check(mem->start_pfn,
654 mem->nr_pages);
655 if (pfn_count <= dm_device.num_pages_onlined) {
656 dm_device.num_pages_onlined -= pfn_count;
657 } else {
658 /*
659 * We're offlining more pages than we managed to online.
660 * This is unexpected. In any case don't let
661 * num_pages_onlined wrap around zero.
662 */
663 WARN_ON_ONCE(1);
664 dm_device.num_pages_onlined = 0;
665 }
597 spin_unlock_irqrestore(&dm_device.ha_lock, flags);666 spin_unlock_irqrestore(&dm_device.ha_lock, flags);
598 break;667 break;
599 case MEM_GOING_ONLINE:668 case MEM_GOING_ONLINE:
@@ -612,30 +681,9 @@ static struct notifier_block hv_memory_nb = { · 12 unmodified lines
612/* Check if the particular page is backed and can be onlined and online it. */681/* Check if the particular page is backed and can be onlined and online it. */
613static void hv_page_online_one(struct hv_hotadd_state *has, struct page *pg)682static void hv_page_online_one(struct hv_hotadd_state *has, struct page *pg)
614{683{
615 unsigned long cur_start_pgp;684 if (!has_pfn_is_backed(has, page_to_pfn(pg)))
616 unsigned long cur_end_pgp;
617 struct hv_hotadd_gap *gap;
618
619 cur_start_pgp = (unsigned long)pfn_to_page(has->covered_start_pfn);
620 cur_end_pgp = (unsigned long)pfn_to_page(has->covered_end_pfn);
621
622 /* The page is not backed. */
623 if (((unsigned long)pg < cur_start_pgp) ||
624 ((unsigned long)pg >= cur_end_pgp))
625 return;685 return;
626 686
627 /* Check for gaps. */
628 list_for_each_entry(gap, &has->gap_list, list) {
629 cur_start_pgp = (unsigned long)
630 pfn_to_page(gap->start_pfn);
631 cur_end_pgp = (unsigned long)
632 pfn_to_page(gap->end_pfn);
633 if (((unsigned long)pg >= cur_start_pgp) &&
634 ((unsigned long)pg < cur_end_pgp)) {
635 return;
636 }
637 }
638
639 /* This frame is currently backed; online the page. */687 /* This frame is currently backed; online the page. */
640 __online_page_set_limits(pg);688 __online_page_set_limits(pg);
641 __online_page_increment_counters(pg);689 __online_page_increment_counters(pg);
@@ -691,7 +739,7 @@ static void hv_mem_hot_add(unsigned long start, unsigned long size, · 49 unmodified lines
691 (HA_CHUNK << PAGE_SHIFT));739 (HA_CHUNK << PAGE_SHIFT));
692 740
693 if (ret) {741 if (ret) {
694 pr_warn("hot_add memory failed error is %d\n", ret);742 pr_err("hot_add memory failed error is %d\n", ret);
695 if (ret == -EEXIST) {743 if (ret == -EEXIST) {
696 /*744 /*
697 * This error indicates that the error745 * This error indicates that the error
@@ -726,19 +774,13 @@ static void hv_mem_hot_add(unsigned long start, unsigned long size, · 28 unmodified lines
726static void hv_online_page(struct page *pg)774static void hv_online_page(struct page *pg)
727{775{
728 struct hv_hotadd_state *has;776 struct hv_hotadd_state *has;
729 unsigned long cur_start_pgp;
730 unsigned long cur_end_pgp;
731 unsigned long flags;777 unsigned long flags;
778 unsigned long pfn = page_to_pfn(pg);
732 779
733 spin_lock_irqsave(&dm_device.ha_lock, flags);780 spin_lock_irqsave(&dm_device.ha_lock, flags);
734 list_for_each_entry(has, &dm_device.ha_region_list, list) {781 list_for_each_entry(has, &dm_device.ha_region_list, list) {
735 cur_start_pgp = (unsigned long)
736 pfn_to_page(has->start_pfn);
737 cur_end_pgp = (unsigned long)pfn_to_page(has->end_pfn);
738
739 /* The page belongs to a different HAS. */782 /* The page belongs to a different HAS. */
740 if (((unsigned long)pg < cur_start_pgp) ||783 if ((pfn < has->start_pfn) || (pfn >= has->end_pfn))
741 ((unsigned long)pg >= cur_end_pgp))
742 continue;784 continue;
743 785
744 hv_page_online_one(has, pg);786 hv_page_online_one(has, pg);
@@ -1014,7 +1056,7 @@ static void hot_add_req(struct work_struct *dummy) · 269 unmodified lines
1014 resp.result = 0;1056 resp.result = 0;
1015 1057
1016 if (!do_hot_add || (resp.page_count == 0))1058 if (!do_hot_add || (resp.page_count == 0))
1017 pr_info("Memory hot add failed\n");1059 pr_err("Memory hot add failed\n");
1018 1060
1019 dm->state = DM_INITIALIZED;1061 dm->state = DM_INITIALIZED;
1020 resp.hdr.trans_id = atomic_inc_return(&trans_id);1062 resp.hdr.trans_id = atomic_inc_return(&trans_id);
@@ -1041,7 +1083,7 @@ static void process_info(struct hv_dynmem_device *dm, struct dm_info_msg *msg) · 20 unmodified lines
1041 1083
1042 break;1084 break;
1043 default:1085 default:
1044 pr_info("Received Unknown type: %d\n", info_hdr->type);1086 pr_warn("Received Unknown type: %d\n", info_hdr->type);
1045 }1087 }
1046}1088}
1047 1089
@@ -1120,6 +1162,9 @@ static void post_status(struct hv_dynmem_device *dm) · 72 unmodified lines
1120 dm->num_pages_added - dm->num_pages_onlined : 0) +1162 dm->num_pages_added - dm->num_pages_onlined : 0) +
1121 compute_balloon_floor();1163 compute_balloon_floor();
1122 1164
1165 trace_balloon_status(status.num_avail, status.num_committed,
1166 vm_memory_committed(), dm->num_pages_ballooned,
1167 dm->num_pages_added, dm->num_pages_onlined);
1123 /*1168 /*
1124 * If our transaction ID is no longer current, just don't1169 * If our transaction ID is no longer current, just don't
1125 * send the status. This can happen if we were interrupted1170 * send the status. This can happen if we were interrupted
@@ -1290,7 +1335,7 @@ static void balloon_up(struct work_struct *dummy) · 164 unmodified lines
1290 /*1335 /*
1291 * Free up the memory we allocatted.1336 * Free up the memory we allocatted.
1292 */1337 */
1293 pr_info("Balloon response failed\n");1338 pr_err("Balloon response failed\n");
1294 1339
1295 for (i = 0; i < bl_resp->range_count; i++)1340 for (i = 0; i < bl_resp->range_count; i++)
1296 free_balloon_pages(&dm_device,1341 free_balloon_pages(&dm_device,
@@ -1421,7 +1466,7 @@ static void cap_resp(struct hv_dynmem_device *dm, · 124 unmodified lines
1421 struct dm_capabilities_resp_msg *cap_resp)1466 struct dm_capabilities_resp_msg *cap_resp)
1422{1467{
1423 if (!cap_resp->is_accepted) {1468 if (!cap_resp->is_accepted) {
1424 pr_info("Capabilities not accepted by host\n");1469 pr_err("Capabilities not accepted by host\n");
1425 dm->state = DM_INIT_ERROR;1470 dm->state = DM_INIT_ERROR;
1426 }1471 }
1427 complete(&dm->host_event);1472 complete(&dm->host_event);
@@ -1508,7 +1553,7 @@ static void balloon_onchannelcallback(void *context) · 80 unmodified lines
1508 break;1553 break;
1509 1554
1510 default:1555 default:
1511 pr_err("Unhandled message: type: %d\n", dm_hdr->type);1556 pr_warn("Unhandled message: type: %d\n", dm_hdr->type);
1512 1557
1513 }1558 }
1514 }1559 }
drivers/hv/hv_trace.c+2−0
@@ -1,3 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0
2
1#include "hyperv_vmbus.h"3#include "hyperv_vmbus.h"
2 4
3#define CREATE_TRACE_POINTS5#define CREATE_TRACE_POINTS
drivers/hv/hv_trace.h+2−0
@@ -1,3 +1,5 @@
1// SPDX-License-Identifier: GPL-2.0
2
1#undef TRACE_SYSTEM3#undef TRACE_SYSTEM
2#define TRACE_SYSTEM hyperv4#define TRACE_SYSTEM hyperv
3 5
drivers/hv/hv_trace_balloon.h+48−0
@@ -0,0 +1,48 @@
1#undef TRACE_SYSTEM
2#define TRACE_SYSTEM hyperv
3
4#if !defined(_HV_TRACE_BALLOON_H) || defined(TRACE_HEADER_MULTI_READ)
5#define _HV_TRACE_BALLOON_H
6
7#include <linux/tracepoint.h>
8
9TRACE_EVENT(balloon_status,
10 TP_PROTO(u64 available, u64 committed,
11 unsigned long vm_memory_committed,
12 unsigned long pages_ballooned,
13 unsigned long pages_added,
14 unsigned long pages_onlined),
15 TP_ARGS(available, committed, vm_memory_committed,
16 pages_ballooned, pages_added, pages_onlined),
17 TP_STRUCT__entry(
18 __field(u64, available)
19 __field(u64, committed)
20 __field(unsigned long, vm_memory_committed)
21 __field(unsigned long, pages_ballooned)
22 __field(unsigned long, pages_added)
23 __field(unsigned long, pages_onlined)
24 ),
25 TP_fast_assign(
26 __entry->available = available;
27 __entry->committed = committed;
28 __entry->vm_memory_committed = vm_memory_committed;
29 __entry->pages_ballooned = pages_ballooned;
30 __entry->pages_added = pages_added;
31 __entry->pages_onlined = pages_onlined;
32 ),
33 TP_printk("available %lld, committed %lld; vm_memory_committed %ld;"
34 " pages_ballooned %ld, pages_added %ld, pages_onlined %ld",
35 __entry->available, __entry->committed,
36 __entry->vm_memory_committed, __entry->pages_ballooned,
37 __entry->pages_added, __entry->pages_onlined
38 )
39 );
40
41#undef TRACE_INCLUDE_PATH
42#define TRACE_INCLUDE_PATH .
43#undef TRACE_INCLUDE_FILE
44#define TRACE_INCLUDE_FILE hv_trace_balloon
45#endif /* _HV_TRACE_BALLOON_H */
46
47/* This part must be outside protection */
48#include <trace/define_trace.h>
drivers/hv/hyperv_vmbus.h+3−1
@@ -57,7 +57,9 @@ union hv_timer_config { · 56 unmodified lines
57 u64 periodic:1;57 u64 periodic:1;
58 u64 lazy:1;58 u64 lazy:1;
59 u64 auto_enable:1;59 u64 auto_enable:1;
60 u64 reserved_z0:12;60 u64 apic_vector:8;
61 u64 direct_mode:1;
62 u64 reserved_z0:3;
61 u64 sintx:4;63 u64 sintx:4;
62 u64 reserved_z1:44;64 u64 reserved_z1:44;
63 };65 };
drivers/hwtracing/Kconfig+7−0
@@ -0,0 +1,7 @@
1menu "HW tracing support"
2
3source "drivers/hwtracing/stm/Kconfig"
4
5source "drivers/hwtracing/intel_th/Kconfig"
6
7endmenu
drivers/hwtracing/coresight/coresight-cpu-debug.c+1−1
@@ -315,7 +315,7 @@ static void debug_dump_regs(struct debug_drvdata *drvdata) · 314 unmodified lines
315 }315 }
316 316
317 pc = debug_adjust_pc(drvdata);317 pc = debug_adjust_pc(drvdata);
318 dev_emerg(dev, " EDPCSR: [<%p>] %pS\n", (void *)pc, (void *)pc);318 dev_emerg(dev, " EDPCSR: [<%px>] %pS\n", (void *)pc, (void *)pc);
319 319
320 if (drvdata->edcidsr_present)320 if (drvdata->edcidsr_present)
321 dev_emerg(dev, " EDCIDSR: %08x\n", drvdata->edcidsr);321 dev_emerg(dev, " EDCIDSR: %08x\n", drvdata->edcidsr);
drivers/hwtracing/coresight/coresight-etm4x-sysfs.c+2−2
@@ -1780,7 +1780,7 @@ static ssize_t ctxid_masks_store(struct device *dev, · 1779 unmodified lines
1780 */1780 */
1781 for (j = 0; j < 8; j++) {1781 for (j = 0; j < 8; j++) {
1782 if (maskbyte & 1)1782 if (maskbyte & 1)
1783 config->ctxid_pid[i] &= ~(0xFF << (j * 8));1783 config->ctxid_pid[i] &= ~(0xFFUL << (j * 8));
1784 maskbyte >>= 1;1784 maskbyte >>= 1;
1785 }1785 }
1786 /* Select the next ctxid comparator mask value */1786 /* Select the next ctxid comparator mask value */
@@ -1963,7 +1963,7 @@ static ssize_t vmid_masks_store(struct device *dev, · 176 unmodified lines
1963 */1963 */
1964 for (j = 0; j < 8; j++) {1964 for (j = 0; j < 8; j++) {
1965 if (maskbyte & 1)1965 if (maskbyte & 1)
1966 config->vmid_val[i] &= ~(0xFF << (j * 8));1966 config->vmid_val[i] &= ~(0xFFUL << (j * 8));
1967 maskbyte >>= 1;1967 maskbyte >>= 1;
1968 }1968 }
1969 /* Select the next vmid comparator mask value */1969 /* Select the next vmid comparator mask value */
drivers/hwtracing/intel_th/Kconfig+12−0
@@ -25,6 +25,18 @@ config INTEL_TH_PCI · 24 unmodified lines
25 25
26 Say Y here to enable PCI Intel TH support.26 Say Y here to enable PCI Intel TH support.
27 27
28config INTEL_TH_ACPI
29 tristate "Intel(R) Trace Hub ACPI controller"
30 depends on ACPI
31 help
32 Intel(R) Trace Hub may exist as an ACPI device. This option enables
33 support glue layer for ACPI-based Intel TH. This typically implies
34 'host debugger' mode, that is, the trace configuration and capture
35 is handled by an external debug host and corresponding controls will
36 not be available on the target.
37
38 Say Y here to enable ACPI Intel TH support.
39
28config INTEL_TH_GTH40config INTEL_TH_GTH
29 tristate "Intel(R) Trace Hub Global Trace Hub"41 tristate "Intel(R) Trace Hub Global Trace Hub"
30 help42 help
drivers/hwtracing/intel_th/Makefile+3−0
@@ -6,6 +6,9 @@ intel_th-$(CONFIG_INTEL_TH_DEBUG) += debug.o · 5 unmodified lines
6obj-$(CONFIG_INTEL_TH_PCI) += intel_th_pci.o6obj-$(CONFIG_INTEL_TH_PCI) += intel_th_pci.o
7intel_th_pci-y := pci.o7intel_th_pci-y := pci.o
8 8
9obj-$(CONFIG_INTEL_TH_ACPI) += intel_th_acpi.o
10intel_th_acpi-y := acpi.o
11
9obj-$(CONFIG_INTEL_TH_GTH) += intel_th_gth.o12obj-$(CONFIG_INTEL_TH_GTH) += intel_th_gth.o
10intel_th_gth-y := gth.o13intel_th_gth-y := gth.o
11 14
drivers/hwtracing/intel_th/acpi.c+79−0
@@ -0,0 +1,79 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Intel(R) Trace Hub ACPI driver
4 *
5 * Copyright (C) 2017 Intel Corporation.
6 */
7
8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9
10#include <linux/types.h>
11#include <linux/module.h>
12#include <linux/device.h>
13#include <linux/sysfs.h>
14#include <linux/platform_device.h>
15#include <linux/acpi.h>
16
17#include "intel_th.h"
18
19#define DRIVER_NAME "intel_th_acpi"
20
21static const struct intel_th_drvdata intel_th_acpi_pch = {
22 .host_mode_only = 1,
23};
24
25static const struct intel_th_drvdata intel_th_acpi_uncore = {
26 .host_mode_only = 1,
27};
28
29static const struct acpi_device_id intel_th_acpi_ids[] = {
30 { "INTC1000", (kernel_ulong_t)&intel_th_acpi_uncore },
31 { "INTC1001", (kernel_ulong_t)&intel_th_acpi_pch },
32 { "", 0 },
33};
34
35MODULE_DEVICE_TABLE(acpi, intel_th_acpi_ids);
36
37static int intel_th_acpi_probe(struct platform_device *pdev)
38{
39 struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
40 const struct acpi_device_id *id;
41 struct intel_th *th;
42
43 id = acpi_match_device(intel_th_acpi_ids, &pdev->dev);
44 if (!id)
45 return -ENODEV;
46
47 th = intel_th_alloc(&pdev->dev, (void *)id->driver_data,
48 pdev->resource, pdev->num_resources, -1);
49 if (IS_ERR(th))
50 return PTR_ERR(th);
51
52 adev->driver_data = th;
53
54 return 0;
55}
56
57static int intel_th_acpi_remove(struct platform_device *pdev)
58{
59 struct intel_th *th = platform_get_drvdata(pdev);
60
61 intel_th_free(th);
62
63 return 0;
64}
65
66static struct platform_driver intel_th_acpi_driver = {
67 .probe = intel_th_acpi_probe,
68 .remove = intel_th_acpi_remove,
69 .driver = {
70 .name = DRIVER_NAME,
71 .acpi_match_table = intel_th_acpi_ids,
72 },
73};
74
75module_platform_driver(intel_th_acpi_driver);
76
77MODULE_LICENSE("GPL v2");
78MODULE_DESCRIPTION("Intel(R) Trace Hub ACPI controller driver");
79MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@intel.com>");
drivers/hwtracing/intel_th/core.c+18−13
@@ -1,16 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/*2/*
2 * Intel(R) Trace Hub driver core3 * Intel(R) Trace Hub driver core
3 *4 *
4 * Copyright (C) 2014-2015 Intel Corporation.5 * Copyright (C) 2014-2015 Intel Corporation.
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 */6 */
15 7
16#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -638,7 +630,8 @@ intel_th_subdevice_alloc(struct intel_th *th, · 621 unmodified lines
638 thdev->output.port = -1;630 thdev->output.port = -1;
639 thdev->output.scratchpad = subdev->scrpd;631 thdev->output.scratchpad = subdev->scrpd;
640 } else if (subdev->type == INTEL_TH_SWITCH) {632 } else if (subdev->type == INTEL_TH_SWITCH) {
641 thdev->host_mode = host_mode;633 thdev->host_mode =
634 INTEL_TH_CAP(th, host_mode_only) ? true : host_mode;
642 th->hub = thdev;635 th->hub = thdev;
643 }636 }
644 637
@@ -737,7 +730,8 @@ static int intel_th_populate(struct intel_th *th) · 92 unmodified lines
737 struct intel_th_device *thdev;730 struct intel_th_device *thdev;
738 731
739 /* only allow SOURCE and SWITCH devices in host mode */732 /* only allow SOURCE and SWITCH devices in host mode */
740 if (host_mode && subdev->type == INTEL_TH_OUTPUT)733 if ((INTEL_TH_CAP(th, host_mode_only) || host_mode) &&
734 subdev->type == INTEL_TH_OUTPUT)
741 continue;735 continue;
742 736
743 /*737 /*
@@ -813,7 +807,14 @@ intel_th_alloc(struct device *dev, struct intel_th_drvdata *drvdata, · 69 unmodified lines
813 struct resource *devres, unsigned int ndevres, int irq)807 struct resource *devres, unsigned int ndevres, int irq)
814{808{
815 struct intel_th *th;809 struct intel_th *th;
816 int err;810 int err, r;
811
812 if (irq == -1)
813 for (r = 0; r < ndevres; r++)
814 if (devres[r].flags & IORESOURCE_IRQ) {
815 irq = devres[r].start;
816 break;
817 }
817 818
818 th = kzalloc(sizeof(*th), GFP_KERNEL);819 th = kzalloc(sizeof(*th), GFP_KERNEL);
819 if (!th)820 if (!th)
@@ -935,9 +936,13 @@ EXPORT_SYMBOL_GPL(intel_th_trace_disable); · 115 unmodified lines
935int intel_th_set_output(struct intel_th_device *thdev,936int intel_th_set_output(struct intel_th_device *thdev,
936 unsigned int master)937 unsigned int master)
937{938{
938 struct intel_th_device *hub = to_intel_th_device(thdev->dev.parent);939 struct intel_th_device *hub = to_intel_th_hub(thdev);
939 struct intel_th_driver *hubdrv = to_intel_th_driver(hub->dev.driver);940 struct intel_th_driver *hubdrv = to_intel_th_driver(hub->dev.driver);
940 941
942 /* In host mode, this is up to the external debugger, do nothing. */
943 if (hub->host_mode)
944 return 0;
945
941 if (!hubdrv->set_output)946 if (!hubdrv->set_output)
942 return -ENOTSUPP;947 return -ENOTSUPP;
943 948
drivers/hwtracing/intel_th/debug.c+1−9
@@ -1,16 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/*2/*
2 * Intel(R) Trace Hub driver debugging3 * Intel(R) Trace Hub driver debugging
3 *4 *
4 * Copyright (C) 2014-2015 Intel Corporation.5 * Copyright (C) 2014-2015 Intel Corporation.
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 */6 */
15 7
16#include <linux/types.h>8#include <linux/types.h>
drivers/hwtracing/intel_th/debug.h+1−9
@@ -1,16 +1,8 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/*2/*
2 * Intel(R) Trace Hub driver debugging3 * Intel(R) Trace Hub driver debugging
3 *4 *
4 * Copyright (C) 2014-2015 Intel Corporation.5 * Copyright (C) 2014-2015 Intel Corporation.
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 */6 */
15 7
16#ifndef __INTEL_TH_DEBUG_H__8#ifndef __INTEL_TH_DEBUG_H__
drivers/hwtracing/intel_th/gth.c+1−9
@@ -1,16 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/*2/*
2 * Intel(R) Trace Hub Global Trace Hub3 * Intel(R) Trace Hub Global Trace Hub
3 *4 *
4 * Copyright (C) 2014-2015 Intel Corporation.5 * Copyright (C) 2014-2015 Intel Corporation.
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 */6 */
15 7
16#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
drivers/hwtracing/intel_th/gth.h+1−9
@@ -1,16 +1,8 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/*2/*
2 * Intel(R) Trace Hub Global Trace Hub (GTH) data structures3 * Intel(R) Trace Hub Global Trace Hub (GTH) data structures
3 *4 *
4 * Copyright (C) 2014-2015 Intel Corporation.5 * Copyright (C) 2014-2015 Intel Corporation.
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 */6 */
15 7
16#ifndef __INTEL_TH_GTH_H__8#ifndef __INTEL_TH_GTH_H__
drivers/hwtracing/intel_th/intel_th.h+4−10
@@ -1,16 +1,8 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/*2/*
2 * Intel(R) Trace Hub data structures3 * Intel(R) Trace Hub data structures
3 *4 *
4 * Copyright (C) 2014-2015 Intel Corporation.5 * Copyright (C) 2014-2015 Intel Corporation.
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 */6 */
15 7
16#ifndef __INTEL_TH_H__8#ifndef __INTEL_TH_H__
@@ -50,9 +42,11 @@ struct intel_th_output { · 33 unmodified lines
50/**42/**
51 * struct intel_th_drvdata - describes hardware capabilities and quirks43 * struct intel_th_drvdata - describes hardware capabilities and quirks
52 * @tscu_enable: device needs SW to enable time stamping unit44 * @tscu_enable: device needs SW to enable time stamping unit
45 * @host_mode_only: device can only operate in 'host debugger' mode
53 */46 */
54struct intel_th_drvdata {47struct intel_th_drvdata {
55 unsigned int tscu_enable : 1;48 unsigned int tscu_enable : 1,
49 host_mode_only : 1;
56};50};
57 51
58#define INTEL_TH_CAP(_th, _cap) ((_th)->drvdata ? (_th)->drvdata->_cap : 0)52#define INTEL_TH_CAP(_th, _cap) ((_th)->drvdata ? (_th)->drvdata->_cap : 0)
drivers/hwtracing/intel_th/msu.c+1−9
@@ -1,16 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/*2/*
2 * Intel(R) Trace Hub Memory Storage Unit3 * Intel(R) Trace Hub Memory Storage Unit
3 *4 *
4 * Copyright (C) 2014-2015 Intel Corporation.5 * Copyright (C) 2014-2015 Intel Corporation.
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 */6 */
15 7
16#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
drivers/hwtracing/intel_th/msu.h+1−9
@@ -1,16 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/*2/*
2 * Intel(R) Trace Hub Memory Storage Unit (MSU) data structures3 * Intel(R) Trace Hub Memory Storage Unit (MSU) data structures
3 *4 *
4 * Copyright (C) 2014-2015 Intel Corporation.5 * Copyright (C) 2014-2015 Intel Corporation.
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 */6 */
15 7
16#ifndef __INTEL_TH_MSU_H__8#ifndef __INTEL_TH_MSU_H__
drivers/hwtracing/intel_th/pci.c+1−9
@@ -1,16 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/*2/*
2 * Intel(R) Trace Hub pci driver3 * Intel(R) Trace Hub pci driver
3 *4 *
4 * Copyright (C) 2014-2015 Intel Corporation.5 * Copyright (C) 2014-2015 Intel Corporation.
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 */6 */
15 7
16#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
drivers/hwtracing/intel_th/pti.c+1−9
@@ -1,16 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/*2/*
2 * Intel(R) Trace Hub PTI output driver3 * Intel(R) Trace Hub PTI output driver
3 *4 *
4 * Copyright (C) 2014-2016 Intel Corporation.5 * Copyright (C) 2014-2016 Intel Corporation.
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 */6 */
15 7
16#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
drivers/hwtracing/intel_th/pti.h+1−9
@@ -1,16 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/*2/*
2 * Intel(R) Trace Hub PTI output data structures3 * Intel(R) Trace Hub PTI output data structures
3 *4 *
4 * Copyright (C) 2014-2015 Intel Corporation.5 * Copyright (C) 2014-2015 Intel Corporation.
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 */6 */
15 7
16#ifndef __INTEL_TH_STH_H__8#ifndef __INTEL_TH_STH_H__
drivers/hwtracing/intel_th/sth.c+1−9
@@ -1,16 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/*2/*
2 * Intel(R) Trace Hub Software Trace Hub support3 * Intel(R) Trace Hub Software Trace Hub support
3 *4 *
4 * Copyright (C) 2014-2015 Intel Corporation.5 * Copyright (C) 2014-2015 Intel Corporation.
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 */6 */
15 7
16#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
drivers/hwtracing/intel_th/sth.h+1−9
@@ -1,16 +1,8 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/*2/*
2 * Intel(R) Trace Hub Software Trace Hub (STH) data structures3 * Intel(R) Trace Hub Software Trace Hub (STH) data structures
3 *4 *
4 * Copyright (C) 2014-2015 Intel Corporation.5 * Copyright (C) 2014-2015 Intel Corporation.
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 */6 */
15 7
16#ifndef __INTEL_TH_STH_H__8#ifndef __INTEL_TH_STH_H__
drivers/hwtracing/stm/console.c+1−9
@@ -1,16 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/*2/*
2 * Simple kernel console driver for STM devices3 * Simple kernel console driver for STM devices
3 * Copyright (c) 2014, Intel Corporation.4 * Copyright (c) 2014, Intel Corporation.
4 *5 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * STM console will send kernel messages over STM devices to a trace host.6 * STM console will send kernel messages over STM devices to a trace host.
15 */7 */
16 8
drivers/hwtracing/stm/core.c+1−9
@@ -1,16 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/*2/*
2 * System Trace Module (STM) infrastructure3 * System Trace Module (STM) infrastructure
3 * Copyright (c) 2014, Intel Corporation.4 * Copyright (c) 2014, Intel Corporation.
4 *5 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * STM class implements generic infrastructure for System Trace Module devices6 * STM class implements generic infrastructure for System Trace Module devices
15 * as defined in MIPI STPv2 specification.7 * as defined in MIPI STPv2 specification.
16 */8 */
drivers/hwtracing/stm/dummy_stm.c+22−12
@@ -1,16 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/*2/*
2 * A dummy STM device for stm/stm_source class testing.3 * A dummy STM device for stm/stm_source class testing.
3 * Copyright (c) 2014, Intel Corporation.4 * Copyright (c) 2014, Intel Corporation.
4 *5 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * STM class implements generic infrastructure for System Trace Module devices6 * STM class implements generic infrastructure for System Trace Module devices
15 * as defined in MIPI STPv2 specification.7 * as defined in MIPI STPv2 specification.
16 */8 */
@@ -20,6 +12,7 @@ · 3 unmodified lines
20#include <linux/module.h>12#include <linux/module.h>
21#include <linux/slab.h>13#include <linux/slab.h>
22#include <linux/stm.h>14#include <linux/stm.h>
15#include <uapi/linux/stm.h>
23 16
24static ssize_t notrace17static ssize_t notrace
25dummy_stm_packet(struct stm_data *stm_data, unsigned int master,18dummy_stm_packet(struct stm_data *stm_data, unsigned int master,
@@ -52,6 +45,18 @@ static unsigned int fail_mode; · 26 unmodified lines
52 45
53module_param(fail_mode, int, 0600);46module_param(fail_mode, int, 0600);
54 47
48static unsigned int master_min;
49
50module_param(master_min, int, 0400);
51
52static unsigned int master_max = STP_MASTER_MAX;
53
54module_param(master_max, int, 0400);
55
56static unsigned int nr_channels = STP_CHANNEL_MAX;
57
58module_param(nr_channels, int, 0400);
59
55static int dummy_stm_link(struct stm_data *data, unsigned int master,60static int dummy_stm_link(struct stm_data *data, unsigned int master,
56 unsigned int channel)61 unsigned int channel)
57{62{
@@ -68,14 +73,19 @@ static int dummy_stm_init(void) · 10 unmodified lines
68 if (nr_dummies < 0 || nr_dummies > DUMMY_STM_MAX)73 if (nr_dummies < 0 || nr_dummies > DUMMY_STM_MAX)
69 return -EINVAL;74 return -EINVAL;
70 75
76 if (master_min > master_max ||
77 master_max > STP_MASTER_MAX ||
78 nr_channels > STP_CHANNEL_MAX)
79 return -EINVAL;
80
71 for (i = 0; i < nr_dummies; i++) {81 for (i = 0; i < nr_dummies; i++) {
72 dummy_stm[i].name = kasprintf(GFP_KERNEL, "dummy_stm.%d", i);82 dummy_stm[i].name = kasprintf(GFP_KERNEL, "dummy_stm.%d", i);
73 if (!dummy_stm[i].name)83 if (!dummy_stm[i].name)
74 goto fail_unregister;84 goto fail_unregister;
75 85
76 dummy_stm[i].sw_start = 0x0000;86 dummy_stm[i].sw_start = master_min;
77 dummy_stm[i].sw_end = 0xffff;87 dummy_stm[i].sw_end = master_max;
78 dummy_stm[i].sw_nchannels = 0xffff;88 dummy_stm[i].sw_nchannels = nr_channels;
79 dummy_stm[i].packet = dummy_stm_packet;89 dummy_stm[i].packet = dummy_stm_packet;
80 dummy_stm[i].link = dummy_stm_link;90 dummy_stm[i].link = dummy_stm_link;
81 91
drivers/hwtracing/stm/heartbeat.c+1−9
@@ -1,16 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/*2/*
2 * Simple heartbeat STM source driver3 * Simple heartbeat STM source driver
3 * Copyright (c) 2016, Intel Corporation.4 * Copyright (c) 2016, Intel Corporation.
4 *5 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * Heartbeat STM source will send repetitive messages over STM devices to a6 * Heartbeat STM source will send repetitive messages over STM devices to a
15 * trace host.7 * trace host.
16 */8 */
drivers/hwtracing/stm/policy.c+1−9
@@ -1,16 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/*2/*
2 * System Trace Module (STM) master/channel allocation policy management3 * System Trace Module (STM) master/channel allocation policy management
3 * Copyright (c) 2014, Intel Corporation.4 * Copyright (c) 2014, Intel Corporation.
4 *5 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * A master/channel allocation policy allows mapping string identifiers to6 * A master/channel allocation policy allows mapping string identifiers to
15 * master and channel ranges, where allocation can be done.7 * master and channel ranges, where allocation can be done.
16 */8 */
drivers/hwtracing/stm/stm.h+1−9
@@ -1,16 +1,8 @@
1/* SPDX-License-Identifier: GPL-2.0 */
1/*2/*
2 * System Trace Module (STM) infrastructure3 * System Trace Module (STM) infrastructure
3 * Copyright (c) 2014, Intel Corporation.4 * Copyright (c) 2014, Intel Corporation.
4 *5 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * STM class implements generic infrastructure for System Trace Module devices6 * STM class implements generic infrastructure for System Trace Module devices
15 * as defined in MIPI STPv2 specification.7 * as defined in MIPI STPv2 specification.
16 */8 */
drivers/mcb/mcb-pci.c+1−0
@@ -117,6 +117,7 @@ static void mcb_pci_remove(struct pci_dev *pdev) · 116 unmodified lines
117 117
118static const struct pci_device_id mcb_pci_tbl[] = {118static const struct pci_device_id mcb_pci_tbl[] = {
119 { PCI_DEVICE(PCI_VENDOR_ID_MEN, PCI_DEVICE_ID_MEN_CHAMELEON) },119 { PCI_DEVICE(PCI_VENDOR_ID_MEN, PCI_DEVICE_ID_MEN_CHAMELEON) },
120 { PCI_DEVICE(PCI_VENDOR_ID_ALTERA, PCI_DEVICE_ID_MEN_CHAMELEON) },
120 { 0 },121 { 0 },
121};122};
122MODULE_DEVICE_TABLE(pci, mcb_pci_tbl);123MODULE_DEVICE_TABLE(pci, mcb_pci_tbl);
drivers/misc/Kconfig+0−1
@@ -75,7 +75,6 @@ config ATMEL_TCB_CLKSRC · 74 unmodified lines
75config ATMEL_TCB_CLKSRC_BLOCK75config ATMEL_TCB_CLKSRC_BLOCK
76 int76 int
77 depends on ATMEL_TCB_CLKSRC77 depends on ATMEL_TCB_CLKSRC
78 prompt "TC Block" if CPU_AT32AP700X
79 default 078 default 0
80 range 0 179 range 0 1
81 help80 help
drivers/misc/Makefile+1−19
@@ -12,7 +12,7 @@ obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o · 11 unmodified lines
12obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o12obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o
13obj-$(CONFIG_DUMMY_IRQ) += dummy-irq.o13obj-$(CONFIG_DUMMY_IRQ) += dummy-irq.o
14obj-$(CONFIG_ICS932S401) += ics932s401.o14obj-$(CONFIG_ICS932S401) += ics932s401.o
15obj-$(CONFIG_LKDTM) += lkdtm.o15obj-$(CONFIG_LKDTM) += lkdtm/
16obj-$(CONFIG_TIFM_CORE) += tifm_core.o16obj-$(CONFIG_TIFM_CORE) += tifm_core.o
17obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o17obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o
18obj-$(CONFIG_PHANTOM) += phantom.o18obj-$(CONFIG_PHANTOM) += phantom.o
@@ -57,21 +57,3 @@ obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o · 38 unmodified lines
57obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o57obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o
58obj-$(CONFIG_OCXL) += ocxl/58obj-$(CONFIG_OCXL) += ocxl/
59obj-$(CONFIG_MISC_RTSX) += cardreader/59obj-$(CONFIG_MISC_RTSX) += cardreader/
60
61lkdtm-$(CONFIG_LKDTM) += lkdtm_core.o
62lkdtm-$(CONFIG_LKDTM) += lkdtm_bugs.o
63lkdtm-$(CONFIG_LKDTM) += lkdtm_heap.o
64lkdtm-$(CONFIG_LKDTM) += lkdtm_perms.o
65lkdtm-$(CONFIG_LKDTM) += lkdtm_refcount.o
66lkdtm-$(CONFIG_LKDTM) += lkdtm_rodata_objcopy.o
67lkdtm-$(CONFIG_LKDTM) += lkdtm_usercopy.o
68
69KCOV_INSTRUMENT_lkdtm_rodata.o := n
70
71OBJCOPYFLAGS :=
72OBJCOPYFLAGS_lkdtm_rodata_objcopy.o := \
73 --set-section-flags .text=alloc,readonly \
74 --rename-section .text=.rodata
75targets += lkdtm_rodata.o lkdtm_rodata_objcopy.o
76$(obj)/lkdtm_rodata_objcopy.o: $(obj)/lkdtm_rodata.o FORCE
77 $(call if_changed,objcopy)
drivers/misc/aspeed-lpc-ctrl.c+39−5
@@ -7,6 +7,7 @@ · 6 unmodified lines
7 * 2 of the License, or (at your option) any later version.7 * 2 of the License, or (at your option) any later version.
8 */8 */
9 9
10#include <linux/clk.h>
10#include <linux/mfd/syscon.h>11#include <linux/mfd/syscon.h>
11#include <linux/miscdevice.h>12#include <linux/miscdevice.h>
12#include <linux/mm.h>13#include <linux/mm.h>
@@ -20,12 +21,17 @@ · 7 unmodified lines
20 21
21#define DEVICE_NAME "aspeed-lpc-ctrl"22#define DEVICE_NAME "aspeed-lpc-ctrl"
22 23
24#define HICR5 0x0
25#define HICR5_ENL2H BIT(8)
26#define HICR5_ENFWH BIT(10)
27
23#define HICR7 0x828#define HICR7 0x8
24#define HICR8 0xc29#define HICR8 0xc
25 30
26struct aspeed_lpc_ctrl {31struct aspeed_lpc_ctrl {
27 struct miscdevice miscdev;32 struct miscdevice miscdev;
28 struct regmap *regmap;33 struct regmap *regmap;
34 struct clk *clk;
29 phys_addr_t mem_base;35 phys_addr_t mem_base;
30 resource_size_t mem_size;36 resource_size_t mem_size;
31 u32 pnor_size;37 u32 pnor_size;
@@ -153,8 +159,18 @@ static long aspeed_lpc_ctrl_ioctl(struct file *file, unsigned int cmd, · 121 unmodified lines
153 if (rc)159 if (rc)
154 return rc;160 return rc;
155 161
156 return regmap_write(lpc_ctrl->regmap, HICR8,162 rc = regmap_write(lpc_ctrl->regmap, HICR8,
157 (~(map.size - 1)) | ((map.size >> 16) - 1));163 (~(map.size - 1)) | ((map.size >> 16) - 1));
164 if (rc)
165 return rc;
166
167 /*
168 * Enable LPC FHW cycles. This is required for the host to
169 * access the regions specified.
170 */
171 return regmap_update_bits(lpc_ctrl->regmap, HICR5,
172 HICR5_ENFWH | HICR5_ENL2H,
173 HICR5_ENFWH | HICR5_ENL2H);
158 }174 }
159 175
160 return -EINVAL;176 return -EINVAL;
@@ -221,16 +237,33 @@ static int aspeed_lpc_ctrl_probe(struct platform_device *pdev) · 60 unmodified lines
221 return -ENODEV;237 return -ENODEV;
222 }238 }
223 239
240 lpc_ctrl->clk = devm_clk_get(dev, NULL);
241 if (IS_ERR(lpc_ctrl->clk)) {
242 dev_err(dev, "couldn't get clock\n");
243 return PTR_ERR(lpc_ctrl->clk);
244 }
245 rc = clk_prepare_enable(lpc_ctrl->clk);
246 if (rc) {
247 dev_err(dev, "couldn't enable clock\n");
248 return rc;
249 }
250
224 lpc_ctrl->miscdev.minor = MISC_DYNAMIC_MINOR;251 lpc_ctrl->miscdev.minor = MISC_DYNAMIC_MINOR;
225 lpc_ctrl->miscdev.name = DEVICE_NAME;252 lpc_ctrl->miscdev.name = DEVICE_NAME;
226 lpc_ctrl->miscdev.fops = &aspeed_lpc_ctrl_fops;253 lpc_ctrl->miscdev.fops = &aspeed_lpc_ctrl_fops;
227 lpc_ctrl->miscdev.parent = dev;254 lpc_ctrl->miscdev.parent = dev;
228 rc = misc_register(&lpc_ctrl->miscdev);255 rc = misc_register(&lpc_ctrl->miscdev);
229 if (rc)256 if (rc) {
230 dev_err(dev, "Unable to register device\n");257 dev_err(dev, "Unable to register device\n");
231 else258 goto err;
232 dev_info(dev, "Loaded at %pr\n", &resm);259 }
260
261 dev_info(dev, "Loaded at %pr\n", &resm);
262
263 return 0;
233 264
265err:
266 clk_disable_unprepare(lpc_ctrl->clk);
234 return rc;267 return rc;
235}268}
236 269
@@ -239,6 +272,7 @@ static int aspeed_lpc_ctrl_remove(struct platform_device *pdev) · 2 unmodified lines
239 struct aspeed_lpc_ctrl *lpc_ctrl = dev_get_drvdata(&pdev->dev);272 struct aspeed_lpc_ctrl *lpc_ctrl = dev_get_drvdata(&pdev->dev);
240 273
241 misc_deregister(&lpc_ctrl->miscdev);274 misc_deregister(&lpc_ctrl->miscdev);
275 clk_disable_unprepare(lpc_ctrl->clk);
242 276
243 return 0;277 return 0;
244}278}
drivers/misc/cardreader/rts5260.c+6−6
@@ -388,17 +388,17 @@ static void rts5260_disable_ocp(struct rtsx_pcr *pcr) · 387 unmodified lines
388 OC_POWER_DOWN);388 OC_POWER_DOWN);
389}389}
390 390
391int rts5260_get_ocpstat(struct rtsx_pcr *pcr, u8 *val)391static int rts5260_get_ocpstat(struct rtsx_pcr *pcr, u8 *val)
392{392{
393 return rtsx_pci_read_register(pcr, REG_OCPSTAT, val);393 return rtsx_pci_read_register(pcr, REG_OCPSTAT, val);
394}394}
395 395
396int rts5260_get_ocpstat2(struct rtsx_pcr *pcr, u8 *val)396static int rts5260_get_ocpstat2(struct rtsx_pcr *pcr, u8 *val)
397{397{
398 return rtsx_pci_read_register(pcr, REG_DV3318_OCPSTAT, val);398 return rtsx_pci_read_register(pcr, REG_DV3318_OCPSTAT, val);
399}399}
400 400
401void rts5260_clear_ocpstat(struct rtsx_pcr *pcr)401static void rts5260_clear_ocpstat(struct rtsx_pcr *pcr)
402{402{
403 u8 mask = 0;403 u8 mask = 0;
404 u8 val = 0;404 u8 val = 0;
@@ -418,7 +418,7 @@ void rts5260_clear_ocpstat(struct rtsx_pcr *pcr) · 13 unmodified lines
418 DV3318_OCP_INT_CLR | DV3318_OCP_CLR, 0);418 DV3318_OCP_INT_CLR | DV3318_OCP_CLR, 0);
419}419}
420 420
421void rts5260_process_ocp(struct rtsx_pcr *pcr)421static void rts5260_process_ocp(struct rtsx_pcr *pcr)
422{422{
423 if (!pcr->option.ocp_en)423 if (!pcr->option.ocp_en)
424 return;424 return;
@@ -449,7 +449,7 @@ void rts5260_process_ocp(struct rtsx_pcr *pcr) · 24 unmodified lines
449 }449 }
450}450}
451 451
452int rts5260_init_hw(struct rtsx_pcr *pcr)452static int rts5260_init_hw(struct rtsx_pcr *pcr)
453{453{
454 int err;454 int err;
455 455
@@ -620,7 +620,7 @@ static int rts5260_extra_init_hw(struct rtsx_pcr *pcr) · 164 unmodified lines
620 return 0;620 return 0;
621}621}
622 622
623void rts5260_set_aspm(struct rtsx_pcr *pcr, bool enable)623static void rts5260_set_aspm(struct rtsx_pcr *pcr, bool enable)
624{624{
625 struct rtsx_cr_option *option = &pcr->option;625 struct rtsx_cr_option *option = &pcr->option;
626 u8 val = 0;626 u8 val = 0;
drivers/misc/eeprom/at24.c+156−137
@@ -1,14 +1,11 @@
1// SPDX-License-Identifier: GPL-2.0+
1/*2/*
2 * at24.c - handle most I2C EEPROMs3 * at24.c - handle most I2C EEPROMs
3 *4 *
4 * Copyright (C) 2005-2007 David Brownell5 * Copyright (C) 2005-2007 David Brownell
5 * Copyright (C) 2008 Wolfram Sang, Pengutronix6 * Copyright (C) 2008 Wolfram Sang, Pengutronix
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */7 */
8
12#include <linux/kernel.h>9#include <linux/kernel.h>
13#include <linux/init.h>10#include <linux/init.h>
14#include <linux/module.h>11#include <linux/module.h>
@@ -63,8 +60,6 @@ struct at24_client { · 48 unmodified lines
63};60};
64 61
65struct at24_data {62struct at24_data {
66 struct at24_platform_data chip;
67
68 /*63 /*
69 * Lock protects against activities from other Linux tasks,64 * Lock protects against activities from other Linux tasks,
70 * but not from changes by other I2C masters.65 * but not from changes by other I2C masters.
@@ -75,7 +70,10 @@ struct at24_data { · 4 unmodified lines
75 unsigned int num_addresses;70 unsigned int num_addresses;
76 unsigned int offset_adj;71 unsigned int offset_adj;
77 72
78 struct nvmem_config nvmem_config;73 u32 byte_len;
74 u16 page_size;
75 u8 flags;
76
79 struct nvmem_device *nvmem;77 struct nvmem_device *nvmem;
80 78
81 struct gpio_desc *wp_gpio;79 struct gpio_desc *wp_gpio;
@@ -239,8 +237,6 @@ static const struct acpi_device_id at24_acpi_ids[] = { · 157 unmodified lines
239};237};
240MODULE_DEVICE_TABLE(acpi, at24_acpi_ids);238MODULE_DEVICE_TABLE(acpi, at24_acpi_ids);
241 239
242/*-------------------------------------------------------------------------*/
243
244/*240/*
245 * This routine supports chips which consume multiple I2C addresses. It241 * This routine supports chips which consume multiple I2C addresses. It
246 * computes the addressing information to be used for a given r/w request.242 * computes the addressing information to be used for a given r/w request.
@@ -255,7 +251,7 @@ static struct at24_client *at24_translate_offset(struct at24_data *at24, · 8 unmodified lines
255{251{
256 unsigned int i;252 unsigned int i;
257 253
258 if (at24->chip.flags & AT24_FLAG_ADDR16) {254 if (at24->flags & AT24_FLAG_ADDR16) {
259 i = *offset >> 16;255 i = *offset >> 16;
260 *offset &= 0xffff;256 *offset &= 0xffff;
261 } else {257 } else {
@@ -266,6 +262,11 @@ static struct at24_client *at24_translate_offset(struct at24_data *at24, · 4 unmodified lines
266 return &at24->client[i];262 return &at24->client[i];
267}263}
268 264
265static struct device *at24_base_client_dev(struct at24_data *at24)
266{
267 return &at24->client[0].client->dev;
268}
269
269static size_t at24_adjust_read_count(struct at24_data *at24,270static size_t at24_adjust_read_count(struct at24_data *at24,
270 unsigned int offset, size_t count)271 unsigned int offset, size_t count)
271{272{
@@ -277,8 +278,8 @@ static size_t at24_adjust_read_count(struct at24_data *at24, · 5 unmodified lines
277 * the next slave address: truncate the count to the slave boundary,278 * the next slave address: truncate the count to the slave boundary,
278 * so that the read never straddles slaves.279 * so that the read never straddles slaves.
279 */280 */
280 if (at24->chip.flags & AT24_FLAG_NO_RDROL) {281 if (at24->flags & AT24_FLAG_NO_RDROL) {
281 bits = (at24->chip.flags & AT24_FLAG_ADDR16) ? 16 : 8;282 bits = (at24->flags & AT24_FLAG_ADDR16) ? 16 : 8;
282 remainder = BIT(bits) - offset;283 remainder = BIT(bits) - offset;
283 if (count > remainder)284 if (count > remainder)
284 count = remainder;285 count = remainder;
@@ -337,7 +338,7 @@ static size_t at24_adjust_write_count(struct at24_data *at24, · 52 unmodified lines
337 count = at24->write_max;338 count = at24->write_max;
338 339
339 /* Never roll over backwards, to the start of this page */340 /* Never roll over backwards, to the start of this page */
340 next_page = roundup(offset + 1, at24->chip.page_size);341 next_page = roundup(offset + 1, at24->page_size);
341 if (offset + count > next_page)342 if (offset + count > next_page)
342 count = next_page - offset;343 count = next_page - offset;
343 344
@@ -371,15 +372,18 @@ static ssize_t at24_regmap_write(struct at24_data *at24, const char *buf, · 27 unmodified lines
371 372
372static int at24_read(void *priv, unsigned int off, void *val, size_t count)373static int at24_read(void *priv, unsigned int off, void *val, size_t count)
373{374{
374 struct at24_data *at24 = priv;375 struct at24_data *at24;
375 struct device *dev = &at24->client[0].client->dev;376 struct device *dev;
376 char *buf = val;377 char *buf = val;
377 int ret;378 int ret;
378 379
380 at24 = priv;
381 dev = at24_base_client_dev(at24);
382
379 if (unlikely(!count))383 if (unlikely(!count))
380 return count;384 return count;
381 385
382 if (off + count > at24->chip.byte_len)386 if (off + count > at24->byte_len)
383 return -EINVAL;387 return -EINVAL;
384 388
385 ret = pm_runtime_get_sync(dev);389 ret = pm_runtime_get_sync(dev);
@@ -395,17 +399,15 @@ static int at24_read(void *priv, unsigned int off, void *val, size_t count) · 9 unmodified lines
395 mutex_lock(&at24->lock);399 mutex_lock(&at24->lock);
396 400
397 while (count) {401 while (count) {
398 int status;402 ret = at24_regmap_read(at24, buf, off, count);
399 403 if (ret < 0) {
400 status = at24_regmap_read(at24, buf, off, count);
401 if (status < 0) {
402 mutex_unlock(&at24->lock);404 mutex_unlock(&at24->lock);
403 pm_runtime_put(dev);405 pm_runtime_put(dev);
404 return status;406 return ret;
405 }407 }
406 buf += status;408 buf += ret;
407 off += status;409 off += ret;
408 count -= status;410 count -= ret;
409 }411 }
410 412
411 mutex_unlock(&at24->lock);413 mutex_unlock(&at24->lock);
@@ -417,15 +419,18 @@ static int at24_read(void *priv, unsigned int off, void *val, size_t count) · 5 unmodified lines
417 419
418static int at24_write(void *priv, unsigned int off, void *val, size_t count)420static int at24_write(void *priv, unsigned int off, void *val, size_t count)
419{421{
420 struct at24_data *at24 = priv;422 struct at24_data *at24;
421 struct device *dev = &at24->client[0].client->dev;423 struct device *dev;
422 char *buf = val;424 char *buf = val;
423 int ret;425 int ret;
424 426
427 at24 = priv;
428 dev = at24_base_client_dev(at24);
429
425 if (unlikely(!count))430 if (unlikely(!count))
426 return -EINVAL;431 return -EINVAL;
427 432
428 if (off + count > at24->chip.byte_len)433 if (off + count > at24->byte_len)
429 return -EINVAL;434 return -EINVAL;
430 435
431 ret = pm_runtime_get_sync(dev);436 ret = pm_runtime_get_sync(dev);
@@ -442,18 +447,16 @@ static int at24_write(void *priv, unsigned int off, void *val, size_t count) · 10 unmodified lines
442 gpiod_set_value_cansleep(at24->wp_gpio, 0);447 gpiod_set_value_cansleep(at24->wp_gpio, 0);
443 448
444 while (count) {449 while (count) {
445 int status;450 ret = at24_regmap_write(at24, buf, off, count);
446 451 if (ret < 0) {
447 status = at24_regmap_write(at24, buf, off, count);
448 if (status < 0) {
449 gpiod_set_value_cansleep(at24->wp_gpio, 1);452 gpiod_set_value_cansleep(at24->wp_gpio, 1);
450 mutex_unlock(&at24->lock);453 mutex_unlock(&at24->lock);
451 pm_runtime_put(dev);454 pm_runtime_put(dev);
452 return status;455 return ret;
453 }456 }
454 buf += status;457 buf += ret;
455 off += status;458 off += ret;
456 count -= status;459 count -= ret;
457 }460 }
458 461
459 gpiod_set_value_cansleep(at24->wp_gpio, 1);462 gpiod_set_value_cansleep(at24->wp_gpio, 1);
@@ -464,7 +467,8 @@ static int at24_write(void *priv, unsigned int off, void *val, size_t count) · 4 unmodified lines
464 return 0;467 return 0;
465}468}
466 469
467static void at24_get_pdata(struct device *dev, struct at24_platform_data *chip)470static void at24_properties_to_pdata(struct device *dev,
471 struct at24_platform_data *chip)
468{472{
469 int err;473 int err;
470 u32 val;474 u32 val;
@@ -491,6 +495,43 @@ static void at24_get_pdata(struct device *dev, struct at24_platform_data *chip) · 20 unmodified lines
491 }495 }
492}496}
493 497
498static int at24_get_pdata(struct device *dev, struct at24_platform_data *pdata)
499{
500 struct device_node *of_node = dev->of_node;
501 const struct at24_chip_data *cdata;
502 const struct i2c_device_id *id;
503 struct at24_platform_data *pd;
504
505 pd = dev_get_platdata(dev);
506 if (pd) {
507 memcpy(pdata, pd, sizeof(*pdata));
508 return 0;
509 }
510
511 id = i2c_match_id(at24_ids, to_i2c_client(dev));
512
513 /*
514 * The I2C core allows OF nodes compatibles to match against the
515 * I2C device ID table as a fallback, so check not only if an OF
516 * node is present but also if it matches an OF device ID entry.
517 */
518 if (of_node && of_match_device(at24_of_match, dev))
519 cdata = of_device_get_match_data(dev);
520 else if (id)
521 cdata = (void *)&id->driver_data;
522 else
523 cdata = acpi_device_get_match_data(dev);
524
525 if (!cdata)
526 return -ENODEV;
527
528 pdata->byte_len = cdata->byte_len;
529 pdata->flags = cdata->flags;
530 at24_properties_to_pdata(dev, pdata);
531
532 return 0;
533}
534
494static unsigned int at24_get_offset_adj(u8 flags, unsigned int byte_len)535static unsigned int at24_get_offset_adj(u8 flags, unsigned int byte_len)
495{536{
496 if (flags & AT24_FLAG_MAC) {537 if (flags & AT24_FLAG_MAC) {
@@ -514,102 +555,83 @@ static unsigned int at24_get_offset_adj(u8 flags, unsigned int byte_len) · 17 unmodified lines
514 }555 }
515}556}
516 557
517static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)558static int at24_probe(struct i2c_client *client)
518{559{
519 struct at24_platform_data chip = { 0 };
520 const struct at24_chip_data *cd = NULL;
521 bool writable;
522 struct at24_data *at24;
523 int err;
524 unsigned int i, num_addresses;
525 struct regmap_config regmap_config = { };560 struct regmap_config regmap_config = { };
561 struct nvmem_config nvmem_config = { };
562 struct at24_platform_data pdata = { };
563 struct device *dev = &client->dev;
564 bool i2c_fn_i2c, i2c_fn_block;
565 unsigned int i, num_addresses;
566 struct at24_data *at24;
567 struct regmap *regmap;
568 size_t at24_size;
569 bool writable;
526 u8 test_byte;570 u8 test_byte;
571 int err;
527 572
528 if (client->dev.platform_data) {573 i2c_fn_i2c = i2c_check_functionality(client->adapter, I2C_FUNC_I2C);
529 chip = *(struct at24_platform_data *)client->dev.platform_data;574 i2c_fn_block = i2c_check_functionality(client->adapter,
530 } else {575 I2C_FUNC_SMBUS_WRITE_I2C_BLOCK);
531 /*
532 * The I2C core allows OF nodes compatibles to match against the
533 * I2C device ID table as a fallback, so check not only if an OF
534 * node is present but also if it matches an OF device ID entry.
535 */
536 if (client->dev.of_node &&
537 of_match_device(at24_of_match, &client->dev)) {
538 cd = of_device_get_match_data(&client->dev);
539 } else if (id) {
540 cd = (void *)id->driver_data;
541 } else {
542 const struct acpi_device_id *aid;
543
544 aid = acpi_match_device(at24_acpi_ids, &client->dev);
545 if (aid)
546 cd = (void *)aid->driver_data;
547 }
548 if (!cd)
549 return -ENODEV;
550 576
551 chip.byte_len = cd->byte_len;577 err = at24_get_pdata(dev, &pdata);
552 chip.flags = cd->flags;578 if (err)
553 at24_get_pdata(&client->dev, &chip);579 return err;
554 }580
581 if (!i2c_fn_i2c && !i2c_fn_block)
582 pdata.page_size = 1;
555 583
556 if (!is_power_of_2(chip.byte_len))584 if (!pdata.page_size) {
557 dev_warn(&client->dev,585 dev_err(dev, "page_size must not be 0!\n");
558 "byte_len looks suspicious (no power of 2)!\n");
559 if (!chip.page_size) {
560 dev_err(&client->dev, "page_size must not be 0!\n");
561 return -EINVAL;586 return -EINVAL;
562 }587 }
563 if (!is_power_of_2(chip.page_size))
564 dev_warn(&client->dev,
565 "page_size looks suspicious (no power of 2)!\n");
566 588
567 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C) &&589 if (!is_power_of_2(pdata.page_size))
568 !i2c_check_functionality(client->adapter,590 dev_warn(dev, "page_size looks suspicious (no power of 2)!\n");
569 I2C_FUNC_SMBUS_WRITE_I2C_BLOCK))
570 chip.page_size = 1;
571 591
572 if (chip.flags & AT24_FLAG_TAKE8ADDR)592 if (pdata.flags & AT24_FLAG_TAKE8ADDR)
573 num_addresses = 8;593 num_addresses = 8;
574 else594 else
575 num_addresses = DIV_ROUND_UP(chip.byte_len,595 num_addresses = DIV_ROUND_UP(pdata.byte_len,
576 (chip.flags & AT24_FLAG_ADDR16) ? 65536 : 256);596 (pdata.flags & AT24_FLAG_ADDR16) ? 65536 : 256);
597
598 if ((pdata.flags & AT24_FLAG_SERIAL) && (pdata.flags & AT24_FLAG_MAC)) {
599 dev_err(dev,
600 "invalid device data - cannot have both AT24_FLAG_SERIAL & AT24_FLAG_MAC.");
601 return -EINVAL;
602 }
577 603
578 regmap_config.val_bits = 8;604 regmap_config.val_bits = 8;
579 regmap_config.reg_bits = (chip.flags & AT24_FLAG_ADDR16) ? 16 : 8;605 regmap_config.reg_bits = (pdata.flags & AT24_FLAG_ADDR16) ? 16 : 8;
606 regmap_config.disable_locking = true;
580 607
581 at24 = devm_kzalloc(&client->dev, sizeof(struct at24_data) +608 regmap = devm_regmap_init_i2c(client, &regmap_config);
582 num_addresses * sizeof(struct at24_client), GFP_KERNEL);609 if (IS_ERR(regmap))
610 return PTR_ERR(regmap);
611
612 at24_size = sizeof(*at24) + num_addresses * sizeof(struct at24_client);
613 at24 = devm_kzalloc(dev, at24_size, GFP_KERNEL);
583 if (!at24)614 if (!at24)
584 return -ENOMEM;615 return -ENOMEM;
585 616
586 mutex_init(&at24->lock);617 mutex_init(&at24->lock);
587 at24->chip = chip;618 at24->byte_len = pdata.byte_len;
619 at24->page_size = pdata.page_size;
620 at24->flags = pdata.flags;
588 at24->num_addresses = num_addresses;621 at24->num_addresses = num_addresses;
589 at24->offset_adj = at24_get_offset_adj(chip.flags, chip.byte_len);622 at24->offset_adj = at24_get_offset_adj(pdata.flags, pdata.byte_len);
623 at24->client[0].client = client;
624 at24->client[0].regmap = regmap;
590 625
591 at24->wp_gpio = devm_gpiod_get_optional(&client->dev,626 at24->wp_gpio = devm_gpiod_get_optional(dev, "wp", GPIOD_OUT_HIGH);
592 "wp", GPIOD_OUT_HIGH);
593 if (IS_ERR(at24->wp_gpio))627 if (IS_ERR(at24->wp_gpio))
594 return PTR_ERR(at24->wp_gpio);628 return PTR_ERR(at24->wp_gpio);
595 629
596 at24->client[0].client = client;630 writable = !(pdata.flags & AT24_FLAG_READONLY);
597 at24->client[0].regmap = devm_regmap_init_i2c(client, &regmap_config);
598 if (IS_ERR(at24->client[0].regmap))
599 return PTR_ERR(at24->client[0].regmap);
600
601 if ((chip.flags & AT24_FLAG_SERIAL) && (chip.flags & AT24_FLAG_MAC)) {
602 dev_err(&client->dev,
603 "invalid device data - cannot have both AT24_FLAG_SERIAL & AT24_FLAG_MAC.");
604 return -EINVAL;
605 }
606
607 writable = !(chip.flags & AT24_FLAG_READONLY);
608 if (writable) {631 if (writable) {
609 at24->write_max = min_t(unsigned int,632 at24->write_max = min_t(unsigned int,
610 chip.page_size, at24_io_limit);633 pdata.page_size, at24_io_limit);
611 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C) &&634 if (!i2c_fn_i2c && at24->write_max > I2C_SMBUS_BLOCK_MAX)
612 at24->write_max > I2C_SMBUS_BLOCK_MAX)
613 at24->write_max = I2C_SMBUS_BLOCK_MAX;635 at24->write_max = I2C_SMBUS_BLOCK_MAX;
614 }636 }
615 637
@@ -618,8 +640,8 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) · 2 unmodified lines
618 at24->client[i].client = i2c_new_dummy(client->adapter,640 at24->client[i].client = i2c_new_dummy(client->adapter,
619 client->addr + i);641 client->addr + i);
620 if (!at24->client[i].client) {642 if (!at24->client[i].client) {
621 dev_err(&client->dev, "address 0x%02x unavailable\n",643 dev_err(dev, "address 0x%02x unavailable\n",
622 client->addr + i);644 client->addr + i);
623 err = -EADDRINUSE;645 err = -EADDRINUSE;
624 goto err_clients;646 goto err_clients;
625 }647 }
@@ -635,48 +657,47 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) · 9 unmodified lines
635 i2c_set_clientdata(client, at24);657 i2c_set_clientdata(client, at24);
636 658
637 /* enable runtime pm */659 /* enable runtime pm */
638 pm_runtime_set_active(&client->dev);660 pm_runtime_set_active(dev);
639 pm_runtime_enable(&client->dev);661 pm_runtime_enable(dev);
640 662
641 /*663 /*
642 * Perform a one-byte test read to verify that the664 * Perform a one-byte test read to verify that the
643 * chip is functional.665 * chip is functional.
644 */666 */
645 err = at24_read(at24, 0, &test_byte, 1);667 err = at24_read(at24, 0, &test_byte, 1);
646 pm_runtime_idle(&client->dev);668 pm_runtime_idle(dev);
647 if (err) {669 if (err) {
648 err = -ENODEV;670 err = -ENODEV;
649 goto err_clients;671 goto err_clients;
650 }672 }
651 673
652 at24->nvmem_config.name = dev_name(&client->dev);674 nvmem_config.name = dev_name(dev);
653 at24->nvmem_config.dev = &client->dev;675 nvmem_config.dev = dev;
654 at24->nvmem_config.read_only = !writable;676 nvmem_config.read_only = !writable;
655 at24->nvmem_config.root_only = true;677 nvmem_config.root_only = true;
656 at24->nvmem_config.owner = THIS_MODULE;678 nvmem_config.owner = THIS_MODULE;
657 at24->nvmem_config.compat = true;679 nvmem_config.compat = true;
658 at24->nvmem_config.base_dev = &client->dev;680 nvmem_config.base_dev = dev;
659 at24->nvmem_config.reg_read = at24_read;681 nvmem_config.reg_read = at24_read;
660 at24->nvmem_config.reg_write = at24_write;682 nvmem_config.reg_write = at24_write;
661 at24->nvmem_config.priv = at24;683 nvmem_config.priv = at24;
662 at24->nvmem_config.stride = 1;684 nvmem_config.stride = 1;
663 at24->nvmem_config.word_size = 1;685 nvmem_config.word_size = 1;
664 at24->nvmem_config.size = chip.byte_len;686 nvmem_config.size = pdata.byte_len;
665 687
666 at24->nvmem = nvmem_register(&at24->nvmem_config);688 at24->nvmem = nvmem_register(&nvmem_config);
667
668 if (IS_ERR(at24->nvmem)) {689 if (IS_ERR(at24->nvmem)) {
669 err = PTR_ERR(at24->nvmem);690 err = PTR_ERR(at24->nvmem);
670 goto err_clients;691 goto err_clients;
671 }692 }
672 693
673 dev_info(&client->dev, "%u byte %s EEPROM, %s, %u bytes/write\n",694 dev_info(dev, "%u byte %s EEPROM, %s, %u bytes/write\n",
674 chip.byte_len, client->name,695 pdata.byte_len, client->name,
675 writable ? "writable" : "read-only", at24->write_max);696 writable ? "writable" : "read-only", at24->write_max);
676 697
677 /* export data to kernel code */698 /* export data to kernel code */
678 if (chip.setup)699 if (pdata.setup)
679 chip.setup(at24->nvmem, chip.context);700 pdata.setup(at24->nvmem, pdata.context);
680 701
681 return 0;702 return 0;
682 703
@@ -685,7 +706,7 @@ err_clients: · 2 unmodified lines
685 if (at24->client[i].client)706 if (at24->client[i].client)
686 i2c_unregister_device(at24->client[i].client);707 i2c_unregister_device(at24->client[i].client);
687 708
688 pm_runtime_disable(&client->dev);709 pm_runtime_disable(dev);
689 710
690 return err;711 return err;
691}712}
@@ -708,15 +729,13 @@ static int at24_remove(struct i2c_client *client) · 16 unmodified lines
708 return 0;729 return 0;
709}730}
710 731
711/*-------------------------------------------------------------------------*/
712
713static struct i2c_driver at24_driver = {732static struct i2c_driver at24_driver = {
714 .driver = {733 .driver = {
715 .name = "at24",734 .name = "at24",
716 .of_match_table = at24_of_match,735 .of_match_table = at24_of_match,
717 .acpi_match_table = ACPI_PTR(at24_acpi_ids),736 .acpi_match_table = ACPI_PTR(at24_acpi_ids),
718 },737 },
719 .probe = at24_probe,738 .probe_new = at24_probe,
720 .remove = at24_remove,739 .remove = at24_remove,
721 .id_table = at24_ids,740 .id_table = at24_ids,
722};741};
drivers/misc/eeprom/at25.c+1−1
@@ -102,7 +102,7 @@ static int at25_ee_read(void *priv, unsigned int offset, · 101 unmodified lines
102 }102 }
103 103
104 spi_message_init(&m);104 spi_message_init(&m);
105 memset(t, 0, sizeof t);105 memset(t, 0, sizeof(t));
106 106
107 t[0].tx_buf = command;107 t[0].tx_buf = command;
108 t[0].len = at25->addrlen + 1;108 t[0].len = at25->addrlen + 1;
drivers/misc/lkdtm/Makefile+20−0
@@ -0,0 +1,20 @@
1# SPDX-License-Identifier: GPL-2.0
2obj-$(CONFIG_LKDTM) += lkdtm.o
3
4lkdtm-$(CONFIG_LKDTM) += core.o
5lkdtm-$(CONFIG_LKDTM) += bugs.o
6lkdtm-$(CONFIG_LKDTM) += heap.o
7lkdtm-$(CONFIG_LKDTM) += perms.o
8lkdtm-$(CONFIG_LKDTM) += refcount.o
9lkdtm-$(CONFIG_LKDTM) += rodata_objcopy.o
10lkdtm-$(CONFIG_LKDTM) += usercopy.o
11
12KCOV_INSTRUMENT_rodata.o := n
13
14OBJCOPYFLAGS :=
15OBJCOPYFLAGS_rodata_objcopy.o := \
16 --set-section-flags .text=alloc,readonly \
17 --rename-section .text=.rodata
18targets += rodata.o rodata_objcopy.o
19$(obj)/rodata_objcopy.o: $(obj)/rodata.o FORCE
20 $(call if_changed,objcopy)
drivers/misc/lkdtm/bugs.crenamed from drivers/misc/lkdtm_bugs.c+0−0

File renamed without changes.

drivers/misc/lkdtm/core.crenamed from drivers/misc/lkdtm_core.c+0−0

File renamed without changes.

drivers/misc/lkdtm/heap.crenamed from drivers/misc/lkdtm_heap.c+0−0

File renamed without changes.

drivers/misc/lkdtm/lkdtm.hrenamed from drivers/misc/lkdtm.h+0−0

File renamed without changes.

drivers/misc/lkdtm/perms.crenamed from drivers/misc/lkdtm_perms.c+0−0

File renamed without changes.

drivers/misc/lkdtm/refcount.crenamed from drivers/misc/lkdtm_refcount.c+1−0
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/*2/*
2 * This is for all the tests related to refcount bugs (e.g. overflow,3 * This is for all the tests related to refcount bugs (e.g. overflow,
3 * underflow, reaching zero untested, etc).4 * underflow, reaching zero untested, etc).
drivers/misc/lkdtm/rodata.crenamed from drivers/misc/lkdtm_rodata.c+0−0

File renamed without changes.

drivers/misc/lkdtm/usercopy.crenamed from drivers/misc/lkdtm_usercopy.c+0−0

File renamed without changes.

drivers/misc/mei/bus.c+51−32
@@ -74,6 +74,23 @@ ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, · 73 unmodified lines
74 goto out;74 goto out;
75 }75 }
76 76
77 while (cl->tx_cb_queued >= bus->tx_queue_limit) {
78 mutex_unlock(&bus->device_lock);
79 rets = wait_event_interruptible(cl->tx_wait,
80 cl->writing_state == MEI_WRITE_COMPLETE ||
81 (!mei_cl_is_connected(cl)));
82 mutex_lock(&bus->device_lock);
83 if (rets) {
84 if (signal_pending(current))
85 rets = -EINTR;
86 goto out;
87 }
88 if (!mei_cl_is_connected(cl)) {
89 rets = -ENODEV;
90 goto out;
91 }
92 }
93
77 cb = mei_cl_alloc_cb(cl, length, MEI_FOP_WRITE, NULL);94 cb = mei_cl_alloc_cb(cl, length, MEI_FOP_WRITE, NULL);
78 if (!cb) {95 if (!cb) {
79 rets = -ENOMEM;96 rets = -ENOMEM;
@@ -449,6 +466,29 @@ bool mei_cldev_enabled(struct mei_cl_device *cldev) · 369 unmodified lines
449}466}
450EXPORT_SYMBOL_GPL(mei_cldev_enabled);467EXPORT_SYMBOL_GPL(mei_cldev_enabled);
451 468
469/**
470 * mei_cl_bus_module_get - acquire module of the underlying
471 * hw driver.
472 *
473 * @cldev: mei client device
474 *
475 * Return: true on success; false if the module was removed.
476 */
477static bool mei_cl_bus_module_get(struct mei_cl_device *cldev)
478{
479 return try_module_get(cldev->bus->dev->driver->owner);
480}
481
482/**
483 * mei_cl_bus_module_put - release the underlying hw module.
484 *
485 * @cldev: mei client device
486 */
487static void mei_cl_bus_module_put(struct mei_cl_device *cldev)
488{
489 module_put(cldev->bus->dev->driver->owner);
490}
491
452/**492/**
453 * mei_cldev_enable - enable me client device493 * mei_cldev_enable - enable me client device
454 * create connection with me client494 * create connection with me client
@@ -487,9 +527,17 @@ int mei_cldev_enable(struct mei_cl_device *cldev) · 32 unmodified lines
487 goto out;527 goto out;
488 }528 }
489 529
530 if (!mei_cl_bus_module_get(cldev)) {
531 dev_err(&cldev->dev, "get hw module failed");
532 ret = -ENODEV;
533 goto out;
534 }
535
490 ret = mei_cl_connect(cl, cldev->me_cl, NULL);536 ret = mei_cl_connect(cl, cldev->me_cl, NULL);
491 if (ret < 0)537 if (ret < 0) {
492 dev_err(&cldev->dev, "cannot connect\n");538 dev_err(&cldev->dev, "cannot connect\n");
539 mei_cl_bus_module_put(cldev);
540 }
493 541
494out:542out:
495 mutex_unlock(&bus->device_lock);543 mutex_unlock(&bus->device_lock);
@@ -553,6 +601,8 @@ int mei_cldev_disable(struct mei_cl_device *cldev) · 57 unmodified lines
553 dev_err(bus->dev, "Could not disconnect from the ME client\n");601 dev_err(bus->dev, "Could not disconnect from the ME client\n");
554 602
555out:603out:
604 mei_cl_bus_module_put(cldev);
605
556 /* Flush queues and remove any pending read */606 /* Flush queues and remove any pending read */
557 mei_cl_flush_queues(cl, NULL);607 mei_cl_flush_queues(cl, NULL);
558 mei_cl_unlink(cl);608 mei_cl_unlink(cl);
@@ -562,37 +612,6 @@ out: · 3 unmodified lines
562}612}
563EXPORT_SYMBOL_GPL(mei_cldev_disable);613EXPORT_SYMBOL_GPL(mei_cldev_disable);
564 614
565/**
566 * mei_cl_bus_module_get - acquire module of the underlying
567 * hw module.
568 *
569 * @cl: host client
570 *
571 * Return: true on success; false if the module was removed.
572 */
573bool mei_cl_bus_module_get(struct mei_cl *cl)
574{
575 struct mei_cl_device *cldev = cl->cldev;
576
577 if (!cldev)
578 return true;
579
580 return try_module_get(cldev->bus->dev->driver->owner);
581}
582
583/**
584 * mei_cl_bus_module_put - release the underlying hw module.
585 *
586 * @cl: host client
587 */
588void mei_cl_bus_module_put(struct mei_cl *cl)
589{
590 struct mei_cl_device *cldev = cl->cldev;
591
592 if (cldev)
593 module_put(cldev->bus->dev->driver->owner);
594}
595
596/**615/**
597 * mei_cl_device_find - find matching entry in the driver id table616 * mei_cl_device_find - find matching entry in the driver id table
598 *617 *
drivers/misc/mei/client.c+50−37
@@ -349,6 +349,36 @@ void mei_io_cb_free(struct mei_cl_cb *cb) · 348 unmodified lines
349 kfree(cb);349 kfree(cb);
350}350}
351 351
352/**
353 * mei_tx_cb_queue - queue tx callback
354 *
355 * Locking: called under "dev->device_lock" lock
356 *
357 * @cb: mei callback struct
358 * @head: an instance of list to queue on
359 */
360static inline void mei_tx_cb_enqueue(struct mei_cl_cb *cb,
361 struct list_head *head)
362{
363 list_add_tail(&cb->list, head);
364 cb->cl->tx_cb_queued++;
365}
366
367/**
368 * mei_tx_cb_dequeue - dequeue tx callback
369 *
370 * Locking: called under "dev->device_lock" lock
371 *
372 * @cb: mei callback struct to dequeue and free
373 */
374static inline void mei_tx_cb_dequeue(struct mei_cl_cb *cb)
375{
376 if (!WARN_ON(cb->cl->tx_cb_queued == 0))
377 cb->cl->tx_cb_queued--;
378
379 mei_io_cb_free(cb);
380}
381
352/**382/**
353 * mei_io_cb_init - allocate and initialize io callback383 * mei_io_cb_init - allocate and initialize io callback
354 *384 *
@@ -377,49 +407,37 @@ static struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, · 22 unmodified lines
377}407}
378 408
379/**409/**
380 * __mei_io_list_flush_cl - removes and frees cbs belonging to cl.410 * mei_io_list_flush_cl - removes cbs belonging to the cl.
381 *411 *
382 * @head: an instance of our list structure412 * @head: an instance of our list structure
383 * @cl: host client, can be NULL for flushing the whole list413 * @cl: host client
384 * @free: whether to free the cbs
385 */414 */
386static void __mei_io_list_flush_cl(struct list_head *head,415static void mei_io_list_flush_cl(struct list_head *head,
387 const struct mei_cl *cl, bool free)416 const struct mei_cl *cl)
388{417{
389 struct mei_cl_cb *cb, *next;418 struct mei_cl_cb *cb, *next;
390 419
391 /* enable removing everything if no cl is specified */
392 list_for_each_entry_safe(cb, next, head, list) {420 list_for_each_entry_safe(cb, next, head, list) {
393 if (!cl || mei_cl_cmp_id(cl, cb->cl)) {421 if (mei_cl_cmp_id(cl, cb->cl))
394 list_del_init(&cb->list);422 list_del_init(&cb->list);
395 if (free)
396 mei_io_cb_free(cb);
397 }
398 }423 }
399}424}
400 425
401/**426/**
402 * mei_io_list_flush_cl - removes list entry belonging to cl.427 * mei_io_tx_list_free_cl - removes cb belonging to the cl and free them
403 *428 *
404 * @head: An instance of our list structure429 * @head: An instance of our list structure
405 * @cl: host client430 * @cl: host client
406 */431 */
407static inline void mei_io_list_flush_cl(struct list_head *head,432static void mei_io_tx_list_free_cl(struct list_head *head,
408 const struct mei_cl *cl)433 const struct mei_cl *cl)
409{434{
410 __mei_io_list_flush_cl(head, cl, false);435 struct mei_cl_cb *cb, *next;
411}
412 436
413/**437 list_for_each_entry_safe(cb, next, head, list) {
414 * mei_io_list_free_cl - removes cb belonging to cl and free them438 if (mei_cl_cmp_id(cl, cb->cl))
415 *439 mei_tx_cb_dequeue(cb);
416 * @head: An instance of our list structure440 }
417 * @cl: host client
418 */
419static inline void mei_io_list_free_cl(struct list_head *head,
420 const struct mei_cl *cl)
421{
422 __mei_io_list_flush_cl(head, cl, true);
423}441}
424 442
425/**443/**
@@ -538,8 +556,8 @@ int mei_cl_flush_queues(struct mei_cl *cl, const struct file *fp) · 112 unmodified lines
538 dev = cl->dev;556 dev = cl->dev;
539 557
540 cl_dbg(dev, cl, "remove list entry belonging to cl\n");558 cl_dbg(dev, cl, "remove list entry belonging to cl\n");
541 mei_io_list_free_cl(&cl->dev->write_list, cl);559 mei_io_tx_list_free_cl(&cl->dev->write_list, cl);
542 mei_io_list_free_cl(&cl->dev->write_waiting_list, cl);560 mei_io_tx_list_free_cl(&cl->dev->write_waiting_list, cl);
543 mei_io_list_flush_cl(&cl->dev->ctrl_wr_list, cl);561 mei_io_list_flush_cl(&cl->dev->ctrl_wr_list, cl);
544 mei_io_list_flush_cl(&cl->dev->ctrl_rd_list, cl);562 mei_io_list_flush_cl(&cl->dev->ctrl_rd_list, cl);
545 mei_io_list_free_fp(&cl->rd_pending, fp);563 mei_io_list_free_fp(&cl->rd_pending, fp);
@@ -756,8 +774,8 @@ static void mei_cl_set_disconnected(struct mei_cl *cl) · 210 unmodified lines
756 return;774 return;
757 775
758 cl->state = MEI_FILE_DISCONNECTED;776 cl->state = MEI_FILE_DISCONNECTED;
759 mei_io_list_free_cl(&dev->write_list, cl);777 mei_io_tx_list_free_cl(&dev->write_list, cl);
760 mei_io_list_free_cl(&dev->write_waiting_list, cl);778 mei_io_tx_list_free_cl(&dev->write_waiting_list, cl);
761 mei_io_list_flush_cl(&dev->ctrl_rd_list, cl);779 mei_io_list_flush_cl(&dev->ctrl_rd_list, cl);
762 mei_io_list_flush_cl(&dev->ctrl_wr_list, cl);780 mei_io_list_flush_cl(&dev->ctrl_wr_list, cl);
763 mei_cl_wake_all(cl);781 mei_cl_wake_all(cl);
@@ -765,8 +783,6 @@ static void mei_cl_set_disconnected(struct mei_cl *cl) · 1 unmodified line
765 cl->tx_flow_ctrl_creds = 0;783 cl->tx_flow_ctrl_creds = 0;
766 cl->timer_count = 0;784 cl->timer_count = 0;
767 785
768 mei_cl_bus_module_put(cl);
769
770 if (!cl->me_cl)786 if (!cl->me_cl)
771 return;787 return;
772 788
@@ -1076,9 +1092,6 @@ int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl, · 303 unmodified lines
1076 1092
1077 dev = cl->dev;1093 dev = cl->dev;
1078 1094
1079 if (!mei_cl_bus_module_get(cl))
1080 return -ENODEV;
1081
1082 rets = mei_cl_set_connecting(cl, me_cl);1095 rets = mei_cl_set_connecting(cl, me_cl);
1083 if (rets)1096 if (rets)
1084 goto nortpm;1097 goto nortpm;
@@ -1698,9 +1711,9 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb) · 613 unmodified lines
1698 1711
1699out:1712out:
1700 if (mei_hdr.msg_complete)1713 if (mei_hdr.msg_complete)
1701 list_add_tail(&cb->list, &dev->write_waiting_list);1714 mei_tx_cb_enqueue(cb, &dev->write_waiting_list);
1702 else1715 else
1703 list_add_tail(&cb->list, &dev->write_list);1716 mei_tx_cb_enqueue(cb, &dev->write_list);
1704 1717
1705 cb = NULL;1718 cb = NULL;
1706 if (blocking && cl->writing_state != MEI_WRITE_COMPLETE) {1719 if (blocking && cl->writing_state != MEI_WRITE_COMPLETE) {
@@ -1746,7 +1759,7 @@ void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb) · 39 unmodified lines
1746 1759
1747 switch (cb->fop_type) {1760 switch (cb->fop_type) {
1748 case MEI_FOP_WRITE:1761 case MEI_FOP_WRITE:
1749 mei_io_cb_free(cb);1762 mei_tx_cb_dequeue(cb);
1750 cl->writing_state = MEI_WRITE_COMPLETE;1763 cl->writing_state = MEI_WRITE_COMPLETE;
1751 if (waitqueue_active(&cl->tx_wait)) {1764 if (waitqueue_active(&cl->tx_wait)) {
1752 wake_up_interruptible(&cl->tx_wait);1765 wake_up_interruptible(&cl->tx_wait);
drivers/misc/mei/debugfs.c+4−3
@@ -97,7 +97,7 @@ static ssize_t mei_dbgfs_read_active(struct file *fp, char __user *ubuf, · 96 unmodified lines
97 int pos = 0;97 int pos = 0;
98 int ret;98 int ret;
99 99
100#define HDR " |me|host|state|rd|wr|\n"100#define HDR " |me|host|state|rd|wr|wrq\n"
101 101
102 if (!dev)102 if (!dev)
103 return -ENODEV;103 return -ENODEV;
@@ -130,9 +130,10 @@ static ssize_t mei_dbgfs_read_active(struct file *fp, char __user *ubuf, · 26 unmodified lines
130 list_for_each_entry(cl, &dev->file_list, link) {130 list_for_each_entry(cl, &dev->file_list, link) {
131 131
132 pos += scnprintf(buf + pos, bufsz - pos,132 pos += scnprintf(buf + pos, bufsz - pos,
133 "%3d|%2d|%4d|%5d|%2d|%2d|\n",133 "%3d|%2d|%4d|%5d|%2d|%2d|%3u\n",
134 i, mei_cl_me_id(cl), cl->host_client_id, cl->state,134 i, mei_cl_me_id(cl), cl->host_client_id, cl->state,
135 !list_empty(&cl->rd_completed), cl->writing_state);135 !list_empty(&cl->rd_completed), cl->writing_state,
136 cl->tx_cb_queued);
136 i++;137 i++;
137 }138 }
138out:139out:
drivers/misc/mei/init.c+1−0
@@ -383,6 +383,7 @@ void mei_device_init(struct mei_device *dev, · 382 unmodified lines
383 INIT_LIST_HEAD(&dev->write_waiting_list);383 INIT_LIST_HEAD(&dev->write_waiting_list);
384 INIT_LIST_HEAD(&dev->ctrl_wr_list);384 INIT_LIST_HEAD(&dev->ctrl_wr_list);
385 INIT_LIST_HEAD(&dev->ctrl_rd_list);385 INIT_LIST_HEAD(&dev->ctrl_rd_list);
386 dev->tx_queue_limit = MEI_TX_QUEUE_LIMIT_DEFAULT;
386 387
387 INIT_DELAYED_WORK(&dev->timer_work, mei_timer);388 INIT_DELAYED_WORK(&dev->timer_work, mei_timer);
388 INIT_WORK(&dev->reset_work, mei_reset_work);389 INIT_WORK(&dev->reset_work, mei_reset_work);
drivers/misc/mei/main.c+65−1
@@ -291,6 +291,27 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, · 290 unmodified lines
291 goto out;291 goto out;
292 }292 }
293 293
294 while (cl->tx_cb_queued >= dev->tx_queue_limit) {
295 if (file->f_flags & O_NONBLOCK) {
296 rets = -EAGAIN;
297 goto out;
298 }
299 mutex_unlock(&dev->device_lock);
300 rets = wait_event_interruptible(cl->tx_wait,
301 cl->writing_state == MEI_WRITE_COMPLETE ||
302 (!mei_cl_is_connected(cl)));
303 mutex_lock(&dev->device_lock);
304 if (rets) {
305 if (signal_pending(current))
306 rets = -EINTR;
307 goto out;
308 }
309 if (!mei_cl_is_connected(cl)) {
310 rets = -ENODEV;
311 goto out;
312 }
313 }
314
294 *offset = 0;315 *offset = 0;
295 cb = mei_cl_alloc_cb(cl, length, MEI_FOP_WRITE, file);316 cb = mei_cl_alloc_cb(cl, length, MEI_FOP_WRITE, file);
296 if (!cb) {317 if (!cb) {
@@ -507,7 +528,6 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data) · 210 unmodified lines
507 break;528 break;
508 529
509 default:530 default:
510 dev_err(dev->dev, ": unsupported ioctl %d.\n", cmd);
511 rets = -ENOIOCTLCMD;531 rets = -ENOIOCTLCMD;
512 }532 }
513 533
@@ -580,6 +600,12 @@ static __poll_t mei_poll(struct file *file, poll_table *wait) · 66 unmodified lines
580 mei_cl_read_start(cl, mei_cl_mtu(cl), file);600 mei_cl_read_start(cl, mei_cl_mtu(cl), file);
581 }601 }
582 602
603 if (req_events & (POLLOUT | POLLWRNORM)) {
604 poll_wait(file, &cl->tx_wait, wait);
605 if (cl->tx_cb_queued < dev->tx_queue_limit)
606 mask |= POLLOUT | POLLWRNORM;
607 }
608
583out:609out:
584 mutex_unlock(&dev->device_lock);610 mutex_unlock(&dev->device_lock);
585 return mask;611 return mask;
@@ -749,10 +775,48 @@ static ssize_t hbm_ver_drv_show(struct device *device, · 163 unmodified lines
749}775}
750static DEVICE_ATTR_RO(hbm_ver_drv);776static DEVICE_ATTR_RO(hbm_ver_drv);
751 777
778static ssize_t tx_queue_limit_show(struct device *device,
779 struct device_attribute *attr, char *buf)
780{
781 struct mei_device *dev = dev_get_drvdata(device);
782 u8 size = 0;
783
784 mutex_lock(&dev->device_lock);
785 size = dev->tx_queue_limit;
786 mutex_unlock(&dev->device_lock);
787
788 return snprintf(buf, PAGE_SIZE, "%u\n", size);
789}
790
791static ssize_t tx_queue_limit_store(struct device *device,
792 struct device_attribute *attr,
793 const char *buf, size_t count)
794{
795 struct mei_device *dev = dev_get_drvdata(device);
796 u8 limit;
797 unsigned int inp;
798 int err;
799
800 err = kstrtouint(buf, 10, &inp);
801 if (err)
802 return err;
803 if (inp > MEI_TX_QUEUE_LIMIT_MAX || inp < MEI_TX_QUEUE_LIMIT_MIN)
804 return -EINVAL;
805 limit = inp;
806
807 mutex_lock(&dev->device_lock);
808 dev->tx_queue_limit = limit;
809 mutex_unlock(&dev->device_lock);
810
811 return count;
812}
813static DEVICE_ATTR_RW(tx_queue_limit);
814
752static struct attribute *mei_attrs[] = {815static struct attribute *mei_attrs[] = {
753 &dev_attr_fw_status.attr,816 &dev_attr_fw_status.attr,
754 &dev_attr_hbm_ver.attr,817 &dev_attr_hbm_ver.attr,
755 &dev_attr_hbm_ver_drv.attr,818 &dev_attr_hbm_ver_drv.attr,
819 &dev_attr_tx_queue_limit.attr,
756 NULL820 NULL
757};821};
758ATTRIBUTE_GROUPS(mei);822ATTRIBUTE_GROUPS(mei);
drivers/misc/mei/mei_dev.h+8−2
@@ -210,6 +210,7 @@ struct mei_cl_cb { · 209 unmodified lines
210 * @timer_count: watchdog timer for operation completion210 * @timer_count: watchdog timer for operation completion
211 * @notify_en: notification - enabled/disabled211 * @notify_en: notification - enabled/disabled
212 * @notify_ev: pending notification event212 * @notify_ev: pending notification event
213 * @tx_cb_queued: number of tx callbacks in queue
213 * @writing_state: state of the tx214 * @writing_state: state of the tx
214 * @rd_pending: pending read credits215 * @rd_pending: pending read credits
215 * @rd_completed: completed read216 * @rd_completed: completed read
@@ -234,6 +235,7 @@ struct mei_cl { · 18 unmodified lines
234 u8 timer_count;235 u8 timer_count;
235 u8 notify_en;236 u8 notify_en;
236 u8 notify_ev;237 u8 notify_ev;
238 u8 tx_cb_queued;
237 enum mei_file_transaction_states writing_state;239 enum mei_file_transaction_states writing_state;
238 struct list_head rd_pending;240 struct list_head rd_pending;
239 struct list_head rd_completed;241 struct list_head rd_completed;
@@ -241,6 +243,10 @@ struct mei_cl { · 1 unmodified line
241 struct mei_cl_device *cldev;243 struct mei_cl_device *cldev;
242};244};
243 245
246#define MEI_TX_QUEUE_LIMIT_DEFAULT 50
247#define MEI_TX_QUEUE_LIMIT_MAX 255
248#define MEI_TX_QUEUE_LIMIT_MIN 30
249
244/**250/**
245 * struct mei_hw_ops - hw specific ops251 * struct mei_hw_ops - hw specific ops
246 *252 *
@@ -315,8 +321,6 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, · 68 unmodified lines
315bool mei_cl_bus_rx_event(struct mei_cl *cl);321bool mei_cl_bus_rx_event(struct mei_cl *cl);
316bool mei_cl_bus_notify_event(struct mei_cl *cl);322bool mei_cl_bus_notify_event(struct mei_cl *cl);
317void mei_cl_bus_remove_devices(struct mei_device *bus);323void mei_cl_bus_remove_devices(struct mei_device *bus);
318bool mei_cl_bus_module_get(struct mei_cl *cl);
319void mei_cl_bus_module_put(struct mei_cl *cl);
320int mei_cl_bus_init(void);324int mei_cl_bus_init(void);
321void mei_cl_bus_exit(void);325void mei_cl_bus_exit(void);
322 326
@@ -361,6 +365,7 @@ const char *mei_pg_state_str(enum mei_pg_state state); · 38 unmodified lines
361 * @write_waiting_list : write completion list365 * @write_waiting_list : write completion list
362 * @ctrl_wr_list : pending control write list366 * @ctrl_wr_list : pending control write list
363 * @ctrl_rd_list : pending control read list367 * @ctrl_rd_list : pending control read list
368 * @tx_queue_limit: tx queues per client linit
364 *369 *
365 * @file_list : list of opened handles370 * @file_list : list of opened handles
366 * @open_handle_count: number of opened handles371 * @open_handle_count: number of opened handles
@@ -425,6 +430,7 @@ struct mei_device { · 58 unmodified lines
425 struct list_head write_waiting_list;430 struct list_head write_waiting_list;
426 struct list_head ctrl_wr_list;431 struct list_head ctrl_wr_list;
427 struct list_head ctrl_rd_list;432 struct list_head ctrl_rd_list;
433 u8 tx_queue_limit;
428 434
429 struct list_head file_list;435 struct list_head file_list;
430 long open_handle_count;436 long open_handle_count;
drivers/misc/mic/bus/vop_bus.c+4−2
@@ -135,7 +135,9 @@ EXPORT_SYMBOL_GPL(vop_unregister_driver); · 134 unmodified lines
135 135
136static void vop_release_dev(struct device *d)136static void vop_release_dev(struct device *d)
137{137{
138 put_device(d);138 struct vop_device *dev = dev_to_vop(d);
139
140 kfree(dev);
139}141}
140 142
141struct vop_device *143struct vop_device *
@@ -174,7 +176,7 @@ vop_register_device(struct device *pdev, int id, · 32 unmodified lines
174 goto free_vdev;176 goto free_vdev;
175 return vdev;177 return vdev;
176free_vdev:178free_vdev:
177 kfree(vdev);179 put_device(&vdev->dev);
178 return ERR_PTR(ret);180 return ERR_PTR(ret);
179}181}
180EXPORT_SYMBOL_GPL(vop_register_device);182EXPORT_SYMBOL_GPL(vop_register_device);
drivers/misc/ocxl/pci.c+1−1
@@ -519,7 +519,7 @@ static struct ocxl_fn *init_function(struct pci_dev *dev) · 518 unmodified lines
519 rc = device_register(&fn->dev);519 rc = device_register(&fn->dev);
520 if (rc) {520 if (rc) {
521 deconfigure_function(fn);521 deconfigure_function(fn);
522 device_unregister(&fn->dev);522 put_device(&fn->dev);
523 return ERR_PTR(rc);523 return ERR_PTR(rc);
524 }524 }
525 return fn;525 return fn;
drivers/nvmem/Kconfig+2−2
@@ -167,10 +167,10 @@ config MESON_MX_EFUSE · 166 unmodified lines
167 167
168config NVMEM_SNVS_LPGPR168config NVMEM_SNVS_LPGPR
169 tristate "Support for Low Power General Purpose Register"169 tristate "Support for Low Power General Purpose Register"
170 depends on SOC_IMX6 || COMPILE_TEST170 depends on SOC_IMX6 || SOC_IMX7D || COMPILE_TEST
171 help171 help
172 This is a driver for Low Power General Purpose Register (LPGPR) available on172 This is a driver for Low Power General Purpose Register (LPGPR) available on
173 i.MX6 SoCs in Secure Non-Volatile Storage (SNVS) of this chip.173 i.MX6 and i.MX7 SoCs in Secure Non-Volatile Storage (SNVS) of this chip.
174 174
175 This driver can also be built as a module. If so, the module175 This driver can also be built as a module. If so, the module
176 will be called nvmem-snvs-lpgpr.176 will be called nvmem-snvs-lpgpr.
drivers/nvmem/bcm-ocotp.c+2−13
@@ -262,8 +262,7 @@ static int bcm_otpc_probe(struct platform_device *pdev) · 261 unmodified lines
262 else if (of_device_is_compatible(dev->of_node, "brcm,ocotp-v2"))262 else if (of_device_is_compatible(dev->of_node, "brcm,ocotp-v2"))
263 priv->map = &otp_map_v2;263 priv->map = &otp_map_v2;
264 else {264 else {
265 dev_err(&pdev->dev,265 dev_err(dev, "%s otpc config map not defined\n", __func__);
266 "%s otpc config map not defined\n", __func__);
267 return -EINVAL;266 return -EINVAL;
268 }267 }
269 268
@@ -302,27 +301,17 @@ static int bcm_otpc_probe(struct platform_device *pdev) · 32 unmodified lines
302 301
303 priv->config = &bcm_otpc_nvmem_config;302 priv->config = &bcm_otpc_nvmem_config;
304 303
305 nvmem = nvmem_register(&bcm_otpc_nvmem_config);304 nvmem = devm_nvmem_register(dev, &bcm_otpc_nvmem_config);
306 if (IS_ERR(nvmem)) {305 if (IS_ERR(nvmem)) {
307 dev_err(dev, "error registering nvmem config\n");306 dev_err(dev, "error registering nvmem config\n");
308 return PTR_ERR(nvmem);307 return PTR_ERR(nvmem);
309 }308 }
310 309
311 platform_set_drvdata(pdev, nvmem);
312
313 return 0;310 return 0;
314}311}
315 312
316static int bcm_otpc_remove(struct platform_device *pdev)
317{
318 struct nvmem_device *nvmem = platform_get_drvdata(pdev);
319
320 return nvmem_unregister(nvmem);
321}
322
323static struct platform_driver bcm_otpc_driver = {313static struct platform_driver bcm_otpc_driver = {
324 .probe = bcm_otpc_probe,314 .probe = bcm_otpc_probe,
325 .remove = bcm_otpc_remove,
326 .driver = {315 .driver = {
327 .name = "brcm-otpc",316 .name = "brcm-otpc",
328 .of_match_table = bcm_otpc_dt_ids,317 .of_match_table = bcm_otpc_dt_ids,
drivers/nvmem/core.c+67−3
@@ -473,9 +473,14 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) · 472 unmodified lines
473 nvmem->reg_read = config->reg_read;473 nvmem->reg_read = config->reg_read;
474 nvmem->reg_write = config->reg_write;474 nvmem->reg_write = config->reg_write;
475 nvmem->dev.of_node = config->dev->of_node;475 nvmem->dev.of_node = config->dev->of_node;
476 dev_set_name(&nvmem->dev, "%s%d",476
477 config->name ? : "nvmem",477 if (config->id == -1 && config->name) {
478 config->name ? config->id : nvmem->id);478 dev_set_name(&nvmem->dev, "%s", config->name);
479 } else {
480 dev_set_name(&nvmem->dev, "%s%d",
481 config->name ? : "nvmem",
482 config->name ? config->id : nvmem->id);
483 }
479 484
480 nvmem->read_only = device_property_present(config->dev, "read-only") |485 nvmem->read_only = device_property_present(config->dev, "read-only") |
481 config->read_only;486 config->read_only;
@@ -544,6 +549,65 @@ int nvmem_unregister(struct nvmem_device *nvmem) · 62 unmodified lines
544}549}
545EXPORT_SYMBOL_GPL(nvmem_unregister);550EXPORT_SYMBOL_GPL(nvmem_unregister);
546 551
552static void devm_nvmem_release(struct device *dev, void *res)
553{
554 WARN_ON(nvmem_unregister(*(struct nvmem_device **)res));
555}
556
557/**
558 * devm_nvmem_register() - Register a managed nvmem device for given
559 * nvmem_config.
560 * Also creates an binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
561 *
562 * @config: nvmem device configuration with which nvmem device is created.
563 *
564 * Return: Will be an ERR_PTR() on error or a valid pointer to nvmem_device
565 * on success.
566 */
567struct nvmem_device *devm_nvmem_register(struct device *dev,
568 const struct nvmem_config *config)
569{
570 struct nvmem_device **ptr, *nvmem;
571
572 ptr = devres_alloc(devm_nvmem_release, sizeof(*ptr), GFP_KERNEL);
573 if (!ptr)
574 return ERR_PTR(-ENOMEM);
575
576 nvmem = nvmem_register(config);
577
578 if (!IS_ERR(nvmem)) {
579 *ptr = nvmem;
580 devres_add(dev, ptr);
581 } else {
582 devres_free(ptr);
583 }
584
585 return nvmem;
586}
587EXPORT_SYMBOL_GPL(devm_nvmem_register);
588
589static int devm_nvmem_match(struct device *dev, void *res, void *data)
590{
591 struct nvmem_device **r = res;
592
593 return *r == data;
594}
595
596/**
597 * devm_nvmem_unregister() - Unregister previously registered managed nvmem
598 * device.
599 *
600 * @nvmem: Pointer to previously registered nvmem device.
601 *
602 * Return: Will be an negative on error or a zero on success.
603 */
604int devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem)
605{
606 return devres_release(dev, devm_nvmem_release, devm_nvmem_match, nvmem);
607}
608EXPORT_SYMBOL(devm_nvmem_unregister);
609
610
547static struct nvmem_device *__nvmem_device_get(struct device_node *np,611static struct nvmem_device *__nvmem_device_get(struct device_node *np,
548 struct nvmem_cell **cellp,612 struct nvmem_cell **cellp,
549 const char *cell_id)613 const char *cell_id)
drivers/nvmem/imx-iim.c+3−15
@@ -125,7 +125,7 @@ static int imx_iim_probe(struct platform_device *pdev) · 124 unmodified lines
125 125
126 drvdata = of_id->data;126 drvdata = of_id->data;
127 127
128 iim->clk = devm_clk_get(&pdev->dev, NULL);128 iim->clk = devm_clk_get(dev, NULL);
129 if (IS_ERR(iim->clk))129 if (IS_ERR(iim->clk))
130 return PTR_ERR(iim->clk);130 return PTR_ERR(iim->clk);
131 131
@@ -138,25 +138,13 @@ static int imx_iim_probe(struct platform_device *pdev) · 6 unmodified lines
138 cfg.size = drvdata->nregs;138 cfg.size = drvdata->nregs;
139 cfg.priv = iim;139 cfg.priv = iim;
140 140
141 nvmem = nvmem_register(&cfg);141 nvmem = devm_nvmem_register(dev, &cfg);
142 if (IS_ERR(nvmem))
143 return PTR_ERR(nvmem);
144 142
145 platform_set_drvdata(pdev, nvmem);143 return PTR_ERR_OR_ZERO(nvmem);
146
147 return 0;
148}
149
150static int imx_iim_remove(struct platform_device *pdev)
151{
152 struct nvmem_device *nvmem = platform_get_drvdata(pdev);
153
154 return nvmem_unregister(nvmem);
155}144}
156 145
157static struct platform_driver imx_iim_driver = {146static struct platform_driver imx_iim_driver = {
158 .probe = imx_iim_probe,147 .probe = imx_iim_probe,
159 .remove = imx_iim_remove,
160 .driver = {148 .driver = {
161 .name = "imx-iim",149 .name = "imx-iim",
162 .of_match_table = imx_iim_dt_ids,150 .of_match_table = imx_iim_dt_ids,
drivers/nvmem/imx-ocotp.c+2−16
@@ -439,7 +439,6 @@ MODULE_DEVICE_TABLE(of, imx_ocotp_dt_ids); · 438 unmodified lines
439 439
440static int imx_ocotp_probe(struct platform_device *pdev)440static int imx_ocotp_probe(struct platform_device *pdev)
441{441{
442 const struct of_device_id *of_id;
443 struct device *dev = &pdev->dev;442 struct device *dev = &pdev->dev;
444 struct resource *res;443 struct resource *res;
445 struct ocotp_priv *priv;444 struct ocotp_priv *priv;
@@ -460,32 +459,19 @@ static int imx_ocotp_probe(struct platform_device *pdev) · 14 unmodified lines
460 if (IS_ERR(priv->clk))459 if (IS_ERR(priv->clk))
461 return PTR_ERR(priv->clk);460 return PTR_ERR(priv->clk);
462 461
463 of_id = of_match_device(imx_ocotp_dt_ids, dev);
464 priv->params = of_device_get_match_data(&pdev->dev);462 priv->params = of_device_get_match_data(&pdev->dev);
465 imx_ocotp_nvmem_config.size = 4 * priv->params->nregs;463 imx_ocotp_nvmem_config.size = 4 * priv->params->nregs;
466 imx_ocotp_nvmem_config.dev = dev;464 imx_ocotp_nvmem_config.dev = dev;
467 imx_ocotp_nvmem_config.priv = priv;465 imx_ocotp_nvmem_config.priv = priv;
468 priv->config = &imx_ocotp_nvmem_config;466 priv->config = &imx_ocotp_nvmem_config;
469 nvmem = nvmem_register(&imx_ocotp_nvmem_config);467 nvmem = devm_nvmem_register(dev, &imx_ocotp_nvmem_config);
470 468
471 if (IS_ERR(nvmem))
472 return PTR_ERR(nvmem);
473 469
474 platform_set_drvdata(pdev, nvmem);470 return PTR_ERR_OR_ZERO(nvmem);
475
476 return 0;
477}
478
479static int imx_ocotp_remove(struct platform_device *pdev)
480{
481 struct nvmem_device *nvmem = platform_get_drvdata(pdev);
482
483 return nvmem_unregister(nvmem);
484}471}
485 472
486static struct platform_driver imx_ocotp_driver = {473static struct platform_driver imx_ocotp_driver = {
487 .probe = imx_ocotp_probe,474 .probe = imx_ocotp_probe,
488 .remove = imx_ocotp_remove,
489 .driver = {475 .driver = {
490 .name = "imx_ocotp",476 .name = "imx_ocotp",
491 .of_match_table = imx_ocotp_dt_ids,477 .of_match_table = imx_ocotp_dt_ids,
drivers/nvmem/lpc18xx_otp.c+2−14
@@ -86,20 +86,9 @@ static int lpc18xx_otp_probe(struct platform_device *pdev) · 85 unmodified lines
86 lpc18xx_otp_nvmem_config.dev = &pdev->dev;86 lpc18xx_otp_nvmem_config.dev = &pdev->dev;
87 lpc18xx_otp_nvmem_config.priv = otp;87 lpc18xx_otp_nvmem_config.priv = otp;
88 88
89 nvmem = nvmem_register(&lpc18xx_otp_nvmem_config);89 nvmem = devm_nvmem_register(&pdev->dev, &lpc18xx_otp_nvmem_config);
90 if (IS_ERR(nvmem))
91 return PTR_ERR(nvmem);
92 90
93 platform_set_drvdata(pdev, nvmem);91 return PTR_ERR_OR_ZERO(nvmem);
94
95 return 0;
96}
97
98static int lpc18xx_otp_remove(struct platform_device *pdev)
99{
100 struct nvmem_device *nvmem = platform_get_drvdata(pdev);
101
102 return nvmem_unregister(nvmem);
103}92}
104 93
105static const struct of_device_id lpc18xx_otp_dt_ids[] = {94static const struct of_device_id lpc18xx_otp_dt_ids[] = {
@@ -110,7 +99,6 @@ MODULE_DEVICE_TABLE(of, lpc18xx_otp_dt_ids); · 4 unmodified lines
110 99
111static struct platform_driver lpc18xx_otp_driver = {100static struct platform_driver lpc18xx_otp_driver = {
112 .probe = lpc18xx_otp_probe,101 .probe = lpc18xx_otp_probe,
113 .remove = lpc18xx_otp_remove,
114 .driver = {102 .driver = {
115 .name = "lpc18xx_otp",103 .name = "lpc18xx_otp",
116 .of_match_table = lpc18xx_otp_dt_ids,104 .of_match_table = lpc18xx_otp_dt_ids,
drivers/nvmem/meson-efuse.c+2−14
@@ -60,25 +60,13 @@ static int meson_efuse_probe(struct platform_device *pdev) · 59 unmodified lines
60 econfig.reg_read = meson_efuse_read;60 econfig.reg_read = meson_efuse_read;
61 econfig.size = size;61 econfig.size = size;
62 62
63 nvmem = nvmem_register(&econfig);63 nvmem = devm_nvmem_register(&pdev->dev, &econfig);
64 if (IS_ERR(nvmem))
65 return PTR_ERR(nvmem);
66 64
67 platform_set_drvdata(pdev, nvmem);65 return PTR_ERR_OR_ZERO(nvmem);
68
69 return 0;
70}
71
72static int meson_efuse_remove(struct platform_device *pdev)
73{
74 struct nvmem_device *nvmem = platform_get_drvdata(pdev);
75
76 return nvmem_unregister(nvmem);
77}66}
78 67
79static struct platform_driver meson_efuse_driver = {68static struct platform_driver meson_efuse_driver = {
80 .probe = meson_efuse_probe,69 .probe = meson_efuse_probe,
81 .remove = meson_efuse_remove,
82 .driver = {70 .driver = {
83 .name = "meson-efuse",71 .name = "meson-efuse",
84 .of_match_table = meson_efuse_match,72 .of_match_table = meson_efuse_match,
drivers/nvmem/meson-mx-efuse.c+2−14
@@ -233,25 +233,13 @@ static int meson_mx_efuse_probe(struct platform_device *pdev) · 232 unmodified lines
233 return PTR_ERR(efuse->core_clk);233 return PTR_ERR(efuse->core_clk);
234 }234 }
235 235
236 efuse->nvmem = nvmem_register(&efuse->config);236 efuse->nvmem = devm_nvmem_register(&pdev->dev, &efuse->config);
237 if (IS_ERR(efuse->nvmem))
238 return PTR_ERR(efuse->nvmem);
239 237
240 platform_set_drvdata(pdev, efuse);238 return PTR_ERR_OR_ZERO(efuse->nvmem);
241
242 return 0;
243}
244
245static int meson_mx_efuse_remove(struct platform_device *pdev)
246{
247 struct meson_mx_efuse *efuse = platform_get_drvdata(pdev);
248
249 return nvmem_unregister(efuse->nvmem);
250}239}
251 240
252static struct platform_driver meson_mx_efuse_driver = {241static struct platform_driver meson_mx_efuse_driver = {
253 .probe = meson_mx_efuse_probe,242 .probe = meson_mx_efuse_probe,
254 .remove = meson_mx_efuse_remove,
255 .driver = {243 .driver = {
256 .name = "meson-mx-efuse",244 .name = "meson-mx-efuse",
257 .of_match_table = meson_mx_efuse_match,245 .of_match_table = meson_mx_efuse_match,
drivers/nvmem/mtk-efuse.c+2−14
@@ -72,20 +72,9 @@ static int mtk_efuse_probe(struct platform_device *pdev) · 71 unmodified lines
72 econfig.size = resource_size(res);72 econfig.size = resource_size(res);
73 econfig.priv = priv;73 econfig.priv = priv;
74 econfig.dev = dev;74 econfig.dev = dev;
75 nvmem = nvmem_register(&econfig);75 nvmem = devm_nvmem_register(dev, &econfig);
76 if (IS_ERR(nvmem))
77 return PTR_ERR(nvmem);
78 76
79 platform_set_drvdata(pdev, nvmem);77 return PTR_ERR_OR_ZERO(nvmem);
80
81 return 0;
82}
83
84static int mtk_efuse_remove(struct platform_device *pdev)
85{
86 struct nvmem_device *nvmem = platform_get_drvdata(pdev);
87
88 return nvmem_unregister(nvmem);
89}78}
90 79
91static const struct of_device_id mtk_efuse_of_match[] = {80static const struct of_device_id mtk_efuse_of_match[] = {
@@ -97,7 +86,6 @@ MODULE_DEVICE_TABLE(of, mtk_efuse_of_match); · 5 unmodified lines
97 86
98static struct platform_driver mtk_efuse_driver = {87static struct platform_driver mtk_efuse_driver = {
99 .probe = mtk_efuse_probe,88 .probe = mtk_efuse_probe,
100 .remove = mtk_efuse_remove,
101 .driver = {89 .driver = {
102 .name = "mediatek,efuse",90 .name = "mediatek,efuse",
103 .of_match_table = mtk_efuse_of_match,91 .of_match_table = mtk_efuse_of_match,
drivers/nvmem/qfprom.c+2−14
@@ -47,13 +47,6 @@ static int qfprom_reg_write(void *context, · 46 unmodified lines
47 return 0;47 return 0;
48}48}
49 49
50static int qfprom_remove(struct platform_device *pdev)
51{
52 struct nvmem_device *nvmem = platform_get_drvdata(pdev);
53
54 return nvmem_unregister(nvmem);
55}
56
57static struct nvmem_config econfig = {50static struct nvmem_config econfig = {
58 .name = "qfprom",51 .name = "qfprom",
59 .stride = 1,52 .stride = 1,
@@ -82,13 +75,9 @@ static int qfprom_probe(struct platform_device *pdev) · 22 unmodified lines
82 econfig.dev = dev;75 econfig.dev = dev;
83 econfig.priv = priv;76 econfig.priv = priv;
84 77
85 nvmem = nvmem_register(&econfig);78 nvmem = devm_nvmem_register(dev, &econfig);
86 if (IS_ERR(nvmem))
87 return PTR_ERR(nvmem);
88
89 platform_set_drvdata(pdev, nvmem);
90 79
91 return 0;80 return PTR_ERR_OR_ZERO(nvmem);
92}81}
93 82
94static const struct of_device_id qfprom_of_match[] = {83static const struct of_device_id qfprom_of_match[] = {
@@ -99,7 +88,6 @@ MODULE_DEVICE_TABLE(of, qfprom_of_match); · 4 unmodified lines
99 88
100static struct platform_driver qfprom_driver = {89static struct platform_driver qfprom_driver = {
101 .probe = qfprom_probe,90 .probe = qfprom_probe,
102 .remove = qfprom_remove,
103 .driver = {91 .driver = {
104 .name = "qcom,qfprom",92 .name = "qcom,qfprom",
105 .of_match_table = qfprom_of_match,93 .of_match_table = qfprom_of_match,
drivers/nvmem/rockchip-efuse.c+10−22
@@ -259,55 +259,43 @@ static int rockchip_efuse_probe(struct platform_device *pdev) · 258 unmodified lines
259 struct resource *res;259 struct resource *res;
260 struct nvmem_device *nvmem;260 struct nvmem_device *nvmem;
261 struct rockchip_efuse_chip *efuse;261 struct rockchip_efuse_chip *efuse;
262 const struct of_device_id *match;262 const void *data;
263 struct device *dev = &pdev->dev;263 struct device *dev = &pdev->dev;
264 264
265 match = of_match_device(dev->driver->of_match_table, dev);265 data = of_device_get_match_data(dev);
266 if (!match || !match->data) {266 if (!data) {
267 dev_err(dev, "failed to get match data\n");267 dev_err(dev, "failed to get match data\n");
268 return -EINVAL;268 return -EINVAL;
269 }269 }
270 270
271 efuse = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_efuse_chip),271 efuse = devm_kzalloc(dev, sizeof(struct rockchip_efuse_chip),
272 GFP_KERNEL);272 GFP_KERNEL);
273 if (!efuse)273 if (!efuse)
274 return -ENOMEM;274 return -ENOMEM;
275 275
276 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);276 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
277 efuse->base = devm_ioremap_resource(&pdev->dev, res);277 efuse->base = devm_ioremap_resource(dev, res);
278 if (IS_ERR(efuse->base))278 if (IS_ERR(efuse->base))
279 return PTR_ERR(efuse->base);279 return PTR_ERR(efuse->base);
280 280
281 efuse->clk = devm_clk_get(&pdev->dev, "pclk_efuse");281 efuse->clk = devm_clk_get(dev, "pclk_efuse");
282 if (IS_ERR(efuse->clk))282 if (IS_ERR(efuse->clk))
283 return PTR_ERR(efuse->clk);283 return PTR_ERR(efuse->clk);
284 284
285 efuse->dev = &pdev->dev;285 efuse->dev = dev;
286 if (of_property_read_u32(dev->of_node, "rockchip,efuse-size",286 if (of_property_read_u32(dev->of_node, "rockchip,efuse-size",
287 &econfig.size))287 &econfig.size))
288 econfig.size = resource_size(res);288 econfig.size = resource_size(res);
289 econfig.reg_read = match->data;289 econfig.reg_read = data;
290 econfig.priv = efuse;290 econfig.priv = efuse;
291 econfig.dev = efuse->dev;291 econfig.dev = efuse->dev;
292 nvmem = nvmem_register(&econfig);292 nvmem = devm_nvmem_register(dev, &econfig);
293 if (IS_ERR(nvmem))
294 return PTR_ERR(nvmem);
295 293
296 platform_set_drvdata(pdev, nvmem);294 return PTR_ERR_OR_ZERO(nvmem);
297
298 return 0;
299}
300
301static int rockchip_efuse_remove(struct platform_device *pdev)
302{
303 struct nvmem_device *nvmem = platform_get_drvdata(pdev);
304
305 return nvmem_unregister(nvmem);
306}295}
307 296
308static struct platform_driver rockchip_efuse_driver = {297static struct platform_driver rockchip_efuse_driver = {
309 .probe = rockchip_efuse_probe,298 .probe = rockchip_efuse_probe,
310 .remove = rockchip_efuse_remove,
311 .driver = {299 .driver = {
312 .name = "rockchip-efuse",300 .name = "rockchip-efuse",
313 .of_match_table = rockchip_efuse_match,301 .of_match_table = rockchip_efuse_match,
drivers/nvmem/snvs_lpgpr.c+28−25
@@ -14,15 +14,21 @@ · 13 unmodified lines
14#include <linux/regmap.h>14#include <linux/regmap.h>
15 15
16#define IMX6Q_SNVS_HPLR 0x0016#define IMX6Q_SNVS_HPLR 0x00
17#define IMX6Q_GPR_SL BIT(5)
18#define IMX6Q_SNVS_LPLR 0x3417#define IMX6Q_SNVS_LPLR 0x34
19#define IMX6Q_GPR_HL BIT(5)
20#define IMX6Q_SNVS_LPGPR 0x6818#define IMX6Q_SNVS_LPGPR 0x68
21 19
20#define IMX7D_SNVS_HPLR 0x00
21#define IMX7D_SNVS_LPLR 0x34
22#define IMX7D_SNVS_LPGPR 0x90
23
24#define IMX_GPR_SL BIT(5)
25#define IMX_GPR_HL BIT(5)
26
22struct snvs_lpgpr_cfg {27struct snvs_lpgpr_cfg {
23 int offset;28 int offset;
24 int offset_hplr;29 int offset_hplr;
25 int offset_lplr;30 int offset_lplr;
31 int size;
26};32};
27 33
28struct snvs_lpgpr_priv {34struct snvs_lpgpr_priv {
@@ -36,6 +42,14 @@ static const struct snvs_lpgpr_cfg snvs_lpgpr_cfg_imx6q = { · 7 unmodified lines
36 .offset = IMX6Q_SNVS_LPGPR,42 .offset = IMX6Q_SNVS_LPGPR,
37 .offset_hplr = IMX6Q_SNVS_HPLR,43 .offset_hplr = IMX6Q_SNVS_HPLR,
38 .offset_lplr = IMX6Q_SNVS_LPLR,44 .offset_lplr = IMX6Q_SNVS_LPLR,
45 .size = 4,
46};
47
48static const struct snvs_lpgpr_cfg snvs_lpgpr_cfg_imx7d = {
49 .offset = IMX7D_SNVS_LPGPR,
50 .offset_hplr = IMX7D_SNVS_HPLR,
51 .offset_lplr = IMX7D_SNVS_LPLR,
52 .size = 16,
39};53};
40 54
41static int snvs_lpgpr_write(void *context, unsigned int offset, void *val,55static int snvs_lpgpr_write(void *context, unsigned int offset, void *val,
@@ -50,14 +64,14 @@ static int snvs_lpgpr_write(void *context, unsigned int offset, void *val, · 8 unmodified lines
50 if (ret < 0)64 if (ret < 0)
51 return ret;65 return ret;
52 66
53 if (lock_reg & IMX6Q_GPR_SL)67 if (lock_reg & IMX_GPR_SL)
54 return -EPERM;68 return -EPERM;
55 69
56 ret = regmap_read(priv->regmap, dcfg->offset_lplr, &lock_reg);70 ret = regmap_read(priv->regmap, dcfg->offset_lplr, &lock_reg);
57 if (ret < 0)71 if (ret < 0)
58 return ret;72 return ret;
59 73
60 if (lock_reg & IMX6Q_GPR_HL)74 if (lock_reg & IMX_GPR_HL)
61 return -EPERM;75 return -EPERM;
62 76
63 return regmap_bulk_write(priv->regmap, dcfg->offset + offset, val,77 return regmap_bulk_write(priv->regmap, dcfg->offset + offset, val,
@@ -110,40 +124,29 @@ static int snvs_lpgpr_probe(struct platform_device *pdev) · 46 unmodified lines
110 cfg->priv = priv;124 cfg->priv = priv;
111 cfg->name = dev_name(dev);125 cfg->name = dev_name(dev);
112 cfg->dev = dev;126 cfg->dev = dev;
113 cfg->stride = 4,127 cfg->stride = 4;
114 cfg->word_size = 4,128 cfg->word_size = 4;
115 cfg->size = 4,129 cfg->size = dcfg->size,
116 cfg->owner = THIS_MODULE,130 cfg->owner = THIS_MODULE;
117 cfg->reg_read = snvs_lpgpr_read,131 cfg->reg_read = snvs_lpgpr_read;
118 cfg->reg_write = snvs_lpgpr_write,132 cfg->reg_write = snvs_lpgpr_write;
119
120 nvmem = nvmem_register(cfg);
121 if (IS_ERR(nvmem))
122 return PTR_ERR(nvmem);
123 133
124 platform_set_drvdata(pdev, nvmem);134 nvmem = devm_nvmem_register(dev, cfg);
125
126 return 0;
127}
128
129static int snvs_lpgpr_remove(struct platform_device *pdev)
130{
131 struct nvmem_device *nvmem = platform_get_drvdata(pdev);
132 135
133 return nvmem_unregister(nvmem);136 return PTR_ERR_OR_ZERO(nvmem);
134}137}
135 138
136static const struct of_device_id snvs_lpgpr_dt_ids[] = {139static const struct of_device_id snvs_lpgpr_dt_ids[] = {
137 { .compatible = "fsl,imx6q-snvs-lpgpr", .data = &snvs_lpgpr_cfg_imx6q },140 { .compatible = "fsl,imx6q-snvs-lpgpr", .data = &snvs_lpgpr_cfg_imx6q },
138 { .compatible = "fsl,imx6ul-snvs-lpgpr",141 { .compatible = "fsl,imx6ul-snvs-lpgpr",
139 .data = &snvs_lpgpr_cfg_imx6q },142 .data = &snvs_lpgpr_cfg_imx6q },
143 { .compatible = "fsl,imx7d-snvs-lpgpr", .data = &snvs_lpgpr_cfg_imx7d },
140 { },144 { },
141};145};
142MODULE_DEVICE_TABLE(of, snvs_lpgpr_dt_ids);146MODULE_DEVICE_TABLE(of, snvs_lpgpr_dt_ids);
143 147
144static struct platform_driver snvs_lpgpr_driver = {148static struct platform_driver snvs_lpgpr_driver = {
145 .probe = snvs_lpgpr_probe,149 .probe = snvs_lpgpr_probe,
146 .remove = snvs_lpgpr_remove,
147 .driver = {150 .driver = {
148 .name = "snvs_lpgpr",151 .name = "snvs_lpgpr",
149 .of_match_table = snvs_lpgpr_dt_ids,152 .of_match_table = snvs_lpgpr_dt_ids,
@@ -152,5 +155,5 @@ static struct platform_driver snvs_lpgpr_driver = { · 2 unmodified lines
152module_platform_driver(snvs_lpgpr_driver);155module_platform_driver(snvs_lpgpr_driver);
153 156
154MODULE_AUTHOR("Oleksij Rempel <o.rempel@pengutronix.de>");157MODULE_AUTHOR("Oleksij Rempel <o.rempel@pengutronix.de>");
155MODULE_DESCRIPTION("Low Power General Purpose Register in i.MX6 Secure Non-Volatile Storage");158MODULE_DESCRIPTION("Low Power General Purpose Register in i.MX6 and i.MX7 Secure Non-Volatile Storage");
156MODULE_LICENSE("GPL v2");159MODULE_LICENSE("GPL v2");
drivers/nvmem/sunxi_sid.c+50−21
@@ -85,13 +85,14 @@ static int sunxi_sid_read(void *context, unsigned int offset, · 84 unmodified lines
85}85}
86 86
87static int sun8i_sid_register_readout(const struct sunxi_sid *sid,87static int sun8i_sid_register_readout(const struct sunxi_sid *sid,
88 const unsigned int word)88 const unsigned int offset,
89 u32 *out)
89{90{
90 u32 reg_val;91 u32 reg_val;
91 int ret;92 int ret;
92 93
93 /* Set word, lock access, and set read command */94 /* Set word, lock access, and set read command */
94 reg_val = (word & SUN8I_SID_OFFSET_MASK)95 reg_val = (offset & SUN8I_SID_OFFSET_MASK)
95 << SUN8I_SID_OFFSET_SHIFT;96 << SUN8I_SID_OFFSET_SHIFT;
96 reg_val |= SUN8I_SID_OP_LOCK | SUN8I_SID_READ;97 reg_val |= SUN8I_SID_OP_LOCK | SUN8I_SID_READ;
97 writel(reg_val, sid->base + SUN8I_SID_PRCTL);98 writel(reg_val, sid->base + SUN8I_SID_PRCTL);
@@ -101,7 +102,49 @@ static int sun8i_sid_register_readout(const struct sunxi_sid *sid, · 3 unmodified lines
101 if (ret)102 if (ret)
102 return ret;103 return ret;
103 104
105 if (out)
106 *out = readl(sid->base + SUN8I_SID_RDKEY);
107
104 writel(0, sid->base + SUN8I_SID_PRCTL);108 writel(0, sid->base + SUN8I_SID_PRCTL);
109
110 return 0;
111}
112
113/*
114 * On Allwinner H3, the value on the 0x200 offset of the SID controller seems
115 * to be not reliable at all.
116 * Read by the registers instead.
117 */
118static int sun8i_sid_read_byte_by_reg(const struct sunxi_sid *sid,
119 const unsigned int offset,
120 u8 *out)
121{
122 u32 word;
123 int ret;
124
125 ret = sun8i_sid_register_readout(sid, offset & ~0x03, &word);
126
127 if (ret)
128 return ret;
129
130 *out = (word >> ((offset & 0x3) * 8)) & 0xff;
131
132 return 0;
133}
134
135static int sun8i_sid_read_by_reg(void *context, unsigned int offset,
136 void *val, size_t bytes)
137{
138 struct sunxi_sid *sid = context;
139 u8 *buf = val;
140 int ret;
141
142 while (bytes--) {
143 ret = sun8i_sid_read_byte_by_reg(sid, offset++, buf++);
144 if (ret)
145 return ret;
146 }
147
105 return 0;148 return 0;
106}149}
107 150
@@ -131,26 +174,12 @@ static int sunxi_sid_probe(struct platform_device *pdev) · 23 unmodified lines
131 174
132 size = cfg->size;175 size = cfg->size;
133 176
134 if (cfg->need_register_readout) {
135 /*
136 * H3's SID controller have a bug that the value at 0x200
137 * offset is not the correct value when the hardware is reseted.
138 * However, after doing a register-based read operation, the
139 * value become right.
140 * Do a full read operation here, but ignore its value
141 * (as it's more fast to read by direct MMIO value than
142 * with registers)
143 */
144 for (i = 0; i < (size >> 2); i++) {
145 ret = sun8i_sid_register_readout(sid, i);
146 if (ret)
147 return ret;
148 }
149 }
150
151 econfig.size = size;177 econfig.size = size;
152 econfig.dev = dev;178 econfig.dev = dev;
153 econfig.reg_read = sunxi_sid_read;179 if (cfg->need_register_readout)
180 econfig.reg_read = sun8i_sid_read_by_reg;
181 else
182 econfig.reg_read = sunxi_sid_read;
154 econfig.priv = sid;183 econfig.priv = sid;
155 nvmem = nvmem_register(&econfig);184 nvmem = nvmem_register(&econfig);
156 if (IS_ERR(nvmem))185 if (IS_ERR(nvmem))
@@ -163,7 +192,7 @@ static int sunxi_sid_probe(struct platform_device *pdev) · 6 unmodified lines
163 }192 }
164 193
165 for (i = 0; i < size; i++)194 for (i = 0; i < size; i++)
166 randomness[i] = sunxi_sid_read_byte(sid, i);195 econfig.reg_read(sid, i, &randomness[i], 1);
167 196
168 add_device_randomness(randomness, size);197 add_device_randomness(randomness, size);
169 kfree(randomness);198 kfree(randomness);
drivers/nvmem/uniphier-efuse.c+2−14
@@ -60,20 +60,9 @@ static int uniphier_efuse_probe(struct platform_device *pdev) · 59 unmodified lines
60 econfig.size = resource_size(res);60 econfig.size = resource_size(res);
61 econfig.priv = priv;61 econfig.priv = priv;
62 econfig.dev = dev;62 econfig.dev = dev;
63 nvmem = nvmem_register(&econfig);63 nvmem = devm_nvmem_register(dev, &econfig);
64 if (IS_ERR(nvmem))
65 return PTR_ERR(nvmem);
66 64
67 platform_set_drvdata(pdev, nvmem);65 return PTR_ERR_OR_ZERO(nvmem);
68
69 return 0;
70}
71
72static int uniphier_efuse_remove(struct platform_device *pdev)
73{
74 struct nvmem_device *nvmem = platform_get_drvdata(pdev);
75
76 return nvmem_unregister(nvmem);
77}66}
78 67
79static const struct of_device_id uniphier_efuse_of_match[] = {68static const struct of_device_id uniphier_efuse_of_match[] = {
@@ -84,7 +73,6 @@ MODULE_DEVICE_TABLE(of, uniphier_efuse_of_match); · 4 unmodified lines
84 73
85static struct platform_driver uniphier_efuse_driver = {74static struct platform_driver uniphier_efuse_driver = {
86 .probe = uniphier_efuse_probe,75 .probe = uniphier_efuse_probe,
87 .remove = uniphier_efuse_remove,
88 .driver = {76 .driver = {
89 .name = "uniphier-efuse",77 .name = "uniphier-efuse",
90 .of_match_table = uniphier_efuse_of_match,78 .of_match_table = uniphier_efuse_of_match,
drivers/nvmem/vf610-ocotp.c+5−19
@@ -217,21 +217,13 @@ static const struct of_device_id ocotp_of_match[] = { · 216 unmodified lines
217};217};
218MODULE_DEVICE_TABLE(of, ocotp_of_match);218MODULE_DEVICE_TABLE(of, ocotp_of_match);
219 219
220static int vf610_ocotp_remove(struct platform_device *pdev)
221{
222 struct vf610_ocotp *ocotp_dev = platform_get_drvdata(pdev);
223
224 return nvmem_unregister(ocotp_dev->nvmem);
225}
226
227static int vf610_ocotp_probe(struct platform_device *pdev)220static int vf610_ocotp_probe(struct platform_device *pdev)
228{221{
229 struct device *dev = &pdev->dev;222 struct device *dev = &pdev->dev;
230 struct resource *res;223 struct resource *res;
231 struct vf610_ocotp *ocotp_dev;224 struct vf610_ocotp *ocotp_dev;
232 225
233 ocotp_dev = devm_kzalloc(&pdev->dev,226 ocotp_dev = devm_kzalloc(dev, sizeof(struct vf610_ocotp), GFP_KERNEL);
234 sizeof(struct vf610_ocotp), GFP_KERNEL);
235 if (!ocotp_dev)227 if (!ocotp_dev)
236 return -ENOMEM;228 return -ENOMEM;
237 229
@@ -246,26 +238,20 @@ static int vf610_ocotp_probe(struct platform_device *pdev) · 8 unmodified lines
246 PTR_ERR(ocotp_dev->clk));238 PTR_ERR(ocotp_dev->clk));
247 return PTR_ERR(ocotp_dev->clk);239 return PTR_ERR(ocotp_dev->clk);
248 }240 }
241 ocotp_dev->dev = dev;
242 ocotp_dev->timing = vf610_ocotp_calculate_timing(ocotp_dev);
249 243
250 ocotp_config.size = resource_size(res);244 ocotp_config.size = resource_size(res);
251 ocotp_config.priv = ocotp_dev;245 ocotp_config.priv = ocotp_dev;
252 ocotp_config.dev = dev;246 ocotp_config.dev = dev;
253 247
254 ocotp_dev->nvmem = nvmem_register(&ocotp_config);248 ocotp_dev->nvmem = devm_nvmem_register(dev, &ocotp_config);
255 if (IS_ERR(ocotp_dev->nvmem))
256 return PTR_ERR(ocotp_dev->nvmem);
257 249
258 ocotp_dev->dev = dev;250 return PTR_ERR_OR_ZERO(ocotp_dev->nvmem);
259 platform_set_drvdata(pdev, ocotp_dev);
260
261 ocotp_dev->timing = vf610_ocotp_calculate_timing(ocotp_dev);
262
263 return 0;
264}251}
265 252
266static struct platform_driver vf610_ocotp_driver = {253static struct platform_driver vf610_ocotp_driver = {
267 .probe = vf610_ocotp_probe,254 .probe = vf610_ocotp_probe,
268 .remove = vf610_ocotp_remove,
269 .driver = {255 .driver = {
270 .name = "vf610-ocotp",256 .name = "vf610-ocotp",
271 .of_match_table = ocotp_of_match,257 .of_match_table = ocotp_of_match,
drivers/parport/parport_ax88796.c+3−5
@@ -273,18 +273,16 @@ static int parport_ax88796_probe(struct platform_device *pdev) · 272 unmodified lines
273{273{
274 struct device *_dev = &pdev->dev;274 struct device *_dev = &pdev->dev;
275 struct ax_drvdata *dd;275 struct ax_drvdata *dd;
276 struct parport *pp = NULL;276 struct parport *pp;
277 struct resource *res;277 struct resource *res;
278 unsigned long size;278 unsigned long size;
279 int spacing;279 int spacing;
280 int irq;280 int irq;
281 int ret;281 int ret;
282 282
283 dd = kzalloc(sizeof(struct ax_drvdata), GFP_KERNEL);283 dd = kzalloc(sizeof(*dd), GFP_KERNEL);
284 if (dd == NULL) {284 if (!dd)
285 dev_err(_dev, "no memory for private data\n");
286 return -ENOMEM;285 return -ENOMEM;
287 }
288 286
289 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);287 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
290 if (res == NULL) {288 if (res == NULL) {
drivers/parport/parport_pc.c+4−0
@@ -2646,6 +2646,7 @@ enum parport_pc_pci_cards { · 2645 unmodified lines
2646 netmos_9901,2646 netmos_9901,
2647 netmos_9865,2647 netmos_9865,
2648 quatech_sppxp100,2648 quatech_sppxp100,
2649 wch_ch382l,
2649};2650};
2650 2651
2651 2652
@@ -2708,6 +2709,7 @@ static struct parport_pc_pci { · 56 unmodified lines
2708 /* netmos_9901 */ { 1, { { 0, -1 }, } },2709 /* netmos_9901 */ { 1, { { 0, -1 }, } },
2709 /* netmos_9865 */ { 1, { { 0, -1 }, } },2710 /* netmos_9865 */ { 1, { { 0, -1 }, } },
2710 /* quatech_sppxp100 */ { 1, { { 0, 1 }, } },2711 /* quatech_sppxp100 */ { 1, { { 0, 1 }, } },
2712 /* wch_ch382l */ { 1, { { 2, -1 }, } },
2711};2713};
2712 2714
2713static const struct pci_device_id parport_pc_pci_tbl[] = {2715static const struct pci_device_id parport_pc_pci_tbl[] = {
@@ -2797,6 +2799,8 @@ static const struct pci_device_id parport_pc_pci_tbl[] = { · 83 unmodified lines
2797 /* Quatech SPPXP-100 Parallel port PCI ExpressCard */2799 /* Quatech SPPXP-100 Parallel port PCI ExpressCard */
2798 { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SPPXP_100,2800 { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SPPXP_100,
2799 PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 },2801 PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 },
2802 /* WCH CH382L PCI-E single parallel port card */
2803 { 0x1c00, 0x3050, 0x1c00, 0x3050, 0, 0, wch_ch382l },
2800 { 0, } /* terminate list */2804 { 0, } /* terminate list */
2801};2805};
2802MODULE_DEVICE_TABLE(pci, parport_pc_pci_tbl);2806MODULE_DEVICE_TABLE(pci, parport_pc_pci_tbl);
drivers/parport/parport_serial.c+46−76
@@ -1,30 +1,24 @@
1// SPDX-License-Identifier: GPL-2.0+
1/*2/*
2 * Support for common PCI multi-I/O cards (which is most of them)3 * Support for common PCI multi-I/O cards (which is most of them)
3 *4 *
4 * Copyright (C) 2001 Tim Waugh <twaugh@redhat.com>5 * Copyright (C) 2001 Tim Waugh <twaugh@redhat.com>
5 *6 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 *
12 * Multi-function PCI cards are supposed to present separate logical7 * Multi-function PCI cards are supposed to present separate logical
13 * devices on the bus. A common thing to do seems to be to just use8 * devices on the bus. A common thing to do seems to be to just use
14 * one logical device with lots of base address registers for both9 * one logical device with lots of base address registers for both
15 * parallel ports and serial ports. This driver is for dealing with10 * parallel ports and serial ports. This driver is for dealing with
16 * that.11 * that.
17 *
18 */12 */
19 13
20#include <linux/types.h>
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <linux/pci.h>
25#include <linux/interrupt.h>14#include <linux/interrupt.h>
15#include <linux/module.h>
26#include <linux/parport.h>16#include <linux/parport.h>
27#include <linux/parport_pc.h>17#include <linux/parport_pc.h>
18#include <linux/pci.h>
19#include <linux/slab.h>
20#include <linux/types.h>
21
28#include <linux/8250_pci.h>22#include <linux/8250_pci.h>
29 23
30enum parport_pc_pci_cards {24enum parport_pc_pci_cards {
@@ -65,6 +59,7 @@ enum parport_pc_pci_cards { · 34 unmodified lines
65 wch_ch353_1s1p,59 wch_ch353_1s1p,
66 wch_ch353_2s1p,60 wch_ch353_2s1p,
67 wch_ch382_2s1p,61 wch_ch382_2s1p,
62 brainboxes_5s1p,
68 sunix_2s1p,63 sunix_2s1p,
69};64};
70 65
@@ -153,6 +148,7 @@ static struct parport_pc_pci cards[] = { · 82 unmodified lines
153 /* wch_ch353_1s1p*/ { 1, { { 1, -1}, } },148 /* wch_ch353_1s1p*/ { 1, { { 1, -1}, } },
154 /* wch_ch353_2s1p*/ { 1, { { 2, -1}, } },149 /* wch_ch353_2s1p*/ { 1, { { 2, -1}, } },
155 /* wch_ch382_2s1p*/ { 1, { { 2, -1}, } },150 /* wch_ch382_2s1p*/ { 1, { { 2, -1}, } },
151 /* brainboxes_5s1p */ { 1, { { 3, -1 }, } },
156 /* sunix_2s1p */ { 1, { { 3, -1 }, } },152 /* sunix_2s1p */ { 1, { { 3, -1 }, } },
157};153};
158 154
@@ -258,6 +254,10 @@ static struct pci_device_id parport_serial_pci_tbl[] = { · 99 unmodified lines
258 { 0x4348, 0x7053, 0x4348, 0x3253, 0, 0, wch_ch353_2s1p},254 { 0x4348, 0x7053, 0x4348, 0x3253, 0, 0, wch_ch353_2s1p},
259 { 0x1c00, 0x3250, 0x1c00, 0x3250, 0, 0, wch_ch382_2s1p},255 { 0x1c00, 0x3250, 0x1c00, 0x3250, 0, 0, wch_ch382_2s1p},
260 256
257 /* BrainBoxes PX272/PX306 MIO card */
258 { PCI_VENDOR_ID_INTASHIELD, 0x4100,
259 PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_5s1p },
260
261 /*261 /*
262 * More SUNIX variations. At least one of these has part number262 * More SUNIX variations. At least one of these has part number
263 * '5079A but subdevice 0x102. That board reports 0x0708 as263 * '5079A but subdevice 0x102. That board reports 0x0708 as
@@ -501,6 +501,12 @@ static struct pciserial_board pci_parport_serial_boards[] = { · 237 unmodified lines
501 .uart_offset = 8,501 .uart_offset = 8,
502 .first_offset = 0xC0,502 .first_offset = 0xC0,
503 },503 },
504 [brainboxes_5s1p] = {
505 .flags = FL_BASE2,
506 .num_ports = 5,
507 .base_baud = 921600,
508 .uart_offset = 8,
509 },
504 [sunix_2s1p] = {510 [sunix_2s1p] = {
505 .flags = FL_BASE0|FL_BASE_BARS,511 .flags = FL_BASE0|FL_BASE_BARS,
506 .num_ports = 2,512 .num_ports = 2,
@@ -524,12 +530,10 @@ static int serial_register(struct pci_dev *dev, const struct pci_device_id *id) · 17 unmodified lines
524 struct serial_private *serial;530 struct serial_private *serial;
525 531
526 board = &pci_parport_serial_boards[id->driver_data];532 board = &pci_parport_serial_boards[id->driver_data];
527
528 if (board->num_ports == 0)533 if (board->num_ports == 0)
529 return 0;534 return 0;
530 535
531 serial = pciserial_init_ports(dev, board);536 serial = pciserial_init_ports(dev, board);
532
533 if (IS_ERR(serial))537 if (IS_ERR(serial))
534 return PTR_ERR(serial);538 return PTR_ERR(serial);
535 539
@@ -558,10 +562,9 @@ static int parport_register(struct pci_dev *dev, const struct pci_device_id *id) · 22 unmodified lines
558 int irq;562 int irq;
559 563
560 if (priv->num_par == ARRAY_SIZE (priv->port)) {564 if (priv->num_par == ARRAY_SIZE (priv->port)) {
561 printk (KERN_WARNING565 dev_warn(&dev->dev,
562 "parport_serial: %s: only %zu parallel ports "566 "only %zu parallel ports supported (%d reported)\n",
563 "supported (%d reported)\n", pci_name (dev),567 ARRAY_SIZE(priv->port), card->numports);
564 ARRAY_SIZE(priv->port), card->numports);
565 break;568 break;
566 }569 }
567 570
@@ -577,12 +580,12 @@ static int parport_register(struct pci_dev *dev, const struct pci_device_id *id) · 9 unmodified lines
577 irq = dev->irq;580 irq = dev->irq;
578 if (irq == IRQ_NONE) {581 if (irq == IRQ_NONE) {
579 dev_dbg(&dev->dev,582 dev_dbg(&dev->dev,
580 "PCI parallel port detected: I/O at %#lx(%#lx)\n",583 "PCI parallel port detected: I/O at %#lx(%#lx)\n",
581 io_lo, io_hi);584 io_lo, io_hi);
582 irq = PARPORT_IRQ_NONE;585 irq = PARPORT_IRQ_NONE;
583 } else {586 } else {
584 dev_dbg(&dev->dev,587 dev_dbg(&dev->dev,
585 "PCI parallel port detected: I/O at %#lx(%#lx), IRQ %d\n",588 "PCI parallel port detected: I/O at %#lx(%#lx), IRQ %d\n",
586 io_lo, io_hi, irq);589 io_lo, io_hi, irq);
587 }590 }
588 port = parport_pc_probe_port (io_lo, io_hi, irq,591 port = parport_pc_probe_port (io_lo, io_hi, irq,
@@ -605,28 +608,26 @@ static int parport_serial_pci_probe(struct pci_dev *dev, · 16 unmodified lines
605 struct parport_serial_private *priv;608 struct parport_serial_private *priv;
606 int err;609 int err;
607 610
608 priv = kzalloc (sizeof *priv, GFP_KERNEL);611 priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);
609 if (!priv)612 if (!priv)
610 return -ENOMEM;613 return -ENOMEM;
614
611 pci_set_drvdata (dev, priv);615 pci_set_drvdata (dev, priv);
612 616
613 err = pci_enable_device (dev);617 err = pcim_enable_device(dev);
614 if (err) {618 if (err)
615 kfree (priv);
616 return err;619 return err;
617 }
618 620
619 if (parport_register (dev, id)) {621 err = parport_register(dev, id);
620 kfree (priv);622 if (err)
621 return -ENODEV;623 return err;
622 }
623 624
624 if (serial_register (dev, id)) {625 err = serial_register(dev, id);
626 if (err) {
625 int i;627 int i;
626 for (i = 0; i < priv->num_par; i++)628 for (i = 0; i < priv->num_par; i++)
627 parport_pc_unregister_port (priv->port[i]);629 parport_pc_unregister_port (priv->port[i]);
628 kfree (priv);630 return err;
629 return -ENODEV;
630 }631 }
631 632
632 return 0;633 return 0;
@@ -645,78 +646,47 @@ static void parport_serial_pci_remove(struct pci_dev *dev) · 12 unmodified lines
645 for (i = 0; i < priv->num_par; i++)646 for (i = 0; i < priv->num_par; i++)
646 parport_pc_unregister_port (priv->port[i]);647 parport_pc_unregister_port (priv->port[i]);
647 648
648 kfree (priv);
649 return;649 return;
650}650}
651 651
652#ifdef CONFIG_PM652static int __maybe_unused parport_serial_pci_suspend(struct device *dev)
653static int parport_serial_pci_suspend(struct pci_dev *dev, pm_message_t state)
654{653{
655 struct parport_serial_private *priv = pci_get_drvdata(dev);654 struct pci_dev *pdev = to_pci_dev(dev);
655 struct parport_serial_private *priv = pci_get_drvdata(pdev);
656 656
657 if (priv->serial)657 if (priv->serial)
658 pciserial_suspend_ports(priv->serial);658 pciserial_suspend_ports(priv->serial);
659 659
660 /* FIXME: What about parport? */660 /* FIXME: What about parport? */
661
662 pci_save_state(dev);
663 pci_set_power_state(dev, pci_choose_state(dev, state));
664 return 0;661 return 0;
665}662}
666 663
667static int parport_serial_pci_resume(struct pci_dev *dev)664static int __maybe_unused parport_serial_pci_resume(struct device *dev)
668{665{
669 struct parport_serial_private *priv = pci_get_drvdata(dev);666 struct pci_dev *pdev = to_pci_dev(dev);
670 int err;667 struct parport_serial_private *priv = pci_get_drvdata(pdev);
671
672 pci_set_power_state(dev, PCI_D0);
673 pci_restore_state(dev);
674
675 /*
676 * The device may have been disabled. Re-enable it.
677 */
678 err = pci_enable_device(dev);
679 if (err) {
680 printk(KERN_ERR "parport_serial: %s: error enabling "
681 "device for resume (%d)\n", pci_name(dev), err);
682 return err;
683 }
684 668
685 if (priv->serial)669 if (priv->serial)
686 pciserial_resume_ports(priv->serial);670 pciserial_resume_ports(priv->serial);
687 671
688 /* FIXME: What about parport? */672 /* FIXME: What about parport? */
689
690 return 0;673 return 0;
691}674}
692#endif675
676static SIMPLE_DEV_PM_OPS(parport_serial_pm_ops,
677 parport_serial_pci_suspend, parport_serial_pci_resume);
693 678
694static struct pci_driver parport_serial_pci_driver = {679static struct pci_driver parport_serial_pci_driver = {
695 .name = "parport_serial",680 .name = "parport_serial",
696 .id_table = parport_serial_pci_tbl,681 .id_table = parport_serial_pci_tbl,
697 .probe = parport_serial_pci_probe,682 .probe = parport_serial_pci_probe,
698 .remove = parport_serial_pci_remove,683 .remove = parport_serial_pci_remove,
699#ifdef CONFIG_PM684 .driver = {
700 .suspend = parport_serial_pci_suspend,685 .pm = &parport_serial_pm_ops,
701 .resume = parport_serial_pci_resume,686 },
702#endif
703};687};
704 688module_pci_driver(parport_serial_pci_driver);
705
706static int __init parport_serial_init (void)
707{
708 return pci_register_driver (&parport_serial_pci_driver);
709}
710
711static void __exit parport_serial_exit (void)
712{
713 pci_unregister_driver (&parport_serial_pci_driver);
714 return;
715}
716 689
717MODULE_AUTHOR("Tim Waugh <twaugh@redhat.com>");690MODULE_AUTHOR("Tim Waugh <twaugh@redhat.com>");
718MODULE_DESCRIPTION("Driver for common parallel+serial multi-I/O PCI cards");691MODULE_DESCRIPTION("Driver for common parallel+serial multi-I/O PCI cards");
719MODULE_LICENSE("GPL");692MODULE_LICENSE("GPL");
720
721module_init(parport_serial_init);
722module_exit(parport_serial_exit);
drivers/pps/clients/pps_parport.c+18−3
@@ -49,6 +49,7 @@ MODULE_PARM_DESC(clear_wait, · 48 unmodified lines
49 " zero turns clear edge capture off entirely");49 " zero turns clear edge capture off entirely");
50module_param(clear_wait, uint, 0);50module_param(clear_wait, uint, 0);
51 51
52static DEFINE_IDA(pps_client_index);
52 53
53/* internal per port structure */54/* internal per port structure */
54struct pps_client_pp {55struct pps_client_pp {
@@ -56,6 +57,7 @@ struct pps_client_pp { · 1 unmodified line
56 struct pps_device *pps; /* PPS device */57 struct pps_device *pps; /* PPS device */
57 unsigned int cw; /* port clear timeout */58 unsigned int cw; /* port clear timeout */
58 unsigned int cw_err; /* number of timeouts */59 unsigned int cw_err; /* number of timeouts */
60 int index; /* device number */
59};61};
60 62
61static inline int signal_is_set(struct parport *port)63static inline int signal_is_set(struct parport *port)
@@ -136,6 +138,8 @@ out_both: · 74 unmodified lines
136 138
137static void parport_attach(struct parport *port)139static void parport_attach(struct parport *port)
138{140{
141 struct pardev_cb pps_client_cb;
142 int index;
139 struct pps_client_pp *device;143 struct pps_client_pp *device;
140 struct pps_source_info info = {144 struct pps_source_info info = {
141 .name = KBUILD_MODNAME,145 .name = KBUILD_MODNAME,
@@ -154,8 +158,15 @@ static void parport_attach(struct parport *port) · 12 unmodified lines
154 return;158 return;
155 }159 }
156 160
157 device->pardev = parport_register_device(port, KBUILD_MODNAME,161 index = ida_simple_get(&pps_client_index, 0, 0, GFP_KERNEL);
158 NULL, NULL, parport_irq, PARPORT_FLAG_EXCL, device);162 memset(&pps_client_cb, 0, sizeof(pps_client_cb));
163 pps_client_cb.private = device;
164 pps_client_cb.irq_func = parport_irq;
165 pps_client_cb.flags = PARPORT_FLAG_EXCL;
166 device->pardev = parport_register_dev_model(port,
167 KBUILD_MODNAME,
168 &pps_client_cb,
169 index);
159 if (!device->pardev) {170 if (!device->pardev) {
160 pr_err("couldn't register with %s\n", port->name);171 pr_err("couldn't register with %s\n", port->name);
161 goto err_free;172 goto err_free;
@@ -176,6 +187,7 @@ static void parport_attach(struct parport *port) · 14 unmodified lines
176 device->cw = clear_wait;187 device->cw = clear_wait;
177 188
178 port->ops->enable_irq(port);189 port->ops->enable_irq(port);
190 device->index = index;
179 191
180 pr_info("attached to %s\n", port->name);192 pr_info("attached to %s\n", port->name);
181 193
@@ -186,6 +198,7 @@ err_release_dev: · 4 unmodified lines
186err_unregister_dev:198err_unregister_dev:
187 parport_unregister_device(device->pardev);199 parport_unregister_device(device->pardev);
188err_free:200err_free:
201 ida_simple_remove(&pps_client_index, index);
189 kfree(device);202 kfree(device);
190}203}
191 204
@@ -205,13 +218,15 @@ static void parport_detach(struct parport *port) · 13 unmodified lines
205 pps_unregister_source(device->pps);218 pps_unregister_source(device->pps);
206 parport_release(pardev);219 parport_release(pardev);
207 parport_unregister_device(pardev);220 parport_unregister_device(pardev);
221 ida_simple_remove(&pps_client_index, device->index);
208 kfree(device);222 kfree(device);
209}223}
210 224
211static struct parport_driver pps_parport_driver = {225static struct parport_driver pps_parport_driver = {
212 .name = KBUILD_MODNAME,226 .name = KBUILD_MODNAME,
213 .attach = parport_attach,227 .match_port = parport_attach,
214 .detach = parport_detach,228 .detach = parport_detach,
229 .devmodel = true,
215};230};
216 231
217/* module staff */232/* module staff */
drivers/pps/generators/pps_gen_parport.c+9−3
@@ -192,13 +192,18 @@ static inline ktime_t next_intr_time(struct pps_generator_pp *dev) · 191 unmodified lines
192 192
193static void parport_attach(struct parport *port)193static void parport_attach(struct parport *port)
194{194{
195 struct pardev_cb pps_cb;
196
195 if (attached) {197 if (attached) {
196 /* we already have a port */198 /* we already have a port */
197 return;199 return;
198 }200 }
199 201
200 device.pardev = parport_register_device(port, KBUILD_MODNAME,202 memset(&pps_cb, 0, sizeof(pps_cb));
201 NULL, NULL, NULL, PARPORT_FLAG_EXCL, &device);203 pps_cb.private = &device;
204 pps_cb.flags = PARPORT_FLAG_EXCL;
205 device.pardev = parport_register_dev_model(port, KBUILD_MODNAME,
206 &pps_cb, 0);
202 if (!device.pardev) {207 if (!device.pardev) {
203 pr_err("couldn't register with %s\n", port->name);208 pr_err("couldn't register with %s\n", port->name);
204 return;209 return;
@@ -236,8 +241,9 @@ static void parport_detach(struct parport *port) · 31 unmodified lines
236 241
237static struct parport_driver pps_gen_parport_driver = {242static struct parport_driver pps_gen_parport_driver = {
238 .name = KBUILD_MODNAME,243 .name = KBUILD_MODNAME,
239 .attach = parport_attach,244 .match_port = parport_attach,
240 .detach = parport_detach,245 .detach = parport_detach,
246 .devmodel = true,
241};247};
242 248
243/* module staff */249/* module staff */
drivers/siox/siox-core.c+1−1
@@ -594,7 +594,7 @@ static ssize_t device_add_store(struct device *dev, · 593 unmodified lines
594 size_t inbytes = 0, outbytes = 0;594 size_t inbytes = 0, outbytes = 0;
595 u8 statustype = 0;595 u8 statustype = 0;
596 596
597 ret = sscanf(buf, "%20s %zu %zu %hhu", type, &inbytes,597 ret = sscanf(buf, "%19s %zu %zu %hhu", type, &inbytes,
598 &outbytes, &statustype);598 &outbytes, &statustype);
599 if (ret != 3 && ret != 4)599 if (ret != 3 && ret != 4)
600 return -EINVAL;600 return -EINVAL;
drivers/slimbus/core.c+1−1
@@ -141,7 +141,7 @@ static struct slim_device *slim_alloc_device(struct slim_controller *ctrl, · 140 unmodified lines
141 sbdev->e_addr = *eaddr;141 sbdev->e_addr = *eaddr;
142 ret = slim_add_device(ctrl, sbdev, node);142 ret = slim_add_device(ctrl, sbdev, node);
143 if (ret) {143 if (ret) {
144 kfree(sbdev);144 put_device(&sbdev->dev);
145 return NULL;145 return NULL;
146 }146 }
147 147
drivers/thunderbolt/dma_port.c+13−15
@@ -170,24 +170,22 @@ static int dma_port_write(struct tb_ctl *ctl, const void *buffer, u64 route, · 169 unmodified lines
170 170
171static int dma_find_port(struct tb_switch *sw)171static int dma_find_port(struct tb_switch *sw)
172{172{
173 int port, ret;173 static const int ports[] = { 3, 5, 7 };
174 u32 type;174 int i;
175 175
176 /*176 /*
177 * The DMA (NHI) port is either 3 or 5 depending on the177 * The DMA (NHI) port is either 3, 5 or 7 depending on the
178 * controller. Try both starting from 5 which is more common.178 * controller. Try all of them.
179 */179 */
180 port = 5;180 for (i = 0; i < ARRAY_SIZE(ports); i++) {
181 ret = dma_port_read(sw->tb->ctl, &type, tb_route(sw), port, 2, 1,181 u32 type;
182 DMA_PORT_TIMEOUT);182 int ret;
183 if (!ret && (type & 0xffffff) == TB_TYPE_NHI)183
184 return port;184 ret = dma_port_read(sw->tb->ctl, &type, tb_route(sw), ports[i],
185 185 2, 1, DMA_PORT_TIMEOUT);
186 port = 3;186 if (!ret && (type & 0xffffff) == TB_TYPE_NHI)
187 ret = dma_port_read(sw->tb->ctl, &type, tb_route(sw), port, 2, 1,187 return ports[i];
188 DMA_PORT_TIMEOUT);188 }
189 if (!ret && (type & 0xffffff) == TB_TYPE_NHI)
190 return port;
191 189
192 return -ENODEV;190 return -ENODEV;
193}191}
drivers/thunderbolt/domain.c+129−1
@@ -117,23 +117,151 @@ static const char * const tb_security_names[] = { · 116 unmodified lines
117 [TB_SECURITY_USER] = "user",117 [TB_SECURITY_USER] = "user",
118 [TB_SECURITY_SECURE] = "secure",118 [TB_SECURITY_SECURE] = "secure",
119 [TB_SECURITY_DPONLY] = "dponly",119 [TB_SECURITY_DPONLY] = "dponly",
120 [TB_SECURITY_USBONLY] = "usbonly",
120};121};
121 122
123static ssize_t boot_acl_show(struct device *dev, struct device_attribute *attr,
124 char *buf)
125{
126 struct tb *tb = container_of(dev, struct tb, dev);
127 uuid_t *uuids;
128 ssize_t ret;
129 int i;
130
131 uuids = kcalloc(tb->nboot_acl, sizeof(uuid_t), GFP_KERNEL);
132 if (!uuids)
133 return -ENOMEM;
134
135 if (mutex_lock_interruptible(&tb->lock)) {
136 ret = -ERESTARTSYS;
137 goto out;
138 }
139 ret = tb->cm_ops->get_boot_acl(tb, uuids, tb->nboot_acl);
140 if (ret) {
141 mutex_unlock(&tb->lock);
142 goto out;
143 }
144 mutex_unlock(&tb->lock);
145
146 for (ret = 0, i = 0; i < tb->nboot_acl; i++) {
147 if (!uuid_is_null(&uuids[i]))
148 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%pUb",
149 &uuids[i]);
150
151 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%s",
152 i < tb->nboot_acl - 1 ? "," : "\n");
153 }
154
155out:
156 kfree(uuids);
157 return ret;
158}
159
160static ssize_t boot_acl_store(struct device *dev, struct device_attribute *attr,
161 const char *buf, size_t count)
162{
163 struct tb *tb = container_of(dev, struct tb, dev);
164 char *str, *s, *uuid_str;
165 ssize_t ret = 0;
166 uuid_t *acl;
167 int i = 0;
168
169 /*
170 * Make sure the value is not bigger than tb->nboot_acl * UUID
171 * length + commas and optional "\n". Also the smallest allowable
172 * string is tb->nboot_acl * ",".
173 */
174 if (count > (UUID_STRING_LEN + 1) * tb->nboot_acl + 1)
175 return -EINVAL;
176 if (count < tb->nboot_acl - 1)
177 return -EINVAL;
178
179 str = kstrdup(buf, GFP_KERNEL);
180 if (!str)
181 return -ENOMEM;
182
183 acl = kcalloc(tb->nboot_acl, sizeof(uuid_t), GFP_KERNEL);
184 if (!acl) {
185 ret = -ENOMEM;
186 goto err_free_str;
187 }
188
189 uuid_str = strim(str);
190 while ((s = strsep(&uuid_str, ",")) != NULL && i < tb->nboot_acl) {
191 size_t len = strlen(s);
192
193 if (len) {
194 if (len != UUID_STRING_LEN) {
195 ret = -EINVAL;
196 goto err_free_acl;
197 }
198 ret = uuid_parse(s, &acl[i]);
199 if (ret)
200 goto err_free_acl;
201 }
202
203 i++;
204 }
205
206 if (s || i < tb->nboot_acl) {
207 ret = -EINVAL;
208 goto err_free_acl;
209 }
210
211 if (mutex_lock_interruptible(&tb->lock)) {
212 ret = -ERESTARTSYS;
213 goto err_free_acl;
214 }
215 ret = tb->cm_ops->set_boot_acl(tb, acl, tb->nboot_acl);
216 mutex_unlock(&tb->lock);
217
218err_free_acl:
219 kfree(acl);
220err_free_str:
221 kfree(str);
222
223 return ret ?: count;
224}
225static DEVICE_ATTR_RW(boot_acl);
226
122static ssize_t security_show(struct device *dev, struct device_attribute *attr,227static ssize_t security_show(struct device *dev, struct device_attribute *attr,
123 char *buf)228 char *buf)
124{229{
125 struct tb *tb = container_of(dev, struct tb, dev);230 struct tb *tb = container_of(dev, struct tb, dev);
231 const char *name = "unknown";
126 232
127 return sprintf(buf, "%s\n", tb_security_names[tb->security_level]);233 if (tb->security_level < ARRAY_SIZE(tb_security_names))
234 name = tb_security_names[tb->security_level];
235
236 return sprintf(buf, "%s\n", name);
128}237}
129static DEVICE_ATTR_RO(security);238static DEVICE_ATTR_RO(security);
130 239
131static struct attribute *domain_attrs[] = {240static struct attribute *domain_attrs[] = {
241 &dev_attr_boot_acl.attr,
132 &dev_attr_security.attr,242 &dev_attr_security.attr,
133 NULL,243 NULL,
134};244};
135 245
246static umode_t domain_attr_is_visible(struct kobject *kobj,
247 struct attribute *attr, int n)
248{
249 struct device *dev = container_of(kobj, struct device, kobj);
250 struct tb *tb = container_of(dev, struct tb, dev);
251
252 if (attr == &dev_attr_boot_acl.attr) {
253 if (tb->nboot_acl &&
254 tb->cm_ops->get_boot_acl &&
255 tb->cm_ops->set_boot_acl)
256 return attr->mode;
257 return 0;
258 }
259
260 return attr->mode;
261}
262
136static struct attribute_group domain_attr_group = {263static struct attribute_group domain_attr_group = {
264 .is_visible = domain_attr_is_visible,
137 .attrs = domain_attrs,265 .attrs = domain_attrs,
138};266};
139 267
drivers/thunderbolt/icm.c+685−79
@@ -41,7 +41,8 @@ · 40 unmodified lines
41#define PHY_PORT_CS1_LINK_STATE_MASK GENMASK(29, 26)41#define PHY_PORT_CS1_LINK_STATE_MASK GENMASK(29, 26)
42#define PHY_PORT_CS1_LINK_STATE_SHIFT 2642#define PHY_PORT_CS1_LINK_STATE_SHIFT 26
43 43
44#define ICM_TIMEOUT 5000 /* ms */44#define ICM_TIMEOUT 5000 /* ms */
45#define ICM_APPROVE_TIMEOUT 10000 /* ms */
45#define ICM_MAX_LINK 446#define ICM_MAX_LINK 4
46#define ICM_MAX_DEPTH 647#define ICM_MAX_DEPTH 6
47 48
@@ -55,9 +56,11 @@ · 7 unmodified lines
55 * @vnd_cap: Vendor defined capability where PCIe2CIO mailbox resides56 * @vnd_cap: Vendor defined capability where PCIe2CIO mailbox resides
56 * (only set when @upstream_port is not %NULL)57 * (only set when @upstream_port is not %NULL)
57 * @safe_mode: ICM is in safe mode58 * @safe_mode: ICM is in safe mode
59 * @max_boot_acl: Maximum number of preboot ACL entries (%0 if not supported)
58 * @is_supported: Checks if we can support ICM on this controller60 * @is_supported: Checks if we can support ICM on this controller
59 * @get_mode: Read and return the ICM firmware mode (optional)61 * @get_mode: Read and return the ICM firmware mode (optional)
60 * @get_route: Find a route string for given switch62 * @get_route: Find a route string for given switch
63 * @driver_ready: Send driver ready message to ICM
61 * @device_connected: Handle device connected ICM message64 * @device_connected: Handle device connected ICM message
62 * @device_disconnected: Handle device disconnected ICM message65 * @device_disconnected: Handle device disconnected ICM message
63 * @xdomain_connected - Handle XDomain connected ICM message66 * @xdomain_connected - Handle XDomain connected ICM message
@@ -67,11 +70,15 @@ struct icm { · 3 unmodified lines
67 struct mutex request_lock;70 struct mutex request_lock;
68 struct delayed_work rescan_work;71 struct delayed_work rescan_work;
69 struct pci_dev *upstream_port;72 struct pci_dev *upstream_port;
73 size_t max_boot_acl;
70 int vnd_cap;74 int vnd_cap;
71 bool safe_mode;75 bool safe_mode;
72 bool (*is_supported)(struct tb *tb);76 bool (*is_supported)(struct tb *tb);
73 int (*get_mode)(struct tb *tb);77 int (*get_mode)(struct tb *tb);
74 int (*get_route)(struct tb *tb, u8 link, u8 depth, u64 *route);78 int (*get_route)(struct tb *tb, u8 link, u8 depth, u64 *route);
79 int (*driver_ready)(struct tb *tb,
80 enum tb_security_level *security_level,
81 size_t *nboot_acl);
75 void (*device_connected)(struct tb *tb,82 void (*device_connected)(struct tb *tb,
76 const struct icm_pkg_header *hdr);83 const struct icm_pkg_header *hdr);
77 void (*device_disconnected)(struct tb *tb,84 void (*device_disconnected)(struct tb *tb,
@@ -111,6 +118,12 @@ static inline u64 get_route(u32 route_hi, u32 route_lo) · 33 unmodified lines
111 return (u64)route_hi << 32 | route_lo;118 return (u64)route_hi << 32 | route_lo;
112}119}
113 120
121static inline u64 get_parent_route(u64 route)
122{
123 int depth = tb_route_length(route);
124 return depth ? route & ~(0xffULL << (depth - 1) * TB_ROUTE_SHIFT) : 0;
125}
126
114static bool icm_match(const struct tb_cfg_request *req,127static bool icm_match(const struct tb_cfg_request *req,
115 const struct ctl_pkg *pkg)128 const struct ctl_pkg *pkg)
116{129{
@@ -245,6 +258,28 @@ err_free: · 128 unmodified lines
245 return ret;258 return ret;
246}259}
247 260
261static int
262icm_fr_driver_ready(struct tb *tb, enum tb_security_level *security_level,
263 size_t *nboot_acl)
264{
265 struct icm_fr_pkg_driver_ready_response reply;
266 struct icm_pkg_driver_ready request = {
267 .hdr.code = ICM_DRIVER_READY,
268 };
269 int ret;
270
271 memset(&reply, 0, sizeof(reply));
272 ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply),
273 1, ICM_TIMEOUT);
274 if (ret)
275 return ret;
276
277 if (security_level)
278 *security_level = reply.security_level & ICM_FR_SLEVEL_MASK;
279
280 return 0;
281}
282
248static int icm_fr_approve_switch(struct tb *tb, struct tb_switch *sw)283static int icm_fr_approve_switch(struct tb *tb, struct tb_switch *sw)
249{284{
250 struct icm_fr_pkg_approve_device request;285 struct icm_fr_pkg_approve_device request;
@@ -260,7 +295,7 @@ static int icm_fr_approve_switch(struct tb *tb, struct tb_switch *sw) · 9 unmodified lines
260 memset(&reply, 0, sizeof(reply));295 memset(&reply, 0, sizeof(reply));
261 /* Use larger timeout as establishing tunnels can take some time */296 /* Use larger timeout as establishing tunnels can take some time */
262 ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply),297 ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply),
263 1, 10000);298 1, ICM_APPROVE_TIMEOUT);
264 if (ret)299 if (ret)
265 return ret;300 return ret;
266 301
@@ -374,6 +409,59 @@ static int icm_fr_disconnect_xdomain_paths(struct tb *tb, struct tb_xdomain *xd) · 107 unmodified lines
374 return 0;409 return 0;
375}410}
376 411
412static void add_switch(struct tb_switch *parent_sw, u64 route,
413 const uuid_t *uuid, u8 connection_id, u8 connection_key,
414 u8 link, u8 depth, enum tb_security_level security_level,
415 bool authorized, bool boot)
416{
417 struct tb_switch *sw;
418
419 sw = tb_switch_alloc(parent_sw->tb, &parent_sw->dev, route);
420 if (!sw)
421 return;
422
423 sw->uuid = kmemdup(uuid, sizeof(*uuid), GFP_KERNEL);
424 sw->connection_id = connection_id;
425 sw->connection_key = connection_key;
426 sw->link = link;
427 sw->depth = depth;
428 sw->authorized = authorized;
429 sw->security_level = security_level;
430 sw->boot = boot;
431
432 /* Link the two switches now */
433 tb_port_at(route, parent_sw)->remote = tb_upstream_port(sw);
434 tb_upstream_port(sw)->remote = tb_port_at(route, parent_sw);
435
436 if (tb_switch_add(sw)) {
437 tb_port_at(tb_route(sw), parent_sw)->remote = NULL;
438 tb_switch_put(sw);
439 return;
440 }
441}
442
443static void update_switch(struct tb_switch *parent_sw, struct tb_switch *sw,
444 u64 route, u8 connection_id, u8 connection_key,
445 u8 link, u8 depth, bool boot)
446{
447 /* Disconnect from parent */
448 tb_port_at(tb_route(sw), parent_sw)->remote = NULL;
449 /* Re-connect via updated port*/
450 tb_port_at(route, parent_sw)->remote = tb_upstream_port(sw);
451
452 /* Update with the new addressing information */
453 sw->config.route_hi = upper_32_bits(route);
454 sw->config.route_lo = lower_32_bits(route);
455 sw->connection_id = connection_id;
456 sw->connection_key = connection_key;
457 sw->link = link;
458 sw->depth = depth;
459 sw->boot = boot;
460
461 /* This switch still exists */
462 sw->is_unplugged = false;
463}
464
377static void remove_switch(struct tb_switch *sw)465static void remove_switch(struct tb_switch *sw)
378{466{
379 struct tb_switch *parent_sw;467 struct tb_switch *parent_sw;
@@ -383,15 +471,52 @@ static void remove_switch(struct tb_switch *sw) · 3 unmodified lines
383 tb_switch_remove(sw);471 tb_switch_remove(sw);
384}472}
385 473
474static void add_xdomain(struct tb_switch *sw, u64 route,
475 const uuid_t *local_uuid, const uuid_t *remote_uuid,
476 u8 link, u8 depth)
477{
478 struct tb_xdomain *xd;
479
480 xd = tb_xdomain_alloc(sw->tb, &sw->dev, route, local_uuid, remote_uuid);
481 if (!xd)
482 return;
483
484 xd->link = link;
485 xd->depth = depth;
486
487 tb_port_at(route, sw)->xdomain = xd;
488
489 tb_xdomain_add(xd);
490}
491
492static void update_xdomain(struct tb_xdomain *xd, u64 route, u8 link)
493{
494 xd->link = link;
495 xd->route = route;
496 xd->is_unplugged = false;
497}
498
499static void remove_xdomain(struct tb_xdomain *xd)
500{
501 struct tb_switch *sw;
502
503 sw = tb_to_switch(xd->dev.parent);
504 tb_port_at(xd->route, sw)->xdomain = NULL;
505 tb_xdomain_remove(xd);
506}
507
386static void508static void
387icm_fr_device_connected(struct tb *tb, const struct icm_pkg_header *hdr)509icm_fr_device_connected(struct tb *tb, const struct icm_pkg_header *hdr)
388{510{
389 const struct icm_fr_event_device_connected *pkg =511 const struct icm_fr_event_device_connected *pkg =
390 (const struct icm_fr_event_device_connected *)hdr;512 (const struct icm_fr_event_device_connected *)hdr;
513 enum tb_security_level security_level;
391 struct tb_switch *sw, *parent_sw;514 struct tb_switch *sw, *parent_sw;
392 struct icm *icm = tb_priv(tb);515 struct icm *icm = tb_priv(tb);
393 bool authorized = false;516 bool authorized = false;
517 struct tb_xdomain *xd;
394 u8 link, depth;518 u8 link, depth;
519 bool boot;
395 u64 route;520 u64 route;
396 int ret;521 int ret;
397 522
@@ -399,6 +524,15 @@ icm_fr_device_connected(struct tb *tb, const struct icm_pkg_header *hdr) · 1 unmodified line
399 depth = (pkg->link_info & ICM_LINK_INFO_DEPTH_MASK) >>524 depth = (pkg->link_info & ICM_LINK_INFO_DEPTH_MASK) >>
400 ICM_LINK_INFO_DEPTH_SHIFT;525 ICM_LINK_INFO_DEPTH_SHIFT;
401 authorized = pkg->link_info & ICM_LINK_INFO_APPROVED;526 authorized = pkg->link_info & ICM_LINK_INFO_APPROVED;
527 security_level = (pkg->hdr.flags & ICM_FLAGS_SLEVEL_MASK) >>
528 ICM_FLAGS_SLEVEL_SHIFT;
529 boot = pkg->link_info & ICM_LINK_INFO_BOOT;
530
531 if (pkg->link_info & ICM_LINK_INFO_REJECTED) {
532 tb_info(tb, "switch at %u.%u was rejected by ICM firmware because topology limit exceeded\n",
533 link, depth);
534 return;
535 }
402 536
403 ret = icm->get_route(tb, link, depth, &route);537 ret = icm->get_route(tb, link, depth, &route);
404 if (ret) {538 if (ret) {
@@ -425,16 +559,8 @@ icm_fr_device_connected(struct tb *tb, const struct icm_pkg_header *hdr) · 20 unmodified lines
425 */559 */
426 if (sw->depth == depth && sw_phy_port == phy_port &&560 if (sw->depth == depth && sw_phy_port == phy_port &&
427 !!sw->authorized == authorized) {561 !!sw->authorized == authorized) {
428 tb_port_at(tb_route(sw), parent_sw)->remote = NULL;562 update_switch(parent_sw, sw, route, pkg->connection_id,
429 tb_port_at(route, parent_sw)->remote =563 pkg->connection_key, link, depth, boot);
430 tb_upstream_port(sw);
431 sw->config.route_hi = upper_32_bits(route);
432 sw->config.route_lo = lower_32_bits(route);
433 sw->connection_id = pkg->connection_id;
434 sw->connection_key = pkg->connection_key;
435 sw->link = link;
436 sw->depth = depth;
437 sw->is_unplugged = false;
438 tb_switch_put(sw);564 tb_switch_put(sw);
439 return;565 return;
440 }566 }
@@ -467,6 +593,13 @@ icm_fr_device_connected(struct tb *tb, const struct icm_pkg_header *hdr) · 26 unmodified lines
467 tb_switch_put(sw);593 tb_switch_put(sw);
468 }594 }
469 595
596 /* Remove existing XDomain connection if found */
597 xd = tb_xdomain_find_by_link_depth(tb, link, depth);
598 if (xd) {
599 remove_xdomain(xd);
600 tb_xdomain_put(xd);
601 }
602
470 parent_sw = tb_switch_find_by_link_depth(tb, link, depth - 1);603 parent_sw = tb_switch_find_by_link_depth(tb, link, depth - 1);
471 if (!parent_sw) {604 if (!parent_sw) {
472 tb_err(tb, "failed to find parent switch for %u.%u\n",605 tb_err(tb, "failed to find parent switch for %u.%u\n",
@@ -474,30 +607,10 @@ icm_fr_device_connected(struct tb *tb, const struct icm_pkg_header *hdr) · 1 unmodified line
474 return;607 return;
475 }608 }
476 609
477 sw = tb_switch_alloc(tb, &parent_sw->dev, route);610 add_switch(parent_sw, route, &pkg->ep_uuid, pkg->connection_id,
478 if (!sw) {611 pkg->connection_key, link, depth, security_level,
479 tb_switch_put(parent_sw);612 authorized, boot);
480 return;
481 }
482
483 sw->uuid = kmemdup(&pkg->ep_uuid, sizeof(pkg->ep_uuid), GFP_KERNEL);
484 sw->connection_id = pkg->connection_id;
485 sw->connection_key = pkg->connection_key;
486 sw->link = link;
487 sw->depth = depth;
488 sw->authorized = authorized;
489 sw->security_level = (pkg->hdr.flags & ICM_FLAGS_SLEVEL_MASK) >>
490 ICM_FLAGS_SLEVEL_SHIFT;
491
492 /* Link the two switches now */
493 tb_port_at(route, parent_sw)->remote = tb_upstream_port(sw);
494 tb_upstream_port(sw)->remote = tb_port_at(route, parent_sw);
495 613
496 ret = tb_switch_add(sw);
497 if (ret) {
498 tb_port_at(tb_route(sw), parent_sw)->remote = NULL;
499 tb_switch_put(sw);
500 }
501 tb_switch_put(parent_sw);614 tb_switch_put(parent_sw);
502}615}
503 616
@@ -529,15 +642,6 @@ icm_fr_device_disconnected(struct tb *tb, const struct icm_pkg_header *hdr) · 25 unmodified lines
529 tb_switch_put(sw);642 tb_switch_put(sw);
530}643}
531 644
532static void remove_xdomain(struct tb_xdomain *xd)
533{
534 struct tb_switch *sw;
535
536 sw = tb_to_switch(xd->dev.parent);
537 tb_port_at(xd->route, sw)->xdomain = NULL;
538 tb_xdomain_remove(xd);
539}
540
541static void645static void
542icm_fr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr)646icm_fr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr)
543{647{
@@ -577,9 +681,7 @@ icm_fr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr) · 33 unmodified lines
577 phy_port = phy_port_from_route(route, depth);681 phy_port = phy_port_from_route(route, depth);
578 682
579 if (xd->depth == depth && xd_phy_port == phy_port) {683 if (xd->depth == depth && xd_phy_port == phy_port) {
580 xd->link = link;684 update_xdomain(xd, route, link);
581 xd->route = route;
582 xd->is_unplugged = false;
583 tb_xdomain_put(xd);685 tb_xdomain_put(xd);
584 return;686 return;
585 }687 }
@@ -629,19 +731,8 @@ icm_fr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr) · 43 unmodified lines
629 return;731 return;
630 }732 }
631 733
632 xd = tb_xdomain_alloc(sw->tb, &sw->dev, route,734 add_xdomain(sw, route, &pkg->local_uuid, &pkg->remote_uuid, link,
633 &pkg->local_uuid, &pkg->remote_uuid);735 depth);
634 if (!xd) {
635 tb_switch_put(sw);
636 return;
637 }
638
639 xd->link = link;
640 xd->depth = depth;
641
642 tb_port_at(route, sw)->xdomain = xd;
643
644 tb_xdomain_add(xd);
645 tb_switch_put(sw);736 tb_switch_put(sw);
646}737}
647 738
@@ -664,6 +755,351 @@ icm_fr_xdomain_disconnected(struct tb *tb, const struct icm_pkg_header *hdr) · 16 unmodified lines
664 }755 }
665}756}
666 757
758static int
759icm_tr_driver_ready(struct tb *tb, enum tb_security_level *security_level,
760 size_t *nboot_acl)
761{
762 struct icm_tr_pkg_driver_ready_response reply;
763 struct icm_pkg_driver_ready request = {
764 .hdr.code = ICM_DRIVER_READY,
765 };
766 int ret;
767
768 memset(&reply, 0, sizeof(reply));
769 ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply),
770 1, 20000);
771 if (ret)
772 return ret;
773
774 if (security_level)
775 *security_level = reply.info & ICM_TR_INFO_SLEVEL_MASK;
776 if (nboot_acl)
777 *nboot_acl = (reply.info & ICM_TR_INFO_BOOT_ACL_MASK) >>
778 ICM_TR_INFO_BOOT_ACL_SHIFT;
779 return 0;
780}
781
782static int icm_tr_approve_switch(struct tb *tb, struct tb_switch *sw)
783{
784 struct icm_tr_pkg_approve_device request;
785 struct icm_tr_pkg_approve_device reply;
786 int ret;
787
788 memset(&request, 0, sizeof(request));
789 memcpy(&request.ep_uuid, sw->uuid, sizeof(request.ep_uuid));
790 request.hdr.code = ICM_APPROVE_DEVICE;
791 request.route_lo = sw->config.route_lo;
792 request.route_hi = sw->config.route_hi;
793 request.connection_id = sw->connection_id;
794
795 memset(&reply, 0, sizeof(reply));
796 ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply),
797 1, ICM_APPROVE_TIMEOUT);
798 if (ret)
799 return ret;
800
801 if (reply.hdr.flags & ICM_FLAGS_ERROR) {
802 tb_warn(tb, "PCIe tunnel creation failed\n");
803 return -EIO;
804 }
805
806 return 0;
807}
808
809static int icm_tr_add_switch_key(struct tb *tb, struct tb_switch *sw)
810{
811 struct icm_tr_pkg_add_device_key_response reply;
812 struct icm_tr_pkg_add_device_key request;
813 int ret;
814
815 memset(&request, 0, sizeof(request));
816 memcpy(&request.ep_uuid, sw->uuid, sizeof(request.ep_uuid));
817 request.hdr.code = ICM_ADD_DEVICE_KEY;
818 request.route_lo = sw->config.route_lo;
819 request.route_hi = sw->config.route_hi;
820 request.connection_id = sw->connection_id;
821 memcpy(request.key, sw->key, TB_SWITCH_KEY_SIZE);
822
823 memset(&reply, 0, sizeof(reply));
824 ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply),
825 1, ICM_TIMEOUT);
826 if (ret)
827 return ret;
828
829 if (reply.hdr.flags & ICM_FLAGS_ERROR) {
830 tb_warn(tb, "Adding key to switch failed\n");
831 return -EIO;
832 }
833
834 return 0;
835}
836
837static int icm_tr_challenge_switch_key(struct tb *tb, struct tb_switch *sw,
838 const u8 *challenge, u8 *response)
839{
840 struct icm_tr_pkg_challenge_device_response reply;
841 struct icm_tr_pkg_challenge_device request;
842 int ret;
843
844 memset(&request, 0, sizeof(request));
845 memcpy(&request.ep_uuid, sw->uuid, sizeof(request.ep_uuid));
846 request.hdr.code = ICM_CHALLENGE_DEVICE;
847 request.route_lo = sw->config.route_lo;
848 request.route_hi = sw->config.route_hi;
849 request.connection_id = sw->connection_id;
850 memcpy(request.challenge, challenge, TB_SWITCH_KEY_SIZE);
851
852 memset(&reply, 0, sizeof(reply));
853 ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply),
854 1, ICM_TIMEOUT);
855 if (ret)
856 return ret;
857
858 if (reply.hdr.flags & ICM_FLAGS_ERROR)
859 return -EKEYREJECTED;
860 if (reply.hdr.flags & ICM_FLAGS_NO_KEY)
861 return -ENOKEY;
862
863 memcpy(response, reply.response, TB_SWITCH_KEY_SIZE);
864
865 return 0;
866}
867
868static int icm_tr_approve_xdomain_paths(struct tb *tb, struct tb_xdomain *xd)
869{
870 struct icm_tr_pkg_approve_xdomain_response reply;
871 struct icm_tr_pkg_approve_xdomain request;
872 int ret;
873
874 memset(&request, 0, sizeof(request));
875 request.hdr.code = ICM_APPROVE_XDOMAIN;
876 request.route_hi = upper_32_bits(xd->route);
877 request.route_lo = lower_32_bits(xd->route);
878 request.transmit_path = xd->transmit_path;
879 request.transmit_ring = xd->transmit_ring;
880 request.receive_path = xd->receive_path;
881 request.receive_ring = xd->receive_ring;
882 memcpy(&request.remote_uuid, xd->remote_uuid, sizeof(*xd->remote_uuid));
883
884 memset(&reply, 0, sizeof(reply));
885 ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply),
886 1, ICM_TIMEOUT);
887 if (ret)
888 return ret;
889
890 if (reply.hdr.flags & ICM_FLAGS_ERROR)
891 return -EIO;
892
893 return 0;
894}
895
896static int icm_tr_xdomain_tear_down(struct tb *tb, struct tb_xdomain *xd,
897 int stage)
898{
899 struct icm_tr_pkg_disconnect_xdomain_response reply;
900 struct icm_tr_pkg_disconnect_xdomain request;
901 int ret;
902
903 memset(&request, 0, sizeof(request));
904 request.hdr.code = ICM_DISCONNECT_XDOMAIN;
905 request.stage = stage;
906 request.route_hi = upper_32_bits(xd->route);
907 request.route_lo = lower_32_bits(xd->route);
908 memcpy(&request.remote_uuid, xd->remote_uuid, sizeof(*xd->remote_uuid));
909
910 memset(&reply, 0, sizeof(reply));
911 ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply),
912 1, ICM_TIMEOUT);
913 if (ret)
914 return ret;
915
916 if (reply.hdr.flags & ICM_FLAGS_ERROR)
917 return -EIO;
918
919 return 0;
920}
921
922static int icm_tr_disconnect_xdomain_paths(struct tb *tb, struct tb_xdomain *xd)
923{
924 int ret;
925
926 ret = icm_tr_xdomain_tear_down(tb, xd, 1);
927 if (ret)
928 return ret;
929
930 usleep_range(10, 50);
931 return icm_tr_xdomain_tear_down(tb, xd, 2);
932}
933
934static void
935icm_tr_device_connected(struct tb *tb, const struct icm_pkg_header *hdr)
936{
937 const struct icm_tr_event_device_connected *pkg =
938 (const struct icm_tr_event_device_connected *)hdr;
939 enum tb_security_level security_level;
940 struct tb_switch *sw, *parent_sw;
941 struct tb_xdomain *xd;
942 bool authorized, boot;
943 u64 route;
944
945 /*
946 * Currently we don't use the QoS information coming with the
947 * device connected message so simply just ignore that extra
948 * packet for now.
949 */
950 if (pkg->hdr.packet_id)
951 return;
952
953 /*
954 * After NVM upgrade adding root switch device fails because we
955 * initiated reset. During that time ICM might still send device
956 * connected message which we ignore here.
957 */
958 if (!tb->root_switch)
959 return;
960
961 route = get_route(pkg->route_hi, pkg->route_lo);
962 authorized = pkg->link_info & ICM_LINK_INFO_APPROVED;
963 security_level = (pkg->hdr.flags & ICM_FLAGS_SLEVEL_MASK) >>
964 ICM_FLAGS_SLEVEL_SHIFT;
965 boot = pkg->link_info & ICM_LINK_INFO_BOOT;
966
967 if (pkg->link_info & ICM_LINK_INFO_REJECTED) {
968 tb_info(tb, "switch at %llx was rejected by ICM firmware because topology limit exceeded\n",
969 route);
970 return;
971 }
972
973 sw = tb_switch_find_by_uuid(tb, &pkg->ep_uuid);
974 if (sw) {
975 /* Update the switch if it is still in the same place */
976 if (tb_route(sw) == route && !!sw->authorized == authorized) {
977 parent_sw = tb_to_switch(sw->dev.parent);
978 update_switch(parent_sw, sw, route, pkg->connection_id,
979 0, 0, 0, boot);
980 tb_switch_put(sw);
981 return;
982 }
983
984 remove_switch(sw);
985 tb_switch_put(sw);
986 }
987
988 /* Another switch with the same address */
989 sw = tb_switch_find_by_route(tb, route);
990 if (sw) {
991 remove_switch(sw);
992 tb_switch_put(sw);
993 }
994
995 /* XDomain connection with the same address */
996 xd = tb_xdomain_find_by_route(tb, route);
997 if (xd) {
998 remove_xdomain(xd);
999 tb_xdomain_put(xd);
1000 }
1001
1002 parent_sw = tb_switch_find_by_route(tb, get_parent_route(route));
1003 if (!parent_sw) {
1004 tb_err(tb, "failed to find parent switch for %llx\n", route);
1005 return;
1006 }
1007
1008 add_switch(parent_sw, route, &pkg->ep_uuid, pkg->connection_id,
1009 0, 0, 0, security_level, authorized, boot);
1010
1011 tb_switch_put(parent_sw);
1012}
1013
1014static void
1015icm_tr_device_disconnected(struct tb *tb, const struct icm_pkg_header *hdr)
1016{
1017 const struct icm_tr_event_device_disconnected *pkg =
1018 (const struct icm_tr_event_device_disconnected *)hdr;
1019 struct tb_switch *sw;
1020 u64 route;
1021
1022 route = get_route(pkg->route_hi, pkg->route_lo);
1023
1024 sw = tb_switch_find_by_route(tb, route);
1025 if (!sw) {
1026 tb_warn(tb, "no switch exists at %llx, ignoring\n", route);
1027 return;
1028 }
1029
1030 remove_switch(sw);
1031 tb_switch_put(sw);
1032}
1033
1034static void
1035icm_tr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr)
1036{
1037 const struct icm_tr_event_xdomain_connected *pkg =
1038 (const struct icm_tr_event_xdomain_connected *)hdr;
1039 struct tb_xdomain *xd;
1040 struct tb_switch *sw;
1041 u64 route;
1042
1043 if (!tb->root_switch)
1044 return;
1045
1046 route = get_route(pkg->local_route_hi, pkg->local_route_lo);
1047
1048 xd = tb_xdomain_find_by_uuid(tb, &pkg->remote_uuid);
1049 if (xd) {
1050 if (xd->route == route) {
1051 update_xdomain(xd, route, 0);
1052 tb_xdomain_put(xd);
1053 return;
1054 }
1055
1056 remove_xdomain(xd);
1057 tb_xdomain_put(xd);
1058 }
1059
1060 /* An existing xdomain with the same address */
1061 xd = tb_xdomain_find_by_route(tb, route);
1062 if (xd) {
1063 remove_xdomain(xd);
1064 tb_xdomain_put(xd);
1065 }
1066
1067 /*
1068 * If the user disconnected a switch during suspend and
1069 * connected another host to the same port, remove the switch
1070 * first.
1071 */
1072 sw = get_switch_at_route(tb->root_switch, route);
1073 if (sw)
1074 remove_switch(sw);
1075
1076 sw = tb_switch_find_by_route(tb, get_parent_route(route));
1077 if (!sw) {
1078 tb_warn(tb, "no switch exists at %llx, ignoring\n", route);
1079 return;
1080 }
1081
1082 add_xdomain(sw, route, &pkg->local_uuid, &pkg->remote_uuid, 0, 0);
1083 tb_switch_put(sw);
1084}
1085
1086static void
1087icm_tr_xdomain_disconnected(struct tb *tb, const struct icm_pkg_header *hdr)
1088{
1089 const struct icm_tr_event_xdomain_disconnected *pkg =
1090 (const struct icm_tr_event_xdomain_disconnected *)hdr;
1091 struct tb_xdomain *xd;
1092 u64 route;
1093
1094 route = get_route(pkg->route_hi, pkg->route_lo);
1095
1096 xd = tb_xdomain_find_by_route(tb, route);
1097 if (xd) {
1098 remove_xdomain(xd);
1099 tb_xdomain_put(xd);
1100 }
1101}
1102
667static struct pci_dev *get_upstream_port(struct pci_dev *pdev)1103static struct pci_dev *get_upstream_port(struct pci_dev *pdev)
668{1104{
669 struct pci_dev *parent;1105 struct pci_dev *parent;
@@ -728,14 +1164,14 @@ static bool icm_ar_is_supported(struct tb *tb) · 58 unmodified lines
728static int icm_ar_get_mode(struct tb *tb)1164static int icm_ar_get_mode(struct tb *tb)
729{1165{
730 struct tb_nhi *nhi = tb->nhi;1166 struct tb_nhi *nhi = tb->nhi;
731 int retries = 5;1167 int retries = 60;
732 u32 val;1168 u32 val;
733 1169
734 do {1170 do {
735 val = ioread32(nhi->iobase + REG_FW_STS);1171 val = ioread32(nhi->iobase + REG_FW_STS);
736 if (val & REG_FW_STS_NVM_AUTH_DONE)1172 if (val & REG_FW_STS_NVM_AUTH_DONE)
737 break;1173 break;
738 msleep(30);1174 msleep(50);
739 } while (--retries);1175 } while (--retries);
740 1176
741 if (!retries) {1177 if (!retries) {
@@ -746,6 +1182,30 @@ static int icm_ar_get_mode(struct tb *tb) · 4 unmodified lines
746 return nhi_mailbox_mode(nhi);1182 return nhi_mailbox_mode(nhi);
747}1183}
748 1184
1185static int
1186icm_ar_driver_ready(struct tb *tb, enum tb_security_level *security_level,
1187 size_t *nboot_acl)
1188{
1189 struct icm_ar_pkg_driver_ready_response reply;
1190 struct icm_pkg_driver_ready request = {
1191 .hdr.code = ICM_DRIVER_READY,
1192 };
1193 int ret;
1194
1195 memset(&reply, 0, sizeof(reply));
1196 ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply),
1197 1, ICM_TIMEOUT);
1198 if (ret)
1199 return ret;
1200
1201 if (security_level)
1202 *security_level = reply.info & ICM_AR_INFO_SLEVEL_MASK;
1203 if (nboot_acl && (reply.info & ICM_AR_INFO_BOOT_ACL_SUPPORTED))
1204 *nboot_acl = (reply.info & ICM_AR_INFO_BOOT_ACL_MASK) >>
1205 ICM_AR_INFO_BOOT_ACL_SHIFT;
1206 return 0;
1207}
1208
749static int icm_ar_get_route(struct tb *tb, u8 link, u8 depth, u64 *route)1209static int icm_ar_get_route(struct tb *tb, u8 link, u8 depth, u64 *route)
750{1210{
751 struct icm_ar_pkg_get_route_response reply;1211 struct icm_ar_pkg_get_route_response reply;
@@ -768,6 +1228,87 @@ static int icm_ar_get_route(struct tb *tb, u8 link, u8 depth, u64 *route) · 16 unmodified lines
768 return 0;1228 return 0;
769}1229}
770 1230
1231static int icm_ar_get_boot_acl(struct tb *tb, uuid_t *uuids, size_t nuuids)
1232{
1233 struct icm_ar_pkg_preboot_acl_response reply;
1234 struct icm_ar_pkg_preboot_acl request = {
1235 .hdr = { .code = ICM_PREBOOT_ACL },
1236 };
1237 int ret, i;
1238
1239 memset(&reply, 0, sizeof(reply));
1240 ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply),
1241 1, ICM_TIMEOUT);
1242 if (ret)
1243 return ret;
1244
1245 if (reply.hdr.flags & ICM_FLAGS_ERROR)
1246 return -EIO;
1247
1248 for (i = 0; i < nuuids; i++) {
1249 u32 *uuid = (u32 *)&uuids[i];
1250
1251 uuid[0] = reply.acl[i].uuid_lo;
1252 uuid[1] = reply.acl[i].uuid_hi;
1253
1254 if (uuid[0] == 0xffffffff && uuid[1] == 0xffffffff) {
1255 /* Map empty entries to null UUID */
1256 uuid[0] = 0;
1257 uuid[1] = 0;
1258 } else {
1259 /* Upper two DWs are always one's */
1260 uuid[2] = 0xffffffff;
1261 uuid[3] = 0xffffffff;
1262 }
1263 }
1264
1265 return ret;
1266}
1267
1268static int icm_ar_set_boot_acl(struct tb *tb, const uuid_t *uuids,
1269 size_t nuuids)
1270{
1271 struct icm_ar_pkg_preboot_acl_response reply;
1272 struct icm_ar_pkg_preboot_acl request = {
1273 .hdr = {
1274 .code = ICM_PREBOOT_ACL,
1275 .flags = ICM_FLAGS_WRITE,
1276 },
1277 };
1278 int ret, i;
1279
1280 for (i = 0; i < nuuids; i++) {
1281 const u32 *uuid = (const u32 *)&uuids[i];
1282
1283 if (uuid_is_null(&uuids[i])) {
1284 /*
1285 * Map null UUID to the empty (all one) entries
1286 * for ICM.
1287 */
1288 request.acl[i].uuid_lo = 0xffffffff;
1289 request.acl[i].uuid_hi = 0xffffffff;
1290 } else {
1291 /* Two high DWs need to be set to all one */
1292 if (uuid[2] != 0xffffffff || uuid[3] != 0xffffffff)
1293 return -EINVAL;
1294
1295 request.acl[i].uuid_lo = uuid[0];
1296 request.acl[i].uuid_hi = uuid[1];
1297 }
1298 }
1299
1300 memset(&reply, 0, sizeof(reply));
1301 ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply),
1302 1, ICM_TIMEOUT);
1303 if (ret)
1304 return ret;
1305
1306 if (reply.hdr.flags & ICM_FLAGS_ERROR)
1307 return -EIO;
1308
1309 return 0;
1310}
1311
771static void icm_handle_notification(struct work_struct *work)1312static void icm_handle_notification(struct work_struct *work)
772{1313{
773 struct icm_notification *n = container_of(work, typeof(*n), work);1314 struct icm_notification *n = container_of(work, typeof(*n), work);
@@ -814,23 +1355,18 @@ static void icm_handle_event(struct tb *tb, enum tb_cfg_pkg_type type, · 40 unmodified lines
814}1355}
815 1356
816static int1357static int
817__icm_driver_ready(struct tb *tb, enum tb_security_level *security_level)1358__icm_driver_ready(struct tb *tb, enum tb_security_level *security_level,
1359 size_t *nboot_acl)
818{1360{
819 struct icm_pkg_driver_ready_response reply;1361 struct icm *icm = tb_priv(tb);
820 struct icm_pkg_driver_ready request = {1362 unsigned int retries = 50;
821 .hdr.code = ICM_DRIVER_READY,
822 };
823 unsigned int retries = 10;
824 int ret;1363 int ret;
825 1364
826 memset(&reply, 0, sizeof(reply));1365 ret = icm->driver_ready(tb, security_level, nboot_acl);
827 ret = icm_request(tb, &request, sizeof(request), &reply, sizeof(reply),1366 if (ret) {
828 1, ICM_TIMEOUT);1367 tb_err(tb, "failed to send driver ready to ICM\n");
829 if (ret)
830 return ret;1368 return ret;
831 1369 }
832 if (security_level)
833 *security_level = reply.security_level & 0xf;
834 1370
835 /*1371 /*
836 * Hold on here until the switch config space is accessible so1372 * Hold on here until the switch config space is accessible so
@@ -848,6 +1384,7 @@ __icm_driver_ready(struct tb *tb, enum tb_security_level *security_level) · 11 unmodified lines
848 msleep(50);1384 msleep(50);
849 } while (--retries);1385 } while (--retries);
850 1386
1387 tb_err(tb, "failed to read root switch config space, giving up\n");
851 return -ETIMEDOUT;1388 return -ETIMEDOUT;
852}1389}
853 1390
@@ -915,6 +1452,9 @@ static int icm_firmware_reset(struct tb *tb, struct tb_nhi *nhi) · 61 unmodified lines
915 struct icm *icm = tb_priv(tb);1452 struct icm *icm = tb_priv(tb);
916 u32 val;1453 u32 val;
917 1454
1455 if (!icm->upstream_port)
1456 return -ENODEV;
1457
918 /* Put ARC to wait for CIO reset event to happen */1458 /* Put ARC to wait for CIO reset event to happen */
919 val = ioread32(nhi->iobase + REG_FW_STS);1459 val = ioread32(nhi->iobase + REG_FW_STS);
920 val |= REG_FW_STS_CIO_RESET_REQ;1460 val |= REG_FW_STS_CIO_RESET_REQ;
@@ -1054,6 +1594,9 @@ static int icm_firmware_init(struct tb *tb) · 133 unmodified lines
1054 break;1594 break;
1055 1595
1056 default:1596 default:
1597 if (ret < 0)
1598 return ret;
1599
1057 tb_err(tb, "ICM firmware is in wrong mode: %u\n", ret);1600 tb_err(tb, "ICM firmware is in wrong mode: %u\n", ret);
1058 return -ENODEV;1601 return -ENODEV;
1059 }1602 }
@@ -1089,7 +1632,18 @@ static int icm_driver_ready(struct tb *tb) · 29 unmodified lines
1089 return 0;1632 return 0;
1090 }1633 }
1091 1634
1092 return __icm_driver_ready(tb, &tb->security_level);1635 ret = __icm_driver_ready(tb, &tb->security_level, &tb->nboot_acl);
1636 if (ret)
1637 return ret;
1638
1639 /*
1640 * Make sure the number of supported preboot ACL matches what we
1641 * expect or disable the whole feature.
1642 */
1643 if (tb->nboot_acl > icm->max_boot_acl)
1644 tb->nboot_acl = 0;
1645
1646 return 0;
1093}1647}
1094 1648
1095static int icm_suspend(struct tb *tb)1649static int icm_suspend(struct tb *tb)
@@ -1185,7 +1739,7 @@ static void icm_complete(struct tb *tb) · 89 unmodified lines
1185 * Now all existing children should be resumed, start events1739 * Now all existing children should be resumed, start events
1186 * from ICM to get updated status.1740 * from ICM to get updated status.
1187 */1741 */
1188 __icm_driver_ready(tb, NULL);1742 __icm_driver_ready(tb, NULL, NULL);
1189 1743
1190 /*1744 /*
1191 * We do not get notifications of devices that have been1745 * We do not get notifications of devices that have been
@@ -1238,7 +1792,7 @@ static int icm_disconnect_pcie_paths(struct tb *tb) · 46 unmodified lines
1238 return nhi_mailbox_cmd(tb->nhi, NHI_MAILBOX_DISCONNECT_PCIE_PATHS, 0);1792 return nhi_mailbox_cmd(tb->nhi, NHI_MAILBOX_DISCONNECT_PCIE_PATHS, 0);
1239}1793}
1240 1794
1241/* Falcon Ridge and Alpine Ridge */1795/* Falcon Ridge */
1242static const struct tb_cm_ops icm_fr_ops = {1796static const struct tb_cm_ops icm_fr_ops = {
1243 .driver_ready = icm_driver_ready,1797 .driver_ready = icm_driver_ready,
1244 .start = icm_start,1798 .start = icm_start,
@@ -1254,6 +1808,42 @@ static const struct tb_cm_ops icm_fr_ops = { · 9 unmodified lines
1254 .disconnect_xdomain_paths = icm_fr_disconnect_xdomain_paths,1808 .disconnect_xdomain_paths = icm_fr_disconnect_xdomain_paths,
1255};1809};
1256 1810
1811/* Alpine Ridge */
1812static const struct tb_cm_ops icm_ar_ops = {
1813 .driver_ready = icm_driver_ready,
1814 .start = icm_start,
1815 .stop = icm_stop,
1816 .suspend = icm_suspend,
1817 .complete = icm_complete,
1818 .handle_event = icm_handle_event,
1819 .get_boot_acl = icm_ar_get_boot_acl,
1820 .set_boot_acl = icm_ar_set_boot_acl,
1821 .approve_switch = icm_fr_approve_switch,
1822 .add_switch_key = icm_fr_add_switch_key,
1823 .challenge_switch_key = icm_fr_challenge_switch_key,
1824 .disconnect_pcie_paths = icm_disconnect_pcie_paths,
1825 .approve_xdomain_paths = icm_fr_approve_xdomain_paths,
1826 .disconnect_xdomain_paths = icm_fr_disconnect_xdomain_paths,
1827};
1828
1829/* Titan Ridge */
1830static const struct tb_cm_ops icm_tr_ops = {
1831 .driver_ready = icm_driver_ready,
1832 .start = icm_start,
1833 .stop = icm_stop,
1834 .suspend = icm_suspend,
1835 .complete = icm_complete,
1836 .handle_event = icm_handle_event,
1837 .get_boot_acl = icm_ar_get_boot_acl,
1838 .set_boot_acl = icm_ar_set_boot_acl,
1839 .approve_switch = icm_tr_approve_switch,
1840 .add_switch_key = icm_tr_add_switch_key,
1841 .challenge_switch_key = icm_tr_challenge_switch_key,
1842 .disconnect_pcie_paths = icm_disconnect_pcie_paths,
1843 .approve_xdomain_paths = icm_tr_approve_xdomain_paths,
1844 .disconnect_xdomain_paths = icm_tr_disconnect_xdomain_paths,
1845};
1846
1257struct tb *icm_probe(struct tb_nhi *nhi)1847struct tb *icm_probe(struct tb_nhi *nhi)
1258{1848{
1259 struct icm *icm;1849 struct icm *icm;
@@ -1272,6 +1862,7 @@ struct tb *icm_probe(struct tb_nhi *nhi) · 12 unmodified lines
1272 case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI:1862 case PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI:
1273 icm->is_supported = icm_fr_is_supported;1863 icm->is_supported = icm_fr_is_supported;
1274 icm->get_route = icm_fr_get_route;1864 icm->get_route = icm_fr_get_route;
1865 icm->driver_ready = icm_fr_driver_ready;
1275 icm->device_connected = icm_fr_device_connected;1866 icm->device_connected = icm_fr_device_connected;
1276 icm->device_disconnected = icm_fr_device_disconnected;1867 icm->device_disconnected = icm_fr_device_disconnected;
1277 icm->xdomain_connected = icm_fr_xdomain_connected;1868 icm->xdomain_connected = icm_fr_xdomain_connected;
@@ -1284,14 +1875,29 @@ struct tb *icm_probe(struct tb_nhi *nhi) · 6 unmodified lines
1284 case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_NHI:1875 case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_NHI:
1285 case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_NHI:1876 case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_NHI:
1286 case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_NHI:1877 case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_NHI:
1878 icm->max_boot_acl = ICM_AR_PREBOOT_ACL_ENTRIES;
1287 icm->is_supported = icm_ar_is_supported;1879 icm->is_supported = icm_ar_is_supported;
1288 icm->get_mode = icm_ar_get_mode;1880 icm->get_mode = icm_ar_get_mode;
1289 icm->get_route = icm_ar_get_route;1881 icm->get_route = icm_ar_get_route;
1882 icm->driver_ready = icm_ar_driver_ready;
1290 icm->device_connected = icm_fr_device_connected;1883 icm->device_connected = icm_fr_device_connected;
1291 icm->device_disconnected = icm_fr_device_disconnected;1884 icm->device_disconnected = icm_fr_device_disconnected;
1292 icm->xdomain_connected = icm_fr_xdomain_connected;1885 icm->xdomain_connected = icm_fr_xdomain_connected;
1293 icm->xdomain_disconnected = icm_fr_xdomain_disconnected;1886 icm->xdomain_disconnected = icm_fr_xdomain_disconnected;
1294 tb->cm_ops = &icm_fr_ops;1887 tb->cm_ops = &icm_ar_ops;
1888 break;
1889
1890 case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_NHI:
1891 case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_NHI:
1892 icm->max_boot_acl = ICM_AR_PREBOOT_ACL_ENTRIES;
1893 icm->is_supported = icm_ar_is_supported;
1894 icm->get_mode = icm_ar_get_mode;
1895 icm->driver_ready = icm_tr_driver_ready;
1896 icm->device_connected = icm_tr_device_connected;
1897 icm->device_disconnected = icm_tr_device_disconnected;
1898 icm->xdomain_connected = icm_tr_xdomain_connected;
1899 icm->xdomain_disconnected = icm_tr_xdomain_disconnected;
1900 tb->cm_ops = &icm_tr_ops;
1295 break;1901 break;
1296 }1902 }
1297 1903
drivers/thunderbolt/nhi.c+4−1
@@ -1036,7 +1036,7 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 1035 unmodified lines
1036 */1036 */
1037 tb_domain_put(tb);1037 tb_domain_put(tb);
1038 nhi_shutdown(nhi);1038 nhi_shutdown(nhi);
1039 return -EIO;1039 return res;
1040 }1040 }
1041 pci_set_drvdata(pdev, tb);1041 pci_set_drvdata(pdev, tb);
1042 1042
@@ -1064,6 +1064,7 @@ static const struct dev_pm_ops nhi_pm_ops = { · 21 unmodified lines
1064 * we just disable hotplug, the1064 * we just disable hotplug, the
1065 * pci-tunnels stay alive.1065 * pci-tunnels stay alive.
1066 */1066 */
1067 .thaw_noirq = nhi_resume_noirq,
1067 .restore_noirq = nhi_resume_noirq,1068 .restore_noirq = nhi_resume_noirq,
1068 .suspend = nhi_suspend,1069 .suspend = nhi_suspend,
1069 .freeze = nhi_suspend,1070 .freeze = nhi_suspend,
@@ -1110,6 +1111,8 @@ static struct pci_device_id nhi_ids[] = { · 40 unmodified lines
1110 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_NHI) },1111 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_NHI) },
1111 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_NHI) },1112 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_NHI) },
1112 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_USBONLY_NHI) },1113 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_USBONLY_NHI) },
1114 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_NHI) },
1115 { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_NHI) },
1113 1116
1114 { 0,}1117 { 0,}
1115};1118};
drivers/thunderbolt/nhi.h+5−0
@@ -45,5 +45,10 @@ enum nhi_fw_mode nhi_mailbox_mode(struct tb_nhi *nhi); · 44 unmodified lines
45#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_USBONLY_NHI 0x15dc45#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_USBONLY_NHI 0x15dc
46#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_USBONLY_NHI 0x15dd46#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_USBONLY_NHI 0x15dd
47#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_USBONLY_NHI 0x15de47#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_USBONLY_NHI 0x15de
48#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_BRIDGE 0x15e7
49#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_NHI 0x15e8
50#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_BRIDGE 0x15ea
51#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_NHI 0x15eb
52#define PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_BRIDGE 0x15ef
48 53
49#endif54#endif
drivers/thunderbolt/switch.c+60−1
@@ -716,6 +716,13 @@ static int tb_switch_set_authorized(struct tb_switch *sw, unsigned int val) · 715 unmodified lines
716 if (sw->authorized)716 if (sw->authorized)
717 goto unlock;717 goto unlock;
718 718
719 /*
720 * Make sure there is no PCIe rescan ongoing when a new PCIe
721 * tunnel is created. Otherwise the PCIe rescan code might find
722 * the new tunnel too early.
723 */
724 pci_lock_rescan_remove();
725
719 switch (val) {726 switch (val) {
720 /* Approve switch */727 /* Approve switch */
721 case 1:728 case 1:
@@ -735,6 +742,8 @@ static int tb_switch_set_authorized(struct tb_switch *sw, unsigned int val) · 13 unmodified lines
735 break;742 break;
736 }743 }
737 744
745 pci_unlock_rescan_remove();
746
738 if (!ret) {747 if (!ret) {
739 sw->authorized = val;748 sw->authorized = val;
740 /* Notify status change to the userspace */749 /* Notify status change to the userspace */
@@ -766,6 +775,15 @@ static ssize_t authorized_store(struct device *dev, · 25 unmodified lines
766}775}
767static DEVICE_ATTR_RW(authorized);776static DEVICE_ATTR_RW(authorized);
768 777
778static ssize_t boot_show(struct device *dev, struct device_attribute *attr,
779 char *buf)
780{
781 struct tb_switch *sw = tb_to_switch(dev);
782
783 return sprintf(buf, "%u\n", sw->boot);
784}
785static DEVICE_ATTR_RO(boot);
786
769static ssize_t device_show(struct device *dev, struct device_attribute *attr,787static ssize_t device_show(struct device *dev, struct device_attribute *attr,
770 char *buf)788 char *buf)
771{789{
@@ -942,6 +960,7 @@ static DEVICE_ATTR_RO(unique_id); · 170 unmodified lines
942 960
943static struct attribute *switch_attrs[] = {961static struct attribute *switch_attrs[] = {
944 &dev_attr_authorized.attr,962 &dev_attr_authorized.attr,
963 &dev_attr_boot.attr,
945 &dev_attr_device.attr,964 &dev_attr_device.attr,
946 &dev_attr_device_name.attr,965 &dev_attr_device_name.attr,
947 &dev_attr_key.attr,966 &dev_attr_key.attr,
@@ -970,6 +989,10 @@ static umode_t switch_attr_is_visible(struct kobject *kobj, · 22 unmodified lines
970 if (sw->dma_port)989 if (sw->dma_port)
971 return attr->mode;990 return attr->mode;
972 return 0;991 return 0;
992 } else if (attr == &dev_attr_boot.attr) {
993 if (tb_route(sw))
994 return attr->mode;
995 return 0;
973 }996 }
974 997
975 return sw->safe_mode ? 0 : attr->mode;998 return sw->safe_mode ? 0 : attr->mode;
@@ -1028,6 +1051,9 @@ static int tb_switch_get_generation(struct tb_switch *sw) · 52 unmodified lines
1028 case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_BRIDGE:1051 case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_BRIDGE:
1029 case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_BRIDGE:1052 case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_BRIDGE:
1030 case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_BRIDGE:1053 case PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_BRIDGE:
1054 case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_2C_BRIDGE:
1055 case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_4C_BRIDGE:
1056 case PCI_DEVICE_ID_INTEL_TITAN_RIDGE_DD_BRIDGE:
1031 return 3;1057 return 3;
1032 1058
1033 default:1059 default:
@@ -1470,6 +1496,7 @@ struct tb_sw_lookup { · 436 unmodified lines
1470 u8 link;1496 u8 link;
1471 u8 depth;1497 u8 depth;
1472 const uuid_t *uuid;1498 const uuid_t *uuid;
1499 u64 route;
1473};1500};
1474 1501
1475static int tb_switch_match(struct device *dev, void *data)1502static int tb_switch_match(struct device *dev, void *data)
@@ -1485,6 +1512,11 @@ static int tb_switch_match(struct device *dev, void *data) · 9 unmodified lines
1485 if (lookup->uuid)1512 if (lookup->uuid)
1486 return !memcmp(sw->uuid, lookup->uuid, sizeof(*lookup->uuid));1513 return !memcmp(sw->uuid, lookup->uuid, sizeof(*lookup->uuid));
1487 1514
1515 if (lookup->route) {
1516 return sw->config.route_lo == lower_32_bits(lookup->route) &&
1517 sw->config.route_hi == upper_32_bits(lookup->route);
1518 }
1519
1488 /* Root switch is matched only by depth */1520 /* Root switch is matched only by depth */
1489 if (!lookup->depth)1521 if (!lookup->depth)
1490 return !sw->depth;1522 return !sw->depth;
@@ -1519,7 +1551,7 @@ struct tb_switch *tb_switch_find_by_link_depth(struct tb *tb, u8 link, u8 depth) · 28 unmodified lines
1519}1551}
1520 1552
1521/**1553/**
1522 * tb_switch_find_by_link_depth() - Find switch by UUID1554 * tb_switch_find_by_uuid() - Find switch by UUID
1523 * @tb: Domain the switch belongs1555 * @tb: Domain the switch belongs
1524 * @uuid: UUID to look for1556 * @uuid: UUID to look for
1525 *1557 *
@@ -1542,6 +1574,33 @@ struct tb_switch *tb_switch_find_by_uuid(struct tb *tb, const uuid_t *uuid) · 16 unmodified lines
1542 return NULL;1574 return NULL;
1543}1575}
1544 1576
1577/**
1578 * tb_switch_find_by_route() - Find switch by route string
1579 * @tb: Domain the switch belongs
1580 * @route: Route string to look for
1581 *
1582 * Returned switch has reference count increased so the caller needs to
1583 * call tb_switch_put() when done with the switch.
1584 */
1585struct tb_switch *tb_switch_find_by_route(struct tb *tb, u64 route)
1586{
1587 struct tb_sw_lookup lookup;
1588 struct device *dev;
1589
1590 if (!route)
1591 return tb_switch_get(tb->root_switch);
1592
1593 memset(&lookup, 0, sizeof(lookup));
1594 lookup.tb = tb;
1595 lookup.route = route;
1596
1597 dev = bus_find_device(&tb_bus_type, NULL, &lookup, tb_switch_match);
1598 if (dev)
1599 return tb_to_switch(dev);
1600
1601 return NULL;
1602}
1603
1545void tb_switch_exit(void)1604void tb_switch_exit(void)
1546{1605{
1547 ida_destroy(&nvm_ida);1606 ida_destroy(&nvm_ida);
drivers/thunderbolt/tb.h+14−0
@@ -66,6 +66,7 @@ struct tb_switch_nvm { · 65 unmodified lines
66 * @nvm: Pointer to the NVM if the switch has one (%NULL otherwise)66 * @nvm: Pointer to the NVM if the switch has one (%NULL otherwise)
67 * @no_nvm_upgrade: Prevent NVM upgrade of this switch67 * @no_nvm_upgrade: Prevent NVM upgrade of this switch
68 * @safe_mode: The switch is in safe-mode68 * @safe_mode: The switch is in safe-mode
69 * @boot: Whether the switch was already authorized on boot or not
69 * @authorized: Whether the switch is authorized by user or policy70 * @authorized: Whether the switch is authorized by user or policy
70 * @work: Work used to automatically authorize a switch71 * @work: Work used to automatically authorize a switch
71 * @security_level: Switch supported security level72 * @security_level: Switch supported security level
@@ -99,6 +100,7 @@ struct tb_switch { · 27 unmodified lines
99 struct tb_switch_nvm *nvm;100 struct tb_switch_nvm *nvm;
100 bool no_nvm_upgrade;101 bool no_nvm_upgrade;
101 bool safe_mode;102 bool safe_mode;
103 bool boot;
102 unsigned int authorized;104 unsigned int authorized;
103 struct work_struct work;105 struct work_struct work;
104 enum tb_security_level security_level;106 enum tb_security_level security_level;
@@ -198,6 +200,8 @@ struct tb_path { · 93 unmodified lines
198 * @suspend: Connection manager specific suspend200 * @suspend: Connection manager specific suspend
199 * @complete: Connection manager specific complete201 * @complete: Connection manager specific complete
200 * @handle_event: Handle thunderbolt event202 * @handle_event: Handle thunderbolt event
203 * @get_boot_acl: Get boot ACL list
204 * @set_boot_acl: Set boot ACL list
201 * @approve_switch: Approve switch205 * @approve_switch: Approve switch
202 * @add_switch_key: Add key to switch206 * @add_switch_key: Add key to switch
203 * @challenge_switch_key: Challenge switch using key207 * @challenge_switch_key: Challenge switch using key
@@ -215,6 +219,8 @@ struct tb_cm_ops { · 11 unmodified lines
215 void (*complete)(struct tb *tb);219 void (*complete)(struct tb *tb);
216 void (*handle_event)(struct tb *tb, enum tb_cfg_pkg_type,220 void (*handle_event)(struct tb *tb, enum tb_cfg_pkg_type,
217 const void *buf, size_t size);221 const void *buf, size_t size);
222 int (*get_boot_acl)(struct tb *tb, uuid_t *uuids, size_t nuuids);
223 int (*set_boot_acl)(struct tb *tb, const uuid_t *uuids, size_t nuuids);
218 int (*approve_switch)(struct tb *tb, struct tb_switch *sw);224 int (*approve_switch)(struct tb *tb, struct tb_switch *sw);
219 int (*add_switch_key)(struct tb *tb, struct tb_switch *sw);225 int (*add_switch_key)(struct tb *tb, struct tb_switch *sw);
220 int (*challenge_switch_key)(struct tb *tb, struct tb_switch *sw,226 int (*challenge_switch_key)(struct tb *tb, struct tb_switch *sw,
@@ -386,6 +392,14 @@ struct tb_switch *get_switch_at_route(struct tb_switch *sw, u64 route); · 165 unmodified lines
386struct tb_switch *tb_switch_find_by_link_depth(struct tb *tb, u8 link,392struct tb_switch *tb_switch_find_by_link_depth(struct tb *tb, u8 link,
387 u8 depth);393 u8 depth);
388struct tb_switch *tb_switch_find_by_uuid(struct tb *tb, const uuid_t *uuid);394struct tb_switch *tb_switch_find_by_uuid(struct tb *tb, const uuid_t *uuid);
395struct tb_switch *tb_switch_find_by_route(struct tb *tb, u64 route);
396
397static inline struct tb_switch *tb_switch_get(struct tb_switch *sw)
398{
399 if (sw)
400 get_device(&sw->dev);
401 return sw;
402}
389 403
390static inline void tb_switch_put(struct tb_switch *sw)404static inline void tb_switch_put(struct tb_switch *sw)
391{405{
drivers/thunderbolt/tb_msgs.h+179−1
@@ -102,6 +102,8 @@ enum icm_pkg_code { · 101 unmodified lines
102 ICM_ADD_DEVICE_KEY = 0x6,102 ICM_ADD_DEVICE_KEY = 0x6,
103 ICM_GET_ROUTE = 0xa,103 ICM_GET_ROUTE = 0xa,
104 ICM_APPROVE_XDOMAIN = 0x10,104 ICM_APPROVE_XDOMAIN = 0x10,
105 ICM_DISCONNECT_XDOMAIN = 0x11,
106 ICM_PREBOOT_ACL = 0x18,
105};107};
106 108
107enum icm_event_code {109enum icm_event_code {
@@ -122,18 +124,23 @@ struct icm_pkg_header { · 14 unmodified lines
122#define ICM_FLAGS_NO_KEY BIT(1)124#define ICM_FLAGS_NO_KEY BIT(1)
123#define ICM_FLAGS_SLEVEL_SHIFT 3125#define ICM_FLAGS_SLEVEL_SHIFT 3
124#define ICM_FLAGS_SLEVEL_MASK GENMASK(4, 3)126#define ICM_FLAGS_SLEVEL_MASK GENMASK(4, 3)
127#define ICM_FLAGS_WRITE BIT(7)
125 128
126struct icm_pkg_driver_ready {129struct icm_pkg_driver_ready {
127 struct icm_pkg_header hdr;130 struct icm_pkg_header hdr;
128};131};
129 132
130struct icm_pkg_driver_ready_response {133/* Falcon Ridge only messages */
134
135struct icm_fr_pkg_driver_ready_response {
131 struct icm_pkg_header hdr;136 struct icm_pkg_header hdr;
132 u8 romver;137 u8 romver;
133 u8 ramver;138 u8 ramver;
134 u16 security_level;139 u16 security_level;
135};140};
136 141
142#define ICM_FR_SLEVEL_MASK 0xf
143
137/* Falcon Ridge & Alpine Ridge common messages */144/* Falcon Ridge & Alpine Ridge common messages */
138 145
139struct icm_fr_pkg_get_topology {146struct icm_fr_pkg_get_topology {
@@ -176,6 +183,8 @@ struct icm_fr_event_device_connected { · 36 unmodified lines
176#define ICM_LINK_INFO_DEPTH_SHIFT 4183#define ICM_LINK_INFO_DEPTH_SHIFT 4
177#define ICM_LINK_INFO_DEPTH_MASK GENMASK(7, 4)184#define ICM_LINK_INFO_DEPTH_MASK GENMASK(7, 4)
178#define ICM_LINK_INFO_APPROVED BIT(8)185#define ICM_LINK_INFO_APPROVED BIT(8)
186#define ICM_LINK_INFO_REJECTED BIT(9)
187#define ICM_LINK_INFO_BOOT BIT(10)
179 188
180struct icm_fr_pkg_approve_device {189struct icm_fr_pkg_approve_device {
181 struct icm_pkg_header hdr;190 struct icm_pkg_header hdr;
@@ -270,6 +279,18 @@ struct icm_fr_pkg_approve_xdomain_response { · 88 unmodified lines
270 279
271/* Alpine Ridge only messages */280/* Alpine Ridge only messages */
272 281
282struct icm_ar_pkg_driver_ready_response {
283 struct icm_pkg_header hdr;
284 u8 romver;
285 u8 ramver;
286 u16 info;
287};
288
289#define ICM_AR_INFO_SLEVEL_MASK GENMASK(3, 0)
290#define ICM_AR_INFO_BOOT_ACL_SHIFT 7
291#define ICM_AR_INFO_BOOT_ACL_MASK GENMASK(11, 7)
292#define ICM_AR_INFO_BOOT_ACL_SUPPORTED BIT(13)
293
273struct icm_ar_pkg_get_route {294struct icm_ar_pkg_get_route {
274 struct icm_pkg_header hdr;295 struct icm_pkg_header hdr;
275 u16 reserved;296 u16 reserved;
@@ -284,6 +305,163 @@ struct icm_ar_pkg_get_route_response { · 8 unmodified lines
284 u32 route_lo;305 u32 route_lo;
285};306};
286 307
308struct icm_ar_boot_acl_entry {
309 u32 uuid_lo;
310 u32 uuid_hi;
311};
312
313#define ICM_AR_PREBOOT_ACL_ENTRIES 16
314
315struct icm_ar_pkg_preboot_acl {
316 struct icm_pkg_header hdr;
317 struct icm_ar_boot_acl_entry acl[ICM_AR_PREBOOT_ACL_ENTRIES];
318};
319
320struct icm_ar_pkg_preboot_acl_response {
321 struct icm_pkg_header hdr;
322 struct icm_ar_boot_acl_entry acl[ICM_AR_PREBOOT_ACL_ENTRIES];
323};
324
325/* Titan Ridge messages */
326
327struct icm_tr_pkg_driver_ready_response {
328 struct icm_pkg_header hdr;
329 u16 reserved1;
330 u16 info;
331 u32 nvm_version;
332 u16 device_id;
333 u16 reserved2;
334};
335
336#define ICM_TR_INFO_SLEVEL_MASK GENMASK(2, 0)
337#define ICM_TR_INFO_BOOT_ACL_SHIFT 7
338#define ICM_TR_INFO_BOOT_ACL_MASK GENMASK(12, 7)
339
340struct icm_tr_event_device_connected {
341 struct icm_pkg_header hdr;
342 uuid_t ep_uuid;
343 u32 route_hi;
344 u32 route_lo;
345 u8 connection_id;
346 u8 reserved;
347 u16 link_info;
348 u32 ep_name[55];
349};
350
351struct icm_tr_event_device_disconnected {
352 struct icm_pkg_header hdr;
353 u32 route_hi;
354 u32 route_lo;
355};
356
357struct icm_tr_event_xdomain_connected {
358 struct icm_pkg_header hdr;
359 u16 reserved;
360 u16 link_info;
361 uuid_t remote_uuid;
362 uuid_t local_uuid;
363 u32 local_route_hi;
364 u32 local_route_lo;
365 u32 remote_route_hi;
366 u32 remote_route_lo;
367};
368
369struct icm_tr_event_xdomain_disconnected {
370 struct icm_pkg_header hdr;
371 u32 route_hi;
372 u32 route_lo;
373 uuid_t remote_uuid;
374};
375
376struct icm_tr_pkg_approve_device {
377 struct icm_pkg_header hdr;
378 uuid_t ep_uuid;
379 u32 route_hi;
380 u32 route_lo;
381 u8 connection_id;
382 u8 reserved1[3];
383};
384
385struct icm_tr_pkg_add_device_key {
386 struct icm_pkg_header hdr;
387 uuid_t ep_uuid;
388 u32 route_hi;
389 u32 route_lo;
390 u8 connection_id;
391 u8 reserved[3];
392 u32 key[8];
393};
394
395struct icm_tr_pkg_challenge_device {
396 struct icm_pkg_header hdr;
397 uuid_t ep_uuid;
398 u32 route_hi;
399 u32 route_lo;
400 u8 connection_id;
401 u8 reserved[3];
402 u32 challenge[8];
403};
404
405struct icm_tr_pkg_approve_xdomain {
406 struct icm_pkg_header hdr;
407 u32 route_hi;
408 u32 route_lo;
409 uuid_t remote_uuid;
410 u16 transmit_path;
411 u16 transmit_ring;
412 u16 receive_path;
413 u16 receive_ring;
414};
415
416struct icm_tr_pkg_disconnect_xdomain {
417 struct icm_pkg_header hdr;
418 u8 stage;
419 u8 reserved[3];
420 u32 route_hi;
421 u32 route_lo;
422 uuid_t remote_uuid;
423};
424
425struct icm_tr_pkg_challenge_device_response {
426 struct icm_pkg_header hdr;
427 uuid_t ep_uuid;
428 u32 route_hi;
429 u32 route_lo;
430 u8 connection_id;
431 u8 reserved[3];
432 u32 challenge[8];
433 u32 response[8];
434};
435
436struct icm_tr_pkg_add_device_key_response {
437 struct icm_pkg_header hdr;
438 uuid_t ep_uuid;
439 u32 route_hi;
440 u32 route_lo;
441 u8 connection_id;
442 u8 reserved[3];
443};
444
445struct icm_tr_pkg_approve_xdomain_response {
446 struct icm_pkg_header hdr;
447 u32 route_hi;
448 u32 route_lo;
449 uuid_t remote_uuid;
450 u16 transmit_path;
451 u16 transmit_ring;
452 u16 receive_path;
453 u16 receive_ring;
454};
455
456struct icm_tr_pkg_disconnect_xdomain_response {
457 struct icm_pkg_header hdr;
458 u8 stage;
459 u8 reserved[3];
460 u32 route_hi;
461 u32 route_lo;
462 uuid_t remote_uuid;
463};
464
287/* XDomain messages */465/* XDomain messages */
288 466
289struct tb_xdomain_header {467struct tb_xdomain_header {
drivers/thunderbolt/xdomain.c+35−12
@@ -1255,6 +1255,7 @@ struct tb_xdomain_lookup { · 1254 unmodified lines
1255 const uuid_t *uuid;1255 const uuid_t *uuid;
1256 u8 link;1256 u8 link;
1257 u8 depth;1257 u8 depth;
1258 u64 route;
1258};1259};
1259 1260
1260static struct tb_xdomain *switch_find_xdomain(struct tb_switch *sw,1261static struct tb_xdomain *switch_find_xdomain(struct tb_switch *sw,
@@ -1275,9 +1276,13 @@ static struct tb_xdomain *switch_find_xdomain(struct tb_switch *sw, · 14 unmodified lines
1275 if (lookup->uuid) {1276 if (lookup->uuid) {
1276 if (uuid_equal(xd->remote_uuid, lookup->uuid))1277 if (uuid_equal(xd->remote_uuid, lookup->uuid))
1277 return xd;1278 return xd;
1278 } else if (lookup->link == xd->link &&1279 } else if (lookup->link &&
1280 lookup->link == xd->link &&
1279 lookup->depth == xd->depth) {1281 lookup->depth == xd->depth) {
1280 return xd;1282 return xd;
1283 } else if (lookup->route &&
1284 lookup->route == xd->route) {
1285 return xd;
1281 }1286 }
1282 } else if (port->remote) {1287 } else if (port->remote) {
1283 xd = switch_find_xdomain(port->remote->sw, lookup);1288 xd = switch_find_xdomain(port->remote->sw, lookup);
@@ -1313,12 +1318,7 @@ struct tb_xdomain *tb_xdomain_find_by_uuid(struct tb *tb, const uuid_t *uuid) · 29 unmodified lines
1313 lookup.uuid = uuid;1318 lookup.uuid = uuid;
1314 1319
1315 xd = switch_find_xdomain(tb->root_switch, &lookup);1320 xd = switch_find_xdomain(tb->root_switch, &lookup);
1316 if (xd) {1321 return tb_xdomain_get(xd);
1317 get_device(&xd->dev);
1318 return xd;
1319 }
1320
1321 return NULL;
1322}1322}
1323EXPORT_SYMBOL_GPL(tb_xdomain_find_by_uuid);1323EXPORT_SYMBOL_GPL(tb_xdomain_find_by_uuid);
1324 1324
@@ -1349,13 +1349,36 @@ struct tb_xdomain *tb_xdomain_find_by_link_depth(struct tb *tb, u8 link, · 24 unmodified lines
1349 lookup.depth = depth;1349 lookup.depth = depth;
1350 1350
1351 xd = switch_find_xdomain(tb->root_switch, &lookup);1351 xd = switch_find_xdomain(tb->root_switch, &lookup);
1352 if (xd) {1352 return tb_xdomain_get(xd);
1353 get_device(&xd->dev);1353}
1354 return xd;
1355 }
1356 1354
1357 return NULL;1355/**
1356 * tb_xdomain_find_by_route() - Find an XDomain by route string
1357 * @tb: Domain where the XDomain belongs to
1358 * @route: XDomain route string
1359 *
1360 * Finds XDomain by walking through the Thunderbolt topology below @tb.
1361 * The returned XDomain will have its reference count increased so the
1362 * caller needs to call tb_xdomain_put() when it is done with the
1363 * object.
1364 *
1365 * This will find all XDomains including the ones that are not yet added
1366 * to the bus (handshake is still in progress).
1367 *
1368 * The caller needs to hold @tb->lock.
1369 */
1370struct tb_xdomain *tb_xdomain_find_by_route(struct tb *tb, u64 route)
1371{
1372 struct tb_xdomain_lookup lookup;
1373 struct tb_xdomain *xd;
1374
1375 memset(&lookup, 0, sizeof(lookup));
1376 lookup.route = route;
1377
1378 xd = switch_find_xdomain(tb->root_switch, &lookup);
1379 return tb_xdomain_get(xd);
1358}1380}
1381EXPORT_SYMBOL_GPL(tb_xdomain_find_by_route);
1359 1382
1360bool tb_xdomain_handle_request(struct tb *tb, enum tb_cfg_pkg_type type,1383bool tb_xdomain_handle_request(struct tb *tb, enum tb_cfg_pkg_type type,
1361 const void *buf, size_t size)1384 const void *buf, size_t size)
drivers/uio/uio_hv_generic.c+89−0
@@ -121,6 +121,94 @@ static void hv_uio_rescind(struct vmbus_channel *channel) · 120 unmodified lines
121 uio_event_notify(&pdata->info);121 uio_event_notify(&pdata->info);
122}122}
123 123
124/*
125 * Handle fault when looking for sub channel ring buffer
126 * Subchannel ring buffer is same as resource 0 which is main ring buffer
127 * This is derived from uio_vma_fault
128 */
129static int hv_uio_vma_fault(struct vm_fault *vmf)
130{
131 struct vm_area_struct *vma = vmf->vma;
132 void *ring_buffer = vma->vm_private_data;
133 struct page *page;
134 void *addr;
135
136 addr = ring_buffer + (vmf->pgoff << PAGE_SHIFT);
137 page = virt_to_page(addr);
138 get_page(page);
139 vmf->page = page;
140 return 0;
141}
142
143static const struct vm_operations_struct hv_uio_vm_ops = {
144 .fault = hv_uio_vma_fault,
145};
146
147/* Sysfs API to allow mmap of the ring buffers */
148static int hv_uio_ring_mmap(struct file *filp, struct kobject *kobj,
149 struct bin_attribute *attr,
150 struct vm_area_struct *vma)
151{
152 struct vmbus_channel *channel
153 = container_of(kobj, struct vmbus_channel, kobj);
154 unsigned long requested_pages, actual_pages;
155
156 if (vma->vm_end < vma->vm_start)
157 return -EINVAL;
158
159 /* only allow 0 for now */
160 if (vma->vm_pgoff > 0)
161 return -EINVAL;
162
163 requested_pages = vma_pages(vma);
164 actual_pages = 2 * HV_RING_SIZE;
165 if (requested_pages > actual_pages)
166 return -EINVAL;
167
168 vma->vm_private_data = channel->ringbuffer_pages;
169 vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
170 vma->vm_ops = &hv_uio_vm_ops;
171 return 0;
172}
173
174static struct bin_attribute ring_buffer_bin_attr __ro_after_init = {
175 .attr = {
176 .name = "ring",
177 .mode = 0600,
178 /* size is set at init time */
179 },
180 .mmap = hv_uio_ring_mmap,
181};
182
183/* Callback from VMBUS subystem when new channel created. */
184static void
185hv_uio_new_channel(struct vmbus_channel *new_sc)
186{
187 struct hv_device *hv_dev = new_sc->primary_channel->device_obj;
188 struct device *device = &hv_dev->device;
189 struct hv_uio_private_data *pdata = hv_get_drvdata(hv_dev);
190 const size_t ring_bytes = HV_RING_SIZE * PAGE_SIZE;
191 int ret;
192
193 /* Create host communication ring */
194 ret = vmbus_open(new_sc, ring_bytes, ring_bytes, NULL, 0,
195 hv_uio_channel_cb, pdata);
196 if (ret) {
197 dev_err(device, "vmbus_open subchannel failed: %d\n", ret);
198 return;
199 }
200
201 /* Disable interrupts on sub channel */
202 new_sc->inbound.ring_buffer->interrupt_mask = 1;
203 set_channel_read_mode(new_sc, HV_CALL_ISR);
204
205 ret = sysfs_create_bin_file(&new_sc->kobj, &ring_buffer_bin_attr);
206 if (ret) {
207 dev_err(device, "sysfs create ring bin file failed; %d\n", ret);
208 vmbus_close(new_sc);
209 }
210}
211
124static void212static void
125hv_uio_cleanup(struct hv_device *dev, struct hv_uio_private_data *pdata)213hv_uio_cleanup(struct hv_device *dev, struct hv_uio_private_data *pdata)
126{214{
@@ -236,6 +324,7 @@ hv_uio_probe(struct hv_device *dev, · 109 unmodified lines
236 }324 }
237 325
238 vmbus_set_chn_rescind_callback(dev->channel, hv_uio_rescind);326 vmbus_set_chn_rescind_callback(dev->channel, hv_uio_rescind);
327 vmbus_set_sc_create_callback(dev->channel, hv_uio_new_channel);
239 328
240 hv_set_drvdata(dev, pdata);329 hv_set_drvdata(dev, pdata);
241 330
drivers/w1/w1.c+1−0
@@ -706,6 +706,7 @@ static int __w1_attach_slave_device(struct w1_slave *sl) · 705 unmodified lines
706 dev_err(&sl->dev,706 dev_err(&sl->dev,
707 "Device registration [%s] failed. err=%d\n",707 "Device registration [%s] failed. err=%d\n",
708 dev_name(&sl->dev), err);708 dev_name(&sl->dev), err);
709 put_device(&sl->dev);
709 return err;710 return err;
710 }711 }
711 w1_family_notify(BUS_NOTIFY_ADD_DEVICE, sl);712 w1_family_notify(BUS_NOTIFY_ADD_DEVICE, sl);
fs/char_dev.c+5−5
@@ -67,18 +67,18 @@ static int find_dynamic_major(void) · 66 unmodified lines
67 int i;67 int i;
68 struct char_device_struct *cd;68 struct char_device_struct *cd;
69 69
70 for (i = ARRAY_SIZE(chrdevs)-1; i > CHRDEV_MAJOR_DYN_END; i--) {70 for (i = ARRAY_SIZE(chrdevs)-1; i >= CHRDEV_MAJOR_DYN_END; i--) {
71 if (chrdevs[i] == NULL)71 if (chrdevs[i] == NULL)
72 return i;72 return i;
73 }73 }
74 74
75 for (i = CHRDEV_MAJOR_DYN_EXT_START;75 for (i = CHRDEV_MAJOR_DYN_EXT_START;
76 i > CHRDEV_MAJOR_DYN_EXT_END; i--) {76 i >= CHRDEV_MAJOR_DYN_EXT_END; i--) {
77 for (cd = chrdevs[major_to_index(i)]; cd; cd = cd->next)77 for (cd = chrdevs[major_to_index(i)]; cd; cd = cd->next)
78 if (cd->major == i)78 if (cd->major == i)
79 break;79 break;
80 80
81 if (cd == NULL || cd->major != i)81 if (cd == NULL)
82 return i;82 return i;
83 }83 }
84 84
@@ -121,8 +121,8 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor, · 36 unmodified lines
121 }121 }
122 122
123 if (major >= CHRDEV_MAJOR_MAX) {123 if (major >= CHRDEV_MAJOR_MAX) {
124 pr_err("CHRDEV \"%s\" major requested (%d) is greater than the maximum (%d)\n",124 pr_err("CHRDEV \"%s\" major requested (%u) is greater than the maximum (%u)\n",
125 name, major, CHRDEV_MAJOR_MAX);125 name, major, CHRDEV_MAJOR_MAX-1);
126 ret = -EINVAL;126 ret = -EINVAL;
127 goto out;127 goto out;
128 }128 }
include/linux/extcon.h+6−0
@@ -230,6 +230,7 @@ extern void devm_extcon_unregister_notifier_all(struct device *dev, · 229 unmodified lines
230 * Following APIs get the extcon_dev from devicetree or by through extcon name.230 * Following APIs get the extcon_dev from devicetree or by through extcon name.
231 */231 */
232extern struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name);232extern struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name);
233extern struct extcon_dev *extcon_find_edev_by_node(struct device_node *node);
233extern struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev,234extern struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev,
234 int index);235 int index);
235 236
@@ -283,6 +284,11 @@ static inline struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name) · 47 unmodified lines
283 return ERR_PTR(-ENODEV);284 return ERR_PTR(-ENODEV);
284}285}
285 286
287static inline struct extcon_dev *extcon_find_edev_by_node(struct device_node *node)
288{
289 return ERR_PTR(-ENODEV);
290}
291
286static inline struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev,292static inline struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev,
287 int index)293 int index)
288{294{
include/linux/extcon/extcon-gpio.h+0−47
@@ -1,47 +0,0 @@
1/*
2 * Single-state GPIO extcon driver based on extcon class
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#ifndef __EXTCON_GPIO_H__
21#define __EXTCON_GPIO_H__ __FILE__
22
23#include <linux/extcon.h>
24
25/**
26 * struct gpio_extcon_pdata - A simple GPIO-controlled extcon device.
27 * @extcon_id: The unique id of specific external connector.
28 * @gpio: Corresponding GPIO.
29 * @gpio_active_low: Boolean describing whether gpio active state is 1 or 0
30 * If true, low state of gpio means active.
31 * If false, high state of gpio means active.
32 * @debounce: Debounce time for GPIO IRQ in ms.
33 * @irq_flags: IRQ Flags (e.g., IRQF_TRIGGER_LOW).
34 * @check_on_resume: Boolean describing whether to check the state of gpio
35 * while resuming from sleep.
36 */
37struct gpio_extcon_pdata {
38 unsigned int extcon_id;
39 unsigned gpio;
40 bool gpio_active_low;
41 unsigned long debounce;
42 unsigned long irq_flags;
43
44 bool check_on_resume;
45};
46
47#endif /* __EXTCON_GPIO_H__ */
include/linux/hyperv.h+1−1
@@ -844,7 +844,7 @@ struct vmbus_channel { · 843 unmodified lines
844 844
845 /*845 /*
846 * NUMA distribution policy:846 * NUMA distribution policy:
847 * We support teo policies:847 * We support two policies:
848 * 1) Balanced: Here all performance critical channels are848 * 1) Balanced: Here all performance critical channels are
849 * distributed evenly amongst all the NUMA nodes.849 * distributed evenly amongst all the NUMA nodes.
850 * This policy will be the default policy.850 * This policy will be the default policy.
include/linux/nvmem-provider.h+42−0
@@ -22,6 +22,31 @@ typedef int (*nvmem_reg_read_t)(void *priv, unsigned int offset, · 21 unmodified lines
22typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset,22typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset,
23 void *val, size_t bytes);23 void *val, size_t bytes);
24 24
25/**
26 * struct nvmem_config - NVMEM device configuration
27 *
28 * @dev: Parent device.
29 * @name: Optional name.
30 * @id: Optional device ID used in full name. Ignored if name is NULL.
31 * @owner: Pointer to exporter module. Used for refcounting.
32 * @cells: Optional array of pre-defined NVMEM cells.
33 * @ncells: Number of elements in cells.
34 * @read_only: Device is read-only.
35 * @root_only: Device is accessibly to root only.
36 * @reg_read: Callback to read data.
37 * @reg_write: Callback to write data.
38 * @size: Device size.
39 * @word_size: Minimum read/write access granularity.
40 * @stride: Minimum read/write access stride.
41 * @priv: User context passed to read/write callbacks.
42 *
43 * Note: A default "nvmem<id>" name will be assigned to the device if
44 * no name is specified in its configuration. In such case "<id>" is
45 * generated with ida_simple_get() and provided id field is ignored.
46 *
47 * Note: Specifying name and setting id to -1 implies a unique device
48 * whose name is provided as-is (kept unaltered).
49 */
25struct nvmem_config {50struct nvmem_config {
26 struct device *dev;51 struct device *dev;
27 const char *name;52 const char *name;
@@ -47,6 +72,11 @@ struct nvmem_config { · 19 unmodified lines
47struct nvmem_device *nvmem_register(const struct nvmem_config *cfg);72struct nvmem_device *nvmem_register(const struct nvmem_config *cfg);
48int nvmem_unregister(struct nvmem_device *nvmem);73int nvmem_unregister(struct nvmem_device *nvmem);
49 74
75struct nvmem_device *devm_nvmem_register(struct device *dev,
76 const struct nvmem_config *cfg);
77
78int devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem);
79
50#else80#else
51 81
52static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c)82static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c)
@@ -59,5 +89,17 @@ static inline int nvmem_unregister(struct nvmem_device *nvmem) · 6 unmodified lines
59 return -ENOSYS;89 return -ENOSYS;
60}90}
61 91
92static inline struct nvmem_device *
93devm_nvmem_register(struct device *dev, const struct nvmem_config *c)
94{
95 return nvmem_register(c);
96}
97
98static inline int
99devm_nvmem_unregister(struct device *dev, struct nvmem_device *nvmem)
100{
101 return nvmem_unregister(nvmem);
102}
103
62#endif /* CONFIG_NVMEM */104#endif /* CONFIG_NVMEM */
63#endif /* ifndef _LINUX_NVMEM_PROVIDER_H */105#endif /* ifndef _LINUX_NVMEM_PROVIDER_H */
include/linux/pci_ids.h+2−0
@@ -1562,6 +1562,8 @@ · 1561 unmodified lines
1562#define PCI_DEVICE_ID_SERVERWORKS_CSB6LPC 0x02271562#define PCI_DEVICE_ID_SERVERWORKS_CSB6LPC 0x0227
1563#define PCI_DEVICE_ID_SERVERWORKS_HT1100LD 0x04081563#define PCI_DEVICE_ID_SERVERWORKS_HT1100LD 0x0408
1564 1564
1565#define PCI_VENDOR_ID_ALTERA 0x1172
1566
1565#define PCI_VENDOR_ID_SBE 0x11761567#define PCI_VENDOR_ID_SBE 0x1176
1566#define PCI_DEVICE_ID_SBE_WANXL100 0x03011568#define PCI_DEVICE_ID_SBE_WANXL100 0x0301
1567#define PCI_DEVICE_ID_SBE_WANXL200 0x03021569#define PCI_DEVICE_ID_SBE_WANXL200 0x0302
include/linux/stm.h+1−9
@@ -1,15 +1,7 @@
1// SPDX-License-Identifier: GPL-2.0
1/*2/*
2 * System Trace Module (STM) infrastructure apis3 * System Trace Module (STM) infrastructure apis
3 * Copyright (C) 2014 Intel Corporation.4 * Copyright (C) 2014 Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 */5 */
14 6
15#ifndef _STM_H_7#ifndef _STM_H_
include/linux/thunderbolt.h+19−0
@@ -45,12 +45,16 @@ enum tb_cfg_pkg_type { · 44 unmodified lines
45 * @TB_SECURITY_USER: User approval required at minimum45 * @TB_SECURITY_USER: User approval required at minimum
46 * @TB_SECURITY_SECURE: One time saved key required at minimum46 * @TB_SECURITY_SECURE: One time saved key required at minimum
47 * @TB_SECURITY_DPONLY: Only tunnel Display port (and USB)47 * @TB_SECURITY_DPONLY: Only tunnel Display port (and USB)
48 * @TB_SECURITY_USBONLY: Only tunnel USB controller of the connected
49 * Thunderbolt dock (and Display Port). All PCIe
50 * links downstream of the dock are removed.
48 */51 */
49enum tb_security_level {52enum tb_security_level {
50 TB_SECURITY_NONE,53 TB_SECURITY_NONE,
51 TB_SECURITY_USER,54 TB_SECURITY_USER,
52 TB_SECURITY_SECURE,55 TB_SECURITY_SECURE,
53 TB_SECURITY_DPONLY,56 TB_SECURITY_DPONLY,
57 TB_SECURITY_USBONLY,
54};58};
55 59
56/**60/**
@@ -65,6 +69,7 @@ enum tb_security_level { · 8 unmodified lines
65 * @cm_ops: Connection manager specific operations vector69 * @cm_ops: Connection manager specific operations vector
66 * @index: Linux assigned domain number70 * @index: Linux assigned domain number
67 * @security_level: Current security level71 * @security_level: Current security level
72 * @nboot_acl: Number of boot ACLs the domain supports
68 * @privdata: Private connection manager specific data73 * @privdata: Private connection manager specific data
69 */74 */
70struct tb {75struct tb {
@@ -77,6 +82,7 @@ struct tb { · 6 unmodified lines
77 const struct tb_cm_ops *cm_ops;82 const struct tb_cm_ops *cm_ops;
78 int index;83 int index;
79 enum tb_security_level security_level;84 enum tb_security_level security_level;
85 size_t nboot_acl;
80 unsigned long privdata[0];86 unsigned long privdata[0];
81};87};
82 88
@@ -237,6 +243,7 @@ int tb_xdomain_enable_paths(struct tb_xdomain *xd, u16 transmit_path, · 154 unmodified lines
237 u16 receive_ring);243 u16 receive_ring);
238int tb_xdomain_disable_paths(struct tb_xdomain *xd);244int tb_xdomain_disable_paths(struct tb_xdomain *xd);
239struct tb_xdomain *tb_xdomain_find_by_uuid(struct tb *tb, const uuid_t *uuid);245struct tb_xdomain *tb_xdomain_find_by_uuid(struct tb *tb, const uuid_t *uuid);
246struct tb_xdomain *tb_xdomain_find_by_route(struct tb *tb, u64 route);
240 247
241static inline struct tb_xdomain *248static inline struct tb_xdomain *
242tb_xdomain_find_by_uuid_locked(struct tb *tb, const uuid_t *uuid)249tb_xdomain_find_by_uuid_locked(struct tb *tb, const uuid_t *uuid)
@@ -250,6 +257,18 @@ tb_xdomain_find_by_uuid_locked(struct tb *tb, const uuid_t *uuid) · 7 unmodified lines
250 return xd;257 return xd;
251}258}
252 259
260static inline struct tb_xdomain *
261tb_xdomain_find_by_route_locked(struct tb *tb, u64 route)
262{
263 struct tb_xdomain *xd;
264
265 mutex_lock(&tb->lock);
266 xd = tb_xdomain_find_by_route(tb, route);
267 mutex_unlock(&tb->lock);
268
269 return xd;
270}
271
253static inline struct tb_xdomain *tb_xdomain_get(struct tb_xdomain *xd)272static inline struct tb_xdomain *tb_xdomain_get(struct tb_xdomain *xd)
254{273{
255 if (xd)274 if (xd)
include/uapi/linux/stm.h+4−9
@@ -3,15 +3,6 @@ · 2 unmodified lines
3 * System Trace Module (STM) userspace interfaces3 * System Trace Module (STM) userspace interfaces
4 * Copyright (c) 2014, Intel Corporation.4 * Copyright (c) 2014, Intel Corporation.
5 *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 * STM class implements generic infrastructure for System Trace Module devices6 * STM class implements generic infrastructure for System Trace Module devices
16 * as defined in MIPI STPv2 specification.7 * as defined in MIPI STPv2 specification.
17 */8 */
@@ -21,6 +12,10 @@ · 3 unmodified lines
21 12
22#include <linux/types.h>13#include <linux/types.h>
23 14
15/* Maximum allowed master and channel values */
16#define STP_MASTER_MAX 0xffff
17#define STP_CHANNEL_MAX 0xffff
18
24/**19/**
25 * struct stp_policy_id - identification for the STP policy20 * struct stp_policy_id - identification for the STP policy
26 * @size: size of the structure including real id[] length21 * @size: size of the structure including real id[] length
lib/devres.c+38−40
@@ -5,6 +5,12 @@ · 4 unmodified lines
5#include <linux/gfp.h>5#include <linux/gfp.h>
6#include <linux/export.h>6#include <linux/export.h>
7 7
8enum devm_ioremap_type {
9 DEVM_IOREMAP = 0,
10 DEVM_IOREMAP_NC,
11 DEVM_IOREMAP_WC,
12};
13
8void devm_ioremap_release(struct device *dev, void *res)14void devm_ioremap_release(struct device *dev, void *res)
9{15{
10 iounmap(*(void __iomem **)res);16 iounmap(*(void __iomem **)res);
@@ -15,24 +21,28 @@ static int devm_ioremap_match(struct device *dev, void *res, void *match_data) · 4 unmodified lines
15 return *(void **)res == match_data;21 return *(void **)res == match_data;
16}22}
17 23
18/**24static void __iomem *__devm_ioremap(struct device *dev, resource_size_t offset,
19 * devm_ioremap - Managed ioremap()25 resource_size_t size,
20 * @dev: Generic device to remap IO address for26 enum devm_ioremap_type type)
21 * @offset: Resource address to map
22 * @size: Size of map
23 *
24 * Managed ioremap(). Map is automatically unmapped on driver detach.
25 */
26void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
27 resource_size_t size)
28{27{
29 void __iomem **ptr, *addr;28 void __iomem **ptr, *addr = NULL;
30 29
31 ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL);30 ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL);
32 if (!ptr)31 if (!ptr)
33 return NULL;32 return NULL;
34 33
35 addr = ioremap(offset, size);34 switch (type) {
35 case DEVM_IOREMAP:
36 addr = ioremap(offset, size);
37 break;
38 case DEVM_IOREMAP_NC:
39 addr = ioremap_nocache(offset, size);
40 break;
41 case DEVM_IOREMAP_WC:
42 addr = ioremap_wc(offset, size);
43 break;
44 }
45
36 if (addr) {46 if (addr) {
37 *ptr = addr;47 *ptr = addr;
38 devres_add(dev, ptr);48 devres_add(dev, ptr);
@@ -41,6 +51,20 @@ void __iomem *devm_ioremap(struct device *dev, resource_size_t offset, · 2 unmodified lines
41 51
42 return addr;52 return addr;
43}53}
54
55/**
56 * devm_ioremap - Managed ioremap()
57 * @dev: Generic device to remap IO address for
58 * @offset: Resource address to map
59 * @size: Size of map
60 *
61 * Managed ioremap(). Map is automatically unmapped on driver detach.
62 */
63void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
64 resource_size_t size)
65{
66 return __devm_ioremap(dev, offset, size, DEVM_IOREMAP);
67}
44EXPORT_SYMBOL(devm_ioremap);68EXPORT_SYMBOL(devm_ioremap);
45 69
46/**70/**
@@ -55,20 +79,7 @@ EXPORT_SYMBOL(devm_ioremap); · 8 unmodified lines
55void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,79void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
56 resource_size_t size)80 resource_size_t size)
57{81{
58 void __iomem **ptr, *addr;82 return __devm_ioremap(dev, offset, size, DEVM_IOREMAP_NC);
59
60 ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL);
61 if (!ptr)
62 return NULL;
63
64 addr = ioremap_nocache(offset, size);
65 if (addr) {
66 *ptr = addr;
67 devres_add(dev, ptr);
68 } else
69 devres_free(ptr);
70
71 return addr;
72}83}
73EXPORT_SYMBOL(devm_ioremap_nocache);84EXPORT_SYMBOL(devm_ioremap_nocache);
74 85
@@ -83,20 +94,7 @@ EXPORT_SYMBOL(devm_ioremap_nocache); · 8 unmodified lines
83void __iomem *devm_ioremap_wc(struct device *dev, resource_size_t offset,94void __iomem *devm_ioremap_wc(struct device *dev, resource_size_t offset,
84 resource_size_t size)95 resource_size_t size)
85{96{
86 void __iomem **ptr, *addr;97 return __devm_ioremap(dev, offset, size, DEVM_IOREMAP_WC);
87
88 ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL);
89 if (!ptr)
90 return NULL;
91
92 addr = ioremap_wc(offset, size);
93 if (addr) {
94 *ptr = addr;
95 devres_add(dev, ptr);
96 } else
97 devres_free(ptr);
98
99 return addr;
100}98}
101EXPORT_SYMBOL(devm_ioremap_wc);99EXPORT_SYMBOL(devm_ioremap_wc);
102 100
tools/hv/hv_fcopy_daemon.c+3−1
@@ -21,15 +21,17 @@ · 20 unmodified lines
21#include <stdio.h>21#include <stdio.h>
22#include <stdlib.h>22#include <stdlib.h>
23#include <unistd.h>23#include <unistd.h>
24#include <string.h>
24#include <errno.h>25#include <errno.h>
25#include <linux/hyperv.h>26#include <linux/hyperv.h>
27#include <linux/limits.h>
26#include <syslog.h>28#include <syslog.h>
27#include <sys/stat.h>29#include <sys/stat.h>
28#include <fcntl.h>30#include <fcntl.h>
29#include <getopt.h>31#include <getopt.h>
30 32
31static int target_fd;33static int target_fd;
32static char target_fname[W_MAX_PATH];34static char target_fname[PATH_MAX];
33static unsigned long long filesize;35static unsigned long long filesize;
34 36
35static int hv_start_fcopy(struct hv_start_fcopy *smsg)37static int hv_start_fcopy(struct hv_start_fcopy *smsg)
tools/hv/hv_kvp_daemon.c+65−73
@@ -634,64 +634,6 @@ static char *kvp_if_name_to_mac(char *if_name) · 633 unmodified lines
634 return mac_addr;634 return mac_addr;
635}635}
636 636
637
638/*
639 * Retrieve the interface name given tha MAC address.
640 */
641
642static char *kvp_mac_to_if_name(char *mac)
643{
644 DIR *dir;
645 struct dirent *entry;
646 FILE *file;
647 char *p, *x;
648 char *if_name = NULL;
649 char buf[256];
650 char dev_id[PATH_MAX];
651 unsigned int i;
652
653 dir = opendir(KVP_NET_DIR);
654 if (dir == NULL)
655 return NULL;
656
657 while ((entry = readdir(dir)) != NULL) {
658 /*
659 * Set the state for the next pass.
660 */
661 snprintf(dev_id, sizeof(dev_id), "%s%s/address", KVP_NET_DIR,
662 entry->d_name);
663
664 file = fopen(dev_id, "r");
665 if (file == NULL)
666 continue;
667
668 p = fgets(buf, sizeof(buf), file);
669 if (p) {
670 x = strchr(p, '\n');
671 if (x)
672 *x = '\0';
673
674 for (i = 0; i < strlen(p); i++)
675 p[i] = toupper(p[i]);
676
677 if (!strcmp(p, mac)) {
678 /*
679 * Found the MAC match; return the interface
680 * name. The caller will free the memory.
681 */
682 if_name = strdup(entry->d_name);
683 fclose(file);
684 break;
685 }
686 }
687 fclose(file);
688 }
689
690 closedir(dir);
691 return if_name;
692}
693
694
695static void kvp_process_ipconfig_file(char *cmd,637static void kvp_process_ipconfig_file(char *cmd,
696 char *config_buf, unsigned int len,638 char *config_buf, unsigned int len,
697 int element_size, int offset)639 int element_size, int offset)
@@ -997,6 +939,70 @@ getaddr_done: · 299 unmodified lines
997 return error;939 return error;
998}940}
999 941
942/*
943 * Retrieve the IP given the MAC address.
944 */
945static int kvp_mac_to_ip(struct hv_kvp_ipaddr_value *kvp_ip_val)
946{
947 char *mac = (char *)kvp_ip_val->adapter_id;
948 DIR *dir;
949 struct dirent *entry;
950 FILE *file;
951 char *p, *x;
952 char *if_name = NULL;
953 char buf[256];
954 char dev_id[PATH_MAX];
955 unsigned int i;
956 int error = HV_E_FAIL;
957
958 dir = opendir(KVP_NET_DIR);
959 if (dir == NULL)
960 return HV_E_FAIL;
961
962 while ((entry = readdir(dir)) != NULL) {
963 /*
964 * Set the state for the next pass.
965 */
966 snprintf(dev_id, sizeof(dev_id), "%s%s/address", KVP_NET_DIR,
967 entry->d_name);
968
969 file = fopen(dev_id, "r");
970 if (file == NULL)
971 continue;
972
973 p = fgets(buf, sizeof(buf), file);
974 fclose(file);
975 if (!p)
976 continue;
977
978 x = strchr(p, '\n');
979 if (x)
980 *x = '\0';
981
982 for (i = 0; i < strlen(p); i++)
983 p[i] = toupper(p[i]);
984
985 if (strcmp(p, mac))
986 continue;
987
988 /*
989 * Found the MAC match.
990 * A NIC (e.g. VF) matching the MAC, but without IP, is skipped.
991 */
992 if_name = entry->d_name;
993 if (!if_name)
994 continue;
995
996 error = kvp_get_ip_info(0, if_name, KVP_OP_GET_IP_INFO,
997 kvp_ip_val, MAX_IP_ADDR_SIZE * 2);
998
999 if (!error && strlen((char *)kvp_ip_val->ip_addr))
1000 break;
1001 }
1002
1003 closedir(dir);
1004 return error;
1005}
1000 1006
1001static int expand_ipv6(char *addr, int type)1007static int expand_ipv6(char *addr, int type)
1002{1008{
@@ -1472,26 +1478,12 @@ int main(int argc, char *argv[]) · 469 unmodified lines
1472 switch (op) {1478 switch (op) {
1473 case KVP_OP_GET_IP_INFO:1479 case KVP_OP_GET_IP_INFO:
1474 kvp_ip_val = &hv_msg->body.kvp_ip_val;1480 kvp_ip_val = &hv_msg->body.kvp_ip_val;
1475 if_name =
1476 kvp_mac_to_if_name((char *)kvp_ip_val->adapter_id);
1477 1481
1478 if (if_name == NULL) {1482 error = kvp_mac_to_ip(kvp_ip_val);
1479 /*
1480 * We could not map the mac address to an
1481 * interface name; return error.
1482 */
1483 hv_msg->error = HV_E_FAIL;
1484 break;
1485 }
1486 error = kvp_get_ip_info(
1487 0, if_name, KVP_OP_GET_IP_INFO,
1488 kvp_ip_val,
1489 (MAX_IP_ADDR_SIZE * 2));
1490 1483
1491 if (error)1484 if (error)
1492 hv_msg->error = error;1485 hv_msg->error = error;
1493 1486
1494 free(if_name);
1495 break;1487 break;
1496 1488
1497 case KVP_OP_SET_IP_INFO:1489 case KVP_OP_SET_IP_INFO:
tools/hv/hv_vss_daemon.c+1−0
@@ -22,6 +22,7 @@ · 21 unmodified lines
22#include <sys/poll.h>22#include <sys/poll.h>
23#include <sys/ioctl.h>23#include <sys/ioctl.h>
24#include <sys/stat.h>24#include <sys/stat.h>
25#include <sys/sysmacros.h>
25#include <fcntl.h>26#include <fcntl.h>
26#include <stdio.h>27#include <stdio.h>
27#include <mntent.h>28#include <mntent.h>

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t