Merge "hwmon: qpnp-adc: Add PMIC QPNP IADC driver" into msm-3.4
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index f144421..0c6b9e6 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -359,9 +359,9 @@
l2_hfpll_b-supply = <&pm8941_l12_ao>;
};
- qcom,ssusb@F9200000 {
+ qcom,ssusb@f9200000 {
compatible = "qcom,dwc-usb3-msm";
- reg = <0xF9200000 0xFA000>;
+ reg = <0xf9200000 0xfc000>;
interrupts = <0 131 0 0 179 0>;
interrupt-names = "irq", "otg_irq";
SSUSB_VDDCX-supply = <&pm8841_s2>;
@@ -628,6 +628,42 @@
interrupts = <0 235 0>;
qcom,bam-pipes = <1>;
};
+
+ qcom,usbbam@f9304000 {
+ compatible = "qcom,usb-bam-msm";
+ reg = <0xf9304000 0x9000>;
+ interrupts = <0 132 0>;
+ qcom,usb-active-bam = <0>;
+ qcom,usb-total-bam-num = <1>;
+ qcom,usb-bam-num-pipes = <16>;
+ qcom,usb-base-address = <0xf9200000>;
+
+ qcom,pipe1 {
+ label = "usb-to-peri-qdss-dwc3";
+ qcom,usb-bam-type = <0>;
+ 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,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>;
+ };
+ };
};
/include/ "msm-pm8x41-rpm-regulator.dtsi"
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h
index 37cbfcb..0d0103a 100644
--- a/arch/arm/include/asm/pmu.h
+++ b/arch/arm/include/asm/pmu.h
@@ -108,6 +108,12 @@
enum arm_pmu_type type;
cpumask_t active_irqs;
const char *name;
+ int num_events;
+ atomic_t active_events;
+ struct mutex reserve_mutex;
+ u64 max_period;
+ struct platform_device *plat_device;
+ u32 from_idle;
irqreturn_t (*handle_irq)(int irq_num, void *dev);
int (*request_pmu_irq)(int irq, irq_handler_t *irq_h);
void (*free_pmu_irq)(int irq);
@@ -123,11 +129,6 @@
void (*stop)(void);
void (*reset)(void *);
int (*map_event)(struct perf_event *event);
- int num_events;
- atomic_t active_events;
- struct mutex reserve_mutex;
- u64 max_period;
- struct platform_device *plat_device;
struct pmu_hw_events *(*get_hw_events)(void);
int (*test_set_event_constraints)(struct perf_event *event);
int (*clear_event_constraints)(struct perf_event *event);
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 778128b..e97aef2 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -600,6 +600,21 @@
struct arm_pmu *armpmu = to_arm_pmu(pmu);
struct pmu_hw_events *hw_events = armpmu->get_hw_events();
int enabled = bitmap_weight(hw_events->used_mask, armpmu->num_events);
+ int idx;
+
+ if (armpmu->from_idle) {
+ for (idx = 0; idx <= cpu_pmu->num_events; ++idx) {
+ struct perf_event *event = hw_events->events[idx];
+
+ if (!event)
+ continue;
+
+ armpmu->enable(&event->hw, idx, event->cpu);
+ }
+
+ /* Reset bit so we don't needlessly re-enable counters.*/
+ armpmu->from_idle = 0;
+ }
if (enabled)
armpmu->start();
@@ -716,6 +731,7 @@
* UNKNOWN at reset, the PMU must be explicitly reset to avoid reading
* junk values out of them.
*/
+
static int __cpuinit pmu_cpu_notify(struct notifier_block *b,
unsigned long action, void *hcpu)
{
@@ -785,6 +801,11 @@
case CPU_PM_ENTER_FAILED:
case CPU_PM_EXIT:
if (cpu_has_active_perf() && cpu_pmu->reset) {
+ /*
+ * Flip this bit so armpmu_enable knows it needs
+ * to re-enable active counters.
+ */
+ cpu_pmu->from_idle = 1;
cpu_pmu->reset(NULL);
perf_pmu_enable(&cpu_pmu->pmu);
}
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index 7898cf6..f57771c 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -493,6 +493,22 @@
},
},
};
+static struct msm_gpiomux_config cyts_gpio_alt_config[] __initdata = {
+ { /* TS INTERRUPT */
+ .gpio = 6,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &cyts_int_act_cfg,
+ [GPIOMUX_SUSPENDED] = &cyts_int_sus_cfg,
+ },
+ },
+ { /* TS SLEEP */
+ .gpio = 12,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &cyts_sleep_act_cfg,
+ [GPIOMUX_SUSPENDED] = &cyts_sleep_sus_cfg,
+ },
+ },
+};
static struct gpiomux_setting hsic_act_cfg = {
.func = GPIOMUX_FUNC_1,
@@ -1202,6 +1218,7 @@
void __init apq8064_init_gpiomux(void)
{
int rc;
+ int platform_version = socinfo_get_platform_version();
rc = msm_gpiomux_init(NR_GPIO_IRQS);
if (rc) {
@@ -1260,11 +1277,17 @@
msm_gpiomux_install(mdm_configs,
ARRAY_SIZE(mdm_configs));
-#ifdef CONFIG_USB_EHCI_MSM_HSIC
- if (machine_is_apq8064_mtp())
- msm_gpiomux_install(cyts_gpio_configs,
- ARRAY_SIZE(cyts_gpio_configs));
+ if (machine_is_apq8064_mtp()) {
+ if (SOCINFO_VERSION_MINOR(platform_version) == 1) {
+ msm_gpiomux_install(cyts_gpio_alt_config,
+ ARRAY_SIZE(cyts_gpio_alt_config));
+ } else {
+ msm_gpiomux_install(cyts_gpio_configs,
+ ARRAY_SIZE(cyts_gpio_configs));
+ }
+ }
+#ifdef CONFIG_USB_EHCI_MSM_HSIC
if (machine_is_apq8064_mtp())
msm_gpiomux_install(apq8064_hsic_configs,
ARRAY_SIZE(apq8064_hsic_configs));
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index da849c8..f733ba6 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1379,6 +1379,7 @@
};
#define CYTTSP_TS_GPIO_IRQ 6
#define CYTTSP_TS_GPIO_SLEEP 33
+#define CYTTSP_TS_GPIO_SLEEP_ALT 12
static ssize_t tma340_vkeys_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
@@ -2972,6 +2973,9 @@
{
if (meminfo_init(SYS_MEMORY, SZ_256M) < 0)
pr_err("meminfo_init() failed!\n");
+ if (machine_is_apq8064_mtp() &&
+ SOCINFO_VERSION_MINOR(socinfo_get_platform_version()) == 1)
+ cyttsp_pdata.sleep_gpio = CYTTSP_TS_GPIO_SLEEP_ALT;
apq8064_common_init();
if (machine_is_mpq8064_cdp() || machine_is_mpq8064_hrd() ||
machine_is_mpq8064_dtv()) {
diff --git a/arch/arm/mach-msm/board-8974.c b/arch/arm/mach-msm/board-8974.c
index 240e094..a44d67b 100644
--- a/arch/arm/mach-msm/board-8974.c
+++ b/arch/arm/mach-msm/board-8974.c
@@ -469,6 +469,8 @@
"msm_otg", NULL),
OF_DEV_AUXDATA("qcom,dwc-usb3-msm", 0xF9200000, \
"msm_dwc3", NULL),
+ OF_DEV_AUXDATA("qcom,usb-bam-msm", 0xF9304000, \
+ "usb_bam", NULL),
OF_DEV_AUXDATA("qcom,spi-qup-v2", 0xF9924000, \
"spi_qsd.1", NULL),
OF_DEV_AUXDATA("qcom,spmi-pmic-arb", 0xFC4C0000, \
diff --git a/arch/arm/mach-msm/include/mach/sps.h b/arch/arm/mach-msm/include/mach/sps.h
index 319a3ec..70f91f3 100644
--- a/arch/arm/mach-msm/include/mach/sps.h
+++ b/arch/arm/mach-msm/include/mach/sps.h
@@ -103,6 +103,9 @@
#define SPS_BAM_SEC_DO_NOT_CONFIG 0
#define SPS_BAM_SEC_DO_CONFIG 0x0A434553
+/* BAM pipe selection */
+#define SPS_BAM_PIPE(n) (1UL << (n))
+
/* This enum specifies the operational mode for an SPS connection */
enum sps_mode {
SPS_MODE_SRC = 0, /* end point is the source (producer) */
@@ -1232,6 +1235,20 @@
*/
int sps_get_unused_desc_num(struct sps_pipe *h, u32 *desc_num);
+/**
+ * Get the debug info of BAM registers and descriptor FIFOs
+ *
+ * @dev - BAM device handle
+ *
+ * @option - debugging option
+ *
+ * @para - parameter used for an option (such as pipe combination)
+ *
+ * @return 0 on success, negative value on error
+ *
+ */
+int sps_get_bam_debug_info(u32 dev, u32 option, u32 para);
+
#else
static inline int sps_register_bam_device(const struct sps_bam_props
*bam_props, u32 *dev_handle)
@@ -1388,6 +1405,11 @@
{
return -EPERM;
}
+
+static inline int sps_get_bam_debug_info(u32 dev, u32 option, u32 para)
+{
+ return -EPERM;
+}
#endif
#endif /* _SPS_H_ */
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index c0bff63..7dc8d0f 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -130,7 +130,6 @@
uint32_t remote_node_id;
uint32_t initialized;
struct list_head pkt_list;
- wait_queue_head_t read_wait;
struct wake_lock wakelock;
struct mutex rx_lock;
struct mutex tx_lock;
@@ -262,16 +261,15 @@
return NULL;
mutex_lock(&xprt_info->rx_lock);
- while (!(xprt_info->abort_data_read) &&
- list_empty(&xprt_info->pkt_list)) {
- mutex_unlock(&xprt_info->rx_lock);
- wait_event(xprt_info->read_wait,
- ((xprt_info->abort_data_read) ||
- !list_empty(&xprt_info->pkt_list)));
- mutex_lock(&xprt_info->rx_lock);
- }
if (xprt_info->abort_data_read) {
mutex_unlock(&xprt_info->rx_lock);
+ pr_err("%s detected SSR & exiting now\n",
+ xprt_info->xprt->name);
+ return NULL;
+ }
+
+ if (list_empty(&xprt_info->pkt_list)) {
+ mutex_unlock(&xprt_info->rx_lock);
return NULL;
}
@@ -1364,144 +1362,135 @@
struct msm_ipc_router_xprt_info,
read_data);
- pkt = rr_read(xprt_info);
- if (!pkt) {
- pr_err("%s: rr_read failed\n", __func__);
- goto fail_io;
- }
+ while ((pkt = rr_read(xprt_info)) != NULL) {
+ if (pkt->length < IPC_ROUTER_HDR_SIZE ||
+ pkt->length > MAX_IPC_PKT_SIZE) {
+ pr_err("%s: Invalid pkt length %d\n",
+ __func__, pkt->length);
+ goto fail_data;
+ }
- if (pkt->length < IPC_ROUTER_HDR_SIZE ||
- pkt->length > MAX_IPC_PKT_SIZE) {
- pr_err("%s: Invalid pkt length %d\n", __func__, pkt->length);
- goto fail_data;
- }
+ head_skb = skb_peek(pkt->pkt_fragment_q);
+ if (!head_skb) {
+ pr_err("%s: head_skb is invalid\n", __func__);
+ goto fail_data;
+ }
- head_skb = skb_peek(pkt->pkt_fragment_q);
- if (!head_skb) {
- pr_err("%s: head_skb is invalid\n", __func__);
- goto fail_data;
- }
+ hdr = (struct rr_header *)(head_skb->data);
+ RR("- ver=%d type=%d src=%d:%08x crx=%d siz=%d dst=%d:%08x\n",
+ hdr->version, hdr->type, hdr->src_node_id, hdr->src_port_id,
+ hdr->confirm_rx, hdr->size, hdr->dst_node_id,
+ hdr->dst_port_id);
- hdr = (struct rr_header *)(head_skb->data);
- RR("- ver=%d type=%d src=%d:%08x crx=%d siz=%d dst=%d:%08x\n",
- hdr->version, hdr->type, hdr->src_node_id, hdr->src_port_id,
- hdr->confirm_rx, hdr->size, hdr->dst_node_id, hdr->dst_port_id);
- RAW_HDR("[r rr_h] "
- "ver=%i,type=%s,src_node_id=%08x,src_port_id=%08x,"
- "confirm_rx=%i,size=%3i,dst_node_id=%08x,dst_port_id=%08x\n",
- hdr->version, type_to_str(hdr->type), hdr->src_node_id,
- hdr->src_port_id, hdr->confirm_rx, hdr->size, hdr->dst_node_id,
- hdr->dst_port_id);
+ if (hdr->version != IPC_ROUTER_VERSION) {
+ pr_err("version %d != %d\n",
+ hdr->version, IPC_ROUTER_VERSION);
+ goto fail_data;
+ }
- if (hdr->version != IPC_ROUTER_VERSION) {
- pr_err("version %d != %d\n", hdr->version, IPC_ROUTER_VERSION);
- goto fail_data;
- }
+ if ((hdr->dst_node_id != IPC_ROUTER_NID_LOCAL) &&
+ ((hdr->type == IPC_ROUTER_CTRL_CMD_RESUME_TX) ||
+ (hdr->type == IPC_ROUTER_CTRL_CMD_DATA))) {
+ forward_msg(xprt_info, pkt);
+ release_pkt(pkt);
+ continue;
+ }
- if ((hdr->dst_node_id != IPC_ROUTER_NID_LOCAL) &&
- ((hdr->type == IPC_ROUTER_CTRL_CMD_RESUME_TX) ||
- (hdr->type == IPC_ROUTER_CTRL_CMD_DATA))) {
- forward_msg(xprt_info, pkt);
- release_pkt(pkt);
- goto done;
- }
-
- if ((hdr->dst_port_id == IPC_ROUTER_ADDRESS) ||
- (hdr->type == IPC_ROUTER_CTRL_CMD_HELLO)) {
- process_control_msg(xprt_info, pkt);
- release_pkt(pkt);
- goto done;
- }
+ if ((hdr->dst_port_id == IPC_ROUTER_ADDRESS) ||
+ (hdr->type == IPC_ROUTER_CTRL_CMD_HELLO)) {
+ process_control_msg(xprt_info, pkt);
+ release_pkt(pkt);
+ continue;
+ }
#if defined(CONFIG_MSM_SMD_LOGGING)
#if defined(DEBUG)
- if (msm_ipc_router_debug_mask & SMEM_LOG) {
- smem_log_event((SMEM_LOG_PROC_ID_APPS |
- SMEM_LOG_RPC_ROUTER_EVENT_BASE |
- IPC_ROUTER_LOG_EVENT_RX),
- (hdr->src_node_id << 24) |
- (hdr->src_port_id & 0xffffff),
- (hdr->dst_node_id << 24) |
- (hdr->dst_port_id & 0xffffff),
- (hdr->type << 24) | (hdr->confirm_rx << 16) |
- (hdr->size & 0xffff));
- }
+ if (msm_ipc_router_debug_mask & SMEM_LOG) {
+ smem_log_event((SMEM_LOG_PROC_ID_APPS |
+ SMEM_LOG_RPC_ROUTER_EVENT_BASE |
+ IPC_ROUTER_LOG_EVENT_RX),
+ (hdr->src_node_id << 24) |
+ (hdr->src_port_id & 0xffffff),
+ (hdr->dst_node_id << 24) |
+ (hdr->dst_port_id & 0xffffff),
+ (hdr->type << 24) | (hdr->confirm_rx << 16) |
+ (hdr->size & 0xffff));
+ }
#endif
#endif
- resume_tx = hdr->confirm_rx;
- resume_tx_node_id = hdr->dst_node_id;
- resume_tx_port_id = hdr->dst_port_id;
+ resume_tx = hdr->confirm_rx;
+ resume_tx_node_id = hdr->dst_node_id;
+ resume_tx_port_id = hdr->dst_port_id;
- rport_ptr = msm_ipc_router_lookup_remote_port(hdr->src_node_id,
+ rport_ptr = msm_ipc_router_lookup_remote_port(hdr->src_node_id,
hdr->src_port_id);
- mutex_lock(&local_ports_lock);
- port_ptr = msm_ipc_router_lookup_local_port(hdr->dst_port_id);
- if (!port_ptr) {
- pr_err("%s: No local port id %08x\n", __func__,
- hdr->dst_port_id);
- mutex_unlock(&local_ports_lock);
- release_pkt(pkt);
- goto process_done;
- }
-
- if (!rport_ptr) {
- rport_ptr = msm_ipc_router_create_remote_port(
- hdr->src_node_id,
- hdr->src_port_id);
- if (!rport_ptr) {
- pr_err("%s: Remote port %08x:%08x creation failed\n",
- __func__, hdr->src_node_id, hdr->src_port_id);
+ mutex_lock(&local_ports_lock);
+ port_ptr = msm_ipc_router_lookup_local_port(hdr->dst_port_id);
+ if (!port_ptr) {
+ pr_err("%s: No local port id %08x\n", __func__,
+ hdr->dst_port_id);
mutex_unlock(&local_ports_lock);
+ release_pkt(pkt);
goto process_done;
}
- }
- if (!port_ptr->notify) {
- mutex_lock(&port_ptr->port_rx_q_lock);
- wake_lock(&port_ptr->port_rx_wake_lock);
- list_add_tail(&pkt->list, &port_ptr->port_rx_q);
- wake_up(&port_ptr->port_rx_wait_q);
- mutex_unlock(&port_ptr->port_rx_q_lock);
- mutex_unlock(&local_ports_lock);
- } else {
- mutex_lock(&port_ptr->port_rx_q_lock);
- src_addr = kmalloc(sizeof(struct msm_ipc_port_addr),
- GFP_KERNEL);
- if (src_addr) {
- src_addr->node_id = hdr->src_node_id;
- src_addr->port_id = hdr->src_port_id;
+ if (!rport_ptr) {
+ rport_ptr = msm_ipc_router_create_remote_port(
+ hdr->src_node_id,
+ hdr->src_port_id);
+ if (!rport_ptr) {
+ pr_err("%s: Rmt Prt %08x:%08x create failed\n",
+ __func__, hdr->src_node_id,
+ hdr->src_port_id);
+ mutex_unlock(&local_ports_lock);
+ goto process_done;
+ }
}
- skb_pull(head_skb, IPC_ROUTER_HDR_SIZE);
- mutex_unlock(&local_ports_lock);
- port_ptr->notify(MSM_IPC_ROUTER_READ_CB, pkt->pkt_fragment_q,
- src_addr, port_ptr->priv);
- mutex_unlock(&port_ptr->port_rx_q_lock);
- pkt->pkt_fragment_q = NULL;
- src_addr = NULL;
- release_pkt(pkt);
- }
+
+ if (!port_ptr->notify) {
+ mutex_lock(&port_ptr->port_rx_q_lock);
+ wake_lock(&port_ptr->port_rx_wake_lock);
+ list_add_tail(&pkt->list, &port_ptr->port_rx_q);
+ wake_up(&port_ptr->port_rx_wait_q);
+ mutex_unlock(&port_ptr->port_rx_q_lock);
+ mutex_unlock(&local_ports_lock);
+ } else {
+ mutex_lock(&port_ptr->port_rx_q_lock);
+ src_addr = kmalloc(sizeof(struct msm_ipc_port_addr),
+ GFP_KERNEL);
+ if (src_addr) {
+ src_addr->node_id = hdr->src_node_id;
+ src_addr->port_id = hdr->src_port_id;
+ }
+ skb_pull(head_skb, IPC_ROUTER_HDR_SIZE);
+ mutex_unlock(&local_ports_lock);
+ port_ptr->notify(MSM_IPC_ROUTER_READ_CB,
+ pkt->pkt_fragment_q, src_addr, port_ptr->priv);
+ mutex_unlock(&port_ptr->port_rx_q_lock);
+ pkt->pkt_fragment_q = NULL;
+ src_addr = NULL;
+ release_pkt(pkt);
+ }
process_done:
- if (resume_tx) {
- union rr_control_msg msg;
+ if (resume_tx) {
+ union rr_control_msg msg;
- msg.cmd = IPC_ROUTER_CTRL_CMD_RESUME_TX;
- msg.cli.node_id = resume_tx_node_id;
- msg.cli.port_id = resume_tx_port_id;
+ msg.cmd = IPC_ROUTER_CTRL_CMD_RESUME_TX;
+ msg.cli.node_id = resume_tx_node_id;
+ msg.cli.port_id = resume_tx_port_id;
- RR("x RESUME_TX id=%d:%08x\n",
- msg.cli.node_id, msg.cli.port_id);
- msm_ipc_router_send_control_msg(xprt_info, &msg);
+ RR("x RESUME_TX id=%d:%08x\n",
+ msg.cli.node_id, msg.cli.port_id);
+ msm_ipc_router_send_control_msg(xprt_info, &msg);
+ }
+
}
-
-done:
- queue_work(xprt_info->workqueue, &xprt_info->read_data);
return;
fail_data:
release_pkt(pkt);
-fail_io:
pr_err("ipc_router has died\n");
}
@@ -2334,7 +2323,6 @@
xprt_info->initialized = 0;
xprt_info->remote_node_id = -1;
INIT_LIST_HEAD(&xprt_info->pkt_list);
- init_waitqueue_head(&xprt_info->read_wait);
mutex_init(&xprt_info->rx_lock);
mutex_init(&xprt_info->tx_lock);
wake_lock_init(&xprt_info->wakelock,
@@ -2368,8 +2356,6 @@
}
mutex_unlock(&routing_table_lock);
- queue_work(xprt_info->workqueue, &xprt_info->read_data);
-
xprt->priv = xprt_info;
return 0;
@@ -2382,8 +2368,9 @@
if (xprt && xprt->priv) {
xprt_info = xprt->priv;
+ mutex_lock(&xprt_info->rx_lock);
xprt_info->abort_data_read = 1;
- wake_up(&xprt_info->read_wait);
+ mutex_unlock(&xprt_info->rx_lock);
mutex_lock(&xprt_info_list_lock);
list_del(&xprt_info->list);
@@ -2481,8 +2468,8 @@
mutex_lock(&xprt_info->rx_lock);
list_add_tail(&pkt->list, &xprt_info->pkt_list);
wake_lock(&xprt_info->wakelock);
- wake_up(&xprt_info->read_wait);
mutex_unlock(&xprt_info->rx_lock);
+ queue_work(xprt_info->workqueue, &xprt_info->read_data);
}
static int modem_restart_notifier_cb(struct notifier_block *this,
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index 90673fc..6d82e11 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -246,6 +246,12 @@
},
};
+static struct mfd_cell taiko_devs[] = {
+ {
+ .name = "taiko_codec",
+ },
+};
+
static void wcd9xxx_bring_up(struct wcd9xxx *wcd9xxx)
{
wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x4);
@@ -336,13 +342,16 @@
} else if (wcd9xxx->idbyte_0 == 0x1) {
wcd9xxx_dev = tabla1x_devs;
wcd9xxx_dev_size = ARRAY_SIZE(tabla1x_devs);
+ } else if (wcd9xxx->idbyte_0 == 0x0 && wcd9xxx->idbyte_1 == 0x0 &&
+ wcd9xxx->idbyte_2 == 0x2 && wcd9xxx->idbyte_3 == 0x1) {
+ wcd9xxx_dev = taiko_devs;
+ wcd9xxx_dev_size = ARRAY_SIZE(taiko_devs);
} else if (wcd9xxx->idbyte_0 == 0x0) {
wcd9xxx_dev = sitar_devs;
wcd9xxx_dev_size = ARRAY_SIZE(sitar_devs);
}
- ret = mfd_add_devices(wcd9xxx->dev, -1,
- wcd9xxx_dev, wcd9xxx_dev_size,
- NULL, 0);
+ ret = mfd_add_devices(wcd9xxx->dev, -1, wcd9xxx_dev, wcd9xxx_dev_size,
+ NULL, 0);
if (ret != 0) {
dev_err(wcd9xxx->dev, "Failed to add children: %d\n", ret);
goto err_irq;
@@ -883,7 +892,9 @@
pr_err("%s: error, initializing device failed\n", __func__);
goto err_slim_add;
}
+
wcd9xxx_init_slimslave(wcd9xxx, wcd9xxx_pgd_la);
+
#ifdef CONFIG_DEBUG_FS
debugCodec = wcd9xxx;
@@ -1091,6 +1102,23 @@
.suspend = wcd9xxx_slim_suspend,
};
+static const struct slim_device_id taiko_slimtest_id[] = {
+ {"taiko-slim", 0},
+ {}
+};
+
+static struct slim_driver taiko_slim_driver = {
+ .driver = {
+ .name = "taiko-slim",
+ .owner = THIS_MODULE,
+ },
+ .probe = wcd9xxx_slim_probe,
+ .remove = wcd9xxx_slim_remove,
+ .id_table = taiko_slimtest_id,
+ .resume = wcd9xxx_slim_resume,
+ .suspend = wcd9xxx_slim_suspend,
+};
+
#define WCD9XXX_I2C_TOP_LEVEL 0
#define WCD9XXX_I2C_ANALOG 1
#define WCD9XXX_I2C_DIGITAL_1 2
@@ -1119,7 +1147,7 @@
static int __init wcd9xxx_init(void)
{
- int ret1, ret2, ret3, ret4, ret5;
+ int ret1, ret2, ret3, ret4, ret5, ret6;
ret1 = slim_driver_register(&tabla_slim_driver);
if (ret1 != 0)
@@ -1141,7 +1169,11 @@
if (ret5 != 0)
pr_err("Failed to register sitar SB driver: %d\n", ret5);
- return (ret1 && ret2 && ret3 && ret4 && ret5) ? -1 : 0;
+ ret6 = slim_driver_register(&taiko_slim_driver);
+ if (ret6 != 0)
+ pr_err("Failed to register taiko SB driver: %d\n", ret6);
+
+ return (ret1 && ret2 && ret3 && ret4 && ret5 && ret6) ? -1 : 0;
}
module_init(wcd9xxx_init);
diff --git a/drivers/mfd/wcd9xxx-slimslave.c b/drivers/mfd/wcd9xxx-slimslave.c
index 789242d..5f839a8 100644
--- a/drivers/mfd/wcd9xxx-slimslave.c
+++ b/drivers/mfd/wcd9xxx-slimslave.c
@@ -12,6 +12,9 @@
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/mfd/wcd9xxx/wcd9xxx-slimslave.h>
+#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
+
+#define WCD9XXX_CHIP_ID_TAIKO 0x00000201
struct wcd9xxx_slim_sch_rx {
u32 sph;
@@ -30,37 +33,111 @@
struct wcd9xxx_slim_sch {
struct wcd9xxx_slim_sch_rx rx[SLIM_MAX_RX_PORTS];
struct wcd9xxx_slim_sch_tx tx[SLIM_MAX_TX_PORTS];
+
+ u16 rx_port_start_offset;
+ u16 num_rx_slave_port;
+ u16 port_ch_0_start_port_id;
+ u16 port_ch_0_end_port_id;
+ u16 pgd_tx_port_ch_1_end_port_id;
+ u16 rx_port_ch_reg_base;
+ u16 port_tx_cfg_reg_base;
+ u16 port_rx_cfg_reg_base;
+ int number_of_tx_slave_dev_ports;
+ int number_of_rx_slave_dev_ports;
};
static struct wcd9xxx_slim_sch sh_ch;
static int wcd9xxx_alloc_slim_sh_ch_rx(struct wcd9xxx *wcd9xxx,
- u8 wcd9xxx_pgd_la);
+ u8 wcd9xxx_pgd_la);
static int wcd9xxx_alloc_slim_sh_ch_tx(struct wcd9xxx *wcd9xxx,
u8 wcd9xxx_pgd_la);
static int wcd9xxx_dealloc_slim_sh_ch_rx(struct wcd9xxx *wcd9xxx);
static int wcd9xxx_dealloc_slim_sh_ch_tx(struct wcd9xxx *wcd9xxx);
+static int wcd9xxx_configure_ports(struct wcd9xxx *wcd9xxx)
+{
+ int i;
+ u32 id;
+ for (i = 0; i < 4; i++)
+ ((u8 *)&id)[i] = wcd9xxx_reg_read(wcd9xxx,
+ WCD9XXX_A_CHIP_ID_BYTE_0 + i);
+ id = cpu_to_be32(id);
+ pr_debug("%s: chip id 0x%08x\n", __func__, id);
+ if (id != WCD9XXX_CHIP_ID_TAIKO) {
+ sh_ch.rx_port_start_offset =
+ TABLA_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS;
+ sh_ch.num_rx_slave_port =
+ TABLA_SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS;
+ sh_ch.port_ch_0_start_port_id =
+ TABLA_SB_PGD_RX_PORT_MULTI_CHANNEL_0_START_PORT_ID;
+ sh_ch.port_ch_0_end_port_id =
+ TABLA_SB_PGD_RX_PORT_MULTI_CHANNEL_0_END_PORT_ID;
+ sh_ch.pgd_tx_port_ch_1_end_port_id =
+ TABLA_SB_PGD_TX_PORT_MULTI_CHANNEL_1_END_PORT_ID;
+
+ sh_ch.rx_port_ch_reg_base =
+ 0x180 + (TABLA_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS * 4);
+ sh_ch.port_rx_cfg_reg_base =
+ 0x040 + (TABLA_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS);
+ sh_ch.port_tx_cfg_reg_base = 0x040;
+
+ sh_ch.number_of_tx_slave_dev_ports =
+ TABLA_SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS;
+ sh_ch.number_of_rx_slave_dev_ports =
+ TABLA_SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS;
+ } else {
+ sh_ch.rx_port_start_offset =
+ TAIKO_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS;
+ sh_ch.num_rx_slave_port =
+ TAIKO_SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS;
+ sh_ch.port_ch_0_start_port_id =
+ TAIKO_SB_PGD_RX_PORT_MULTI_CHANNEL_0_START_PORT_ID;
+ sh_ch.port_ch_0_end_port_id =
+ TAIKO_SB_PGD_RX_PORT_MULTI_CHANNEL_0_END_PORT_ID;
+ sh_ch.pgd_tx_port_ch_1_end_port_id =
+ TAIKO_SB_PGD_TX_PORT_MULTI_CHANNEL_1_END_PORT_ID;
+
+ sh_ch.rx_port_ch_reg_base = 0x180;
+ sh_ch.port_rx_cfg_reg_base = 0x040;
+ sh_ch.port_tx_cfg_reg_base = 0x050;
+
+ sh_ch.number_of_tx_slave_dev_ports =
+ TAIKO_SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS;
+ sh_ch.number_of_rx_slave_dev_ports =
+ TAIKO_SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS;
+ }
+
+ return 0;
+}
+
int wcd9xxx_init_slimslave(struct wcd9xxx *wcd9xxx, u8 wcd9xxx_pgd_la)
{
int ret = 0;
+ ret = wcd9xxx_configure_ports(wcd9xxx);
+ if (ret) {
+ pr_err("%s: Failed to configure register address offset\n",
+ __func__);
+ goto err;
+ }
+
ret = wcd9xxx_alloc_slim_sh_ch_rx(wcd9xxx, wcd9xxx_pgd_la);
if (ret) {
pr_err("%s: Failed to alloc rx slimbus shared channels\n",
- __func__);
- goto rx_err;
+ __func__);
+ goto err;
}
ret = wcd9xxx_alloc_slim_sh_ch_tx(wcd9xxx, wcd9xxx_pgd_la);
if (ret) {
pr_err("%s: Failed to alloc tx slimbus shared channels\n",
- __func__);
+ __func__);
goto tx_err;
}
return 0;
tx_err:
wcd9xxx_dealloc_slim_sh_ch_rx(wcd9xxx);
-rx_err:
+err:
return ret;
}
@@ -82,23 +159,22 @@
return ret;
}
-int wcd9xxx_get_channel(struct wcd9xxx *wcd9xxx,
- unsigned int *rx_ch,
- unsigned int *tx_ch)
+int wcd9xxx_get_channel(struct wcd9xxx *wcd9xxx, unsigned int *rx_ch,
+ unsigned int *tx_ch)
{
int ch_idx = 0;
struct wcd9xxx_slim_sch_rx *rx = sh_ch.rx;
struct wcd9xxx_slim_sch_tx *tx = sh_ch.tx;
- for (ch_idx = 0; ch_idx < SLIM_MAX_RX_PORTS; ch_idx++)
+ for (ch_idx = 0; ch_idx < sh_ch.number_of_rx_slave_dev_ports; ch_idx++)
rx_ch[ch_idx] = rx[ch_idx].ch_num;
- for (ch_idx = 0; ch_idx < SLIM_MAX_TX_PORTS; ch_idx++)
+ for (ch_idx = 0; ch_idx < sh_ch.number_of_tx_slave_dev_ports; ch_idx++)
tx_ch[ch_idx] = tx[ch_idx].ch_num;
return 0;
}
static int wcd9xxx_alloc_slim_sh_ch_rx(struct wcd9xxx *wcd9xxx,
- u8 wcd9xxx_pgd_la)
+ u8 wcd9xxx_pgd_la)
{
int ret = 0;
u8 ch_idx ;
@@ -109,35 +185,38 @@
* DSP requires channel number to be between 128 and 255.
*/
pr_debug("%s: pgd_la[%d]\n", __func__, wcd9xxx_pgd_la);
- for (ch_idx = 0; ch_idx < SLIM_MAX_RX_PORTS; ch_idx++) {
- slave_port_id = (ch_idx + 1 +
- SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS);
+ for (ch_idx = 0; ch_idx < sh_ch.number_of_rx_slave_dev_ports;
+ ch_idx++) {
+ slave_port_id = (ch_idx + sh_ch.rx_port_start_offset);
rx[ch_idx].ch_num = slave_port_id + BASE_CH_NUM;
ret = slim_get_slaveport(wcd9xxx_pgd_la, slave_port_id,
&rx[ch_idx].sph, SLIM_SINK);
if (ret < 0) {
pr_err("%s: slave port failure id[%d] ret[%d]\n",
- __func__, slave_port_id, ret);
+ __func__, slave_port_id, ret);
goto err;
}
ret = slim_query_ch(wcd9xxx->slim, rx[ch_idx].ch_num,
- &rx[ch_idx].ch_h);
+ &rx[ch_idx].ch_h);
if (ret < 0) {
pr_err("%s: slim_query_ch failed ch-num[%d] ret[%d]\n",
- __func__, rx[ch_idx].ch_num, ret);
+ __func__, rx[ch_idx].ch_num, ret);
goto err;
}
+ pr_debug("%s:ch_num=%d ch_h=%d sph=%d la=%d slave_port_id %d\n",
+ __func__, rx[ch_idx].ch_num, rx[ch_idx].ch_h,
+ rx[ch_idx].sph, wcd9xxx_pgd_la, slave_port_id);
}
err:
return ret;
}
static int wcd9xxx_alloc_slim_sh_ch_tx(struct wcd9xxx *wcd9xxx,
- u8 wcd9xxx_pgd_la)
+ u8 wcd9xxx_pgd_la)
{
int ret = 0;
- u8 ch_idx ;
+ u8 ch_idx;
struct wcd9xxx_slim_sch_tx *tx = sh_ch.tx;
u16 slave_port_id = 0;
@@ -146,21 +225,22 @@
* use channel numbers from 138 to 144, for TX port
* use channel numbers from 128 to 137
*/
- for (ch_idx = 0; ch_idx < SLIM_MAX_TX_PORTS; ch_idx++) {
+ for (ch_idx = 0; ch_idx < sh_ch.number_of_tx_slave_dev_ports;
+ ch_idx++) {
slave_port_id = ch_idx;
tx[ch_idx].ch_num = slave_port_id + BASE_CH_NUM;
ret = slim_get_slaveport(wcd9xxx_pgd_la, slave_port_id,
- &tx[ch_idx].sph, SLIM_SRC);
+ &tx[ch_idx].sph, SLIM_SRC);
if (ret < 0) {
pr_err("%s: slave port failure id[%d] ret[%d]\n",
- __func__, slave_port_id, ret);
+ __func__, slave_port_id, ret);
goto err;
}
ret = slim_query_ch(wcd9xxx->slim, tx[ch_idx].ch_num,
- &tx[ch_idx].ch_h);
+ &tx[ch_idx].ch_h);
if (ret < 0) {
pr_err("%s: slim_query_ch failed ch-num[%d] ret[%d]\n",
- __func__, tx[ch_idx].ch_num, ret);
+ __func__, tx[ch_idx].ch_num, ret);
goto err;
}
}
@@ -174,7 +254,7 @@
int ret = 0;
struct wcd9xxx_slim_sch_rx *rx = sh_ch.rx;
/* slim_dealloc_ch */
- for (idx = 0; idx < SLIM_MAX_RX_PORTS; idx++) {
+ for (idx = 0; idx < sh_ch.number_of_rx_slave_dev_ports; idx++) {
ret = slim_dealloc_ch(wcd9xxx->slim, rx[idx].ch_h);
if (ret < 0) {
pr_err("%s: slim_dealloc_ch fail ret[%d] ch_h[%d]\n",
@@ -191,7 +271,7 @@
int ret = 0;
struct wcd9xxx_slim_sch_tx *tx = sh_ch.tx;
/* slim_dealloc_ch */
- for (idx = 0; idx < SLIM_MAX_TX_PORTS; idx++) {
+ for (idx = 0; idx < sh_ch.number_of_tx_slave_dev_ports; idx++) {
ret = slim_dealloc_ch(wcd9xxx->slim, tx[idx].ch_h);
if (ret < 0) {
pr_err("%s: slim_dealloc_ch fail ret[%d] ch_h[%d]\n",
@@ -204,9 +284,9 @@
/* Enable slimbus slave device for RX path */
int wcd9xxx_cfg_slim_sch_rx(struct wcd9xxx *wcd9xxx, unsigned int *ch_num,
- unsigned int ch_cnt, unsigned int rate)
+ unsigned int ch_cnt, unsigned int rate)
{
- u8 i = 0;
+ u8 i;
u16 grph;
u32 sph[SLIM_MAX_RX_PORTS] = {0};
u16 ch_h[SLIM_MAX_RX_PORTS] = {0};
@@ -221,53 +301,56 @@
pr_debug("%s: ch_cnt[%d] rate=%d\n", __func__, ch_cnt, rate);
for (i = 0; i < ch_cnt; i++) {
- idx = (ch_num[i] - BASE_CH_NUM -
- SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS - 1);
+ idx = (ch_num[i] - BASE_CH_NUM - sh_ch.rx_port_start_offset);
ch_h[i] = rx[idx].ch_h;
sph[i] = rx[idx].sph;
- slave_port_id = idx + 1;
- if ((slave_port_id > SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS) ||
- (slave_port_id == 0)) {
+ slave_port_id = idx;
+ pr_debug("%s: idx %d, ch_h %d, sph %d\n",
+ __func__, idx, ch_h[i], sph[i]);
+ if ((slave_port_id > sh_ch.num_rx_slave_port)) {
pr_err("Slimbus: invalid slave port id: %d",
- slave_port_id);
+ slave_port_id);
ret = -EINVAL;
goto err;
}
- slave_port_id += SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS;
+ slave_port_id += sh_ch.rx_port_start_offset;
+ pr_debug("%s: slave_port_id %d\n", __func__, slave_port_id);
/* look for the valid port range and chose the
* payload accordingly
*/
- if ((slave_port_id >
- SB_PGD_TX_PORT_MULTI_CHANNEL_1_END_PORT_ID) &&
- (slave_port_id <=
- SB_PGD_RX_PORT_MULTI_CHANNEL_0_END_PORT_ID)) {
- payload_rx = payload_rx |
- (1 <<
- (slave_port_id -
- SB_PGD_RX_PORT_MULTI_CHANNEL_0_START_PORT_ID));
+ if ((slave_port_id > sh_ch.pgd_tx_port_ch_1_end_port_id) &&
+ (slave_port_id <= sh_ch.port_ch_0_end_port_id)) {
+ payload_rx = payload_rx |
+ (1 << (slave_port_id -
+ sh_ch.port_ch_0_start_port_id));
} else {
ret = -EINVAL;
goto err;
}
+
multi_chan_cfg_reg_addr =
- SB_PGD_RX_PORT_MULTI_CHANNEL_0(slave_port_id);
+ SB_PGD_RX_PORT_MULTI_CHANNEL_0(sh_ch.rx_port_ch_reg_base,
+ idx);
+ pr_debug("%s: multi_chan_cfg_reg_addr 0x%x\n", __func__,
+ multi_chan_cfg_reg_addr);
+
/* write to interface device */
ret = wcd9xxx_interface_reg_write(wcd9xxx,
- multi_chan_cfg_reg_addr,
- payload_rx);
+ multi_chan_cfg_reg_addr,
+ payload_rx);
if (ret < 0) {
pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n",
- __func__,
- multi_chan_cfg_reg_addr,
- payload_rx, ret);
+ __func__, multi_chan_cfg_reg_addr,
+ payload_rx, ret);
goto err;
}
/* configure the slave port for water mark and enable*/
wm_payload = (SLAVE_PORT_WATER_MARK_VALUE <<
- SLAVE_PORT_WATER_MARK_SHIFT) +
- SLAVE_PORT_ENABLE;
- ret = wcd9xxx_interface_reg_write(wcd9xxx,
- SB_PGD_PORT_CFG_BYTE_ADDR(slave_port_id),
+ SLAVE_PORT_WATER_MARK_SHIFT) + SLAVE_PORT_ENABLE;
+ ret = wcd9xxx_interface_reg_write(
+ wcd9xxx,
+ SB_PGD_PORT_CFG_BYTE_ADDR(
+ sh_ch.port_rx_cfg_reg_base, idx),
wm_payload);
if (ret < 0) {
pr_err("%s:watermark set failure for port[%d] ret[%d]",
@@ -283,16 +366,14 @@
prop.ratem = (rate/4000);
prop.sampleszbits = 16;
- ret = slim_define_ch(wcd9xxx->slim, &prop, ch_h, ch_cnt,
- true, &grph);
+ ret = slim_define_ch(wcd9xxx->slim, &prop, ch_h, ch_cnt, true, &grph);
if (ret < 0) {
pr_err("%s: slim_define_ch failed ret[%d]\n",
__func__, ret);
goto err;
}
for (i = 0; i < ch_cnt; i++) {
- ret = slim_connect_sink(wcd9xxx->slim, &sph[i],
- 1, ch_h[i]);
+ ret = slim_connect_sink(wcd9xxx->slim, &sph[i], 1, ch_h[i]);
if (ret < 0) {
pr_err("%s: slim_connect_sink failed ret[%d]\n",
__func__, ret);
@@ -300,16 +381,14 @@
}
}
/* slim_control_ch */
- ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_ACTIVATE,
- true);
+ ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_ACTIVATE, true);
if (ret < 0) {
pr_err("%s: slim_control_ch failed ret[%d]\n",
__func__, ret);
goto err_close_slim_sch;
}
for (i = 0; i < ch_cnt; i++) {
- idx = (ch_num[i] - BASE_CH_NUM -
- SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS - 1);
+ idx = (ch_num[i] - BASE_CH_NUM - sh_ch.rx_port_start_offset);
rx[idx].grph = grph;
}
return 0;
@@ -324,7 +403,7 @@
/* Enable slimbus slave device for RX path */
int wcd9xxx_cfg_slim_sch_tx(struct wcd9xxx *wcd9xxx, unsigned int *ch_num,
- unsigned int ch_cnt, unsigned int rate)
+ unsigned int ch_cnt, unsigned int rate)
{
u8 i = 0;
u8 payload_tx_0 = 0, payload_tx_1 = 0, wm_payload = 0;
@@ -333,7 +412,7 @@
u16 ch_h[SLIM_MAX_TX_PORTS] = {0};
u16 idx = 0, slave_port_id;
int ret = 0;
- unsigned short multi_chan_cfg_reg_addr;
+ unsigned short multi_chan_cfg_reg_addr;
struct wcd9xxx_slim_sch_tx *tx = sh_ch.tx;
struct slim_ch prop;
@@ -343,10 +422,12 @@
idx = (ch_num[i] - BASE_CH_NUM);
ch_h[i] = tx[idx].ch_h;
sph[i] = tx[idx].sph;
- slave_port_id = idx ;
- if (slave_port_id > SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS) {
+ slave_port_id = idx;
+ pr_debug("%s: idx %d, ch_h %d, sph %d, slave_port_id %d\n",
+ __func__, idx, ch_h[i], sph[i], slave_port_id);
+ if (slave_port_id > sh_ch.number_of_tx_slave_dev_ports) {
pr_err("SLIMbus: invalid slave port id: %d",
- slave_port_id);
+ slave_port_id);
ret = -EINVAL;
goto err;
}
@@ -354,55 +435,60 @@
* payload accordingly
*/
if (slave_port_id <=
- SB_PGD_TX_PORT_MULTI_CHANNEL_0_END_PORT_ID) {
+ SB_PGD_TX_PORT_MULTI_CHANNEL_0_END_PORT_ID) {
payload_tx_0 = payload_tx_0 | (1 << slave_port_id);
} else if (slave_port_id <=
- SB_PGD_TX_PORT_MULTI_CHANNEL_1_END_PORT_ID) {
- payload_tx_1 = payload_tx_1 |
- (1 <<
- (slave_port_id -
- SB_PGD_TX_PORT_MULTI_CHANNEL_1_START_PORT_ID));
+ sh_ch.pgd_tx_port_ch_1_end_port_id) {
+ payload_tx_1 = payload_tx_1 |
+ (1 << (slave_port_id -
+ SB_PGD_TX_PORT_MULTI_CHANNEL_1_START_PORT_ID));
} else {
+ pr_err("%s: slave port id %d error\n", __func__,
+ slave_port_id);
ret = -EINVAL;
goto err;
}
multi_chan_cfg_reg_addr =
- SB_PGD_TX_PORT_MULTI_CHANNEL_0(slave_port_id);
+ SB_PGD_TX_PORT_MULTI_CHANNEL_0(slave_port_id);
+ pr_debug("%s: multi_chan_cfg_reg_addr 0x%x\n", __func__,
+ multi_chan_cfg_reg_addr);
/* write to interface device */
ret = wcd9xxx_interface_reg_write(wcd9xxx,
multi_chan_cfg_reg_addr,
payload_tx_0);
if (ret < 0) {
pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n",
- __func__,
- multi_chan_cfg_reg_addr,
- payload_tx_0, ret);
+ __func__, multi_chan_cfg_reg_addr, payload_tx_0,
+ ret);
goto err;
}
multi_chan_cfg_reg_addr =
- SB_PGD_TX_PORT_MULTI_CHANNEL_1(slave_port_id);
+ SB_PGD_TX_PORT_MULTI_CHANNEL_1(slave_port_id);
/* ports 8,9 */
ret = wcd9xxx_interface_reg_write(wcd9xxx,
- multi_chan_cfg_reg_addr,
- payload_tx_1);
+ multi_chan_cfg_reg_addr,
+ payload_tx_1);
if (ret < 0) {
pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n",
- __func__,
- multi_chan_cfg_reg_addr,
- payload_tx_1, ret);
+ __func__, multi_chan_cfg_reg_addr,
+ payload_tx_1, ret);
goto err;
}
/* configure the slave port for water mark and enable*/
wm_payload = (SLAVE_PORT_WATER_MARK_VALUE <<
- SLAVE_PORT_WATER_MARK_SHIFT) +
- SLAVE_PORT_ENABLE;
- ret = wcd9xxx_interface_reg_write(wcd9xxx,
- SB_PGD_PORT_CFG_BYTE_ADDR(slave_port_id),
- wm_payload);
+ SLAVE_PORT_WATER_MARK_SHIFT) + SLAVE_PORT_ENABLE;
+ pr_debug("%s: tx_cfg_reg 0x%x wm 0x%x\n", __func__,
+ SB_PGD_PORT_CFG_BYTE_ADDR(sh_ch.port_tx_cfg_reg_base,
+ slave_port_id), wm_payload);
+ ret = wcd9xxx_interface_reg_write(
+ wcd9xxx,
+ SB_PGD_PORT_CFG_BYTE_ADDR(
+ sh_ch.port_tx_cfg_reg_base,
+ slave_port_id),
+ wm_payload);
if (ret < 0) {
- pr_err("%s:watermark set failure for port[%d] ret[%d]",
- __func__,
- slave_port_id, ret);
+ pr_err("%s: watermark set failure for port[%d] ret[%d]",
+ __func__, slave_port_id, ret);
}
}
@@ -413,25 +499,21 @@
prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE;
prop.ratem = (rate/4000);
prop.sampleszbits = 16;
- ret = slim_define_ch(wcd9xxx->slim, &prop, ch_h, ch_cnt,
- true, &grph);
+ ret = slim_define_ch(wcd9xxx->slim, &prop, ch_h, ch_cnt, true, &grph);
if (ret < 0) {
- pr_err("%s: slim_define_ch failed ret[%d]\n",
- __func__, ret);
+ pr_err("%s: slim_define_ch failed ret[%d]\n", __func__, ret);
goto err;
}
for (i = 0; i < ch_cnt; i++) {
- ret = slim_connect_src(wcd9xxx->slim, sph[i],
- ch_h[i]);
+ ret = slim_connect_src(wcd9xxx->slim, sph[i], ch_h[i]);
if (ret < 0) {
pr_err("%s: slim_connect_src failed ret[%d]\n",
- __func__, ret);
+ __func__, ret);
goto err;
}
}
/* slim_control_ch */
- ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_ACTIVATE,
- true);
+ ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_ACTIVATE, true);
if (ret < 0) {
pr_err("%s: slim_control_ch failed ret[%d]\n",
__func__, ret);
@@ -460,34 +542,33 @@
pr_debug("%s: ch_cnt[%d]\n", __func__, ch_cnt);
for (i = 0; i < ch_cnt; i++) {
- idx = (ch_num[i] - BASE_CH_NUM -
- SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS - 1);
+ idx = (ch_num[i] - BASE_CH_NUM - sh_ch.rx_port_start_offset);
if (idx < 0) {
pr_err("%s: Error:-Invalid index found = %d\n",
- __func__, idx);
+ __func__, idx);
ret = -EINVAL;
goto err;
}
sph[i] = rx[idx].sph;
grph = rx[idx].grph;
+ pr_debug("%s: ch_num[%d] %d, idx %d, sph[%d] %x, grph %x\n",
+ __func__, i, ch_num[i], idx, i, sph[i], grph);
}
/* slim_disconnect_port */
ret = slim_disconnect_ports(wcd9xxx->slim, sph, ch_cnt);
if (ret < 0) {
pr_err("%s: slim_disconnect_ports failed ret[%d]\n",
- __func__, ret);
+ __func__, ret);
}
/* slim_control_ch (REMOVE) */
ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_REMOVE, true);
if (ret < 0) {
- pr_err("%s: slim_control_ch failed ret[%d]\n",
- __func__, ret);
+ pr_err("%s: slim_control_ch failed ret[%d]\n", __func__, ret);
goto err;
}
for (i = 0; i < ch_cnt; i++) {
- idx = (ch_num[i] - BASE_CH_NUM -
- SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS - 1);
+ idx = (ch_num[i] - BASE_CH_NUM - sh_ch.rx_port_start_offset);
rx[idx].grph = 0;
}
err:
@@ -496,7 +577,7 @@
EXPORT_SYMBOL_GPL(wcd9xxx_close_slim_sch_rx);
int wcd9xxx_close_slim_sch_tx(struct wcd9xxx *wcd9xxx, unsigned int *ch_num,
- unsigned int ch_cnt)
+ unsigned int ch_cnt)
{
u16 grph = 0;
u32 sph[SLIM_MAX_TX_PORTS] = {0};
diff --git a/drivers/platform/msm/sps/bam.c b/drivers/platform/msm/sps/bam.c
index cf98f68..31b405a 100644
--- a/drivers/platform/msm/sps/bam.c
+++ b/drivers/platform/msm/sps/bam.c
@@ -1152,7 +1152,6 @@
return bam_read_reg(base, P_TIMER(pipe));
}
-#ifdef CONFIG_DEBUG_FS
/* output the content of BAM-level registers */
void print_bam_reg(void *virt_addr)
{
@@ -1399,4 +1398,3 @@
SPS_INFO("-------------------- end of FIFO --------------------\n");
}
-#endif
diff --git a/drivers/platform/msm/sps/sps.c b/drivers/platform/msm/sps/sps.c
index 0371f5a..a7f07a6 100644
--- a/drivers/platform/msm/sps/sps.c
+++ b/drivers/platform/msm/sps/sps.c
@@ -461,6 +461,98 @@
}
#endif
+/* Get the debug info of BAM registers and descriptor FIFOs */
+int sps_get_bam_debug_info(u32 dev, u32 option, u32 para)
+{
+ int res = 0;
+ struct sps_bam *bam;
+ u32 i;
+ u32 num_pipes = 0;
+ void *vir_addr;
+
+ if (dev == 0) {
+ SPS_ERR("sps:%s:device handle should not be 0.\n", __func__);
+ return SPS_ERROR;
+ }
+
+ mutex_lock(&sps->lock);
+ /* Search for the target BAM device */
+ bam = sps_h2bam(dev);
+ if (bam == NULL) {
+ pr_err("sps:Can't find any BAM with handle 0x%x.", dev);
+ mutex_unlock(&sps->lock);
+ return SPS_ERROR;
+ }
+ mutex_unlock(&sps->lock);
+
+ vir_addr = bam->base;
+ num_pipes = bam->props.num_pipes;
+
+ switch (option) {
+ case 1: /* output all registers of this BAM */
+ print_bam_reg(vir_addr);
+ for (i = 0; i < num_pipes; i++)
+ print_bam_pipe_reg(vir_addr, i);
+ break;
+ case 2: /* output BAM-level registers */
+ print_bam_reg(vir_addr);
+ break;
+ case 3: /* output selected BAM-level registers */
+ print_bam_selected_reg(vir_addr);
+ break;
+ case 4: /* output selected registers of all pipes */
+ for (i = 0; i < num_pipes; i++)
+ print_bam_pipe_selected_reg(vir_addr, i);
+ break;
+ case 5: /* output selected registers of selected pipes */
+ for (i = 0; i < num_pipes; i++)
+ if (para & (1UL << i))
+ print_bam_pipe_selected_reg(vir_addr, i);
+ break;
+ case 6: /* output selected registers of typical pipes */
+ print_bam_pipe_selected_reg(vir_addr, 4);
+ print_bam_pipe_selected_reg(vir_addr, 5);
+ break;
+ case 7: /* output desc FIFO of all pipes */
+ for (i = 0; i < num_pipes; i++)
+ print_bam_pipe_desc_fifo(vir_addr, i);
+ break;
+ case 8: /* output desc FIFO of selected pipes */
+ for (i = 0; i < num_pipes; i++)
+ if (para & (1UL << i))
+ print_bam_pipe_desc_fifo(vir_addr, i);
+ break;
+ case 9: /* output desc FIFO of typical pipes */
+ print_bam_pipe_desc_fifo(vir_addr, 4);
+ print_bam_pipe_desc_fifo(vir_addr, 5);
+ break;
+ case 10: /* output selected registers and desc FIFO of all pipes */
+ for (i = 0; i < num_pipes; i++) {
+ print_bam_pipe_selected_reg(vir_addr, i);
+ print_bam_pipe_desc_fifo(vir_addr, i);
+ }
+ break;
+ case 11: /* output selected registers and desc FIFO of selected pipes */
+ for (i = 0; i < num_pipes; i++)
+ if (para & (1UL << i)) {
+ print_bam_pipe_selected_reg(vir_addr, i);
+ print_bam_pipe_desc_fifo(vir_addr, i);
+ }
+ break;
+ case 12: /* output selected registers and desc FIFO of typical pipes */
+ print_bam_pipe_selected_reg(vir_addr, 4);
+ print_bam_pipe_desc_fifo(vir_addr, 4);
+ print_bam_pipe_selected_reg(vir_addr, 5);
+ print_bam_pipe_desc_fifo(vir_addr, 5);
+ break;
+ default:
+ pr_info("sps:no option is chosen yet.");
+ }
+
+ return res;
+}
+EXPORT_SYMBOL(sps_get_bam_debug_info);
+
/**
* Initialize SPS device
*
diff --git a/drivers/platform/msm/sps/spsi.h b/drivers/platform/msm/sps/spsi.h
index 5a141ca..43a50bd 100644
--- a/drivers/platform/msm/sps/spsi.h
+++ b/drivers/platform/msm/sps/spsi.h
@@ -183,6 +183,7 @@
#ifdef CONFIG_DEBUG_FS
/* record debug info for debugfs */
void sps_debugfs_record(const char *);
+#endif
/* output the content of BAM-level registers */
void print_bam_reg(void *);
@@ -198,7 +199,6 @@
/* output descriptor FIFO of a pipe */
void print_bam_pipe_desc_fifo(void *, u32);
-#endif
/**
* Translate physical to virtual address
diff --git a/drivers/slimbus/slimbus.c b/drivers/slimbus/slimbus.c
index 72564b0..2198954 100644
--- a/drivers/slimbus/slimbus.c
+++ b/drivers/slimbus/slimbus.c
@@ -2516,6 +2516,18 @@
u32 segdist;
struct slim_pending_ch *pch;
+ /*
+ * If there are no pending changes from this client, avoid sending
+ * the reconfiguration sequence
+ */
+ if (sb->pending_msgsl == sb->cur_msgsl &&
+ list_empty(&sb->mark_define) &&
+ list_empty(&sb->mark_removal) &&
+ list_empty(&sb->mark_suspend)) {
+ pr_debug("SLIM_CL: skip reconfig sequence");
+ return 0;
+ }
+
mutex_lock(&ctrl->sched.m_reconf);
mutex_lock(&ctrl->m_ctrl);
ctrl->sched.pending_msgsl += sb->pending_msgsl - sb->cur_msgsl;
@@ -2538,7 +2550,6 @@
struct slim_ich *slc = &ctrl->chans[pch->chan];
slc->state = SLIM_CH_SUSPENDED;
}
- mutex_unlock(&ctrl->m_ctrl);
ret = slim_allocbw(sb, &subframe, &clkgear);
@@ -2688,7 +2699,6 @@
NULL, 0, 3, NULL, 0, NULL);
dev_dbg(&ctrl->dev, "reconfig now:ret:%d\n", ret);
if (!ret) {
- mutex_lock(&ctrl->m_ctrl);
ctrl->sched.subfrmcode = subframe;
ctrl->clkgear = clkgear;
ctrl->sched.msgsl = ctrl->sched.pending_msgsl;
@@ -2700,7 +2710,6 @@
}
revert_reconfig:
- mutex_lock(&ctrl->m_ctrl);
/* Revert channel changes */
slim_chan_changes(sb, true);
mutex_unlock(&ctrl->m_ctrl);
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
index 422e99e..ae1eff8 100644
--- a/drivers/spmi/spmi-pmic-arb.c
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -79,6 +79,7 @@
#define PMIC_ARB_MAX_PERIPHS 256
#define PMIC_ARB_PERIPH_ID_VALID (1 << 15)
#define PMIC_ARB_TIMEOUT_US 100
+#define PMIC_ARB_MAX_TRANS_BYTES (8)
#define PMIC_ARB_APID_MASK 0xFF
#define PMIC_ARB_PPID_MASK 0xFFF
@@ -160,49 +161,29 @@
return -ETIMEDOUT;
}
+/**
+ * pa_read_data: reads pmic-arb's register and copy 1..4 bytes to buf
+ * @bc byte count -1. range: 0..3
+ * @reg register's address
+ * @buf output parameter, length must be bc+1
+ */
static void pa_read_data(struct spmi_pmic_arb_dev *dev, u8 *buf, u32 reg, u8 bc)
{
u32 data = pmic_arb_read(dev, reg);
-
- switch (bc & 0x3) {
- case 3:
- *buf++ = data & 0xff;
- data >>= 8;
- case 2:
- *buf++ = data & 0xff;
- data >>= 8;
- case 1:
- *buf++ = data & 0xff;
- data >>= 8;
- case 0:
- *buf++ = data & 0xff;
- default:
- break;
- }
+ memcpy(buf, &data, (bc & 3) + 1);
}
+/**
+ * pa_write_data: write 1..4 bytes from buf to pmic-arb's register
+ * @bc byte-count -1. range: 0..3
+ * @reg register's address
+ * @buf buffer to write. length must be bc+1
+ */
static void
pa_write_data(struct spmi_pmic_arb_dev *dev, u8 *buf, u32 reg, u8 bc)
{
u32 data = 0;
-
- switch (bc & 0x3) {
- case 3:
- data = (buf[0]|buf[1]<<8|buf[2]<<16|buf[3]<<24);
- break;
- case 2:
- data = (buf[0]|buf[1]<<8|buf[2]<<16);
- break;
- case 1:
- data = (buf[0]|buf[1]<<8);
- break;
- case 0:
- data = (buf[0]);
- break;
- default:
- break;
- }
-
+ memcpy(&data, buf, (bc & 3) + 1);
pmic_arb_write(dev, reg, data);
}
@@ -238,6 +219,12 @@
u32 cmd;
int rc;
+ if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
+ dev_err(pmic_arb->dev
+ , "pmic-arb supports 1..%d bytes per trans, but:%d requested"
+ , PMIC_ARB_MAX_TRANS_BYTES, bc+1);
+ return -EINVAL;
+ }
pr_debug("op:0x%x sid:%d bc:%d addr:0x%x\n", opc, sid, bc, addr);
/* Check the opcode */
@@ -259,11 +246,12 @@
goto done;
/* Read from FIFO, note 'bc' is actually number of bytes minus 1 */
- pa_read_data(pmic_arb, buf, PMIC_ARB_RDATA0(pmic_arb->channel), bc);
+ pa_read_data(pmic_arb, buf, PMIC_ARB_RDATA0(pmic_arb->channel)
+ , min_t(u8, bc, 3));
if (bc > 3)
pa_read_data(pmic_arb, buf + 4,
- PMIC_ARB_RDATA1(pmic_arb->channel), bc);
+ PMIC_ARB_RDATA1(pmic_arb->channel), bc - 4);
done:
spin_unlock_irqrestore(&pmic_arb->lock, flags);
@@ -278,6 +266,12 @@
u32 cmd;
int rc;
+ if (bc >= PMIC_ARB_MAX_TRANS_BYTES) {
+ dev_err(pmic_arb->dev
+ , "pmic-arb supports 1..%d bytes per trans, but:%d requested"
+ , PMIC_ARB_MAX_TRANS_BYTES, bc+1);
+ return -EINVAL;
+ }
pr_debug("op:0x%x sid:%d bc:%d addr:0x%x\n", opc, sid, bc, addr);
/* Check the opcode */
@@ -296,11 +290,11 @@
/* Write data to FIFOs */
spin_lock_irqsave(&pmic_arb->lock, flags);
- pa_write_data(pmic_arb, buf, PMIC_ARB_WDATA0(pmic_arb->channel), bc);
-
+ pa_write_data(pmic_arb, buf, PMIC_ARB_WDATA0(pmic_arb->channel)
+ , min_t(u8, bc, 3));
if (bc > 3)
pa_write_data(pmic_arb, buf + 4,
- PMIC_ARB_WDATA1(pmic_arb->channel), bc);
+ PMIC_ARB_WDATA1(pmic_arb->channel), bc - 4);
/* Start the transaction */
pmic_arb_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd);
diff --git a/drivers/tty/smux_ctl.c b/drivers/tty/smux_ctl.c
index 0078b04..7e0e6f8 100644
--- a/drivers/tty/smux_ctl.c
+++ b/drivers/tty/smux_ctl.c
@@ -33,6 +33,7 @@
#include <linux/smux.h>
#include <linux/slab.h>
#include <linux/debugfs.h>
+#include <linux/poll.h>
#include <asm/ioctls.h>
@@ -753,6 +754,33 @@
return ret;
}
+static unsigned int smux_ctl_poll(struct file *file, poll_table *wait)
+{
+ struct smux_ctl_dev *devp;
+ unsigned int mask = 0;
+ int readable;
+
+ devp = file->private_data;
+ if (!devp)
+ return -ENODEV;
+
+ SMUXCTL_DBG(SMUX_CTL_MODULE_NAME ": %s called on smuxctl%d\n",
+ __func__, devp->id);
+
+ poll_wait(file, &devp->read_wait_queue, wait);
+
+ readable = smux_ctl_readable(devp->id);
+ if (readable < 0) {
+ pr_err(SMUX_CTL_MODULE_NAME ": %s err%d during poll for smuxctl%d\n",
+ __func__, readable, devp->id);
+ mask = POLLERR;
+ } else if (readable) {
+ mask = POLLIN | POLLRDNORM;
+ }
+
+ return mask;
+}
+
static const struct file_operations smux_ctl_fops = {
.owner = THIS_MODULE,
.open = smux_ctl_open,
@@ -760,6 +788,7 @@
.read = smux_ctl_read,
.write = smux_ctl_write,
.unlocked_ioctl = smux_ctl_ioctl,
+ .poll = smux_ctl_poll,
};
static void smux_ctl_reset_channel(struct smux_ctl_dev *devp)
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index 78ab8b7..fd10394 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -46,6 +46,8 @@
#define UETH__VERSION "29-May-2008"
+static struct workqueue_struct *uether_wq;
+
struct eth_dev {
/* lock is held while accessing port_usb
* or updating its backlink port_usb->ioport
@@ -74,6 +76,7 @@
struct sk_buff_head *list);
struct work_struct work;
+ struct work_struct rx_work;
unsigned long todo;
#define WORK_RX_MEMORY 0
@@ -88,7 +91,6 @@
#define DEFAULT_QLEN 2 /* double buffering by default */
-
#ifdef CONFIG_USB_GADGET_DUALSPEED
static unsigned qmult = 10;
@@ -265,18 +267,16 @@
DBG(dev, "rx submit --> %d\n", retval);
if (skb)
dev_kfree_skb_any(skb);
- spin_lock_irqsave(&dev->req_lock, flags);
- list_add(&req->list, &dev->rx_reqs);
- spin_unlock_irqrestore(&dev->req_lock, flags);
}
return retval;
}
static void rx_complete(struct usb_ep *ep, struct usb_request *req)
{
- struct sk_buff *skb = req->context, *skb2;
+ struct sk_buff *skb = req->context;
struct eth_dev *dev = ep->driver_data;
int status = req->status;
+ bool queue = 0;
switch (status) {
@@ -300,30 +300,9 @@
} else {
skb_queue_tail(&dev->rx_frames, skb);
}
- skb = NULL;
- skb2 = skb_dequeue(&dev->rx_frames);
- while (skb2) {
- if (status < 0
- || ETH_HLEN > skb2->len
- || skb2->len > ETH_FRAME_LEN) {
- dev->net->stats.rx_errors++;
- dev->net->stats.rx_length_errors++;
- DBG(dev, "rx length %d\n", skb2->len);
- dev_kfree_skb_any(skb2);
- goto next_frame;
- }
- skb2->protocol = eth_type_trans(skb2, dev->net);
- dev->net->stats.rx_packets++;
- dev->net->stats.rx_bytes += skb2->len;
-
- /* no buffer copies needed, unless hardware can't
- * use skb buffers.
- */
- status = netif_rx(skb2);
-next_frame:
- skb2 = skb_dequeue(&dev->rx_frames);
- }
+ if (!status)
+ queue = 1;
break;
/* software-driven interface shutdown */
@@ -346,22 +325,20 @@
/* FALLTHROUGH */
default:
+ queue = 1;
+ dev_kfree_skb_any(skb);
dev->net->stats.rx_errors++;
DBG(dev, "rx status %d\n", status);
break;
}
- if (skb)
- dev_kfree_skb_any(skb);
- if (!netif_running(dev->net)) {
clean:
- spin_lock(&dev->req_lock);
- list_add(&req->list, &dev->rx_reqs);
- spin_unlock(&dev->req_lock);
- req = NULL;
- }
- if (req)
- rx_submit(dev, req, GFP_ATOMIC);
+ spin_lock(&dev->req_lock);
+ list_add(&req->list, &dev->rx_reqs);
+ spin_unlock(&dev->req_lock);
+
+ if (queue)
+ queue_work(uether_wq, &dev->rx_work);
}
static int prealloc(struct list_head *list, struct usb_ep *ep, unsigned n)
@@ -426,16 +403,24 @@
{
struct usb_request *req;
unsigned long flags;
+ int req_cnt = 0;
/* fill unused rxq slots with some skb */
spin_lock_irqsave(&dev->req_lock, flags);
while (!list_empty(&dev->rx_reqs)) {
+ /* break the nexus of continuous completion and re-submission*/
+ if (++req_cnt > qlen(dev->gadget))
+ break;
+
req = container_of(dev->rx_reqs.next,
struct usb_request, list);
list_del_init(&req->list);
spin_unlock_irqrestore(&dev->req_lock, flags);
if (rx_submit(dev, req, gfp_flags) < 0) {
+ spin_lock_irqsave(&dev->req_lock, flags);
+ list_add(&req->list, &dev->rx_reqs);
+ spin_unlock_irqrestore(&dev->req_lock, flags);
defer_kevent(dev, WORK_RX_MEMORY);
return;
}
@@ -445,6 +430,36 @@
spin_unlock_irqrestore(&dev->req_lock, flags);
}
+static void process_rx_w(struct work_struct *work)
+{
+ struct eth_dev *dev = container_of(work, struct eth_dev, rx_work);
+ struct sk_buff *skb;
+ int status = 0;
+
+ if (!dev->port_usb)
+ return;
+
+ while ((skb = skb_dequeue(&dev->rx_frames))) {
+ if (status < 0
+ || ETH_HLEN > skb->len
+ || skb->len > ETH_FRAME_LEN) {
+ dev->net->stats.rx_errors++;
+ dev->net->stats.rx_length_errors++;
+ DBG(dev, "rx length %d\n", skb->len);
+ dev_kfree_skb_any(skb);
+ continue;
+ }
+ skb->protocol = eth_type_trans(skb, dev->net);
+ dev->net->stats.rx_packets++;
+ dev->net->stats.rx_bytes += skb->len;
+
+ status = netif_rx_ni(skb);
+ }
+
+ if (netif_running(dev->net))
+ rx_fill(dev, GFP_KERNEL);
+}
+
static void eth_work(struct work_struct *work)
{
struct eth_dev *dev = container_of(work, struct eth_dev, work);
@@ -931,6 +946,7 @@
spin_lock_init(&dev->lock);
spin_lock_init(&dev->req_lock);
INIT_WORK(&dev->work, eth_work);
+ INIT_WORK(&dev->rx_work, process_rx_w);
INIT_LIST_HEAD(&dev->tx_reqs);
INIT_LIST_HEAD(&dev->rx_reqs);
@@ -1096,6 +1112,7 @@
{
struct eth_dev *dev = link->ioport;
struct usb_request *req;
+ struct sk_buff *skb;
if (!dev)
return;
@@ -1138,6 +1155,12 @@
spin_lock(&dev->req_lock);
}
spin_unlock(&dev->req_lock);
+
+ spin_lock(&dev->rx_frames.lock);
+ while ((skb = __skb_dequeue(&dev->rx_frames)))
+ dev_kfree_skb_any(skb);
+ spin_unlock(&dev->rx_frames.lock);
+
link->out_ep->driver_data = NULL;
link->out_ep->desc = NULL;
@@ -1151,3 +1174,23 @@
link->ioport = NULL;
spin_unlock(&dev->lock);
}
+
+static int __init gether_init(void)
+{
+ uether_wq = create_singlethread_workqueue("uether");
+ if (!uether_wq) {
+ pr_err("%s: Unable to create workqueue: uether\n", __func__);
+ return -ENOMEM;
+ }
+ return 0;
+}
+module_init(gether_init);
+
+static void __exit gether_exit(void)
+{
+ destroy_workqueue(uether_wq);
+
+}
+module_exit(gether_exit);
+MODULE_DESCRIPTION("ethernet over USB driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index c397f84..ee73eea 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -68,6 +68,8 @@
boolean mdp_current_clk_on = FALSE;
boolean mdp_is_in_isr = FALSE;
+struct vsync vsync_cntrl;
+
/*
* legacy mdp_in_processing is only for DMA2-MDDI
* this applies to DMA2 block only
@@ -95,13 +97,13 @@
static struct delayed_work mdp_pipe_ctrl_worker;
static boolean mdp_suspended = FALSE;
+ulong mdp4_display_intf;
DEFINE_MUTEX(mdp_suspend_mutex);
#ifdef CONFIG_FB_MSM_MDP40
struct mdp_dma_data dma2_data;
struct mdp_dma_data dma_s_data;
struct mdp_dma_data dma_e_data;
-ulong mdp4_display_intf;
#else
static struct mdp_dma_data dma2_data;
static struct mdp_dma_data dma_s_data;
@@ -1270,8 +1272,56 @@
}
#endif
-/* Returns < 0 on error, 0 on timeout, or > 0 on successful wait */
+static void send_vsync_work(struct work_struct *work)
+{
+ char buf[64];
+ char *envp[2];
+ snprintf(buf, sizeof(buf), "VSYNC=%llu",
+ ktime_to_ns(vsync_cntrl.vsync_time));
+ envp[0] = buf;
+ envp[1] = NULL;
+ kobject_uevent_env(&(vsync_cntrl.dev->kobj), KOBJ_CHANGE, envp);
+}
+
+void mdp3_vsync_irq_enable(int intr, int term)
+{
+ unsigned long flag;
+
+ spin_lock_irqsave(&mdp_spin_lock, flag);
+ outp32(MDP_INTR_CLEAR, intr);
+ mdp_intr_mask |= intr;
+ outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+ mdp_enable_irq(term);
+ spin_unlock_irqrestore(&mdp_spin_lock, flag);
+}
+
+void mdp3_vsync_irq_disable(int intr, int term)
+{
+ unsigned long flag;
+
+ spin_lock_irqsave(&mdp_spin_lock, flag);
+ /* required to synchronize between frame update and vsync
+ * since both use the same LCDC_FRAME_START interrupt
+ */
+ if (intr == LCDC_FRAME_START && dma2_data.waiting == FALSE) {
+ mdp_intr_mask &= ~intr;
+ outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+ }
+ mdp_disable_irq(term);
+ spin_unlock_irqrestore(&mdp_spin_lock, flag);
+}
+
+#ifdef CONFIG_FB_MSM_MDP303
+/* vsync_isr_handler: Called from isr context*/
+static void vsync_isr_handler(void)
+{
+ vsync_cntrl.vsync_time = ktime_get();
+ schedule_work(&(vsync_cntrl.vsync_work));
+}
+#endif
+
+/* Returns < 0 on error, 0 on timeout, or > 0 on successful wait */
int mdp_ppp_pipe_wait(void)
{
int ret = 1;
@@ -1729,6 +1779,10 @@
if (!mdp_interrupt)
goto out;
+ /*Primary Vsync interrupt*/
+ if (mdp_interrupt & MDP_PRIM_RDPTR)
+ vsync_isr_handler();
+
/* DMA3 TV-Out Start */
if (mdp_interrupt & TV_OUT_DMA3_START) {
/* let's disable TV out interrupt */
@@ -1776,12 +1830,19 @@
dma = &dma2_data;
spin_lock_irqsave(&mdp_spin_lock, flag);
/* let's disable LCDC interrupt */
- mdp_intr_mask &= ~LCDC_FRAME_START;
- outp32(MDP_INTR_ENABLE, mdp_intr_mask);
if (dma->waiting) {
dma->waiting = FALSE;
complete(&dma->comp);
}
+
+ if (vsync_cntrl.vsync_irq_enabled)
+ vsync_isr_handler();
+
+ if (!vsync_cntrl.vsync_irq_enabled && !(dma->waiting)) {
+ mdp_intr_mask &= ~LCDC_FRAME_START;
+ outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+ }
+
spin_unlock_irqrestore(&mdp_spin_lock, flag);
}
@@ -1912,7 +1973,7 @@
for (i = 0; i < MDP_MAX_BLOCK; i++) {
atomic_set(&mdp_block_power_cnt[i], 0);
}
-
+ INIT_WORK(&(vsync_cntrl.vsync_work), send_vsync_work);
#ifdef MSM_FB_ENABLE_DBGFS
{
struct dentry *root;
@@ -2030,33 +2091,39 @@
static int mdp_on(struct platform_device *pdev)
{
int ret = 0;
-#ifdef CONFIG_FB_MSM_MDP40
struct msm_fb_data_type *mfd;
-
mfd = platform_get_drvdata(pdev);
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
- mdp_clk_ctrl(1);
- mdp4_hw_init();
- outpdw(MDP_BASE + 0x0038, mdp4_display_intf);
- if (mfd->panel.type == MIPI_CMD_PANEL) {
- mdp_vsync_cfg_regs(mfd, FALSE);
- mdp4_dsi_cmd_on(pdev);
- } else if (mfd->panel.type == MIPI_VIDEO_PANEL)
- mdp4_dsi_video_on(pdev);
- else if (mfd->panel.type == HDMI_PANEL ||
- mfd->panel.type == LCDC_PANEL ||
- mfd->panel.type == LVDS_PANEL)
- mdp4_lcdc_on(pdev);
- mdp_clk_ctrl(0);
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
-#endif
+ if (mdp_rev >= MDP_REV_40) {
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+ mdp_clk_ctrl(1);
+ mdp4_hw_init();
+ outpdw(MDP_BASE + 0x0038, mdp4_display_intf);
+ if (mfd->panel.type == MIPI_CMD_PANEL) {
+ mdp_vsync_cfg_regs(mfd, FALSE);
+ mdp4_dsi_cmd_on(pdev);
+ } else if (mfd->panel.type == MIPI_VIDEO_PANEL) {
+ mdp4_dsi_video_on(pdev);
+ } else if (mfd->panel.type == HDMI_PANEL ||
+ mfd->panel.type == LCDC_PANEL ||
+ mfd->panel.type == LVDS_PANEL) {
+ mdp4_lcdc_on(pdev);
+ }
+
+ mdp_clk_ctrl(0);
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+ }
+
+ if ((mdp_rev == MDP_REV_303) &&
+ (mfd->panel.type == MIPI_CMD_PANEL))
+ vsync_cntrl.dev = mfd->fbi->dev;
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
ret = panel_next_on(pdev);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
mdp_histogram_ctrl_all(TRUE);
return ret;
@@ -2518,6 +2585,7 @@
mfd->do_histogram = mdp_do_histogram;
mfd->start_histogram = mdp_histogram_start;
mfd->stop_histogram = mdp_histogram_stop;
+ mfd->vsync_ctrl = mdp_dma_video_vsync_ctrl;
if (mfd->panel_info.pdest == DISPLAY_1)
mfd->dma = &dma2_data;
else {
@@ -2564,6 +2632,7 @@
mfd->do_histogram = mdp_do_histogram;
mfd->start_histogram = mdp_histogram_start;
mfd->stop_histogram = mdp_histogram_stop;
+ mfd->vsync_ctrl = mdp_dma_vsync_ctrl;
if (mfd->panel_info.pdest == DISPLAY_1)
mfd->dma = &dma2_data;
else {
@@ -2631,6 +2700,7 @@
}
#else
mfd->dma = &dma2_data;
+ mfd->vsync_ctrl = mdp_dma_lcdc_vsync_ctrl;
spin_lock_irqsave(&mdp_spin_lock, flag);
mdp_intr_mask &= ~MDP_DMA_P_DONE;
outp32(MDP_INTR_ENABLE, mdp_intr_mask);
@@ -2683,11 +2753,12 @@
mdp_clk_ctrl(0);
goto mdp_probe_err;
}
-#ifdef CONFIG_FB_MSM_MDP40
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
- mdp4_display_intf = inpdw(MDP_BASE + 0x0038);
- mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
-#endif
+
+ if (mdp_rev >= MDP_REV_40) {
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+ mdp4_display_intf = inpdw(MDP_BASE + 0x0038);
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+ }
mdp_clk_ctrl(0);
diff --git a/drivers/video/msm/mdp.h b/drivers/video/msm/mdp.h
index 2411dca..12bd1d4 100644
--- a/drivers/video/msm/mdp.h
+++ b/drivers/video/msm/mdp.h
@@ -44,9 +44,10 @@
extern int mdp_rev;
extern int mdp_iommu_split_domain;
extern struct mdp_csc_cfg mdp_csc_convert[4];
-
extern struct workqueue_struct *mdp_hist_wq;
+extern uint32 mdp_intr_mask;
+
#define MDP4_REVISION_V1 0
#define MDP4_REVISION_V2 1
#define MDP4_REVISION_V2_1 2
@@ -90,6 +91,15 @@
extern unsigned char hdmi_prim_display;
extern unsigned char hdmi_prim_resolution;
+struct vsync {
+ ktime_t vsync_time;
+ struct device *dev;
+ struct work_struct vsync_work;
+ int vsync_irq_enabled;
+};
+
+extern struct vsync vsync_cntrl;
+
/*
* MDP Image Structure
*/
@@ -287,6 +297,7 @@
#define MDP_HISTOGRAM_TERM_DMA_S 0x20000
#define MDP_HISTOGRAM_TERM_VG_1 0x40000
#define MDP_HISTOGRAM_TERM_VG_2 0x80000
+#define MDP_VSYNC_TERM 0x1000
#define ACTIVE_START_X_EN BIT(31)
#define ACTIVE_START_Y_EN BIT(31)
@@ -306,6 +317,7 @@
#define MDP_PPP_DONE BIT(0)
#define TV_OUT_DMA3_DONE BIT(6)
#define TV_ENC_UNDERRUN BIT(7)
+#define MDP_PRIM_RDPTR BIT(8)
#define TV_OUT_DMA3_START BIT(13)
#define MDP_HIST_DONE BIT(20)
@@ -812,6 +824,11 @@
return 0;
}
#endif
+void mdp_dma_vsync_ctrl(int enable);
+void mdp_dma_video_vsync_ctrl(int enable);
+void mdp_dma_lcdc_vsync_ctrl(int enable);
+void mdp3_vsync_irq_enable(int intr, int term);
+void mdp3_vsync_irq_disable(int intr, int term);
#ifdef MDP_HW_VSYNC
void vsync_clk_enable(void);
@@ -862,6 +879,11 @@
{
/* empty */
}
+static inline int msmfb_overlay_vsync_ctrl(struct fb_info *info,
+ void __user *argp)
+{
+ return 0;
+}
#endif
int mdp_ppp_v4l2_overlay_set(struct fb_info *info, struct mdp_overlay *req);
diff --git a/drivers/video/msm/mdp_dma.c b/drivers/video/msm/mdp_dma.c
index 3a7513a..a506648 100644
--- a/drivers/video/msm/mdp_dma.c
+++ b/drivers/video/msm/mdp_dma.c
@@ -512,6 +512,23 @@
up(&mfd->dma->mutex);
}
+void mdp_dma_vsync_ctrl(int enable)
+{
+ if (vsync_cntrl.vsync_irq_enabled == enable)
+ return;
+
+ vsync_cntrl.vsync_irq_enabled = enable;
+
+ if (enable) {
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+ MDP_OUTP(MDP_BASE + 0x021c, 0x10); /* read pointer */
+ mdp3_vsync_irq_enable(MDP_PRIM_RDPTR, MDP_VSYNC_TERM);
+ } else {
+ mdp3_vsync_irq_disable(MDP_PRIM_RDPTR, MDP_VSYNC_TERM);
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+ }
+}
+
void mdp_lcd_update_workqueue_handler(struct work_struct *work)
{
struct msm_fb_data_type *mfd = NULL;
diff --git a/drivers/video/msm/mdp_dma_dsi_video.c b/drivers/video/msm/mdp_dma_dsi_video.c
index 3d6448f..d94896f 100644
--- a/drivers/video/msm/mdp_dma_dsi_video.c
+++ b/drivers/video/msm/mdp_dma_dsi_video.c
@@ -87,6 +87,7 @@
fbi = mfd->fbi;
var = &fbi->var;
+ vsync_cntrl.dev = mfd->fbi->dev;
bpp = fbi->var.bits_per_pixel / 8;
buf = (uint8 *) fbi->fix.smem_start;
@@ -246,6 +247,22 @@
return ret;
}
+void mdp_dma_video_vsync_ctrl(int enable)
+{
+ if (vsync_cntrl.vsync_irq_enabled == enable)
+ return;
+
+ vsync_cntrl.vsync_irq_enabled = enable;
+
+ if (enable) {
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+ mdp3_vsync_irq_enable(LCDC_FRAME_START, MDP_VSYNC_TERM);
+ } else {
+ mdp3_vsync_irq_disable(LCDC_FRAME_START, MDP_VSYNC_TERM);
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+ }
+}
+
void mdp_dsi_video_update(struct msm_fb_data_type *mfd)
{
struct fb_info *fbi = mfd->fbi;
diff --git a/drivers/video/msm/mdp_dma_lcdc.c b/drivers/video/msm/mdp_dma_lcdc.c
index f9bf269..e030c99 100644
--- a/drivers/video/msm/mdp_dma_lcdc.c
+++ b/drivers/video/msm/mdp_dma_lcdc.c
@@ -105,6 +105,7 @@
fbi = mfd->fbi;
var = &fbi->var;
+ vsync_cntrl.dev = mfd->fbi->dev;
/* MDP cmd block enable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
@@ -327,6 +328,22 @@
return ret;
}
+void mdp_dma_lcdc_vsync_ctrl(int enable)
+{
+ if (vsync_cntrl.vsync_irq_enabled == enable)
+ return;
+
+ vsync_cntrl.vsync_irq_enabled = enable;
+
+ if (enable) {
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+ mdp3_vsync_irq_enable(LCDC_FRAME_START, MDP_VSYNC_TERM);
+ } else {
+ mdp3_vsync_irq_disable(LCDC_FRAME_START, MDP_VSYNC_TERM);
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+ }
+}
+
void mdp_lcdc_update(struct msm_fb_data_type *mfd)
{
struct fb_info *fbi = mfd->fbi;
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index a984637..18ec3f1 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -377,6 +377,7 @@
if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
return -ENOMEM;
+ vsync_cntrl.dev = mfd->fbi->dev;
mfd->panel_info.frame_count = 0;
mfd->bl_level = 0;
bl_scale = 1024;
@@ -2819,6 +2820,27 @@
return 0;
}
+static int msmfb_vsync_ctrl(struct fb_info *info, void __user *argp)
+{
+ int enable, ret;
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+
+ ret = copy_from_user(&enable, argp, sizeof(enable));
+ if (ret) {
+ pr_err("%s:msmfb_overlay_vsync ioctl failed", __func__);
+ return ret;
+ }
+
+ if (mfd->vsync_ctrl)
+ mfd->vsync_ctrl(enable);
+ else {
+ pr_err("%s: Vsync IOCTL not supported", __func__);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
#ifdef CONFIG_FB_MSM_OVERLAY
static int msmfb_overlay_get(struct fb_info *info, void __user *p)
{
@@ -2881,25 +2903,6 @@
return mdp4_overlay_unset(info, ndx);
}
-static int msmfb_overlay_wait4vsync(struct fb_info *info, void __user *argp)
-{
- int ret;
- long long vtime;
-
- ret = mdp4_overlay_wait4vsync(info, &vtime);
- if (ret) {
- pr_err("%s: ioctl failed\n", __func__);
- return ret;
- }
-
- if (copy_to_user(argp, &vtime, sizeof(vtime))) {
- pr_err("%s: copy2user failed\n", __func__);
- return -EFAULT;
- }
-
- return 0;
-}
-
static int msmfb_overlay_vsync_ctrl(struct fb_info *info, void __user *argp)
{
int ret;
@@ -3331,16 +3334,6 @@
switch (cmd) {
#ifdef CONFIG_FB_MSM_OVERLAY
- case FBIO_WAITFORVSYNC:
- down(&msm_fb_ioctl_ppp_sem);
- ret = msmfb_overlay_wait4vsync(info, argp);
- up(&msm_fb_ioctl_ppp_sem);
- break;
- case MSMFB_OVERLAY_VSYNC_CTRL:
- down(&msm_fb_ioctl_ppp_sem);
- ret = msmfb_overlay_vsync_ctrl(info, argp);
- up(&msm_fb_ioctl_ppp_sem);
- break;
case MSMFB_OVERLAY_GET:
down(&msm_fb_ioctl_ppp_sem);
ret = msmfb_overlay_get(info, argp);
@@ -3409,6 +3402,15 @@
ret = msmfb_overlay_ioctl_writeback_terminate(info);
break;
#endif
+ case MSMFB_VSYNC_CTRL:
+ case MSMFB_OVERLAY_VSYNC_CTRL:
+ down(&msm_fb_ioctl_ppp_sem);
+ if (mdp_rev >= MDP_REV_40)
+ ret = msmfb_overlay_vsync_ctrl(info, argp);
+ else
+ ret = msmfb_vsync_ctrl(info, argp);
+ up(&msm_fb_ioctl_ppp_sem);
+ break;
case MSMFB_BLIT:
down(&msm_fb_ioctl_ppp_sem);
ret = msmfb_blit(info, argp);
diff --git a/drivers/video/msm/msm_fb.h b/drivers/video/msm/msm_fb.h
index 0658365..efe6160 100644
--- a/drivers/video/msm/msm_fb.h
+++ b/drivers/video/msm/msm_fb.h
@@ -80,6 +80,7 @@
DISP_TARGET dest;
struct fb_info *fbi;
+ struct device *dev;
boolean op_enable;
uint32 fb_imgType;
boolean sw_currently_refreshing;
@@ -134,6 +135,7 @@
struct mdp_histogram_data *hist);
int (*start_histogram) (struct mdp_histogram_start_req *req);
int (*stop_histogram) (struct fb_info *info, uint32_t block);
+ void (*vsync_ctrl) (int enable);
void *cursor_buf;
void *cursor_buf_phys;
diff --git a/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h b/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h
index 93c21ce..9619527 100644
--- a/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h
+++ b/include/linux/mfd/wcd9xxx/wcd9xxx-slimslave.h
@@ -16,10 +16,6 @@
#include <linux/slimbus/slimbus.h>
#include <linux/mfd/wcd9xxx/core.h>
-/* Local to the core only */
-#define SLIM_MAX_RX_PORTS 7
-#define SLIM_MAX_TX_PORTS 10
-
/* Channel numbers to be used for each port */
enum {
SLIM_TX_1 = 128,
@@ -43,20 +39,43 @@
};
/*
- * client is expected to give port ids in the range of 1-10 for Tx ports and
- * 1-7 for Rx ports, we need to add offset for getting the absolute slave
+ * client is expected to give port ids in the range of
+ * 1-10 for pre Taiko Tx ports and 1-16 for Taiko
+ * 1-7 for pre Taiko Rx ports and 1-16 for Tako,
+ * we need to add offset for getting the absolute slave
* port id before configuring the HW
*/
-#define SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS 10
-#define SB_PGD_OFFSET_OF_TX_SLAVE_DEV_PORTS -1
-#define SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS 7
-#define SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS 9
+#define TABLA_SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS 10
+#define TAIKO_SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS 16
+
+#define SLIM_MAX_TX_PORTS TAIKO_SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS
+
+#define TABLA_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS \
+ TABLA_SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS
+#define TAIKO_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS \
+ TAIKO_SB_PGD_MAX_NUMBER_OF_TX_SLAVE_DEV_PORTS
+
+#define TABLA_SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS 7
+#define TAIKO_SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS 13
+
+#define SLIM_MAX_RX_PORTS TAIKO_SB_PGD_MAX_NUMBER_OF_RX_SLAVE_DEV_PORTS
+
+#define TABLA_SB_PGD_RX_PORT_MULTI_CHANNEL_0_START_PORT_ID \
+ TABLA_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS
+#define TAIKO_SB_PGD_RX_PORT_MULTI_CHANNEL_0_START_PORT_ID \
+ TAIKO_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS
+
+#define TABLA_SB_PGD_RX_PORT_MULTI_CHANNEL_0_END_PORT_ID 16
+#define TAIKO_SB_PGD_RX_PORT_MULTI_CHANNEL_0_END_PORT_ID 31
+
+#define TABLA_SB_PGD_TX_PORT_MULTI_CHANNEL_1_END_PORT_ID 9
+#define TAIKO_SB_PGD_TX_PORT_MULTI_CHANNEL_1_END_PORT_ID 15
/* below details are taken from SLIMBUS slave SWI */
#define SB_PGD_PORT_BASE 0x000
-#define SB_PGD_PORT_CFG_BYTE_ADDR(port_num) \
- (SB_PGD_PORT_BASE + 0x040 + 1*port_num)
+#define SB_PGD_PORT_CFG_BYTE_ADDR(offset, port_num) \
+ (SB_PGD_PORT_BASE + offset + (1 * port_num))
#define SB_PGD_TX_PORT_MULTI_CHANNEL_0(port_num) \
(SB_PGD_PORT_BASE + 0x100 + 4*port_num)
@@ -66,12 +85,9 @@
#define SB_PGD_TX_PORT_MULTI_CHANNEL_1(port_num) \
(SB_PGD_PORT_BASE + 0x101 + 4*port_num)
#define SB_PGD_TX_PORT_MULTI_CHANNEL_1_START_PORT_ID 8
-#define SB_PGD_TX_PORT_MULTI_CHANNEL_1_END_PORT_ID 9
-#define SB_PGD_RX_PORT_MULTI_CHANNEL_0(port_num) \
- (SB_PGD_PORT_BASE + 0x180 + 4*port_num)
-#define SB_PGD_RX_PORT_MULTI_CHANNEL_0_START_PORT_ID 10
-#define SB_PGD_RX_PORT_MULTI_CHANNEL_0_END_PORT_ID 16
+#define SB_PGD_RX_PORT_MULTI_CHANNEL_0(offset, port_num) \
+ (SB_PGD_PORT_BASE + offset + (4 * port_num))
/* slave port water mark level
* (0: 6bytes, 1: 9bytes, 2: 12 bytes, 3: 15 bytes)
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index 4c42623..2519a6e 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -68,10 +68,8 @@
struct msmfb_data)
#define MSMFB_WRITEBACK_TERMINATE _IO(MSMFB_IOCTL_MAGIC, 155)
#define MSMFB_MDP_PP _IOWR(MSMFB_IOCTL_MAGIC, 156, struct msmfb_mdp_pp)
-
-#define MSMFB_OVERLAY_VSYNC_CTRL _IOW(MSMFB_IOCTL_MAGIC, 160, unsigned int)
-
-
+#define MSMFB_OVERLAY_VSYNC_CTRL _IOW(MSMFB_IOCTL_MAGIC, 160, unsigned int)
+#define MSMFB_VSYNC_CTRL _IOW(MSMFB_IOCTL_MAGIC, 161, unsigned int)
#define FB_TYPE_3D_PANEL 0x10101010
#define MDP_IMGTYPE2_START 0x10000
#define MSMFB_DRIVER_VERSION 0xF9E8D701