linux-can-fixes-for-5.5-20191208
-----BEGIN PGP SIGNATURE----- iQFHBAABCgAxFiEEmvEkXzgOfc881GuFWsYho5HknSAFAl3s3dwTHG1rbEBwZW5n dXRyb25peC5kZQAKCRBaxiGjkeSdIKhhB/sE+kGrGECa6DSehxKsSTCvh/5AGw2U AGh+AHgpfCRKOPNBeN0yKCdBVSE40fURsIjNvn5SDZ1cY8tUOVCJAyUU31MfgzkW b+Xiro5iOu6G/UpfZgMCeGV617FZg/65rz7ylwNzzA7zuUcoml6o4A55/QUFNIXx juDzhdKmpmLRQusekzbP9qyCgDGXv8/cPBloI+frzqaDU5bgS6Q3ldHe26lkQzNH bwF6bCGpJYykuNFIrLoFpSuJ+7ttZhLexXCwsl90UfpwmHVvUgQKJuF8JVR1AF3x 5mjHWi3GFyi4aUL4yY4kU3cWWPse3MQLPt5QqMu56dW4UADp1k3FHByo =YMzV -----END PGP SIGNATURE----- Merge tag 'linux-can-fixes-for-5.5-20191208' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can Marc Kleine-Budde says: ==================== pull-request: can 2019-12-08 this is a pull request of 13 patches for net/master. The first two patches are by Dan Murphy. He adds himself as a maintainer to the m-can MMIO and tcan SPI driver. The next two patches the j1939 stack. The first one is by Oleksij Rempel and fixes a locking problem found by the syzbot, the second one is by me an fixes a mistake in the documentation. Srinivas Neeli fixes missing RX CAN packets on CANFD2.0 in the xilinx driver. Sean Nyekjaer fixes a possible deadlock in the the flexcan driver after suspend/resume. Joakim Zhang contributes two patches for the flexcan driver that fix problems with the low power enter/exit. The next 4 patches all target the tcan part of the m_can driver. Sean Nyekjaer adds the required delay after reset and fixes the device tree binding example. Dan Murphy's patches make the wake-gpio optional. In the last patch Xiaolong Huang fixes several kernel memory info leaks to the USB device in the kvaser_usb_leaf driver. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
43aad8104b
|
@ -10,7 +10,6 @@ Required properties:
|
||||||
- #size-cells: 0
|
- #size-cells: 0
|
||||||
- spi-max-frequency: Maximum frequency of the SPI bus the chip can
|
- spi-max-frequency: Maximum frequency of the SPI bus the chip can
|
||||||
operate at should be less than or equal to 18 MHz.
|
operate at should be less than or equal to 18 MHz.
|
||||||
- device-wake-gpios: Wake up GPIO to wake up the TCAN device.
|
|
||||||
- interrupt-parent: the phandle to the interrupt controller which provides
|
- interrupt-parent: the phandle to the interrupt controller which provides
|
||||||
the interrupt.
|
the interrupt.
|
||||||
- interrupts: interrupt specification for data-ready.
|
- interrupts: interrupt specification for data-ready.
|
||||||
|
@ -23,6 +22,7 @@ Optional properties:
|
||||||
reset.
|
reset.
|
||||||
- device-state-gpios: Input GPIO that indicates if the device is in
|
- device-state-gpios: Input GPIO that indicates if the device is in
|
||||||
a sleep state or if the device is active.
|
a sleep state or if the device is active.
|
||||||
|
- device-wake-gpios: Wake up GPIO to wake up the TCAN device.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
tcan4x5x: tcan4x5x@0 {
|
tcan4x5x: tcan4x5x@0 {
|
||||||
|
@ -36,5 +36,5 @@ tcan4x5x: tcan4x5x@0 {
|
||||||
interrupts = <14 GPIO_ACTIVE_LOW>;
|
interrupts = <14 GPIO_ACTIVE_LOW>;
|
||||||
device-state-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>;
|
device-state-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>;
|
||||||
device-wake-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
|
device-wake-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
|
||||||
reset-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>;
|
reset-gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -339,7 +339,7 @@ To claim an address following code example can be used:
|
||||||
.pgn = J1939_PGN_ADDRESS_CLAIMED,
|
.pgn = J1939_PGN_ADDRESS_CLAIMED,
|
||||||
.pgn_mask = J1939_PGN_PDU1_MAX,
|
.pgn_mask = J1939_PGN_PDU1_MAX,
|
||||||
}, {
|
}, {
|
||||||
.pgn = J1939_PGN_ADDRESS_REQUEST,
|
.pgn = J1939_PGN_REQUEST,
|
||||||
.pgn_mask = J1939_PGN_PDU1_MAX,
|
.pgn_mask = J1939_PGN_PDU1_MAX,
|
||||||
}, {
|
}, {
|
||||||
.pgn = J1939_PGN_ADDRESS_COMMANDED,
|
.pgn = J1939_PGN_ADDRESS_COMMANDED,
|
||||||
|
|
|
@ -10108,6 +10108,7 @@ S: Maintained
|
||||||
F: drivers/media/radio/radio-maxiradio*
|
F: drivers/media/radio/radio-maxiradio*
|
||||||
|
|
||||||
MCAN MMIO DEVICE DRIVER
|
MCAN MMIO DEVICE DRIVER
|
||||||
|
M: Dan Murphy <dmurphy@ti.com>
|
||||||
M: Sriram Dash <sriram.dash@samsung.com>
|
M: Sriram Dash <sriram.dash@samsung.com>
|
||||||
L: linux-can@vger.kernel.org
|
L: linux-can@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
@ -16533,6 +16534,13 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||||
S: Odd Fixes
|
S: Odd Fixes
|
||||||
F: sound/soc/codecs/tas571x*
|
F: sound/soc/codecs/tas571x*
|
||||||
|
|
||||||
|
TI TCAN4X5X DEVICE DRIVER
|
||||||
|
M: Dan Murphy <dmurphy@ti.com>
|
||||||
|
L: linux-can@vger.kernel.org
|
||||||
|
S: Maintained
|
||||||
|
F: Documentation/devicetree/bindings/net/can/tcan4x5x.txt
|
||||||
|
F: drivers/net/can/m_can/tcan4x5x.c
|
||||||
|
|
||||||
TI TRF7970A NFC DRIVER
|
TI TRF7970A NFC DRIVER
|
||||||
M: Mark Greer <mgreer@animalcreek.com>
|
M: Mark Greer <mgreer@animalcreek.com>
|
||||||
L: linux-wireless@vger.kernel.org
|
L: linux-wireless@vger.kernel.org
|
||||||
|
|
|
@ -389,6 +389,34 @@ static struct flexcan_mb __iomem *flexcan_get_mb(const struct flexcan_priv *priv
|
||||||
(&priv->regs->mb[bank][priv->mb_size * mb_index]);
|
(&priv->regs->mb[bank][priv->mb_size * mb_index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int flexcan_low_power_enter_ack(struct flexcan_priv *priv)
|
||||||
|
{
|
||||||
|
struct flexcan_regs __iomem *regs = priv->regs;
|
||||||
|
unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
|
||||||
|
|
||||||
|
while (timeout-- && !(priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
|
||||||
|
udelay(10);
|
||||||
|
|
||||||
|
if (!(priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int flexcan_low_power_exit_ack(struct flexcan_priv *priv)
|
||||||
|
{
|
||||||
|
struct flexcan_regs __iomem *regs = priv->regs;
|
||||||
|
unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
|
||||||
|
|
||||||
|
while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
|
||||||
|
udelay(10);
|
||||||
|
|
||||||
|
if (priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void flexcan_enable_wakeup_irq(struct flexcan_priv *priv, bool enable)
|
static void flexcan_enable_wakeup_irq(struct flexcan_priv *priv, bool enable)
|
||||||
{
|
{
|
||||||
struct flexcan_regs __iomem *regs = priv->regs;
|
struct flexcan_regs __iomem *regs = priv->regs;
|
||||||
|
@ -407,7 +435,6 @@ static void flexcan_enable_wakeup_irq(struct flexcan_priv *priv, bool enable)
|
||||||
static inline int flexcan_enter_stop_mode(struct flexcan_priv *priv)
|
static inline int flexcan_enter_stop_mode(struct flexcan_priv *priv)
|
||||||
{
|
{
|
||||||
struct flexcan_regs __iomem *regs = priv->regs;
|
struct flexcan_regs __iomem *regs = priv->regs;
|
||||||
unsigned int ackval;
|
|
||||||
u32 reg_mcr;
|
u32 reg_mcr;
|
||||||
|
|
||||||
reg_mcr = priv->read(®s->mcr);
|
reg_mcr = priv->read(®s->mcr);
|
||||||
|
@ -418,36 +445,24 @@ static inline int flexcan_enter_stop_mode(struct flexcan_priv *priv)
|
||||||
regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr,
|
regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr,
|
||||||
1 << priv->stm.req_bit, 1 << priv->stm.req_bit);
|
1 << priv->stm.req_bit, 1 << priv->stm.req_bit);
|
||||||
|
|
||||||
/* get stop acknowledgment */
|
return flexcan_low_power_enter_ack(priv);
|
||||||
if (regmap_read_poll_timeout(priv->stm.gpr, priv->stm.ack_gpr,
|
|
||||||
ackval, ackval & (1 << priv->stm.ack_bit),
|
|
||||||
0, FLEXCAN_TIMEOUT_US))
|
|
||||||
return -ETIMEDOUT;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int flexcan_exit_stop_mode(struct flexcan_priv *priv)
|
static inline int flexcan_exit_stop_mode(struct flexcan_priv *priv)
|
||||||
{
|
{
|
||||||
struct flexcan_regs __iomem *regs = priv->regs;
|
struct flexcan_regs __iomem *regs = priv->regs;
|
||||||
unsigned int ackval;
|
|
||||||
u32 reg_mcr;
|
u32 reg_mcr;
|
||||||
|
|
||||||
/* remove stop request */
|
/* remove stop request */
|
||||||
regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr,
|
regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr,
|
||||||
1 << priv->stm.req_bit, 0);
|
1 << priv->stm.req_bit, 0);
|
||||||
|
|
||||||
/* get stop acknowledgment */
|
|
||||||
if (regmap_read_poll_timeout(priv->stm.gpr, priv->stm.ack_gpr,
|
|
||||||
ackval, !(ackval & (1 << priv->stm.ack_bit)),
|
|
||||||
0, FLEXCAN_TIMEOUT_US))
|
|
||||||
return -ETIMEDOUT;
|
|
||||||
|
|
||||||
reg_mcr = priv->read(®s->mcr);
|
reg_mcr = priv->read(®s->mcr);
|
||||||
reg_mcr &= ~FLEXCAN_MCR_SLF_WAK;
|
reg_mcr &= ~FLEXCAN_MCR_SLF_WAK;
|
||||||
priv->write(reg_mcr, ®s->mcr);
|
priv->write(reg_mcr, ®s->mcr);
|
||||||
|
|
||||||
return 0;
|
return flexcan_low_power_exit_ack(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv)
|
static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv)
|
||||||
|
@ -506,39 +521,25 @@ static inline int flexcan_transceiver_disable(const struct flexcan_priv *priv)
|
||||||
static int flexcan_chip_enable(struct flexcan_priv *priv)
|
static int flexcan_chip_enable(struct flexcan_priv *priv)
|
||||||
{
|
{
|
||||||
struct flexcan_regs __iomem *regs = priv->regs;
|
struct flexcan_regs __iomem *regs = priv->regs;
|
||||||
unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
|
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
reg = priv->read(®s->mcr);
|
reg = priv->read(®s->mcr);
|
||||||
reg &= ~FLEXCAN_MCR_MDIS;
|
reg &= ~FLEXCAN_MCR_MDIS;
|
||||||
priv->write(reg, ®s->mcr);
|
priv->write(reg, ®s->mcr);
|
||||||
|
|
||||||
while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
|
return flexcan_low_power_exit_ack(priv);
|
||||||
udelay(10);
|
|
||||||
|
|
||||||
if (priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)
|
|
||||||
return -ETIMEDOUT;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int flexcan_chip_disable(struct flexcan_priv *priv)
|
static int flexcan_chip_disable(struct flexcan_priv *priv)
|
||||||
{
|
{
|
||||||
struct flexcan_regs __iomem *regs = priv->regs;
|
struct flexcan_regs __iomem *regs = priv->regs;
|
||||||
unsigned int timeout = FLEXCAN_TIMEOUT_US / 10;
|
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
reg = priv->read(®s->mcr);
|
reg = priv->read(®s->mcr);
|
||||||
reg |= FLEXCAN_MCR_MDIS;
|
reg |= FLEXCAN_MCR_MDIS;
|
||||||
priv->write(reg, ®s->mcr);
|
priv->write(reg, ®s->mcr);
|
||||||
|
|
||||||
while (timeout-- && !(priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
|
return flexcan_low_power_enter_ack(priv);
|
||||||
udelay(10);
|
|
||||||
|
|
||||||
if (!(priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK))
|
|
||||||
return -ETIMEDOUT;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int flexcan_chip_freeze(struct flexcan_priv *priv)
|
static int flexcan_chip_freeze(struct flexcan_priv *priv)
|
||||||
|
@ -1722,6 +1723,9 @@ static int __maybe_unused flexcan_resume(struct device *device)
|
||||||
netif_start_queue(dev);
|
netif_start_queue(dev);
|
||||||
if (device_may_wakeup(device)) {
|
if (device_may_wakeup(device)) {
|
||||||
disable_irq_wake(dev->irq);
|
disable_irq_wake(dev->irq);
|
||||||
|
err = flexcan_exit_stop_mode(priv);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
} else {
|
} else {
|
||||||
err = pm_runtime_force_resume(device);
|
err = pm_runtime_force_resume(device);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -1767,14 +1771,9 @@ static int __maybe_unused flexcan_noirq_resume(struct device *device)
|
||||||
{
|
{
|
||||||
struct net_device *dev = dev_get_drvdata(device);
|
struct net_device *dev = dev_get_drvdata(device);
|
||||||
struct flexcan_priv *priv = netdev_priv(dev);
|
struct flexcan_priv *priv = netdev_priv(dev);
|
||||||
int err;
|
|
||||||
|
|
||||||
if (netif_running(dev) && device_may_wakeup(device)) {
|
if (netif_running(dev) && device_may_wakeup(device))
|
||||||
flexcan_enable_wakeup_irq(priv, false);
|
flexcan_enable_wakeup_irq(priv, false);
|
||||||
err = flexcan_exit_stop_mode(priv);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,6 +101,8 @@
|
||||||
#define TCAN4X5X_MODE_STANDBY BIT(6)
|
#define TCAN4X5X_MODE_STANDBY BIT(6)
|
||||||
#define TCAN4X5X_MODE_NORMAL BIT(7)
|
#define TCAN4X5X_MODE_NORMAL BIT(7)
|
||||||
|
|
||||||
|
#define TCAN4X5X_DISABLE_WAKE_MSK (BIT(31) | BIT(30))
|
||||||
|
|
||||||
#define TCAN4X5X_SW_RESET BIT(2)
|
#define TCAN4X5X_SW_RESET BIT(2)
|
||||||
|
|
||||||
#define TCAN4X5X_MCAN_CONFIGURED BIT(5)
|
#define TCAN4X5X_MCAN_CONFIGURED BIT(5)
|
||||||
|
@ -338,6 +340,14 @@ static int tcan4x5x_init(struct m_can_classdev *cdev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tcan4x5x_disable_wake(struct m_can_classdev *cdev)
|
||||||
|
{
|
||||||
|
struct tcan4x5x_priv *tcan4x5x = cdev->device_data;
|
||||||
|
|
||||||
|
return regmap_update_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG,
|
||||||
|
TCAN4X5X_DISABLE_WAKE_MSK, 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
static int tcan4x5x_parse_config(struct m_can_classdev *cdev)
|
static int tcan4x5x_parse_config(struct m_can_classdev *cdev)
|
||||||
{
|
{
|
||||||
struct tcan4x5x_priv *tcan4x5x = cdev->device_data;
|
struct tcan4x5x_priv *tcan4x5x = cdev->device_data;
|
||||||
|
@ -345,8 +355,10 @@ static int tcan4x5x_parse_config(struct m_can_classdev *cdev)
|
||||||
tcan4x5x->device_wake_gpio = devm_gpiod_get(cdev->dev, "device-wake",
|
tcan4x5x->device_wake_gpio = devm_gpiod_get(cdev->dev, "device-wake",
|
||||||
GPIOD_OUT_HIGH);
|
GPIOD_OUT_HIGH);
|
||||||
if (IS_ERR(tcan4x5x->device_wake_gpio)) {
|
if (IS_ERR(tcan4x5x->device_wake_gpio)) {
|
||||||
dev_err(cdev->dev, "device-wake gpio not defined\n");
|
if (PTR_ERR(tcan4x5x->power) == -EPROBE_DEFER)
|
||||||
return -EINVAL;
|
return -EPROBE_DEFER;
|
||||||
|
|
||||||
|
tcan4x5x_disable_wake(cdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
tcan4x5x->reset_gpio = devm_gpiod_get_optional(cdev->dev, "reset",
|
tcan4x5x->reset_gpio = devm_gpiod_get_optional(cdev->dev, "reset",
|
||||||
|
@ -354,6 +366,8 @@ static int tcan4x5x_parse_config(struct m_can_classdev *cdev)
|
||||||
if (IS_ERR(tcan4x5x->reset_gpio))
|
if (IS_ERR(tcan4x5x->reset_gpio))
|
||||||
tcan4x5x->reset_gpio = NULL;
|
tcan4x5x->reset_gpio = NULL;
|
||||||
|
|
||||||
|
usleep_range(700, 1000);
|
||||||
|
|
||||||
tcan4x5x->device_state_gpio = devm_gpiod_get_optional(cdev->dev,
|
tcan4x5x->device_state_gpio = devm_gpiod_get_optional(cdev->dev,
|
||||||
"device-state",
|
"device-state",
|
||||||
GPIOD_IN);
|
GPIOD_IN);
|
||||||
|
@ -428,10 +442,6 @@ static int tcan4x5x_can_probe(struct spi_device *spi)
|
||||||
|
|
||||||
spi_set_drvdata(spi, priv);
|
spi_set_drvdata(spi, priv);
|
||||||
|
|
||||||
ret = tcan4x5x_parse_config(mcan_class);
|
|
||||||
if (ret)
|
|
||||||
goto out_clk;
|
|
||||||
|
|
||||||
/* Configure the SPI bus */
|
/* Configure the SPI bus */
|
||||||
spi->bits_per_word = 32;
|
spi->bits_per_word = 32;
|
||||||
ret = spi_setup(spi);
|
ret = spi_setup(spi);
|
||||||
|
@ -441,6 +451,10 @@ static int tcan4x5x_can_probe(struct spi_device *spi)
|
||||||
priv->regmap = devm_regmap_init(&spi->dev, &tcan4x5x_bus,
|
priv->regmap = devm_regmap_init(&spi->dev, &tcan4x5x_bus,
|
||||||
&spi->dev, &tcan4x5x_regmap);
|
&spi->dev, &tcan4x5x_regmap);
|
||||||
|
|
||||||
|
ret = tcan4x5x_parse_config(mcan_class);
|
||||||
|
if (ret)
|
||||||
|
goto out_clk;
|
||||||
|
|
||||||
tcan4x5x_power_enable(priv->power, 1);
|
tcan4x5x_power_enable(priv->power, 1);
|
||||||
|
|
||||||
ret = m_can_class_register(mcan_class);
|
ret = m_can_class_register(mcan_class);
|
||||||
|
|
|
@ -608,7 +608,7 @@ static int kvaser_usb_leaf_simple_cmd_async(struct kvaser_usb_net_priv *priv,
|
||||||
struct kvaser_cmd *cmd;
|
struct kvaser_cmd *cmd;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
|
cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
|
||||||
if (!cmd)
|
if (!cmd)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -1140,7 +1140,7 @@ static int kvaser_usb_leaf_set_opt_mode(const struct kvaser_usb_net_priv *priv)
|
||||||
struct kvaser_cmd *cmd;
|
struct kvaser_cmd *cmd;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
|
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
|
||||||
if (!cmd)
|
if (!cmd)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -1206,7 +1206,7 @@ static int kvaser_usb_leaf_flush_queue(struct kvaser_usb_net_priv *priv)
|
||||||
struct kvaser_cmd *cmd;
|
struct kvaser_cmd *cmd;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
|
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
|
||||||
if (!cmd)
|
if (!cmd)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,8 @@ enum xcan_reg {
|
||||||
XCAN_TXMSG_BASE_OFFSET = 0x0100, /* TX Message Space */
|
XCAN_TXMSG_BASE_OFFSET = 0x0100, /* TX Message Space */
|
||||||
XCAN_RXMSG_BASE_OFFSET = 0x1100, /* RX Message Space */
|
XCAN_RXMSG_BASE_OFFSET = 0x1100, /* RX Message Space */
|
||||||
XCAN_RXMSG_2_BASE_OFFSET = 0x2100, /* RX Message Space */
|
XCAN_RXMSG_2_BASE_OFFSET = 0x2100, /* RX Message Space */
|
||||||
|
XCAN_AFR_2_MASK_OFFSET = 0x0A00, /* Acceptance Filter MASK */
|
||||||
|
XCAN_AFR_2_ID_OFFSET = 0x0A04, /* Acceptance Filter ID */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define XCAN_FRAME_ID_OFFSET(frame_base) ((frame_base) + 0x00)
|
#define XCAN_FRAME_ID_OFFSET(frame_base) ((frame_base) + 0x00)
|
||||||
|
@ -1809,6 +1811,11 @@ static int xcan_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
pm_runtime_put(&pdev->dev);
|
pm_runtime_put(&pdev->dev);
|
||||||
|
|
||||||
|
if (priv->devtype.flags & XCAN_FLAG_CANFD_2) {
|
||||||
|
priv->write_reg(priv, XCAN_AFR_2_ID_OFFSET, 0x00000000);
|
||||||
|
priv->write_reg(priv, XCAN_AFR_2_MASK_OFFSET, 0x00000000);
|
||||||
|
}
|
||||||
|
|
||||||
netdev_dbg(ndev, "reg_base=0x%p irq=%d clock=%d, tx buffers: actual %d, using %d\n",
|
netdev_dbg(ndev, "reg_base=0x%p irq=%d clock=%d, tx buffers: actual %d, using %d\n",
|
||||||
priv->reg_base, ndev->irq, priv->can.clock.freq,
|
priv->reg_base, ndev->irq, priv->can.clock.freq,
|
||||||
hw_tx_max, priv->tx_max);
|
hw_tx_max, priv->tx_max);
|
||||||
|
|
|
@ -423,9 +423,9 @@ static int j1939_sk_bind(struct socket *sock, struct sockaddr *uaddr, int len)
|
||||||
{
|
{
|
||||||
struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
|
struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
|
||||||
struct j1939_sock *jsk = j1939_sk(sock->sk);
|
struct j1939_sock *jsk = j1939_sk(sock->sk);
|
||||||
struct j1939_priv *priv = jsk->priv;
|
struct j1939_priv *priv;
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk;
|
||||||
struct net *net = sock_net(sk);
|
struct net *net;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
ret = j1939_sk_sanity_check(addr, len);
|
ret = j1939_sk_sanity_check(addr, len);
|
||||||
|
@ -434,6 +434,10 @@ static int j1939_sk_bind(struct socket *sock, struct sockaddr *uaddr, int len)
|
||||||
|
|
||||||
lock_sock(sock->sk);
|
lock_sock(sock->sk);
|
||||||
|
|
||||||
|
priv = jsk->priv;
|
||||||
|
sk = sock->sk;
|
||||||
|
net = sock_net(sk);
|
||||||
|
|
||||||
/* Already bound to an interface? */
|
/* Already bound to an interface? */
|
||||||
if (jsk->state & J1939_SOCK_BOUND) {
|
if (jsk->state & J1939_SOCK_BOUND) {
|
||||||
/* A re-bind() to a different interface is not
|
/* A re-bind() to a different interface is not
|
||||||
|
|
Загрузка…
Ссылка в новой задаче