diff options
author | Chris Zankel <chris@zankel.net> | 2015-04-14 00:47:53 -0400 |
---|---|---|
committer | Chris Zankel <chris@zankel.net> | 2015-04-14 00:47:53 -0400 |
commit | 2ba9268dd603d23e17643437b2246acb6844953b (patch) | |
tree | b352aedb562f33369194152e448b49551ae76233 | |
parent | 7ead5b7e4a3cf4a16579a8f164022345b93fe972 (diff) | |
parent | e0bf6c5ca2d3281f231c5f0c9bf145e9513644de (diff) |
Merge tag 'xtensa-for-next-20150413' of git://github.com/jcmvbkbc/linux-xtensa into for_next
Xtensa improvements for 4.1:
- fix locking issues in ISS network driver;
- document PIC and MX interrupt distributor device tree bindings;
- add CY7C67300 USB controller support to XTFPGA.
Signed-off-by: Chris Zankel <chris@zankel.net>
5 files changed, 95 insertions, 14 deletions
diff --git a/Documentation/devicetree/bindings/interrupt-controller/cdns,xtensa-mx.txt b/Documentation/devicetree/bindings/interrupt-controller/cdns,xtensa-mx.txt new file mode 100644 index 000000000000..d4de980e55fa --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/cdns,xtensa-mx.txt | |||
@@ -0,0 +1,18 @@ | |||
1 | * Xtensa Interrupt Distributor and Programmable Interrupt Controller (MX) | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should be "cdns,xtensa-mx". | ||
5 | |||
6 | Remaining properties have exact same meaning as in Xtensa PIC | ||
7 | (see cdns,xtensa-pic.txt). | ||
8 | |||
9 | Examples: | ||
10 | pic: pic { | ||
11 | compatible = "cdns,xtensa-mx"; | ||
12 | /* one cell: internal irq number, | ||
13 | * two cells: second cell == 0: internal irq number | ||
14 | * second cell == 1: external irq number | ||
15 | */ | ||
16 | #interrupt-cells = <2>; | ||
17 | interrupt-controller; | ||
18 | }; | ||
diff --git a/Documentation/devicetree/bindings/interrupt-controller/cdns,xtensa-pic.txt b/Documentation/devicetree/bindings/interrupt-controller/cdns,xtensa-pic.txt new file mode 100644 index 000000000000..026ef4cfc1d5 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/cdns,xtensa-pic.txt | |||
@@ -0,0 +1,25 @@ | |||
1 | * Xtensa built-in Programmable Interrupt Controller (PIC) | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should be "cdns,xtensa-pic". | ||
5 | - interrupt-controller: Identifies the node as an interrupt controller. | ||
6 | - #interrupt-cells: The number of cells to define the interrupts. | ||
7 | It may be either 1 or 2. | ||
8 | When it's 1, the first cell is the internal IRQ number. | ||
9 | When it's 2, the first cell is the IRQ number, and the second cell | ||
10 | specifies whether it's internal (0) or external (1). | ||
11 | Periferals are usually connected to a fixed external IRQ, but for different | ||
12 | core variants it may be mapped to different internal IRQ. | ||
13 | IRQ sensitivity and priority are fixed for each core variant and may not be | ||
14 | changed at runtime. | ||
15 | |||
16 | Examples: | ||
17 | pic: pic { | ||
18 | compatible = "cdns,xtensa-pic"; | ||
19 | /* one cell: internal irq number, | ||
20 | * two cells: second cell == 0: internal irq number | ||
21 | * second cell == 1: external irq number | ||
22 | */ | ||
23 | #interrupt-cells = <2>; | ||
24 | interrupt-controller; | ||
25 | }; | ||
diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c index d05f8feeb8d7..17b1ef3232e4 100644 --- a/arch/xtensa/platforms/iss/network.c +++ b/arch/xtensa/platforms/iss/network.c | |||
@@ -349,8 +349,8 @@ static void iss_net_timer(unsigned long priv) | |||
349 | { | 349 | { |
350 | struct iss_net_private *lp = (struct iss_net_private *)priv; | 350 | struct iss_net_private *lp = (struct iss_net_private *)priv; |
351 | 351 | ||
352 | spin_lock(&lp->lock); | ||
353 | iss_net_poll(); | 352 | iss_net_poll(); |
353 | spin_lock(&lp->lock); | ||
354 | mod_timer(&lp->timer, jiffies + lp->timer_val); | 354 | mod_timer(&lp->timer, jiffies + lp->timer_val); |
355 | spin_unlock(&lp->lock); | 355 | spin_unlock(&lp->lock); |
356 | } | 356 | } |
@@ -361,7 +361,7 @@ static int iss_net_open(struct net_device *dev) | |||
361 | struct iss_net_private *lp = netdev_priv(dev); | 361 | struct iss_net_private *lp = netdev_priv(dev); |
362 | int err; | 362 | int err; |
363 | 363 | ||
364 | spin_lock(&lp->lock); | 364 | spin_lock_bh(&lp->lock); |
365 | 365 | ||
366 | err = lp->tp.open(lp); | 366 | err = lp->tp.open(lp); |
367 | if (err < 0) | 367 | if (err < 0) |
@@ -376,9 +376,11 @@ static int iss_net_open(struct net_device *dev) | |||
376 | while ((err = iss_net_rx(dev)) > 0) | 376 | while ((err = iss_net_rx(dev)) > 0) |
377 | ; | 377 | ; |
378 | 378 | ||
379 | spin_lock(&opened_lock); | 379 | spin_unlock_bh(&lp->lock); |
380 | spin_lock_bh(&opened_lock); | ||
380 | list_add(&lp->opened_list, &opened); | 381 | list_add(&lp->opened_list, &opened); |
381 | spin_unlock(&opened_lock); | 382 | spin_unlock_bh(&opened_lock); |
383 | spin_lock_bh(&lp->lock); | ||
382 | 384 | ||
383 | init_timer(&lp->timer); | 385 | init_timer(&lp->timer); |
384 | lp->timer_val = ISS_NET_TIMER_VALUE; | 386 | lp->timer_val = ISS_NET_TIMER_VALUE; |
@@ -387,7 +389,7 @@ static int iss_net_open(struct net_device *dev) | |||
387 | mod_timer(&lp->timer, jiffies + lp->timer_val); | 389 | mod_timer(&lp->timer, jiffies + lp->timer_val); |
388 | 390 | ||
389 | out: | 391 | out: |
390 | spin_unlock(&lp->lock); | 392 | spin_unlock_bh(&lp->lock); |
391 | return err; | 393 | return err; |
392 | } | 394 | } |
393 | 395 | ||
@@ -395,7 +397,7 @@ static int iss_net_close(struct net_device *dev) | |||
395 | { | 397 | { |
396 | struct iss_net_private *lp = netdev_priv(dev); | 398 | struct iss_net_private *lp = netdev_priv(dev); |
397 | netif_stop_queue(dev); | 399 | netif_stop_queue(dev); |
398 | spin_lock(&lp->lock); | 400 | spin_lock_bh(&lp->lock); |
399 | 401 | ||
400 | spin_lock(&opened_lock); | 402 | spin_lock(&opened_lock); |
401 | list_del(&opened); | 403 | list_del(&opened); |
@@ -405,18 +407,17 @@ static int iss_net_close(struct net_device *dev) | |||
405 | 407 | ||
406 | lp->tp.close(lp); | 408 | lp->tp.close(lp); |
407 | 409 | ||
408 | spin_unlock(&lp->lock); | 410 | spin_unlock_bh(&lp->lock); |
409 | return 0; | 411 | return 0; |
410 | } | 412 | } |
411 | 413 | ||
412 | static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev) | 414 | static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev) |
413 | { | 415 | { |
414 | struct iss_net_private *lp = netdev_priv(dev); | 416 | struct iss_net_private *lp = netdev_priv(dev); |
415 | unsigned long flags; | ||
416 | int len; | 417 | int len; |
417 | 418 | ||
418 | netif_stop_queue(dev); | 419 | netif_stop_queue(dev); |
419 | spin_lock_irqsave(&lp->lock, flags); | 420 | spin_lock_bh(&lp->lock); |
420 | 421 | ||
421 | len = lp->tp.write(lp, &skb); | 422 | len = lp->tp.write(lp, &skb); |
422 | 423 | ||
@@ -438,7 +439,7 @@ static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
438 | pr_err("%s: %s failed(%d)\n", dev->name, __func__, len); | 439 | pr_err("%s: %s failed(%d)\n", dev->name, __func__, len); |
439 | } | 440 | } |
440 | 441 | ||
441 | spin_unlock_irqrestore(&lp->lock, flags); | 442 | spin_unlock_bh(&lp->lock); |
442 | 443 | ||
443 | dev_kfree_skb(skb); | 444 | dev_kfree_skb(skb); |
444 | return NETDEV_TX_OK; | 445 | return NETDEV_TX_OK; |
@@ -466,9 +467,9 @@ static int iss_net_set_mac(struct net_device *dev, void *addr) | |||
466 | 467 | ||
467 | if (!is_valid_ether_addr(hwaddr->sa_data)) | 468 | if (!is_valid_ether_addr(hwaddr->sa_data)) |
468 | return -EADDRNOTAVAIL; | 469 | return -EADDRNOTAVAIL; |
469 | spin_lock(&lp->lock); | 470 | spin_lock_bh(&lp->lock); |
470 | memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN); | 471 | memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN); |
471 | spin_unlock(&lp->lock); | 472 | spin_unlock_bh(&lp->lock); |
472 | return 0; | 473 | return 0; |
473 | } | 474 | } |
474 | 475 | ||
@@ -520,11 +521,11 @@ static int iss_net_configure(int index, char *init) | |||
520 | *lp = (struct iss_net_private) { | 521 | *lp = (struct iss_net_private) { |
521 | .device_list = LIST_HEAD_INIT(lp->device_list), | 522 | .device_list = LIST_HEAD_INIT(lp->device_list), |
522 | .opened_list = LIST_HEAD_INIT(lp->opened_list), | 523 | .opened_list = LIST_HEAD_INIT(lp->opened_list), |
523 | .lock = __SPIN_LOCK_UNLOCKED(lp.lock), | ||
524 | .dev = dev, | 524 | .dev = dev, |
525 | .index = index, | 525 | .index = index, |
526 | }; | 526 | }; |
527 | 527 | ||
528 | spin_lock_init(&lp->lock); | ||
528 | /* | 529 | /* |
529 | * If this name ends up conflicting with an existing registered | 530 | * If this name ends up conflicting with an existing registered |
530 | * netdevice, that is OK, register_netdev{,ice}() will notice this | 531 | * netdevice, that is OK, register_netdev{,ice}() will notice this |
diff --git a/arch/xtensa/platforms/xtfpga/include/platform/hardware.h b/arch/xtensa/platforms/xtfpga/include/platform/hardware.h index 4e0af2662a21..0a55bb9c5420 100644 --- a/arch/xtensa/platforms/xtfpga/include/platform/hardware.h +++ b/arch/xtensa/platforms/xtfpga/include/platform/hardware.h | |||
@@ -59,4 +59,7 @@ | |||
59 | /* 5*rx buffs + 5*tx buffs */ | 59 | /* 5*rx buffs + 5*tx buffs */ |
60 | #define OETH_SRAMBUFF_SIZE (5 * 0x600 + 5 * 0x600) | 60 | #define OETH_SRAMBUFF_SIZE (5 * 0x600 + 5 * 0x600) |
61 | 61 | ||
62 | #define C67X00_PADDR (XCHAL_KIO_PADDR + 0x0D0D0000) | ||
63 | #define C67X00_SIZE 0x10 | ||
64 | #define C67X00_IRQ 5 | ||
62 | #endif /* __XTENSA_XTAVNET_HARDWARE_H */ | 65 | #endif /* __XTENSA_XTAVNET_HARDWARE_H */ |
diff --git a/arch/xtensa/platforms/xtfpga/setup.c b/arch/xtensa/platforms/xtfpga/setup.c index 57fd08b36f51..b4cf70e535ab 100644 --- a/arch/xtensa/platforms/xtfpga/setup.c +++ b/arch/xtensa/platforms/xtfpga/setup.c | |||
@@ -189,6 +189,7 @@ void __init platform_calibrate_ccount(void) | |||
189 | #include <linux/serial_8250.h> | 189 | #include <linux/serial_8250.h> |
190 | #include <linux/if.h> | 190 | #include <linux/if.h> |
191 | #include <net/ethoc.h> | 191 | #include <net/ethoc.h> |
192 | #include <linux/usb/c67x00.h> | ||
192 | 193 | ||
193 | /*---------------------------------------------------------------------------- | 194 | /*---------------------------------------------------------------------------- |
194 | * Ethernet -- OpenCores Ethernet MAC (ethoc driver) | 195 | * Ethernet -- OpenCores Ethernet MAC (ethoc driver) |
@@ -233,6 +234,38 @@ static struct platform_device ethoc_device = { | |||
233 | }; | 234 | }; |
234 | 235 | ||
235 | /*---------------------------------------------------------------------------- | 236 | /*---------------------------------------------------------------------------- |
237 | * USB Host/Device -- Cypress CY7C67300 | ||
238 | */ | ||
239 | |||
240 | static struct resource c67x00_res[] = { | ||
241 | [0] = { /* register space */ | ||
242 | .start = C67X00_PADDR, | ||
243 | .end = C67X00_PADDR + C67X00_SIZE - 1, | ||
244 | .flags = IORESOURCE_MEM, | ||
245 | }, | ||
246 | [1] = { /* IRQ number */ | ||
247 | .start = C67X00_IRQ, | ||
248 | .end = C67X00_IRQ, | ||
249 | .flags = IORESOURCE_IRQ, | ||
250 | }, | ||
251 | }; | ||
252 | |||
253 | static struct c67x00_platform_data c67x00_pdata = { | ||
254 | .sie_config = C67X00_SIE1_HOST | C67X00_SIE2_UNUSED, | ||
255 | .hpi_regstep = 4, | ||
256 | }; | ||
257 | |||
258 | static struct platform_device c67x00_device = { | ||
259 | .name = "c67x00", | ||
260 | .id = -1, | ||
261 | .num_resources = ARRAY_SIZE(c67x00_res), | ||
262 | .resource = c67x00_res, | ||
263 | .dev = { | ||
264 | .platform_data = &c67x00_pdata, | ||
265 | }, | ||
266 | }; | ||
267 | |||
268 | /*---------------------------------------------------------------------------- | ||
236 | * UART | 269 | * UART |
237 | */ | 270 | */ |
238 | 271 | ||
@@ -268,6 +301,7 @@ static struct platform_device xtavnet_uart = { | |||
268 | /* platform devices */ | 301 | /* platform devices */ |
269 | static struct platform_device *platform_devices[] __initdata = { | 302 | static struct platform_device *platform_devices[] __initdata = { |
270 | ðoc_device, | 303 | ðoc_device, |
304 | &c67x00_device, | ||
271 | &xtavnet_uart, | 305 | &xtavnet_uart, |
272 | }; | 306 | }; |
273 | 307 | ||