aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Zyngier <maz@misterjones.org>2010-03-29 04:57:56 -0400
committerDavid S. Miller <davem@davemloft.net>2010-03-31 02:51:09 -0400
commite446630c960946b5c1762e4eadb618becef599e7 (patch)
tree7dc73fc57fd1d38f309b208b6dadfddf248cb05f
parent598ed9367a36ee1fd4ae3271a54a3547a33975a5 (diff)
Add hotplug support to mcp251x driver
Chip model can now be selected directly by matching the modalias name (instead of filling the .model field in platform_data), and allows the module to be auto-loaded. Previous behaviour is of course still supported. Convert the two in-tree users to this feature (icontrol & zeus). Tested on an Zeus platform (mcp2515). Signed-off-by: Marc Zyngier <maz@misterjones.org> Acked-by: Christian Pellegrin <chripell@fsfe.org> Cc: Edwin Peer <epeer@tmtservices.co.za> Acked-by: Wolfgang Grandegger <wg@grandegger.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/arm/mach-pxa/icontrol.c9
-rw-r--r--arch/arm/mach-pxa/zeus.c4
-rw-r--r--drivers/net/can/mcp251x.c14
-rw-r--r--include/linux/can/platform/mcp251x.h4
4 files changed, 21 insertions, 10 deletions
diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c
index 771137fc1a82..5ccb0ceff6c4 100644
--- a/arch/arm/mach-pxa/icontrol.c
+++ b/arch/arm/mach-pxa/icontrol.c
@@ -73,7 +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 .model = CAN_MCP251X_MCP2515,
77 .board_specific_setup = NULL, 76 .board_specific_setup = NULL,
78 .power_enable = NULL, 77 .power_enable = NULL,
79 .transceiver_enable = NULL 78 .transceiver_enable = NULL
@@ -81,7 +80,7 @@ static struct mcp251x_platform_data mcp251x_info = {
81 80
82static struct spi_board_info mcp251x_board_info[] = { 81static struct spi_board_info mcp251x_board_info[] = {
83 { 82 {
84 .modalias = "mcp251x", 83 .modalias = "mcp2515",
85 .max_speed_hz = 6500000, 84 .max_speed_hz = 6500000,
86 .bus_num = 3, 85 .bus_num = 3,
87 .chip_select = 0, 86 .chip_select = 0,
@@ -90,7 +89,7 @@ static struct spi_board_info mcp251x_board_info[] = {
90 .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ1) 89 .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ1)
91 }, 90 },
92 { 91 {
93 .modalias = "mcp251x", 92 .modalias = "mcp2515",
94 .max_speed_hz = 6500000, 93 .max_speed_hz = 6500000,
95 .bus_num = 3, 94 .bus_num = 3,
96 .chip_select = 1, 95 .chip_select = 1,
@@ -99,7 +98,7 @@ static struct spi_board_info mcp251x_board_info[] = {
99 .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ2) 98 .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ2)
100 }, 99 },
101 { 100 {
102 .modalias = "mcp251x", 101 .modalias = "mcp2515",
103 .max_speed_hz = 6500000, 102 .max_speed_hz = 6500000,
104 .bus_num = 4, 103 .bus_num = 4,
105 .chip_select = 0, 104 .chip_select = 0,
@@ -108,7 +107,7 @@ static struct spi_board_info mcp251x_board_info[] = {
108 .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ3) 107 .irq = gpio_to_irq(ICONTROL_MCP251x_nIRQ3)
109 }, 108 },
110 { 109 {
111 .modalias = "mcp251x", 110 .modalias = "mcp2515",
112 .max_speed_hz = 6500000, 111 .max_speed_hz = 6500000,
113 .bus_num = 4, 112 .bus_num = 4,
114 .chip_select = 1, 113 .chip_select = 1,
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c
index 39896d883584..dbd256966379 100644
--- a/arch/arm/mach-pxa/zeus.c
+++ b/arch/arm/mach-pxa/zeus.c
@@ -414,15 +414,13 @@ static int zeus_mcp2515_transceiver_enable(int enable)
414 414
415static struct mcp251x_platform_data zeus_mcp2515_pdata = { 415static struct mcp251x_platform_data zeus_mcp2515_pdata = {
416 .oscillator_frequency = 16*1000*1000, 416 .oscillator_frequency = 16*1000*1000,
417 .model = CAN_MCP251X_MCP2515,
418 .board_specific_setup = zeus_mcp2515_setup, 417 .board_specific_setup = zeus_mcp2515_setup,
419 .transceiver_enable = zeus_mcp2515_transceiver_enable,
420 .power_enable = zeus_mcp2515_transceiver_enable, 418 .power_enable = zeus_mcp2515_transceiver_enable,
421}; 419};
422 420
423static struct spi_board_info zeus_spi_board_info[] = { 421static struct spi_board_info zeus_spi_board_info[] = {
424 [0] = { 422 [0] = {
425 .modalias = "mcp251x", 423 .modalias = "mcp2515",
426 .platform_data = &zeus_mcp2515_pdata, 424 .platform_data = &zeus_mcp2515_pdata,
427 .irq = gpio_to_irq(ZEUS_CAN_GPIO), 425 .irq = gpio_to_irq(ZEUS_CAN_GPIO),
428 .max_speed_hz = 1*1000*1000, 426 .max_speed_hz = 1*1000*1000,
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c
index f8cc168ec76c..f521579f5adb 100644
--- a/drivers/net/can/mcp251x.c
+++ b/drivers/net/can/mcp251x.c
@@ -922,12 +922,16 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi)
922 struct net_device *net; 922 struct net_device *net;
923 struct mcp251x_priv *priv; 923 struct mcp251x_priv *priv;
924 struct mcp251x_platform_data *pdata = spi->dev.platform_data; 924 struct mcp251x_platform_data *pdata = spi->dev.platform_data;
925 int model = spi_get_device_id(spi)->driver_data;
925 int ret = -ENODEV; 926 int ret = -ENODEV;
926 927
927 if (!pdata) 928 if (!pdata)
928 /* Platform data is required for osc freq */ 929 /* Platform data is required for osc freq */
929 goto error_out; 930 goto error_out;
930 931
932 if (model)
933 pdata->model = model;
934
931 /* Allocate can/net device */ 935 /* Allocate can/net device */
932 net = alloc_candev(sizeof(struct mcp251x_priv), TX_ECHO_SKB_MAX); 936 net = alloc_candev(sizeof(struct mcp251x_priv), TX_ECHO_SKB_MAX);
933 if (!net) { 937 if (!net) {
@@ -1117,6 +1121,15 @@ static int mcp251x_can_resume(struct spi_device *spi)
1117#define mcp251x_can_resume NULL 1121#define mcp251x_can_resume NULL
1118#endif 1122#endif
1119 1123
1124static struct spi_device_id mcp251x_id_table[] = {
1125 { "mcp251x", 0 /* Use pdata.model */ },
1126 { "mcp2510", CAN_MCP251X_MCP2510 },
1127 { "mcp2515", CAN_MCP251X_MCP2515 },
1128 { },
1129};
1130
1131MODULE_DEVICE_TABLE(spi, mcp251x_id_table);
1132
1120static struct spi_driver mcp251x_can_driver = { 1133static struct spi_driver mcp251x_can_driver = {
1121 .driver = { 1134 .driver = {
1122 .name = DEVICE_NAME, 1135 .name = DEVICE_NAME,
@@ -1124,6 +1137,7 @@ static struct spi_driver mcp251x_can_driver = {
1124 .owner = THIS_MODULE, 1137 .owner = THIS_MODULE,
1125 }, 1138 },
1126 1139
1140 .id_table = mcp251x_id_table,
1127 .probe = mcp251x_can_probe, 1141 .probe = mcp251x_can_probe,
1128 .remove = __devexit_p(mcp251x_can_remove), 1142 .remove = __devexit_p(mcp251x_can_remove),
1129 .suspend = mcp251x_can_suspend, 1143 .suspend = mcp251x_can_suspend,
diff --git a/include/linux/can/platform/mcp251x.h b/include/linux/can/platform/mcp251x.h
index 1448177d86d5..dba28268e651 100644
--- a/include/linux/can/platform/mcp251x.h
+++ b/include/linux/can/platform/mcp251x.h
@@ -26,8 +26,8 @@
26struct mcp251x_platform_data { 26struct mcp251x_platform_data {
27 unsigned long oscillator_frequency; 27 unsigned long oscillator_frequency;
28 int model; 28 int model;
29#define CAN_MCP251X_MCP2510 0 29#define CAN_MCP251X_MCP2510 0x2510
30#define CAN_MCP251X_MCP2515 1 30#define CAN_MCP251X_MCP2515 0x2515
31 int (*board_specific_setup)(struct spi_device *spi); 31 int (*board_specific_setup)(struct spi_device *spi);
32 int (*transceiver_enable)(int enable); 32 int (*transceiver_enable)(int enable);
33 int (*power_enable) (int enable); 33 int (*power_enable) (int enable);