1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /******************************************************************************* |
3 | * |
4 | * CTU CAN FD IP Core |
5 | * |
6 | * Copyright (C) 2015-2018 Ondrej Ille <ondrej.ille@gmail.com> FEE CTU |
7 | * Copyright (C) 2018-2021 Ondrej Ille <ondrej.ille@gmail.com> self-funded |
8 | * Copyright (C) 2018-2019 Martin Jerabek <martin.jerabek01@gmail.com> FEE CTU |
9 | * Copyright (C) 2018-2022 Pavel Pisa <pisa@cmp.felk.cvut.cz> FEE CTU/self-funded |
10 | * |
11 | * Project advisors: |
12 | * Jiri Novak <jnovak@fel.cvut.cz> |
13 | * Pavel Pisa <pisa@cmp.felk.cvut.cz> |
14 | * |
15 | * Department of Measurement (http://meas.fel.cvut.cz/) |
16 | * Faculty of Electrical Engineering (http://www.fel.cvut.cz) |
17 | * Czech Technical University (http://www.cvut.cz/) |
18 | ******************************************************************************/ |
19 | |
20 | #include <linux/module.h> |
21 | #include <linux/netdevice.h> |
22 | #include <linux/of.h> |
23 | #include <linux/platform_device.h> |
24 | #include <linux/pm_runtime.h> |
25 | |
26 | #include "ctucanfd.h" |
27 | |
28 | #define DRV_NAME "ctucanfd" |
29 | |
30 | static void ctucan_platform_set_drvdata(struct device *dev, |
31 | struct net_device *ndev) |
32 | { |
33 | struct platform_device *pdev = container_of(dev, struct platform_device, |
34 | dev); |
35 | |
36 | platform_set_drvdata(pdev, data: ndev); |
37 | } |
38 | |
39 | /** |
40 | * ctucan_platform_probe - Platform registration call |
41 | * @pdev: Handle to the platform device structure |
42 | * |
43 | * This function does all the memory allocation and registration for the CAN |
44 | * device. |
45 | * |
46 | * Return: 0 on success and failure value on error |
47 | */ |
48 | static int ctucan_platform_probe(struct platform_device *pdev) |
49 | { |
50 | struct device *dev = &pdev->dev; |
51 | void __iomem *addr; |
52 | int ret; |
53 | unsigned int ntxbufs; |
54 | int irq; |
55 | |
56 | /* Get the virtual base address for the device */ |
57 | addr = devm_platform_ioremap_resource(pdev, index: 0); |
58 | if (IS_ERR(ptr: addr)) { |
59 | ret = PTR_ERR(ptr: addr); |
60 | goto err; |
61 | } |
62 | irq = platform_get_irq(pdev, 0); |
63 | if (irq < 0) { |
64 | ret = irq; |
65 | goto err; |
66 | } |
67 | |
68 | /* Number of tx bufs might be change in HW for future. If so, |
69 | * it will be passed as property via device tree |
70 | */ |
71 | ntxbufs = 4; |
72 | ret = ctucan_probe_common(dev, addr, irq, ntxbufs, can_clk_rate: 0, |
73 | pm_enable_call: 1, set_drvdata_fnc: ctucan_platform_set_drvdata); |
74 | |
75 | if (ret < 0) |
76 | platform_set_drvdata(pdev, NULL); |
77 | |
78 | err: |
79 | return ret; |
80 | } |
81 | |
82 | /** |
83 | * ctucan_platform_remove - Unregister the device after releasing the resources |
84 | * @pdev: Handle to the platform device structure |
85 | * |
86 | * This function frees all the resources allocated to the device. |
87 | * Return: 0 always |
88 | */ |
89 | static void ctucan_platform_remove(struct platform_device *pdev) |
90 | { |
91 | struct net_device *ndev = platform_get_drvdata(pdev); |
92 | struct ctucan_priv *priv = netdev_priv(dev: ndev); |
93 | |
94 | netdev_dbg(ndev, "ctucan_remove" ); |
95 | |
96 | unregister_candev(dev: ndev); |
97 | pm_runtime_disable(dev: &pdev->dev); |
98 | netif_napi_del(napi: &priv->napi); |
99 | free_candev(dev: ndev); |
100 | } |
101 | |
102 | static SIMPLE_DEV_PM_OPS(ctucan_platform_pm_ops, ctucan_suspend, ctucan_resume); |
103 | |
104 | /* Match table for OF platform binding */ |
105 | static const struct of_device_id ctucan_of_match[] = { |
106 | { .compatible = "ctu,ctucanfd-2" , }, |
107 | { .compatible = "ctu,ctucanfd" , }, |
108 | { /* end of list */ }, |
109 | }; |
110 | MODULE_DEVICE_TABLE(of, ctucan_of_match); |
111 | |
112 | static struct platform_driver ctucanfd_driver = { |
113 | .probe = ctucan_platform_probe, |
114 | .remove_new = ctucan_platform_remove, |
115 | .driver = { |
116 | .name = DRV_NAME, |
117 | .pm = &ctucan_platform_pm_ops, |
118 | .of_match_table = ctucan_of_match, |
119 | }, |
120 | }; |
121 | |
122 | module_platform_driver(ctucanfd_driver); |
123 | |
124 | MODULE_LICENSE("GPL" ); |
125 | MODULE_AUTHOR("Martin Jerabek" ); |
126 | MODULE_DESCRIPTION("CTU CAN FD for platform" ); |
127 | |