Loading arch/arm/boot/dts/qcom/msm8996-cv2x.dtsi +1 −1 Original line number Diff line number Diff line Loading @@ -232,7 +232,7 @@ reg = <0>; spi-max-frequency = <9600000>; interrupt-parent = <&tlmm>; interrupts = <78 0>; interrupts = <78 2>; qcom,reset-gpio = <&tlmm 71 GPIO_ACTIVE_LOW>; qcom,clk-freq-mhz = <20000000>; qcom,max-can-channels = <2>; Loading drivers/net/can/spi/qti-can.c +63 −8 Original line number Diff line number Diff line Loading @@ -70,6 +70,7 @@ struct qti_can { bool can_fw_cmd_timeout_req; u32 rem_all_buffering_timeout_ms; u32 can_fw_cmd_timeout_ms; s64 time_diff; }; struct qti_can_netdev_privdata { Loading Loading @@ -118,6 +119,10 @@ struct spi_miso { /* TLV for MISO line */ #define CMD_BEGIN_BOOT_ROM_UPGRADE 0x99 #define CMD_BOOT_ROM_UPGRADE_DATA 0x9A #define CMD_END_BOOT_ROM_UPGRADE 0x9B #define CMD_END_FW_UPDATE_FILE 0x9C #define CMD_UPDATE_TIME_INFO 0x9D #define CMD_UPDATE_SUSPEND_EVENT 0x9E #define CMD_UPDATE_RESUME_EVENT 0x9F #define IOCTL_RELEASE_CAN_BUFFER (SIOCDEVPRIVATE + 0) #define IOCTL_ENABLE_BUFFERING (SIOCDEVPRIVATE + 1) Loading @@ -132,6 +137,7 @@ struct spi_miso { /* TLV for MISO line */ #define IOCTL_BEGIN_BOOT_ROM_UPGRADE (SIOCDEVPRIVATE + 11) #define IOCTL_BOOT_ROM_UPGRADE_DATA (SIOCDEVPRIVATE + 12) #define IOCTL_END_BOOT_ROM_UPGRADE (SIOCDEVPRIVATE + 13) #define IOCTL_END_FW_UPDATE_FILE (SIOCDEVPRIVATE + 14) #define IFR_DATA_OFFSET 0x100 struct can_fw_resp { Loading Loading @@ -163,7 +169,7 @@ struct can_add_filter_resp { struct can_receive_frame { u8 can_if; u32 ts; __le64 ts; u32 mid; u8 dlc; u8 data[8]; Loading @@ -178,6 +184,10 @@ struct can_config_bit_timing { u32 brp; } __packed; struct can_time_info { __le64 time; } __packed; static struct can_bittiming_const rh850_bittiming_const = { .name = "qti_can", .tseg1_min = 1, Loading Loading @@ -291,7 +301,7 @@ static void qti_can_receive_frame(struct qti_can *priv_data, return; } LOGDI("rcv frame %d %d %x %d %x %x %x %x %x %x %x %x\n", LOGDI("rcv frame %d %llu %x %d %x %x %x %x %x %x %x %x\n", frame->can_if, frame->ts, frame->mid, frame->dlc, frame->data[0], frame->data[1], frame->data[2], frame->data[3], frame->data[4], frame->data[5], frame->data[6], frame->data[7]); Loading @@ -301,7 +311,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(le32_to_cpu(frame->ts)); nsec = ms_to_ktime(le64_to_cpu(frame->ts) + priv_data->time_diff); skt = skb_hwtstamps(skb); skt->hwtstamp = nsec; LOGDI(" hwtstamp %lld\n", ktime_to_ms(skt->hwtstamp)); Loading Loading @@ -354,6 +365,8 @@ static int qti_can_process_response(struct qti_can *priv_data, struct spi_miso *resp, int length) { int ret = 0; u64 mstime; ktime_t ktime_now; LOGDI("<%x %2d [%d]\n", resp->cmd, resp->len, resp->seq); if (resp->cmd == CMD_CAN_RECEIVE_FRAME) { Loading Loading @@ -402,6 +415,12 @@ static int qti_can_process_response(struct qti_can *priv_data, ret |= (fw_resp->br_min & 0xFF) << 16; ret |= (fw_resp->maj & 0xF) << 8; ret |= (fw_resp->min & 0xFF); } else if (resp->cmd == CMD_UPDATE_TIME_INFO) { struct can_time_info *time_data = (struct can_time_info *)resp->data; ktime_now = ktime_get_boottime(); mstime = ktime_to_ms(ktime_now); priv_data->time_diff = mstime - (le64_to_cpu(time_data->time)); } if (resp->cmd == priv_data->wait_cmd) { Loading Loading @@ -445,8 +464,8 @@ static int qti_can_process_rx(struct qti_can *priv_data, char *rx_buf) } else { data = rx_buf + length_processed; resp = (struct spi_miso *)data; if (resp->cmd == 0) { /* special case. ignore cmd==0 */ if (resp->cmd == 0x00 || resp->cmd == 0xFF) { /* special case. ignore cmd==0x00, 0xFF */ length_processed += 1; continue; } Loading Loading @@ -563,6 +582,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 @@ -983,6 +1026,8 @@ static int qti_can_convert_ioctl_cmd_to_spi_cmd(int ioctl_cmd) return CMD_BOOT_ROM_UPGRADE_DATA; case IOCTL_END_BOOT_ROM_UPGRADE: return CMD_END_BOOT_ROM_UPGRADE; case IOCTL_END_FW_UPDATE_FILE: return CMD_END_FW_UPDATE_FILE; } return -EINVAL; } Loading Loading @@ -1119,6 +1164,7 @@ static int qti_can_netdev_do_ioctl(struct net_device *netdev, case IOCTL_BEGIN_BOOT_ROM_UPGRADE: case IOCTL_BOOT_ROM_UPGRADE_DATA: case IOCTL_END_BOOT_ROM_UPGRADE: case IOCTL_END_FW_UPDATE_FILE: ret = qti_can_do_blocking_ioctl(netdev, ifr, cmd); break; } Loading Loading @@ -1242,6 +1288,7 @@ static int qti_can_probe(struct spi_device *spi) int err, retry = 0, query_err = -1, i; struct qti_can *priv_data = NULL; struct device *dev; u32 irq_type; dev = &spi->dev; dev_info(dev, "qti_can_probe"); Loading Loading @@ -1318,7 +1365,7 @@ static int qti_can_probe(struct spi_device *spi) } priv_data->support_can_fd = of_property_read_bool(spi->dev.of_node, "support-can-fd"); "qcom,support-can-fd"); if (of_device_is_compatible(spi->dev.of_node, "qcom,nxp,mpc5746c")) qti_can_bittiming_const = flexcan_bittiming_const; Loading Loading @@ -1348,8 +1395,11 @@ static int qti_can_probe(struct spi_device *spi) } } irq_type = irq_get_trigger_type(spi->irq); if (irq_type == IRQ_TYPE_NONE) irq_type = IRQ_TYPE_EDGE_FALLING; err = request_threaded_irq(spi->irq, NULL, qti_can_irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, irq_type | IRQF_ONESHOT, "qti-can", priv_data); if (err) { LOGDE("Failed to request irq: %d", err); Loading Loading @@ -1415,6 +1465,10 @@ 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 = spi_get_drvdata(spi); u8 power_event = CMD_UPDATE_SUSPEND_EVENT; qti_can_notify_power_events(priv_data, power_event); enable_irq_wake(spi->irq); return 0; Loading @@ -1424,9 +1478,10 @@ 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); u8 power_event = CMD_UPDATE_RESUME_EVENT; disable_irq_wake(spi->irq); qti_can_rx_message(priv_data); qti_can_notify_power_events(priv_data, power_event); return 0; } Loading Loading
arch/arm/boot/dts/qcom/msm8996-cv2x.dtsi +1 −1 Original line number Diff line number Diff line Loading @@ -232,7 +232,7 @@ reg = <0>; spi-max-frequency = <9600000>; interrupt-parent = <&tlmm>; interrupts = <78 0>; interrupts = <78 2>; qcom,reset-gpio = <&tlmm 71 GPIO_ACTIVE_LOW>; qcom,clk-freq-mhz = <20000000>; qcom,max-can-channels = <2>; Loading
drivers/net/can/spi/qti-can.c +63 −8 Original line number Diff line number Diff line Loading @@ -70,6 +70,7 @@ struct qti_can { bool can_fw_cmd_timeout_req; u32 rem_all_buffering_timeout_ms; u32 can_fw_cmd_timeout_ms; s64 time_diff; }; struct qti_can_netdev_privdata { Loading Loading @@ -118,6 +119,10 @@ struct spi_miso { /* TLV for MISO line */ #define CMD_BEGIN_BOOT_ROM_UPGRADE 0x99 #define CMD_BOOT_ROM_UPGRADE_DATA 0x9A #define CMD_END_BOOT_ROM_UPGRADE 0x9B #define CMD_END_FW_UPDATE_FILE 0x9C #define CMD_UPDATE_TIME_INFO 0x9D #define CMD_UPDATE_SUSPEND_EVENT 0x9E #define CMD_UPDATE_RESUME_EVENT 0x9F #define IOCTL_RELEASE_CAN_BUFFER (SIOCDEVPRIVATE + 0) #define IOCTL_ENABLE_BUFFERING (SIOCDEVPRIVATE + 1) Loading @@ -132,6 +137,7 @@ struct spi_miso { /* TLV for MISO line */ #define IOCTL_BEGIN_BOOT_ROM_UPGRADE (SIOCDEVPRIVATE + 11) #define IOCTL_BOOT_ROM_UPGRADE_DATA (SIOCDEVPRIVATE + 12) #define IOCTL_END_BOOT_ROM_UPGRADE (SIOCDEVPRIVATE + 13) #define IOCTL_END_FW_UPDATE_FILE (SIOCDEVPRIVATE + 14) #define IFR_DATA_OFFSET 0x100 struct can_fw_resp { Loading Loading @@ -163,7 +169,7 @@ struct can_add_filter_resp { struct can_receive_frame { u8 can_if; u32 ts; __le64 ts; u32 mid; u8 dlc; u8 data[8]; Loading @@ -178,6 +184,10 @@ struct can_config_bit_timing { u32 brp; } __packed; struct can_time_info { __le64 time; } __packed; static struct can_bittiming_const rh850_bittiming_const = { .name = "qti_can", .tseg1_min = 1, Loading Loading @@ -291,7 +301,7 @@ static void qti_can_receive_frame(struct qti_can *priv_data, return; } LOGDI("rcv frame %d %d %x %d %x %x %x %x %x %x %x %x\n", LOGDI("rcv frame %d %llu %x %d %x %x %x %x %x %x %x %x\n", frame->can_if, frame->ts, frame->mid, frame->dlc, frame->data[0], frame->data[1], frame->data[2], frame->data[3], frame->data[4], frame->data[5], frame->data[6], frame->data[7]); Loading @@ -301,7 +311,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(le32_to_cpu(frame->ts)); nsec = ms_to_ktime(le64_to_cpu(frame->ts) + priv_data->time_diff); skt = skb_hwtstamps(skb); skt->hwtstamp = nsec; LOGDI(" hwtstamp %lld\n", ktime_to_ms(skt->hwtstamp)); Loading Loading @@ -354,6 +365,8 @@ static int qti_can_process_response(struct qti_can *priv_data, struct spi_miso *resp, int length) { int ret = 0; u64 mstime; ktime_t ktime_now; LOGDI("<%x %2d [%d]\n", resp->cmd, resp->len, resp->seq); if (resp->cmd == CMD_CAN_RECEIVE_FRAME) { Loading Loading @@ -402,6 +415,12 @@ static int qti_can_process_response(struct qti_can *priv_data, ret |= (fw_resp->br_min & 0xFF) << 16; ret |= (fw_resp->maj & 0xF) << 8; ret |= (fw_resp->min & 0xFF); } else if (resp->cmd == CMD_UPDATE_TIME_INFO) { struct can_time_info *time_data = (struct can_time_info *)resp->data; ktime_now = ktime_get_boottime(); mstime = ktime_to_ms(ktime_now); priv_data->time_diff = mstime - (le64_to_cpu(time_data->time)); } if (resp->cmd == priv_data->wait_cmd) { Loading Loading @@ -445,8 +464,8 @@ static int qti_can_process_rx(struct qti_can *priv_data, char *rx_buf) } else { data = rx_buf + length_processed; resp = (struct spi_miso *)data; if (resp->cmd == 0) { /* special case. ignore cmd==0 */ if (resp->cmd == 0x00 || resp->cmd == 0xFF) { /* special case. ignore cmd==0x00, 0xFF */ length_processed += 1; continue; } Loading Loading @@ -563,6 +582,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 @@ -983,6 +1026,8 @@ static int qti_can_convert_ioctl_cmd_to_spi_cmd(int ioctl_cmd) return CMD_BOOT_ROM_UPGRADE_DATA; case IOCTL_END_BOOT_ROM_UPGRADE: return CMD_END_BOOT_ROM_UPGRADE; case IOCTL_END_FW_UPDATE_FILE: return CMD_END_FW_UPDATE_FILE; } return -EINVAL; } Loading Loading @@ -1119,6 +1164,7 @@ static int qti_can_netdev_do_ioctl(struct net_device *netdev, case IOCTL_BEGIN_BOOT_ROM_UPGRADE: case IOCTL_BOOT_ROM_UPGRADE_DATA: case IOCTL_END_BOOT_ROM_UPGRADE: case IOCTL_END_FW_UPDATE_FILE: ret = qti_can_do_blocking_ioctl(netdev, ifr, cmd); break; } Loading Loading @@ -1242,6 +1288,7 @@ static int qti_can_probe(struct spi_device *spi) int err, retry = 0, query_err = -1, i; struct qti_can *priv_data = NULL; struct device *dev; u32 irq_type; dev = &spi->dev; dev_info(dev, "qti_can_probe"); Loading Loading @@ -1318,7 +1365,7 @@ static int qti_can_probe(struct spi_device *spi) } priv_data->support_can_fd = of_property_read_bool(spi->dev.of_node, "support-can-fd"); "qcom,support-can-fd"); if (of_device_is_compatible(spi->dev.of_node, "qcom,nxp,mpc5746c")) qti_can_bittiming_const = flexcan_bittiming_const; Loading Loading @@ -1348,8 +1395,11 @@ static int qti_can_probe(struct spi_device *spi) } } irq_type = irq_get_trigger_type(spi->irq); if (irq_type == IRQ_TYPE_NONE) irq_type = IRQ_TYPE_EDGE_FALLING; err = request_threaded_irq(spi->irq, NULL, qti_can_irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, irq_type | IRQF_ONESHOT, "qti-can", priv_data); if (err) { LOGDE("Failed to request irq: %d", err); Loading Loading @@ -1415,6 +1465,10 @@ 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 = spi_get_drvdata(spi); u8 power_event = CMD_UPDATE_SUSPEND_EVENT; qti_can_notify_power_events(priv_data, power_event); enable_irq_wake(spi->irq); return 0; Loading @@ -1424,9 +1478,10 @@ 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); u8 power_event = CMD_UPDATE_RESUME_EVENT; disable_irq_wake(spi->irq); qti_can_rx_message(priv_data); qti_can_notify_power_events(priv_data, power_event); return 0; } Loading