1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
4 * Author: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
5 */
6
7 #include <linux/device.h>
8 #include <linux/delay.h>
9 #include <linux/gpio/consumer.h>
10 #include <linux/mod_devicetable.h>
11 #include <linux/module.h>
12 #include <linux/of.h>
13 #include <linux/of_graph.h>
14 #include <linux/of_platform.h>
15 #include <linux/pci.h>
16 #include <linux/platform_device.h>
17 #include <linux/pwrseq/provider.h>
18 #include <linux/regulator/consumer.h>
19 #include <linux/serdev.h>
20 #include <linux/slab.h>
21
22 struct pwrseq_pcie_m2_pdata {
23 const struct pwrseq_target_data **targets;
24 };
25
26 struct pwrseq_pcie_m2_ctx {
27 struct pwrseq_device *pwrseq;
28 struct device_node *of_node;
29 const struct pwrseq_pcie_m2_pdata *pdata;
30 struct regulator_bulk_data *regs;
31 size_t num_vregs;
32 struct notifier_block nb;
33 struct gpio_desc *w_disable1_gpio;
34 struct gpio_desc *w_disable2_gpio;
35 struct serdev_device *serdev;
36 struct of_changeset *ocs;
37 struct device *dev;
38 };
39
pwrseq_pcie_m2_vregs_enable(struct pwrseq_device * pwrseq)40 static int pwrseq_pcie_m2_vregs_enable(struct pwrseq_device *pwrseq)
41 {
42 struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
43
44 return regulator_bulk_enable(ctx->num_vregs, ctx->regs);
45 }
46
pwrseq_pcie_m2_vregs_disable(struct pwrseq_device * pwrseq)47 static int pwrseq_pcie_m2_vregs_disable(struct pwrseq_device *pwrseq)
48 {
49 struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
50
51 return regulator_bulk_disable(ctx->num_vregs, ctx->regs);
52 }
53
54 static const struct pwrseq_unit_data pwrseq_pcie_m2_vregs_unit_data = {
55 .name = "regulators-enable",
56 .enable = pwrseq_pcie_m2_vregs_enable,
57 .disable = pwrseq_pcie_m2_vregs_disable,
58 };
59
60 static const struct pwrseq_unit_data *pwrseq_pcie_m2_unit_deps[] = {
61 &pwrseq_pcie_m2_vregs_unit_data,
62 NULL
63 };
64
pwrseq_pci_m2_e_uart_enable(struct pwrseq_device * pwrseq)65 static int pwrseq_pci_m2_e_uart_enable(struct pwrseq_device *pwrseq)
66 {
67 struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
68
69 return gpiod_set_value_cansleep(ctx->w_disable2_gpio, 0);
70 }
71
pwrseq_pci_m2_e_uart_disable(struct pwrseq_device * pwrseq)72 static int pwrseq_pci_m2_e_uart_disable(struct pwrseq_device *pwrseq)
73 {
74 struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
75
76 return gpiod_set_value_cansleep(ctx->w_disable2_gpio, 1);
77 }
78
79 static const struct pwrseq_unit_data pwrseq_pcie_m2_e_uart_unit_data = {
80 .name = "uart-enable",
81 .deps = pwrseq_pcie_m2_unit_deps,
82 .enable = pwrseq_pci_m2_e_uart_enable,
83 .disable = pwrseq_pci_m2_e_uart_disable,
84 };
85
pwrseq_pci_m2_e_pcie_enable(struct pwrseq_device * pwrseq)86 static int pwrseq_pci_m2_e_pcie_enable(struct pwrseq_device *pwrseq)
87 {
88 struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
89
90 return gpiod_set_value_cansleep(ctx->w_disable1_gpio, 0);
91 }
92
pwrseq_pci_m2_e_pcie_disable(struct pwrseq_device * pwrseq)93 static int pwrseq_pci_m2_e_pcie_disable(struct pwrseq_device *pwrseq)
94 {
95 struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
96
97 return gpiod_set_value_cansleep(ctx->w_disable1_gpio, 1);
98 }
99
100 static const struct pwrseq_unit_data pwrseq_pcie_m2_e_pcie_unit_data = {
101 .name = "pcie-enable",
102 .deps = pwrseq_pcie_m2_unit_deps,
103 .enable = pwrseq_pci_m2_e_pcie_enable,
104 .disable = pwrseq_pci_m2_e_pcie_disable,
105 };
106
107 static const struct pwrseq_unit_data pwrseq_pcie_m2_m_pcie_unit_data = {
108 .name = "pcie-enable",
109 .deps = pwrseq_pcie_m2_unit_deps,
110 };
111
pwrseq_pcie_m2_e_pwup_delay(struct pwrseq_device * pwrseq)112 static int pwrseq_pcie_m2_e_pwup_delay(struct pwrseq_device *pwrseq)
113 {
114 /*
115 * FIXME: This delay is only required for some Qcom WLAN/BT cards like
116 * WCN7850 and not for all devices. But currently, there is no way to
117 * identify the device model before enumeration.
118 */
119 msleep(50);
120
121 return 0;
122 }
123
124 static const struct pwrseq_target_data pwrseq_pcie_m2_e_uart_target_data = {
125 .name = "uart",
126 .unit = &pwrseq_pcie_m2_e_uart_unit_data,
127 .post_enable = pwrseq_pcie_m2_e_pwup_delay,
128 };
129
130 static const struct pwrseq_target_data pwrseq_pcie_m2_e_pcie_target_data = {
131 .name = "pcie",
132 .unit = &pwrseq_pcie_m2_e_pcie_unit_data,
133 .post_enable = pwrseq_pcie_m2_e_pwup_delay,
134 };
135
136 static const struct pwrseq_target_data pwrseq_pcie_m2_m_pcie_target_data = {
137 .name = "pcie",
138 .unit = &pwrseq_pcie_m2_m_pcie_unit_data,
139 };
140
141 static const struct pwrseq_target_data *pwrseq_pcie_m2_e_targets[] = {
142 &pwrseq_pcie_m2_e_pcie_target_data,
143 &pwrseq_pcie_m2_e_uart_target_data,
144 NULL
145 };
146
147 static const struct pwrseq_target_data *pwrseq_pcie_m2_m_targets[] = {
148 &pwrseq_pcie_m2_m_pcie_target_data,
149 NULL
150 };
151
152 static const struct pwrseq_pcie_m2_pdata pwrseq_pcie_m2_e_of_data = {
153 .targets = pwrseq_pcie_m2_e_targets,
154 };
155
156 static const struct pwrseq_pcie_m2_pdata pwrseq_pcie_m2_m_of_data = {
157 .targets = pwrseq_pcie_m2_m_targets,
158 };
159
pwrseq_pcie_m2_match(struct pwrseq_device * pwrseq,struct device * dev)160 static int pwrseq_pcie_m2_match(struct pwrseq_device *pwrseq,
161 struct device *dev)
162 {
163 struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
164 struct device_node *endpoint __free(device_node) = NULL;
165
166 /*
167 * Traverse the 'remote-endpoint' nodes and check if the remote node's
168 * parent matches the OF node of 'dev'.
169 */
170 for_each_endpoint_of_node(ctx->of_node, endpoint) {
171 struct device_node *remote __free(device_node) =
172 of_graph_get_remote_port_parent(endpoint);
173 if (remote && (remote == dev_of_node(dev)))
174 return PWRSEQ_MATCH_OK;
175 }
176
177 return PWRSEQ_NO_MATCH;
178 }
179
pwrseq_m2_pcie_create_bt_node(struct pwrseq_pcie_m2_ctx * ctx,struct device_node * parent)180 static int pwrseq_m2_pcie_create_bt_node(struct pwrseq_pcie_m2_ctx *ctx,
181 struct device_node *parent)
182 {
183 struct device *dev = ctx->dev;
184 struct device_node *np;
185 int ret;
186
187 ctx->ocs = kzalloc_obj(*ctx->ocs);
188 if (!ctx->ocs)
189 return -ENOMEM;
190
191 of_changeset_init(ctx->ocs);
192
193 np = of_changeset_create_node(ctx->ocs, parent, "bluetooth");
194 if (!np) {
195 dev_err(dev, "Failed to create bluetooth node\n");
196 ret = -ENODEV;
197 goto err_destroy_changeset;
198 }
199
200 ret = of_changeset_add_prop_string(ctx->ocs, np, "compatible", "qcom,wcn7850-bt");
201 if (ret) {
202 dev_err(dev, "Failed to add bluetooth compatible: %d\n", ret);
203 goto err_destroy_changeset;
204 }
205
206 ret = of_changeset_apply(ctx->ocs);
207 if (ret) {
208 dev_err(dev, "Failed to apply changeset: %d\n", ret);
209 goto err_destroy_changeset;
210 }
211
212 ret = device_add_of_node(&ctx->serdev->dev, np);
213 if (ret) {
214 dev_err(dev, "Failed to add OF node: %d\n", ret);
215 goto err_revert_changeset;
216 }
217
218 return 0;
219
220 err_revert_changeset:
221 of_changeset_revert(ctx->ocs);
222 err_destroy_changeset:
223 of_changeset_destroy(ctx->ocs);
224 kfree(ctx->ocs);
225 ctx->ocs = NULL;
226
227 return ret;
228 }
229
pwrseq_pcie_m2_create_serdev(struct pwrseq_pcie_m2_ctx * ctx)230 static int pwrseq_pcie_m2_create_serdev(struct pwrseq_pcie_m2_ctx *ctx)
231 {
232 struct serdev_controller *serdev_ctrl;
233 struct device *dev = ctx->dev;
234 int ret;
235
236 struct device_node *serdev_parent __free(device_node) =
237 of_graph_get_remote_node(dev_of_node(ctx->dev), 3, 0);
238 if (!serdev_parent)
239 return 0;
240
241 serdev_ctrl = of_find_serdev_controller_by_node(serdev_parent);
242 if (!serdev_ctrl)
243 return 0;
244
245 /* Bail out if the device was already attached to this controller */
246 if (serdev_ctrl->serdev) {
247 serdev_controller_put(serdev_ctrl);
248 return 0;
249 }
250
251 ctx->serdev = serdev_device_alloc(serdev_ctrl);
252 if (!ctx->serdev) {
253 ret = -ENOMEM;
254 goto err_put_ctrl;
255 }
256
257 ret = pwrseq_m2_pcie_create_bt_node(ctx, serdev_parent);
258 if (ret)
259 goto err_free_serdev;
260
261 ret = serdev_device_add(ctx->serdev);
262 if (ret) {
263 dev_err(dev, "Failed to add serdev for WCN7850: %d\n", ret);
264 goto err_free_dt_node;
265 }
266
267 serdev_controller_put(serdev_ctrl);
268
269 return 0;
270
271 err_free_dt_node:
272 device_remove_of_node(&ctx->serdev->dev);
273 of_changeset_revert(ctx->ocs);
274 of_changeset_destroy(ctx->ocs);
275 kfree(ctx->ocs);
276 ctx->ocs = NULL;
277 err_free_serdev:
278 serdev_device_put(ctx->serdev);
279 ctx->serdev = NULL;
280 err_put_ctrl:
281 serdev_controller_put(serdev_ctrl);
282
283 return ret;
284 }
285
pwrseq_pcie_m2_remove_serdev(struct pwrseq_pcie_m2_ctx * ctx)286 static void pwrseq_pcie_m2_remove_serdev(struct pwrseq_pcie_m2_ctx *ctx)
287 {
288 if (ctx->serdev) {
289 device_remove_of_node(&ctx->serdev->dev);
290 serdev_device_remove(ctx->serdev);
291 ctx->serdev = NULL;
292 }
293
294 if (ctx->ocs) {
295 of_changeset_revert(ctx->ocs);
296 of_changeset_destroy(ctx->ocs);
297 kfree(ctx->ocs);
298 ctx->ocs = NULL;
299 }
300 }
301
pwrseq_m2_pcie_notify(struct notifier_block * nb,unsigned long action,void * data)302 static int pwrseq_m2_pcie_notify(struct notifier_block *nb, unsigned long action,
303 void *data)
304 {
305 struct pwrseq_pcie_m2_ctx *ctx = container_of(nb, struct pwrseq_pcie_m2_ctx, nb);
306 struct pci_dev *pdev = to_pci_dev(data);
307 int ret;
308
309 /*
310 * Check whether the PCI device is associated with this M.2 connector or
311 * not, by comparing the OF node of the PCI device parent and the Port 0
312 * (PCIe) remote node parent OF node.
313 */
314 struct device_node *pci_parent __free(device_node) =
315 of_graph_get_remote_node(dev_of_node(ctx->dev), 0, 0);
316 if (!pci_parent || (pci_parent != pdev->dev.parent->of_node))
317 return NOTIFY_DONE;
318
319 switch (action) {
320 case BUS_NOTIFY_ADD_DEVICE:
321 /* Create serdev device for WCN7850 */
322 if (pdev->vendor == PCI_VENDOR_ID_QCOM && pdev->device == 0x1107) {
323 ret = pwrseq_pcie_m2_create_serdev(ctx);
324 if (ret)
325 return notifier_from_errno(ret);
326 }
327 break;
328 case BUS_NOTIFY_REMOVED_DEVICE:
329 /* Destroy serdev device for WCN7850 */
330 if (pdev->vendor == PCI_VENDOR_ID_QCOM && pdev->device == 0x1107)
331 pwrseq_pcie_m2_remove_serdev(ctx);
332
333 break;
334 }
335
336 return NOTIFY_OK;
337 }
338
pwrseq_pcie_m2_check_remote_node(struct device * dev,u8 port,u8 endpoint,const char * node)339 static bool pwrseq_pcie_m2_check_remote_node(struct device *dev, u8 port, u8 endpoint,
340 const char *node)
341 {
342 struct device_node *remote __free(device_node) =
343 of_graph_get_remote_node(dev_of_node(dev), port, endpoint);
344
345 if (remote && of_node_name_eq(remote, node))
346 return true;
347
348 return false;
349 }
350
351 /*
352 * If the connector exposes a non-discoverable bus like UART, the respective
353 * protocol device needs to be created manually with the help of the notifier
354 * of the discoverable bus like PCIe.
355 */
pwrseq_pcie_m2_register_notifier(struct pwrseq_pcie_m2_ctx * ctx,struct device * dev)356 static int pwrseq_pcie_m2_register_notifier(struct pwrseq_pcie_m2_ctx *ctx, struct device *dev)
357 {
358 int ret;
359
360 /*
361 * Register a PCI notifier for Key E connector that has PCIe as Port
362 * 0/Endpoint 0 interface and Serial as Port 3/Endpoint 0 interface.
363 */
364 if (pwrseq_pcie_m2_check_remote_node(dev, 3, 0, "serial")) {
365 if (pwrseq_pcie_m2_check_remote_node(dev, 0, 0, "pcie")) {
366 ctx->dev = dev;
367 ctx->nb.notifier_call = pwrseq_m2_pcie_notify;
368 ret = bus_register_notifier(&pci_bus_type, &ctx->nb);
369 if (ret)
370 return dev_err_probe(dev, ret,
371 "Failed to register notifier for serdev\n");
372 }
373 }
374
375 return 0;
376 }
377
pwrseq_pcie_m2_probe(struct platform_device * pdev)378 static int pwrseq_pcie_m2_probe(struct platform_device *pdev)
379 {
380 struct device *dev = &pdev->dev;
381 struct pwrseq_pcie_m2_ctx *ctx;
382 struct pwrseq_config config = {};
383 int ret;
384
385 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
386 if (!ctx)
387 return -ENOMEM;
388
389 platform_set_drvdata(pdev, ctx);
390 ctx->of_node = dev_of_node(dev);
391 ctx->pdata = device_get_match_data(dev);
392 if (!ctx->pdata)
393 return dev_err_probe(dev, -ENODEV,
394 "Failed to obtain platform data\n");
395
396 /*
397 * Currently, of_regulator_bulk_get_all() is the only regulator API that
398 * allows to get all supplies in the devicetree node without manually
399 * specifying them.
400 */
401 ret = of_regulator_bulk_get_all(dev, dev_of_node(dev), &ctx->regs);
402 if (ret < 0)
403 return dev_err_probe(dev, ret,
404 "Failed to get all regulators\n");
405
406 ctx->num_vregs = ret;
407
408 ctx->w_disable1_gpio = devm_gpiod_get_optional(dev, "w-disable1", GPIOD_OUT_HIGH);
409 if (IS_ERR(ctx->w_disable1_gpio)) {
410 ret = dev_err_probe(dev, PTR_ERR(ctx->w_disable1_gpio),
411 "Failed to get the W_DISABLE_1# GPIO\n");
412 goto err_free_regulators;
413 }
414
415 ctx->w_disable2_gpio = devm_gpiod_get_optional(dev, "w-disable2", GPIOD_OUT_HIGH);
416 if (IS_ERR(ctx->w_disable2_gpio)) {
417 ret = dev_err_probe(dev, PTR_ERR(ctx->w_disable2_gpio),
418 "Failed to get the W_DISABLE_2# GPIO\n");
419 goto err_free_regulators;
420 }
421
422 config.parent = dev;
423 config.owner = THIS_MODULE;
424 config.drvdata = ctx;
425 config.match = pwrseq_pcie_m2_match;
426 config.targets = ctx->pdata->targets;
427
428 ctx->pwrseq = devm_pwrseq_device_register(dev, &config);
429 if (IS_ERR(ctx->pwrseq)) {
430 ret = dev_err_probe(dev, PTR_ERR(ctx->pwrseq),
431 "Failed to register the power sequencer\n");
432 goto err_free_regulators;
433 }
434
435 /*
436 * Register a notifier for creating protocol devices for
437 * non-discoverable busses like UART.
438 */
439 ret = pwrseq_pcie_m2_register_notifier(ctx, dev);
440 if (ret)
441 goto err_free_regulators;
442
443 return 0;
444
445 err_free_regulators:
446 regulator_bulk_free(ctx->num_vregs, ctx->regs);
447
448 return ret;
449 }
450
pwrseq_pcie_m2_remove(struct platform_device * pdev)451 static void pwrseq_pcie_m2_remove(struct platform_device *pdev)
452 {
453 struct pwrseq_pcie_m2_ctx *ctx = platform_get_drvdata(pdev);
454
455 bus_unregister_notifier(&pci_bus_type, &ctx->nb);
456 pwrseq_pcie_m2_remove_serdev(ctx);
457
458 regulator_bulk_free(ctx->num_vregs, ctx->regs);
459 }
460
461 static const struct of_device_id pwrseq_pcie_m2_of_match[] = {
462 {
463 .compatible = "pcie-m2-m-connector",
464 .data = &pwrseq_pcie_m2_m_of_data,
465 },
466 {
467 .compatible = "pcie-m2-e-connector",
468 .data = &pwrseq_pcie_m2_e_of_data,
469 },
470 { }
471 };
472 MODULE_DEVICE_TABLE(of, pwrseq_pcie_m2_of_match);
473
474 static struct platform_driver pwrseq_pcie_m2_driver = {
475 .driver = {
476 .name = "pwrseq-pcie-m2",
477 .of_match_table = pwrseq_pcie_m2_of_match,
478 },
479 .probe = pwrseq_pcie_m2_probe,
480 .remove = pwrseq_pcie_m2_remove,
481 };
482 module_platform_driver(pwrseq_pcie_m2_driver);
483
484 MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>");
485 MODULE_DESCRIPTION("Power Sequencing driver for PCIe M.2 connector");
486 MODULE_LICENSE("GPL");
487