summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Zankel <chris@zankel.net>2015-04-14 04:47:53 +0000
committerChris Zankel <chris@zankel.net>2015-04-14 04:47:53 +0000
commit2ba9268dd603d23e17643437b2246acb6844953b (patch)
treeb352aedb562f33369194152e448b49551ae76233
parent7ead5b7e4a3cf4a16579a8f164022345b93fe972 (diff)
parente0bf6c5ca2d3281f231c5f0c9bf145e9513644de (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>
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/cdns,xtensa-mx.txt18
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/cdns,xtensa-pic.txt25
-rw-r--r--arch/xtensa/platforms/iss/network.c29
-rw-r--r--arch/xtensa/platforms/xtfpga/include/platform/hardware.h3
-rw-r--r--arch/xtensa/platforms/xtfpga/setup.c34
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 @@
+* Xtensa Interrupt Distributor and Programmable Interrupt Controller (MX)
+
+Required properties:
+- compatible: Should be "cdns,xtensa-mx".
+
+Remaining properties have exact same meaning as in Xtensa PIC
+(see cdns,xtensa-pic.txt).
+
+Examples:
+ pic: pic {
+ compatible = "cdns,xtensa-mx";
+ /* one cell: internal irq number,
+ * two cells: second cell == 0: internal irq number
+ * second cell == 1: external irq number
+ */
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
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 @@
+* Xtensa built-in Programmable Interrupt Controller (PIC)
+
+Required properties:
+- compatible: Should be "cdns,xtensa-pic".
+- interrupt-controller: Identifies the node as an interrupt controller.
+- #interrupt-cells: The number of cells to define the interrupts.
+ It may be either 1 or 2.
+ When it's 1, the first cell is the internal IRQ number.
+ When it's 2, the first cell is the IRQ number, and the second cell
+ specifies whether it's internal (0) or external (1).
+ Periferals are usually connected to a fixed external IRQ, but for different
+ core variants it may be mapped to different internal IRQ.
+ IRQ sensitivity and priority are fixed for each core variant and may not be
+ changed at runtime.
+
+Examples:
+ pic: pic {
+ compatible = "cdns,xtensa-pic";
+ /* one cell: internal irq number,
+ * two cells: second cell == 0: internal irq number
+ * second cell == 1: external irq number
+ */
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
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)
{
struct iss_net_private *lp = (struct iss_net_private *)priv;
- spin_lock(&lp->lock);
iss_net_poll();
+ spin_lock(&lp->lock);
mod_timer(&lp->timer, jiffies + lp->timer_val);
spin_unlock(&lp->lock);
}
@@ -361,7 +361,7 @@ static int iss_net_open(struct net_device *dev)
struct iss_net_private *lp = netdev_priv(dev);
int err;
- spin_lock(&lp->lock);
+ spin_lock_bh(&lp->lock);
err = lp->tp.open(lp);
if (err < 0)
@@ -376,9 +376,11 @@ static int iss_net_open(struct net_device *dev)
while ((err = iss_net_rx(dev)) > 0)
;
- spin_lock(&opened_lock);
+ spin_unlock_bh(&lp->lock);
+ spin_lock_bh(&opened_lock);
list_add(&lp->opened_list, &opened);
- spin_unlock(&opened_lock);
+ spin_unlock_bh(&opened_lock);
+ spin_lock_bh(&lp->lock);
init_timer(&lp->timer);
lp->timer_val = ISS_NET_TIMER_VALUE;
@@ -387,7 +389,7 @@ static int iss_net_open(struct net_device *dev)
mod_timer(&lp->timer, jiffies + lp->timer_val);
out:
- spin_unlock(&lp->lock);
+ spin_unlock_bh(&lp->lock);
return err;
}
@@ -395,7 +397,7 @@ static int iss_net_close(struct net_device *dev)
{
struct iss_net_private *lp = netdev_priv(dev);
netif_stop_queue(dev);
- spin_lock(&lp->lock);
+ spin_lock_bh(&lp->lock);
spin_lock(&opened_lock);
list_del(&opened);
@@ -405,18 +407,17 @@ static int iss_net_close(struct net_device *dev)
lp->tp.close(lp);
- spin_unlock(&lp->lock);
+ spin_unlock_bh(&lp->lock);
return 0;
}
static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct iss_net_private *lp = netdev_priv(dev);
- unsigned long flags;
int len;
netif_stop_queue(dev);
- spin_lock_irqsave(&lp->lock, flags);
+ spin_lock_bh(&lp->lock);
len = lp->tp.write(lp, &skb);
@@ -438,7 +439,7 @@ static int iss_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
pr_err("%s: %s failed(%d)\n", dev->name, __func__, len);
}
- spin_unlock_irqrestore(&lp->lock, flags);
+ spin_unlock_bh(&lp->lock);
dev_kfree_skb(skb);
return NETDEV_TX_OK;
@@ -466,9 +467,9 @@ static int iss_net_set_mac(struct net_device *dev, void *addr)
if (!is_valid_ether_addr(hwaddr->sa_data))
return -EADDRNOTAVAIL;
- spin_lock(&lp->lock);
+ spin_lock_bh(&lp->lock);
memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN);
- spin_unlock(&lp->lock);
+ spin_unlock_bh(&lp->lock);
return 0;
}
@@ -520,11 +521,11 @@ static int iss_net_configure(int index, char *init)
*lp = (struct iss_net_private) {
.device_list = LIST_HEAD_INIT(lp->device_list),
.opened_list = LIST_HEAD_INIT(lp->opened_list),
- .lock = __SPIN_LOCK_UNLOCKED(lp.lock),
.dev = dev,
.index = index,
- };
+ };
+ spin_lock_init(&lp->lock);
/*
* If this name ends up conflicting with an existing registered
* 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 @@
/* 5*rx buffs + 5*tx buffs */
#define OETH_SRAMBUFF_SIZE (5 * 0x600 + 5 * 0x600)
+#define C67X00_PADDR (XCHAL_KIO_PADDR + 0x0D0D0000)
+#define C67X00_SIZE 0x10
+#define C67X00_IRQ 5
#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)
#include <linux/serial_8250.h>
#include <linux/if.h>
#include <net/ethoc.h>
+#include <linux/usb/c67x00.h>
/*----------------------------------------------------------------------------
* Ethernet -- OpenCores Ethernet MAC (ethoc driver)
@@ -233,6 +234,38 @@ static struct platform_device ethoc_device = {
};
/*----------------------------------------------------------------------------
+ * USB Host/Device -- Cypress CY7C67300
+ */
+
+static struct resource c67x00_res[] = {
+ [0] = { /* register space */
+ .start = C67X00_PADDR,
+ .end = C67X00_PADDR + C67X00_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = { /* IRQ number */
+ .start = C67X00_IRQ,
+ .end = C67X00_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct c67x00_platform_data c67x00_pdata = {
+ .sie_config = C67X00_SIE1_HOST | C67X00_SIE2_UNUSED,
+ .hpi_regstep = 4,
+};
+
+static struct platform_device c67x00_device = {
+ .name = "c67x00",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(c67x00_res),
+ .resource = c67x00_res,
+ .dev = {
+ .platform_data = &c67x00_pdata,
+ },
+};
+
+/*----------------------------------------------------------------------------
* UART
*/
@@ -268,6 +301,7 @@ static struct platform_device xtavnet_uart = {
/* platform devices */
static struct platform_device *platform_devices[] __initdata = {
&ethoc_device,
+ &c67x00_device,
&xtavnet_uart,
};