[PATCH 22/25] USB OTG Langwell: use notifier for otg events

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Hao Wu <hao.wu@xxxxxxxxx>

Original implementation is that both host/client driver will modify state
machine data structure directly, but according to common data structure
and framework, host/client will only notify the transceiver driver the
otg events using the unified interface - notifier, and the event handle
will only be in the transceiver driver.

This patch updates Langwell Transceiver Driver to use notifier according
to the common data structure for Intel MID platform. Please notice that
it requires related modification in Host/client driver to work.

Signed-off-by: Hao Wu <hao.wu@xxxxxxxxx>
Signed-off-by: Alan Cox <alan@xxxxxxxxxxxxxxx>
---

 drivers/usb/otg/langwell_otg.c   |  107 ++++++++++++++++++++++++++++++++++++++
 include/linux/usb/langwell_otg.h |    2 +
 2 files changed, 109 insertions(+), 0 deletions(-)


diff --git a/drivers/usb/otg/langwell_otg.c b/drivers/usb/otg/langwell_otg.c
index c23471c..8791880 100644
--- a/drivers/usb/otg/langwell_otg.c
+++ b/drivers/usb/otg/langwell_otg.c
@@ -887,6 +887,101 @@ static irqreturn_t otg_irq(int irq, void *_dev)
 	return IRQ_HANDLED;
 }
 
+static int langwell_otg_iotg_notify(struct notifier_block *nb,
+				unsigned long action, void *data)
+{
+	struct langwell_otg		*lnw = the_transceiver;
+	struct intel_mid_otg_xceiv	*iotg = data;
+	int				flag = 0;
+
+	if (iotg == NULL)
+		return NOTIFY_BAD;
+
+	if (lnw == NULL)
+		return NOTIFY_BAD;
+
+	switch (action) {
+	case MID_OTG_NOTIFY_CONNECT:
+		dev_dbg(lnw->dev, "Lnw OTG Notify Connect Event\n");
+		if (iotg->otg.default_a == 1)
+			iotg->hsm.b_conn = 1;
+		else
+			iotg->hsm.a_conn = 1;
+		flag = 1;
+		break;
+	case MID_OTG_NOTIFY_DISCONN:
+		dev_dbg(lnw->dev, "Lnw OTG Notify Disconnect Event\n");
+		if (iotg->otg.default_a == 1)
+			iotg->hsm.b_conn = 0;
+		else
+			iotg->hsm.a_conn = 0;
+		flag = 1;
+		break;
+	case MID_OTG_NOTIFY_HSUSPEND:
+		dev_dbg(lnw->dev, "Lnw OTG Notify Host Bus suspend Event\n");
+		if (iotg->otg.default_a == 1)
+			iotg->hsm.a_suspend_req = 1;
+		else
+			iotg->hsm.b_bus_req = 0;
+		flag = 1;
+		break;
+	case MID_OTG_NOTIFY_HRESUME:
+		dev_dbg(lnw->dev, "Lnw OTG Notify Host Bus resume Event\n");
+		if (iotg->otg.default_a == 1)
+			iotg->hsm.b_bus_resume = 1;
+		flag = 1;
+		break;
+	case MID_OTG_NOTIFY_CSUSPEND:
+		dev_dbg(lnw->dev, "Lnw OTG Notify Client Bus suspend Event\n");
+		if (iotg->otg.default_a == 1) {
+			if (iotg->hsm.b_bus_suspend_vld == 2) {
+				iotg->hsm.b_bus_suspend = 1;
+				iotg->hsm.b_bus_suspend_vld = 0;
+				flag = 1;
+			} else {
+				iotg->hsm.b_bus_suspend_vld++;
+				flag = 0;
+			}
+		} else {
+			if (iotg->hsm.a_bus_suspend == 0) {
+				iotg->hsm.a_bus_suspend = 1;
+				flag = 1;
+			}
+		}
+		break;
+	case MID_OTG_NOTIFY_CRESUME:
+		dev_dbg(lnw->dev, "Lnw OTG Notify Client Bus resume Event\n");
+		if (iotg->otg.default_a == 0)
+			iotg->hsm.a_bus_suspend = 0;
+		flag = 0;
+		break;
+	case MID_OTG_NOTIFY_HOSTADD:
+		dev_dbg(lnw->dev, "Lnw OTG Nofity Host Driver Add\n");
+		flag = 1;
+		break;
+	case MID_OTG_NOTIFY_HOSTREMOVE:
+		dev_dbg(lnw->dev, "Lnw OTG Nofity Host Driver remove\n");
+		flag = 1;
+		break;
+	case MID_OTG_NOTIFY_CLIENTADD:
+		dev_dbg(lnw->dev, "Lnw OTG Nofity Client Driver Add\n");
+		flag = 1;
+		break;
+	case MID_OTG_NOTIFY_CLIENTREMOVE:
+		dev_dbg(lnw->dev, "Lnw OTG Nofity Client Driver remove\n");
+		flag = 1;
+		break;
+	default:
+		dev_dbg(lnw->dev, "Lnw OTG Nofity unknown notify message\n");
+		return NOTIFY_DONE;
+	}
+
+	if (flag)
+		langwell_update_transceiver();
+
+	return NOTIFY_OK;
+}
+
 static void langwell_otg_work(struct work_struct *work)
 {
 	struct langwell_otg		*lnw;
@@ -2030,6 +2125,17 @@ static int langwell_otg_probe(struct pci_dev *pdev,
 	}
 
 	init_timer(&lnw->hsm_timer);
+	ATOMIC_INIT_NOTIFIER_HEAD(&lnw->iotg.iotg_notifier);
+
+	lnw->iotg_notifier.notifier_call = langwell_otg_iotg_notify;
+
+	retval = intel_mid_otg_register_notifier(&lnw->iotg,
+						&lnw->iotg_notifier);
+	if (retval) {
+		dev_dbg(lnw->dev, "Failed to register notifier\n");
+		goto err;
+	}
+
 	if (request_irq(pdev->irq, otg_irq, IRQF_SHARED,
 				driver_name, lnw) != 0) {
 		dev_dbg(lnw->dev, "request interrupt %d failed\n", pdev->irq);
@@ -2082,6 +2188,7 @@ static void langwell_otg_remove(struct pci_dev *pdev)
 		flush_workqueue(lnw->qwork);
 		destroy_workqueue(lnw->qwork);
 	}
+	intel_mid_otg_unregister_notifier(&lnw->iotg, &lnw->iotg_notifier);
 	langwell_otg_free_timers();
 
 	/* disable OTGSC interrupt as OTGSC doesn't change in reset */
diff --git a/include/linux/usb/langwell_otg.h b/include/linux/usb/langwell_otg.h
index 5da7f59..a6562f1 100644
--- a/include/linux/usb/langwell_otg.h
+++ b/include/linux/usb/langwell_otg.h
@@ -126,6 +126,8 @@ struct langwell_otg {
 
 	spinlock_t			lock;
 	spinlock_t			wq_lock;
+
+	struct notifier_block		iotg_notifier;
 };
 
 static inline

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux