Loading drivers/net/can/spi/qti-can.c +116 −12 Original line number Diff line number Diff line Loading @@ -126,6 +126,8 @@ struct spi_miso { /* TLV for MISO line */ #define CMD_END_BOOT_ROM_UPGRADE 0x9B #define CMD_END_FW_UPDATE_FILE 0x9C #define CMD_UPDATE_TIME_INFO 0x9D #define CMD_SUSPEND_EVENT 0x9E #define CMD_RESUME_EVENT 0x9F #define IOCTL_RELEASE_CAN_BUFFER (SIOCDEVPRIVATE + 0) #define IOCTL_ENABLE_BUFFERING (SIOCDEVPRIVATE + 1) Loading Loading @@ -172,8 +174,8 @@ struct can_add_filter_resp { struct can_receive_frame { u8 can_if; u64 ts; u32 mid; __le64 ts; __le32 mid; u8 dlc; u8 data[8]; } __packed; Loading @@ -188,7 +190,7 @@ struct can_config_bit_timing { } __packed; struct can_time_info { u64 time; __le64 time; } __packed; static struct can_bittiming_const rh850_bittiming_const = { Loading Loading @@ -231,7 +233,7 @@ static struct can_bittiming_const qti_can_data_bittiming_const = { struct vehicle_property { int id; u64 ts; __le64 ts; int zone; int val_type; u32 data_len; Loading Loading @@ -333,7 +335,8 @@ static void qti_can_receive_frame(struct qti_can *priv_data, for (i = 0; i < cf->can_dlc; i++) cf->data[i] = frame->data[i]; nsec = ms_to_ktime(le64_to_cpu(frame->ts) + priv_data->time_diff); nsec = ms_to_ktime(le64_to_cpu(frame->ts) + priv_data->time_diff); skt = skb_hwtstamps(skb); skt->hwtstamp = nsec; skb->tstamp = nsec; Loading Loading @@ -620,6 +623,30 @@ static int qti_can_query_firmware_version(struct qti_can *priv_data) return ret; } static int qti_can_notify_power_events(struct qti_can *priv_data, u8 event_type) { char *tx_buf, *rx_buf; int ret; struct spi_mosi *req; mutex_lock(&priv_data->spi_lock); tx_buf = priv_data->tx_buf; rx_buf = priv_data->rx_buf; memset(tx_buf, 0, XFER_BUFFER_SIZE); memset(rx_buf, 0, XFER_BUFFER_SIZE); priv_data->xfer_length = XFER_BUFFER_SIZE; req = (struct spi_mosi *)tx_buf; req->cmd = event_type; req->len = 0; req->seq = atomic_inc_return(&priv_data->msg_seq); ret = qti_can_do_spi_transaction(priv_data); mutex_unlock(&priv_data->spi_lock); return ret; } static int qti_can_set_bitrate(struct net_device *netdev) { char *tx_buf, *rx_buf; Loading Loading @@ -1046,6 +1073,40 @@ static int qti_can_convert_ioctl_cmd_to_spi_cmd(int ioctl_cmd) return -EINVAL; } static int qti_can_end_fwupgrade_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) { int spi_cmd, ret; struct qti_can *priv_data; struct qti_can_netdev_privdata *netdev_priv_data; struct spi_device *spi; int len = 0; u8 *data = NULL; netdev_priv_data = netdev_priv(netdev); priv_data = netdev_priv_data->qti_can; spi = priv_data->spidev; spi_cmd = qti_can_convert_ioctl_cmd_to_spi_cmd(cmd); LOGDI("%s spi_cmd %x\n", __func__, spi_cmd); if (spi_cmd < 0) { LOGDE("%s wrong command %d\n", __func__, cmd); return spi_cmd; } if (!ifr) return -EINVAL; mutex_lock(&priv_data->spi_lock); LOGDI("%s len %d\n", __func__, len); ret = qti_can_send_spi_locked(priv_data, spi_cmd, len, data); mutex_unlock(&priv_data->spi_lock); return ret; } static int qti_can_do_blocking_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) { Loading Loading @@ -1088,6 +1149,11 @@ static int qti_can_do_blocking_ioctl(struct net_device *netdev, return -EFAULT; } if (ioctl_data->len < 0) { LOGDE("ioctl_data->len is: %d\n", ioctl_data->len); return -EINVAL; } /* Regular NULL check will fail here as ioctl_data is at * some offset */ Loading @@ -1098,6 +1164,11 @@ static int qti_can_do_blocking_ioctl(struct net_device *netdev, } LOGDI("%s len %d\n", __func__, len); if (len > 64 || len < 0) { LOGDE("len value[%d] is not correct!!\n", len); return -EINVAL; } priv_data->wait_cmd = spi_cmd; priv_data->cmd_result = -1; reinit_completion(&priv_data->response_completion); Loading Loading @@ -1171,10 +1242,12 @@ static int qti_can_netdev_do_ioctl(struct net_device *netdev, qti_can_frame_filter(netdev, ifr, cmd); ret = 0; break; case IOCTL_END_FIRMWARE_UPGRADE: ret = qti_can_end_fwupgrade_ioctl(netdev, ifr, cmd); break; case IOCTL_GET_FW_BR_VERSION: case IOCTL_BEGIN_FIRMWARE_UPGRADE: case IOCTL_FIRMWARE_UPGRADE_DATA: case IOCTL_END_FIRMWARE_UPGRADE: case IOCTL_BEGIN_BOOT_ROM_UPGRADE: case IOCTL_BOOT_ROM_UPGRADE_DATA: case IOCTL_END_BOOT_ROM_UPGRADE: Loading Loading @@ -1380,6 +1453,8 @@ static int qti_can_probe(struct spi_device *spi) gpio_direction_output(priv_data->reset, 1); /* wait for controller to come up after reset */ msleep(priv_data->reset_delay_msec); } else { msleep(priv_data->reset_delay_msec); } priv_data->support_can_fd = of_property_read_bool(spi->dev.of_node, Loading Loading @@ -1486,19 +1561,47 @@ static int qti_can_remove(struct spi_device *spi) static int qti_can_suspend(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct qti_can *priv_data = NULL; u8 power_event = CMD_SUSPEND_EVENT; int ret = 0; if (spi) { priv_data = spi_get_drvdata(spi); enable_irq_wake(spi->irq); return 0; } else { ret = -1; } if (priv_data && !(ret < 0)) ret = qti_can_notify_power_events(priv_data, power_event); return ret; } static int qti_can_resume(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct qti_can *priv_data = spi_get_drvdata(spi); struct qti_can *priv_data = NULL; int ret = 0; u8 power_event = CMD_RESUME_EVENT; if (spi) { priv_data = spi_get_drvdata(spi); disable_irq_wake(spi->irq); if (priv_data) qti_can_rx_message(priv_data); return 0; else ret = -1; } else { ret = -1; } if (priv_data && !(ret < 0)) ret = qti_can_notify_power_events(priv_data, power_event); return ret; } static const struct dev_pm_ops qti_can_dev_pm_ops = { Loading @@ -1515,6 +1618,7 @@ static struct spi_driver qti_can_driver = { #ifdef CONFIG_PM .pm = &qti_can_dev_pm_ops, #endif .probe_type = PROBE_PREFER_ASYNCHRONOUS, }, .probe = qti_can_probe, .remove = qti_can_remove, Loading Loading
drivers/net/can/spi/qti-can.c +116 −12 Original line number Diff line number Diff line Loading @@ -126,6 +126,8 @@ struct spi_miso { /* TLV for MISO line */ #define CMD_END_BOOT_ROM_UPGRADE 0x9B #define CMD_END_FW_UPDATE_FILE 0x9C #define CMD_UPDATE_TIME_INFO 0x9D #define CMD_SUSPEND_EVENT 0x9E #define CMD_RESUME_EVENT 0x9F #define IOCTL_RELEASE_CAN_BUFFER (SIOCDEVPRIVATE + 0) #define IOCTL_ENABLE_BUFFERING (SIOCDEVPRIVATE + 1) Loading Loading @@ -172,8 +174,8 @@ struct can_add_filter_resp { struct can_receive_frame { u8 can_if; u64 ts; u32 mid; __le64 ts; __le32 mid; u8 dlc; u8 data[8]; } __packed; Loading @@ -188,7 +190,7 @@ struct can_config_bit_timing { } __packed; struct can_time_info { u64 time; __le64 time; } __packed; static struct can_bittiming_const rh850_bittiming_const = { Loading Loading @@ -231,7 +233,7 @@ static struct can_bittiming_const qti_can_data_bittiming_const = { struct vehicle_property { int id; u64 ts; __le64 ts; int zone; int val_type; u32 data_len; Loading Loading @@ -333,7 +335,8 @@ static void qti_can_receive_frame(struct qti_can *priv_data, for (i = 0; i < cf->can_dlc; i++) cf->data[i] = frame->data[i]; nsec = ms_to_ktime(le64_to_cpu(frame->ts) + priv_data->time_diff); nsec = ms_to_ktime(le64_to_cpu(frame->ts) + priv_data->time_diff); skt = skb_hwtstamps(skb); skt->hwtstamp = nsec; skb->tstamp = nsec; Loading Loading @@ -620,6 +623,30 @@ static int qti_can_query_firmware_version(struct qti_can *priv_data) return ret; } static int qti_can_notify_power_events(struct qti_can *priv_data, u8 event_type) { char *tx_buf, *rx_buf; int ret; struct spi_mosi *req; mutex_lock(&priv_data->spi_lock); tx_buf = priv_data->tx_buf; rx_buf = priv_data->rx_buf; memset(tx_buf, 0, XFER_BUFFER_SIZE); memset(rx_buf, 0, XFER_BUFFER_SIZE); priv_data->xfer_length = XFER_BUFFER_SIZE; req = (struct spi_mosi *)tx_buf; req->cmd = event_type; req->len = 0; req->seq = atomic_inc_return(&priv_data->msg_seq); ret = qti_can_do_spi_transaction(priv_data); mutex_unlock(&priv_data->spi_lock); return ret; } static int qti_can_set_bitrate(struct net_device *netdev) { char *tx_buf, *rx_buf; Loading Loading @@ -1046,6 +1073,40 @@ static int qti_can_convert_ioctl_cmd_to_spi_cmd(int ioctl_cmd) return -EINVAL; } static int qti_can_end_fwupgrade_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) { int spi_cmd, ret; struct qti_can *priv_data; struct qti_can_netdev_privdata *netdev_priv_data; struct spi_device *spi; int len = 0; u8 *data = NULL; netdev_priv_data = netdev_priv(netdev); priv_data = netdev_priv_data->qti_can; spi = priv_data->spidev; spi_cmd = qti_can_convert_ioctl_cmd_to_spi_cmd(cmd); LOGDI("%s spi_cmd %x\n", __func__, spi_cmd); if (spi_cmd < 0) { LOGDE("%s wrong command %d\n", __func__, cmd); return spi_cmd; } if (!ifr) return -EINVAL; mutex_lock(&priv_data->spi_lock); LOGDI("%s len %d\n", __func__, len); ret = qti_can_send_spi_locked(priv_data, spi_cmd, len, data); mutex_unlock(&priv_data->spi_lock); return ret; } static int qti_can_do_blocking_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) { Loading Loading @@ -1088,6 +1149,11 @@ static int qti_can_do_blocking_ioctl(struct net_device *netdev, return -EFAULT; } if (ioctl_data->len < 0) { LOGDE("ioctl_data->len is: %d\n", ioctl_data->len); return -EINVAL; } /* Regular NULL check will fail here as ioctl_data is at * some offset */ Loading @@ -1098,6 +1164,11 @@ static int qti_can_do_blocking_ioctl(struct net_device *netdev, } LOGDI("%s len %d\n", __func__, len); if (len > 64 || len < 0) { LOGDE("len value[%d] is not correct!!\n", len); return -EINVAL; } priv_data->wait_cmd = spi_cmd; priv_data->cmd_result = -1; reinit_completion(&priv_data->response_completion); Loading Loading @@ -1171,10 +1242,12 @@ static int qti_can_netdev_do_ioctl(struct net_device *netdev, qti_can_frame_filter(netdev, ifr, cmd); ret = 0; break; case IOCTL_END_FIRMWARE_UPGRADE: ret = qti_can_end_fwupgrade_ioctl(netdev, ifr, cmd); break; case IOCTL_GET_FW_BR_VERSION: case IOCTL_BEGIN_FIRMWARE_UPGRADE: case IOCTL_FIRMWARE_UPGRADE_DATA: case IOCTL_END_FIRMWARE_UPGRADE: case IOCTL_BEGIN_BOOT_ROM_UPGRADE: case IOCTL_BOOT_ROM_UPGRADE_DATA: case IOCTL_END_BOOT_ROM_UPGRADE: Loading Loading @@ -1380,6 +1453,8 @@ static int qti_can_probe(struct spi_device *spi) gpio_direction_output(priv_data->reset, 1); /* wait for controller to come up after reset */ msleep(priv_data->reset_delay_msec); } else { msleep(priv_data->reset_delay_msec); } priv_data->support_can_fd = of_property_read_bool(spi->dev.of_node, Loading Loading @@ -1486,19 +1561,47 @@ static int qti_can_remove(struct spi_device *spi) static int qti_can_suspend(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct qti_can *priv_data = NULL; u8 power_event = CMD_SUSPEND_EVENT; int ret = 0; if (spi) { priv_data = spi_get_drvdata(spi); enable_irq_wake(spi->irq); return 0; } else { ret = -1; } if (priv_data && !(ret < 0)) ret = qti_can_notify_power_events(priv_data, power_event); return ret; } static int qti_can_resume(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct qti_can *priv_data = spi_get_drvdata(spi); struct qti_can *priv_data = NULL; int ret = 0; u8 power_event = CMD_RESUME_EVENT; if (spi) { priv_data = spi_get_drvdata(spi); disable_irq_wake(spi->irq); if (priv_data) qti_can_rx_message(priv_data); return 0; else ret = -1; } else { ret = -1; } if (priv_data && !(ret < 0)) ret = qti_can_notify_power_events(priv_data, power_event); return ret; } static const struct dev_pm_ops qti_can_dev_pm_ops = { Loading @@ -1515,6 +1618,7 @@ static struct spi_driver qti_can_driver = { #ifdef CONFIG_PM .pm = &qti_can_dev_pm_ops, #endif .probe_type = PROBE_PREFER_ASYNCHRONOUS, }, .probe = qti_can_probe, .remove = qti_can_remove, Loading