Commit ee0d44f2 authored by Hans de Goede's avatar Hans de Goede

Merge tag 'platform-drivers-x86-int3472-1' into review-hans

Signed tag for the immutable platform-drivers-x86-int3472 branch

This branch contains 5.16-rc1 + the pending ACPI/i2c, tps68570 platform_data
and INT3472 driver patches.
parents 692562ab 97c2259e
...@@ -797,6 +797,12 @@ static const char * const acpi_ignore_dep_ids[] = { ...@@ -797,6 +797,12 @@ static const char * const acpi_ignore_dep_ids[] = {
NULL NULL
}; };
/* List of HIDs for which we honor deps of matching ACPI devs, when checking _DEP lists. */
static const char * const acpi_honor_dep_ids[] = {
"INT3472", /* Camera sensor PMIC / clk and regulator info */
NULL
};
static struct acpi_device *acpi_bus_get_parent(acpi_handle handle) static struct acpi_device *acpi_bus_get_parent(acpi_handle handle)
{ {
struct acpi_device *device = NULL; struct acpi_device *device = NULL;
...@@ -1762,9 +1768,13 @@ static void acpi_scan_dep_init(struct acpi_device *adev) ...@@ -1762,9 +1768,13 @@ static void acpi_scan_dep_init(struct acpi_device *adev)
struct acpi_dep_data *dep; struct acpi_dep_data *dep;
list_for_each_entry(dep, &acpi_dep_list, node) { list_for_each_entry(dep, &acpi_dep_list, node) {
if (dep->consumer == adev->handle) if (dep->consumer == adev->handle) {
if (dep->honor_dep)
adev->flags.honor_deps = 1;
adev->dep_unmet++; adev->dep_unmet++;
} }
}
} }
void acpi_device_add_finalize(struct acpi_device *device) void acpi_device_add_finalize(struct acpi_device *device)
...@@ -1967,7 +1977,7 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep) ...@@ -1967,7 +1977,7 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep)
for (count = 0, i = 0; i < dep_devices.count; i++) { for (count = 0, i = 0; i < dep_devices.count; i++) {
struct acpi_device_info *info; struct acpi_device_info *info;
struct acpi_dep_data *dep; struct acpi_dep_data *dep;
bool skip; bool skip, honor_dep;
status = acpi_get_object_info(dep_devices.handles[i], &info); status = acpi_get_object_info(dep_devices.handles[i], &info);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
...@@ -1976,6 +1986,7 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep) ...@@ -1976,6 +1986,7 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep)
} }
skip = acpi_info_matches_ids(info, acpi_ignore_dep_ids); skip = acpi_info_matches_ids(info, acpi_ignore_dep_ids);
honor_dep = acpi_info_matches_ids(info, acpi_honor_dep_ids);
kfree(info); kfree(info);
if (skip) if (skip)
...@@ -1989,6 +2000,7 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep) ...@@ -1989,6 +2000,7 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep)
dep->supplier = dep_devices.handles[i]; dep->supplier = dep_devices.handles[i];
dep->consumer = handle; dep->consumer = handle;
dep->honor_dep = honor_dep;
mutex_lock(&acpi_dep_list_lock); mutex_lock(&acpi_dep_list_lock);
list_add_tail(&dep->node , &acpi_dep_list); list_add_tail(&dep->node , &acpi_dep_list);
...@@ -2155,8 +2167,8 @@ static void acpi_bus_attach(struct acpi_device *device, bool first_pass) ...@@ -2155,8 +2167,8 @@ static void acpi_bus_attach(struct acpi_device *device, bool first_pass)
register_dock_dependent_device(device, ejd); register_dock_dependent_device(device, ejd);
acpi_bus_get_status(device); acpi_bus_get_status(device);
/* Skip devices that are not present. */ /* Skip devices that are not ready for enumeration (e.g. not present) */
if (!acpi_device_is_present(device)) { if (!acpi_dev_ready_for_enumeration(device)) {
device->flags.initialized = false; device->flags.initialized = false;
acpi_device_clear_enumerated(device); acpi_device_clear_enumerated(device);
device->flags.power_manageable = 0; device->flags.power_manageable = 0;
...@@ -2318,6 +2330,23 @@ void acpi_dev_clear_dependencies(struct acpi_device *supplier) ...@@ -2318,6 +2330,23 @@ void acpi_dev_clear_dependencies(struct acpi_device *supplier)
} }
EXPORT_SYMBOL_GPL(acpi_dev_clear_dependencies); EXPORT_SYMBOL_GPL(acpi_dev_clear_dependencies);
/**
* acpi_dev_ready_for_enumeration - Check if the ACPI device is ready for enumeration
* @device: Pointer to the &struct acpi_device to check
*
* Check if the device is present and has no unmet dependencies.
*
* Return true if the device is ready for enumeratino. Otherwise, return false.
*/
bool acpi_dev_ready_for_enumeration(const struct acpi_device *device)
{
if (device->flags.honor_deps && device->dep_unmet)
return false;
return acpi_device_is_present(device);
}
EXPORT_SYMBOL_GPL(acpi_dev_ready_for_enumeration);
/** /**
* acpi_dev_get_first_consumer_dev - Return ACPI device dependent on @supplier * acpi_dev_get_first_consumer_dev - Return ACPI device dependent on @supplier
* @supplier: Pointer to the dependee device * @supplier: Pointer to the dependee device
......
...@@ -144,9 +144,12 @@ static int i2c_acpi_do_lookup(struct acpi_device *adev, ...@@ -144,9 +144,12 @@ static int i2c_acpi_do_lookup(struct acpi_device *adev,
struct list_head resource_list; struct list_head resource_list;
int ret; int ret;
if (acpi_bus_get_status(adev) || !adev->status.present) if (acpi_bus_get_status(adev))
return -EINVAL; return -EINVAL;
if (!acpi_dev_ready_for_enumeration(adev))
return -ENODEV;
if (acpi_match_device_ids(adev, i2c_acpi_ignored_device_ids) == 0) if (acpi_match_device_ids(adev, i2c_acpi_ignored_device_ids) == 0)
return -ENODEV; return -ENODEV;
...@@ -473,8 +476,8 @@ struct notifier_block i2c_acpi_notifier = { ...@@ -473,8 +476,8 @@ struct notifier_block i2c_acpi_notifier = {
}; };
/** /**
* i2c_acpi_new_device - Create i2c-client for the Nth I2cSerialBus resource * i2c_acpi_new_device_by_fwnode - Create i2c-client for the Nth I2cSerialBus resource
* @dev: Device owning the ACPI resources to get the client from * @fwnode: fwnode with the ACPI resources to get the client from
* @index: Index of ACPI resource to get * @index: Index of ACPI resource to get
* @info: describes the I2C device; note this is modified (addr gets set) * @info: describes the I2C device; note this is modified (addr gets set)
* Context: can sleep * Context: can sleep
...@@ -490,15 +493,20 @@ struct notifier_block i2c_acpi_notifier = { ...@@ -490,15 +493,20 @@ struct notifier_block i2c_acpi_notifier = {
* Returns a pointer to the new i2c-client, or error pointer in case of failure. * Returns a pointer to the new i2c-client, or error pointer in case of failure.
* Specifically, -EPROBE_DEFER is returned if the adapter is not found. * Specifically, -EPROBE_DEFER is returned if the adapter is not found.
*/ */
struct i2c_client *i2c_acpi_new_device(struct device *dev, int index, struct i2c_client *i2c_acpi_new_device_by_fwnode(struct fwnode_handle *fwnode,
int index,
struct i2c_board_info *info) struct i2c_board_info *info)
{ {
struct acpi_device *adev = ACPI_COMPANION(dev);
struct i2c_acpi_lookup lookup; struct i2c_acpi_lookup lookup;
struct i2c_adapter *adapter; struct i2c_adapter *adapter;
struct acpi_device *adev;
LIST_HEAD(resource_list); LIST_HEAD(resource_list);
int ret; int ret;
adev = to_acpi_device_node(fwnode);
if (!adev)
return ERR_PTR(-ENODEV);
memset(&lookup, 0, sizeof(lookup)); memset(&lookup, 0, sizeof(lookup));
lookup.info = info; lookup.info = info;
lookup.device_handle = acpi_device_handle(adev); lookup.device_handle = acpi_device_handle(adev);
...@@ -520,7 +528,7 @@ struct i2c_client *i2c_acpi_new_device(struct device *dev, int index, ...@@ -520,7 +528,7 @@ struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
return i2c_new_client_device(adapter, info); return i2c_new_client_device(adapter, info);
} }
EXPORT_SYMBOL_GPL(i2c_acpi_new_device); EXPORT_SYMBOL_GPL(i2c_acpi_new_device_by_fwnode);
bool i2c_acpi_waive_d0_probe(struct device *dev) bool i2c_acpi_waive_d0_probe(struct device *dev)
{ {
......
obj-$(CONFIG_INTEL_SKL_INT3472) += intel_skl_int3472.o obj-$(CONFIG_INTEL_SKL_INT3472) += intel_skl_int3472_discrete.o \
intel_skl_int3472-y := intel_skl_int3472_common.o \ intel_skl_int3472_tps68470.o
intel_skl_int3472_discrete.o \ intel_skl_int3472_discrete-y := discrete.o clk_and_regulator.o common.o
intel_skl_int3472_tps68470.o \ intel_skl_int3472_tps68470-y := tps68470.o tps68470_board_data.o common.o
intel_skl_int3472_clk_and_regulator.o
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include <linux/regulator/driver.h> #include <linux/regulator/driver.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "intel_skl_int3472_common.h" #include "common.h"
/* /*
* The regulators have to have .ops to be valid, but the only ops we actually * The regulators have to have .ops to be valid, but the only ops we actually
......
...@@ -2,11 +2,9 @@ ...@@ -2,11 +2,9 @@
/* Author: Dan Scally <djrscally@gmail.com> */ /* Author: Dan Scally <djrscally@gmail.com> */
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "intel_skl_int3472_common.h" #include "common.h"
union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev, char *id) union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev, char *id)
{ {
...@@ -55,52 +53,30 @@ int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb) ...@@ -55,52 +53,30 @@ int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb)
return ret; return ret;
} }
static const struct acpi_device_id int3472_device_id[] = { /* sensor_adev_ret may be NULL, name_ret must not be NULL */
{ "INT3472", 0 }, int skl_int3472_get_sensor_adev_and_name(struct device *dev,
{ } struct acpi_device **sensor_adev_ret,
}; const char **name_ret)
MODULE_DEVICE_TABLE(acpi, int3472_device_id);
static struct platform_driver int3472_discrete = {
.driver = {
.name = "int3472-discrete",
.acpi_match_table = int3472_device_id,
},
.probe = skl_int3472_discrete_probe,
.remove = skl_int3472_discrete_remove,
};
static struct i2c_driver int3472_tps68470 = {
.driver = {
.name = "int3472-tps68470",
.acpi_match_table = int3472_device_id,
},
.probe_new = skl_int3472_tps68470_probe,
};
static int skl_int3472_init(void)
{ {
int ret; struct acpi_device *adev = ACPI_COMPANION(dev);
struct acpi_device *sensor;
int ret = 0;
sensor = acpi_dev_get_first_consumer_dev(adev);
if (!sensor) {
dev_err(dev, "INT3472 seems to have no dependents.\n");
return -ENODEV;
}
ret = platform_driver_register(&int3472_discrete); *name_ret = devm_kasprintf(dev, GFP_KERNEL, I2C_DEV_NAME_FORMAT,
if (ret) acpi_dev_name(sensor));
return ret; if (!*name_ret)
ret = -ENOMEM;
ret = i2c_register_driver(THIS_MODULE, &int3472_tps68470); if (ret == 0 && sensor_adev_ret)
if (ret) *sensor_adev_ret = sensor;
platform_driver_unregister(&int3472_discrete); else
acpi_dev_put(sensor);
return ret; return ret;
} }
module_init(skl_int3472_init);
static void skl_int3472_exit(void)
{
platform_driver_unregister(&int3472_discrete);
i2c_del_driver(&int3472_tps68470);
}
module_exit(skl_int3472_exit);
MODULE_DESCRIPTION("Intel SkyLake INT3472 ACPI Device Driver");
MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
MODULE_LICENSE("GPL v2");
...@@ -105,12 +105,12 @@ struct int3472_discrete_device { ...@@ -105,12 +105,12 @@ struct int3472_discrete_device {
struct gpiod_lookup_table gpios; struct gpiod_lookup_table gpios;
}; };
int skl_int3472_discrete_probe(struct platform_device *pdev);
int skl_int3472_discrete_remove(struct platform_device *pdev);
int skl_int3472_tps68470_probe(struct i2c_client *client);
union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev, union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev,
char *id); char *id);
int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb); int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb);
int skl_int3472_get_sensor_adev_and_name(struct device *dev,
struct acpi_device **sensor_adev_ret,
const char **name_ret);
int skl_int3472_register_clock(struct int3472_discrete_device *int3472); int skl_int3472_register_clock(struct int3472_discrete_device *int3472);
void skl_int3472_unregister_clock(struct int3472_discrete_device *int3472); void skl_int3472_unregister_clock(struct int3472_discrete_device *int3472);
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/uuid.h> #include <linux/uuid.h>
#include "intel_skl_int3472_common.h" #include "common.h"
/* /*
* 79234640-9e10-4fea-a5c1-b5aa8b19756f * 79234640-9e10-4fea-a5c1-b5aa8b19756f
...@@ -332,7 +332,9 @@ static int skl_int3472_parse_crs(struct int3472_discrete_device *int3472) ...@@ -332,7 +332,9 @@ static int skl_int3472_parse_crs(struct int3472_discrete_device *int3472)
return 0; return 0;
} }
int skl_int3472_discrete_probe(struct platform_device *pdev) static int skl_int3472_discrete_remove(struct platform_device *pdev);
static int skl_int3472_discrete_probe(struct platform_device *pdev)
{ {
struct acpi_device *adev = ACPI_COMPANION(&pdev->dev); struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
struct int3472_discrete_device *int3472; struct int3472_discrete_device *int3472;
...@@ -361,19 +363,10 @@ int skl_int3472_discrete_probe(struct platform_device *pdev) ...@@ -361,19 +363,10 @@ int skl_int3472_discrete_probe(struct platform_device *pdev)
int3472->dev = &pdev->dev; int3472->dev = &pdev->dev;
platform_set_drvdata(pdev, int3472); platform_set_drvdata(pdev, int3472);
int3472->sensor = acpi_dev_get_first_consumer_dev(adev); ret = skl_int3472_get_sensor_adev_and_name(&pdev->dev, &int3472->sensor,
if (!int3472->sensor) { &int3472->sensor_name);
dev_err(&pdev->dev, "INT3472 seems to have no dependents.\n"); if (ret)
return -ENODEV; return ret;
}
int3472->sensor_name = devm_kasprintf(int3472->dev, GFP_KERNEL,
I2C_DEV_NAME_FORMAT,
acpi_dev_name(int3472->sensor));
if (!int3472->sensor_name) {
ret = -ENOMEM;
goto err_put_sensor;
}
/* /*
* Initialising this list means we can call gpiod_remove_lookup_table() * Initialising this list means we can call gpiod_remove_lookup_table()
...@@ -387,15 +380,11 @@ int skl_int3472_discrete_probe(struct platform_device *pdev) ...@@ -387,15 +380,11 @@ int skl_int3472_discrete_probe(struct platform_device *pdev)
return ret; return ret;
} }
acpi_dev_clear_dependencies(adev);
return 0; return 0;
err_put_sensor:
acpi_dev_put(int3472->sensor);
return ret;
} }
int skl_int3472_discrete_remove(struct platform_device *pdev) static int skl_int3472_discrete_remove(struct platform_device *pdev)
{ {
struct int3472_discrete_device *int3472 = platform_get_drvdata(pdev); struct int3472_discrete_device *int3472 = platform_get_drvdata(pdev);
...@@ -411,3 +400,23 @@ int skl_int3472_discrete_remove(struct platform_device *pdev) ...@@ -411,3 +400,23 @@ int skl_int3472_discrete_remove(struct platform_device *pdev)
return 0; return 0;
} }
static const struct acpi_device_id int3472_device_id[] = {
{ "INT3472", 0 },
{ }
};
MODULE_DEVICE_TABLE(acpi, int3472_device_id);
static struct platform_driver int3472_discrete = {
.driver = {
.name = "int3472-discrete",
.acpi_match_table = int3472_device_id,
},
.probe = skl_int3472_discrete_probe,
.remove = skl_int3472_discrete_remove,
};
module_platform_driver(int3472_discrete);
MODULE_DESCRIPTION("Intel SkyLake INT3472 ACPI Discrete Device Driver");
MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
MODULE_LICENSE("GPL v2");
...@@ -2,27 +2,27 @@ ...@@ -2,27 +2,27 @@
/* Author: Dan Scally <djrscally@gmail.com> */ /* Author: Dan Scally <djrscally@gmail.com> */
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/mfd/core.h> #include <linux/mfd/core.h>
#include <linux/mfd/tps68470.h> #include <linux/mfd/tps68470.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/platform_data/tps68470.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/string.h>
#include "intel_skl_int3472_common.h" #include "common.h"
#include "tps68470.h"
#define DESIGNED_FOR_CHROMEOS 1 #define DESIGNED_FOR_CHROMEOS 1
#define DESIGNED_FOR_WINDOWS 2 #define DESIGNED_FOR_WINDOWS 2
#define TPS68470_WIN_MFD_CELL_COUNT 3
static const struct mfd_cell tps68470_cros[] = { static const struct mfd_cell tps68470_cros[] = {
{ .name = "tps68470-gpio" }, { .name = "tps68470-gpio" },
{ .name = "tps68470_pmic_opregion" }, { .name = "tps68470_pmic_opregion" },
}; };
static const struct mfd_cell tps68470_win[] = {
{ .name = "tps68470-gpio" },
{ .name = "tps68470-clk" },
{ .name = "tps68470-regulator" },
};
static const struct regmap_config tps68470_regmap_config = { static const struct regmap_config tps68470_regmap_config = {
.reg_bits = 8, .reg_bits = 8,
.val_bits = 8, .val_bits = 8,
...@@ -95,13 +95,21 @@ static int skl_int3472_tps68470_calc_type(struct acpi_device *adev) ...@@ -95,13 +95,21 @@ static int skl_int3472_tps68470_calc_type(struct acpi_device *adev)
return DESIGNED_FOR_WINDOWS; return DESIGNED_FOR_WINDOWS;
} }
int skl_int3472_tps68470_probe(struct i2c_client *client) static int skl_int3472_tps68470_probe(struct i2c_client *client)
{ {
struct acpi_device *adev = ACPI_COMPANION(&client->dev); struct acpi_device *adev = ACPI_COMPANION(&client->dev);
const struct int3472_tps68470_board_data *board_data;
struct tps68470_clk_platform_data clk_pdata = {};
struct mfd_cell *cells;
struct regmap *regmap; struct regmap *regmap;
int device_type; int device_type;
int ret; int ret;
ret = skl_int3472_get_sensor_adev_and_name(&client->dev, NULL,
&clk_pdata.consumer_dev_name);
if (ret)
return ret;
regmap = devm_regmap_init_i2c(client, &tps68470_regmap_config); regmap = devm_regmap_init_i2c(client, &tps68470_regmap_config);
if (IS_ERR(regmap)) { if (IS_ERR(regmap)) {
dev_err(&client->dev, "Failed to create regmap: %ld\n", PTR_ERR(regmap)); dev_err(&client->dev, "Failed to create regmap: %ld\n", PTR_ERR(regmap));
...@@ -119,9 +127,38 @@ int skl_int3472_tps68470_probe(struct i2c_client *client) ...@@ -119,9 +127,38 @@ int skl_int3472_tps68470_probe(struct i2c_client *client)
device_type = skl_int3472_tps68470_calc_type(adev); device_type = skl_int3472_tps68470_calc_type(adev);
switch (device_type) { switch (device_type) {
case DESIGNED_FOR_WINDOWS: case DESIGNED_FOR_WINDOWS:
board_data = int3472_tps68470_get_board_data(dev_name(&client->dev));
if (!board_data)
return dev_err_probe(&client->dev, -ENODEV, "No board-data found for this model\n");
cells = kcalloc(TPS68470_WIN_MFD_CELL_COUNT, sizeof(*cells), GFP_KERNEL);
if (!cells)
return -ENOMEM;
/*
* The order of the cells matters here! The clk must be first
* because the regulator depends on it. The gpios must be last,
* acpi_gpiochip_add() calls acpi_dev_clear_dependencies() and
* the clk + regulators must be ready when this happens.
*/
cells[0].name = "tps68470-clk";
cells[0].platform_data = &clk_pdata;
cells[0].pdata_size = sizeof(clk_pdata);
cells[1].name = "tps68470-regulator";
cells[1].platform_data = (void *)board_data->tps68470_regulator_pdata;
cells[1].pdata_size = sizeof(struct tps68470_regulator_platform_data);
cells[2].name = "tps68470-gpio";
gpiod_add_lookup_table(board_data->tps68470_gpio_lookup_table);
ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE, ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
tps68470_win, ARRAY_SIZE(tps68470_win), cells, TPS68470_WIN_MFD_CELL_COUNT,
NULL, 0, NULL); NULL, 0, NULL);
kfree(cells);
if (ret)
gpiod_remove_lookup_table(board_data->tps68470_gpio_lookup_table);
break; break;
case DESIGNED_FOR_CHROMEOS: case DESIGNED_FOR_CHROMEOS:
ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE, ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
...@@ -133,5 +170,42 @@ int skl_int3472_tps68470_probe(struct i2c_client *client) ...@@ -133,5 +170,42 @@ int skl_int3472_tps68470_probe(struct i2c_client *client)
return device_type; return device_type;
} }
/*
* No acpi_dev_clear_dependencies() here, since the acpi_gpiochip_add()
* for the GPIO cell already does this.
*/
return ret; return ret;
} }
static int skl_int3472_tps68470_remove(struct i2c_client *client)
{
const struct int3472_tps68470_board_data *board_data;
board_data = int3472_tps68470_get_board_data(dev_name(&client->dev));
if (board_data)
gpiod_remove_lookup_table(board_data->tps68470_gpio_lookup_table);
return 0;
}
static const struct acpi_device_id int3472_device_id[] = {
{ "INT3472", 0 },
{ }
};
MODULE_DEVICE_TABLE(acpi, int3472_device_id);
static struct i2c_driver int3472_tps68470 = {
.driver = {
.name = "int3472-tps68470",
.acpi_match_table = int3472_device_id,
},
.probe_new = skl_int3472_tps68470_probe,
.remove = skl_int3472_tps68470_remove,
};
module_i2c_driver(int3472_tps68470);
MODULE_DESCRIPTION("Intel SkyLake INT3472 ACPI TPS68470 Device Driver");
MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
MODULE_LICENSE("GPL v2");
MODULE_SOFTDEP("pre: clk-tps68470 tps68470-regulator");
/* SPDX-License-Identifier: GPL-2.0 */
/*
* TI TPS68470 PMIC platform data definition.
*
* Copyright (c) 2021 Red Hat Inc.
*
* Red Hat authors:
* Hans de Goede <hdegoede@redhat.com>
*/
#ifndef _INTEL_SKL_INT3472_TPS68470_H
#define _INTEL_SKL_INT3472_TPS68470_H
struct gpiod_lookup_table;
struct tps68470_regulator_platform_data;
struct int3472_tps68470_board_data {
const char *dev_name;
struct gpiod_lookup_table *tps68470_gpio_lookup_table;
const struct tps68470_regulator_platform_data *tps68470_regulator_pdata;
};
const struct int3472_tps68470_board_data *int3472_tps68470_get_board_data(const char *dev_name);
#endif
// SPDX-License-Identifier: GPL-2.0
/*
* TI TPS68470 PMIC platform data definition.
*
* Copyright (c) 2021 Dan Scally <djrscally@gmail.com>
* Copyright (c) 2021 Red Hat Inc.
*
* Red Hat authors:
* Hans de Goede <hdegoede@redhat.com>
*/
#include <linux/dmi.h>
#include <linux/gpio/machine.h>
#include <linux/platform_data/tps68470.h>
#include <linux/regulator/machine.h>
#include "tps68470.h"
static struct regulator_consumer_supply int347a_core_consumer_supplies[] = {
REGULATOR_SUPPLY("dvdd", "i2c-INT347A:00"),
};
static struct regulator_consumer_supply int347a_ana_consumer_supplies[] = {
REGULATOR_SUPPLY("avdd", "i2c-INT347A:00"),
};
static struct regulator_consumer_supply int347a_vcm_consumer_supplies[] = {
REGULATOR_SUPPLY("vdd", "i2c-INT347A:00-VCM"),
};
static struct regulator_consumer_supply int347a_vsio_consumer_supplies[] = {
REGULATOR_SUPPLY("dovdd", "i2c-INT347A:00"),
REGULATOR_SUPPLY("vsio", "i2c-INT347A:00-VCM"),
};
static const struct regulator_init_data surface_go_tps68470_core_reg_init_data = {
.constraints = {
.min_uV = 1200000,
.max_uV = 1200000,
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = ARRAY_SIZE(int347a_core_consumer_supplies),
.consumer_supplies = int347a_core_consumer_supplies,
};
static const struct regulator_init_data surface_go_tps68470_ana_reg_init_data = {
.constraints = {
.min_uV = 2815200,
.max_uV = 2815200,
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = ARRAY_SIZE(int347a_ana_consumer_supplies),
.consumer_supplies = int347a_ana_consumer_supplies,
};
static const struct regulator_init_data surface_go_tps68470_vcm_reg_init_data = {
.constraints = {
.min_uV = 2815200,
.max_uV = 2815200,
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = ARRAY_SIZE(int347a_vcm_consumer_supplies),
.consumer_supplies = int347a_vcm_consumer_supplies,
};
/* Ensure the always-on VIO regulator has the same voltage as VSIO */
static const struct regulator_init_data surface_go_tps68470_vio_reg_init_data = {
.constraints = {
.min_uV = 1800600,
.max_uV = 1800600,
.apply_uV = true,
.always_on = true,
},
};
static const struct regulator_init_data surface_go_tps68470_vsio_reg_init_data = {
.constraints = {
.min_uV = 1800600,
.max_uV = 1800600,
.apply_uV = true,
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = ARRAY_SIZE(int347a_vsio_consumer_supplies),
.consumer_supplies = int347a_vsio_consumer_supplies,
};
static const struct tps68470_regulator_platform_data surface_go_tps68470_pdata = {
.reg_init_data = {
[TPS68470_CORE] = &surface_go_tps68470_core_reg_init_data,
[TPS68470_ANA] = &surface_go_tps68470_ana_reg_init_data,
[TPS68470_VCM] = &surface_go_tps68470_vcm_reg_init_data,
[TPS68470_VIO] = &surface_go_tps68470_vio_reg_init_data,
[TPS68470_VSIO] = &surface_go_tps68470_vsio_reg_init_data,
},
};
static struct gpiod_lookup_table surface_go_tps68470_gpios = {
.dev_id = "i2c-INT347A:00",
.table = {
GPIO_LOOKUP("tps68470-gpio", 9, "reset", GPIO_ACTIVE_LOW),
GPIO_LOOKUP("tps68470-gpio", 7, "powerdown", GPIO_ACTIVE_LOW)
}
};
static const struct int3472_tps68470_board_data surface_go_tps68470_board_data = {
.dev_name = "i2c-INT3472:05",
.tps68470_gpio_lookup_table = &surface_go_tps68470_gpios,
.tps68470_regulator_pdata = &surface_go_tps68470_pdata,
};
static const struct dmi_system_id int3472_tps68470_board_data_table[] = {
{
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Go"),
},
.driver_data = (void *)&surface_go_tps68470_board_data,
},
{
.matches = {
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Go 2"),
},
.driver_data = (void *)&surface_go_tps68470_board_data,
},
{ }
};
const struct int3472_tps68470_board_data *int3472_tps68470_get_board_data(const char *dev_name)
{
const struct int3472_tps68470_board_data *board_data;
const struct dmi_system_id *match;
for (match = dmi_first_match(int3472_tps68470_board_data_table);
match;
match = dmi_first_match(match + 1)) {
board_data = match->driver_data;
if (strcmp(board_data->dev_name, dev_name) == 0)
return board_data;
}
return NULL;
}
...@@ -202,7 +202,8 @@ struct acpi_device_flags { ...@@ -202,7 +202,8 @@ struct acpi_device_flags {
u32 coherent_dma:1; u32 coherent_dma:1;
u32 cca_seen:1; u32 cca_seen:1;
u32 enumeration_by_parent:1; u32 enumeration_by_parent:1;
u32 reserved:19; u32 honor_deps:1;
u32 reserved:18;
}; };
/* File System */ /* File System */
...@@ -285,6 +286,7 @@ struct acpi_dep_data { ...@@ -285,6 +286,7 @@ struct acpi_dep_data {
struct list_head node; struct list_head node;
acpi_handle supplier; acpi_handle supplier;
acpi_handle consumer; acpi_handle consumer;
bool honor_dep;
}; };
/* Performance Management */ /* Performance Management */
...@@ -693,6 +695,7 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev) ...@@ -693,6 +695,7 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2); bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2);
void acpi_dev_clear_dependencies(struct acpi_device *supplier); void acpi_dev_clear_dependencies(struct acpi_device *supplier);
bool acpi_dev_ready_for_enumeration(const struct acpi_device *device);
struct acpi_device *acpi_dev_get_first_consumer_dev(struct acpi_device *supplier); struct acpi_device *acpi_dev_get_first_consumer_dev(struct acpi_device *supplier);
struct acpi_device * struct acpi_device *
acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv); acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv);
......
...@@ -1025,7 +1025,8 @@ bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares, ...@@ -1025,7 +1025,8 @@ bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
struct acpi_resource_i2c_serialbus **i2c); struct acpi_resource_i2c_serialbus **i2c);
int i2c_acpi_client_count(struct acpi_device *adev); int i2c_acpi_client_count(struct acpi_device *adev);
u32 i2c_acpi_find_bus_speed(struct device *dev); u32 i2c_acpi_find_bus_speed(struct device *dev);
struct i2c_client *i2c_acpi_new_device(struct device *dev, int index, struct i2c_client *i2c_acpi_new_device_by_fwnode(struct fwnode_handle *fwnode,
int index,
struct i2c_board_info *info); struct i2c_board_info *info);
struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle); struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle);
bool i2c_acpi_waive_d0_probe(struct device *dev); bool i2c_acpi_waive_d0_probe(struct device *dev);
...@@ -1043,8 +1044,9 @@ static inline u32 i2c_acpi_find_bus_speed(struct device *dev) ...@@ -1043,8 +1044,9 @@ static inline u32 i2c_acpi_find_bus_speed(struct device *dev)
{ {
return 0; return 0;
} }
static inline struct i2c_client *i2c_acpi_new_device(struct device *dev, static inline struct i2c_client *i2c_acpi_new_device_by_fwnode(
int index, struct i2c_board_info *info) struct fwnode_handle *fwnode, int index,
struct i2c_board_info *info)
{ {
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
} }
...@@ -1058,4 +1060,11 @@ static inline bool i2c_acpi_waive_d0_probe(struct device *dev) ...@@ -1058,4 +1060,11 @@ static inline bool i2c_acpi_waive_d0_probe(struct device *dev)
} }
#endif /* CONFIG_ACPI */ #endif /* CONFIG_ACPI */
static inline struct i2c_client *i2c_acpi_new_device(struct device *dev,
int index,
struct i2c_board_info *info)
{
return i2c_acpi_new_device_by_fwnode(dev_fwnode(dev), index, info);
}
#endif /* _LINUX_I2C_H */ #endif /* _LINUX_I2C_H */
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* TI TPS68470 PMIC platform data definition.
*
* Copyright (c) 2021 Red Hat Inc.
*
* Red Hat authors:
* Hans de Goede <hdegoede@redhat.com>
*/
#ifndef __PDATA_TPS68470_H
#define __PDATA_TPS68470_H
enum tps68470_regulators {
TPS68470_CORE,
TPS68470_ANA,
TPS68470_VCM,
TPS68470_VIO,
TPS68470_VSIO,
TPS68470_AUX1,
TPS68470_AUX2,
TPS68470_NUM_REGULATORS
};
struct regulator_init_data;
struct tps68470_regulator_platform_data {
const struct regulator_init_data *reg_init_data[TPS68470_NUM_REGULATORS];
};
struct tps68470_clk_platform_data {
const char *consumer_dev_name;
const char *consumer_con_id;
};
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment