diff options
author | Thomas Moll <thomas.moll@sysgo.com> | 2010-05-26 14:44:01 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-27 09:12:51 -0700 |
commit | 933af4a6c4913ab4c0691c8fb27fc305063889cd (patch) | |
tree | 5bc7b63482131f184e006ef0d3346aac79d300cb /drivers/rapidio/rio-scan.c | |
parent | a52c8f521fed43bce53451d7dfddf2b42a2af689 (diff) | |
download | kernel_samsung_smdk4412-933af4a6c4913ab4c0691c8fb27fc305063889cd.zip kernel_samsung_smdk4412-933af4a6c4913ab4c0691c8fb27fc305063889cd.tar.gz kernel_samsung_smdk4412-933af4a6c4913ab4c0691c8fb27fc305063889cd.tar.bz2 |
rapidio: add enabling SRIO port RX and TX
Add the functionality to enable Input receiver and Output transmitter of
every port, to allow non-maintenance traffic.
Signed-off-by: Thomas Moll <thomas.moll@sysgo.com>
Signed-off-by: Alexandre Bounine <abounine@tundra.com>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Li Yang <leoli@freescale.com>
Cc: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rapidio/rio-scan.c')
-rw-r--r-- | drivers/rapidio/rio-scan.c | 79 |
1 files changed, 78 insertions, 1 deletions
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index 74633cc..1faa1a5 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c @@ -8,6 +8,10 @@ * Alex Bounine <alexandre.bounine@idt.com> * - Added Port-Write/Error Management initialization and handling * + * Copyright 2009 Sysgo AG + * Thomas Moll <thomas.moll@sysgo.com> + * - Added Input- Output- enable functionality, to allow full communication + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your @@ -328,6 +332,65 @@ static int __devinit rio_add_device(struct rio_dev *rdev) } /** + * rio_enable_rx_tx_port - enable input reciever and output transmitter of + * given port + * @port: Master port associated with the RIO network + * @local: local=1 select local port otherwise a far device is reached + * @destid: Destination ID of the device to check host bit + * @hopcount: Number of hops to reach the target + * @port_num: Port (-number on switch) to enable on a far end device + * + * Returns 0 or 1 from on General Control Command and Status Register + * (EXT_PTR+0x3C) + */ +inline int rio_enable_rx_tx_port(struct rio_mport *port, + int local, u16 destid, + u8 hopcount, u8 port_num) { +#ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS + u32 regval; + u32 ext_ftr_ptr; + + /* + * enable rx input tx output port + */ + pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = " + "%d, port_num = %d)\n", local, destid, hopcount, port_num); + + ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, hopcount); + + if (local) { + rio_local_read_config_32(port, ext_ftr_ptr + + RIO_PORT_N_CTL_CSR(0), + ®val); + } else { + if (rio_mport_read_config_32(port, destid, hopcount, + ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), ®val) < 0) + return -EIO; + } + + if (regval & RIO_PORT_N_CTL_P_TYP_SER) { + /* serial */ + regval = regval | RIO_PORT_N_CTL_EN_RX_SER + | RIO_PORT_N_CTL_EN_TX_SER; + } else { + /* parallel */ + regval = regval | RIO_PORT_N_CTL_EN_RX_PAR + | RIO_PORT_N_CTL_EN_TX_PAR; + } + + if (local) { + rio_local_write_config_32(port, ext_ftr_ptr + + RIO_PORT_N_CTL_CSR(0), regval); + } else { + if (rio_mport_write_config_32(port, destid, hopcount, + ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), regval) < 0) + return -EIO; + } +#endif + return 0; +} + +/** * rio_setup_device- Allocates and sets up a RIO device * @net: RIO network * @port: Master port to send transactions @@ -430,9 +493,14 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, list_add_tail(&rswitch->node, &rio_switches); - } else + } else { + if (do_enum) + /*Enable Input Output Port (transmitter reviever)*/ + rio_enable_rx_tx_port(port, 0, destid, hopcount, 0); + dev_set_name(&rdev->dev, "%02x:e:%04x", rdev->net->id, rdev->destid); + } rdev->dev.bus = &rio_bus_type; @@ -812,6 +880,11 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, rio_name(rdev), rdev->vid, rdev->did, num_ports); sw_destid = next_destid; for (port_num = 0; port_num < num_ports; port_num++) { + /*Enable Input Output Port (transmitter reviever)*/ + rio_enable_rx_tx_port(port, 0, + RIO_ANY_DESTID(port->sys_size), + hopcount, port_num); + if (sw_inport == port_num) { rdev->rswitch->port_ok |= (1 << port_num); continue; @@ -1132,6 +1205,10 @@ int __devinit rio_enum_mport(struct rio_mport *mport) rc = -ENOMEM; goto out; } + + /* Enable Input Output Port (transmitter reviever) */ + rio_enable_rx_tx_port(mport, 1, 0, 0, 0); + if (rio_enum_peer(net, mport, 0) < 0) { /* A higher priority host won enumeration, bail. */ printk(KERN_INFO |