usb: usb_bam: Add support for multi USB BAMs
This change add the support for activating more than
one usb core in the system in bam to bam mode.
Potentially, we can have up to three usb cores in
the system: HSUSB, HSIC and DWC3.
This change simplify the USB BAM driver design, such that
we can easily define bam to bam paths for more than one usb
core concurrently with flexible peer BAMs configuration.
Change-Id: Ie5acb68f29e30cb6c14d2afd957ac8e21cc7beba
Signed-off-by: Shimrit Malichi <smalichi@codeaurora.org>
diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index df88caa..02c2871 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -172,115 +172,90 @@
If SSUSB_BAM is used, "ssusb" should be present.
If HSUSB_BAM is used, "hsusb" should be present.
If HSIC_BAM is used, "hsic" should be present.
-- qcom,usb-active-bam: active BAM type. Can be one of
- 0 - SSUSB_BAM
- 1 - HSUSB_BAM
- 2 - HSIC_BAM
-- qcom,usb-total-bam-num: total number of BAMs that are supported
- qcom,usb-bam-num-pipes: max number of pipes that can be used
- qcom,usb-base-address: physical base address of the BAM
A number of USB BAM pipe parameters are represented as sub-nodes:
Subnode Required:
-- label: a string describing the pipe's direction and BAM instance under use
-- qcom,usb-bam-type: BAM type. Can be one of
- 0 - SSUSB_BAM
- 1 - HSUSB_BAM
- 2 - HSIC_BAM
+- label: a string describing uniquely the usb bam pipe. The string can be
+ constracted as follows: <core>-<peer>-<direction>-<pipe num>.
+ core options: hsusb, ssusb/dwc3, hsic
+ peer options: qdss, ipa, a2
+ direction options: in (from peer to usb), out (from usb to peer)
+ pipe num options: 0..127
- qcom,usb-bam-mem-type: Type of memory used by this PIPE. Can be one of
0 - Uses SPS's dedicated pipe memory
1 - USB's private memory residing @ 'qcom,usb-base-address'
2 - System RAM allocated by driver
-- qcom,src-bam-physical-address: source BAM physical address
-- qcom,src-bam-pipe-index: source BAM pipe index
-- qcom,dst-bam-physical-address: destination BAM physical address
-- qcom,dst-bam-pipe-index: destination BAM pipe index
-- qcom,data-fifo-offset: data fifo offset address
+- qcom,bam-type: BAM type can be one of
+ 0 - SSUSB_BAM
+ 1 - HSUSB_BAM
+ 2 - HSIC_BAM
+- qcom,dir: pipe direction
+ 0 - from usb (out)
+ 1 - to usb (in)
+- qcom,pipe-num: pipe number
+- qcom,peer-bam: peer BAM can be one of
+ 0 - A2_P_BAM
+ 1 - QDSS_P_BAM
+ 2 - IPA_P_BAM
- qcom,data-fifo-size: data fifo size
-- qcom,descriptor-fifo-offset: descriptor fifo offset address
- qcom,descriptor-fifo-size: descriptor fifo size
Optional Properties for Subnode:
- qcom,reset-bam-on-connect: If present then BAM is RESET before connecting
pipe. This may be required if BAM peripheral is also reset before connect.
+- qcom,dst-bam-physical-address: destination BAM physical address
+- qcom,dst-bam-pipe-index: destination BAM pipe index
+- qcom,src-bam-physical-address: source BAM physical address
+- qcom,src-bam-pipe-index: source BAM pipe index
+- qcom,data-fifo-offset: data fifo offset address
+- qcom,descriptor-fifo-offset: descriptor fifo offset address
Optional properties :
- qcom,ignore-core-reset-ack: If present then BAM ignores ACK from USB core
while performing PIPE RESET
- qcom,disable-clk-gating: If present then disable BAM clock gating.
-
Example USB BAM controller device node:
- qcom,usbbam@f9304000 {
+ qcom,usbbam@f9a44000 {
compatible = "qcom,usb-bam-msm";
- reg = <0xf9304000 0x5000>,
- <0xf9a44000 0x11000>,
- <0xf92f880c 0x4>;
- reg-names = "ssusb", "hsusb", "qscratch_ram1_reg";
- interrupts = <0 132 0 0 135 0>;
- interrupt-names = "ssusb", "hsusb";
- qcom,usb-active-bam = <0>;
- qcom,usb-total-bam-num = <2>;
+ reg = <0xf9a44000 0x11000>;
+ reg-names = "hsusb";
+ interrupts = <0 135 0>;
+ interrupt-names = "hsusb";
qcom,usb-bam-num-pipes = <16>;
- qcom,usb-base-address = <0xf9200000>;
qcom,ignore-core-reset-ack;
+ qcom,disable-clk-gating;
+ qcom,pipe0 {
+ label = "hsusb-ipa-out-0";
+ qcom,usb-bam-mem-type = <0>;
+ qcom,bam-type = <1>;
+ qcom,dir = <0>;
+ qcom,pipe-num = <0>;
+ qcom,peer-bam = <2>;
+ qcom,src-bam-physical-address = <0xf9a44000>;
+ qcom,src-bam-pipe-index = <1>;
+ qcom,data-fifo-offset = <0x2200>;
+ qcom,data-fifo-size = <0x1e00>;
+ qcom,descriptor-fifo-offset = <0x2100>;
+ qcom,descriptor-fifo-size = <0x100>;
+ };
qcom,pipe1 {
- label = "usb-to-peri-qdss-dwc3";
- qcom,usb-bam-type = <0>;
- qcom,usb-bam-mem-type = <1>;
- qcom,src-bam-physical-address = <0>;
- qcom,src-bam-pipe-index = <0>;
- qcom,dst-bam-physical-address = <0>;
- qcom,dst-bam-pipe-index = <0>;
- qcom,data-fifo-offset = <0>;
- qcom,data-fifo-size = <0>;
- qcom,descriptor-fifo-offset = <0>;
- qcom,descriptor-fifo-size = <0>;
- };
-
- qcom,pipe2 {
- label = "peri-to-usb-qdss-dwc3";
- qcom,usb-bam-type = <0>;
- qcom,usb-bam-mem-type = <1>;
- qcom,src-bam-physical-address = <0xfc37C000>;
- qcom,src-bam-pipe-index = <0>;
- qcom,dst-bam-physical-address = <0xf9304000>;
- qcom,dst-bam-pipe-index = <2>;
- qcom,data-fifo-offset = <0xf0000>;
- qcom,data-fifo-size = <0x4000>;
- qcom,descriptor-fifo-offset = <0xf4000>;
- qcom,descriptor-fifo-size = <0x1400>;
- qcom,reset-bam-on-connect;
- };
-
- qcom,pipe3 {
- label = "usb-to-peri-qdss-hsusb";
- qcom,usb-bam-type = <1>;
- qcom,usb-bam-mem-type = <1>;
- qcom,src-bam-physical-address = <0>;
- qcom,src-bam-pipe-index = <0>;
- qcom,dst-bam-physical-address = <0>;
- qcom,dst-bam-pipe-index = <0>;
- qcom,data-fifo-offset = <0>;
- qcom,data-fifo-size = <0>;
- qcom,descriptor-fifo-offset = <0>;
- qcom,descriptor-fifo-size = <0>;
- };
-
- qcom,pipe4 {
- label = "peri-to-usb-qdss-hsusb";
- qcom,usb-bam-type = <1>;
- qcom,usb-bam-mem-type = <1>;
- qcom,src-bam-physical-address = <0xfc37c000>;
- qcom,src-bam-pipe-index = <0>;
+ label = "hsusb-ipa-in-0";
+ qcom,usb-bam-mem-type = <0>;
+ qcom,bam-type = <1>;
+ qcom,dir = <1>;
+ qcom,pipe-num = <0>;
+ qcom,peer-bam = <2>;
qcom,dst-bam-physical-address = <0xf9a44000>;
- qcom,dst-bam-pipe-index = <2>;
- qcom,data-fifo-offset = <0xf4000>;
- qcom,data-fifo-size = <0x1000>;
- qcom,descriptor-fifo-offset = <0xf5000>;
- qcom,descriptor-fifo-size = <0x400>;
+ qcom,dst-bam-pipe-index = <0>;
+ qcom,data-fifo-offset = <0x300>;
+ qcom,data-fifo-size = <0x1e00>;
+ qcom,descriptor-fifo-offset = <0>;
+ qcom,descriptor-fifo-size = <0x300>;
};
};
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 2a5347e..0377dca 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -1186,31 +1186,18 @@
reg-names = "ssusb", "hsusb", "qscratch_ram1_reg";
interrupts = <0 132 0 0 135 0>;
interrupt-names = "ssusb", "hsusb";
- qcom,usb-active-bam = <0>;
- qcom,usb-total-bam-num = <2>;
qcom,usb-bam-num-pipes = <16>;
qcom,usb-base-address = <0xf9200000>;
qcom,ignore-core-reset-ack;
qcom,disable-clk-gating;
- qcom,pipe1 {
- label = "usb-to-peri-qdss-dwc3";
- qcom,usb-bam-type = <0>;
+ qcom,pipe0 {
+ label = "ssusb-qdss-in-0";
qcom,usb-bam-mem-type = <1>;
- qcom,src-bam-physical-address = <0>;
- qcom,src-bam-pipe-index = <0>;
- qcom,dst-bam-physical-address = <0>;
- qcom,dst-bam-pipe-index = <0>;
- qcom,data-fifo-offset = <0>;
- qcom,data-fifo-size = <0>;
- qcom,descriptor-fifo-offset = <0>;
- qcom,descriptor-fifo-size = <0>;
- };
-
- qcom,pipe2 {
- label = "peri-to-usb-qdss-dwc3";
- qcom,usb-bam-type = <0>;
- qcom,usb-bam-mem-type = <1>;
+ qcom,bam-type = <0>;
+ qcom,dir = <1>;
+ qcom,pipe-num = <0>;
+ qcom,peer-bam = <1>;
qcom,src-bam-physical-address = <0xfc37C000>;
qcom,src-bam-pipe-index = <0>;
qcom,dst-bam-physical-address = <0xf9304000>;
@@ -1222,24 +1209,13 @@
qcom,reset-bam-on-connect;
};
- qcom,pipe3 {
- label = "usb-to-peri-qdss-hsusb";
- qcom,usb-bam-type = <1>;
+ qcom,pipe1 {
+ label = "hsusb-qdss-in-0";
qcom,usb-bam-mem-type = <1>;
- qcom,src-bam-physical-address = <0>;
- qcom,src-bam-pipe-index = <0>;
- qcom,dst-bam-physical-address = <0>;
- qcom,dst-bam-pipe-index = <0>;
- qcom,data-fifo-offset = <0>;
- qcom,data-fifo-size = <0>;
- qcom,descriptor-fifo-offset = <0>;
- qcom,descriptor-fifo-size = <0>;
- };
-
- qcom,pipe4 {
- label = "peri-to-usb-qdss-hsusb";
- qcom,usb-bam-type = <1>;
- qcom,usb-bam-mem-type = <1>;
+ qcom,bam-type = <1>;
+ qcom,dir = <1>;
+ qcom,pipe-num = <0>;
+ qcom,peer-bam = <1>;
qcom,src-bam-physical-address = <0xfc37c000>;
qcom,src-bam-pipe-index = <0>;
qcom,dst-bam-physical-address = <0xf9a44000>;
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 78786f6..5b32a14 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -131,16 +131,17 @@
reg-names = "hsusb";
interrupts = <0 135 0>;
interrupt-names = "hsusb";
- qcom,usb-active-bam = <1>;
- qcom,usb-total-bam-num = <3>;
qcom,usb-bam-num-pipes = <16>;
qcom,ignore-core-reset-ack;
qcom,disable-clk-gating;
qcom,pipe0 {
- label = "usb-to-ipa";
- qcom,usb-bam-type = <1>;
+ label = "hsusb-ipa-out-0";
qcom,usb-bam-mem-type = <0>;
+ qcom,bam-type = <1>;
+ qcom,dir = <0>;
+ qcom,pipe-num = <0>;
+ qcom,peer-bam = <2>;
qcom,src-bam-physical-address = <0xf9a44000>;
qcom,src-bam-pipe-index = <1>;
qcom,data-fifo-offset = <0x2200>;
@@ -149,9 +150,12 @@
qcom,descriptor-fifo-size = <0x100>;
};
qcom,pipe1 {
- label = "ipa-to-usb";
- qcom,usb-bam-type = <1>;
+ label = "hsusb-ipa-in-0";
qcom,usb-bam-mem-type = <0>;
+ qcom,bam-type = <1>;
+ qcom,dir = <1>;
+ qcom,pipe-num = <0>;
+ qcom,peer-bam = <2>;
qcom,dst-bam-physical-address = <0xf9a44000>;
qcom,dst-bam-pipe-index = <0>;
qcom,data-fifo-offset = <0x300>;
@@ -160,22 +164,12 @@
qcom,descriptor-fifo-size = <0x300>;
};
qcom,pipe2 {
- label = "usb-to-qdss-hsusb";
- qcom,usb-bam-type = <1>;
+ label = "hsusb-qdss-in-0";
qcom,usb-bam-mem-type = <0>;
- qcom,src-bam-physical-address = <0xf9a44000>;
- qcom,src-bam-pipe-index = <0>;
- qcom,dst-bam-physical-address = <0xfc37c000>;
- qcom,dst-bam-pipe-index = <0>;
- qcom,data-fifo-offset = <0>;
- qcom,data-fifo-size = <0>;
- qcom,descriptor-fifo-offset = <0>;
- qcom,descriptor-fifo-size = <0>;
- };
- qcom,pipe3 {
- label = "qdss-to-usb-hsusb";
- qcom,usb-bam-type = <1>;
- qcom,usb-bam-mem-type = <0>;
+ qcom,bam-type = <1>;
+ qcom,dir = <1>;
+ qcom,pipe-num = <0>;
+ qcom,peer-bam = <1>;
qcom,src-bam-physical-address = <0xfc37c000>;
qcom,src-bam-pipe-index = <0>;
qcom,dst-bam-physical-address = <0xf9a44000>;
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index f609bbc..50f4fd7 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -625,8 +625,13 @@
#define USB_BAM_PHY_BASE 0x12502000
#define HSIC_BAM_PHY_BASE 0x12542000
#define A2_BAM_PHY_BASE 0x124C2000
-static struct usb_bam_pipe_connect msm_usb_bam_connections[MAX_BAMS][8][2] = {
- [HSUSB_BAM][0][USB_TO_PEER_PERIPHERAL] = {
+static struct usb_bam_pipe_connect msm_usb_bam_connections[] = {
+ {
+ .name = "hsusb-a2-out-0",
+ .bam_type = HSUSB_BAM,
+ .peer_bam = A2_P_BAM,
+ .dir = USB_TO_PEER_PERIPHERAL,
+ .pipe_num = 0,
.src_phy_addr = USB_BAM_PHY_BASE,
.src_pipe_index = 11,
.dst_phy_addr = A2_BAM_PHY_BASE,
@@ -636,7 +641,12 @@
.desc_fifo_base_offset = 0x1700,
.desc_fifo_size = 0x300,
},
- [HSUSB_BAM][0][PEER_PERIPHERAL_TO_USB] = {
+ {
+ .name = "hsusb-a2-in-0",
+ .bam_type = HSUSB_BAM,
+ .peer_bam = A2_P_BAM,
+ .dir = PEER_PERIPHERAL_TO_USB,
+ .pipe_num = 0,
.src_phy_addr = A2_BAM_PHY_BASE,
.src_pipe_index = 1,
.dst_phy_addr = USB_BAM_PHY_BASE,
@@ -646,7 +656,12 @@
.desc_fifo_base_offset = 0x1000,
.desc_fifo_size = 0x100,
},
- [HSUSB_BAM][1][USB_TO_PEER_PERIPHERAL] = {
+ {
+ .name = "hsusb-a2-out-1",
+ .bam_type = HSUSB_BAM,
+ .peer_bam = A2_P_BAM,
+ .dir = USB_TO_PEER_PERIPHERAL,
+ .pipe_num = 1,
.src_phy_addr = USB_BAM_PHY_BASE,
.src_pipe_index = 13,
.dst_phy_addr = A2_BAM_PHY_BASE,
@@ -656,7 +671,12 @@
.desc_fifo_base_offset = 0x2700,
.desc_fifo_size = 0x300,
},
- [HSUSB_BAM][1][PEER_PERIPHERAL_TO_USB] = {
+ {
+ .name = "hsusb-a2-in-1",
+ .bam_type = HSUSB_BAM,
+ .peer_bam = A2_P_BAM,
+ .dir = PEER_PERIPHERAL_TO_USB,
+ .pipe_num = 1,
.src_phy_addr = A2_BAM_PHY_BASE,
.src_pipe_index = 3,
.dst_phy_addr = USB_BAM_PHY_BASE,
@@ -666,7 +686,12 @@
.desc_fifo_base_offset = 0x2000,
.desc_fifo_size = 0x100,
},
- [HSUSB_BAM][2][USB_TO_PEER_PERIPHERAL] = {
+ {
+ .name = "hsusb-a2-out-2",
+ .bam_type = HSUSB_BAM,
+ .peer_bam = A2_P_BAM,
+ .dir = USB_TO_PEER_PERIPHERAL,
+ .pipe_num = 2,
.src_phy_addr = USB_BAM_PHY_BASE,
.src_pipe_index = 15,
.dst_phy_addr = A2_BAM_PHY_BASE,
@@ -676,7 +701,12 @@
.desc_fifo_base_offset = 0x3700,
.desc_fifo_size = 0x300,
},
- [HSUSB_BAM][2][PEER_PERIPHERAL_TO_USB] = {
+ {
+ .name = "hsusb-a2-in-2",
+ .bam_type = HSUSB_BAM,
+ .peer_bam = A2_P_BAM,
+ .dir = PEER_PERIPHERAL_TO_USB,
+ .pipe_num = 2,
.src_phy_addr = A2_BAM_PHY_BASE,
.src_pipe_index = 5,
.dst_phy_addr = USB_BAM_PHY_BASE,
@@ -686,7 +716,12 @@
.desc_fifo_base_offset = 0x3000,
.desc_fifo_size = 0x100,
},
- [HSIC_BAM][0][USB_TO_PEER_PERIPHERAL] = {
+ {
+ .name = "hsic-a2-out-0",
+ .bam_type = HSIC_BAM,
+ .peer_bam = A2_P_BAM,
+ .dir = USB_TO_PEER_PERIPHERAL,
+ .pipe_num = 0,
.src_phy_addr = HSIC_BAM_PHY_BASE,
.src_pipe_index = 1,
.dst_phy_addr = A2_BAM_PHY_BASE,
@@ -696,7 +731,12 @@
.desc_fifo_base_offset = 0x1700,
.desc_fifo_size = 0x300,
},
- [HSIC_BAM][0][PEER_PERIPHERAL_TO_USB] = {
+ {
+ .name = "hsic-a2-in-0",
+ .bam_type = HSIC_BAM,
+ .peer_bam = A2_P_BAM,
+ .dir = PEER_PERIPHERAL_TO_USB,
+ .pipe_num = 0,
.src_phy_addr = A2_BAM_PHY_BASE,
.src_pipe_index = 1,
.dst_phy_addr = HSIC_BAM_PHY_BASE,
@@ -706,7 +746,12 @@
.desc_fifo_base_offset = 0x1000,
.desc_fifo_size = 0x100,
},
- [HSIC_BAM][1][USB_TO_PEER_PERIPHERAL] = {
+ {
+ .name = "hsic-a2-out-1",
+ .bam_type = HSIC_BAM,
+ .peer_bam = A2_P_BAM,
+ .dir = USB_TO_PEER_PERIPHERAL,
+ .pipe_num = 1,
.src_phy_addr = HSIC_BAM_PHY_BASE,
.src_pipe_index = 3,
.dst_phy_addr = A2_BAM_PHY_BASE,
@@ -716,7 +761,12 @@
.desc_fifo_base_offset = 0x2700,
.desc_fifo_size = 0x300,
},
- [HSIC_BAM][1][PEER_PERIPHERAL_TO_USB] = {
+ {
+ .name = "hsic-a2-in-1",
+ .bam_type = HSIC_BAM,
+ .peer_bam = A2_P_BAM,
+ .dir = PEER_PERIPHERAL_TO_USB,
+ .pipe_num = 1,
.src_phy_addr = A2_BAM_PHY_BASE,
.src_pipe_index = 3,
.dst_phy_addr = HSIC_BAM_PHY_BASE,
@@ -726,7 +776,12 @@
.desc_fifo_base_offset = 0x2000,
.desc_fifo_size = 0x100,
},
- [HSIC_BAM][2][USB_TO_PEER_PERIPHERAL] = {
+ {
+ .name = "hsic-a2-out-2",
+ .bam_type = HSIC_BAM,
+ .peer_bam = A2_P_BAM,
+ .dir = USB_TO_PEER_PERIPHERAL,
+ .pipe_num = 2,
.src_phy_addr = HSIC_BAM_PHY_BASE,
.src_pipe_index = 5,
.dst_phy_addr = A2_BAM_PHY_BASE,
@@ -736,7 +791,12 @@
.desc_fifo_base_offset = 0x3700,
.desc_fifo_size = 0x300,
},
- [HSIC_BAM][2][PEER_PERIPHERAL_TO_USB] = {
+ {
+ .name = "hsic-a2-in-2",
+ .bam_type = HSIC_BAM,
+ .peer_bam = A2_P_BAM,
+ .dir = PEER_PERIPHERAL_TO_USB,
+ .pipe_num = 2,
.src_phy_addr = A2_BAM_PHY_BASE,
.src_pipe_index = 5,
.dst_phy_addr = HSIC_BAM_PHY_BASE,
@@ -749,12 +809,9 @@
};
static struct msm_usb_bam_platform_data msm_usb_bam_pdata = {
- .connections = &msm_usb_bam_connections[0][0][0],
-#ifndef CONFIG_USB_CI13XXX_MSM_HSIC
- .usb_active_bam = HSUSB_BAM,
-#else
- .usb_active_bam = HSIC_BAM,
-#endif
+ .connections = &msm_usb_bam_connections[0],
+ .max_connections = sizeof(msm_usb_bam_connections) /
+ sizeof(struct usb_bam_pipe_connect),
.usb_bam_num_pipes = 16,
};
diff --git a/arch/arm/mach-msm/include/mach/usb_bam.h b/arch/arm/mach-msm/include/mach/usb_bam.h
index b3fb8af..5a77d99 100644
--- a/arch/arm/mach-msm/include/mach/usb_bam.h
+++ b/arch/arm/mach-msm/include/mach/usb_bam.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -14,22 +14,36 @@
#define _USB_BAM_H_
#include "sps.h"
#include <mach/ipa.h>
+#include <linux/usb/msm_hsusb.h>
-/**
- * SPS Pipes direction.
- *
- * USB_TO_PEER_PERIPHERAL USB (as Producer) to other
- * peer peripheral.
- * PEER_PERIPHERAL_TO_USB Other Peripheral to
- * USB (as consumer).
- */
+enum usb_bam {
+ SSUSB_BAM = 0,
+ HSUSB_BAM,
+ HSIC_BAM,
+ MAX_BAMS,
+};
+
+enum peer_bam {
+ A2_P_BAM = 0,
+ QDSS_P_BAM,
+ IPA_P_BAM,
+ MAX_PEER_BAMS,
+};
+
enum usb_bam_pipe_dir {
USB_TO_PEER_PERIPHERAL,
PEER_PERIPHERAL_TO_USB,
};
+enum usb_pipe_mem_type {
+ SPS_PIPE_MEM = 0, /* Default, SPS dedicated pipe memory */
+ USB_PRIVATE_MEM, /* USB's private memory */
+ SYSTEM_MEM, /* System RAM, requires allocation */
+};
+
struct usb_bam_connect_ipa_params {
- u8 idx;
+ u8 src_idx;
+ u8 dst_idx;
u32 *src_pipe;
u32 *dst_pipe;
enum usb_bam_pipe_dir dir;
@@ -44,29 +58,100 @@
unsigned long data);
};
+/**
+* struct usb_bam_event_info: suspend/resume event information.
+* @event: holds event data.
+* @callback: suspend/resume callback.
+* @param: port num (for suspend) or NULL (for resume).
+* @event_w: holds work queue parameters.
+*/
+struct usb_bam_event_info {
+ struct sps_register_event event;
+ int (*callback)(void *);
+ void *param;
+ struct work_struct event_w;
+};
+
+/**
+* struct usb_bam_pipe_connect: pipe connection information
+* between USB/HSIC BAM and another BAM. USB/HSIC BAM can be
+* either src BAM or dst BAM
+* @name: pipe description.
+* @mem_type: type of memory used for BAM FIFOs
+* @src_phy_addr: src bam physical address.
+* @src_pipe_index: src bam pipe index.
+* @dst_phy_addr: dst bam physical address.
+* @dst_pipe_index: dst bam pipe index.
+* @data_fifo_base_offset: data fifo offset.
+* @data_fifo_size: data fifo size.
+* @desc_fifo_base_offset: descriptor fifo offset.
+* @desc_fifo_size: descriptor fifo size.
+* @data_mem_buf: data fifo buffer.
+* @desc_mem_buf: descriptor fifo buffer.
+* @wake_event: event for wakeup.
+* @enabled: true if pipe is enabled.
+*/
+struct usb_bam_pipe_connect {
+ const char *name;
+ u32 pipe_num;
+ enum usb_pipe_mem_type mem_type;
+ enum usb_bam_pipe_dir dir;
+ enum usb_bam bam_type;
+ enum peer_bam peer_bam;
+ u32 src_phy_addr;
+ u32 src_pipe_index;
+ u32 dst_phy_addr;
+ u32 dst_pipe_index;
+ u32 data_fifo_base_offset;
+ u32 data_fifo_size;
+ u32 desc_fifo_base_offset;
+ u32 desc_fifo_size;
+ struct sps_mem_buffer data_mem_buf;
+ struct sps_mem_buffer desc_mem_buf;
+ struct usb_bam_event_info wake_event;
+ bool enabled;
+};
+
+/**
+ * struct msm_usb_bam_platform_data: pipe connection information
+ * between USB/HSIC BAM and another BAM. USB/HSIC BAM can be
+ * either src BAM or dst BAM
+ * @connections: holds all pipe connections data.
+ * @usb_bam_num_pipes: max number of pipes to use.
+ * @active_conn_num: number of active pipe connections.
+ * @usb_base_address: BAM physical address.
+ * @ignore_core_reset_ack: BAM can ignore ACK from USB core during PIPE RESET
+ * @disable_clk_gating: Disable clock gating
+ */
+struct msm_usb_bam_platform_data {
+ struct usb_bam_pipe_connect *connections;
+ u8 max_connections;
+ int usb_bam_num_pipes;
+ u32 usb_base_address;
+ bool ignore_core_reset_ack;
+ bool reset_on_connect[MAX_BAMS];
+ bool disable_clk_gating;
+};
+
#ifdef CONFIG_USB_BAM
/**
- * Connect USB-to-Periperal SPS connection.
+ * Connect USB-to-Peripheral SPS connection.
*
- * This function returns the allocated pipes number.
+ * This function returns the allocated pipe number.
*
* @idx - Connection index.
*
- * @src_pipe_idx - allocated pipe index - USB as a
- * source (output)
- *
- * @dst_pipe_idx - allocated pipe index - USB as a
- * destination (output)
+ * @bam_pipe_idx - allocated pipe index.
*
* @return 0 on success, negative value on error
*
*/
-int usb_bam_connect(u8 idx, u32 *src_pipe_idx, u32 *dst_pipe_idx);
+int usb_bam_connect(u8 idx, u32 *bam_pipe_idx);
/**
* Connect USB-to-IPA SPS connection.
*
- * This function returns the allocated pipes number adn clnt handles.
+ * This function returns the allocated pipes number and clnt handles.
*
* @ipa_params - in/out parameters
*
@@ -78,14 +163,12 @@
/**
* Disconnect USB-to-IPA SPS connection.
*
- * @idx - Connection index.
- *
* @ipa_params - in/out parameters
*
* @return 0 on success, negative value on error
*
*/
-int usb_bam_disconnect_ipa(u8 idx,
+int usb_bam_disconnect_ipa(
struct usb_bam_connect_ipa_params *ipa_params);
/**
@@ -99,13 +182,11 @@
*
*/
int usb_bam_register_wake_cb(u8 idx,
- int (*callback)(void *), void* param);
+ int (*callback)(void *), void *param);
/**
* Register a callback for peer BAM reset.
*
- * @idx - Connection index.
- *
* @callback - the callback function that will be called in USB
* driver upon a peer bam reset
*
@@ -114,8 +195,7 @@
* @return 0 on success, negative value on error
*
*/
-int usb_bam_register_peer_reset_cb(u8 idx,
- int (*callback)(void *), void *param);
+int usb_bam_register_peer_reset_cb(int (*callback)(void *), void *param);
/**
* Disconnect USB-to-Periperal SPS connection.
@@ -129,9 +209,7 @@
/**
* Returns usb bam connection parameters.
*
- * @conn_idx - Connection index.
- *
- * @usb_bam_pipe_dir - Usb pipe direction to/from peripheral.
+ * @idx - Connection index.
*
* @usb_bam_handle - Usb bam handle.
*
@@ -143,16 +221,17 @@
*
* @data_fifo - Data fifo parameters.
*
+ * @return pipe index on success, negative value on error.
*/
-void get_bam2bam_connection_info(u8 conn_idx, enum usb_bam_pipe_dir pipe_dir,
+int get_bam2bam_connection_info(u8 idx,
u32 *usb_bam_handle, u32 *usb_bam_pipe_idx, u32 *peer_pipe_idx,
struct sps_mem_buffer *desc_fifo, struct sps_mem_buffer *data_fifo);
/**
- * Resets the entire USB BAM.
+ * Resets the USB BAM that has A2 pipes
*
*/
-int usb_bam_reset(void);
+int usb_bam_a2_reset(void);
/**
* Indicates if the client of the USB BAM is ready to start
@@ -162,9 +241,41 @@
*
*/
int usb_bam_client_ready(bool ready);
+/**
+* Returns qdss index from the connections array.
+*
+* @num - The qdss pipe number.
+*
+* @return pipe index on success, negative value on error
+*/
+int usb_bam_get_qdss_idx(u8 num);
+
+/**
+* Saves qdss core number.
+*
+* @qdss_core - The qdss core name.
+*/
+void usb_bam_set_qdss_core(const char *qdss_core);
+
+/**
+* Indicates if the client of the USB BAM is ready to start
+* sending/receiving transfers.
+*
+* @name - Core name (ssusb/hsusb/hsic).
+*
+* @client - Usb pipe peer (a2, ipa, qdss...)
+*
+* @dir - In (from peer to usb) or out (from usb to peer)
+*
+* @num - Pipe number.
+*
+* @return 0 on success, negative value on error
+*/
+int usb_bam_get_connection_idx(const char *name, enum peer_bam client,
+ enum usb_bam_pipe_dir dir, u32 num);
#else
-static inline int usb_bam_connect(u8 idx, u32 *src_pipe_idx, u32 *dst_pipe_idx)
+static inline int usb_bam_connect(u8 idx, u32 *bam_pipe_idx)
{
return -ENODEV;
}
@@ -175,7 +286,7 @@
return -ENODEV;
}
-static inline int usb_bam_disconnect_ipa(u8 idx,
+static inline int usb_bam_disconnect_ipa(
struct usb_bam_connect_ipa_params *ipa_params)
{
return -ENODEV;
@@ -187,8 +298,8 @@
return -ENODEV;
}
-static inline int usb_bam_register_peer_reset_cb(u8 idx,
- int (*callback)(void *), void *param)
+static inline int usb_bam_register_peer_reset_cb(
+ int (*callback)(void *), void *param)
{
return -ENODEV;
}
@@ -198,15 +309,14 @@
return -ENODEV;
}
-static inline void get_bam2bam_connection_info(u8 conn_idx,
- enum usb_bam_pipe_dir pipe_dir, u32 *usb_bam_handle,
- u32 *usb_bam_pipe_idx, u32 *peer_pipe_idx,
+static inline int get_bam2bam_connection_info(u8 idx,
+ u32 *usb_bam_handle, u32 *usb_bam_pipe_idx, u32 *peer_pipe_idx,
struct sps_mem_buffer *desc_fifo, struct sps_mem_buffer *data_fifo)
{
- return;
+ return -ENODEV;
}
-static inline int usb_bam_reset(void)
+static inline int usb_bam_a2_reset(void)
{
return -ENODEV;
}
@@ -216,5 +326,20 @@
return -ENODEV;
}
+static inline int usb_bam_get_qdss_idx(u8 num)
+{
+ return -ENODEV;
+}
+
+static inline void usb_bam_set_qdss_core(const char *qdss_core)
+{
+ return;
+}
+
+static inline int usb_bam_get_connection_idx(const char *name,
+ enum peer_bam client, enum usb_bam_pipe_dir dir, u32 num)
+{
+ return -ENODEV;
+}
#endif
#endif /* _USB_BAM_H_ */
diff --git a/drivers/coresight/coresight-tmc.c b/drivers/coresight/coresight-tmc.c
index 0afb5a2..86276b7 100644
--- a/drivers/coresight/coresight-tmc.c
+++ b/drivers/coresight/coresight-tmc.c
@@ -217,7 +217,7 @@
{
struct tmc_etr_bam_data *bamdata = drvdata->bamdata;
- get_bam2bam_connection_info(0, PEER_PERIPHERAL_TO_USB,
+ get_bam2bam_connection_info(usb_bam_get_qdss_idx(0),
&bamdata->dest,
&bamdata->dest_pipe_idx,
&bamdata->src_pipe_idx,
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index a9a850c..ef21b7b 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.c
@@ -28,34 +28,8 @@
#include <linux/dma-mapping.h>
#include <mach/msm_smsm.h>
-#define USB_SUMMING_THRESHOLD 512
-#define CONNECTIONS_NUM 8
-
-static struct sps_bam_props usb_props;
-static struct sps_pipe *sps_pipes[CONNECTIONS_NUM][2];
-static struct sps_connect sps_connections[CONNECTIONS_NUM][2];
-static struct sps_mem_buffer data_mem_buf[CONNECTIONS_NUM][2];
-static struct sps_mem_buffer desc_mem_buf[CONNECTIONS_NUM][2];
-static struct platform_device *usb_bam_pdev;
-static struct workqueue_struct *usb_bam_wq;
-static u32 h_bam;
-static spinlock_t usb_bam_lock;
-
-struct usb_bam_event_info {
- struct sps_register_event event;
- int (*callback)(void *);
- void *param;
- struct work_struct event_w;
-};
-
-struct usb_bam_connect_info {
- u8 idx;
- u32 *src_pipe;
- u32 *dst_pipe;
- struct usb_bam_event_info wake_event;
- bool src_enabled;
- bool dst_enabled;
-};
+#define USB_THRESHOLD 512
+#define USB_BAM_MAX_STR_LEN 50
enum usb_bam_sm {
USB_BAM_SM_INIT = 0,
@@ -64,7 +38,7 @@
USB_BAM_SM_UNPLUG_NOTIFIED,
};
-struct usb_bam_peer_handhskae_info {
+struct usb_bam_peer_handshake_info {
enum usb_bam_sm state;
bool client_ready;
bool ack_received;
@@ -72,26 +46,79 @@
struct usb_bam_event_info reset_event;
};
-static struct usb_bam_connect_info usb_bam_connections[CONNECTIONS_NUM];
-static struct usb_bam_pipe_connect ***msm_usb_bam_connections_info;
-static struct usb_bam_pipe_connect *bam_connection_arr;
-void __iomem *qscratch_ram1_reg;
-struct clk *mem_clk;
-struct clk *mem_iface_clk;
-struct usb_bam_peer_handhskae_info peer_handhskae_info;
+struct usb_bam_sps_type {
+ struct sps_bam_props usb_props;
+ struct sps_pipe **sps_pipes;
+ struct sps_connect *sps_connections;
+};
-static int connect_pipe(u8 conn_idx, enum usb_bam_pipe_dir pipe_dir,
- u32 *usb_pipe_idx)
+struct usb_bam_ctx_type {
+ struct usb_bam_sps_type usb_bam_sps;
+ struct platform_device *usb_bam_pdev;
+ struct workqueue_struct *usb_bam_wq;
+ void __iomem *qscratch_ram1_reg;
+ u8 max_connections;
+ struct clk *mem_clk;
+ struct clk *mem_iface_clk;
+ char qdss_core_name[USB_BAM_MAX_STR_LEN];
+ char bam_enabled_list[USB_BAM_MAX_STR_LEN];
+ u32 h_bam[MAX_BAMS];
+};
+
+static char *bam_enable_strings[3] = {
+ [SSUSB_BAM] = "ssusb",
+ [HSUSB_BAM] = "hsusb",
+ [HSIC_BAM] = "hsic",
+};
+
+static spinlock_t usb_bam_lock;
+static struct usb_bam_peer_handshake_info peer_handshake_info;
+static struct usb_bam_pipe_connect *usb_bam_connections;
+static struct usb_bam_ctx_type ctx;
+
+static int get_bam_type_from_core_name(const char *name)
+{
+ if (strnstr(name, bam_enable_strings[SSUSB_BAM],
+ USB_BAM_MAX_STR_LEN) ||
+ strnstr(name, "dwc3", USB_BAM_MAX_STR_LEN))
+ return SSUSB_BAM;
+ else if (strnstr(name, bam_enable_strings[HSIC_BAM],
+ USB_BAM_MAX_STR_LEN))
+ return HSIC_BAM;
+ else if (strnstr(name, bam_enable_strings[HSUSB_BAM],
+ USB_BAM_MAX_STR_LEN) ||
+ strnstr(name, "ci", USB_BAM_MAX_STR_LEN))
+ return HSUSB_BAM;
+
+ pr_err("%s: invalid BAM name(%s)\n", __func__, name);
+ return -EINVAL;
+}
+
+static bool bam_use_private_mem(enum usb_bam bam)
+{
+ int i;
+
+ for (i = 0; i < ctx.max_connections; i++)
+ if (usb_bam_connections[i].bam_type == bam &&
+ usb_bam_connections[i].mem_type == USB_PRIVATE_MEM)
+ return true;
+
+ return false;
+}
+
+static int connect_pipe(u8 idx, u32 *usb_pipe_idx)
{
int ret, ram1_value;
- struct sps_pipe **pipe = &sps_pipes[conn_idx][pipe_dir];
- struct sps_connect *connection =
- &sps_connections[conn_idx][pipe_dir];
+ enum usb_bam bam;
+ struct usb_bam_sps_type usb_bam_sps = ctx.usb_bam_sps;
+ struct sps_pipe **pipe = &(usb_bam_sps.sps_pipes[idx]);
+ struct sps_connect *sps_connection = &usb_bam_sps.sps_connections[idx];
struct msm_usb_bam_platform_data *pdata =
- usb_bam_pdev->dev.platform_data;
- struct usb_bam_pipe_connect *pipe_connection =
- &msm_usb_bam_connections_info
- [pdata->usb_active_bam][conn_idx][pipe_dir];
+ ctx.usb_bam_pdev->dev.platform_data;
+ struct usb_bam_pipe_connect *pipe_connect = &usb_bam_connections[idx];
+ enum usb_bam_pipe_dir dir = pipe_connect->dir;
+ struct sps_mem_buffer *data_buf = &(pipe_connect->data_mem_buf);
+ struct sps_mem_buffer *desc_buf = &(pipe_connect->desc_mem_buf);
*pipe = sps_alloc_endpoint();
if (*pipe == NULL) {
@@ -99,42 +126,42 @@
return -ENOMEM;
}
- ret = sps_get_config(*pipe, connection);
+ ret = sps_get_config(*pipe, sps_connection);
if (ret) {
pr_err("%s: tx get config failed %d\n", __func__, ret);
goto free_sps_endpoint;
}
- ret = sps_phy2h(pipe_connection->src_phy_addr, &(connection->source));
+ ret = sps_phy2h(pipe_connect->src_phy_addr, &(sps_connection->source));
if (ret) {
pr_err("%s: sps_phy2h failed (src BAM) %d\n", __func__, ret);
goto free_sps_endpoint;
}
- connection->src_pipe_index = pipe_connection->src_pipe_index;
- ret = sps_phy2h(pipe_connection->dst_phy_addr,
- &(connection->destination));
+ sps_connection->src_pipe_index = pipe_connect->src_pipe_index;
+ ret = sps_phy2h(pipe_connect->dst_phy_addr,
+ &(sps_connection->destination));
if (ret) {
pr_err("%s: sps_phy2h failed (dst BAM) %d\n", __func__, ret);
goto free_sps_endpoint;
}
- connection->dest_pipe_index = pipe_connection->dst_pipe_index;
+ sps_connection->dest_pipe_index = pipe_connect->dst_pipe_index;
- if (pipe_dir == USB_TO_PEER_PERIPHERAL) {
- connection->mode = SPS_MODE_SRC;
- *usb_pipe_idx = connection->src_pipe_index;
+ if (dir == USB_TO_PEER_PERIPHERAL) {
+ sps_connection->mode = SPS_MODE_SRC;
+ *usb_pipe_idx = pipe_connect->src_pipe_index;
} else {
- connection->mode = SPS_MODE_DEST;
- *usb_pipe_idx = connection->dest_pipe_index;
+ sps_connection->mode = SPS_MODE_DEST;
+ *usb_pipe_idx = pipe_connect->dst_pipe_index;
}
/* If BAM is using dedicated SPS pipe memory, get it */
- if (pipe_connection->mem_type == SPS_PIPE_MEM) {
+ if (pipe_connect->mem_type == SPS_PIPE_MEM) {
pr_debug("%s: USB BAM using SPS pipe memory\n", __func__);
ret = sps_setup_bam2bam_fifo(
- &data_mem_buf[conn_idx][pipe_dir],
- pipe_connection->data_fifo_base_offset,
- pipe_connection->data_fifo_size, 1);
+ data_buf,
+ pipe_connect->data_fifo_base_offset,
+ pipe_connect->data_fifo_size, 1);
if (ret) {
pr_err("%s: data fifo setup failure %d\n", __func__,
ret);
@@ -142,90 +169,84 @@
}
ret = sps_setup_bam2bam_fifo(
- &desc_mem_buf[conn_idx][pipe_dir],
- pipe_connection->desc_fifo_base_offset,
- pipe_connection->desc_fifo_size, 1);
+ desc_buf,
+ pipe_connect->desc_fifo_base_offset,
+ pipe_connect->desc_fifo_size, 1);
if (ret) {
pr_err("%s: desc. fifo setup failure %d\n", __func__,
ret);
goto free_sps_endpoint;
}
- } else if (pipe_connection->mem_type == USB_PRIVATE_MEM) {
+ } else if (pipe_connect->mem_type == USB_PRIVATE_MEM) {
pr_debug("%s: USB BAM using private memory\n", __func__);
- if (IS_ERR(mem_clk) || IS_ERR(mem_iface_clk)) {
+ if (IS_ERR(ctx.mem_clk) || IS_ERR(ctx.mem_iface_clk)) {
pr_err("%s: Failed to enable USB mem_clk\n", __func__);
- ret = IS_ERR(mem_clk);
+ ret = IS_ERR(ctx.mem_clk);
goto free_sps_endpoint;
}
- clk_prepare_enable(mem_clk);
- clk_prepare_enable(mem_iface_clk);
+ clk_prepare_enable(ctx.mem_clk);
+ clk_prepare_enable(ctx.mem_iface_clk);
/*
* Enable USB PRIVATE RAM to be used for BAM FIFOs
* HSUSB: Only RAM13 is used for BAM FIFOs
* SSUSB: RAM11, 12, 13 are used for BAM FIFOs
*/
- if (pdata->usb_active_bam == HSUSB_BAM)
+ bam = pipe_connect->bam_type;
+ if (bam < 0)
+ goto free_sps_endpoint;
+
+ if (bam == HSUSB_BAM)
ram1_value = 0x4;
else
ram1_value = 0x7;
pr_debug("Writing 0x%x to QSCRATCH_RAM1\n", ram1_value);
- writel_relaxed(ram1_value, qscratch_ram1_reg);
+ writel_relaxed(ram1_value, ctx.qscratch_ram1_reg);
- data_mem_buf[conn_idx][pipe_dir].phys_base =
- pipe_connection->data_fifo_base_offset +
+ data_buf->phys_base =
+ pipe_connect->data_fifo_base_offset +
pdata->usb_base_address;
- data_mem_buf[conn_idx][pipe_dir].size =
- pipe_connection->data_fifo_size;
- data_mem_buf[conn_idx][pipe_dir].base =
- ioremap(data_mem_buf[conn_idx][pipe_dir].phys_base,
- data_mem_buf[conn_idx][pipe_dir].size);
- memset(data_mem_buf[conn_idx][pipe_dir].base, 0,
- data_mem_buf[conn_idx][pipe_dir].size);
+ data_buf->size = pipe_connect->data_fifo_size;
+ data_buf->base =
+ ioremap(data_buf->phys_base, data_buf->size);
+ memset(data_buf->base, 0, data_buf->size);
- desc_mem_buf[conn_idx][pipe_dir].phys_base =
- pipe_connection->desc_fifo_base_offset +
+ desc_buf->phys_base =
+ pipe_connect->desc_fifo_base_offset +
pdata->usb_base_address;
- desc_mem_buf[conn_idx][pipe_dir].size =
- pipe_connection->desc_fifo_size;
- desc_mem_buf[conn_idx][pipe_dir].base =
- ioremap(desc_mem_buf[conn_idx][pipe_dir].phys_base,
- desc_mem_buf[conn_idx][pipe_dir].size);
- memset(desc_mem_buf[conn_idx][pipe_dir].base, 0,
- desc_mem_buf[conn_idx][pipe_dir].size);
+ desc_buf->size = pipe_connect->desc_fifo_size;
+ desc_buf->base =
+ ioremap(desc_buf->phys_base, desc_buf->size);
+ memset(desc_buf->base, 0, desc_buf->size);
} else {
pr_debug("%s: USB BAM using system memory\n", __func__);
/* BAM would use system memory, allocate FIFOs */
- data_mem_buf[conn_idx][pipe_dir].size =
- pipe_connection->data_fifo_size;
- data_mem_buf[conn_idx][pipe_dir].base =
- dma_alloc_coherent(&usb_bam_pdev->dev,
- pipe_connection->data_fifo_size,
- &data_mem_buf[conn_idx][pipe_dir].phys_base,
- 0);
- memset(data_mem_buf[conn_idx][pipe_dir].base, 0,
- pipe_connection->data_fifo_size);
+ data_buf->size = pipe_connect->data_fifo_size;
+ data_buf->base =
+ dma_alloc_coherent(&ctx.usb_bam_pdev->dev,
+ pipe_connect->data_fifo_size,
+ &(data_buf->phys_base),
+ 0);
+ memset(data_buf->base, 0, pipe_connect->data_fifo_size);
- desc_mem_buf[conn_idx][pipe_dir].size =
- pipe_connection->desc_fifo_size;
- desc_mem_buf[conn_idx][pipe_dir].base =
- dma_alloc_coherent(&usb_bam_pdev->dev,
- pipe_connection->desc_fifo_size,
- &desc_mem_buf[conn_idx][pipe_dir].phys_base,
- 0);
- memset(desc_mem_buf[conn_idx][pipe_dir].base, 0,
- pipe_connection->desc_fifo_size);
+ desc_buf->size = pipe_connect->desc_fifo_size;
+ desc_buf->base =
+ dma_alloc_coherent(&ctx.usb_bam_pdev->dev,
+ pipe_connect->desc_fifo_size,
+ &(desc_buf->phys_base),
+ 0);
+ memset(desc_buf->base, 0, pipe_connect->desc_fifo_size);
}
- connection->data = data_mem_buf[conn_idx][pipe_dir];
- connection->desc = desc_mem_buf[conn_idx][pipe_dir];
- connection->event_thresh = 16;
- connection->options = SPS_O_AUTO_ENABLE;
+ sps_connection->data = *data_buf;
+ sps_connection->desc = *desc_buf;
+ sps_connection->event_thresh = 16;
+ sps_connection->options = SPS_O_AUTO_ENABLE;
- ret = sps_connect(*pipe, connection);
+ ret = sps_connect(*pipe, sps_connection);
if (ret < 0) {
pr_err("%s: sps_connect failed %d\n", __func__, ret);
goto error;
@@ -239,20 +260,15 @@
return ret;
}
-static int connect_pipe_ipa(
- struct usb_bam_connect_ipa_params *connection_params)
+static int connect_pipe_ipa(u8 idx,
+ struct usb_bam_connect_ipa_params *ipa_params)
{
int ret;
- u8 conn_idx = connection_params->idx;
- enum usb_bam_pipe_dir pipe_dir = connection_params->dir;
- struct sps_pipe **pipe = &sps_pipes[conn_idx][pipe_dir];
- struct sps_connect *connection =
- &sps_connections[conn_idx][pipe_dir];
- struct msm_usb_bam_platform_data *pdata =
- usb_bam_pdev->dev.platform_data;
- struct usb_bam_pipe_connect *pipe_connection =
- &msm_usb_bam_connections_info
- [pdata->usb_active_bam][conn_idx][pipe_dir];
+ struct usb_bam_sps_type usb_bam_sps = ctx.usb_bam_sps;
+ enum usb_bam_pipe_dir dir = ipa_params->dir;
+ struct sps_pipe **pipe = &(usb_bam_sps.sps_pipes[idx]);
+ struct sps_connect *sps_connection = &usb_bam_sps.sps_connections[idx];
+ struct usb_bam_pipe_connect *pipe_connect = &usb_bam_connections[idx];
struct ipa_connect_params ipa_in_params;
struct ipa_sps_params sps_out_params;
@@ -262,12 +278,12 @@
memset(&ipa_in_params, 0, sizeof(ipa_in_params));
memset(&sps_out_params, 0, sizeof(sps_out_params));
- if (pipe_dir == USB_TO_PEER_PERIPHERAL) {
- usb_phy_addr = pipe_connection->src_phy_addr;
- ipa_in_params.client_ep_idx = pipe_connection->src_pipe_index;
+ if (dir == USB_TO_PEER_PERIPHERAL) {
+ usb_phy_addr = pipe_connect->src_phy_addr;
+ ipa_in_params.client_ep_idx = pipe_connect->src_pipe_index;
} else {
- usb_phy_addr = pipe_connection->dst_phy_addr;
- ipa_in_params.client_ep_idx = pipe_connection->dst_pipe_index;
+ usb_phy_addr = pipe_connect->dst_phy_addr;
+ ipa_in_params.client_ep_idx = pipe_connect->dst_pipe_index;
}
/* Get HSUSB / HSIC bam handle */
ret = sps_phy2h(usb_phy_addr, &usb_handle);
@@ -279,46 +295,41 @@
/* IPA input parameters */
ipa_in_params.client_bam_hdl = usb_handle;
- ipa_in_params.desc_fifo_sz = pipe_connection->desc_fifo_size;
- ipa_in_params.data_fifo_sz = pipe_connection->data_fifo_size;
- ipa_in_params.notify = connection_params->notify;
- ipa_in_params.priv = connection_params->priv;
- ipa_in_params.client = connection_params->client;
+ ipa_in_params.desc_fifo_sz = pipe_connect->desc_fifo_size;
+ ipa_in_params.data_fifo_sz = pipe_connect->data_fifo_size;
+ ipa_in_params.notify = ipa_params->notify;
+ ipa_in_params.priv = ipa_params->priv;
+ ipa_in_params.client = ipa_params->client;
/* If BAM is using dedicated SPS pipe memory, get it */
- if (pipe_connection->mem_type == SPS_PIPE_MEM) {
+ if (pipe_connect->mem_type == SPS_PIPE_MEM) {
pr_debug("%s: USB BAM using SPS pipe memory\n", __func__);
ret = sps_setup_bam2bam_fifo(
- &data_mem_buf[conn_idx][pipe_dir],
- pipe_connection->data_fifo_base_offset,
- pipe_connection->data_fifo_size, 1);
+ &pipe_connect->data_mem_buf,
+ pipe_connect->data_fifo_base_offset,
+ pipe_connect->data_fifo_size, 1);
if (ret) {
- pr_err("%s: data fifo setup failure %d\n", __func__,
- ret);
+ pr_err("%s: data fifo setup failure %d\n",
+ __func__, ret);
return ret;
}
ret = sps_setup_bam2bam_fifo(
- &desc_mem_buf[conn_idx][pipe_dir],
- pipe_connection->desc_fifo_base_offset,
- pipe_connection->desc_fifo_size, 1);
+ &pipe_connect->desc_mem_buf,
+ pipe_connect->desc_fifo_base_offset,
+ pipe_connect->desc_fifo_size, 1);
if (ret) {
- pr_err("%s: desc. fifo setup failure %d\n", __func__,
- ret);
+ pr_err("%s: desc. fifo setup failure %d\n",
+ __func__, ret);
return ret;
}
- } else {
- pr_err("%s: unsupported memory type(%d)\n",
- __func__, pipe_connection->mem_type);
- return -EINVAL;
+ ipa_in_params.desc = pipe_connect->desc_mem_buf;
+ ipa_in_params.data = pipe_connect->data_mem_buf;
}
- ipa_in_params.desc = desc_mem_buf[conn_idx][pipe_dir];
- ipa_in_params.data = data_mem_buf[conn_idx][pipe_dir];
-
- memcpy(&ipa_in_params.ipa_ep_cfg, &connection_params->ipa_ep_cfg,
+ memcpy(&ipa_in_params.ipa_ep_cfg, &ipa_params->ipa_ep_cfg,
sizeof(struct ipa_ep_cfg));
ret = ipa_connect(&ipa_in_params, &sps_out_params, &clnt_hdl);
@@ -334,38 +345,48 @@
goto disconnect_ipa;
}
- ret = sps_get_config(*pipe, connection);
+ ret = sps_get_config(*pipe, sps_connection);
if (ret) {
pr_err("%s: tx get config failed %d\n", __func__, ret);
goto free_sps_endpoints;
}
- if (pipe_dir == USB_TO_PEER_PERIPHERAL) {
+ if (dir == USB_TO_PEER_PERIPHERAL) {
/* USB src IPA dest */
- connection->mode = SPS_MODE_SRC;
- connection_params->cons_clnt_hdl = clnt_hdl;
- connection->source = usb_handle;
- connection->destination = sps_out_params.ipa_bam_hdl;
- connection->src_pipe_index = pipe_connection->src_pipe_index;
- connection->dest_pipe_index = sps_out_params.ipa_ep_idx;
- *(connection_params->src_pipe) = connection->src_pipe_index;
+ sps_connection->mode = SPS_MODE_SRC;
+ ipa_params->cons_clnt_hdl = clnt_hdl;
+ sps_connection->source = usb_handle;
+ sps_connection->destination = sps_out_params.ipa_bam_hdl;
+ sps_connection->src_pipe_index = pipe_connect->src_pipe_index;
+ sps_connection->dest_pipe_index = sps_out_params.ipa_ep_idx;
+ *(ipa_params->src_pipe) = sps_connection->src_pipe_index;
+ pipe_connect->dst_pipe_index = sps_out_params.ipa_ep_idx;
+ pr_debug("%s: BAM pipe usb[%x]->ipa[%x] connection\n",
+ __func__,
+ pipe_connect->src_pipe_index,
+ pipe_connect->dst_pipe_index);
} else {
/* IPA src, USB dest */
- connection->mode = SPS_MODE_DEST;
- connection_params->prod_clnt_hdl = clnt_hdl;
- connection->source = sps_out_params.ipa_bam_hdl;
- connection->destination = usb_handle;
- connection->src_pipe_index = sps_out_params.ipa_ep_idx;
- connection->dest_pipe_index = pipe_connection->dst_pipe_index;
- *(connection_params->dst_pipe) = connection->dest_pipe_index;
+ sps_connection->mode = SPS_MODE_DEST;
+ ipa_params->prod_clnt_hdl = clnt_hdl;
+ sps_connection->source = sps_out_params.ipa_bam_hdl;
+ sps_connection->destination = usb_handle;
+ sps_connection->src_pipe_index = sps_out_params.ipa_ep_idx;
+ sps_connection->dest_pipe_index = pipe_connect->dst_pipe_index;
+ *(ipa_params->dst_pipe) = sps_connection->dest_pipe_index;
+ pipe_connect->src_pipe_index = sps_out_params.ipa_ep_idx;
+ pr_debug("%s: BAM pipe ipa[%x]->usb[%x] connection\n",
+ __func__,
+ pipe_connect->src_pipe_index,
+ pipe_connect->dst_pipe_index);
}
- connection->data = sps_out_params.data;
- connection->desc = sps_out_params.desc;
- connection->event_thresh = 16;
- connection->options = SPS_O_AUTO_ENABLE;
+ sps_connection->data = sps_out_params.data;
+ sps_connection->desc = sps_out_params.desc;
+ sps_connection->event_thresh = 16;
+ sps_connection->options = SPS_O_AUTO_ENABLE;
- ret = sps_connect(*pipe, connection);
+ ret = sps_connect(*pipe, sps_connection);
if (ret < 0) {
pr_err("%s: sps_connect failed %d\n", __func__, ret);
goto error;
@@ -382,92 +403,83 @@
return ret;
}
-static int disconnect_pipe(u8 connection_idx, enum usb_bam_pipe_dir pipe_dir)
+static int disconnect_pipe(u8 idx)
{
- struct msm_usb_bam_platform_data *pdata =
- usb_bam_pdev->dev.platform_data;
- struct usb_bam_pipe_connect *pipe_connection =
- &msm_usb_bam_connections_info
- [pdata->usb_active_bam][connection_idx][pipe_dir];
- struct sps_pipe *pipe = sps_pipes[connection_idx][pipe_dir];
- struct sps_connect *connection =
- &sps_connections[connection_idx][pipe_dir];
+ struct usb_bam_pipe_connect *pipe_connect =
+ &usb_bam_connections[idx];
+ struct sps_pipe *pipe = ctx.usb_bam_sps.sps_pipes[idx];
+ struct sps_connect *sps_connection =
+ &ctx.usb_bam_sps.sps_connections[idx];
sps_disconnect(pipe);
sps_free_endpoint(pipe);
- if (pipe_connection->mem_type == SYSTEM_MEM) {
+ if (pipe_connect->mem_type == SYSTEM_MEM) {
pr_debug("%s: Freeing system memory used by PIPE\n", __func__);
- dma_free_coherent(&usb_bam_pdev->dev, connection->data.size,
- connection->data.base, connection->data.phys_base);
- dma_free_coherent(&usb_bam_pdev->dev, connection->desc.size,
- connection->desc.base, connection->desc.phys_base);
- } else if (pipe_connection->mem_type == USB_PRIVATE_MEM) {
+ dma_free_coherent(&ctx.usb_bam_pdev->dev,
+ sps_connection->data.size,
+ sps_connection->data.base,
+ sps_connection->data.phys_base);
+ dma_free_coherent(&ctx.usb_bam_pdev->dev,
+ sps_connection->desc.size,
+ sps_connection->desc.base,
+ sps_connection->desc.phys_base);
+ } else if (pipe_connect->mem_type == USB_PRIVATE_MEM) {
pr_debug("Freeing USB private memory used by BAM PIPE\n");
- writel_relaxed(0x0, qscratch_ram1_reg);
- iounmap(connection->data.base);
- iounmap(connection->desc.base);
- clk_disable_unprepare(mem_clk);
- clk_disable_unprepare(mem_iface_clk);
+ writel_relaxed(0x0, ctx.qscratch_ram1_reg);
+ iounmap(sps_connection->data.base);
+ iounmap(sps_connection->desc.base);
+ clk_disable_unprepare(ctx.mem_clk);
+ clk_disable_unprepare(ctx.mem_iface_clk);
}
- connection->options &= ~SPS_O_AUTO_ENABLE;
+ sps_connection->options &= ~SPS_O_AUTO_ENABLE;
return 0;
}
-int usb_bam_connect(u8 idx, u32 *src_pipe_idx, u32 *dst_pipe_idx)
+int usb_bam_connect(u8 idx, u32 *bam_pipe_idx)
{
- struct usb_bam_connect_info *connection = &usb_bam_connections[idx];
- struct msm_usb_bam_platform_data *pdata =
- usb_bam_pdev->dev.platform_data;
- int usb_active_bam = pdata->usb_active_bam;
int ret;
+ enum usb_bam bam;
+ struct usb_bam_pipe_connect *pipe_connect = &usb_bam_connections[idx];
+ struct msm_usb_bam_platform_data *pdata;
- if (!usb_bam_pdev) {
+ if (!ctx.usb_bam_pdev) {
pr_err("%s: usb_bam device not found\n", __func__);
return -ENODEV;
}
- if (idx >= CONNECTIONS_NUM) {
- pr_err("%s: Invalid connection index\n",
- __func__);
- return -EINVAL;
- }
+ pdata = ctx.usb_bam_pdev->dev.platform_data;
- if (connection->src_enabled && connection->dst_enabled) {
+ if (pipe_connect->enabled) {
pr_debug("%s: connection %d was already established\n",
__func__, idx);
return 0;
}
- connection->src_pipe = src_pipe_idx;
- connection->dst_pipe = dst_pipe_idx;
- connection->idx = idx;
+
+ if (!bam_pipe_idx) {
+ pr_err("%s: invalid bam_pipe_idx\n", __func__);
+ return -EINVAL;
+ }
+ if (idx < 0 || idx > ctx.max_connections) {
+ pr_err("idx is wrong %d", idx);
+ return -EINVAL;
+ }
+ bam = pipe_connect->bam_type;
+ if (bam < 0)
+ return -EINVAL;
/* Check if BAM requires RESET before connect */
- if (pdata->reset_on_connect[usb_active_bam] == true)
- sps_device_reset(h_bam);
+ if (pdata->reset_on_connect[bam] == true)
+ sps_device_reset(ctx.h_bam[bam]);
- if (src_pipe_idx) {
- /* open USB -> Peripheral pipe */
- ret = connect_pipe(connection->idx, USB_TO_PEER_PERIPHERAL,
- connection->src_pipe);
- if (ret) {
- pr_err("%s: src pipe connection failure\n", __func__);
- return ret;
- }
- connection->src_enabled = 1;
+ ret = connect_pipe(idx, bam_pipe_idx);
+ if (ret) {
+ pr_err("%s: pipe connection[%d] failure\n", __func__, idx);
+ return ret;
}
- if (dst_pipe_idx) {
- /* open Peripheral -> USB pipe */
- ret = connect_pipe(connection->idx, PEER_PERIPHERAL_TO_USB,
- connection->dst_pipe);
- if (ret) {
- pr_err("%s: dst pipe connection failure\n", __func__);
- return ret;
- }
- connection->dst_enabled = 1;
- }
+ pipe_connect->enabled = 1;
return 0;
}
@@ -531,64 +543,65 @@
int usb_bam_connect_ipa(struct usb_bam_connect_ipa_params *ipa_params)
{
- u8 idx = ipa_params->idx;
- struct usb_bam_connect_info *connection = &usb_bam_connections[idx];
+ u8 idx;
+ struct usb_bam_pipe_connect *pipe_connect;
int ret;
- if (idx >= CONNECTIONS_NUM) {
- pr_err("%s: Invalid connection index\n",
+ if (!ipa_params) {
+ pr_err("%s: Invalid ipa params\n",
__func__);
return -EINVAL;
}
- if ((connection->src_enabled &&
- ipa_params->dir == USB_TO_PEER_PERIPHERAL) ||
- (connection->dst_enabled &&
- ipa_params->dir == PEER_PERIPHERAL_TO_USB)) {
+ if (ipa_params->dir == USB_TO_PEER_PERIPHERAL)
+ idx = ipa_params->src_idx;
+ else
+ idx = ipa_params->dst_idx;
+
+ if (idx >= ctx.max_connections) {
+ pr_err("%s: Invalid connection index\n",
+ __func__);
+ return -EINVAL;
+ }
+ pipe_connect = &usb_bam_connections[idx];
+
+ if (pipe_connect->enabled) {
pr_debug("%s: connection %d was already established\n",
__func__, idx);
return 0;
}
- if (ipa_params->dir == USB_TO_PEER_PERIPHERAL)
- connection->src_pipe = ipa_params->src_pipe;
- else
- connection->dst_pipe = ipa_params->dst_pipe;
-
- connection->idx = idx;
-
+ ret = connect_pipe_ipa(idx, ipa_params);
ipa_rm_request_resource(IPA_CLIENT_USB_PROD);
- ret = connect_pipe_ipa(ipa_params);
if (ret) {
pr_err("%s: dst pipe connection failure\n", __func__);
return ret;
}
- if (ipa_params->dir == USB_TO_PEER_PERIPHERAL)
- connection->src_enabled = 1;
- else
- connection->dst_enabled = 1;
+ pipe_connect->enabled = 1;
return 0;
}
+EXPORT_SYMBOL(usb_bam_connect_ipa);
int usb_bam_client_ready(bool ready)
{
spin_lock(&usb_bam_lock);
- if (peer_handhskae_info.client_ready == ready) {
+ if (peer_handshake_info.client_ready == ready) {
pr_debug("%s: client state is already %d\n",
__func__, ready);
spin_unlock(&usb_bam_lock);
return 0;
}
- peer_handhskae_info.client_ready = ready;
+ peer_handshake_info.client_ready = ready;
spin_unlock(&usb_bam_lock);
- if (!queue_work(usb_bam_wq, &peer_handhskae_info.reset_event.event_w)) {
+ if (!queue_work(ctx.usb_bam_wq,
+ &peer_handshake_info.reset_event.event_w)) {
spin_lock(&usb_bam_lock);
- peer_handhskae_info.pending_work++;
+ peer_handshake_info.pending_work++;
spin_unlock(&usb_bam_lock);
}
@@ -608,65 +621,65 @@
struct usb_bam_event_info *wake_event_info =
(struct usb_bam_event_info *)notify->user;
- queue_work(usb_bam_wq, &wake_event_info->event_w);
+ queue_work(ctx.usb_bam_wq, &wake_event_info->event_w);
}
static void usb_bam_sm_work(struct work_struct *w)
{
pr_debug("%s: current state: %d\n", __func__,
- peer_handhskae_info.state);
+ peer_handshake_info.state);
spin_lock(&usb_bam_lock);
- switch (peer_handhskae_info.state) {
+ switch (peer_handshake_info.state) {
case USB_BAM_SM_INIT:
- if (peer_handhskae_info.client_ready) {
+ if (peer_handshake_info.client_ready) {
spin_unlock(&usb_bam_lock);
smsm_change_state(SMSM_APPS_STATE, 0,
SMSM_USB_PLUG_UNPLUG);
spin_lock(&usb_bam_lock);
- peer_handhskae_info.state = USB_BAM_SM_PLUG_NOTIFIED;
+ peer_handshake_info.state = USB_BAM_SM_PLUG_NOTIFIED;
}
break;
case USB_BAM_SM_PLUG_NOTIFIED:
- if (peer_handhskae_info.ack_received) {
- peer_handhskae_info.state = USB_BAM_SM_PLUG_ACKED;
- peer_handhskae_info.ack_received = 0;
+ if (peer_handshake_info.ack_received) {
+ peer_handshake_info.state = USB_BAM_SM_PLUG_ACKED;
+ peer_handshake_info.ack_received = 0;
}
break;
case USB_BAM_SM_PLUG_ACKED:
- if (!peer_handhskae_info.client_ready) {
+ if (!peer_handshake_info.client_ready) {
spin_unlock(&usb_bam_lock);
smsm_change_state(SMSM_APPS_STATE,
SMSM_USB_PLUG_UNPLUG, 0);
spin_lock(&usb_bam_lock);
- peer_handhskae_info.state = USB_BAM_SM_UNPLUG_NOTIFIED;
+ peer_handshake_info.state = USB_BAM_SM_UNPLUG_NOTIFIED;
}
break;
case USB_BAM_SM_UNPLUG_NOTIFIED:
- if (peer_handhskae_info.ack_received) {
+ if (peer_handshake_info.ack_received) {
spin_unlock(&usb_bam_lock);
- peer_handhskae_info.reset_event.
- callback(peer_handhskae_info.reset_event.param);
+ peer_handshake_info.reset_event.
+ callback(peer_handshake_info.reset_event.param);
spin_lock(&usb_bam_lock);
- peer_handhskae_info.state = USB_BAM_SM_INIT;
- peer_handhskae_info.ack_received = 0;
+ peer_handshake_info.state = USB_BAM_SM_INIT;
+ peer_handshake_info.ack_received = 0;
}
break;
}
- if (peer_handhskae_info.pending_work) {
- peer_handhskae_info.pending_work--;
+ if (peer_handshake_info.pending_work) {
+ peer_handshake_info.pending_work--;
spin_unlock(&usb_bam_lock);
- queue_work(usb_bam_wq,
- &peer_handhskae_info.reset_event.event_w);
+ queue_work(ctx.usb_bam_wq,
+ &peer_handshake_info.reset_event.event_w);
spin_lock(&usb_bam_lock);
}
spin_unlock(&usb_bam_lock);
}
-static void usb_bam_ack_toggle_cb(void *priv, uint32_t old_state,
- uint32_t new_state)
+static void usb_bam_ack_toggle_cb(void *priv,
+ uint32_t old_state, uint32_t new_state)
{
static int last_processed_state;
int current_state;
@@ -681,27 +694,35 @@
}
last_processed_state = current_state;
- peer_handhskae_info.ack_received = true;
+ peer_handshake_info.ack_received = true;
spin_unlock(&usb_bam_lock);
- if (!queue_work(usb_bam_wq, &peer_handhskae_info.reset_event.event_w)) {
+ if (!queue_work(ctx.usb_bam_wq,
+ &peer_handshake_info.reset_event.event_w)) {
spin_lock(&usb_bam_lock);
- peer_handhskae_info.pending_work++;
+ peer_handshake_info.pending_work++;
spin_unlock(&usb_bam_lock);
}
}
-int usb_bam_register_wake_cb(u8 idx,
- int (*callback)(void *user), void* param)
+int usb_bam_register_wake_cb(u8 idx, int (*callback)(void *user),
+ void *param)
{
- struct sps_pipe *pipe = sps_pipes[idx][PEER_PERIPHERAL_TO_USB];
- struct sps_connect *sps_connection =
- &sps_connections[idx][PEER_PERIPHERAL_TO_USB];
- struct usb_bam_connect_info *connection = &usb_bam_connections[idx];
- struct usb_bam_event_info *wake_event_info =
- &connection->wake_event;
+ struct sps_pipe *pipe = ctx.usb_bam_sps.sps_pipes[idx];
+ struct sps_connect *sps_connection;
+ struct usb_bam_pipe_connect *pipe_connect;
+ struct usb_bam_event_info *wake_event_info;
int ret;
+ if (idx < 0 || idx > ctx.max_connections) {
+ pr_err("%s:idx is wrong %d", __func__, idx);
+ return -EINVAL;
+ }
+ pipe = ctx.usb_bam_sps.sps_pipes[idx];
+ sps_connection = &ctx.usb_bam_sps.sps_connections[idx];
+ pipe_connect = &usb_bam_connections[idx];
+ wake_event_info = &pipe_connect->wake_event;
+
wake_event_info->param = param;
wake_event_info->callback = callback;
wake_event_info->event.mode = SPS_TRIGGER_CALLBACK;
@@ -717,7 +738,7 @@
sps_connection->options = callback ?
(SPS_O_AUTO_ENABLE | SPS_O_WAKEUP | SPS_O_WAKEUP_IS_ONESHOT) :
- SPS_O_AUTO_ENABLE;
+ SPS_O_AUTO_ENABLE;
ret = sps_set_config(pipe, sps_connection);
if (ret) {
pr_err("%s: sps_set_config() failed %d\n", __func__, ret);
@@ -727,14 +748,13 @@
return 0;
}
-int usb_bam_register_peer_reset_cb(u8 idx,
- int (*callback)(void *), void *param)
+int usb_bam_register_peer_reset_cb(int (*callback)(void *), void *param)
{
u32 ret = 0;
if (callback) {
- peer_handhskae_info.reset_event.param = param;
- peer_handhskae_info.reset_event.callback = callback;
+ peer_handshake_info.reset_event.param = param;
+ peer_handshake_info.reset_event.callback = callback;
ret = smsm_state_cb_register(SMSM_MODEM_STATE,
SMSM_USB_PLUG_UNPLUG, usb_bam_ack_toggle_cb, NULL);
@@ -748,8 +768,8 @@
SMSM_USB_PLUG_UNPLUG);
}
} else {
- peer_handhskae_info.reset_event.param = NULL;
- peer_handhskae_info.reset_event.callback = NULL;
+ peer_handshake_info.reset_event.param = NULL;
+ peer_handshake_info.reset_event.callback = NULL;
smsm_state_cb_deregister(SMSM_MODEM_STATE,
SMSM_USB_PLUG_UNPLUG, usb_bam_ack_toggle_cb, NULL);
}
@@ -759,126 +779,110 @@
int usb_bam_disconnect_pipe(u8 idx)
{
- struct usb_bam_connect_info *connection = &usb_bam_connections[idx];
+ struct usb_bam_pipe_connect *pipe_connect;
int ret;
- if (idx >= CONNECTIONS_NUM) {
- pr_err("%s: Invalid connection index\n",
- __func__);
- return -EINVAL;
- }
+ pipe_connect = &usb_bam_connections[idx];
- if (!connection->src_enabled && !connection->dst_enabled) {
+ if (!pipe_connect->enabled) {
pr_debug("%s: connection %d isn't enabled\n",
__func__, idx);
return 0;
}
- if (connection->src_enabled) {
- /* close USB -> Peripheral pipe */
- ret = disconnect_pipe(connection->idx, USB_TO_PEER_PERIPHERAL);
- if (ret) {
- pr_err("%s: src pipe connection failure\n", __func__);
- return ret;
- }
- connection->src_enabled = 0;
- }
- if (connection->dst_enabled) {
- /* close Peripheral -> USB pipe */
- ret = disconnect_pipe(connection->idx, PEER_PERIPHERAL_TO_USB);
- if (ret) {
- pr_err("%s: dst pipe connection failure\n", __func__);
- return ret;
- }
- connection->dst_enabled = 0;
+ ret = disconnect_pipe(idx);
+ if (ret) {
+ pr_err("%s: src pipe connection failure\n", __func__);
+ return ret;
}
- connection->src_pipe = 0;
- connection->dst_pipe = 0;
+ pipe_connect->enabled = 0;
return 0;
}
-int usb_bam_disconnect_ipa(u8 idx,
- struct usb_bam_connect_ipa_params *ipa_params)
+int usb_bam_disconnect_ipa(struct usb_bam_connect_ipa_params *ipa_params)
{
- struct usb_bam_connect_info *connection = &usb_bam_connections[idx];
int ret;
+ u8 idx;
+ struct usb_bam_pipe_connect *pipe_connect;
- if (!usb_bam_pdev) {
- pr_err("%s: usb_bam device not found\n", __func__);
- return -ENODEV;
- }
-
- if (idx >= CONNECTIONS_NUM) {
- pr_err("%s: Invalid connection index\n",
- __func__);
- return -EINVAL;
- }
-
- /* Currently just calls ipa_disconnect, no sps pipes
- disconenction support */
-
- /* close IPA -> USB pipe */
- if (connection->dst_pipe) {
+ if (ipa_params->prod_clnt_hdl) {
+ /* close USB -> IPA pipe */
+ idx = ipa_params->src_idx;
ret = ipa_disconnect(ipa_params->prod_clnt_hdl);
if (ret) {
pr_err("%s: dst pipe disconnection failure\n",
__func__);
return ret;
}
+ pipe_connect = &usb_bam_connections[idx];
+ pipe_connect->enabled = 0;
}
- /* close USB -> IPA pipe */
- if (connection->src_pipe) {
+ if (ipa_params->cons_clnt_hdl) {
+ /* close IPA -> USB pipe */
+ idx = ipa_params->dst_idx;
ret = ipa_disconnect(ipa_params->cons_clnt_hdl);
if (ret) {
pr_err("%s: src pipe disconnection failure\n",
__func__);
return ret;
}
+ pipe_connect = &usb_bam_connections[idx];
+ pipe_connect->enabled = 0;
}
ipa_rm_release_resource(IPA_CLIENT_USB_PROD);
return 0;
-
}
+EXPORT_SYMBOL(usb_bam_disconnect_ipa);
-int usb_bam_reset(void)
+int usb_bam_a2_reset(void)
{
- struct usb_bam_connect_info *connection;
+ struct usb_bam_pipe_connect *pipe_connect;
int i;
int ret = 0, ret_int;
- bool reconnect[CONNECTIONS_NUM];
- u32 *reconnect_src_pipe[CONNECTIONS_NUM];
- u32 *reconnect_dst_pipe[CONNECTIONS_NUM];
+ u8 bam = -1;
+ int reconnect_pipe_idx[ctx.max_connections];
- /* Disconnect all pipes */
- for (i = 0; i < CONNECTIONS_NUM; i++) {
- connection = &usb_bam_connections[i];
- reconnect[i] = connection->src_enabled ||
- connection->dst_enabled;
- reconnect_src_pipe[i] = connection->src_pipe;
- reconnect_dst_pipe[i] = connection->dst_pipe;
+ for (i = 0; i < ctx.max_connections; i++)
+ reconnect_pipe_idx[i] = -1;
- ret_int = usb_bam_disconnect_pipe(i);
- if (ret_int) {
- pr_err("%s: failure to connect pipe %d\n",
- __func__, i);
- ret = ret_int;
- continue;
+ /* Disconnect a2 pipes */
+ for (i = 0; i < ctx.max_connections; i++) {
+ pipe_connect = &usb_bam_connections[i];
+ if (strnstr(pipe_connect->name, "a2", USB_BAM_MAX_STR_LEN) &&
+ pipe_connect->enabled) {
+ if (pipe_connect->dir == USB_TO_PEER_PERIPHERAL)
+ reconnect_pipe_idx[i] =
+ pipe_connect->src_pipe_index;
+ else
+ reconnect_pipe_idx[i] =
+ pipe_connect->dst_pipe_index;
+
+ bam = pipe_connect->bam_type;
+ if (bam < 0) {
+ ret = -EINVAL;
+ continue;
+ }
+ ret_int = usb_bam_disconnect_pipe(i);
+ if (ret_int) {
+ pr_err("%s: failure to connect pipe %d\n",
+ __func__, i);
+ ret = ret_int;
+ continue;
+ }
}
}
-
- /* Reset USB/HSIC BAM */
- if (sps_device_reset(h_bam))
+ /* Reset A2 (USB/HSIC) BAM */
+ if (bam != -1 && sps_device_reset(ctx.h_bam[bam]))
pr_err("%s: BAM reset failed\n", __func__);
- /* Reconnect all pipes */
- for (i = 0; i < CONNECTIONS_NUM; i++) {
- connection = &usb_bam_connections[i];
- if (reconnect[i]) {
- ret_int = usb_bam_connect(i, reconnect_src_pipe[i],
- reconnect_dst_pipe[i]);
+ /* Reconnect A2 pipes */
+ for (i = 0; i < ctx.max_connections; i++) {
+ pipe_connect = &usb_bam_connections[i];
+ if (reconnect_pipe_idx[i] != -1) {
+ ret_int = usb_bam_connect(i, &reconnect_pipe_idx[i]);
if (ret_int) {
pr_err("%s: failure to reconnect pipe %d\n",
__func__, i);
@@ -891,134 +895,23 @@
return ret;
}
-static int update_connections_info(struct device_node *node, int bam,
- int conn_num, int dir, enum usb_pipe_mem_type mem_type)
-{
- u32 rc;
- char *key = NULL;
- uint32_t val = 0;
-
- struct usb_bam_pipe_connect *pipe_connection;
-
- pipe_connection = &msm_usb_bam_connections_info[bam][conn_num][dir];
-
- pipe_connection->mem_type = mem_type;
-
- key = "qcom,src-bam-physical-address";
- rc = of_property_read_u32(node, key, &val);
- if (!rc)
- pipe_connection->src_phy_addr = val;
-
- key = "qcom,src-bam-pipe-index";
- rc = of_property_read_u32(node, key, &val);
- if (!rc)
- pipe_connection->src_pipe_index = val;
-
- key = "qcom,dst-bam-physical-address";
- rc = of_property_read_u32(node, key, &val);
- if (!rc)
- pipe_connection->dst_phy_addr = val;
-
- key = "qcom,dst-bam-pipe-index";
- rc = of_property_read_u32(node, key, &val);
- if (!rc)
- pipe_connection->dst_pipe_index = val;
-
- key = "qcom,data-fifo-offset";
- rc = of_property_read_u32(node, key, &val);
- if (!rc)
- pipe_connection->data_fifo_base_offset = val;
-
- key = "qcom,data-fifo-size";
- rc = of_property_read_u32(node, key, &val);
- if (rc)
- goto err;
- pipe_connection->data_fifo_size = val;
-
- key = "qcom,descriptor-fifo-offset";
- rc = of_property_read_u32(node, key, &val);
- if (!rc)
- pipe_connection->desc_fifo_base_offset = val;
-
- key = "qcom,descriptor-fifo-size";
- rc = of_property_read_u32(node, key, &val);
- if (rc)
- goto err;
- pipe_connection->desc_fifo_size = val;
-
- return 0;
-
-err:
- pr_err("%s: Error in name %s key %s\n", __func__,
- node->full_name, key);
- return -EFAULT;
-}
-
-static int usb_bam_update_conn_array_index(struct platform_device *pdev,
- void *buff, int bam_max, int conn_max, int pipe_dirs)
-{
- int bam_num, conn_num;
- struct usb_bam_pipe_connect *bam_connection_arr = buff;
-
- msm_usb_bam_connections_info = devm_kzalloc(&pdev->dev,
- bam_max * sizeof(struct usb_bam_pipe_connect **),
- GFP_KERNEL);
-
- if (!msm_usb_bam_connections_info)
- return -ENOMEM;
-
- for (bam_num = 0; bam_num < bam_max; bam_num++) {
- msm_usb_bam_connections_info[bam_num] =
- devm_kzalloc(&pdev->dev, conn_max *
- sizeof(struct usb_bam_pipe_connect *),
- GFP_KERNEL);
- if (!msm_usb_bam_connections_info[bam_num])
- return -ENOMEM;
-
- for (conn_num = 0; conn_num < conn_max; conn_num++)
- msm_usb_bam_connections_info[bam_num][conn_num] =
- bam_connection_arr +
- (bam_num * conn_max * pipe_dirs) +
- (conn_num * pipe_dirs);
- }
-
- return 0;
-}
-
static struct msm_usb_bam_platform_data *usb_bam_dt_to_pdata(
struct platform_device *pdev)
{
struct msm_usb_bam_platform_data *pdata;
struct device_node *node = pdev->dev.of_node;
- int conn_num, bam;
- u8 dir;
- u8 ncolumns = 2;
- int bam_amount, rc = 0;
- u32 pipe_entry = 0;
- char *key = NULL;
- enum usb_pipe_mem_type mem_type;
+ int rc = 0;
+ u8 i = 0;
bool reset_bam;
+ enum usb_bam bam;
+ ctx.max_connections = 0;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) {
pr_err("unable to allocate platform data\n");
return NULL;
}
- rc = of_property_read_u32(node, "qcom,usb-active-bam",
- &pdata->usb_active_bam);
- if (rc) {
- pr_err("Invalid usb active bam property\n");
- return NULL;
- }
-
- rc = of_property_read_u32(node, "qcom,usb-total-bam-num",
- &pdata->total_bam_num);
- if (rc) {
- pr_err("Invalid usb total bam num property\n");
- return NULL;
- }
-
rc = of_property_read_u32(node, "qcom,usb-bam-num-pipes",
&pdata->usb_bam_num_pipes);
if (rc) {
@@ -1032,91 +925,113 @@
pr_debug("%s: Invalid usb base address property\n", __func__);
pdata->ignore_core_reset_ack = of_property_read_bool(node,
- "qcom,ignore-core-reset-ack");
+ "qcom,ignore-core-reset-ack");
pdata->disable_clk_gating = of_property_read_bool(node,
- "qcom,disable-clk-gating");
+ "qcom,disable-clk-gating");
for_each_child_of_node(pdev->dev.of_node, node)
- pipe_entry++;
+ ctx.max_connections++;
- /*
- * we need to know the number of connection, so we will know
- * how much memory to allocate
- */
- conn_num = pipe_entry / 2;
- bam_amount = pdata->total_bam_num;
-
- if (conn_num <= 0 || conn_num >= pdata->usb_bam_num_pipes)
+ if (!ctx.max_connections) {
+ pr_err("%s: error: max_connections is zero\n", __func__);
goto err;
+ }
-
- /* alloc msm_usb_bam_connections_info */
- bam_connection_arr = devm_kzalloc(&pdev->dev, bam_amount *
- conn_num * ncolumns *
+ usb_bam_connections = devm_kzalloc(&pdev->dev, ctx.max_connections *
sizeof(struct usb_bam_pipe_connect), GFP_KERNEL);
- if (!bam_connection_arr)
- goto err;
-
- rc = usb_bam_update_conn_array_index(pdev, bam_connection_arr,
- bam_amount, conn_num, ncolumns);
- if (rc)
- goto err;
+ if (!usb_bam_connections) {
+ pr_err("%s: devm_kzalloc failed(%d)\n", __func__, __LINE__);
+ return NULL;
+ }
/* retrieve device tree parameters */
for_each_child_of_node(pdev->dev.of_node, node) {
- const char *str;
-
- key = "qcom,usb-bam-type";
- rc = of_property_read_u32(node, key, &bam);
+ rc = of_property_read_string(node, "label",
+ &usb_bam_connections[i].name);
if (rc)
goto err;
- key = "qcom,usb-bam-mem-type";
- rc = of_property_read_u32(node, key, &mem_type);
+ rc = of_property_read_u32(node, "qcom,usb-bam-mem-type",
+ &usb_bam_connections[i].mem_type);
if (rc)
goto err;
- if (mem_type == USB_PRIVATE_MEM &&
- !pdata->usb_base_address)
- goto err;
-
- rc = of_property_read_string(node, "label", &str);
- if (rc) {
- pr_err("Cannot read string\n");
+ if (usb_bam_connections[i].mem_type == USB_PRIVATE_MEM &&
+ !pdata->usb_base_address) {
+ pr_err("%s: base address is missing for private mem\n",
+ __func__);
goto err;
}
+
+ rc = of_property_read_u32(node, "qcom,bam-type",
+ &usb_bam_connections[i].bam_type);
+ if (rc) {
+ pr_err("%s: bam type is missing in device tree\n",
+ __func__);
+ goto err;
+ }
+
+ rc = of_property_read_u32(node, "qcom,peer-bam",
+ &usb_bam_connections[i].peer_bam);
+ if (rc) {
+ pr_err("%s: peer bam is missing in device tree\n",
+ __func__);
+ goto err;
+ }
+ rc = of_property_read_u32(node, "qcom,dir",
+ &usb_bam_connections[i].dir);
+ if (rc) {
+ pr_err("%s: direction is missing in device tree\n",
+ __func__);
+ goto err;
+ }
+
+ rc = of_property_read_u32(node, "qcom,pipe-num",
+ &usb_bam_connections[i].pipe_num);
+ if (rc) {
+ pr_err("%s: pipe num is missing in device tree\n",
+ __func__);
+ goto err;
+ }
+
reset_bam = of_property_read_bool(node,
- "qcom,reset-bam-on-connect");
+ "qcom,reset-bam-on-connect");
if (reset_bam)
pdata->reset_on_connect[bam] = true;
- if (strnstr(str, "usb-to", 30))
- dir = USB_TO_PEER_PERIPHERAL;
- else if (strnstr(str, "to-usb", 30))
- dir = PEER_PERIPHERAL_TO_USB;
- else
- goto err;
+ of_property_read_u32(node, "qcom,src-bam-physical-address",
+ &usb_bam_connections[i].src_phy_addr);
- /* Check if connection type is supported */
- if (!strcmp(str, "usb-to-peri-qdss-dwc3") ||
- !strcmp(str, "peri-to-usb-qdss-dwc3") ||
- !strcmp(str, "usb-to-ipa") ||
- !strcmp(str, "ipa-to-usb") ||
- !strcmp(str, "usb-to-peri-qdss-hsusb") ||
- !strcmp(str, "peri-to-usb-qdss-hsusb"))
- conn_num = 0;
- else
- goto err;
+ of_property_read_u32(node, "qcom,src-bam-pipe-index",
+ &usb_bam_connections[i].src_pipe_index);
- rc = update_connections_info(node, bam, conn_num,
- dir, mem_type);
+ of_property_read_u32(node, "qcom,dst-bam-physical-address",
+ &usb_bam_connections[i].dst_phy_addr);
+
+ of_property_read_u32(node, "qcom,dst-bam-pipe-index",
+ &usb_bam_connections[i].dst_pipe_index);
+
+ of_property_read_u32(node, "qcom,data-fifo-offset",
+ &usb_bam_connections[i].data_fifo_base_offset);
+
+ rc = of_property_read_u32(node, "qcom,data-fifo-size",
+ &usb_bam_connections[i].data_fifo_size);
if (rc)
goto err;
+
+ of_property_read_u32(node, "qcom,descriptor-fifo-offset",
+ &usb_bam_connections[i].desc_fifo_base_offset);
+
+ rc = of_property_read_u32(node, "qcom,descriptor-fifo-size",
+ &usb_bam_connections[i].desc_fifo_size);
+ if (rc)
+ goto err;
+ i++;
}
- pdata->connections = &msm_usb_bam_connections_info[0][0][0];
+ pdata->connections = usb_bam_connections;
return pdata;
err:
@@ -1124,83 +1039,78 @@
return NULL;
}
-static char *bam_enable_strings[3] = {
- [SSUSB_BAM] = "ssusb",
- [HSUSB_BAM] = "hsusb",
- [HSIC_BAM] = "hsic",
-};
-
-static int usb_bam_init(void)
+static int usb_bam_init(int bam_idx)
{
- int ret;
+ int ret, irq;
void *usb_virt_addr;
struct msm_usb_bam_platform_data *pdata =
- usb_bam_pdev->dev.platform_data;
- struct usb_bam_pipe_connect *pipe_connection =
- &msm_usb_bam_connections_info[pdata->usb_active_bam][0][0];
+ ctx.usb_bam_pdev->dev.platform_data;
struct resource *res, *ram_resource;
- int irq;
+ struct sps_bam_props props = ctx.usb_bam_sps.usb_props;
- res = platform_get_resource_byname(usb_bam_pdev, IORESOURCE_MEM,
- bam_enable_strings[pdata->usb_active_bam]);
+ pr_debug("%s: usb_bam_init - %s\n", __func__,
+ bam_enable_strings[bam_idx]);
+ res = platform_get_resource_byname(ctx.usb_bam_pdev, IORESOURCE_MEM,
+ bam_enable_strings[bam_idx]);
if (!res) {
- dev_err(&usb_bam_pdev->dev, "Unable to get memory resource\n");
- return -ENODEV;
+ dev_dbg(&ctx.usb_bam_pdev->dev, "bam not initialized\n");
+ return 0;
}
- irq = platform_get_irq_byname(usb_bam_pdev,
- bam_enable_strings[pdata->usb_active_bam]);
+ irq = platform_get_irq_byname(ctx.usb_bam_pdev,
+ bam_enable_strings[bam_idx]);
if (irq < 0) {
- dev_err(&usb_bam_pdev->dev, "Unable to get IRQ resource\n");
+ dev_err(&ctx.usb_bam_pdev->dev, "Unable to get IRQ resource\n");
return irq;
}
- usb_virt_addr = devm_ioremap(&usb_bam_pdev->dev, res->start,
- resource_size(res));
+ usb_virt_addr = devm_ioremap(&ctx.usb_bam_pdev->dev, res->start,
+ resource_size(res));
if (!usb_virt_addr) {
pr_err("%s: ioremap failed\n", __func__);
return -ENOMEM;
}
/* Check if USB3 pipe memory needs to be enabled */
- if (pipe_connection->mem_type == USB_PRIVATE_MEM) {
+ if (bam_idx == SSUSB_BAM && bam_use_private_mem(bam_idx)) {
pr_debug("%s: Enabling USB private memory for: %s\n", __func__,
- bam_enable_strings[pdata->usb_active_bam]);
+ bam_enable_strings[bam_idx]);
- ram_resource = platform_get_resource_byname(usb_bam_pdev,
- IORESOURCE_MEM, "qscratch_ram1_reg");
+ ram_resource = platform_get_resource_byname(ctx.usb_bam_pdev,
+ IORESOURCE_MEM, "qscratch_ram1_reg");
if (!res) {
- dev_err(&usb_bam_pdev->dev, "Unable to get qscratch\n");
+ dev_err(&ctx.usb_bam_pdev->dev, "Unable to get qscratch\n");
ret = -ENODEV;
goto free_bam_regs;
}
- qscratch_ram1_reg = devm_ioremap(&usb_bam_pdev->dev,
- ram_resource->start,
- resource_size(ram_resource));
- if (!qscratch_ram1_reg) {
+ ctx.qscratch_ram1_reg = devm_ioremap(&ctx.usb_bam_pdev->dev,
+ ram_resource->start,
+ resource_size(ram_resource));
+ if (!ctx.qscratch_ram1_reg) {
pr_err("%s: ioremap failed for qscratch\n", __func__);
ret = -ENOMEM;
goto free_bam_regs;
}
}
- usb_props.phys_addr = res->start;
- usb_props.virt_addr = usb_virt_addr;
- usb_props.virt_size = resource_size(res);
- usb_props.irq = irq;
- usb_props.summing_threshold = USB_SUMMING_THRESHOLD;
- usb_props.event_threshold = 512;
- usb_props.num_pipes = pdata->usb_bam_num_pipes;
+ props.phys_addr = res->start;
+ props.virt_addr = usb_virt_addr;
+ props.virt_size = resource_size(res);
+ props.irq = irq;
+ props.summing_threshold = USB_THRESHOLD;
+ props.event_threshold = USB_THRESHOLD;
+ props.num_pipes = pdata->usb_bam_num_pipes;
/*
- * HSUSB and HSIC Cores don't support RESET ACK signal to BAMs
- * Hence, let BAM to ignore acknowledge from USB while resetting PIPE
- */
- if (pdata->ignore_core_reset_ack && pdata->usb_active_bam != SSUSB_BAM)
- usb_props.options = SPS_BAM_NO_EXT_P_RST;
- if (pdata->disable_clk_gating)
- usb_props.options |= SPS_BAM_NO_LOCAL_CLK_GATING;
+ * HSUSB and HSIC Cores don't support RESET ACK signal to BAMs
+ * Hence, let BAM to ignore acknowledge from USB while resetting PIPE
+ */
+ if (pdata->ignore_core_reset_ack && bam_idx != SSUSB_BAM)
+ props.options = SPS_BAM_NO_EXT_P_RST;
- ret = sps_register_bam_device(&usb_props, &h_bam);
+ if (pdata->disable_clk_gating)
+ props.options |= SPS_BAM_NO_LOCAL_CLK_GATING;
+
+ ret = sps_register_bam_device(&props, &(ctx.h_bam[bam_idx]));
if (ret < 0) {
pr_err("%s: register bam error %d\n", __func__, ret);
ret = -EFAULT;
@@ -1210,61 +1120,46 @@
return 0;
free_qscratch_reg:
- iounmap(qscratch_ram1_reg);
+ iounmap(ctx.qscratch_ram1_reg);
free_bam_regs:
iounmap(usb_virt_addr);
return ret;
}
-static ssize_t
-usb_bam_show_enable(struct device *dev, struct device_attribute *attr,
- char *buf)
+static int enable_usb_bams(struct platform_device *pdev)
{
- struct msm_usb_bam_platform_data *pdata = dev->platform_data;
-
- if (!pdata)
- return 0;
- return scnprintf(buf, PAGE_SIZE, "%s\n",
- bam_enable_strings[pdata->usb_active_bam]);
-}
-
-static ssize_t usb_bam_store_enable(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct msm_usb_bam_platform_data *pdata = dev->platform_data;
- char str[10], *pstr;
int ret, i;
- if (!pdata) {
- dev_err(dev, "no usb_bam pdata found\n");
- return -ENODEV;
- }
-
- strlcpy(str, buf, sizeof(str));
- pstr = strim(str);
-
for (i = 0; i < ARRAY_SIZE(bam_enable_strings); i++) {
- if (!strncmp(pstr, bam_enable_strings[i], sizeof(str)))
- pdata->usb_active_bam = i;
+ ret = usb_bam_init(i);
+ if (ret) {
+ pr_err("failed to init usb bam %s\n",
+ bam_enable_strings[i]);
+ return ret;
+ }
}
- dev_dbg(dev, "active_bam=%s\n",
- bam_enable_strings[pdata->usb_active_bam]);
+ ctx.usb_bam_sps.sps_pipes = devm_kzalloc(&pdev->dev,
+ ctx.max_connections * sizeof(struct sps_pipe *),
+ GFP_KERNEL);
- ret = usb_bam_init();
- if (ret) {
- dev_err(dev, "failed to initialize usb bam\n");
- return ret;
+ if (!ctx.usb_bam_sps.sps_pipes) {
+ pr_err("%s: failed to allocate sps_pipes\n", __func__);
+ return -ENOMEM;
}
- return count;
+ ctx.usb_bam_sps.sps_connections = devm_kzalloc(&pdev->dev,
+ ctx.max_connections * sizeof(struct sps_connect),
+ GFP_KERNEL);
+ if (!ctx.usb_bam_sps.sps_connections) {
+ pr_err("%s: failed to allocate sps_connections\n", __func__);
+ return -ENOMEM;
+ }
+
+ return 0;
}
-static DEVICE_ATTR(enable, S_IWUSR | S_IRUSR, usb_bam_show_enable,
- usb_bam_store_enable);
-
static int usb_bam_probe(struct platform_device *pdev)
{
int ret, i;
@@ -1272,89 +1167,126 @@
dev_dbg(&pdev->dev, "usb_bam_probe\n");
- for (i = 0; i < CONNECTIONS_NUM; i++) {
- usb_bam_connections[i].src_enabled = 0;
- usb_bam_connections[i].dst_enabled = 0;
- INIT_WORK(&usb_bam_connections[i].wake_event.event_w,
- usb_bam_work);
- }
+ ctx.mem_clk = devm_clk_get(&pdev->dev, "mem_clk");
+ if (IS_ERR(ctx.mem_clk))
- spin_lock_init(&usb_bam_lock);
- INIT_WORK(&peer_handhskae_info.reset_event.event_w, usb_bam_sm_work);
- mem_clk = devm_clk_get(&pdev->dev, "mem_clk");
- if (IS_ERR(mem_clk))
dev_dbg(&pdev->dev, "failed to get mem_clock\n");
- mem_iface_clk = devm_clk_get(&pdev->dev, "mem_iface_clk");
- if (IS_ERR(mem_iface_clk))
+ ctx.mem_iface_clk = devm_clk_get(&pdev->dev, "mem_iface_clk");
+ if (IS_ERR(ctx.mem_iface_clk))
dev_dbg(&pdev->dev, "failed to get mem_iface_clock\n");
if (pdev->dev.of_node) {
dev_dbg(&pdev->dev, "device tree enabled\n");
pdata = usb_bam_dt_to_pdata(pdev);
if (!pdata)
- return -ENOMEM;
+ return -EINVAL;
pdev->dev.platform_data = pdata;
} else if (!pdev->dev.platform_data) {
dev_err(&pdev->dev, "missing platform_data\n");
return -ENODEV;
} else {
pdata = pdev->dev.platform_data;
- ret = usb_bam_update_conn_array_index(pdev, pdata->connections,
- MAX_BAMS, CONNECTIONS_NUM, 2);
- if (ret) {
- pr_err("usb_bam_update_conn_array_index failed\n");
- return ret;
- }
+ usb_bam_connections = pdata->connections;
+ ctx.max_connections = pdata->max_connections;
}
- usb_bam_pdev = pdev;
+ ctx.usb_bam_pdev = pdev;
- ret = device_create_file(&pdev->dev, &dev_attr_enable);
- if (ret)
- dev_err(&pdev->dev, "failed to create device file\n");
+ for (i = 0; i < ctx.max_connections; i++) {
+ usb_bam_connections[i].enabled = 0;
+ INIT_WORK(&usb_bam_connections[i].wake_event.event_w,
+ usb_bam_work);
+ }
- usb_bam_wq = alloc_workqueue("usb_bam_wq",
+ spin_lock_init(&usb_bam_lock);
+ INIT_WORK(&peer_handshake_info.reset_event.event_w, usb_bam_sm_work);
+
+ ctx.usb_bam_wq = alloc_workqueue("usb_bam_wq",
WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
- if (!usb_bam_wq) {
+ if (!ctx.usb_bam_wq) {
pr_err("unable to create workqueue usb_bam_wq\n");
return -ENOMEM;
}
+ ret = enable_usb_bams(pdev);
+ if (ret) {
+ destroy_workqueue(ctx.usb_bam_wq);
+ return ret;
+ }
usb_bam_ipa_create_resources();
return ret;
}
-void get_bam2bam_connection_info(u8 conn_idx, enum usb_bam_pipe_dir pipe_dir,
- u32 *usb_bam_handle, u32 *usb_bam_pipe_idx, u32 *peer_pipe_idx,
+int usb_bam_get_qdss_idx(u8 num)
+{
+ return usb_bam_get_connection_idx(ctx.qdss_core_name, QDSS_P_BAM,
+ PEER_PERIPHERAL_TO_USB, num);
+}
+EXPORT_SYMBOL(usb_bam_get_qdss_idx);
+
+void usb_bam_set_qdss_core(const char *qdss_core)
+{
+ strlcpy(ctx.qdss_core_name, qdss_core, USB_BAM_MAX_STR_LEN);
+}
+
+int get_bam2bam_connection_info(u8 idx, u32 *usb_bam_handle,
+ u32 *usb_bam_pipe_idx, u32 *peer_pipe_idx,
struct sps_mem_buffer *desc_fifo, struct sps_mem_buffer *data_fifo)
{
- struct sps_connect *connection =
- &sps_connections[conn_idx][pipe_dir];
+ struct usb_bam_pipe_connect *pipe_connect = &usb_bam_connections[idx];
+ enum usb_bam_pipe_dir dir = pipe_connect->dir;
+ struct sps_connect *sps_connection =
+ &ctx.usb_bam_sps.sps_connections[idx];
-
- if (pipe_dir == USB_TO_PEER_PERIPHERAL) {
- *usb_bam_handle = connection->source;
- *usb_bam_pipe_idx = connection->src_pipe_index;
- *peer_pipe_idx = connection->dest_pipe_index;
+ if (dir == USB_TO_PEER_PERIPHERAL) {
+ *usb_bam_handle = sps_connection->source;
+ *usb_bam_pipe_idx = sps_connection->src_pipe_index;
+ *peer_pipe_idx = sps_connection->dest_pipe_index;
} else {
- *usb_bam_handle = connection->destination;
- *usb_bam_pipe_idx = connection->dest_pipe_index;
- *peer_pipe_idx = connection->src_pipe_index;
+ *usb_bam_handle = sps_connection->destination;
+ *usb_bam_pipe_idx = sps_connection->dest_pipe_index;
+ *peer_pipe_idx = sps_connection->src_pipe_index;
}
if (data_fifo)
- memcpy(data_fifo, &data_mem_buf[conn_idx][pipe_dir],
- sizeof(struct sps_mem_buffer));
+ memcpy(data_fifo, &pipe_connect->data_mem_buf,
+ sizeof(struct sps_mem_buffer));
if (desc_fifo)
- memcpy(desc_fifo, &desc_mem_buf[conn_idx][pipe_dir],
- sizeof(struct sps_mem_buffer));
+ memcpy(desc_fifo, &pipe_connect->desc_mem_buf,
+ sizeof(struct sps_mem_buffer));
+ return 0;
}
EXPORT_SYMBOL(get_bam2bam_connection_info);
+
+int usb_bam_get_connection_idx(const char *core_name, enum peer_bam client,
+ enum usb_bam_pipe_dir dir, u32 num)
+{
+ u8 i;
+ int bam_type;
+
+ bam_type = get_bam_type_from_core_name(core_name);
+ if (bam_type < 0)
+ return -EINVAL;
+
+ for (i = 0; i < ctx.max_connections; i++)
+ if (usb_bam_connections[i].bam_type == bam_type &&
+ usb_bam_connections[i].peer_bam == client &&
+ usb_bam_connections[i].dir == dir &&
+ usb_bam_connections[i].pipe_num == num) {
+ pr_debug("%s: index %d was found\n", __func__, i);
+ return i;
+ }
+
+ pr_err("%s: failed for %s\n", __func__, core_name);
+ return -ENODEV;
+}
+EXPORT_SYMBOL(usb_bam_get_connection_idx);
+
static int usb_bam_remove(struct platform_device *pdev)
{
- destroy_workqueue(usb_bam_wq);
+ destroy_workqueue(ctx.usb_bam_wq);
return 0;
}
diff --git a/drivers/usb/gadget/f_mbim.c b/drivers/usb/gadget/f_mbim.c
index a32dd15..893f315 100644
--- a/drivers/usb/gadget/f_mbim.c
+++ b/drivers/usb/gadget/f_mbim.c
@@ -662,19 +662,30 @@
static int mbim_bam_connect(struct f_mbim *dev)
{
int ret;
+ u8 src_connection_idx, dst_connection_idx;
+ struct usb_gadget *gadget = dev->cdev->gadget;
pr_info("dev:%p portno:%d\n", dev, dev->port_num);
+ src_connection_idx = usb_bam_get_connection_idx(gadget->name, A2_P_BAM,
+ USB_TO_PEER_PERIPHERAL, dev->port_num);
+ dst_connection_idx = usb_bam_get_connection_idx(gadget->name, A2_P_BAM,
+ PEER_PERIPHERAL_TO_USB, dev->port_num);
+ if (src_connection_idx < 0 || dst_connection_idx < 0) {
+ pr_err("%s: usb_bam_get_connection_idx failed\n", __func__);
+ return ret;
+ }
+
ret = bam_data_connect(&dev->bam_port, dev->port_num,
- USB_GADGET_XPORT_BAM2BAM, dev->port_num, USB_FUNC_MBIM);
+ USB_GADGET_XPORT_BAM2BAM, src_connection_idx,
+ dst_connection_idx, USB_FUNC_MBIM);
if (ret) {
pr_err("bam_data_setup failed: err:%d\n",
ret);
return ret;
- } else {
- pr_info("mbim bam connected\n");
}
+ pr_info("mbim bam connected\n");
return 0;
}
diff --git a/drivers/usb/gadget/f_qc_ecm.c b/drivers/usb/gadget/f_qc_ecm.c
index 559fd04..51f0e50 100644
--- a/drivers/usb/gadget/f_qc_ecm.c
+++ b/drivers/usb/gadget/f_qc_ecm.c
@@ -390,14 +390,27 @@
static int ecm_qc_bam_connect(struct f_ecm_qc *dev)
{
int ret;
+ u8 src_connection_idx, dst_connection_idx;
+ struct usb_composite_dev *cdev = dev->port.func.config->cdev;
+ struct usb_gadget *gadget = cdev->gadget;
+ enum peer_bam peer_bam = (dev->xport == USB_GADGET_XPORT_BAM2BAM_IPA) ?
+ IPA_P_BAM : A2_P_BAM;
- ecm_qc_bam_port.cdev = dev->port.func.config->cdev;
+ ecm_qc_bam_port.cdev = cdev;
ecm_qc_bam_port.in = dev->port.in_ep;
ecm_qc_bam_port.out = dev->port.out_ep;
/* currently we use the first connection */
+ src_connection_idx = usb_bam_get_connection_idx(gadget->name, peer_bam,
+ USB_TO_PEER_PERIPHERAL, 0);
+ dst_connection_idx = usb_bam_get_connection_idx(gadget->name, peer_bam,
+ PEER_PERIPHERAL_TO_USB, 0);
+ if (src_connection_idx < 0 || dst_connection_idx < 0) {
+ pr_err("%s: usb_bam_get_connection_idx failed\n", __func__);
+ return ret;
+ }
ret = bam_data_connect(&ecm_qc_bam_port, 0, dev->xport,
- 0, USB_FUNC_ECM);
+ src_connection_idx, dst_connection_idx, USB_FUNC_ECM);
if (ret) {
pr_err("bam_data_connect failed: err:%d\n", ret);
return ret;
diff --git a/drivers/usb/gadget/f_qc_rndis.c b/drivers/usb/gadget/f_qc_rndis.c
index 51d7bc1..8b01176 100644
--- a/drivers/usb/gadget/f_qc_rndis.c
+++ b/drivers/usb/gadget/f_qc_rndis.c
@@ -421,22 +421,33 @@
static int rndis_qc_bam_connect(struct f_rndis_qc *dev)
{
int ret;
+ u8 src_connection_idx, dst_connection_idx;
+ struct usb_composite_dev *cdev = dev->port.func.config->cdev;
+ struct usb_gadget *gadget = cdev->gadget;
- dev->bam_port.cdev = dev->port.func.config->cdev;
+ dev->bam_port.cdev = cdev;
dev->bam_port.in = dev->port.in_ep;
dev->bam_port.out = dev->port.out_ep;
/* currently we use the first connection */
+ src_connection_idx = usb_bam_get_connection_idx(gadget->name, A2_P_BAM,
+ USB_TO_PEER_PERIPHERAL, 0);
+ dst_connection_idx = usb_bam_get_connection_idx(gadget->name, A2_P_BAM,
+ PEER_PERIPHERAL_TO_USB, 0);
+ if (src_connection_idx < 0 || dst_connection_idx < 0) {
+ pr_err("%s: usb_bam_get_connection_idx failed\n", __func__);
+ return ret;
+ }
ret = bam_data_connect(&dev->bam_port, 0, USB_GADGET_XPORT_BAM2BAM,
- 0, USB_FUNC_RNDIS);
+ src_connection_idx, dst_connection_idx, USB_FUNC_RNDIS);
if (ret) {
pr_err("bam_data_connect failed: err:%d\n",
ret);
return ret;
- } else {
- pr_info("rndis bam connected\n");
}
+ pr_info("rndis bam connected\n");
+
return 0;
}
diff --git a/drivers/usb/gadget/f_qdss.c b/drivers/usb/gadget/f_qdss.c
index 3069bcb..6518095 100644
--- a/drivers/usb/gadget/f_qdss.c
+++ b/drivers/usb/gadget/f_qdss.c
@@ -1,7 +1,7 @@
/*
* f_qdss.c -- QDSS function Driver
*
- * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -447,8 +447,8 @@
qdss->ch.notify(qdss->ch.priv, USB_QDSS_DISCONNECT, NULL,
NULL);
/* If the app was never started, we can skip USB BAM reset */
- status = set_qdss_data_connection(qdss->data,
- qdss->data->address, 0);
+ status = set_qdss_data_connection(qdss->cdev->gadget,
+ qdss->data, qdss->data->address, 0);
if (status)
pr_err("qdss_disconnect error");
}
@@ -490,7 +490,7 @@
return;
}
- status = set_qdss_data_connection(qdss->data,
+ status = set_qdss_data_connection(qdss->cdev->gadget, qdss->data,
qdss->data->address, 1);
if (status) {
pr_err("set_qdss_data_connection error");
diff --git a/drivers/usb/gadget/f_rmnet.c b/drivers/usb/gadget/f_rmnet.c
index af68827..4b9dfbf 100644
--- a/drivers/usb/gadget/f_rmnet.c
+++ b/drivers/usb/gadget/f_rmnet.c
@@ -387,6 +387,8 @@
unsigned port_num;
enum transport_type cxport = rmnet_ports[dev->port_num].ctrl_xport;
enum transport_type dxport = rmnet_ports[dev->port_num].data_xport;
+ u8 src_connection_idx, dst_connection_idx;
+ struct usb_gadget *gadget = dev->cdev->gadget;
pr_debug("%s: ctrl xport: %s data xport: %s dev: %p portno: %d\n",
__func__, xport_to_str(cxport), xport_to_str(dxport),
@@ -435,12 +437,42 @@
}
port_num = rmnet_ports[dev->port_num].data_xport_num;
+
switch (dxport) {
case USB_GADGET_XPORT_BAM:
case USB_GADGET_XPORT_BAM2BAM:
- case USB_GADGET_XPORT_BAM2BAM_IPA:
+ src_connection_idx = usb_bam_get_connection_idx(gadget->name,
+ A2_P_BAM, USB_TO_PEER_PERIPHERAL, port_num);
+ dst_connection_idx = usb_bam_get_connection_idx(gadget->name,
+ A2_P_BAM, PEER_PERIPHERAL_TO_USB, port_num);
+ if (dst_connection_idx < 0 || src_connection_idx < 0) {
+ pr_err("%s: usb_bam_get_connection_idx failed\n",
+ __func__);
+ gsmd_ctrl_disconnect(&dev->port, port_num);
+ return ret;
+ }
ret = gbam_connect(&dev->port, port_num,
- dxport, port_num);
+ dxport, src_connection_idx, dst_connection_idx);
+ if (ret) {
+ pr_err("%s: gbam_connect failed: err:%d\n",
+ __func__, ret);
+ gsmd_ctrl_disconnect(&dev->port, port_num);
+ return ret;
+ }
+ break;
+ case USB_GADGET_XPORT_BAM2BAM_IPA:
+ src_connection_idx = usb_bam_get_connection_idx(gadget->name,
+ IPA_P_BAM, USB_TO_PEER_PERIPHERAL, port_num);
+ dst_connection_idx = usb_bam_get_connection_idx(gadget->name,
+ IPA_P_BAM, PEER_PERIPHERAL_TO_USB, port_num);
+ if (dst_connection_idx < 0 || src_connection_idx < 0) {
+ pr_err("%s: usb_bam_get_connection_idx failed\n",
+ __func__);
+ gsmd_ctrl_disconnect(&dev->port, port_num);
+ return ret;
+ }
+ ret = gbam_connect(&dev->port, port_num,
+ dxport, src_connection_idx, dst_connection_idx);
if (ret) {
pr_err("%s: gbam_connect failed: err:%d\n",
__func__, ret);
diff --git a/drivers/usb/gadget/u_bam.c b/drivers/usb/gadget/u_bam.c
index 5a6faf2..3c3fbca 100644
--- a/drivers/usb/gadget/u_bam.c
+++ b/drivers/usb/gadget/u_bam.c
@@ -100,7 +100,8 @@
u32 src_pipe_idx;
u32 dst_pipe_idx;
- u8 connection_idx;
+ u8 src_connection_idx;
+ u8 dst_connection_idx;
enum transport_type trans;
struct usb_bam_connect_ipa_params ipa_params;
@@ -663,7 +664,7 @@
int ret;
if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
- ret = usb_bam_disconnect_ipa(d->connection_idx, &d->ipa_params);
+ ret = usb_bam_disconnect_ipa(&d->ipa_params);
if (ret)
pr_err("%s: usb_bam_disconnect_ipa failed: err:%d\n",
__func__, ret);
@@ -715,10 +716,15 @@
int ret;
if (d->trans == USB_GADGET_XPORT_BAM2BAM) {
- ret = usb_bam_connect(d->connection_idx, &d->src_pipe_idx,
- &d->dst_pipe_idx);
+ ret = usb_bam_connect(d->src_connection_idx, &d->src_pipe_idx);
if (ret) {
- pr_err("%s: usb_bam_connect failed: err:%d\n",
+ pr_err("%s: usb_bam_connect (src) failed: err:%d\n",
+ __func__, ret);
+ return;
+ }
+ ret = usb_bam_connect(d->dst_connection_idx, &d->dst_pipe_idx);
+ if (ret) {
+ pr_err("%s: usb_bam_connect (dst) failed: err:%d\n",
__func__, ret);
return;
}
@@ -787,8 +793,7 @@
if (d->trans == USB_GADGET_XPORT_BAM2BAM && port->port_num == 0) {
/* Register for peer reset callback */
- usb_bam_register_peer_reset_cb(d->connection_idx,
- gbam_peer_reset_cb, port);
+ usb_bam_register_peer_reset_cb(gbam_peer_reset_cb, port);
ret = usb_bam_client_ready(true);
if (ret) {
@@ -832,7 +837,7 @@
msm_hw_bam_disable(1);
/* Reset BAM */
- ret = usb_bam_reset();
+ ret = usb_bam_a2_reset();
if (ret) {
pr_err("%s: BAM reset failed %d\n", __func__, ret);
goto reenable_eps;
@@ -867,7 +872,7 @@
/* Unregister the peer reset callback */
if (d->trans == USB_GADGET_XPORT_BAM2BAM && port->port_num == 0)
- usb_bam_register_peer_reset_cb(d->connection_idx, NULL, NULL);
+ usb_bam_register_peer_reset_cb(NULL, NULL);
return 0;
}
@@ -1216,7 +1221,8 @@
}
int gbam_connect(struct grmnet *gr, u8 port_num,
- enum transport_type trans, u8 connection_idx)
+ enum transport_type trans, u8 src_connection_idx,
+ u8 dst_connection_idx)
{
struct gbam_port *port;
struct bam_ch_info *d;
@@ -1283,12 +1289,14 @@
if (trans == USB_GADGET_XPORT_BAM2BAM) {
port->gr = gr;
- d->connection_idx = connection_idx;
+ d->src_connection_idx = src_connection_idx;
+ d->dst_connection_idx = dst_connection_idx;
} else if (trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
port->gr = gr;
d->ipa_params.src_pipe = &(d->src_pipe_idx);
d->ipa_params.dst_pipe = &(d->dst_pipe_idx);
- d->ipa_params.idx = connection_idx;
+ d->ipa_params.src_idx = src_connection_idx;
+ d->ipa_params.dst_idx = dst_connection_idx;
}
d->trans = trans;
@@ -1379,7 +1387,7 @@
pr_debug("%s: suspended port %d\n", __func__, port_num);
- usb_bam_register_wake_cb(d->connection_idx, gbam_wake_cb, port);
+ usb_bam_register_wake_cb(d->dst_connection_idx, gbam_wake_cb, port);
}
void gbam_resume(struct grmnet *gr, u8 port_num, enum transport_type trans)
@@ -1396,5 +1404,5 @@
pr_debug("%s: resumed port %d\n", __func__, port_num);
- usb_bam_register_wake_cb(d->connection_idx, NULL, NULL);
+ usb_bam_register_wake_cb(d->dst_connection_idx, NULL, NULL);
}
diff --git a/drivers/usb/gadget/u_bam_data.c b/drivers/usb/gadget/u_bam_data.c
index 700d07f..83f885a 100644
--- a/drivers/usb/gadget/u_bam_data.c
+++ b/drivers/usb/gadget/u_bam_data.c
@@ -47,7 +47,8 @@
u32 src_pipe_idx;
u32 dst_pipe_idx;
- u8 connection_idx;
+ u8 src_connection_idx;
+ u8 dst_connection_idx;
enum function_type func_type;
enum transport_type trans;
@@ -135,7 +136,7 @@
msm_hw_bam_disable(1);
/* Reset BAM */
- ret = usb_bam_reset();
+ ret = usb_bam_a2_reset();
if (ret) {
pr_err("%s: BAM reset failed %d\n", __func__, ret);
goto reenable_eps;
@@ -169,7 +170,7 @@
}
/* Unregister the peer reset callback */
- usb_bam_register_peer_reset_cb(d->connection_idx, NULL, NULL);
+ usb_bam_register_peer_reset_cb(NULL, NULL);
return 0;
}
@@ -184,7 +185,7 @@
if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
if (d->func_type == USB_FUNC_ECM)
ecm_ipa_disconnect(d->ipa_params.priv);
- ret = usb_bam_disconnect_ipa(d->connection_idx, &d->ipa_params);
+ ret = usb_bam_disconnect_ipa(&d->ipa_params);
if (ret)
pr_err("usb_bam_disconnect_ipa failed: err:%d\n", ret);
}
@@ -237,13 +238,17 @@
}
}
} else { /* transport type is USB_GADGET_XPORT_BAM2BAM */
- ret = usb_bam_connect(d->connection_idx, &d->src_pipe_idx,
- &d->dst_pipe_idx);
- if (ret) {
- pr_err("usb_bam_connect failed: err:%d\n", ret);
- return;
- }
+ ret = usb_bam_connect(d->src_connection_idx, &d->src_pipe_idx);
+ if (ret) {
+ pr_err("usb_bam_connect (src) failed: err:%d\n", ret);
+ return;
}
+ ret = usb_bam_connect(d->dst_connection_idx, &d->dst_pipe_idx);
+ if (ret) {
+ pr_err("usb_bam_connect (dst) failed: err:%d\n", ret);
+ return;
+ }
+}
if (!port->port_usb) {
pr_err("port_usb is NULL");
@@ -282,8 +287,7 @@
/* Register for peer reset callback if USB_GADGET_XPORT_BAM2BAM */
if (d->trans != USB_GADGET_XPORT_BAM2BAM_IPA) {
- usb_bam_register_peer_reset_cb(d->connection_idx,
- bam_data_peer_reset_cb, port);
+ usb_bam_register_peer_reset_cb(bam_data_peer_reset_cb, port);
ret = usb_bam_client_ready(true);
if (ret) {
@@ -369,7 +373,8 @@
}
int bam_data_connect(struct data_port *gr, u8 port_num,
- enum transport_type trans, u8 connection_idx, enum function_type func)
+ enum transport_type trans, u8 src_connection_idx,
+ u8 dst_connection_idx, enum function_type func)
{
struct bam_data_port *port;
struct bam_data_ch_info *d;
@@ -408,14 +413,16 @@
port->port_usb = gr;
- d->connection_idx = connection_idx;
+ d->src_connection_idx = src_connection_idx;
+ d->dst_connection_idx = dst_connection_idx;
d->trans = trans;
if (trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
d->ipa_params.src_pipe = &(d->src_pipe_idx);
d->ipa_params.dst_pipe = &(d->dst_pipe_idx);
- d->ipa_params.idx = connection_idx;
+ d->ipa_params.src_idx = src_connection_idx;
+ d->ipa_params.dst_idx = dst_connection_idx;
}
d->func_type = func;
@@ -499,7 +506,7 @@
d = &port->data_ch;
pr_debug("%s: suspended port %d\n", __func__, port_num);
- usb_bam_register_wake_cb(d->connection_idx, bam_data_wake_cb, port);
+ usb_bam_register_wake_cb(d->dst_connection_idx, bam_data_wake_cb, port);
}
void bam_data_resume(u8 port_num)
@@ -512,6 +519,6 @@
d = &port->data_ch;
pr_debug("%s: resumed port %d\n", __func__, port_num);
- usb_bam_register_wake_cb(d->connection_idx, NULL, NULL);
+ usb_bam_register_wake_cb(d->dst_connection_idx, NULL, NULL);
}
diff --git a/drivers/usb/gadget/u_bam_data.h b/drivers/usb/gadget/u_bam_data.h
index 71a01b9..486191b5 100644
--- a/drivers/usb/gadget/u_bam_data.h
+++ b/drivers/usb/gadget/u_bam_data.h
@@ -30,7 +30,8 @@
void bam_data_disconnect(struct data_port *gr, u8 port_num);
int bam_data_connect(struct data_port *gr, u8 port_num,
- enum transport_type trans, u8 connection_idx, enum function_type func);
+ enum transport_type trans, u8 src_connection_idx,
+ u8 dst_connection_idx, enum function_type func);
int bam_data_setup(unsigned int no_bam2bam_port);
diff --git a/drivers/usb/gadget/u_qdss.c b/drivers/usb/gadget/u_qdss.c
index 028d5e6..e241e29 100644
--- a/drivers/usb/gadget/u_qdss.c
+++ b/drivers/usb/gadget/u_qdss.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -15,8 +15,6 @@
#include <linux/usb/msm_hsusb.h>
#include <mach/usb_bam.h>
-#define BAM_CONNC_IDX 0 /* USB bam connection index */
-
struct usb_qdss_bam_connect_info {
u32 usb_bam_pipe_idx;
u32 peer_pipe_idx;
@@ -60,28 +58,33 @@
return 0;
}
-int set_qdss_data_connection(struct usb_ep *data_ep, u8 data_addr, int enable)
+static int set_qdss_data_connection(struct usb_gadget *gadget,
+ struct usb_ep *data_ep, u8 data_addr, int enable)
{
int res = 0;
+ u8 idx;
pr_debug("set_qdss_data_connection\n");
- if (enable) {
- res = usb_bam_connect(BAM_CONNC_IDX, NULL,
- &(bam_info.usb_bam_pipe_idx));
- if (res) {
- pr_err("usb_bam_connection error\n");
- return res;
- }
+ /* There is only one qdss pipe, so the pipe number can be set to 0 */
+ idx = usb_bam_get_connection_idx(gadget->name, QDSS_P_BAM,
+ PEER_PERIPHERAL_TO_USB, 0);
+ if (idx < 0) {
+ pr_err("%s: usb_bam_get_connection_idx failed\n", __func__);
+ return idx;
+ }
+ if (enable) {
+ res = usb_bam_connect(idx, &(bam_info.usb_bam_pipe_idx));
bam_info.data_fifo =
kzalloc(sizeof(struct sps_mem_buffer *), GFP_KERNEL);
if (!bam_info.data_fifo) {
pr_err("qdss_data_connection: memory alloc failed\n");
return -ENOMEM;
}
- get_bam2bam_connection_info(BAM_CONNC_IDX,
- PEER_PERIPHERAL_TO_USB, &bam_info.usb_bam_handle,
+ usb_bam_set_qdss_core(gadget->name);
+ get_bam2bam_connection_info(idx,
+ &bam_info.usb_bam_handle,
&bam_info.usb_bam_pipe_idx, &bam_info.peer_pipe_idx,
NULL, bam_info.data_fifo);
@@ -89,13 +92,13 @@
bam_info.data_fifo->size, bam_info.usb_bam_pipe_idx);
} else {
kfree(bam_info.data_fifo);
- res = usb_bam_disconnect_pipe(BAM_CONNC_IDX);
+ res = usb_bam_disconnect_pipe(idx);
if (res) {
pr_err("usb_bam_disconnection error\n");
return res;
}
-
}
+
return res;
}
diff --git a/drivers/usb/gadget/u_rmnet.h b/drivers/usb/gadget/u_rmnet.h
index cea9369..a9cca50 100644
--- a/drivers/usb/gadget/u_rmnet.h
+++ b/drivers/usb/gadget/u_rmnet.h
@@ -48,8 +48,10 @@
int gbam_setup(unsigned int no_bam_port, unsigned int no_bam2bam_port);
int gbam_connect(struct grmnet *gr, u8 port_num,
- enum transport_type trans, u8 connection_idx);
-void gbam_disconnect(struct grmnet *gr, u8 port_num, enum transport_type trans);
+ enum transport_type trans, u8 src_connection_idx,
+ u8 dst_connection_idx);
+void gbam_disconnect(struct grmnet *gr, u8 port_num,
+ enum transport_type trans);
void gbam_suspend(struct grmnet *gr, u8 port_num, enum transport_type trans);
void gbam_resume(struct grmnet *gr, u8 port_num, enum transport_type trans);
int gsmd_ctrl_connect(struct grmnet *gr, int port_num);
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index c5943c9..48e7155 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -1,4 +1,4 @@
-/* linux/include/asm-arm/arch-msm/hsusb.h
+/* include/linux/usb/msm_hsusb.h
*
* Copyright (C) 2008 Google, Inc.
* Author: Brian Swetland <swetland@google.com>
@@ -432,68 +432,6 @@
bool core_clk_always_on_workaround;
};
-enum usb_pipe_mem_type {
- SPS_PIPE_MEM = 0, /* Default, SPS dedicated pipe memory */
- USB_PRIVATE_MEM, /* USB's private memory */
- SYSTEM_MEM, /* System RAM, requires allocation */
-};
-
-/**
- * struct usb_bam_pipe_connect: pipe connection information
- * between USB/HSIC BAM and another BAM. USB/HSIC BAM can be
- * either src BAM or dst BAM
- * @src_phy_addr: src bam physical address.
- * @src_pipe_index: src bam pipe index.
- * @dst_phy_addr: dst bam physical address.
- * @dst_pipe_index: dst bam pipe index.
- * @mem_type: type of memory used for BAM FIFOs
- * @data_fifo_base_offset: data fifo offset.
- * @data_fifo_size: data fifo size.
- * @desc_fifo_base_offset: descriptor fifo offset.
- * @desc_fifo_size: descriptor fifo size.
- */
-struct usb_bam_pipe_connect {
- u32 src_phy_addr;
- u32 src_pipe_index;
- u32 dst_phy_addr;
- u32 dst_pipe_index;
- enum usb_pipe_mem_type mem_type;
- u32 data_fifo_base_offset;
- u32 data_fifo_size;
- u32 desc_fifo_base_offset;
- u32 desc_fifo_size;
-};
-
-enum usb_bam {
- SSUSB_BAM = 0,
- HSUSB_BAM,
- HSIC_BAM,
- MAX_BAMS,
-};
-
-/**
- * struct msm_usb_bam_platform_data: pipe connection information
- * between USB/HSIC BAM and another BAM. USB/HSIC BAM can be
- * either src BAM or dst BAM
- * @connections: holds all pipe connections data.
- * @usb_active_bam: set USB or HSIC as the active BAM.
- * @usb_bam_num_pipes: max number of pipes to use.
- * @active_conn_num: number of active pipe connections.
- * @usb_base_address: BAM physical address.
- * @ignore_core_reset_ack: BAM can ignore ACK from USB core during PIPE RESET
- * @disable_clk_gating: Disable clock gating
- */
-struct msm_usb_bam_platform_data {
- struct usb_bam_pipe_connect *connections;
- int usb_active_bam;
- int usb_bam_num_pipes;
- u32 total_bam_num;
- u32 usb_base_address;
- bool ignore_core_reset_ack;
- bool reset_on_connect[MAX_BAMS];
- bool disable_clk_gating;
-};
-
/**
* struct usb_ext_notification: event notification structure
* @notify: pointer to client function to call when ID event is detected.