예제 #1
0
파일: c_can.c 프로젝트: 03199618/linux
int c_can_power_up(struct net_device *dev)
{
	u32 val;
	unsigned long time_out;
	struct c_can_priv *priv = netdev_priv(dev);

	if (!(dev->flags & IFF_UP))
		return 0;

	WARN_ON(priv->type != BOSCH_D_CAN);

	c_can_pm_runtime_get_sync(priv);
	c_can_reset_ram(priv, true);

	/* Clear PDR and INIT bits */
	val = priv->read_reg(priv, C_CAN_CTRL_EX_REG);
	val &= ~CONTROL_EX_PDR;
	priv->write_reg(priv, C_CAN_CTRL_EX_REG, val);
	val = priv->read_reg(priv, C_CAN_CTRL_REG);
	val &= ~CONTROL_INIT;
	priv->write_reg(priv, C_CAN_CTRL_REG, val);

	/* Wait for the PDA bit to get clear */
	time_out = jiffies + msecs_to_jiffies(INIT_WAIT_MS);
	while ((priv->read_reg(priv, C_CAN_STS_REG) & STATUS_PDA) &&
				time_after(time_out, jiffies))
		cpu_relax();

	if (time_after(jiffies, time_out))
		return -ETIMEDOUT;

	c_can_start(dev);

	return 0;
}
예제 #2
0
static int c_can_get_berr_counter(const struct net_device *dev,
				  struct can_berr_counter *bec)
{
	struct c_can_priv *priv = netdev_priv(dev);
	int err;

	c_can_pm_runtime_get_sync(priv);
	err = __c_can_get_berr_counter(dev, bec);
	c_can_pm_runtime_put_sync(priv);

	return err;
}
예제 #3
0
파일: c_can.c 프로젝트: 03199618/linux
static int c_can_get_berr_counter(const struct net_device *dev,
					struct can_berr_counter *bec)
{
	unsigned int reg_err_counter;
	struct c_can_priv *priv = netdev_priv(dev);

	c_can_pm_runtime_get_sync(priv);

	reg_err_counter = priv->read_reg(priv, C_CAN_ERR_CNT_REG);
	bec->rxerr = (reg_err_counter & ERR_CNT_REC_MASK) >>
				ERR_CNT_REC_SHIFT;
	bec->txerr = reg_err_counter & ERR_CNT_TEC_MASK;

	c_can_pm_runtime_put_sync(priv);

	return 0;
}
예제 #4
0
파일: c_can.c 프로젝트: Flipkart/linux
static int c_can_open(struct net_device *dev)
{
	int err;
	struct c_can_priv *priv = netdev_priv(dev);

	c_can_pm_runtime_get_sync(priv);
	c_can_reset_ram(priv, true);

	/* open the can device */
	err = open_candev(dev);
	if (err) {
		netdev_err(dev, "failed to open can device\n");
		goto exit_open_fail;
	}

	/* register interrupt handler */
	err = request_irq(dev->irq, &c_can_isr, IRQF_SHARED, dev->name,
				dev);
	if (err < 0) {
		netdev_err(dev, "failed to request interrupt\n");
		goto exit_irq_fail;
	}

	/* start the c_can controller */
	err = c_can_start(dev);
	if (err)
		goto exit_start_fail;

	can_led_event(dev, CAN_LED_EVENT_OPEN);

	napi_enable(&priv->napi);
	/* enable status change, error and module interrupts */
	c_can_irq_control(priv, true);
	netif_start_queue(dev);

	return 0;

exit_start_fail:
	free_irq(dev->irq, dev);
exit_irq_fail:
	close_candev(dev);
exit_open_fail:
	c_can_reset_ram(priv, false);
	c_can_pm_runtime_put_sync(priv);
	return err;
}