mirror of https://gitee.com/openkylin/linux.git
linux-can-fixes-for-3.15-20140424
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iEYEABECAAYFAlNZf5EACgkQjTAFq1RaXHPFhACghgdQaxG++36VEhtToY+H8o2x 3UUAniZ+DbwtSapriPekjVKRC7VuQFsD =N5FA -----END PGP SIGNATURE----- Merge tag 'linux-can-fixes-for-3.15-20140424' of git://gitorious.org/linux-can/linux-can Marc Kleine-Budde says: ==================== this is a pull request for net/master, for the v3.15 release cycle, consisting of 26 patches. Thomas Gleixner contributes 21 patches for the c_can driver, which address several shortcomings in the driver like hardware initialisation, concurrency, message ordering and poor performance. Two patches Oliver Hartkopp, one adds a missing lock to the sja1000_isa driver, the other one fixes the return value in the generic bit time configuration function. And finally a patch by Alexander Stein, that fixes the slcan driver to use the correct spinlock variant. To make it 26 patches, Wolfgang Grandegger patch for the c_can_pci driver, which enables the bus master only for MSI and a patch by Wolfram Sang, which converts the 'instance' in the c_can driver to the proper type. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
69d268b772
|
@ -14,6 +14,13 @@ config CAN_C_CAN_PLATFORM
|
|||
SPEAr1310 and SPEAr320 evaluation boards & TI (www.ti.com)
|
||||
boards like am335x, dm814x, dm813x and dm811x.
|
||||
|
||||
config CAN_C_CAN_STRICT_FRAME_ORDERING
|
||||
bool "Force a strict RX CAN frame order (may cause frame loss)"
|
||||
---help---
|
||||
The RX split buffer prevents packet reordering but can cause packet
|
||||
loss. Only enable this option when you accept to lose CAN frames
|
||||
in favour of getting the received CAN frames in the correct order.
|
||||
|
||||
config CAN_C_CAN_PCI
|
||||
tristate "Generic PCI Bus based C_CAN/D_CAN driver"
|
||||
depends on PCI
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -22,14 +22,6 @@
|
|||
#ifndef C_CAN_H
|
||||
#define C_CAN_H
|
||||
|
||||
/*
|
||||
* IFx register masks:
|
||||
* allow easy operation on 16-bit registers when the
|
||||
* argument is 32-bit instead
|
||||
*/
|
||||
#define IFX_WRITE_LOW_16BIT(x) ((x) & 0xFFFF)
|
||||
#define IFX_WRITE_HIGH_16BIT(x) (((x) & 0xFFFF0000) >> 16)
|
||||
|
||||
/* message object split */
|
||||
#define C_CAN_NO_OF_OBJECTS 32
|
||||
#define C_CAN_MSG_OBJ_RX_NUM 16
|
||||
|
@ -45,8 +37,6 @@
|
|||
|
||||
#define C_CAN_MSG_OBJ_RX_SPLIT 9
|
||||
#define C_CAN_MSG_RX_LOW_LAST (C_CAN_MSG_OBJ_RX_SPLIT - 1)
|
||||
|
||||
#define C_CAN_NEXT_MSG_OBJ_MASK (C_CAN_MSG_OBJ_TX_NUM - 1)
|
||||
#define RECEIVE_OBJECT_BITS 0x0000ffff
|
||||
|
||||
enum reg {
|
||||
|
@ -183,23 +173,20 @@ struct c_can_priv {
|
|||
struct napi_struct napi;
|
||||
struct net_device *dev;
|
||||
struct device *device;
|
||||
spinlock_t xmit_lock;
|
||||
int tx_object;
|
||||
int current_status;
|
||||
atomic_t tx_active;
|
||||
unsigned long tx_dir;
|
||||
int last_status;
|
||||
u16 (*read_reg) (struct c_can_priv *priv, enum reg index);
|
||||
void (*write_reg) (struct c_can_priv *priv, enum reg index, u16 val);
|
||||
void __iomem *base;
|
||||
const u16 *regs;
|
||||
unsigned long irq_flags; /* for request_irq() */
|
||||
unsigned int tx_next;
|
||||
unsigned int tx_echo;
|
||||
void *priv; /* for board-specific data */
|
||||
u16 irqstatus;
|
||||
enum c_can_dev_id type;
|
||||
u32 __iomem *raminit_ctrlreg;
|
||||
unsigned int instance;
|
||||
int instance;
|
||||
void (*raminit) (const struct c_can_priv *priv, bool enable);
|
||||
u32 comm_rcv_high;
|
||||
u32 rxmasked;
|
||||
u32 dlc[C_CAN_MSG_OBJ_TX_NUM];
|
||||
};
|
||||
|
||||
|
|
|
@ -84,8 +84,11 @@ static int c_can_pci_probe(struct pci_dev *pdev,
|
|||
goto out_disable_device;
|
||||
}
|
||||
|
||||
pci_set_master(pdev);
|
||||
pci_enable_msi(pdev);
|
||||
ret = pci_enable_msi(pdev);
|
||||
if (!ret) {
|
||||
dev_info(&pdev->dev, "MSI enabled\n");
|
||||
pci_set_master(pdev);
|
||||
}
|
||||
|
||||
addr = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));
|
||||
if (!addr) {
|
||||
|
@ -132,6 +135,8 @@ static int c_can_pci_probe(struct pci_dev *pdev,
|
|||
goto out_free_c_can;
|
||||
}
|
||||
|
||||
priv->type = c_can_pci_data->type;
|
||||
|
||||
/* Configure access to registers */
|
||||
switch (c_can_pci_data->reg_align) {
|
||||
case C_CAN_REG_ALIGN_32:
|
||||
|
|
|
@ -222,7 +222,7 @@ static int c_can_plat_probe(struct platform_device *pdev)
|
|||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
priv->raminit_ctrlreg = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(priv->raminit_ctrlreg) || (int)priv->instance < 0)
|
||||
if (IS_ERR(priv->raminit_ctrlreg) || priv->instance < 0)
|
||||
dev_info(&pdev->dev, "control memory is not used for raminit\n");
|
||||
else
|
||||
priv->raminit = c_can_hw_raminit;
|
||||
|
|
|
@ -256,7 +256,7 @@ static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt,
|
|||
|
||||
/* Check if the CAN device has bit-timing parameters */
|
||||
if (!btc)
|
||||
return -ENOTSUPP;
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/*
|
||||
* Depending on the given can_bittiming parameter structure the CAN
|
||||
|
|
|
@ -46,6 +46,7 @@ static int clk[MAXDEV];
|
|||
static unsigned char cdr[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
|
||||
static unsigned char ocr[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
|
||||
static int indirect[MAXDEV] = {[0 ... (MAXDEV - 1)] = -1};
|
||||
static spinlock_t indirect_lock[MAXDEV]; /* lock for indirect access mode */
|
||||
|
||||
module_param_array(port, ulong, NULL, S_IRUGO);
|
||||
MODULE_PARM_DESC(port, "I/O port number");
|
||||
|
@ -101,19 +102,26 @@ static void sja1000_isa_port_write_reg(const struct sja1000_priv *priv,
|
|||
static u8 sja1000_isa_port_read_reg_indirect(const struct sja1000_priv *priv,
|
||||
int reg)
|
||||
{
|
||||
unsigned long base = (unsigned long)priv->reg_base;
|
||||
unsigned long flags, base = (unsigned long)priv->reg_base;
|
||||
u8 readval;
|
||||
|
||||
spin_lock_irqsave(&indirect_lock[priv->dev->dev_id], flags);
|
||||
outb(reg, base);
|
||||
return inb(base + 1);
|
||||
readval = inb(base + 1);
|
||||
spin_unlock_irqrestore(&indirect_lock[priv->dev->dev_id], flags);
|
||||
|
||||
return readval;
|
||||
}
|
||||
|
||||
static void sja1000_isa_port_write_reg_indirect(const struct sja1000_priv *priv,
|
||||
int reg, u8 val)
|
||||
{
|
||||
unsigned long base = (unsigned long)priv->reg_base;
|
||||
unsigned long flags, base = (unsigned long)priv->reg_base;
|
||||
|
||||
spin_lock_irqsave(&indirect_lock[priv->dev->dev_id], flags);
|
||||
outb(reg, base);
|
||||
outb(val, base + 1);
|
||||
spin_unlock_irqrestore(&indirect_lock[priv->dev->dev_id], flags);
|
||||
}
|
||||
|
||||
static int sja1000_isa_probe(struct platform_device *pdev)
|
||||
|
@ -169,6 +177,7 @@ static int sja1000_isa_probe(struct platform_device *pdev)
|
|||
if (iosize == SJA1000_IOSIZE_INDIRECT) {
|
||||
priv->read_reg = sja1000_isa_port_read_reg_indirect;
|
||||
priv->write_reg = sja1000_isa_port_write_reg_indirect;
|
||||
spin_lock_init(&indirect_lock[idx]);
|
||||
} else {
|
||||
priv->read_reg = sja1000_isa_port_read_reg;
|
||||
priv->write_reg = sja1000_isa_port_write_reg;
|
||||
|
@ -198,6 +207,7 @@ static int sja1000_isa_probe(struct platform_device *pdev)
|
|||
|
||||
platform_set_drvdata(pdev, dev);
|
||||
SET_NETDEV_DEV(dev, &pdev->dev);
|
||||
dev->dev_id = idx;
|
||||
|
||||
err = register_sja1000dev(dev);
|
||||
if (err) {
|
||||
|
|
|
@ -322,13 +322,13 @@ static void slcan_write_wakeup(struct tty_struct *tty)
|
|||
if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev))
|
||||
return;
|
||||
|
||||
spin_lock(&sl->lock);
|
||||
spin_lock_bh(&sl->lock);
|
||||
if (sl->xleft <= 0) {
|
||||
/* Now serial buffer is almost free & we can start
|
||||
* transmission of another packet */
|
||||
sl->dev->stats.tx_packets++;
|
||||
clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
|
||||
spin_unlock(&sl->lock);
|
||||
spin_unlock_bh(&sl->lock);
|
||||
netif_wake_queue(sl->dev);
|
||||
return;
|
||||
}
|
||||
|
@ -336,7 +336,7 @@ static void slcan_write_wakeup(struct tty_struct *tty)
|
|||
actual = tty->ops->write(tty, sl->xhead, sl->xleft);
|
||||
sl->xleft -= actual;
|
||||
sl->xhead += actual;
|
||||
spin_unlock(&sl->lock);
|
||||
spin_unlock_bh(&sl->lock);
|
||||
}
|
||||
|
||||
/* Send a can_frame to a TTY queue. */
|
||||
|
|
Loading…
Reference in New Issue