blob: db356b0cdb2ad28b5af6e12e94e107c59a855d30 [file] [log] [blame]
Angel Pons182dbde2020-04-02 23:49:05 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Vladimir Serbinenko36fa5b82014-10-28 23:43:20 +01002
3#include <string.h>
Furquan Shaikh76cedd22020-05-02 10:24:23 -07004#include <acpi/acpigen.h>
Vladimir Serbinenko36fa5b82014-10-28 23:43:20 +01005#include <device/device.h>
6#include <device/pci.h>
Elyes HAOUAS4b7202e2019-03-16 10:02:31 +01007
Vladimir Serbinenko36fa5b82014-10-28 23:43:20 +01008#include "pciehp.h"
9
10void intel_acpi_pcie_hotplug_generator(u8 *hotplug_map, int port_number)
11{
12 int port;
13 int have_hotplug = 0;
14
15 for (port = 0; port < port_number; port++) {
16 if (hotplug_map[port]) {
17 have_hotplug = 1;
18 }
19 }
20
21 if (!have_hotplug) {
22 return;
23 }
24
25 for (port = 0; port < port_number; port++) {
26 if (hotplug_map[port]) {
27 char scope_name[] = "\\_SB.PCI0.RP0x";
28 scope_name[sizeof("\\_SB.PCI0.RP0x") - 2] = '1' + port;
29 acpigen_write_scope(scope_name);
30
31 /*
32 Device (SLOT)
33 {
Elyes HAOUASb0f19882018-06-09 11:59:00 +020034 Name (_ADR, 0x00)
35 Method (_RMV, 0, NotSerialized)
36 {
37 Return (0x01)
38 }
Vladimir Serbinenko36fa5b82014-10-28 23:43:20 +010039 }
40 */
41
42 acpigen_write_device("SLOT");
43
44 acpigen_write_name_byte("_ADR", 0x00);
45
46 acpigen_write_method("_RMV", 0);
47 /* ReturnOp */
48 acpigen_emit_byte (0xa4);
49 /* One */
50 acpigen_emit_byte (0x01);
51 acpigen_pop_len();
52 acpigen_pop_len();
53 acpigen_pop_len();
54 }
55 }
56
57 /* Method (_L01, 0, NotSerialized)
58 {
59 If (\_SB.PCI0.RP04.HPCS)
60 {
61 Sleep (100)
62 Store (0x01, \_SB.PCI0.RP04.HPCS)
63 If (\_SB.PCI0.RP04.PDC)
64 {
65 Store (0x01, \_SB.PCI0.RP04.PDC)
66 Notify (\_SB.PCI0.RP04, 0x00)
67 }
68 }
69 }
70
71 */
72 acpigen_write_scope("\\_GPE");
73 acpigen_write_method("_L01", 0);
74 for (port = 0; port < port_number; port++) {
75 if (hotplug_map[port]) {
76 char reg_name[] = "\\_SB.PCI0.RP0x.HPCS";
77 reg_name[sizeof("\\_SB.PCI0.RP0x") - 2] = '1' + port;
78 acpigen_emit_byte(0xa0); /* IfOp. */
79 acpigen_write_len_f();
80 acpigen_emit_namestring(reg_name);
81
82 /* Sleep (100) */
83 acpigen_emit_byte(0x5b); /* SleepOp. */
84 acpigen_emit_byte(0x22);
85 acpigen_write_byte(100);
86
87 /* Store (0x01, \_SB.PCI0.RP04.HPCS) */
88 acpigen_emit_byte(0x70);
89 acpigen_emit_byte(0x01);
90 acpigen_emit_namestring(reg_name);
91
92 memcpy(reg_name + sizeof("\\_SB.PCI0.RP0x.") - 1, "PDC", 4);
93
94 /* If (\_SB.PCI0.RP04.PDC) */
95 acpigen_emit_byte(0xa0); /* IfOp. */
96 acpigen_write_len_f();
97 acpigen_emit_namestring(reg_name);
98
99 /* Store (0x01, \_SB.PCI0.RP04.PDC) */
100 acpigen_emit_byte(0x70);
101 acpigen_emit_byte(0x01);
102 acpigen_emit_namestring(reg_name);
103
104 reg_name[sizeof("\\_SB.PCI0.RP0x") - 1] = '\0';
105
106 /* Notify(\_SB.PCI0.RP04, 0x00) */
107 acpigen_emit_byte(0x86);
108 acpigen_emit_namestring(reg_name);
109 acpigen_emit_byte(0x00);
110 acpigen_pop_len();
111 acpigen_pop_len();
112 }
113 }
114 acpigen_pop_len();
115 acpigen_pop_len();
116
117}