aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Shiyan <shc_work@mail.ru>2013-08-19 07:39:19 -0400
committerMarc Kleine-Budde <mkl@pengutronix.de>2013-08-21 03:28:29 -0400
commit1ddff7da0faecffdcdeab3d981fb8241453cea44 (patch)
tree7388e85b2a844917fe3103c47bdb044799fba95f
parent954c396756e3d31985f7bc6a414a988a4736a7d0 (diff)
can: mcp251x: Replace power callbacks with regulator API
This patch replaces power callbacks to the regulator API. To improve the readability of the code, helper for the regulator enable/disable was added. Acked-by: Haojian Zhuang <haojian.zhuang@gmail.com> Signed-off-by: Alexander Shiyan <shc_work@mail.ru> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
-rw-r--r--arch/arm/mach-pxa/icontrol.c3
-rw-r--r--arch/arm/mach-pxa/zeus.c46
-rw-r--r--drivers/net/can/mcp251x.c83
-rw-r--r--include/linux/can/platform/mcp251x.h13
4 files changed, 69 insertions, 76 deletions
diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c
index fe31bfcbb8df..c98511c5abd1 100644
--- a/arch/arm/mach-pxa/icontrol.c
+++ b/arch/arm/mach-pxa/icontrol.c
@@ -73,9 +73,6 @@ static struct pxa2xx_spi_chip mcp251x_chip_info4 = {
73 73
74static struct mcp251x_platform_data mcp251x_info = { 74static struct mcp251x_platform_data mcp251x_info = {
75 .oscillator_frequency = 16E6, 75 .oscillator_frequency = 16E6,
76 .board_specific_setup = NULL,
77 .power_enable = NULL,
78 .transceiver_enable = NULL
79}; 76};
80 77
81static struct spi_board_info mcp251x_board_info[] = { 78static struct spi_board_info mcp251x_board_info[] = {
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c
index f5d436434566..04a0aea23873 100644
--- a/arch/arm/mach-pxa/zeus.c
+++ b/arch/arm/mach-pxa/zeus.c
@@ -29,6 +29,8 @@
29#include <linux/i2c/pca953x.h> 29#include <linux/i2c/pca953x.h>
30#include <linux/apm-emulation.h> 30#include <linux/apm-emulation.h>
31#include <linux/can/platform/mcp251x.h> 31#include <linux/can/platform/mcp251x.h>
32#include <linux/regulator/fixed.h>
33#include <linux/regulator/machine.h>
32 34
33#include <asm/mach-types.h> 35#include <asm/mach-types.h>
34#include <asm/suspend.h> 36#include <asm/suspend.h>
@@ -391,33 +393,34 @@ static struct pxa2xx_spi_master pxa2xx_spi_ssp3_master_info = {
391}; 393};
392 394
393/* CAN bus on SPI */ 395/* CAN bus on SPI */
394static int zeus_mcp2515_setup(struct spi_device *sdev) 396static struct regulator_consumer_supply can_regulator_consumer =
395{ 397 REGULATOR_SUPPLY("vdd", "spi3.0");
396 int err;
397
398 err = gpio_request(ZEUS_CAN_SHDN_GPIO, "CAN shutdown");
399 if (err)
400 return err;
401 398
402 err = gpio_direction_output(ZEUS_CAN_SHDN_GPIO, 1); 399static struct regulator_init_data can_regulator_init_data = {
403 if (err) { 400 .constraints = {
404 gpio_free(ZEUS_CAN_SHDN_GPIO); 401 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
405 return err; 402 },
406 } 403 .consumer_supplies = &can_regulator_consumer,
404 .num_consumer_supplies = 1,
405};
407 406
408 return 0; 407static struct fixed_voltage_config can_regulator_pdata = {
409} 408 .supply_name = "CAN_SHDN",
409 .microvolts = 3300000,
410 .gpio = ZEUS_CAN_SHDN_GPIO,
411 .init_data = &can_regulator_init_data,
412};
410 413
411static int zeus_mcp2515_transceiver_enable(int enable) 414static struct platform_device can_regulator_device = {
412{ 415 .name = "reg-fixed-volage",
413 gpio_set_value(ZEUS_CAN_SHDN_GPIO, !enable); 416 .id = -1,
414 return 0; 417 .dev = {
415} 418 .platform_data = &can_regulator_pdata,
419 },
420};
416 421
417static struct mcp251x_platform_data zeus_mcp2515_pdata = { 422static struct mcp251x_platform_data zeus_mcp2515_pdata = {
418 .oscillator_frequency = 16*1000*1000, 423 .oscillator_frequency = 16*1000*1000,
419 .board_specific_setup = zeus_mcp2515_setup,
420 .power_enable = zeus_mcp2515_transceiver_enable,
421}; 424};
422 425
423static struct spi_board_info zeus_spi_board_info[] = { 426static struct spi_board_info zeus_spi_board_info[] = {
@@ -516,6 +519,7 @@ static struct platform_device *zeus_devices[] __initdata = {
516 &zeus_leds_device, 519 &zeus_leds_device,
517 &zeus_pcmcia_device, 520 &zeus_pcmcia_device,
518 &zeus_max6369_device, 521 &zeus_max6369_device,
522 &can_regulator_device,
519}; 523};
520 524
521/* AC'97 */ 525/* AC'97 */
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c
index 8cda23bf0614..d2c54888b211 100644
--- a/drivers/net/can/mcp251x.c
+++ b/drivers/net/can/mcp251x.c
@@ -37,9 +37,6 @@
37 * 37 *
38 * static struct mcp251x_platform_data mcp251x_info = { 38 * static struct mcp251x_platform_data mcp251x_info = {
39 * .oscillator_frequency = 8000000, 39 * .oscillator_frequency = 8000000,
40 * .board_specific_setup = &mcp251x_setup,
41 * .power_enable = mcp251x_power_enable,
42 * .transceiver_enable = NULL,
43 * }; 40 * };
44 * 41 *
45 * static struct spi_board_info spi_board_info[] = { 42 * static struct spi_board_info spi_board_info[] = {
@@ -76,6 +73,7 @@
76#include <linux/slab.h> 73#include <linux/slab.h>
77#include <linux/spi/spi.h> 74#include <linux/spi/spi.h>
78#include <linux/uaccess.h> 75#include <linux/uaccess.h>
76#include <linux/regulator/consumer.h>
79 77
80/* SPI interface instruction set */ 78/* SPI interface instruction set */
81#define INSTRUCTION_WRITE 0x02 79#define INSTRUCTION_WRITE 0x02
@@ -264,6 +262,8 @@ struct mcp251x_priv {
264#define AFTER_SUSPEND_POWER 4 262#define AFTER_SUSPEND_POWER 4
265#define AFTER_SUSPEND_RESTART 8 263#define AFTER_SUSPEND_RESTART 8
266 int restart_tx; 264 int restart_tx;
265 struct regulator *power;
266 struct regulator *transceiver;
267}; 267};
268 268
269#define MCP251X_IS(_model) \ 269#define MCP251X_IS(_model) \
@@ -667,16 +667,25 @@ static int mcp251x_hw_probe(struct spi_device *spi)
667 return (st1 == 0x80 && st2 == 0x07) ? 1 : 0; 667 return (st1 == 0x80 && st2 == 0x07) ? 1 : 0;
668} 668}
669 669
670static int mcp251x_power_enable(struct regulator *reg, int enable)
671{
672 if (IS_ERR(reg))
673 return 0;
674
675 if (enable)
676 return regulator_enable(reg);
677 else
678 return regulator_disable(reg);
679}
680
670static void mcp251x_open_clean(struct net_device *net) 681static void mcp251x_open_clean(struct net_device *net)
671{ 682{
672 struct mcp251x_priv *priv = netdev_priv(net); 683 struct mcp251x_priv *priv = netdev_priv(net);
673 struct spi_device *spi = priv->spi; 684 struct spi_device *spi = priv->spi;
674 struct mcp251x_platform_data *pdata = spi->dev.platform_data;
675 685
676 free_irq(spi->irq, priv); 686 free_irq(spi->irq, priv);
677 mcp251x_hw_sleep(spi); 687 mcp251x_hw_sleep(spi);
678 if (pdata->transceiver_enable) 688 mcp251x_power_enable(priv->transceiver, 0);
679 pdata->transceiver_enable(0);
680 close_candev(net); 689 close_candev(net);
681} 690}
682 691
@@ -684,7 +693,6 @@ static int mcp251x_stop(struct net_device *net)
684{ 693{
685 struct mcp251x_priv *priv = netdev_priv(net); 694 struct mcp251x_priv *priv = netdev_priv(net);
686 struct spi_device *spi = priv->spi; 695 struct spi_device *spi = priv->spi;
687 struct mcp251x_platform_data *pdata = spi->dev.platform_data;
688 696
689 close_candev(net); 697 close_candev(net);
690 698
@@ -704,8 +712,7 @@ static int mcp251x_stop(struct net_device *net)
704 712
705 mcp251x_hw_sleep(spi); 713 mcp251x_hw_sleep(spi);
706 714
707 if (pdata->transceiver_enable) 715 mcp251x_power_enable(priv->transceiver, 0);
708 pdata->transceiver_enable(0);
709 716
710 priv->can.state = CAN_STATE_STOPPED; 717 priv->can.state = CAN_STATE_STOPPED;
711 718
@@ -939,8 +946,7 @@ static int mcp251x_open(struct net_device *net)
939 } 946 }
940 947
941 mutex_lock(&priv->mcp_lock); 948 mutex_lock(&priv->mcp_lock);
942 if (pdata->transceiver_enable) 949 mcp251x_power_enable(priv->transceiver, 1);
943 pdata->transceiver_enable(1);
944 950
945 priv->force_quit = 0; 951 priv->force_quit = 0;
946 priv->tx_skb = NULL; 952 priv->tx_skb = NULL;
@@ -956,8 +962,7 @@ static int mcp251x_open(struct net_device *net)
956 flags, DEVICE_NAME, priv); 962 flags, DEVICE_NAME, priv);
957 if (ret) { 963 if (ret) {
958 dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq); 964 dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);
959 if (pdata->transceiver_enable) 965 mcp251x_power_enable(priv->transceiver, 0);
960 pdata->transceiver_enable(0);
961 close_candev(net); 966 close_candev(net);
962 goto open_unlock; 967 goto open_unlock;
963 } 968 }
@@ -1026,6 +1031,19 @@ static int mcp251x_can_probe(struct spi_device *spi)
1026 CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY; 1031 CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY;
1027 priv->model = spi_get_device_id(spi)->driver_data; 1032 priv->model = spi_get_device_id(spi)->driver_data;
1028 priv->net = net; 1033 priv->net = net;
1034
1035 priv->power = devm_regulator_get(&spi->dev, "vdd");
1036 priv->transceiver = devm_regulator_get(&spi->dev, "xceiver");
1037 if ((PTR_ERR(priv->power) == -EPROBE_DEFER) ||
1038 (PTR_ERR(priv->transceiver) == -EPROBE_DEFER)) {
1039 ret = -EPROBE_DEFER;
1040 goto error_power;
1041 }
1042
1043 ret = mcp251x_power_enable(priv->power, 1);
1044 if (ret)
1045 goto error_power;
1046
1029 spi_set_drvdata(spi, priv); 1047 spi_set_drvdata(spi, priv);
1030 1048
1031 priv->spi = spi; 1049 priv->spi = spi;
@@ -1068,13 +1086,6 @@ static int mcp251x_can_probe(struct spi_device *spi)
1068 } 1086 }
1069 } 1087 }
1070 1088
1071 if (pdata->power_enable)
1072 pdata->power_enable(1);
1073
1074 /* Call out to platform specific setup */
1075 if (pdata->board_specific_setup)
1076 pdata->board_specific_setup(spi);
1077
1078 SET_NETDEV_DEV(net, &spi->dev); 1089 SET_NETDEV_DEV(net, &spi->dev);
1079 1090
1080 /* Configure the SPI bus */ 1091 /* Configure the SPI bus */
@@ -1084,14 +1095,11 @@ static int mcp251x_can_probe(struct spi_device *spi)
1084 1095
1085 /* Here is OK to not lock the MCP, no one knows about it yet */ 1096 /* Here is OK to not lock the MCP, no one knows about it yet */
1086 if (!mcp251x_hw_probe(spi)) { 1097 if (!mcp251x_hw_probe(spi)) {
1087 dev_info(&spi->dev, "Probe failed\n"); 1098 ret = -ENODEV;
1088 goto error_probe; 1099 goto error_probe;
1089 } 1100 }
1090 mcp251x_hw_sleep(spi); 1101 mcp251x_hw_sleep(spi);
1091 1102
1092 if (pdata->transceiver_enable)
1093 pdata->transceiver_enable(0);
1094
1095 ret = register_candev(net); 1103 ret = register_candev(net);
1096 if (ret) 1104 if (ret)
1097 goto error_probe; 1105 goto error_probe;
@@ -1109,13 +1117,13 @@ error_rx_buf:
1109 if (!mcp251x_enable_dma) 1117 if (!mcp251x_enable_dma)
1110 kfree(priv->spi_tx_buf); 1118 kfree(priv->spi_tx_buf);
1111error_tx_buf: 1119error_tx_buf:
1112 free_candev(net);
1113 if (mcp251x_enable_dma) 1120 if (mcp251x_enable_dma)
1114 dma_free_coherent(&spi->dev, PAGE_SIZE, 1121 dma_free_coherent(&spi->dev, PAGE_SIZE,
1115 priv->spi_tx_buf, priv->spi_tx_dma); 1122 priv->spi_tx_buf, priv->spi_tx_dma);
1123 mcp251x_power_enable(priv->power, 0);
1124error_power:
1125 free_candev(net);
1116error_alloc: 1126error_alloc:
1117 if (pdata->power_enable)
1118 pdata->power_enable(0);
1119 dev_err(&spi->dev, "probe failed\n"); 1127 dev_err(&spi->dev, "probe failed\n");
1120error_out: 1128error_out:
1121 return ret; 1129 return ret;
@@ -1123,12 +1131,10 @@ error_out:
1123 1131
1124static int mcp251x_can_remove(struct spi_device *spi) 1132static int mcp251x_can_remove(struct spi_device *spi)
1125{ 1133{
1126 struct mcp251x_platform_data *pdata = spi->dev.platform_data;
1127 struct mcp251x_priv *priv = spi_get_drvdata(spi); 1134 struct mcp251x_priv *priv = spi_get_drvdata(spi);
1128 struct net_device *net = priv->net; 1135 struct net_device *net = priv->net;
1129 1136
1130 unregister_candev(net); 1137 unregister_candev(net);
1131 free_candev(net);
1132 1138
1133 if (mcp251x_enable_dma) { 1139 if (mcp251x_enable_dma) {
1134 dma_free_coherent(&spi->dev, PAGE_SIZE, 1140 dma_free_coherent(&spi->dev, PAGE_SIZE,
@@ -1138,8 +1144,9 @@ static int mcp251x_can_remove(struct spi_device *spi)
1138 kfree(priv->spi_rx_buf); 1144 kfree(priv->spi_rx_buf);
1139 } 1145 }
1140 1146
1141 if (pdata->power_enable) 1147 mcp251x_power_enable(priv->power, 0);
1142 pdata->power_enable(0); 1148
1149 free_candev(net);
1143 1150
1144 return 0; 1151 return 0;
1145} 1152}
@@ -1149,7 +1156,6 @@ static int mcp251x_can_remove(struct spi_device *spi)
1149static int mcp251x_can_suspend(struct device *dev) 1156static int mcp251x_can_suspend(struct device *dev)
1150{ 1157{
1151 struct spi_device *spi = to_spi_device(dev); 1158 struct spi_device *spi = to_spi_device(dev);
1152 struct mcp251x_platform_data *pdata = spi->dev.platform_data;
1153 struct mcp251x_priv *priv = spi_get_drvdata(spi); 1159 struct mcp251x_priv *priv = spi_get_drvdata(spi);
1154 struct net_device *net = priv->net; 1160 struct net_device *net = priv->net;
1155 1161
@@ -1163,15 +1169,14 @@ static int mcp251x_can_suspend(struct device *dev)
1163 netif_device_detach(net); 1169 netif_device_detach(net);
1164 1170
1165 mcp251x_hw_sleep(spi); 1171 mcp251x_hw_sleep(spi);
1166 if (pdata->transceiver_enable) 1172 mcp251x_power_enable(priv->transceiver, 0);
1167 pdata->transceiver_enable(0);
1168 priv->after_suspend = AFTER_SUSPEND_UP; 1173 priv->after_suspend = AFTER_SUSPEND_UP;
1169 } else { 1174 } else {
1170 priv->after_suspend = AFTER_SUSPEND_DOWN; 1175 priv->after_suspend = AFTER_SUSPEND_DOWN;
1171 } 1176 }
1172 1177
1173 if (pdata->power_enable) { 1178 if (!IS_ERR(priv->power)) {
1174 pdata->power_enable(0); 1179 regulator_disable(priv->power);
1175 priv->after_suspend |= AFTER_SUSPEND_POWER; 1180 priv->after_suspend |= AFTER_SUSPEND_POWER;
1176 } 1181 }
1177 1182
@@ -1181,16 +1186,14 @@ static int mcp251x_can_suspend(struct device *dev)
1181static int mcp251x_can_resume(struct device *dev) 1186static int mcp251x_can_resume(struct device *dev)
1182{ 1187{
1183 struct spi_device *spi = to_spi_device(dev); 1188 struct spi_device *spi = to_spi_device(dev);
1184 struct mcp251x_platform_data *pdata = spi->dev.platform_data;
1185 struct mcp251x_priv *priv = spi_get_drvdata(spi); 1189 struct mcp251x_priv *priv = spi_get_drvdata(spi);
1186 1190
1187 if (priv->after_suspend & AFTER_SUSPEND_POWER) { 1191 if (priv->after_suspend & AFTER_SUSPEND_POWER) {
1188 pdata->power_enable(1); 1192 mcp251x_power_enable(priv->power, 1);
1189 queue_work(priv->wq, &priv->restart_work); 1193 queue_work(priv->wq, &priv->restart_work);
1190 } else { 1194 } else {
1191 if (priv->after_suspend & AFTER_SUSPEND_UP) { 1195 if (priv->after_suspend & AFTER_SUSPEND_UP) {
1192 if (pdata->transceiver_enable) 1196 mcp251x_power_enable(priv->transceiver, 1);
1193 pdata->transceiver_enable(1);
1194 queue_work(priv->wq, &priv->restart_work); 1197 queue_work(priv->wq, &priv->restart_work);
1195 } else { 1198 } else {
1196 priv->after_suspend = 0; 1199 priv->after_suspend = 0;
diff --git a/include/linux/can/platform/mcp251x.h b/include/linux/can/platform/mcp251x.h
index 089fe43211a4..8a2725676d8b 100644
--- a/include/linux/can/platform/mcp251x.h
+++ b/include/linux/can/platform/mcp251x.h
@@ -9,26 +9,15 @@
9 9
10#include <linux/spi/spi.h> 10#include <linux/spi/spi.h>
11 11
12/** 12/*
13 * struct mcp251x_platform_data - MCP251X SPI CAN controller platform data 13 * struct mcp251x_platform_data - MCP251X SPI CAN controller platform data
14 * @oscillator_frequency: - oscillator frequency in Hz 14 * @oscillator_frequency: - oscillator frequency in Hz
15 * @irq_flags: - IRQF configuration flags 15 * @irq_flags: - IRQF configuration flags
16 * @board_specific_setup: - called before probing the chip (power,reset)
17 * @transceiver_enable: - called to power on/off the transceiver
18 * @power_enable: - called to power on/off the mcp *and* the
19 * transceiver
20 *
21 * Please note that you should define power_enable or transceiver_enable or
22 * none of them. Defining both of them is no use.
23 *
24 */ 16 */
25 17
26struct mcp251x_platform_data { 18struct mcp251x_platform_data {
27 unsigned long oscillator_frequency; 19 unsigned long oscillator_frequency;
28 unsigned long irq_flags; 20 unsigned long irq_flags;
29 int (*board_specific_setup)(struct spi_device *spi);
30 int (*transceiver_enable)(int enable);
31 int (*power_enable) (int enable);
32}; 21};
33 22
34#endif /* __CAN_PLATFORM_MCP251X_H__ */ 23#endif /* __CAN_PLATFORM_MCP251X_H__ */