diff options
Diffstat (limited to 'drivers/platform/x86/intel/int3472/discrete.c')
| -rw-r--r-- | drivers/platform/x86/intel/int3472/discrete.c | 103 | 
1 files changed, 79 insertions, 24 deletions
| diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c index e33c2d75975c..07b302e09340 100644 --- a/drivers/platform/x86/intel/int3472/discrete.c +++ b/drivers/platform/x86/intel/int3472/discrete.c @@ -52,21 +52,15 @@ static void skl_int3472_log_sensor_module_name(struct int3472_discrete_device *i  	}  } -static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int3472, -					  struct acpi_resource_gpio *agpio, -					  const char *func, u32 polarity) +static int skl_int3472_fill_gpiod_lookup(struct gpiod_lookup *table_entry, +					 struct acpi_resource_gpio *agpio, +					 const char *func, u32 polarity)  {  	char *path = agpio->resource_source.string_ptr; -	struct gpiod_lookup *table_entry;  	struct acpi_device *adev;  	acpi_handle handle;  	acpi_status status; -	if (int3472->n_sensor_gpios >= INT3472_MAX_SENSOR_GPIOS) { -		dev_warn(int3472->dev, "Too many GPIOs mapped\n"); -		return -EINVAL; -	} -  	status = acpi_get_handle(NULL, path, &handle);  	if (ACPI_FAILURE(status))  		return -EINVAL; @@ -75,18 +69,62 @@ static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int347  	if (!adev)  		return -ENODEV; -	table_entry = &int3472->gpios.table[int3472->n_sensor_gpios];  	table_entry->key = acpi_dev_name(adev);  	table_entry->chip_hwnum = agpio->pin_table[0];  	table_entry->con_id = func;  	table_entry->idx = 0;  	table_entry->flags = polarity; +	return 0; +} + +static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int3472, +					  struct acpi_resource_gpio *agpio, +					  const char *func, u32 polarity) +{ +	int ret; + +	if (int3472->n_sensor_gpios >= INT3472_MAX_SENSOR_GPIOS) { +		dev_warn(int3472->dev, "Too many GPIOs mapped\n"); +		return -EINVAL; +	} + +	ret = skl_int3472_fill_gpiod_lookup(&int3472->gpios.table[int3472->n_sensor_gpios], +					    agpio, func, polarity); +	if (ret) +		return ret; +  	int3472->n_sensor_gpios++;  	return 0;  } +/* This should *really* only be used when there's no other way... */ +static struct gpio_desc * +skl_int3472_gpiod_get_from_temp_lookup(struct int3472_discrete_device *int3472, +				       struct acpi_resource_gpio *agpio, +				       const char *func, u32 polarity) +{ +	struct gpio_desc *desc; +	int ret; + +	struct gpiod_lookup_table *lookup __free(kfree) = +			kzalloc(struct_size(lookup, table, 2), GFP_KERNEL); +	if (!lookup) +		return ERR_PTR(-ENOMEM); + +	lookup->dev_id = dev_name(int3472->dev); +	ret = skl_int3472_fill_gpiod_lookup(&lookup->table[0], agpio, func, polarity); +	if (ret) +		return ERR_PTR(ret); + +	gpiod_add_lookup_table(lookup); +	desc = devm_gpiod_get(int3472->dev, func, GPIOD_OUT_LOW); +	gpiod_remove_lookup_table(lookup); + +	return desc; +} +  static void int3472_get_func_and_polarity(u8 type, const char **func, u32 *polarity)  {  	switch (type) { @@ -156,6 +194,7 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares,  	struct acpi_resource_gpio *agpio;  	u8 active_value, pin, type;  	union acpi_object *obj; +	struct gpio_desc *gpio;  	const char *err_msg;  	const char *func;  	u32 polarity; @@ -206,22 +245,38 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares,  		break;  	case INT3472_GPIO_TYPE_CLK_ENABLE: -		ret = skl_int3472_register_gpio_clock(int3472, agpio, polarity); -		if (ret) -			err_msg = "Failed to register clock\n"; - -		break;  	case INT3472_GPIO_TYPE_PRIVACY_LED: -		ret = skl_int3472_register_pled(int3472, agpio, polarity); -		if (ret) -			err_msg = "Failed to register LED\n"; - -		break;  	case INT3472_GPIO_TYPE_POWER_ENABLE: -		ret = skl_int3472_register_regulator(int3472, agpio); -		if (ret) -			err_msg = "Failed to map regulator to sensor\n"; - +		gpio = skl_int3472_gpiod_get_from_temp_lookup(int3472, agpio, func, polarity); +		if (IS_ERR(gpio)) { +			ret = PTR_ERR(gpio); +			err_msg = "Failed to get GPIO\n"; +			break; +		} + +		switch (type) { +		case INT3472_GPIO_TYPE_CLK_ENABLE: +			ret = skl_int3472_register_gpio_clock(int3472, gpio); +			if (ret) +				err_msg = "Failed to register clock\n"; + +			break; +		case INT3472_GPIO_TYPE_PRIVACY_LED: +			ret = skl_int3472_register_pled(int3472, gpio); +			if (ret) +				err_msg = "Failed to register LED\n"; + +			break; +		case INT3472_GPIO_TYPE_POWER_ENABLE: +			ret = skl_int3472_register_regulator(int3472, gpio); +			if (ret) +				err_msg = "Failed to map regulator to sensor\n"; + +			break; +		default: /* Never reached */ +			ret = -EINVAL; +			break; +		}  		break;  	default:  		dev_warn(int3472->dev, |