aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeikki Krogerus <heikki.krogerus@linux.intel.com>2019-05-31 10:15:44 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2019-06-03 04:55:39 -0400
commit4ed89a005a97c5e729548567810f9d766efbb0d6 (patch)
tree4683d2344728814811b4f94e78f57ed4dc1f2a88
parent80b915c11dbd4a13fc31ce879ad910277f89e7a7 (diff)
platform/x86: intel_cht_int33fe: Provide software nodes for the devices
Software nodes provide two features that we will need later. 1) Software nodes can have references to other software nodes. 2) Software nodes can exist before a device entry is created. Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Tested-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/platform/x86/intel_cht_int33fe.c54
1 files changed, 46 insertions, 8 deletions
diff --git a/drivers/platform/x86/intel_cht_int33fe.c b/drivers/platform/x86/intel_cht_int33fe.c
index 4ab47d6df413..9eb2ec47b47e 100644
--- a/drivers/platform/x86/intel_cht_int33fe.c
+++ b/drivers/platform/x86/intel_cht_int33fe.c
@@ -27,6 +27,13 @@
27 27
28#define EXPECTED_PTYPE 4 28#define EXPECTED_PTYPE 4
29 29
30enum {
31 INT33FE_NODE_FUSB302,
32 INT33FE_NODE_MAX17047,
33 INT33FE_NODE_PI3USB30532,
34 INT33FE_NODE_MAX,
35};
36
30struct cht_int33fe_data { 37struct cht_int33fe_data {
31 struct i2c_client *max17047; 38 struct i2c_client *max17047;
32 struct i2c_client *fusb302; 39 struct i2c_client *fusb302;
@@ -72,8 +79,13 @@ static const struct property_entry max17047_props[] = {
72 79
73static const struct property_entry fusb302_props[] = { 80static const struct property_entry fusb302_props[] = {
74 PROPERTY_ENTRY_STRING("linux,extcon-name", "cht_wcove_pwrsrc"), 81 PROPERTY_ENTRY_STRING("linux,extcon-name", "cht_wcove_pwrsrc"),
75 PROPERTY_ENTRY_U32("fcs,max-sink-microvolt", 12000000), 82 { }
76 PROPERTY_ENTRY_U32("fcs,max-sink-microamp", 3000000), 83};
84
85static const struct software_node nodes[] = {
86 { "fusb302", NULL, fusb302_props },
87 { "max17047", NULL, max17047_props },
88 { "pi3usb30532" },
77 { } 89 { }
78}; 90};
79 91
@@ -82,14 +94,18 @@ cht_int33fe_register_max17047(struct device *dev, struct cht_int33fe_data *data)
82{ 94{
83 struct i2c_client *max17047 = NULL; 95 struct i2c_client *max17047 = NULL;
84 struct i2c_board_info board_info; 96 struct i2c_board_info board_info;
97 struct fwnode_handle *fwnode;
85 int ret; 98 int ret;
86 99
100 fwnode = software_node_fwnode(&nodes[INT33FE_NODE_MAX17047]);
101 if (!fwnode)
102 return -ENODEV;
103
87 i2c_for_each_dev(&max17047, cht_int33fe_check_for_max17047); 104 i2c_for_each_dev(&max17047, cht_int33fe_check_for_max17047);
88 if (max17047) { 105 if (max17047) {
89 /* Pre-existing i2c-client for the max17047, add device-props */ 106 /* Pre-existing i2c-client for the max17047, add device-props */
90 ret = device_add_properties(&max17047->dev, max17047_props); 107 fwnode->secondary = ERR_PTR(-ENODEV);
91 if (ret) 108 max17047->dev.fwnode->secondary = fwnode;
92 return ret;
93 /* And re-probe to get the new device-props applied. */ 109 /* And re-probe to get the new device-props applied. */
94 ret = device_reprobe(&max17047->dev); 110 ret = device_reprobe(&max17047->dev);
95 if (ret) 111 if (ret)
@@ -100,7 +116,7 @@ cht_int33fe_register_max17047(struct device *dev, struct cht_int33fe_data *data)
100 memset(&board_info, 0, sizeof(board_info)); 116 memset(&board_info, 0, sizeof(board_info));
101 strlcpy(board_info.type, "max17047", I2C_NAME_SIZE); 117 strlcpy(board_info.type, "max17047", I2C_NAME_SIZE);
102 board_info.dev_name = "max17047"; 118 board_info.dev_name = "max17047";
103 board_info.properties = max17047_props; 119 board_info.fwnode = fwnode;
104 data->max17047 = i2c_acpi_new_device(dev, 1, &board_info); 120 data->max17047 = i2c_acpi_new_device(dev, 1, &board_info);
105 121
106 return PTR_ERR_OR_ZERO(data->max17047); 122 return PTR_ERR_OR_ZERO(data->max17047);
@@ -111,6 +127,7 @@ static int cht_int33fe_probe(struct platform_device *pdev)
111 struct device *dev = &pdev->dev; 127 struct device *dev = &pdev->dev;
112 struct i2c_board_info board_info; 128 struct i2c_board_info board_info;
113 struct cht_int33fe_data *data; 129 struct cht_int33fe_data *data;
130 struct fwnode_handle *fwnode;
114 struct regulator *regulator; 131 struct regulator *regulator;
115 unsigned long long ptyp; 132 unsigned long long ptyp;
116 acpi_status status; 133 acpi_status status;
@@ -170,10 +187,14 @@ static int cht_int33fe_probe(struct platform_device *pdev)
170 if (!data) 187 if (!data)
171 return -ENOMEM; 188 return -ENOMEM;
172 189
190 ret = software_node_register_nodes(nodes);
191 if (ret)
192 return ret;
193
173 /* Work around BIOS bug, see comment on cht_int33fe_check_for_max17047 */ 194 /* Work around BIOS bug, see comment on cht_int33fe_check_for_max17047 */
174 ret = cht_int33fe_register_max17047(dev, data); 195 ret = cht_int33fe_register_max17047(dev, data);
175 if (ret) 196 if (ret)
176 return ret; 197 goto out_remove_nodes;
177 198
178 data->connections[0].endpoint[0] = "port0"; 199 data->connections[0].endpoint[0] = "port0";
179 data->connections[0].endpoint[1] = "i2c-pi3usb30532-switch"; 200 data->connections[0].endpoint[1] = "i2c-pi3usb30532-switch";
@@ -187,10 +208,16 @@ static int cht_int33fe_probe(struct platform_device *pdev)
187 208
188 device_connections_add(data->connections); 209 device_connections_add(data->connections);
189 210
211 fwnode = software_node_fwnode(&nodes[INT33FE_NODE_FUSB302]);
212 if (!fwnode) {
213 ret = -ENODEV;
214 goto out_unregister_max17047;
215 }
216
190 memset(&board_info, 0, sizeof(board_info)); 217 memset(&board_info, 0, sizeof(board_info));
191 strlcpy(board_info.type, "typec_fusb302", I2C_NAME_SIZE); 218 strlcpy(board_info.type, "typec_fusb302", I2C_NAME_SIZE);
192 board_info.dev_name = "fusb302"; 219 board_info.dev_name = "fusb302";
193 board_info.properties = fusb302_props; 220 board_info.fwnode = fwnode;
194 board_info.irq = fusb302_irq; 221 board_info.irq = fusb302_irq;
195 222
196 data->fusb302 = i2c_acpi_new_device(dev, 2, &board_info); 223 data->fusb302 = i2c_acpi_new_device(dev, 2, &board_info);
@@ -199,8 +226,15 @@ static int cht_int33fe_probe(struct platform_device *pdev)
199 goto out_unregister_max17047; 226 goto out_unregister_max17047;
200 } 227 }
201 228
229 fwnode = software_node_fwnode(&nodes[INT33FE_NODE_PI3USB30532]);
230 if (!fwnode) {
231 ret = -ENODEV;
232 goto out_unregister_fusb302;
233 }
234
202 memset(&board_info, 0, sizeof(board_info)); 235 memset(&board_info, 0, sizeof(board_info));
203 board_info.dev_name = "pi3usb30532"; 236 board_info.dev_name = "pi3usb30532";
237 board_info.fwnode = fwnode;
204 strlcpy(board_info.type, "pi3usb30532", I2C_NAME_SIZE); 238 strlcpy(board_info.type, "pi3usb30532", I2C_NAME_SIZE);
205 239
206 data->pi3usb30532 = i2c_acpi_new_device(dev, 3, &board_info); 240 data->pi3usb30532 = i2c_acpi_new_device(dev, 3, &board_info);
@@ -221,6 +255,9 @@ out_unregister_max17047:
221 255
222 device_connections_remove(data->connections); 256 device_connections_remove(data->connections);
223 257
258out_remove_nodes:
259 software_node_unregister_nodes(nodes);
260
224 return ret; 261 return ret;
225} 262}
226 263
@@ -233,6 +270,7 @@ static int cht_int33fe_remove(struct platform_device *pdev)
233 i2c_unregister_device(data->max17047); 270 i2c_unregister_device(data->max17047);
234 271
235 device_connections_remove(data->connections); 272 device_connections_remove(data->connections);
273 software_node_unregister_nodes(nodes);
236 274
237 return 0; 275 return 0;
238} 276}