static void cpc_read(struct cpc_reg *reg, u64 *val) { u64 addr = get_phys_addr(reg); acpi_os_read_memory((acpi_physical_address)addr, val, reg->bit_width); }
acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) { u64 address; acpi_status status; ACPI_FUNCTION_NAME(hw_read); status = acpi_hw_validate_register(reg, 32, &address); if (ACPI_FAILURE(status)) { return (status); } *value = 0; if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { status = acpi_os_read_memory((acpi_physical_address) address, value, reg->bit_width); } else { status = acpi_hw_read_port((acpi_io_address) address, value, reg->bit_width); } ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", *value, reg->bit_width, ACPI_FORMAT_UINT64(address), acpi_ut_get_region_name(reg->space_id))); return (status); }
static int cpc_read(struct cpc_reg *reg, u64 *val) { int ret_val = 0; *val = 0; if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) { void __iomem *vaddr = GET_PCC_VADDR(reg->address); switch (reg->bit_width) { case 8: *val = readb_relaxed(vaddr); break; case 16: *val = readw_relaxed(vaddr); break; case 32: *val = readl_relaxed(vaddr); break; case 64: *val = readq_relaxed(vaddr); break; default: pr_debug("Error: Cannot read %u bit width from PCC\n", reg->bit_width); ret_val = -EFAULT; } } else ret_val = acpi_os_read_memory((acpi_physical_address)reg->address, val, reg->bit_width); return ret_val; }
static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val) { int ret_val = 0; void __iomem *vaddr = 0; int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); struct cpc_reg *reg = ®_res->cpc_entry.reg; if (reg_res->type == ACPI_TYPE_INTEGER) { *val = reg_res->cpc_entry.int_value; return ret_val; } *val = 0; if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id); else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) vaddr = reg_res->sys_mem_vaddr; else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) return cpc_read_ffh(cpu, reg, val); else return acpi_os_read_memory((acpi_physical_address)reg->address, val, reg->bit_width); switch (reg->bit_width) { case 8: *val = readb_relaxed(vaddr); break; case 16: *val = readw_relaxed(vaddr); break; case 32: *val = readl_relaxed(vaddr); break; case 64: *val = readq_relaxed(vaddr); break; default: pr_debug("Error: Cannot read %u bit width from PCC\n", reg->bit_width); ret_val = -EFAULT; } return ret_val; }
acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) { u64 address; u64 value64; acpi_status status; ACPI_FUNCTION_NAME(hw_read); /* Validate contents of the GAS register */ status = acpi_hw_validate_register(reg, 32, &address); if (ACPI_FAILURE(status)) { return (status); } /* Initialize entire 32-bit return value to zero */ *value = 0; /* * Two address spaces supported: Memory or IO. PCI_Config is * not supported here because the GAS structure is insufficient */ if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { status = acpi_os_read_memory((acpi_physical_address) address, &value64, reg->bit_width); *value = (u32)value64; } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ status = acpi_hw_read_port((acpi_io_address) address, value, reg->bit_width); } ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", *value, reg->bit_width, ACPI_FORMAT_UINT64(address), acpi_ut_get_region_name(reg->space_id))); return (status); }
acpi_status acpi_hw_read(u64 *value, struct acpi_generic_address *reg) { u64 address; u8 access_width; u32 bit_width; u8 bit_offset; u64 value64; u32 value32; u8 index; acpi_status status; ACPI_FUNCTION_NAME(hw_read); /* Validate contents of the GAS register */ status = acpi_hw_validate_register(reg, 64, &address); if (ACPI_FAILURE(status)) { return (status); } /* * Initialize entire 64-bit return value to zero, convert access_width * into number of bits based */ *value = 0; access_width = acpi_hw_get_access_bit_width(address, reg, 64); bit_width = reg->bit_offset + reg->bit_width; bit_offset = reg->bit_offset; /* * Two address spaces supported: Memory or IO. PCI_Config is * not supported here because the GAS structure is insufficient */ index = 0; while (bit_width) { if (bit_offset >= access_width) { value64 = 0; bit_offset -= access_width; } else { if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { status = acpi_os_read_memory((acpi_physical_address) address + index * ACPI_DIV_8 (access_width), &value64, access_width); } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ status = acpi_hw_read_port((acpi_io_address) address + index * ACPI_DIV_8 (access_width), &value32, access_width); value64 = (u64)value32; } } /* * Use offset style bit writes because "Index * AccessWidth" is * ensured to be less than 64-bits by acpi_hw_validate_register(). */ ACPI_SET_BITS(value, index * access_width, ACPI_MASK_BITS_ABOVE_64(access_width), value64); bit_width -= bit_width > access_width ? access_width : bit_width; index++; } ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n", ACPI_FORMAT_UINT64(*value), access_width, ACPI_FORMAT_UINT64(address), acpi_ut_get_region_name(reg->space_id))); return (status); }
acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) { u64 address; u8 access_width; u32 bit_width; u8 bit_offset; u64 value64; u32 new_value32, old_value32; u8 index; acpi_status status; ACPI_FUNCTION_NAME(hw_write); /* Validate contents of the GAS register */ status = acpi_hw_validate_register(reg, 32, &address); if (ACPI_FAILURE(status)) { return (status); } /* Convert access_width into number of bits based */ access_width = acpi_hw_get_access_bit_width(reg, 32); bit_width = reg->bit_offset + reg->bit_width; bit_offset = reg->bit_offset; /* * Two address spaces supported: Memory or IO. PCI_Config is * not supported here because the GAS structure is insufficient */ index = 0; while (bit_width) { /* * Use offset style bit reads because "Index * AccessWidth" is * ensured to be less than 32-bits by acpi_hw_validate_register(). */ new_value32 = ACPI_GET_BITS(&value, index * access_width, ACPI_MASK_BITS_ABOVE_32 (access_width)); if (bit_offset >= access_width) { bit_offset -= access_width; } else { /* * Use offset style bit masks because access_width is ensured * to be less than 32-bits by acpi_hw_validate_register() and * bit_offset/bit_width is less than access_width here. */ if (bit_offset) { new_value32 &= ACPI_MASK_BITS_BELOW(bit_offset); } if (bit_width < access_width) { new_value32 &= ACPI_MASK_BITS_ABOVE(bit_width); } if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { if (bit_offset || bit_width < access_width) { /* * Read old values in order not to modify the bits that * are beyond the register bit_width/bit_offset setting. */ status = acpi_os_read_memory((acpi_physical_address) address + index * ACPI_DIV_8 (access_width), &value64, access_width); old_value32 = (u32)value64; /* * Use offset style bit masks because access_width is * ensured to be less than 32-bits by * acpi_hw_validate_register() and bit_offset/bit_width is * less than access_width here. */ if (bit_offset) { old_value32 &= ACPI_MASK_BITS_ABOVE (bit_offset); bit_offset = 0; } if (bit_width < access_width) { old_value32 &= ACPI_MASK_BITS_BELOW (bit_width); } new_value32 |= old_value32; } value64 = (u64)new_value32; status = acpi_os_write_memory((acpi_physical_address) address + index * ACPI_DIV_8 (access_width), value64, access_width); } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ if (bit_offset || bit_width < access_width) { /* * Read old values in order not to modify the bits that * are beyond the register bit_width/bit_offset setting. */ status = acpi_hw_read_port((acpi_io_address) address + index * ACPI_DIV_8 (access_width), &old_value32, access_width); /* * Use offset style bit masks because access_width is * ensured to be less than 32-bits by * acpi_hw_validate_register() and bit_offset/bit_width is * less than access_width here. */ if (bit_offset) { old_value32 &= ACPI_MASK_BITS_ABOVE (bit_offset); bit_offset = 0; } if (bit_width < access_width) { old_value32 &= ACPI_MASK_BITS_BELOW (bit_width); } new_value32 |= old_value32; } status = acpi_hw_write_port((acpi_io_address) address + index * ACPI_DIV_8 (access_width), new_value32, access_width); } } /* * Index * access_width is ensured to be less than 32-bits by * acpi_hw_validate_register(). */ bit_width -= bit_width > access_width ? access_width : bit_width; index++; } ACPI_DEBUG_PRINT((ACPI_DB_IO, "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", value, access_width, ACPI_FORMAT_UINT64(address), acpi_ut_get_region_name(reg->space_id))); return (status); }