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