Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 46577e6a authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branch 'acpica-fixes'

* acpica-fixes:
  Revert "ACPICA: ACPI 2.0, Hardware: Add access_width/bit_offset support for acpi_hw_write()"
parents 5edb5649 da4e7925
Loading
Loading
Loading
Loading
+9 −137
Original line number Diff line number Diff line
@@ -306,12 +306,6 @@ acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg)
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);
@@ -323,145 +317,23 @@ acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg)
		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);
		status = acpi_os_write_memory((acpi_physical_address)
					      address, (u64)value,
					      reg->bit_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++;
					    address, value, reg->bit_width);
	}

	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),
			  value, reg->bit_width, ACPI_FORMAT_UINT64(address),
			  acpi_ut_get_region_name(reg->space_id)));

	return (status);