Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

can: mcp251x: Add device tree support

This patch adds Device Tree support to the Microchip MCP251X driver.

Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>

authored by

Alexander Shiyan and committed by
Marc Kleine-Budde
66606aaf c0ebbdd6

+99 -25
+25
Documentation/devicetree/bindings/net/can/microchip,mcp251x.txt
··· 1 + * Microchip MCP251X stand-alone CAN controller device tree bindings 2 + 3 + Required properties: 4 + - compatible: Should be one of the following: 5 + - "microchip,mcp2510" for MCP2510. 6 + - "microchip,mcp2515" for MCP2515. 7 + - reg: SPI chip select. 8 + - clocks: The clock feeding the CAN controller. 9 + - interrupt-parent: The parent interrupt controller. 10 + - interrupts: Should contain IRQ line for the CAN controller. 11 + 12 + Optional properties: 13 + - vdd-supply: Regulator that powers the CAN controller. 14 + - xceiver-supply: Regulator that powers the CAN transceiver. 15 + 16 + Example: 17 + can0: can@1 { 18 + compatible = "microchip,mcp2515"; 19 + reg = <1>; 20 + clocks = <&clk24m>; 21 + interrupt-parent = <&gpio4>; 22 + interrupts = <13 0x2>; 23 + vdd-supply = <&reg5v0>; 24 + xceiver-supply = <&reg5v0>; 25 + };
+74 -25
drivers/net/can/mcp251x.c
··· 58 58 #include <linux/can/dev.h> 59 59 #include <linux/can/led.h> 60 60 #include <linux/can/platform/mcp251x.h> 61 + #include <linux/clk.h> 61 62 #include <linux/completion.h> 62 63 #include <linux/delay.h> 63 64 #include <linux/device.h> ··· 69 68 #include <linux/kernel.h> 70 69 #include <linux/module.h> 71 70 #include <linux/netdevice.h> 71 + #include <linux/of.h> 72 + #include <linux/of_device.h> 72 73 #include <linux/platform_device.h> 73 74 #include <linux/slab.h> 74 75 #include <linux/spi/spi.h> ··· 266 263 int restart_tx; 267 264 struct regulator *power; 268 265 struct regulator *transceiver; 266 + struct clk *clk; 269 267 }; 270 268 271 269 #define MCP251X_IS(_model) \ ··· 998 994 .ndo_start_xmit = mcp251x_hard_start_xmit, 999 995 }; 1000 996 997 + static const struct of_device_id mcp251x_of_match[] = { 998 + { 999 + .compatible = "microchip,mcp2510", 1000 + .data = (void *)CAN_MCP251X_MCP2510, 1001 + }, 1002 + { 1003 + .compatible = "microchip,mcp2515", 1004 + .data = (void *)CAN_MCP251X_MCP2515, 1005 + }, 1006 + { } 1007 + }; 1008 + MODULE_DEVICE_TABLE(of, mcp251x_of_match); 1009 + 1010 + static const struct spi_device_id mcp251x_id_table[] = { 1011 + { 1012 + .name = "mcp2510", 1013 + .driver_data = (kernel_ulong_t)CAN_MCP251X_MCP2510, 1014 + }, 1015 + { 1016 + .name = "mcp2515", 1017 + .driver_data = (kernel_ulong_t)CAN_MCP251X_MCP2515, 1018 + }, 1019 + { } 1020 + }; 1021 + MODULE_DEVICE_TABLE(spi, mcp251x_id_table); 1022 + 1001 1023 static int mcp251x_can_probe(struct spi_device *spi) 1002 1024 { 1025 + const struct of_device_id *of_id = of_match_device(mcp251x_of_match, 1026 + &spi->dev); 1027 + struct mcp251x_platform_data *pdata = dev_get_platdata(&spi->dev); 1003 1028 struct net_device *net; 1004 1029 struct mcp251x_priv *priv; 1005 - struct mcp251x_platform_data *pdata = dev_get_platdata(&spi->dev); 1006 - int ret = -ENODEV; 1030 + int freq, ret = -ENODEV; 1031 + struct clk *clk; 1007 1032 1008 - if (!pdata) 1009 - /* Platform data is required for osc freq */ 1010 - goto error_out; 1033 + clk = devm_clk_get(&spi->dev, NULL); 1034 + if (IS_ERR(clk)) { 1035 + if (pdata) 1036 + freq = pdata->oscillator_frequency; 1037 + else 1038 + return PTR_ERR(clk); 1039 + } else { 1040 + freq = clk_get_rate(clk); 1041 + } 1042 + 1043 + /* Sanity check */ 1044 + if (freq < 1000000 || freq > 25000000) 1045 + return -ERANGE; 1011 1046 1012 1047 /* Allocate can/net device */ 1013 1048 net = alloc_candev(sizeof(struct mcp251x_priv), TX_ECHO_SKB_MAX); 1014 - if (!net) { 1015 - ret = -ENOMEM; 1016 - goto error_alloc; 1049 + if (!net) 1050 + return -ENOMEM; 1051 + 1052 + if (!IS_ERR(clk)) { 1053 + ret = clk_prepare_enable(clk); 1054 + if (ret) 1055 + goto out_free; 1017 1056 } 1018 1057 1019 1058 net->netdev_ops = &mcp251x_netdev_ops; ··· 1065 1018 priv = netdev_priv(net); 1066 1019 priv->can.bittiming_const = &mcp251x_bittiming_const; 1067 1020 priv->can.do_set_mode = mcp251x_do_set_mode; 1068 - priv->can.clock.freq = pdata->oscillator_frequency / 2; 1021 + priv->can.clock.freq = freq / 2; 1069 1022 priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | 1070 1023 CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY; 1071 - priv->model = spi_get_device_id(spi)->driver_data; 1024 + if (of_id) 1025 + priv->model = (enum mcp251x_model)of_id->data; 1026 + else 1027 + priv->model = spi_get_device_id(spi)->driver_data; 1072 1028 priv->net = net; 1029 + priv->clk = clk; 1073 1030 1074 1031 priv->power = devm_regulator_get(&spi->dev, "vdd"); 1075 1032 priv->transceiver = devm_regulator_get(&spi->dev, "xceiver"); 1076 1033 if ((PTR_ERR(priv->power) == -EPROBE_DEFER) || 1077 1034 (PTR_ERR(priv->transceiver) == -EPROBE_DEFER)) { 1078 1035 ret = -EPROBE_DEFER; 1079 - goto error_power; 1036 + goto out_clk; 1080 1037 } 1081 1038 1082 1039 ret = mcp251x_power_enable(priv->power, 1); 1083 1040 if (ret) 1084 - goto error_power; 1041 + goto out_clk; 1085 1042 1086 1043 spi_set_drvdata(spi, priv); 1087 1044 ··· 1164 1113 dma_free_coherent(&spi->dev, PAGE_SIZE, 1165 1114 priv->spi_tx_buf, priv->spi_tx_dma); 1166 1115 mcp251x_power_enable(priv->power, 0); 1167 - error_power: 1116 + 1117 + out_clk: 1118 + if (!IS_ERR(clk)) 1119 + clk_disable_unprepare(clk); 1120 + 1121 + out_free: 1168 1122 free_candev(net); 1169 - error_alloc: 1170 - dev_err(&spi->dev, "probe failed\n"); 1171 - error_out: 1123 + 1172 1124 return ret; 1173 1125 } 1174 1126 ··· 1188 1134 } 1189 1135 1190 1136 mcp251x_power_enable(priv->power, 0); 1137 + 1138 + if (!IS_ERR(priv->clk)) 1139 + clk_disable_unprepare(priv->clk); 1191 1140 1192 1141 free_candev(net); 1193 1142 ··· 1254 1197 static SIMPLE_DEV_PM_OPS(mcp251x_can_pm_ops, mcp251x_can_suspend, 1255 1198 mcp251x_can_resume); 1256 1199 1257 - static const struct spi_device_id mcp251x_id_table[] = { 1258 - { "mcp2510", CAN_MCP251X_MCP2510 }, 1259 - { "mcp2515", CAN_MCP251X_MCP2515 }, 1260 - { }, 1261 - }; 1262 - 1263 - MODULE_DEVICE_TABLE(spi, mcp251x_id_table); 1264 - 1265 1200 static struct spi_driver mcp251x_can_driver = { 1266 1201 .driver = { 1267 1202 .name = DEVICE_NAME, 1268 1203 .owner = THIS_MODULE, 1204 + .of_match_table = mcp251x_of_match, 1269 1205 .pm = &mcp251x_can_pm_ops, 1270 1206 }, 1271 - 1272 1207 .id_table = mcp251x_id_table, 1273 1208 .probe = mcp251x_can_probe, 1274 1209 .remove = mcp251x_can_remove,