diff options
Diffstat (limited to 'drivers/net/can/sja1000/plx_pci.c')
-rw-r--r-- | drivers/net/can/sja1000/plx_pci.c | 154 |
1 files changed, 142 insertions, 12 deletions
diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c index 4aff4070db96..437b5c716a24 100644 --- a/drivers/net/can/sja1000/plx_pci.c +++ b/drivers/net/can/sja1000/plx_pci.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
30 | #include <linux/can.h> | ||
31 | #include <linux/can/dev.h> | 30 | #include <linux/can/dev.h> |
32 | #include <linux/io.h> | 31 | #include <linux/io.h> |
33 | 32 | ||
@@ -41,7 +40,10 @@ MODULE_DESCRIPTION("Socket-CAN driver for PLX90xx PCI-bridge cards with " | |||
41 | MODULE_SUPPORTED_DEVICE("Adlink PCI-7841/cPCI-7841, " | 40 | MODULE_SUPPORTED_DEVICE("Adlink PCI-7841/cPCI-7841, " |
42 | "Adlink PCI-7841/cPCI-7841 SE, " | 41 | "Adlink PCI-7841/cPCI-7841 SE, " |
43 | "Marathon CAN-bus-PCI, " | 42 | "Marathon CAN-bus-PCI, " |
44 | "TEWS TECHNOLOGIES TPMC810"); | 43 | "TEWS TECHNOLOGIES TPMC810, " |
44 | "esd CAN-PCI/CPCI/PCI104/200, " | ||
45 | "esd CAN-PCI/PMC/266, " | ||
46 | "esd CAN-PCIe/2000") | ||
45 | MODULE_LICENSE("GPL v2"); | 47 | MODULE_LICENSE("GPL v2"); |
46 | 48 | ||
47 | #define PLX_PCI_MAX_CHAN 2 | 49 | #define PLX_PCI_MAX_CHAN 2 |
@@ -50,11 +52,14 @@ struct plx_pci_card { | |||
50 | int channels; /* detected channels count */ | 52 | int channels; /* detected channels count */ |
51 | struct net_device *net_dev[PLX_PCI_MAX_CHAN]; | 53 | struct net_device *net_dev[PLX_PCI_MAX_CHAN]; |
52 | void __iomem *conf_addr; | 54 | void __iomem *conf_addr; |
55 | |||
56 | /* Pointer to device-dependent reset function */ | ||
57 | void (*reset_func)(struct pci_dev *pdev); | ||
53 | }; | 58 | }; |
54 | 59 | ||
55 | #define PLX_PCI_CAN_CLOCK (16000000 / 2) | 60 | #define PLX_PCI_CAN_CLOCK (16000000 / 2) |
56 | 61 | ||
57 | /* PLX90xx registers */ | 62 | /* PLX9030/9050/9052 registers */ |
58 | #define PLX_INTCSR 0x4c /* Interrupt Control/Status */ | 63 | #define PLX_INTCSR 0x4c /* Interrupt Control/Status */ |
59 | #define PLX_CNTRL 0x50 /* User I/O, Direct Slave Response, | 64 | #define PLX_CNTRL 0x50 /* User I/O, Direct Slave Response, |
60 | * Serial EEPROM, and Initialization | 65 | * Serial EEPROM, and Initialization |
@@ -66,6 +71,14 @@ struct plx_pci_card { | |||
66 | #define PLX_PCI_INT_EN (1 << 6) /* PCI Interrupt Enable */ | 71 | #define PLX_PCI_INT_EN (1 << 6) /* PCI Interrupt Enable */ |
67 | #define PLX_PCI_RESET (1 << 30) /* PCI Adapter Software Reset */ | 72 | #define PLX_PCI_RESET (1 << 30) /* PCI Adapter Software Reset */ |
68 | 73 | ||
74 | /* PLX9056 registers */ | ||
75 | #define PLX9056_INTCSR 0x68 /* Interrupt Control/Status */ | ||
76 | #define PLX9056_CNTRL 0x6c /* Control / Software Reset */ | ||
77 | |||
78 | #define PLX9056_LINTI (1 << 11) | ||
79 | #define PLX9056_PCI_INT_EN (1 << 8) | ||
80 | #define PLX9056_PCI_RCR (1 << 29) /* Read Configuration Registers */ | ||
81 | |||
69 | /* | 82 | /* |
70 | * The board configuration is probably following: | 83 | * The board configuration is probably following: |
71 | * RX1 is connected to ground. | 84 | * RX1 is connected to ground. |
@@ -101,6 +114,13 @@ struct plx_pci_card { | |||
101 | #define ADLINK_PCI_VENDOR_ID 0x144A | 114 | #define ADLINK_PCI_VENDOR_ID 0x144A |
102 | #define ADLINK_PCI_DEVICE_ID 0x7841 | 115 | #define ADLINK_PCI_DEVICE_ID 0x7841 |
103 | 116 | ||
117 | #define ESD_PCI_SUB_SYS_ID_PCI200 0x0004 | ||
118 | #define ESD_PCI_SUB_SYS_ID_PCI266 0x0009 | ||
119 | #define ESD_PCI_SUB_SYS_ID_PMC266 0x000e | ||
120 | #define ESD_PCI_SUB_SYS_ID_CPCI200 0x010b | ||
121 | #define ESD_PCI_SUB_SYS_ID_PCIE2000 0x0200 | ||
122 | #define ESD_PCI_SUB_SYS_ID_PCI104200 0x0501 | ||
123 | |||
104 | #define MARATHON_PCI_DEVICE_ID 0x2715 | 124 | #define MARATHON_PCI_DEVICE_ID 0x2715 |
105 | 125 | ||
106 | #define TEWS_PCI_VENDOR_ID 0x1498 | 126 | #define TEWS_PCI_VENDOR_ID 0x1498 |
@@ -108,6 +128,7 @@ struct plx_pci_card { | |||
108 | 128 | ||
109 | static void plx_pci_reset_common(struct pci_dev *pdev); | 129 | static void plx_pci_reset_common(struct pci_dev *pdev); |
110 | static void plx_pci_reset_marathon(struct pci_dev *pdev); | 130 | static void plx_pci_reset_marathon(struct pci_dev *pdev); |
131 | static void plx9056_pci_reset_common(struct pci_dev *pdev); | ||
111 | 132 | ||
112 | struct plx_pci_channel_map { | 133 | struct plx_pci_channel_map { |
113 | u32 bar; | 134 | u32 bar; |
@@ -148,6 +169,30 @@ static struct plx_pci_card_info plx_pci_card_info_adlink_se __devinitdata = { | |||
148 | /* based on PLX9052 */ | 169 | /* based on PLX9052 */ |
149 | }; | 170 | }; |
150 | 171 | ||
172 | static struct plx_pci_card_info plx_pci_card_info_esd200 __devinitdata = { | ||
173 | "esd CAN-PCI/CPCI/PCI104/200", 2, | ||
174 | PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR, | ||
175 | {0, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x100, 0x80} }, | ||
176 | &plx_pci_reset_common | ||
177 | /* based on PLX9030/9050 */ | ||
178 | }; | ||
179 | |||
180 | static struct plx_pci_card_info plx_pci_card_info_esd266 __devinitdata = { | ||
181 | "esd CAN-PCI/PMC/266", 2, | ||
182 | PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR, | ||
183 | {0, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x100, 0x80} }, | ||
184 | &plx9056_pci_reset_common | ||
185 | /* based on PLX9056 */ | ||
186 | }; | ||
187 | |||
188 | static struct plx_pci_card_info plx_pci_card_info_esd2000 __devinitdata = { | ||
189 | "esd CAN-PCIe/2000", 2, | ||
190 | PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR, | ||
191 | {0, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x100, 0x80} }, | ||
192 | &plx9056_pci_reset_common | ||
193 | /* based on PEX8311 */ | ||
194 | }; | ||
195 | |||
151 | static struct plx_pci_card_info plx_pci_card_info_marathon __devinitdata = { | 196 | static struct plx_pci_card_info plx_pci_card_info_marathon __devinitdata = { |
152 | "Marathon CAN-bus-PCI", 2, | 197 | "Marathon CAN-bus-PCI", 2, |
153 | PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR, | 198 | PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR, |
@@ -180,6 +225,48 @@ static DEFINE_PCI_DEVICE_TABLE(plx_pci_tbl) = { | |||
180 | (kernel_ulong_t)&plx_pci_card_info_adlink_se | 225 | (kernel_ulong_t)&plx_pci_card_info_adlink_se |
181 | }, | 226 | }, |
182 | { | 227 | { |
228 | /* esd CAN-PCI/200 */ | ||
229 | PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, | ||
230 | PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_PCI200, | ||
231 | 0, 0, | ||
232 | (kernel_ulong_t)&plx_pci_card_info_esd200 | ||
233 | }, | ||
234 | { | ||
235 | /* esd CAN-CPCI/200 */ | ||
236 | PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, | ||
237 | PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_CPCI200, | ||
238 | 0, 0, | ||
239 | (kernel_ulong_t)&plx_pci_card_info_esd200 | ||
240 | }, | ||
241 | { | ||
242 | /* esd CAN-PCI104/200 */ | ||
243 | PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, | ||
244 | PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_PCI104200, | ||
245 | 0, 0, | ||
246 | (kernel_ulong_t)&plx_pci_card_info_esd200 | ||
247 | }, | ||
248 | { | ||
249 | /* esd CAN-PCI/266 */ | ||
250 | PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9056, | ||
251 | PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_PCI266, | ||
252 | 0, 0, | ||
253 | (kernel_ulong_t)&plx_pci_card_info_esd266 | ||
254 | }, | ||
255 | { | ||
256 | /* esd CAN-PMC/266 */ | ||
257 | PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9056, | ||
258 | PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_PMC266, | ||
259 | 0, 0, | ||
260 | (kernel_ulong_t)&plx_pci_card_info_esd266 | ||
261 | }, | ||
262 | { | ||
263 | /* esd CAN-PCIE/2000 */ | ||
264 | PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9056, | ||
265 | PCI_VENDOR_ID_ESDGMBH, ESD_PCI_SUB_SYS_ID_PCIE2000, | ||
266 | 0, 0, | ||
267 | (kernel_ulong_t)&plx_pci_card_info_esd2000 | ||
268 | }, | ||
269 | { | ||
183 | /* Marathon CAN-bus-PCI card */ | 270 | /* Marathon CAN-bus-PCI card */ |
184 | PCI_VENDOR_ID_PLX, MARATHON_PCI_DEVICE_ID, | 271 | PCI_VENDOR_ID_PLX, MARATHON_PCI_DEVICE_ID, |
185 | PCI_ANY_ID, PCI_ANY_ID, | 272 | PCI_ANY_ID, PCI_ANY_ID, |
@@ -242,7 +329,7 @@ static inline int plx_pci_check_sja1000(const struct sja1000_priv *priv) | |||
242 | } | 329 | } |
243 | 330 | ||
244 | /* | 331 | /* |
245 | * PLX90xx software reset | 332 | * PLX9030/50/52 software reset |
246 | * Also LRESET# asserts and brings to reset device on the Local Bus (if wired). | 333 | * Also LRESET# asserts and brings to reset device on the Local Bus (if wired). |
247 | * For most cards it's enough for reset the SJA1000 chips. | 334 | * For most cards it's enough for reset the SJA1000 chips. |
248 | */ | 335 | */ |
@@ -259,6 +346,38 @@ static void plx_pci_reset_common(struct pci_dev *pdev) | |||
259 | iowrite32(cntrl, card->conf_addr + PLX_CNTRL); | 346 | iowrite32(cntrl, card->conf_addr + PLX_CNTRL); |
260 | }; | 347 | }; |
261 | 348 | ||
349 | /* | ||
350 | * PLX9056 software reset | ||
351 | * Assert LRESET# and reset device(s) on the Local Bus (if wired). | ||
352 | */ | ||
353 | static void plx9056_pci_reset_common(struct pci_dev *pdev) | ||
354 | { | ||
355 | struct plx_pci_card *card = pci_get_drvdata(pdev); | ||
356 | u32 cntrl; | ||
357 | |||
358 | /* issue a local bus reset */ | ||
359 | cntrl = ioread32(card->conf_addr + PLX9056_CNTRL); | ||
360 | cntrl |= PLX_PCI_RESET; | ||
361 | iowrite32(cntrl, card->conf_addr + PLX9056_CNTRL); | ||
362 | udelay(100); | ||
363 | cntrl ^= PLX_PCI_RESET; | ||
364 | iowrite32(cntrl, card->conf_addr + PLX9056_CNTRL); | ||
365 | |||
366 | /* reload local configuration from EEPROM */ | ||
367 | cntrl |= PLX9056_PCI_RCR; | ||
368 | iowrite32(cntrl, card->conf_addr + PLX9056_CNTRL); | ||
369 | |||
370 | /* | ||
371 | * There is no safe way to poll for the end | ||
372 | * of reconfiguration process. Waiting for 10ms | ||
373 | * is safe. | ||
374 | */ | ||
375 | mdelay(10); | ||
376 | |||
377 | cntrl ^= PLX9056_PCI_RCR; | ||
378 | iowrite32(cntrl, card->conf_addr + PLX9056_CNTRL); | ||
379 | }; | ||
380 | |||
262 | /* Special reset function for Marathon card */ | 381 | /* Special reset function for Marathon card */ |
263 | static void plx_pci_reset_marathon(struct pci_dev *pdev) | 382 | static void plx_pci_reset_marathon(struct pci_dev *pdev) |
264 | { | 383 | { |
@@ -302,13 +421,16 @@ static void plx_pci_del_card(struct pci_dev *pdev) | |||
302 | free_sja1000dev(dev); | 421 | free_sja1000dev(dev); |
303 | } | 422 | } |
304 | 423 | ||
305 | plx_pci_reset_common(pdev); | 424 | card->reset_func(pdev); |
306 | 425 | ||
307 | /* | 426 | /* |
308 | * Disable interrupts from PCI-card (PLX90xx) and disable Local_1, | 427 | * Disable interrupts from PCI-card and disable local |
309 | * Local_2 interrupts | 428 | * interrupts |
310 | */ | 429 | */ |
311 | iowrite32(0x0, card->conf_addr + PLX_INTCSR); | 430 | if (pdev->device != PCI_DEVICE_ID_PLX_9056) |
431 | iowrite32(0x0, card->conf_addr + PLX_INTCSR); | ||
432 | else | ||
433 | iowrite32(0x0, card->conf_addr + PLX9056_INTCSR); | ||
312 | 434 | ||
313 | if (card->conf_addr) | 435 | if (card->conf_addr) |
314 | pci_iounmap(pdev, card->conf_addr); | 436 | pci_iounmap(pdev, card->conf_addr); |
@@ -367,6 +489,7 @@ static int __devinit plx_pci_add_card(struct pci_dev *pdev, | |||
367 | card->conf_addr = addr + ci->conf_map.offset; | 489 | card->conf_addr = addr + ci->conf_map.offset; |
368 | 490 | ||
369 | ci->reset_func(pdev); | 491 | ci->reset_func(pdev); |
492 | card->reset_func = ci->reset_func; | ||
370 | 493 | ||
371 | /* Detect available channels */ | 494 | /* Detect available channels */ |
372 | for (i = 0; i < ci->channel_count; i++) { | 495 | for (i = 0; i < ci->channel_count; i++) { |
@@ -438,10 +561,17 @@ static int __devinit plx_pci_add_card(struct pci_dev *pdev, | |||
438 | * Enable interrupts from PCI-card (PLX90xx) and enable Local_1, | 561 | * Enable interrupts from PCI-card (PLX90xx) and enable Local_1, |
439 | * Local_2 interrupts from the SJA1000 chips | 562 | * Local_2 interrupts from the SJA1000 chips |
440 | */ | 563 | */ |
441 | val = ioread32(card->conf_addr + PLX_INTCSR); | 564 | if (pdev->device != PCI_DEVICE_ID_PLX_9056) { |
442 | val |= PLX_LINT1_EN | PLX_LINT2_EN | PLX_PCI_INT_EN; | 565 | val = ioread32(card->conf_addr + PLX_INTCSR); |
443 | iowrite32(val, card->conf_addr + PLX_INTCSR); | 566 | if (pdev->subsystem_vendor == PCI_VENDOR_ID_ESDGMBH) |
444 | 567 | val |= PLX_LINT1_EN | PLX_PCI_INT_EN; | |
568 | else | ||
569 | val |= PLX_LINT1_EN | PLX_LINT2_EN | PLX_PCI_INT_EN; | ||
570 | iowrite32(val, card->conf_addr + PLX_INTCSR); | ||
571 | } else { | ||
572 | iowrite32(PLX9056_LINTI | PLX9056_PCI_INT_EN, | ||
573 | card->conf_addr + PLX9056_INTCSR); | ||
574 | } | ||
445 | return 0; | 575 | return 0; |
446 | 576 | ||
447 | failure_cleanup: | 577 | failure_cleanup: |