Several Intel PCHs and SOCs have an internal mux that is[...]
used to share one USB port between USB Device Controller and
xHCI. The mux is normally handled by System FW/BIOS, but not
always. For those platforms where the FW does not take care
of the mux, this driver is needed.
Signed-off-by: Heikki Krogerus <heikki.krogerus@xxxxxxxxxxxxxxx>
diff --git a/drivers/extcon/extcon-intel-usb.c b/drivers/extcon/extcon-intel-usb.c[...]
new file mode 100644
index 0000000..3da6039
--- /dev/null
+++ b/drivers/extcon/extcon-intel-usb.c
@@ -0,0 +1,118 @@
+struct intel_usb_mux *intel_usb_mux_register(struct device *dev,
+ struct resource *r)
+{
+ struct intel_usb_mux *mux;
+ int ret;
+
+ mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+ if (!mux)
+ return ERR_PTR(-ENOMEM);
+
+ mux->regs = ioremap_nocache(r->start, resource_size(r));
+ if (!mux->regs) {
+ kfree(mux);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ mux->cfg0_ctx = readl(mux->regs + INTEL_MUX_CFG0);
+
+ mux->edev.dev.parent = dev;
+ mux->edev.supported_cable = intel_mux_cable;
+
+ ret = extcon_dev_register(&mux->edev);
+ if (ret)
+ goto err;
+
+ mux->edev.name = "intel_usb_mux";
+ mux->edev.state = !!(readl(mux->regs + INTEL_MUX_CFG1) & CFG1_MODE);
+
+ /* An external source needs to tell us what to do */
+ mux->nb.notifier_call = intel_usb_mux_notifier;
+ ret = extcon_register_notifier(&mux->edev, EXTCON_USB_HOST, &mux->nb);