int acpigen_write_len_f(void) { ASSERT(ltop < (ACPIGEN_LENSTACK_SIZE - 1)) len_stack[ltop++] = gencurrent; acpigen_emit_byte(0); acpigen_emit_byte(0); return 2; }
static void acpigen_soc_get_gpio_in_local5(uintptr_t addr) { /* * Store (\_SB.GPR2 (addr), Local5) * \_SB.GPR2 is used to read control byte 2 from control register. * / It is defined in gpio_lib.asl. */ acpigen_write_store(); acpigen_emit_namestring("\\_SB.GPR2"); acpigen_write_integer(addr); acpigen_emit_byte(LOCAL5_OP); }
static int acpigen_soc_set_gpio_val(unsigned int gpio_num, uint32_t val) { if (gpio_num >= GPIO_TOTAL_PINS) { printk(BIOS_WARNING, "Warning: Pin %d should be smaller than" " %d\n", gpio_num, GPIO_TOTAL_PINS); return -1; } uintptr_t addr = (uintptr_t) gpio_get_address(gpio_num); /* Store (0x40, Local0) */ acpigen_write_store(); acpigen_write_integer(GPIO_PIN_OUT); acpigen_emit_byte(LOCAL0_OP); acpigen_soc_get_gpio_in_local5(addr); if (val) { /* Or (Local5, GPIO_PIN_OUT, Local5) */ acpigen_write_or(LOCAL5_OP, LOCAL0_OP, LOCAL5_OP); } else { /* Not (GPIO_PIN_OUT, Local6) */ acpigen_write_not(LOCAL0_OP, LOCAL6_OP); /* And (Local5, Local6, Local5) */ acpigen_write_and(LOCAL5_OP, LOCAL6_OP, LOCAL5_OP); } /* * SB.GPW2 (addr, Local5) * \_SB.GPW2 is used to write control byte in control register * / byte 2. It is defined in gpio_lib.asl. */ acpigen_emit_namestring("\\_SB.GPW2"); acpigen_write_integer(addr); acpigen_emit_byte(LOCAL5_OP); return 0; }
void intel_acpi_pcie_hotplug_generator(u8 *hotplug_map, int port_number) { int port; int have_hotplug = 0; for (port = 0; port < port_number; port++) { if (hotplug_map[port]) { have_hotplug = 1; } } if (!have_hotplug) { return; } for (port = 0; port < port_number; port++) { if (hotplug_map[port]) { char scope_name[] = "\\_SB.PCI0.RP0x"; scope_name[sizeof("\\_SB.PCI0.RP0x") - 2] = '1' + port; acpigen_write_scope(scope_name); /* Device (SLOT) { Name (_ADR, 0x00) Method (_RMV, 0, NotSerialized) { Return (0x01) } } */ acpigen_write_device("SLOT"); acpigen_write_name_byte("_ADR", 0x00); acpigen_write_method("_RMV", 0); /* ReturnOp */ acpigen_emit_byte (0xa4); /* One */ acpigen_emit_byte (0x01); acpigen_pop_len(); acpigen_pop_len(); acpigen_pop_len(); } } /* Method (_L01, 0, NotSerialized) { If (\_SB.PCI0.RP04.HPCS) { Sleep (100) Store (0x01, \_SB.PCI0.RP04.HPCS) If (\_SB.PCI0.RP04.PDC) { Store (0x01, \_SB.PCI0.RP04.PDC) Notify (\_SB.PCI0.RP04, 0x00) } } } */ acpigen_write_scope("\\_GPE"); acpigen_write_method("_L01", 0); for (port = 0; port < port_number; port++) { if (hotplug_map[port]) { char reg_name[] = "\\_SB.PCI0.RP0x.HPCS"; reg_name[sizeof("\\_SB.PCI0.RP0x") - 2] = '1' + port; acpigen_emit_byte(0xa0); /* IfOp. */ acpigen_write_len_f(); acpigen_emit_namestring(reg_name); /* Sleep (100) */ acpigen_emit_byte(0x5b); /* SleepOp. */ acpigen_emit_byte(0x22); acpigen_write_byte(100); /* Store (0x01, \_SB.PCI0.RP04.HPCS) */ acpigen_emit_byte(0x70); acpigen_emit_byte(0x01); acpigen_emit_namestring(reg_name); memcpy(reg_name + sizeof("\\_SB.PCI0.RP0x.") - 1, "PDC", 4); /* If (\_SB.PCI0.RP04.PDC) */ acpigen_emit_byte(0xa0); /* IfOp. */ acpigen_write_len_f(); acpigen_emit_namestring(reg_name); /* Store (0x01, \_SB.PCI0.RP04.PDC) */ acpigen_emit_byte(0x70); acpigen_emit_byte(0x01); acpigen_emit_namestring(reg_name); reg_name[sizeof("\\_SB.PCI0.RP0x") - 1] = '\0'; /* Notify(\_SB.PCI0.RP04, 0x00) */ acpigen_emit_byte(0x86); acpigen_emit_namestring(reg_name); acpigen_emit_byte(0x00); acpigen_pop_len(); acpigen_pop_len(); } } acpigen_pop_len(); acpigen_pop_len(); }