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; }
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; }
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; }
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; }