usb: add support for Intel dual role port mux
cover usb: add support for Intel dual role port mux
Intel SOC chips are featured with USB dual role. The host role is provided by Intel xHCI IP, and the gadget role is provided by IP from designware. Tablet platform designs always share a single port for both host and gadget controllers. There is a mux to switch the port to the right controller according to the cable type. OS needs to provide the callback to control the mux when a plug-in event raises. The method to control the mux is platform dependent. At least three types of implementation can be found across current devices. 1) GPIO pins; 2) a unit which can be controlled by memory mapped registers; 3) ACPI ASL code.
This patch series adds supports for Intel dual role port mux. It includes:
(1) A helper layer on top of extcon for individual mux driver. It listens to the USB-HOST extcon cable and call the switch call-back when the cable state changes.
(2) Drivers for GPIO controlled port mux which could be found on Baytrail devices. A mfd driver is used to split the GPIOs into USB gpio extcon device and a USB mux device. Driver for USB gpio extcon device is already in upstream Linux. This patch series includes a driver for GPIO USB mux.
(3) Drivers for USB port mux controlled through memory mapped registers and the logic to create the mux device. This type of dual role port mux could be found in Cherry Trail and Broxton devices.
Lu Baolu (7):
extcon: usb-gpio: add device binding for platform device
extcon: usb-gpio: add support for ACPI gpio interface
usb: misc: add common code for Intel dual role port mux
usb: misc: add driver for Intel gpio controlled port mux
usb: misc: add driver for Intel drcfg controlled port mux
usb: pci-quirks: add Intel USB drcfg mux device
mfd: intel_vuport: Add Intel virtual USB port MFD Driver
MAINTAINERS | 10 +++ drivers/extcon/extcon-usb-gpio.c | 10 ++- drivers/mfd/Kconfig | 7 ++ drivers/mfd/Makefile | 1 + drivers/mfd/intel-vuport.c | 79 +++++++++++++++++ drivers/usb/host/pci-quirks.c | 47 +++++++++- drivers/usb/host/xhci-ext-caps.h | 2 + drivers/usb/misc/Kconfig | 20 +++++ drivers/usb/misc/Makefile | 4 + drivers/usb/misc/intel-mux-drcfg.c | 174 +++++++++++++++++++++++++++++++++++++ drivers/usb/misc/intel-mux-gpio.c | 126 +++++++++++++++++++++++++++ drivers/usb/misc/mux.c | 172 ++++++++++++++++++++++++++++++++++++ include/linux/usb/mux.h | 71 +++++++++++++++ 13 files changed, 720 insertions(+), 3 deletions(-) create mode 100644 drivers/mfd/intel-vuport.c create mode 100644 drivers/usb/misc/intel-mux-drcfg.c create mode 100644 drivers/usb/misc/intel-mux-gpio.c create mode 100644 drivers/usb/misc/mux.c create mode 100644 include/linux/usb/mux.h
Signature · 1 line
2.1.4
PATCH 1/7 extcon: usb-gpio: add device binding for platform device
This is needed to handle the GPIO connected USB ID pin found on Intel Baytrail devices.
--- drivers/extcon/extcon-usb-gpio.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/extcon/extcon-usb-gpio.c +7 -0
@@ -206,6 +206,12 @@ static const struct of_device_id usb_extcon_dt_match[] = { };MODULE_DEVICE_TABLE (of, usb_extcon_dt_match); +static const struct platform_device_id usb_extcon_platform_ids[] = { + { .name ="extcon-usb-gpio" , }, + {/* sentinel */ } +}; +MODULE_DEVICE_TABLE (platform, usb_extcon_platform_ids); +static struct platform_driver usb_extcon_driver = { .probe = usb_extcon_probe, .remove = usb_extcon_remove,
@@ -214,6 +220,7 @@ static struct platform_driver usb_extcon_driver = { .pm = &usb_extcon_pm_ops, .of_match_table = usb_extcon_dt_match, }, + .id_table = usb_extcon_platform_ids, };module_platform_driver (usb_extcon_driver);
Signature · 1 line
2.1.4
Re: [PATCH 1/7] extcon: usb-gpio: add device binding for platform device
Hell Lu,
Quoted 28 lines · Lu Baolu
This is needed to handle the GPIO connected USB ID pin found on Intel Baytrail devices.
Signed-off-by Lu Baolu <[email protected]>Reviewed-by Felipe Balbi <[email protected]>--- drivers/extcon/extcon-usb-gpio.c | 7 +++++++ 1 file changed, 7 insertions(+)drivers/extcon/extcon-usb-gpio.c +6
-0@@ -206,6 +206,12 @@ static const struct of_device_id usb_extcon_dt_match[] = { };MODULE_DEVICE_TABLE (of, usb_extcon_dt_match); +static const struct platform_device_id usb_extcon_platform_ids[] = { + { .name ="extcon-usb-gpio" , }, + {/* sentinel */ } +}; +MODULE_DEVICE_TABLE (platform, usb_extcon_platform_ids); +static struct platform_driver usb_extcon_driver = { .probe = usb_extcon_probe, .remove = usb_extcon_remove,
drivers/extcon/extcon-usb-gpio.c static struct platform_driver usb_extcon_driver = { · line 226
Quoted 7 lines
drivers/extcon/extcon-usb-gpio.c +1
-0@@ -214,6 +220,7 @@ static struct platform_driver usb_extcon_driver = { .pm = &usb_extcon_pm_ops, .of_match_table = usb_extcon_dt_match, }, + .id_table = usb_extcon_platform_ids, };module_platform_driver (usb_extcon_driver);
Looks good to me.
Best Regards,
Chanwoo Choi
Re: [PATCH 1/7] extcon: usb-gpio: add device binding for platform device
Quoted 36 lines · Chanwoo Choi
Hell Lu,
Quoted 33 lines · Lu Baolu
This is needed to handle the GPIO connected USB ID pin found on Intel Baytrail devices.
Signed-off-by Lu Baolu <[email protected]>Reviewed-by Felipe Balbi <[email protected]>--- drivers/extcon/extcon-usb-gpio.c | 7 +++++++ 1 file changed, 7 insertions(+)drivers/extcon/extcon-usb-gpio.c +7
-0@@ -206,6 +206,12 @@ static const struct of_device_id usb_extcon_dt_match[] = { };MODULE_DEVICE_TABLE (of, usb_extcon_dt_match); +static const struct platform_device_id usb_extcon_platform_ids[] = { + { .name ="extcon-usb-gpio" , }, + {/* sentinel */ } +}; +MODULE_DEVICE_TABLE (platform, usb_extcon_platform_ids); +static struct platform_driver usb_extcon_driver = { .probe = usb_extcon_probe, .remove = usb_extcon_remove,@@ -214,6 +220,7 @@ static struct platform_driver usb_extcon_driver = { .pm = &usb_extcon_pm_ops, .of_match_table = usb_extcon_dt_match, }, + .id_table = usb_extcon_platform_ids, };
Quoted 5 lines
drivers/extcon/extcon-usb-gpio.c static struct platform_driver usb_extcon_driver = { · line 226
Quoted 2 lines
drivers/extcon/extcon-usb-gpio.c +0
-0module_platform_driver (usb_extcon_driver);Looks good to me.
Acked-by Chanwoo Choi <[email protected]>
Thank you!
Quoted 5 lines
Best Regards,
Chanwoo Choi
PATCH 2/7 extcon: usb-gpio: add support for ACPI gpio interface
In reply to Lu BaoluGPIO resource could be retrieved through APCI as well.
--- drivers/extcon/extcon-usb-gpio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/extcon/extcon-usb-gpio.c +2 -1
@@ -26,6 +26,7 @@#include <linux/platform_device.h> #include <linux/slab.h> #include <linux/workqueue.h> +#include <linux/acpi.h> #define USB_GPIO_DEBOUNCE_MS 20/* ms */
@@ -91,7 +92,7 @@ static int usb_extcon_probe(struct platform_device *pdev)struct usb_extcon_info *info;int ret; -if (!np) +if (!np && !ACPI_HANDLE (dev))return -EINVAL ; info =devm_kzalloc (&pdev->dev,sizeof (*info),GFP_KERNEL );
Signature · 1 line
2.1.4
Re: [PATCH 2/7] extcon: usb-gpio: add support for ACPI gpio interface
Hi Lu,
Quoted 22 lines · Lu Baolu
GPIO resource could be retrieved through APCI as well.
Signed-off-by Lu Baolu <[email protected]>Reviewed-by Felipe Balbi <[email protected]>--- drivers/extcon/extcon-usb-gpio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)drivers/extcon/extcon-usb-gpio.c +1
-0@@ -26,6 +26,7 @@#include <linux/platform_device.h> #include <linux/slab.h> #include <linux/workqueue.h> +#include <linux/acpi.h> #define USB_GPIO_DEBOUNCE_MS 20/* ms */
drivers/extcon/extcon-usb-gpio.c static int usb_extcon_probe(struct platform_device *pdev) · line 98
Quoted 8 lines
drivers/extcon/extcon-usb-gpio.c +1
-1@@ -91,7 +92,7 @@ static int usb_extcon_probe(struct platform_device *pdev)struct usb_extcon_info *info;int ret; -if (!np) +if (!np && !ACPI_HANDLE (dev))return -EINVAL ; info =devm_kzalloc (&pdev->dev,sizeof (*info),GFP_KERNEL );
Looks good to me.
Best Regards,
Chanwoo Choi
Re: [PATCH 2/7] extcon: usb-gpio: add support for ACPI gpio interface
Quoted 31 lines · Chanwoo Choi
Hi Lu,
Quoted 28 lines · Lu Baolu
GPIO resource could be retrieved through APCI as well.
Signed-off-by Lu Baolu <[email protected]>Reviewed-by Felipe Balbi <[email protected]>--- drivers/extcon/extcon-usb-gpio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)drivers/extcon/extcon-usb-gpio.c +2
-1@@ -26,6 +26,7 @@#include <linux/platform_device.h> #include <linux/slab.h> #include <linux/workqueue.h> +#include <linux/acpi.h> #define USB_GPIO_DEBOUNCE_MS 20/* ms */ @@ -91,7 +92,7 @@ static int usb_extcon_probe(struct platform_device *pdev)struct usb_extcon_info *info;int ret; -if (!np) +if (!np && !ACPI_HANDLE (dev))return -EINVAL ;
Quoted 5 lines
drivers/extcon/extcon-usb-gpio.c static int usb_extcon_probe(struct platform_device *pdev) · line 98
Quoted 2 lines
drivers/extcon/extcon-usb-gpio.c +0
-0info =devm_kzalloc (&pdev->dev,sizeof (*info),GFP_KERNEL );Looks good to me.
Acked-by Chanwoo Choi <[email protected]>
Thank you!
Quoted 4 lines
Best Regards,
Chanwoo Choi
PATCH 3/7 usb: misc: add common code for Intel dual role port mux
In reply to Lu BaoluSeveral Intel PCHs and SOCs have an internal mux that is used to share one USB port between device controller and host controller.
A usb port mux could be abstracted as the following elements:
1) mux state: HOST or PERIPHERAL;
2) an extcon cable which triggers the change of mux state between HOST and PERIPHERAL;
3) The required action to do the real port switch.
This patch adds the common code to handle usb port mux. With this common code, the individual mux driver, which always is platform dependent, could focus on the real operation of mux switch.
--- MAINTAINERS | 7 ++ drivers/usb/misc/Kconfig | 4 ++ drivers/usb/misc/Makefile | 2 + drivers/usb/misc/mux.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/usb/mux.h | 71 +++++++++++++++++++ 5 files changed, 256 insertions(+) create mode 100644 drivers/usb/misc/mux.c create mode 100644 include/linux/usb/mux.h
MAINTAINERS +7 -0
@@ -11389,6 +11389,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git S: Maintained F: drivers/usb/phy/ +USB PORT MUX DRIVER +M: Lu Baolu <[email protected]> +L: [email protected] +S: Supported +F: drivers/usb/misc/mux.c +F: include/linux/usb/mux.h + USB PRINTER DRIVER (usblp) M: Pete Zaitcev <[email protected]> L: [email protected]
drivers/usb/misc/Kconfig +4 -0
@@ -3,6 +3,10 @@ # comment "USB Miscellaneous drivers" +config USB_MUX + select EXTCON + def_bool n + config USB_EMI62 tristate "EMI 6|2m USB Audio interface support" ---help---
drivers/usb/misc/Makefile +2 -0
@@ -29,3 +29,5 @@ obj-$(CONFIG_USB_CHAOSKEY) += chaoskey.o obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ obj-$(CONFIG_USB_LINK_LAYER_TEST) += lvstest.o + +obj-$(CONFIG_USB_MUX) += mux.o
drivers/usb/misc/mux.c new file +172 -0
172 lines not on this page · raw message
include/linux/usb/mux.h new file +71 -0
71 lines not on this page · raw message
Signature · 1 line
2.1.4
Greg Kroah-Hartman
maintainerRe: [PATCH 3/7] usb: misc: add common code for Intel dual role port mux
Quoted 64 lines · Lu Baolu
Several Intel PCHs and SOCs have an internal mux that is used to share one USB port between device controller and host controller.
A usb port mux could be abstracted as the following elements:
1) mux state: HOST or PERIPHERAL;
2) an extcon cable which triggers the change of mux state between HOST and PERIPHERAL;
3) The required action to do the real port switch.This patch adds the common code to handle usb port mux. With this common code, the individual mux driver, which always is platform dependent, could focus on the real operation of mux switch.
Signed-off-by Lu Baolu <[email protected]>Reviewed-by Heikki Krogerus <[email protected]>Reviewed-by Felipe Balbi <[email protected]>--- MAINTAINERS | 7 ++ drivers/usb/misc/Kconfig | 4 ++ drivers/usb/misc/Makefile | 2 + drivers/usb/misc/mux.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/usb/mux.h | 71 +++++++++++++++++++ 5 files changed, 256 insertions(+) create mode 100644 drivers/usb/misc/mux.c create mode 100644 include/linux/usb/mux.hMAINTAINERS +7
-0@@ -11389,6 +11389,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git S: Maintained F: drivers/usb/phy/ +USB PORT MUX DRIVER +M: Lu Baolu <[email protected]> +L: [email protected] +S: Supported +F: drivers/usb/misc/mux.c +F: include/linux/usb/mux.h + USB PRINTER DRIVER (usblp) M: Pete Zaitcev <[email protected]> L: [email protected]drivers/usb/misc/Kconfig +4
-0@@ -3,6 +3,10 @@ # comment "USB Miscellaneous drivers" +config USB_MUX + select EXTCON + def_bool n + config USB_EMI62 tristate "EMI 6|2m USB Audio interface support" ---help---drivers/usb/misc/Makefile +0
-0
drivers/usb/misc/Makefile obj-$(CONFIG_USB_CHAOSKEY) += chaoskey.o · line 33
Quoted 5 lines
drivers/usb/misc/Makefile +2
-0@@ -29,3 +29,5 @@ obj-$(CONFIG_USB_CHAOSKEY) += chaoskey.o obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ obj-$(CONFIG_USB_LINK_LAYER_TEST) += lvstest.o + +obj-$(CONFIG_USB_MUX) += mux.o
"mux.ko" is a _VERY_ generic name of a kernel module. Please make this much more specific to your chip as this will not work for any other platform that has this type of functionality.
Same goes for all of your exported symbols.
Quoted 132 lines
drivers/usb/misc/mux.c new file +126
-0@@ -0,0 +1,172 @@ +/** +* mux.c - USB Port Mux support +* +* Copyright (C) 2016 Intel Corporation +* +* Author: Lu Baolu <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ +#include <linux/notifier.h> +#include <linux/usb/mux.h> +#include <linux/debugfs.h> +#include <linux/err.h> + +static int usb_mux_change_state (struct usb_mux *mux,int state) +{ +int ret; +struct usb_mux_dev *umdev = mux->umdev; + +dev_WARN_ONCE (umdev->dev, !mutex_is_locked (&mux->mux_mutex), +"mutex is unlocked\n" ); + + mux->mux_state = state; + +if (mux->mux_state) + ret = umdev->cable_set_cb (umdev); +else + ret = umdev->cable_unset_cb (umdev); + +return ret; +} + +static int usb_mux_notifier (struct notifier_block *nb, +unsigned long event,void *ptr) +{ +struct usb_mux *mux; +int state; +int ret =NOTIFY_DONE ; + + mux = container_of(nb, struct usb_mux, nb); + + state =extcon_get_cable_state (mux->obj.edev, + mux->umdev->cable_name); + +if (mux->mux_state ==-1 || mux->mux_state != state) { +mutex_lock (&mux->mux_mutex); + ret =usb_mux_change_state (mux, state); +mutex_unlock (&mux->mux_mutex); + } + +return ret; +} + +static ssize_t mux_debug_read (struct file *file,char __user *user_buf, +size_t len,loff_t *offset) +{ +struct usb_mux *mux = file->private_data; +char output_buf[16 ]; + +memset (output_buf,0 ,sizeof (output_buf)); +if (mux->mux_state) +strcpy (output_buf,"host\n" ); +else +strcpy (output_buf,"peripheral\n" ); + +return simple_read_from_buffer (user_buf, len, offset, + output_buf,strlen (output_buf)); +} + +static ssize_t mux_debug_write (struct file *file,const char __user *user_buf, +size_t count,loff_t *offset) +{ +struct usb_mux *mux = file->private_data; +char input_buf[16 ]; +int size, state; + + size =min (count,sizeof (input_buf) -1 ); +memset (input_buf,0 ,sizeof (input_buf)); +if (strncpy_from_user (input_buf, user_buf, size) <0 ) +return -EFAULT ; + +if (!strncmp (input_buf,"host" ,4 )) + state =1 ; +else if (!strncmp (input_buf,"peripheral" ,10 )) + state =0 ; +else + state =-1 ; + +if (state !=-1 ) { +mutex_lock (&mux->mux_mutex); +usb_mux_change_state (mux, state); +mutex_unlock (&mux->mux_mutex); + } + +return count; +} + +static const struct file_operations mux_debug_fops = { + .read = mux_debug_read, + .write = mux_debug_write, + .open = simple_open, + .llseek = default_llseek, +}; + +int usb_mux_register (struct usb_mux_dev *umdev) +{ +int ret; +struct device *dev = umdev->dev; +struct usb_mux *mux; + +if (!umdev->cable_name) +return -ENODEV ; + + mux =devm_kzalloc (dev,sizeof (*mux),GFP_KERNEL ); +if (!mux) +return -ENOMEM ; + + mux->umdev = umdev; + mux->nb.notifier_call = usb_mux_notifier; +mutex_init (&mux->mux_mutex); + mux->mux_state =-1 ; +dev_set_drvdata (dev, mux); + + ret = extcon_register_interest(&mux->obj, umdev->extcon_name,
drivers/usb/misc/mux.c line 136
Quoted 10 lines
drivers/usb/misc/mux.c new file +10
-0+ umdev->cable_name, &mux->nb); +if (ret) { +dev_err (dev,"failed to register extcon notifier\n" ); +return -ENODEV ; + } + +usb_mux_notifier (&mux->nb,0 ,NULL ); + + mux->debug_file =debugfs_create_file ("usb_mux" ,0600 , + usb_debug_root, mux, &mux_debug_fops);
So you control this through debugfs? That's not a good idea, what if you have multiple ones of these? What if debugfs is not enabled? Who is in charge of controlling this from userspace?
Quoted 75 lines
drivers/usb/misc/mux.c new file +36
-0+ +return 0 ; +} +EXPORT_SYMBOL_GPL (usb_mux_register); + +int usb_mux_unregister (struct device *dev) +{ +struct usb_mux *mux =dev_get_drvdata (dev); + +debugfs_remove (mux->debug_file); +extcon_unregister_interest (&mux->obj); + +return 0 ; +} +EXPORT_SYMBOL_GPL (usb_mux_unregister); + +struct usb_mux_dev *usb_mux_get_dev (struct device *dev) +{ +struct usb_mux *mux =dev_get_drvdata (dev); + +if (mux) +return mux->umdev; + +return NULL ; +} +EXPORT_SYMBOL_GPL (usb_mux_get_dev); + +#ifdef CONFIG_PM_SLEEP +void usb_mux_complete (struct device *dev) +{ +struct usb_mux *mux =dev_get_drvdata (dev); + +usb_mux_notifier (&mux->nb,0 ,NULL ); +} +EXPORT_SYMBOL_GPL (usb_mux_complete); +#endif include/linux/usb/mux.h new file +33
-0@@ -0,0 +1,71 @@ +/** +* mux.h - USB Port Mux defines +* +* Copyright (C) 2016 Intel Corporation +* +* Author: Lu Baolu <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef __LINUX_USB_MUX_H +#define __LINUX_USB_MUX_H + +#include <linux/extcon.h> +#include <linux/usb.h> + +struct usb_mux_dev { + struct device *dev; + char *extcon_name; + char *cable_name; + int (*cable_set_cb)(struct usb_mux_dev *mux); + int (*cable_unset_cb)(struct usb_mux_dev *mux); +}; + +struct usb_mux { + struct usb_mux_dev *umdev; + struct notifier_block nb; + struct extcon_specific_cable_nb obj; + + /* + * The state of the mux.
include/linux/usb/mux.h line 43
Quoted 10 lines
include/linux/usb/mux.h new file +10
-0+* 0, 1 - mux switch state +* -1 - uninitialized state +* +* mux_mutex is lock to protect mux_state +*/ +int mux_state; +struct mutex mux_mutex; + +struct dentry *debug_file; +};
Why is this a public structure?
And why isn't it properly reference counted if it is a public structure?
Quoted 18 lines
include/linux/usb/mux.h new file +18
-0+ +#if IS_ENABLED (CONFIG_USB_MUX ) +extern int usb_mux_register (struct usb_mux_dev *mux); +extern int usb_mux_unregister (struct device *dev); +extern struct usb_mux_dev *usb_mux_get_dev (struct device *dev); + +#ifdef CONFIG_PM_SLEEP +extern void usb_mux_complete (struct device *dev); +#endif + +#else /* CONFIG_USB_MUX */ +static inline int usb_mux_register (struct usb_mux_dev *mux) +{ +return -ENODEV ; +} + +static inline int usb_mux_unregister (struct device *dev) +{
include/linux/usb/mux.h line 71
Quoted 10 lines
include/linux/usb/mux.h new file +10
-0+return 0 ; +} + +static inline struct usb_mux_dev *usb_mux_get_dev (struct device *dev) +{ +return NULL ; +} +#endif /* CONFIG_USB_MUX */ + +#endif /* __LINUX_USB_MUX_H */
Why do you need this .h file at all?
thanks,
greg k-h
Re: [PATCH 3/7] usb: misc: add common code for Intel dual role port mux
Quoted 74 lines · Greg Kroah-Hartman
Quoted 64 lines · Lu Baolu
Several Intel PCHs and SOCs have an internal mux that is used to share one USB port between device controller and host controller.
A usb port mux could be abstracted as the following elements:
1) mux state: HOST or PERIPHERAL;
2) an extcon cable which triggers the change of mux state between HOST and PERIPHERAL;
3) The required action to do the real port switch.This patch adds the common code to handle usb port mux. With this common code, the individual mux driver, which always is platform dependent, could focus on the real operation of mux switch.
Signed-off-by Lu Baolu <[email protected]>Reviewed-by Heikki Krogerus <[email protected]>Reviewed-by Felipe Balbi <[email protected]>--- MAINTAINERS | 7 ++ drivers/usb/misc/Kconfig | 4 ++ drivers/usb/misc/Makefile | 2 + drivers/usb/misc/mux.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/usb/mux.h | 71 +++++++++++++++++++ 5 files changed, 256 insertions(+) create mode 100644 drivers/usb/misc/mux.c create mode 100644 include/linux/usb/mux.hMAINTAINERS +7
-0@@ -11389,6 +11389,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git S: Maintained F: drivers/usb/phy/ +USB PORT MUX DRIVER +M: Lu Baolu <[email protected]> +L: [email protected] +S: Supported +F: drivers/usb/misc/mux.c +F: include/linux/usb/mux.h + USB PRINTER DRIVER (usblp) M: Pete Zaitcev <[email protected]> L: [email protected]drivers/usb/misc/Kconfig +4
-0@@ -3,6 +3,10 @@ # comment "USB Miscellaneous drivers" +config USB_MUX + select EXTCON + def_bool n + config USB_EMI62 tristate "EMI 6|2m USB Audio interface support" ---help---drivers/usb/misc/Makefile +0
-0drivers/usb/misc/Makefile obj-$(CONFIG_USB_CHAOSKEY) += chaoskey.o · line 33
Quoted 5 lines
drivers/usb/misc/Makefile +2
-0@@ -29,3 +29,5 @@ obj-$(CONFIG_USB_CHAOSKEY) += chaoskey.o obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ obj-$(CONFIG_USB_LINK_LAYER_TEST) += lvstest.o + +obj-$(CONFIG_USB_MUX) += mux.o"mux.ko" is a _VERY_ generic name of a kernel module. Please make this much more specific to your chip as this will not work for any other platform that has this type of functionality.
Quoted 1 line
Same goes for all of your exported symbols.
Sure. I will change the module name to "intel-mux", and change the exported symbols to "intel_usb_mux_*".
Quoted 138 lines
Quoted 138 lines
drivers/usb/misc/mux.c new file +130
-0@@ -0,0 +1,172 @@ +/** +* mux.c - USB Port Mux support +* +* Copyright (C) 2016 Intel Corporation +* +* Author: Lu Baolu <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ +#include <linux/notifier.h> +#include <linux/usb/mux.h> +#include <linux/debugfs.h> +#include <linux/err.h> + +static int usb_mux_change_state (struct usb_mux *mux,int state) +{ +int ret; +struct usb_mux_dev *umdev = mux->umdev; + +dev_WARN_ONCE (umdev->dev, !mutex_is_locked (&mux->mux_mutex), +"mutex is unlocked\n" ); + + mux->mux_state = state; + +if (mux->mux_state) + ret = umdev->cable_set_cb (umdev); +else + ret = umdev->cable_unset_cb (umdev); + +return ret; +} + +static int usb_mux_notifier (struct notifier_block *nb, +unsigned long event,void *ptr) +{ +struct usb_mux *mux; +int state; +int ret =NOTIFY_DONE ; + + mux = container_of(nb, struct usb_mux, nb); + + state =extcon_get_cable_state (mux->obj.edev, + mux->umdev->cable_name); + +if (mux->mux_state ==-1 || mux->mux_state != state) { +mutex_lock (&mux->mux_mutex); + ret =usb_mux_change_state (mux, state); +mutex_unlock (&mux->mux_mutex); + } + +return ret; +} + +static ssize_t mux_debug_read (struct file *file,char __user *user_buf, +size_t len,loff_t *offset) +{ +struct usb_mux *mux = file->private_data; +char output_buf[16 ]; + +memset (output_buf,0 ,sizeof (output_buf)); +if (mux->mux_state) +strcpy (output_buf,"host\n" ); +else +strcpy (output_buf,"peripheral\n" ); + +return simple_read_from_buffer (user_buf, len, offset, + output_buf,strlen (output_buf)); +} + +static ssize_t mux_debug_write (struct file *file,const char __user *user_buf, +size_t count,loff_t *offset) +{ +struct usb_mux *mux = file->private_data; +char input_buf[16 ]; +int size, state; + + size =min (count,sizeof (input_buf) -1 ); +memset (input_buf,0 ,sizeof (input_buf)); +if (strncpy_from_user (input_buf, user_buf, size) <0 ) +return -EFAULT ; + +if (!strncmp (input_buf,"host" ,4 )) + state =1 ; +else if (!strncmp (input_buf,"peripheral" ,10 )) + state =0 ; +else + state =-1 ; + +if (state !=-1 ) { +mutex_lock (&mux->mux_mutex); +usb_mux_change_state (mux, state); +mutex_unlock (&mux->mux_mutex); + } + +return count; +} + +static const struct file_operations mux_debug_fops = { + .read = mux_debug_read, + .write = mux_debug_write, + .open = simple_open, + .llseek = default_llseek, +}; + +int usb_mux_register (struct usb_mux_dev *umdev) +{ +int ret; +struct device *dev = umdev->dev; +struct usb_mux *mux; + +if (!umdev->cable_name) +return -ENODEV ; + + mux =devm_kzalloc (dev,sizeof (*mux),GFP_KERNEL ); +if (!mux) +return -ENOMEM ; + + mux->umdev = umdev; + mux->nb.notifier_call = usb_mux_notifier; +mutex_init (&mux->mux_mutex); + mux->mux_state =-1 ; +dev_set_drvdata (dev, mux); + + ret =extcon_register_interest (&mux->obj, umdev->extcon_name, + umdev->cable_name, &mux->nb); +if (ret) { +dev_err (dev,"failed to register extcon notifier\n" ); +return -ENODEV ;
Quoted 8 lines
drivers/usb/misc/mux.c line 136
Quoted 6 lines
drivers/usb/misc/mux.c new file +6
-0+ } + +usb_mux_notifier (&mux->nb,0 ,NULL ); + + mux->debug_file =debugfs_create_file ("usb_mux" ,0600 , + usb_debug_root, mux, &mux_debug_fops);So you control this through debugfs? That's not a good idea, what if you have multiple ones of these? What if debugfs is not enabled?
Agree. It's really a problem if we have multiple ones (although currently we have only single one).
I will make it with sysfs instead.
Quoted 2 lines
Who
is in charge of controlling this from userspace?
Port mux is only handled in kernel. There is no requirement to control it from user space. This is added for debugging and information only.
Quoted 89 lines
Quoted 76 lines
drivers/usb/misc/mux.c new file +36
-0+ +return 0 ; +} +EXPORT_SYMBOL_GPL (usb_mux_register); + +int usb_mux_unregister (struct device *dev) +{ +struct usb_mux *mux =dev_get_drvdata (dev); + +debugfs_remove (mux->debug_file); +extcon_unregister_interest (&mux->obj); + +return 0 ; +} +EXPORT_SYMBOL_GPL (usb_mux_unregister); + +struct usb_mux_dev *usb_mux_get_dev (struct device *dev) +{ +struct usb_mux *mux =dev_get_drvdata (dev); + +if (mux) +return mux->umdev; + +return NULL ; +} +EXPORT_SYMBOL_GPL (usb_mux_get_dev); + +#ifdef CONFIG_PM_SLEEP +void usb_mux_complete (struct device *dev) +{ +struct usb_mux *mux =dev_get_drvdata (dev); + +usb_mux_notifier (&mux->nb,0 ,NULL ); +} +EXPORT_SYMBOL_GPL (usb_mux_complete); +#endif include/linux/usb/mux.h new file +33
-0@@ -0,0 +1,71 @@ +/** +* mux.h - USB Port Mux defines +* +* Copyright (C) 2016 Intel Corporation +* +* Author: Lu Baolu <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef __LINUX_USB_MUX_H +#define __LINUX_USB_MUX_H + +#include <linux/extcon.h> +#include <linux/usb.h> + +struct usb_mux_dev { + struct device *dev; + char *extcon_name; + char *cable_name; + int (*cable_set_cb)(struct usb_mux_dev *mux); + int (*cable_unset_cb)(struct usb_mux_dev *mux); +}; + +struct usb_mux { + struct usb_mux_dev *umdev; + struct notifier_block nb; + struct extcon_specific_cable_nb obj; + + /* + * The state of the mux.include/linux/usb/mux.h line 43
Quoted 10 lines
include/linux/usb/mux.h new file +10
-0+* 0, 1 - mux switch state +* -1 - uninitialized state +* +* mux_mutex is lock to protect mux_state +*/ +int mux_state; +struct mutex mux_mutex; + +struct dentry *debug_file; +};Why is this a public structure?
Quoted 1 line
And why isn't it properly reference counted if it is a public structure?
Agree. I will move it to .c file and make it private one.
Quoted 24 lines
Quoted 24 lines
include/linux/usb/mux.h new file +22
-0+ +#if IS_ENABLED (CONFIG_USB_MUX ) +extern int usb_mux_register (struct usb_mux_dev *mux); +extern int usb_mux_unregister (struct device *dev); +extern struct usb_mux_dev *usb_mux_get_dev (struct device *dev); + +#ifdef CONFIG_PM_SLEEP +extern void usb_mux_complete (struct device *dev); +#endif + +#else /* CONFIG_USB_MUX */ +static inline int usb_mux_register (struct usb_mux_dev *mux) +{ +return -ENODEV ; +} + +static inline int usb_mux_unregister (struct device *dev) +{ +return 0 ; +} + +static inline struct usb_mux_dev *usb_mux_get_dev (struct device *dev)
Quoted 8 lines
include/linux/usb/mux.h line 71
Quoted 6 lines
include/linux/usb/mux.h new file +6
-0+{ +return NULL ; +} +#endif /* CONFIG_USB_MUX */ + +#endif /* __LINUX_USB_MUX_H */ Why do you need this .h file at all?
File mux.c is a common file for all port mux drivers. The individual port mux driver needs this .h file for structure and function interface definition.
Quoted 5 lines
thanks,
greg k-h
Thank you for your time.
Best Regards,
-Baolu
Greg Kroah-Hartman
maintainerRe: [PATCH 3/7] usb: misc: add common code for Intel dual role port mux
In reply to Lu Baoluinclude/linux/usb/mux.h line 48
Quoted 4 lines · Lu Baolu
include/linux/usb/mux.h new file +4
-0+#if IS_ENABLED (CONFIG_USB_MUX ) +extern int usb_mux_register (struct usb_mux_dev *mux); +extern int usb_mux_unregister (struct device *dev); +extern struct usb_mux_dev *usb_mux_get_dev (struct device *dev);
This api needs a lot of work, for such a "tiny" api, it's obviously pretty incorrect. Please fix it up to be sane...
Re: [PATCH 3/7] usb: misc: add common code for Intel dual role port mux
Quoted 7 lines · Greg Kroah-Hartman
include/linux/usb/mux.h line 48
Quoted 4 lines · Lu Baolu
include/linux/usb/mux.h new file +4
-0+#if IS_ENABLED (CONFIG_USB_MUX ) +extern int usb_mux_register (struct usb_mux_dev *mux); +extern int usb_mux_unregister (struct device *dev); +extern struct usb_mux_dev *usb_mux_get_dev (struct device *dev);This api needs a lot of work, for such a "tiny" api, it's obviously pretty incorrect. Please fix it up to be sane...
Sure.
Quoted 3 lines
PATCH 4/7 usb: misc: add driver for Intel gpio controlled port mux
In reply to Lu BaoluIn some Intel platforms, a single usb port is shared between USB host and device controller. The shared port is under control of GPIO pins.
This patch adds the support for USB GPIO controlled port mux.
--- MAINTAINERS | 1 + drivers/usb/misc/Kconfig | 9 +++ drivers/usb/misc/Makefile | 1 + drivers/usb/misc/intel-mux-gpio.c | 126 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 137 insertions(+) create mode 100644 drivers/usb/misc/intel-mux-gpio.c
MAINTAINERS +1 -0
@@ -11395,6 +11395,7 @@ L: [email protected] S: Supported F: drivers/usb/misc/mux.c F: include/linux/usb/mux.h +F: drivers/usb/misc/intel-mux-gpio.c USB PRINTER DRIVER (usblp) M: Pete Zaitcev <[email protected]>
drivers/usb/misc/Kconfig +9 -0
@@ -272,3 +272,12 @@ config USB_CHAOSKEY To compile this driver as a module, choose M here: the module will be called chaoskey. + +config INTEL_MUX_GPIO + tristate "Intel dual role port mux controlled by GPIOs" + depends on GPIOLIB + depends on ACPI + select USB_MUX + help + Say Y here to enable support for Intel dual role port mux + controlled by GPIOs.
drivers/usb/misc/Makefile +1 -0
@@ -31,3 +31,4 @@ obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/ obj-$(CONFIG_USB_LINK_LAYER_TEST) += lvstest.o obj-$(CONFIG_USB_MUX) += mux.o +obj-$(CONFIG_INTEL_MUX_GPIO) += intel-mux-gpio.o
drivers/usb/misc/intel-mux-gpio.c new file +126 -0
126 lines not on this page · raw message
Signature · 1 line
2.1.4
kbuild test robot
build botRe: [PATCH 4/7] usb: misc: add driver for Intel gpio controlled port mux
coccinelle warnings: (new ones prefixed by >>)
Hi Lu,
[auto build test WARNING on usb/usb-testing]
[also build test WARNING on v4.5-rc6 next-20160303]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Lu-Baolu/usb-add-support-for-Intel-dual-role-port-mux/20160303-144241 base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
coccinelle warnings: (new ones prefixed by >>)
>> drivers/usb/misc/intel-mux-gpio.c:111:3-8: No need to set .owner here. The core will do it.
Please review and possibly fold the followup patch.
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
kbuild test robot
build bot[PATCH] usb: misc: fix platform_no_drv_owner.cocci warnings
In reply to Lu Baoludrivers/usb/misc/intel-mux-gpio.c:111:3-8: No need to set .owner here. The core will do it.
drivers/usb/misc/intel-mux-gpio.c:111:3-8: No need to set .owner here. The core will do it.
Remove .owner field if calls are used which set it automatically
Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci
---
intel-mux-gpio.c | 1 - 1 file changed, 1 deletion(-)
drivers/usb/misc/intel-mux-gpio.c +0 -1
@@ -108,7 +108,6 @@ MODULE_DEVICE_TABLE(platform, vuport_plastatic struct platform_driver vuport_driver = { .driver = { .name ="intel-mux-gpio" , - .owner =THIS_MODULE , #ifdef CONFIG_PM_SLEEP .pm = &vuport_pm_ops, #endif
PATCH 5/7 usb: misc: add driver for Intel drcfg controlled port mux
In reply to Lu BaoluSeveral Intel PCHs and SOCs have an internal mux that is used to share one USB port between device controller and host controller. The mux is handled through the Dual Role Configuration Register.
--- MAINTAINERS | 1 + drivers/usb/misc/Kconfig | 7 ++ drivers/usb/misc/Makefile | 1 + drivers/usb/misc/intel-mux-drcfg.c | 174 +++++++++++++++++++++++++++++++++++++ 4 files changed, 183 insertions(+) create mode 100644 drivers/usb/misc/intel-mux-drcfg.c
MAINTAINERS +1 -0
@@ -11396,6 +11396,7 @@ S: Supported F: drivers/usb/misc/mux.c F: include/linux/usb/mux.h F: drivers/usb/misc/intel-mux-gpio.c +F: drivers/usb/misc/intel-mux-drcfg.c USB PRINTER DRIVER (usblp) M: Pete Zaitcev <[email protected]>
drivers/usb/misc/Kconfig +7 -0
@@ -281,3 +281,10 @@ config INTEL_MUX_GPIO help Say Y here to enable support for Intel dual role port mux controlled by GPIOs. + +config INTEL_MUX_DRCFG + tristate "Intel dual role port mux controlled by register" + select USB_MUX + help + Say Y here to enable support for Intel dual role port mux + controlled by the Dual Role Configuration Registers.
drivers/usb/misc/Makefile +1 -0
@@ -32,3 +32,4 @@ obj-$(CONFIG_USB_LINK_LAYER_TEST) += lvstest.o obj-$(CONFIG_USB_MUX) += mux.o obj-$(CONFIG_INTEL_MUX_GPIO) += intel-mux-gpio.o +obj-$(CONFIG_INTEL_MUX_DRCFG) += intel-mux-drcfg.o
drivers/usb/misc/intel-mux-drcfg.c new file +174 -0
174 lines not on this page · raw message
Signature · 1 line
2.1.4
kbuild test robot
build botRe: [PATCH 5/7] usb: misc: add driver for Intel drcfg controlled port mux
reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree…
Hi Lu,
[auto build test ERROR on usb/usb-testing]
[also build test ERROR on v4.5-rc6 next-20160303]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Lu-Baolu/usb-add-support-for-Intel-dual-role-port-mux/20160303-144241 base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing config: arm64-allyesconfig (attached as .config)
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm64
All error/warnings (new ones prefixed by >>):
drivers/usb/misc/intel-mux-drcfg.c: In function 'intel_mux_drcfg_switch':
>> drivers/usb/misc/intel-mux-drcfg.c:42:2: error: implicit declaration of function 'readl' [-Werror=implicit-function-declaration]
data = readl(mux->regs + INTEL_MUX_CFG0);
^
>> drivers/usb/misc/intel-mux-drcfg.c:45:3: error: implicit declaration of function 'writel' [-Werror=implicit-function-declaration]
writel(data, mux->regs + INTEL_MUX_CFG0);
^
drivers/usb/misc/intel-mux-drcfg.c: In function 'intel_mux_drcfg_probe':
>> drivers/usb/misc/intel-mux-drcfg.c:108:2: error: implicit declaration of function 'devm_ioremap_nocache' [-Werror=implicit-function-declaration]
mux->regs = devm_ioremap_nocache(dev, start, size);
^
>> drivers/usb/misc/intel-mux-drcfg.c:108:12: warning: assignment makes pointer from integer without a cast
mux->regs = devm_ioremap_nocache(dev, start, size);
^cc1: some warnings being treated as errors
vim +/readl +42 drivers/usb/misc/intel-mux-drcfg.c
36 unsigned long timeout;
37 u32 data;
38
39 mux = container_of(umdev, struct intel_usb_mux, umdev);
40
41 /* Check and set mux to SW controlled mode */
> 42 data = readl(mux->regs + INTEL_MUX_CFG0);
43 if (!(data & CFG0_SW_IDPIN_EN)) {
44 data |= CFG0_SW_IDPIN_EN;
> 45 writel(data, mux->regs + INTEL_MUX_CFG0);
46 }
47
48 /*
49 * Configure CFG0 to switch the mux and VBUS_VALID bit is
50 * required for device mode.
51 */
52 data = readl(mux->regs + INTEL_MUX_CFG0);
53 if (host)
54 data &= ~(CFG0_SW_IDPIN | CFG0_SW_VBUS_VALID);
55 else
56 data |= (CFG0_SW_IDPIN | CFG0_SW_VBUS_VALID);
57 writel(data, mux->regs + INTEL_MUX_CFG0);
58
59 /*
60 * Polling CFG1 for safety, most case it takes about 600ms
61 * to finish mode switching, set TIMEOUT long enough.
62 */
63 timeout = jiffies + msecs_to_jiffies(CFG1_POLL_TIMEOUT);
64
65 /* Polling on CFG1 register to confirm mode switch. */
66 while (!time_after(jiffies, timeout)) {
67 data = readl(mux->regs + INTEL_MUX_CFG1);
68 if (!(host ^ (data & CFG1_SW_MODE)))
69 return 0;
70 /* interval for polling is set to about 5ms */
71 usleep_range(5000, 5100);
72 }
73
74 return -ETIMEDOUT;
75 }
76
77 static int intel_mux_drcfg_cable_set(struct usb_mux_dev *umdev)
78 {
79 dev_dbg(umdev->dev, "drcfg mux switch to HOST\n");
80
81 return intel_mux_drcfg_switch(umdev, true);
82 }
83
84 static int intel_mux_drcfg_cable_unset(struct usb_mux_dev *umdev)
85 {
86 dev_dbg(umdev->dev, "drcfg mux switch to DEVICE\n");
87
88 return intel_mux_drcfg_switch(umdev, false);
89 }
90
91 static int intel_mux_drcfg_probe(struct platform_device *pdev)
92 {
93 struct intel_usb_mux *mux;
94 struct usb_mux_dev *umdev;
95 struct device *dev = &pdev->dev;
96 u64 start, size;
97 int ret;
98
99 mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
100 if (!mux)
101 return -ENOMEM;
102
103 ret = device_property_read_u64(dev, "reg-start", &start);
104 ret |= device_property_read_u64(dev, "reg-size", &size);
105 if (ret)
106 return -ENODEV;
107
> 108 mux->regs = devm_ioremap_nocache(dev, start, size); 109 if (!mux->regs)
110 return -ENOMEM;
111
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
Greg Kroah-Hartman
maintainerRe: [PATCH 5/7] usb: misc: add driver for Intel drcfg controlled port mux
In reply to Lu BaoluQuoted 8 lines · Lu Baolu
Several Intel PCHs and SOCs have an internal mux that is used to share one USB port between device controller and host controller. The mux is handled through the Dual Role Configuration Register.
Signed-off-by Heikki Krogerus <[email protected]>Signed-off-by Lu Baolu <[email protected]>Signed-off-by Wu Hao <[email protected]>Reviewed-by Felipe Balbi <[email protected]>
Quoted 5 lines
--- MAINTAINERS | 1 + drivers/usb/misc/Kconfig | 7 ++ drivers/usb/misc/Makefile | 1 + drivers/usb/misc/intel-mux-drcfg.c | 174 +++++++++++++++++++++++++++++++++++++
If you are going to start having a bunch of these, please make a new directory, drivers/usb/mux/ ?
Re: [PATCH 5/7] usb: misc: add driver for Intel drcfg controlled port mux
Quoted 14 lines · Greg Kroah-Hartman
Quoted 8 lines · Lu Baolu
Several Intel PCHs and SOCs have an internal mux that is used to share one USB port between device controller and host controller. The mux is handled through the Dual Role Configuration Register.
Signed-off-by Heikki Krogerus <[email protected]>Signed-off-by Lu Baolu <[email protected]>Signed-off-by Wu Hao <[email protected]>Reviewed-by Felipe Balbi <[email protected]>Quoted 5 lines
--- MAINTAINERS | 1 + drivers/usb/misc/Kconfig | 7 ++ drivers/usb/misc/Makefile | 1 + drivers/usb/misc/intel-mux-drcfg.c | 174 +++++++++++++++++++++++++++++++++++++
Quoted 2 lines
If you are going to start having a bunch of these, please make a new directory,
drivers/usb/mux/?
Sure. I can put them in drivers/usb/mux.
Greg Kroah-Hartman
maintainerRe: [PATCH 5/7] usb: misc: add driver for Intel drcfg controlled port mux
In reply to Lu BaoluQuoted 154 lines · Lu Baolu
Several Intel PCHs and SOCs have an internal mux that is used to share one USB port between device controller and host controller. The mux is handled through the Dual Role Configuration Register.
Signed-off-by Heikki Krogerus <[email protected]>Signed-off-by Lu Baolu <[email protected]>Signed-off-by Wu Hao <[email protected]>Reviewed-by Felipe Balbi <[email protected]>--- MAINTAINERS | 1 + drivers/usb/misc/Kconfig | 7 ++ drivers/usb/misc/Makefile | 1 + drivers/usb/misc/intel-mux-drcfg.c | 174 +++++++++++++++++++++++++++++++++++++ 4 files changed, 183 insertions(+) create mode 100644 drivers/usb/misc/intel-mux-drcfg.cMAINTAINERS +1
-0@@ -11396,6 +11396,7 @@ S: Supported F: drivers/usb/misc/mux.c F: include/linux/usb/mux.h F: drivers/usb/misc/intel-mux-gpio.c +F: drivers/usb/misc/intel-mux-drcfg.c USB PRINTER DRIVER (usblp) M: Pete Zaitcev <[email protected]>drivers/usb/misc/Kconfig +7
-0@@ -281,3 +281,10 @@ config INTEL_MUX_GPIO help Say Y here to enable support for Intel dual role port mux controlled by GPIOs. + +config INTEL_MUX_DRCFG + tristate "Intel dual role port mux controlled by register" + select USB_MUX + help + Say Y here to enable support for Intel dual role port mux + controlled by the Dual Role Configuration Registers.drivers/usb/misc/Makefile +1
-0@@ -32,3 +32,4 @@ obj-$(CONFIG_USB_LINK_LAYER_TEST) += lvstest.o obj-$(CONFIG_USB_MUX) += mux.o obj-$(CONFIG_INTEL_MUX_GPIO) += intel-mux-gpio.o +obj-$(CONFIG_INTEL_MUX_DRCFG) += intel-mux-drcfg.odrivers/usb/misc/intel-mux-drcfg.c new file +96
-0@@ -0,0 +1,174 @@ +/** +* intel-mux-drcfg.c - Driver for Intel USB mux via register +* +* Copyright (C) 2016 Intel Corporation +* Author: Heikki Krogerus <[email protected]> +* Author: Lu Baolu <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/slab.h> +#include <linux/module.h> +#include <linux/property.h> +#include <linux/usb/mux.h> +#include <linux/platform_device.h> + +#define INTEL_MUX_CFG0 0x00 +#define INTEL_MUX_CFG1 0x04 +#define CFG0_SW_IDPIN BIT(20) +#define CFG0_SW_IDPIN_EN BIT(21) +#define CFG0_SW_VBUS_VALID BIT(24) +#define CFG1_SW_MODE BIT(29) +#define CFG1_POLL_TIMEOUT 1000 + +struct intel_usb_mux { +struct usb_mux_dev umdev; +void __iomem *regs; +u32 cfg0_ctx; +}; + +static inline int intel_mux_drcfg_switch (struct usb_mux_dev *umdev,bool host) +{ +struct intel_usb_mux *mux; +unsigned long timeout; +u32 data; + + mux = container_of(umdev, struct intel_usb_mux, umdev); + +/* Check and set mux to SW controlled mode */ + data =readl (mux->regs +INTEL_MUX_CFG0 ); +if (!(data &CFG0_SW_IDPIN_EN )) { + data |=CFG0_SW_IDPIN_EN ; +writel (data, mux->regs +INTEL_MUX_CFG0 ); + } + +/* +* Configure CFG0 to switch the mux and VBUS_VALID bit is +* required for device mode. +*/ + data =readl (mux->regs +INTEL_MUX_CFG0 ); +if (host) + data &= ~(CFG0_SW_IDPIN |CFG0_SW_VBUS_VALID ); +else + data |= (CFG0_SW_IDPIN |CFG0_SW_VBUS_VALID ); +writel (data, mux->regs +INTEL_MUX_CFG0 ); + +/* +* Polling CFG1 for safety, most case it takes about 600ms +* to finish mode switching, set TIMEOUT long enough. +*/ + timeout = jiffies +msecs_to_jiffies (CFG1_POLL_TIMEOUT ); + +/* Polling on CFG1 register to confirm mode switch. */ +while (!time_after (jiffies, timeout)) { + data =readl (mux->regs +INTEL_MUX_CFG1 ); +if (!(host ^ (data &CFG1_SW_MODE ))) +return 0 ; +/* interval for polling is set to about 5ms */ +usleep_range (5000 ,5100 ); + } + +return -ETIMEDOUT ; +} + +static int intel_mux_drcfg_cable_set (struct usb_mux_dev *umdev) +{ +dev_dbg (umdev->dev,"drcfg mux switch to HOST\n" ); + +return intel_mux_drcfg_switch (umdev, true); +} + +static int intel_mux_drcfg_cable_unset (struct usb_mux_dev *umdev) +{ +dev_dbg (umdev->dev,"drcfg mux switch to DEVICE\n" ); + +return intel_mux_drcfg_switch (umdev, false); +} + +static int intel_mux_drcfg_probe (struct platform_device *pdev) +{ +struct intel_usb_mux *mux; +struct usb_mux_dev *umdev; +struct device *dev = &pdev->dev; +u64 start, size;
drivers/usb/misc/intel-mux-drcfg.c line 106
Quoted 10 lines
drivers/usb/misc/intel-mux-drcfg.c new file +10
-0+int ret; + + mux =devm_kzalloc (dev,sizeof (*mux),GFP_KERNEL ); +if (!mux) +return -ENOMEM ; + + ret =device_property_read_u64 (dev,"reg-start" , &start); + ret |=device_property_read_u64 (dev,"reg-size" , &size); +if (ret) +return -ENODEV ;
And you leaked memory :(
drivers/usb/misc/intel-mux-drcfg.c line 110
Quoted 4 lines
drivers/usb/misc/intel-mux-drcfg.c new file +4
-0+ + mux->regs =devm_ioremap_nocache (dev, start, size); +if (!mux->regs) +return -ENOMEM ;
Memory gone :(
drivers/usb/misc/intel-mux-drcfg.c line 122
Quoted 12 lines
drivers/usb/misc/intel-mux-drcfg.c new file +12
-0+ + mux->cfg0_ctx =readl (mux->regs +INTEL_MUX_CFG0 ); + + umdev = &mux->umdev; + umdev->dev = dev; + umdev->cable_name ="USB-HOST" ; + umdev->cable_set_cb = intel_mux_drcfg_cable_set; + umdev->cable_unset_cb = intel_mux_drcfg_cable_unset; + + ret =usb_mux_register (umdev); +if (ret) +writel (mux->cfg0_ctx, mux->regs +INTEL_MUX_CFG0 );
So if an error happens you just keep going?
Re: [PATCH 5/7] usb: misc: add driver for Intel drcfg controlled port mux
Quoted 158 lines · Greg Kroah-Hartman
Quoted 157 lines · Lu Baolu
Several Intel PCHs and SOCs have an internal mux that is used to share one USB port between device controller and host controller. The mux is handled through the Dual Role Configuration Register.
Signed-off-by Heikki Krogerus <[email protected]>Signed-off-by Lu Baolu <[email protected]>Signed-off-by Wu Hao <[email protected]>Reviewed-by Felipe Balbi <[email protected]>--- MAINTAINERS | 1 + drivers/usb/misc/Kconfig | 7 ++ drivers/usb/misc/Makefile | 1 + drivers/usb/misc/intel-mux-drcfg.c | 174 +++++++++++++++++++++++++++++++++++++ 4 files changed, 183 insertions(+) create mode 100644 drivers/usb/misc/intel-mux-drcfg.cMAINTAINERS +1
-0@@ -11396,6 +11396,7 @@ S: Supported F: drivers/usb/misc/mux.c F: include/linux/usb/mux.h F: drivers/usb/misc/intel-mux-gpio.c +F: drivers/usb/misc/intel-mux-drcfg.c USB PRINTER DRIVER (usblp) M: Pete Zaitcev <[email protected]>drivers/usb/misc/Kconfig +7
-0@@ -281,3 +281,10 @@ config INTEL_MUX_GPIO help Say Y here to enable support for Intel dual role port mux controlled by GPIOs. + +config INTEL_MUX_DRCFG + tristate "Intel dual role port mux controlled by register" + select USB_MUX + help + Say Y here to enable support for Intel dual role port mux + controlled by the Dual Role Configuration Registers.drivers/usb/misc/Makefile +1
-0@@ -32,3 +32,4 @@ obj-$(CONFIG_USB_LINK_LAYER_TEST) += lvstest.o obj-$(CONFIG_USB_MUX) += mux.o obj-$(CONFIG_INTEL_MUX_GPIO) += intel-mux-gpio.o +obj-$(CONFIG_INTEL_MUX_DRCFG) += intel-mux-drcfg.odrivers/usb/misc/intel-mux-drcfg.c new file +99
-0@@ -0,0 +1,174 @@ +/** +* intel-mux-drcfg.c - Driver for Intel USB mux via register +* +* Copyright (C) 2016 Intel Corporation +* Author: Heikki Krogerus <[email protected]> +* Author: Lu Baolu <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/slab.h> +#include <linux/module.h> +#include <linux/property.h> +#include <linux/usb/mux.h> +#include <linux/platform_device.h> + +#define INTEL_MUX_CFG0 0x00 +#define INTEL_MUX_CFG1 0x04 +#define CFG0_SW_IDPIN BIT(20) +#define CFG0_SW_IDPIN_EN BIT(21) +#define CFG0_SW_VBUS_VALID BIT(24) +#define CFG1_SW_MODE BIT(29) +#define CFG1_POLL_TIMEOUT 1000 + +struct intel_usb_mux { +struct usb_mux_dev umdev; +void __iomem *regs; +u32 cfg0_ctx; +}; + +static inline int intel_mux_drcfg_switch (struct usb_mux_dev *umdev,bool host) +{ +struct intel_usb_mux *mux; +unsigned long timeout; +u32 data; + + mux = container_of(umdev, struct intel_usb_mux, umdev); + +/* Check and set mux to SW controlled mode */ + data =readl (mux->regs +INTEL_MUX_CFG0 ); +if (!(data &CFG0_SW_IDPIN_EN )) { + data |=CFG0_SW_IDPIN_EN ; +writel (data, mux->regs +INTEL_MUX_CFG0 ); + } + +/* +* Configure CFG0 to switch the mux and VBUS_VALID bit is +* required for device mode. +*/ + data =readl (mux->regs +INTEL_MUX_CFG0 ); +if (host) + data &= ~(CFG0_SW_IDPIN |CFG0_SW_VBUS_VALID ); +else + data |= (CFG0_SW_IDPIN |CFG0_SW_VBUS_VALID ); +writel (data, mux->regs +INTEL_MUX_CFG0 ); + +/* +* Polling CFG1 for safety, most case it takes about 600ms +* to finish mode switching, set TIMEOUT long enough. +*/ + timeout = jiffies +msecs_to_jiffies (CFG1_POLL_TIMEOUT ); + +/* Polling on CFG1 register to confirm mode switch. */ +while (!time_after (jiffies, timeout)) { + data =readl (mux->regs +INTEL_MUX_CFG1 ); +if (!(host ^ (data &CFG1_SW_MODE ))) +return 0 ; +/* interval for polling is set to about 5ms */ +usleep_range (5000 ,5100 ); + } + +return -ETIMEDOUT ; +} + +static int intel_mux_drcfg_cable_set (struct usb_mux_dev *umdev) +{ +dev_dbg (umdev->dev,"drcfg mux switch to HOST\n" ); + +return intel_mux_drcfg_switch (umdev, true); +} + +static int intel_mux_drcfg_cable_unset (struct usb_mux_dev *umdev) +{ +dev_dbg (umdev->dev,"drcfg mux switch to DEVICE\n" ); + +return intel_mux_drcfg_switch (umdev, false); +} + +static int intel_mux_drcfg_probe (struct platform_device *pdev) +{ +struct intel_usb_mux *mux; +struct usb_mux_dev *umdev; +struct device *dev = &pdev->dev; +u64 start, size; +int ret; + + mux =devm_kzalloc (dev,sizeof (*mux),GFP_KERNEL );
Quoted 8 lines
drivers/usb/misc/intel-mux-drcfg.c line 106
Quoted 7 lines
drivers/usb/misc/intel-mux-drcfg.c new file +7
-0+if (!mux) +return -ENOMEM ; + + ret =device_property_read_u64 (dev,"reg-start" , &start); + ret |=device_property_read_u64 (dev,"reg-size" , &size); +if (ret) +return -ENODEV ;And you leaked memory :(
Did you mean device_property_read_*() allocated memory and I need to release it before return error?
Quoted 6 lines
drivers/usb/misc/intel-mux-drcfg.c line 110
Quoted 5 lines
drivers/usb/misc/intel-mux-drcfg.c new file +4
-0+ + mux->regs =devm_ioremap_nocache (dev, start, size); +if (!mux->regs) +return -ENOMEM ;Memory gone :(
devm interface will manage the resources by itself, or not?
Quoted 14 lines
drivers/usb/misc/intel-mux-drcfg.c line 122
Quoted 13 lines
drivers/usb/misc/intel-mux-drcfg.c new file +12
-0+ + mux->cfg0_ctx =readl (mux->regs +INTEL_MUX_CFG0 ); + + umdev = &mux->umdev; + umdev->dev = dev; + umdev->cable_name ="USB-HOST" ; + umdev->cable_set_cb = intel_mux_drcfg_cable_set; + umdev->cable_unset_cb = intel_mux_drcfg_cable_unset; + + ret =usb_mux_register (umdev); +if (ret) +writel (mux->cfg0_ctx, mux->regs +INTEL_MUX_CFG0 );So if an error happens you just keep going?
No. If error happens, I will restore the register and return error.
Thanks,
-Baolu
Greg Kroah-Hartman
maintainerRe: [PATCH 5/7] usb: misc: add driver for Intel drcfg controlled port mux
Quoted 174 lines · Lu Baolu
Quoted 158 lines · Greg Kroah-Hartman
Quoted 157 lines · Lu Baolu
Several Intel PCHs and SOCs have an internal mux that is used to share one USB port between device controller and host controller. The mux is handled through the Dual Role Configuration Register.
Signed-off-by Heikki Krogerus <[email protected]>Signed-off-by Lu Baolu <[email protected]>Signed-off-by Wu Hao <[email protected]>Reviewed-by Felipe Balbi <[email protected]>--- MAINTAINERS | 1 + drivers/usb/misc/Kconfig | 7 ++ drivers/usb/misc/Makefile | 1 + drivers/usb/misc/intel-mux-drcfg.c | 174 +++++++++++++++++++++++++++++++++++++ 4 files changed, 183 insertions(+) create mode 100644 drivers/usb/misc/intel-mux-drcfg.cMAINTAINERS +1
-0@@ -11396,6 +11396,7 @@ S: Supported F: drivers/usb/misc/mux.c F: include/linux/usb/mux.h F: drivers/usb/misc/intel-mux-gpio.c +F: drivers/usb/misc/intel-mux-drcfg.c USB PRINTER DRIVER (usblp) M: Pete Zaitcev <[email protected]>drivers/usb/misc/Kconfig +7
-0@@ -281,3 +281,10 @@ config INTEL_MUX_GPIO help Say Y here to enable support for Intel dual role port mux controlled by GPIOs. + +config INTEL_MUX_DRCFG + tristate "Intel dual role port mux controlled by register" + select USB_MUX + help + Say Y here to enable support for Intel dual role port mux + controlled by the Dual Role Configuration Registers.drivers/usb/misc/Makefile +1
-0@@ -32,3 +32,4 @@ obj-$(CONFIG_USB_LINK_LAYER_TEST) += lvstest.o obj-$(CONFIG_USB_MUX) += mux.o obj-$(CONFIG_INTEL_MUX_GPIO) += intel-mux-gpio.o +obj-$(CONFIG_INTEL_MUX_DRCFG) += intel-mux-drcfg.odrivers/usb/misc/intel-mux-drcfg.c new file +99
-0@@ -0,0 +1,174 @@ +/** +* intel-mux-drcfg.c - Driver for Intel USB mux via register +* +* Copyright (C) 2016 Intel Corporation +* Author: Heikki Krogerus <[email protected]> +* Author: Lu Baolu <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/slab.h> +#include <linux/module.h> +#include <linux/property.h> +#include <linux/usb/mux.h> +#include <linux/platform_device.h> + +#define INTEL_MUX_CFG0 0x00 +#define INTEL_MUX_CFG1 0x04 +#define CFG0_SW_IDPIN BIT(20) +#define CFG0_SW_IDPIN_EN BIT(21) +#define CFG0_SW_VBUS_VALID BIT(24) +#define CFG1_SW_MODE BIT(29) +#define CFG1_POLL_TIMEOUT 1000 + +struct intel_usb_mux { +struct usb_mux_dev umdev; +void __iomem *regs; +u32 cfg0_ctx; +}; + +static inline int intel_mux_drcfg_switch (struct usb_mux_dev *umdev,bool host) +{ +struct intel_usb_mux *mux; +unsigned long timeout; +u32 data; + + mux = container_of(umdev, struct intel_usb_mux, umdev); + +/* Check and set mux to SW controlled mode */ + data =readl (mux->regs +INTEL_MUX_CFG0 ); +if (!(data &CFG0_SW_IDPIN_EN )) { + data |=CFG0_SW_IDPIN_EN ; +writel (data, mux->regs +INTEL_MUX_CFG0 ); + } + +/* +* Configure CFG0 to switch the mux and VBUS_VALID bit is +* required for device mode. +*/ + data =readl (mux->regs +INTEL_MUX_CFG0 ); +if (host) + data &= ~(CFG0_SW_IDPIN |CFG0_SW_VBUS_VALID ); +else + data |= (CFG0_SW_IDPIN |CFG0_SW_VBUS_VALID ); +writel (data, mux->regs +INTEL_MUX_CFG0 ); + +/* +* Polling CFG1 for safety, most case it takes about 600ms +* to finish mode switching, set TIMEOUT long enough. +*/ + timeout = jiffies +msecs_to_jiffies (CFG1_POLL_TIMEOUT ); + +/* Polling on CFG1 register to confirm mode switch. */ +while (!time_after (jiffies, timeout)) { + data =readl (mux->regs +INTEL_MUX_CFG1 ); +if (!(host ^ (data &CFG1_SW_MODE ))) +return 0 ; +/* interval for polling is set to about 5ms */ +usleep_range (5000 ,5100 ); + } + +return -ETIMEDOUT ; +} + +static int intel_mux_drcfg_cable_set (struct usb_mux_dev *umdev) +{ +dev_dbg (umdev->dev,"drcfg mux switch to HOST\n" ); + +return intel_mux_drcfg_switch (umdev, true); +} + +static int intel_mux_drcfg_cable_unset (struct usb_mux_dev *umdev) +{ +dev_dbg (umdev->dev,"drcfg mux switch to DEVICE\n" ); + +return intel_mux_drcfg_switch (umdev, false); +} + +static int intel_mux_drcfg_probe (struct platform_device *pdev) +{ +struct intel_usb_mux *mux; +struct usb_mux_dev *umdev; +struct device *dev = &pdev->dev; +u64 start, size; +int ret; + + mux =devm_kzalloc (dev,sizeof (*mux),GFP_KERNEL );Quoted 8 lines
drivers/usb/misc/intel-mux-drcfg.c line 106
Quoted 7 lines
drivers/usb/misc/intel-mux-drcfg.c new file +7
-0+if (!mux) +return -ENOMEM ; + + ret =device_property_read_u64 (dev,"reg-start" , &start); + ret |=device_property_read_u64 (dev,"reg-size" , &size); +if (ret) +return -ENODEV ;And you leaked memory :(
Did you mean device_property_read_*() allocated memory and I need to release it before return error?
Quoted 1 line
Quoted 7 lines
Quoted 5 lines
drivers/usb/misc/intel-mux-drcfg.c line 110
Quoted 4 lines
drivers/usb/misc/intel-mux-drcfg.c new file +4
-0+ + mux->regs =devm_ioremap_nocache (dev, start, size); +if (!mux->regs) +return -ENOMEM ;Memory gone :(
devm interface will manage the resources by itself, or not?
Ugh, you are right, nevermind, these both are fine, sorry for the noise.
Quoted 13 lines
Quoted 4 lines
Quoted 4 lines
drivers/usb/misc/intel-mux-drcfg.c new file +4
-0+ mux->cfg0_ctx =readl (mux->regs +INTEL_MUX_CFG0 ); + + umdev = &mux->umdev; + umdev->dev = dev;Quoted 8 lines
drivers/usb/misc/intel-mux-drcfg.c line 122
Quoted 7 lines
drivers/usb/misc/intel-mux-drcfg.c new file +7
-0+ umdev->cable_name ="USB-HOST" ; + umdev->cable_set_cb = intel_mux_drcfg_cable_set; + umdev->cable_unset_cb = intel_mux_drcfg_cable_unset; + + ret =usb_mux_register (umdev); +if (ret) +writel (mux->cfg0_ctx, mux->regs +INTEL_MUX_CFG0 );So if an error happens you just keep going?
Quoted 1 line
No. If error happens, I will restore the register and return error.
That seems a bit "odd", and will change when you fix up the api...
thanks,
greg k-h
Re: [PATCH 5/7] usb: misc: add driver for Intel drcfg controlled port mux
Quoted 192 lines · Greg Kroah-Hartman
Quoted 171 lines · Lu Baolu
Quoted 158 lines · Greg Kroah-Hartman
Quoted 157 lines · Lu Baolu
Several Intel PCHs and SOCs have an internal mux that is used to share one USB port between device controller and host controller. The mux is handled through the Dual Role Configuration Register.
Signed-off-by Heikki Krogerus <[email protected]>Signed-off-by Lu Baolu <[email protected]>Signed-off-by Wu Hao <[email protected]>Reviewed-by Felipe Balbi <[email protected]>--- MAINTAINERS | 1 + drivers/usb/misc/Kconfig | 7 ++ drivers/usb/misc/Makefile | 1 + drivers/usb/misc/intel-mux-drcfg.c | 174 +++++++++++++++++++++++++++++++++++++ 4 files changed, 183 insertions(+) create mode 100644 drivers/usb/misc/intel-mux-drcfg.cMAINTAINERS +1
-0@@ -11396,6 +11396,7 @@ S: Supported F: drivers/usb/misc/mux.c F: include/linux/usb/mux.h F: drivers/usb/misc/intel-mux-gpio.c +F: drivers/usb/misc/intel-mux-drcfg.c USB PRINTER DRIVER (usblp) M: Pete Zaitcev <[email protected]>drivers/usb/misc/Kconfig +7
-0@@ -281,3 +281,10 @@ config INTEL_MUX_GPIO help Say Y here to enable support for Intel dual role port mux controlled by GPIOs. + +config INTEL_MUX_DRCFG + tristate "Intel dual role port mux controlled by register" + select USB_MUX + help + Say Y here to enable support for Intel dual role port mux + controlled by the Dual Role Configuration Registers.drivers/usb/misc/Makefile +1
-0@@ -32,3 +32,4 @@ obj-$(CONFIG_USB_LINK_LAYER_TEST) += lvstest.o obj-$(CONFIG_USB_MUX) += mux.o obj-$(CONFIG_INTEL_MUX_GPIO) += intel-mux-gpio.o +obj-$(CONFIG_INTEL_MUX_DRCFG) += intel-mux-drcfg.odrivers/usb/misc/intel-mux-drcfg.c new file +99
-0@@ -0,0 +1,174 @@ +/** +* intel-mux-drcfg.c - Driver for Intel USB mux via register +* +* Copyright (C) 2016 Intel Corporation +* Author: Heikki Krogerus <[email protected]> +* Author: Lu Baolu <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/slab.h> +#include <linux/module.h> +#include <linux/property.h> +#include <linux/usb/mux.h> +#include <linux/platform_device.h> + +#define INTEL_MUX_CFG0 0x00 +#define INTEL_MUX_CFG1 0x04 +#define CFG0_SW_IDPIN BIT(20) +#define CFG0_SW_IDPIN_EN BIT(21) +#define CFG0_SW_VBUS_VALID BIT(24) +#define CFG1_SW_MODE BIT(29) +#define CFG1_POLL_TIMEOUT 1000 + +struct intel_usb_mux { +struct usb_mux_dev umdev; +void __iomem *regs; +u32 cfg0_ctx; +}; + +static inline int intel_mux_drcfg_switch (struct usb_mux_dev *umdev,bool host) +{ +struct intel_usb_mux *mux; +unsigned long timeout; +u32 data; + + mux = container_of(umdev, struct intel_usb_mux, umdev); + +/* Check and set mux to SW controlled mode */ + data =readl (mux->regs +INTEL_MUX_CFG0 ); +if (!(data &CFG0_SW_IDPIN_EN )) { + data |=CFG0_SW_IDPIN_EN ; +writel (data, mux->regs +INTEL_MUX_CFG0 ); + } + +/* +* Configure CFG0 to switch the mux and VBUS_VALID bit is +* required for device mode. +*/ + data =readl (mux->regs +INTEL_MUX_CFG0 ); +if (host) + data &= ~(CFG0_SW_IDPIN |CFG0_SW_VBUS_VALID ); +else + data |= (CFG0_SW_IDPIN |CFG0_SW_VBUS_VALID ); +writel (data, mux->regs +INTEL_MUX_CFG0 ); + +/* +* Polling CFG1 for safety, most case it takes about 600ms +* to finish mode switching, set TIMEOUT long enough. +*/ + timeout = jiffies +msecs_to_jiffies (CFG1_POLL_TIMEOUT ); + +/* Polling on CFG1 register to confirm mode switch. */ +while (!time_after (jiffies, timeout)) { + data =readl (mux->regs +INTEL_MUX_CFG1 ); +if (!(host ^ (data &CFG1_SW_MODE ))) +return 0 ; +/* interval for polling is set to about 5ms */ +usleep_range (5000 ,5100 ); + } + +return -ETIMEDOUT ; +} + +static int intel_mux_drcfg_cable_set (struct usb_mux_dev *umdev) +{ +dev_dbg (umdev->dev,"drcfg mux switch to HOST\n" ); + +return intel_mux_drcfg_switch (umdev, true); +} + +static int intel_mux_drcfg_cable_unset (struct usb_mux_dev *umdev) +{ +dev_dbg (umdev->dev,"drcfg mux switch to DEVICE\n" ); + +return intel_mux_drcfg_switch (umdev, false); +} + +static int intel_mux_drcfg_probe (struct platform_device *pdev) +{ +struct intel_usb_mux *mux; +struct usb_mux_dev *umdev; +struct device *dev = &pdev->dev; +u64 start, size; +int ret; + + mux =devm_kzalloc (dev,sizeof (*mux),GFP_KERNEL );Quoted 8 lines
drivers/usb/misc/intel-mux-drcfg.c line 106
Quoted 7 lines
drivers/usb/misc/intel-mux-drcfg.c new file +7
-0+if (!mux) +return -ENOMEM ; + + ret =device_property_read_u64 (dev,"reg-start" , &start); + ret |=device_property_read_u64 (dev,"reg-size" , &size); +if (ret) +return -ENODEV ;And you leaked memory :(
Did you mean device_property_read_*() allocated memory and I need to release it before return error?
Quoted 6 lines
Quoted 5 lines
drivers/usb/misc/intel-mux-drcfg.c line 110
Quoted 4 lines
drivers/usb/misc/intel-mux-drcfg.c new file +4
-0+ + mux->regs =devm_ioremap_nocache (dev, start, size); +if (!mux->regs) +return -ENOMEM ;Memory gone :(
devm interface will manage the resources by itself, or not?
Ugh, you are right, nevermind, these both are fine, sorry for the noise.
Quoted 12 lines
Quoted 12 lines
drivers/usb/misc/intel-mux-drcfg.c line 122
Quoted 11 lines
drivers/usb/misc/intel-mux-drcfg.c new file +11
-0+ mux->cfg0_ctx =readl (mux->regs +INTEL_MUX_CFG0 ); + + umdev = &mux->umdev; + umdev->dev = dev; + umdev->cable_name ="USB-HOST" ; + umdev->cable_set_cb = intel_mux_drcfg_cable_set; + umdev->cable_unset_cb = intel_mux_drcfg_cable_unset; + + ret =usb_mux_register (umdev); +if (ret) +writel (mux->cfg0_ctx, mux->regs +INTEL_MUX_CFG0 );So if an error happens you just keep going?
Quoted 2 lines
Quoted 1 line
No. If error happens, I will restore the register and return error.
That seems a bit "odd", and will change when you fix up the api...
Sure.
Quoted 5 lines
thanks,
greg k-h
Thank you for your time.
Best Regards,
baolu
PATCH 6/7 usb: pci-quirks: add Intel USB drcfg mux device
In reply to Lu BaoluIn some Intel platforms, a single usb port is shared between USB host and device controllers. The shared port is under control of a switch which is defined in the Intel vendor defined extended capability for xHCI.
This patch adds the support to detect and create the platform device for the port mux switch.
--- drivers/usb/host/pci-quirks.c | 47 ++++++++++++++++++++++++++++++++++++++-- drivers/usb/host/xhci-ext-caps.h | 2 ++ 2 files changed, 47 insertions(+), 2 deletions(-)
drivers/usb/host/pci-quirks.c +45 -2
@@ -16,10 +16,11 @@#include <linux/export.h> #include <linux/acpi.h> #include <linux/dmi.h> +#include <linux/platform_device.h> +#include "pci-quirks.h" #include "xhci-ext-caps.h" -#define UHCI_USBLEGSUP 0xc0/* legacy support */ #define UHCI_USBCMD 0/* command register */ #define UHCI_USBINTR 4/* interrupt register */
@@ -78,6 +79,9 @@#define USB_INTEL_USB3_PSSEN 0xD8#define USB_INTEL_USB3PRM 0xDC +#define DEVICE_ID_INTEL_CHERRYVIEW_XHCI 0x22b5 +#define DEVICE_ID_INTEL_BROXTON_M_XHCI 0x0aa8 +/* * amd_chipset_gen values represent AMD different chipset generations */
@@ -956,6 +960,41 @@ void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) }EXPORT_SYMBOL_GPL (usb_disable_xhci_ports); +static void create_intel_usb_mux_device (struct pci_dev *xhci_pdev, +void __iomem *base) +{ +struct platform_device *plat_dev; +struct property_set pset; +int ret; + +struct property_entry pentry[] = { +PROPERTY_ENTRY_U64 ("reg-start" , +pci_resource_start (xhci_pdev,0 ) +0x80d8 ), +PROPERTY_ENTRY_U64 ("reg-size" ,8 ), + { }, + }; + +if (!xhci_find_next_ext_cap (base,0 ,XHCI_EXT_CAPS_INTEL_USB_MUX )) +return ; + + plat_dev =platform_device_alloc ("intel-mux-drcfg" , +PLATFORM_DEVID_AUTO ); +if (!plat_dev) +return ; + + plat_dev->dev.parent = &xhci_pdev->dev; + pset.properties = pentry; +platform_device_add_properties (plat_dev, &pset); + + ret =platform_device_add (plat_dev); +if (ret) { +dev_warn (&xhci_pdev->dev, +"failed to create mux device with error %d" , + ret); +platform_device_put (plat_dev); + } +} +/** * PCI Quirks for xHCI. *
@@ -1022,8 +1061,12 @@ static void quirk_usb_handoff_xhci(struct pci_dev *pdev)writel (val, base + ext_cap_offset +XHCI_LEGACY_CONTROL_OFFSET ); hc_init: -if (pdev->vendor ==PCI_VENDOR_ID_INTEL ) +if (pdev->vendor ==PCI_VENDOR_ID_INTEL ) {usb_enable_intel_xhci_ports (pdev); +if (pdev->device ==DEVICE_ID_INTEL_CHERRYVIEW_XHCI || + pdev->device ==DEVICE_ID_INTEL_BROXTON_M_XHCI ) +create_intel_usb_mux_device (pdev, base); + } op_reg_base = base +XHCI_HC_LENGTH (readl (base));
drivers/usb/host/xhci-ext-caps.h +2 -0
@@ -51,6 +51,8 @@#define XHCI_EXT_CAPS_ROUTE 5/* IDs 6-9 reserved */ #define XHCI_EXT_CAPS_DEBUG 10 +/* Vendor defined 192-255 */ +#define XHCI_EXT_CAPS_INTEL_USB_MUX 192/* USB Legacy Support Capability - section 7.1.1 */ #define XHCI_HC_BIOS_OWNED (1 << 16)#define XHCI_HC_OS_OWNED (1 << 24)
Signature · 1 line
2.1.4
PATCH 7/7 mfd: intel_vuport: Add Intel virtual USB port MFD Driver
In reply to Lu BaoluSome Intel platforms have an USB port mux controlled by GPIOs. There's a single ACPI platform device that provides both USB ID extcon device and a USB port mux device. This MFD driver will split the 2 devices for their respective drivers.
--- MAINTAINERS | 1 + drivers/mfd/Kconfig | 7 ++++ drivers/mfd/Makefile | 1 + drivers/mfd/intel-vuport.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+) create mode 100644 drivers/mfd/intel-vuport.c
MAINTAINERS +1 -0
@@ -11397,6 +11397,7 @@ F: drivers/usb/misc/mux.c F: include/linux/usb/mux.h F: drivers/usb/misc/intel-mux-gpio.c F: drivers/usb/misc/intel-mux-drcfg.c +F: drivers/mfd/intel-vuport.c USB PRINTER DRIVER (usblp) M: Pete Zaitcev <[email protected]>
drivers/mfd/Kconfig +7 -0
@@ -1534,5 +1534,12 @@ config MFD_VEXPRESS_SYSREG System Registers are the platform configuration block on the ARM Ltd. Versatile Express board. +config MFD_INTEL_VUPORT + tristate "Intel virtual USB port controller" + select MFD_CORE + help + Say Y here to enable support for Intel dual role port mux + controlled by 3 GPIOs. + endmenu endif
drivers/mfd/Makefile +1 -0
@@ -198,3 +198,4 @@ intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o intel-soc-pmic-$(CONFIG_INTEL_PMC_IPC) += intel_soc_pmic_bxtwc.o obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o obj-$(CONFIG_MFD_MT6397) += mt6397-core.o +obj-$(CONFIG_MFD_INTEL_VUPORT) += intel-vuport.o
drivers/mfd/intel-vuport.c new file +79 -0
79 lines not on this page · raw message
Signature · 1 line
2.1.4
kbuild test robot
build botRe: [PATCH 7/7] mfd: intel_vuport: Add Intel virtual USB port MFD Driver
coccinelle warnings: (new ones prefixed by >>)
Hi Lu,
[auto build test WARNING on usb/usb-testing]
[also build test WARNING on v4.5-rc6 next-20160303]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Lu-Baolu/usb-add-support-for-Intel-dual-role-port-mux/20160303-144241 base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing
coccinelle warnings: (new ones prefixed by >>)
>> drivers/mfd/intel-vuport.c:68:3-8: No need to set .owner here. The core will do it.
Please review and possibly fold the followup patch.
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
kbuild test robot
build bot[PATCH] mfd: intel_vuport: fix platform_no_drv_owner.cocci warnings
In reply to Lu Baoludrivers/mfd/intel-vuport.c:68:3-8: No need to set .owner here. The core will do it.
drivers/mfd/intel-vuport.c:68:3-8: No need to set .owner here. The core will do it.
Remove .owner field if calls are used which set it automatically
Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci
---
intel-vuport.c | 1 - 1 file changed, 1 deletion(-)
drivers/mfd/intel-vuport.c +0 -1
@@ -65,7 +65,6 @@ MODULE_DEVICE_TABLE(acpi, vuport_acpi_mastatic struct platform_driver vuport_driver = { .driver = { .name ="intel-vuport" , - .owner =THIS_MODULE , .acpi_match_table =ACPI_PTR (vuport_acpi_match), }, .probe = vuport_probe,
kbuild test robot
build botRe: [PATCH 7/7] mfd: intel_vuport: Add Intel virtual USB port MFD Driver
In reply to Lu Baolureproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree…
Hi Lu,
[auto build test WARNING on usb/usb-testing]
[also build test WARNING on v4.5-rc6 next-20160303]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Lu-Baolu/usb-add-support-for-Intel-dual-role-port-mux/20160303-144241 base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing config: openrisc-allyesconfig (attached as .config)
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=openrisc
All warnings (new ones prefixed by >>):
drivers/mfd/intel-vuport.c: In function 'vuport_probe':
>> drivers/mfd/intel-vuport.c:39:17: warning: unused variable 'dev'
drivers/mfd/intel-vuport.c: At top level:
drivers/mfd/intel-vuport.c:59:30: warning: 'vuport_acpi_match' defined but not used
vim +/dev +39 drivers/mfd/intel-vuport.c
23 { "vbus_en-gpios", &vbus_gpio, 1 },
24 { "usb_mux-gpios", &mux_gpio, 1 },
25 { },
26 };
27
28 static const struct mfd_cell intel_vuport_mfd_cells[] = {
29 {
30 .name = "extcon-usb-gpio",
31 },
32 {
33 .name = "intel-mux-gpio",
34 },
35 };
36
37 static int vuport_probe(struct platform_device *pdev)
38 {
> 39 struct device *dev = &pdev->dev;
40 int ret;
41
42 ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), acpi_usb_gpios);
43 if (ret)
44 return ret;
45
46 return mfd_add_devices(&pdev->dev, 0, intel_vuport_mfd_cells,
47 ARRAY_SIZE(intel_vuport_mfd_cells), NULL, 0,---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
kbuild test robot
build botRe: [PATCH 7/7] mfd: intel_vuport: Add Intel virtual USB port MFD Driver
In reply to Lu Baolureproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree…
Hi Lu,
[auto build test WARNING on usb/usb-testing]
[also build test WARNING on v4.5-rc6 next-20160303]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Lu-Baolu/usb-add-support-for-Intel-dual-role-port-mux/20160303-144241 base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing config: parisc-allyesconfig (attached as .config)
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=parisc
All warnings (new ones prefixed by >>):
drivers/mfd/intel-vuport.c: In function 'vuport_probe':
drivers/mfd/intel-vuport.c:39:17: warning: unused variable 'dev' [-Wunused-variable]
struct device *dev = &pdev->dev;
^
drivers/mfd/intel-vuport.c: At top level:
drivers/mfd/intel-vuport.c:63:1: warning: data definition has no type or storage class
MODULE_DEVICE_TABLE(acpi, vuport_acpi_match);
^
drivers/mfd/intel-vuport.c:63:1: error: type defaults to 'int' in declaration of 'MODULE_DEVICE_TABLE' [-Werror=implicit-int]
drivers/mfd/intel-vuport.c:63:1: warning: parameter names (without types) in function declaration
In file included from include/linux/acpi.h:27:0,
from drivers/mfd/intel-vuport.c:12:
include/linux/device.h:1337:1: warning: data definition has no type or storage class
module_init(__driver##_init); \
^
include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
module_driver(__platform_driver, platform_driver_register, \
^
>> drivers/mfd/intel-vuport.c:75:1: note: in expansion of macro 'module_platform_driver'
module_platform_driver(vuport_driver);
^
include/linux/device.h:1337:1: error: type defaults to 'int' in declaration of 'module_init' [-Werror=implicit-int]
module_init(__driver##_init); \
^
include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
module_driver(__platform_driver, platform_driver_register, \
^
>> drivers/mfd/intel-vuport.c:75:1: note: in expansion of macro 'module_platform_driver'
module_platform_driver(vuport_driver);
^
In file included from include/linux/linkage.h:6:0,
from include/linux/kernel.h:6,
from include/linux/list.h:8,
from include/linux/resource_ext.h:17,
from include/linux/acpi.h:26,
from drivers/mfd/intel-vuport.c:12:
include/linux/export.h:36:30: warning: parameter names (without types) in function declaration
#define THIS_MODULE ((struct module *)0)
^
include/linux/platform_device.h:198:34: note: in expansion of macro 'THIS_MODULE'
__platform_driver_register(drv, THIS_MODULE)
^
include/linux/device.h:1335:9: note: in expansion of macro 'platform_driver_register'
return __register(&(__driver) , ##__VA_ARGS__); \
^
include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
module_driver(__platform_driver, platform_driver_register, \
^
>> drivers/mfd/intel-vuport.c:75:1: note: in expansion of macro 'module_platform_driver'
module_platform_driver(vuport_driver);
^
In file included from include/linux/acpi.h:27:0,
from drivers/mfd/intel-vuport.c:12:
include/linux/device.h:1342:1: warning: data definition has no type or storage class
module_exit(__driver##_exit);
^
include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
module_driver(__platform_driver, platform_driver_register, \
^
>> drivers/mfd/intel-vuport.c:75:1: note: in expansion of macro 'module_platform_driver'
module_platform_driver(vuport_driver);
^
include/linux/device.h:1342:1: error: type defaults to 'int' in declaration of 'module_exit' [-Werror=implicit-int]
module_exit(__driver##_exit);
^
include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
module_driver(__platform_driver, platform_driver_register, \
^
>> drivers/mfd/intel-vuport.c:75:1: note: in expansion of macro 'module_platform_driver'
module_platform_driver(vuport_driver);
^
In file included from include/linux/linkage.h:6:0,
from include/linux/kernel.h:6,
from include/linux/list.h:8,
from include/linux/resource_ext.h:17,
from include/linux/acpi.h:26,
from drivers/mfd/intel-vuport.c:12:
include/linux/export.h:36:30: warning: parameter names (without types) in function declaration
#define THIS_MODULE ((struct module *)0)
^
include/linux/platform_device.h:198:34: note: in expansion of macro 'THIS_MODULE'
__platform_driver_register(drv, THIS_MODULE)
^
include/linux/device.h:1335:9: note: in expansion of macro 'platform_driver_register'
return __register(&(__driver) , ##__VA_ARGS__); \
^
include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
module_driver(__platform_driver, platform_driver_register, \
^
>> drivers/mfd/intel-vuport.c:75:1: note: in expansion of macro 'module_platform_driver'
module_platform_driver(vuport_driver);
^
drivers/mfd/intel-vuport.c:77:15: error: expected declaration specifiers or '...' before string constant
MODULE_AUTHOR("Lu Baolu <[email protected]>");
^
drivers/mfd/intel-vuport.c:78:20: error: expected declaration specifiers or '...' before string constant
MODULE_DESCRIPTION("Intel virtual USB port");
^
drivers/mfd/intel-vuport.c:79:16: error: expected declaration specifiers or '...' before string constant
MODULE_LICENSE("GPL v2");
^
drivers/mfd/intel-vuport.c:59:30: warning: 'vuport_acpi_match' defined but not used [-Wunused-variable]
static struct acpi_device_id vuport_acpi_match[] = {
^
In file included from include/linux/acpi.h:27:0,
from drivers/mfd/intel-vuport.c:12:
drivers/mfd/intel-vuport.c:75:24: warning: 'vuport_driver_init' defined but not used [-Wunused-function]
module_platform_driver(vuport_driver);
^
include/linux/device.h:1333:19: note: in definition of macro 'module_driver'
static int __init __driver##_init(void) \
^
>> drivers/mfd/intel-vuport.c:75:1: note: in expansion of macro 'module_platform_driver'
module_platform_driver(vuport_driver);
^cc1: some warnings being treated as errors
vim +/module_platform_driver +75 drivers/mfd/intel-vuport.c
57 }
58
59 static struct acpi_device_id vuport_acpi_match[] = {
60 { "INT3496" },
61 { }
62 };
> 63 MODULE_DEVICE_TABLE(acpi, vuport_acpi_match);
64
65 static struct platform_driver vuport_driver = {
66 .driver = {
67 .name = "intel-vuport",
68 .owner = THIS_MODULE,
69 .acpi_match_table = ACPI_PTR(vuport_acpi_match),
70 },
71 .probe = vuport_probe,
72 .remove = vuport_remove,
73 };
74
> 75 module_platform_driver(vuport_driver);
76
77 MODULE_AUTHOR("Lu Baolu <[email protected]>");
78 MODULE_DESCRIPTION("Intel virtual USB port");---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
kbuild test robot
build botRe: [PATCH 7/7] mfd: intel_vuport: Add Intel virtual USB port MFD Driver
In reply to Lu Baolureproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree…
Hi Lu,
[auto build test ERROR on usb/usb-testing]
[also build test ERROR on v4.5-rc6 next-20160303]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Lu-Baolu/usb-add-support-for-Intel-dual-role-port-mux/20160303-144241 base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-testing config: mn10300-allmodconfig (attached as .config)
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=mn10300
All error/warnings (new ones prefixed by >>):
drivers/mfd/intel-vuport.c: In function 'vuport_probe':
drivers/mfd/intel-vuport.c:39:17: warning: unused variable 'dev' [-Wunused-variable]
struct device *dev = &pdev->dev;
^
drivers/mfd/intel-vuport.c: At top level:
>> drivers/mfd/intel-vuport.c:63:1: warning: data definition has no type or storage class
MODULE_DEVICE_TABLE(acpi, vuport_acpi_match);
^
>> drivers/mfd/intel-vuport.c:63:1: error: type defaults to 'int' in declaration of 'MODULE_DEVICE_TABLE' [-Werror=implicit-int]
>> drivers/mfd/intel-vuport.c:63:1: warning: parameter names (without types) in function declaration
In file included from include/linux/acpi.h:27:0,
from drivers/mfd/intel-vuport.c:12:
include/linux/device.h:1337:1: warning: data definition has no type or storage class
module_init(__driver##_init); \
^
include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
module_driver(__platform_driver, platform_driver_register, \
^
drivers/mfd/intel-vuport.c:75:1: note: in expansion of macro 'module_platform_driver'
module_platform_driver(vuport_driver);
^
include/linux/device.h:1337:1: error: type defaults to 'int' in declaration of 'module_init' [-Werror=implicit-int]
module_init(__driver##_init); \
^
include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
module_driver(__platform_driver, platform_driver_register, \
^
drivers/mfd/intel-vuport.c:75:1: note: in expansion of macro 'module_platform_driver'
module_platform_driver(vuport_driver);
^
drivers/mfd/intel-vuport.c:75:1: warning: parameter names (without types) in function declaration
In file included from include/linux/acpi.h:27:0,
from drivers/mfd/intel-vuport.c:12:
include/linux/device.h:1342:1: warning: data definition has no type or storage class
module_exit(__driver##_exit);
^
include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
module_driver(__platform_driver, platform_driver_register, \
^
drivers/mfd/intel-vuport.c:75:1: note: in expansion of macro 'module_platform_driver'
module_platform_driver(vuport_driver);
^
include/linux/device.h:1342:1: error: type defaults to 'int' in declaration of 'module_exit' [-Werror=implicit-int]
module_exit(__driver##_exit);
^
include/linux/platform_device.h:228:2: note: in expansion of macro 'module_driver'
module_driver(__platform_driver, platform_driver_register, \
^
drivers/mfd/intel-vuport.c:75:1: note: in expansion of macro 'module_platform_driver'
module_platform_driver(vuport_driver);
^
drivers/mfd/intel-vuport.c:75:1: warning: parameter names (without types) in function declaration
>> drivers/mfd/intel-vuport.c:77:15: error: expected declaration specifiers or '...' before string constant
MODULE_AUTHOR("Lu Baolu <[email protected]>");
^
drivers/mfd/intel-vuport.c:78:20: error: expected declaration specifiers or '...' before string constant
MODULE_DESCRIPTION("Intel virtual USB port");
^
drivers/mfd/intel-vuport.c:79:16: error: expected declaration specifiers or '...' before string constant
MODULE_LICENSE("GPL v2");
^
drivers/mfd/intel-vuport.c:59:30: warning: 'vuport_acpi_match' defined but not used [-Wunused-variable]
static struct acpi_device_id vuport_acpi_match[] = {
^
In file included from include/linux/acpi.h:27:0,
from drivers/mfd/intel-vuport.c:12:
drivers/mfd/intel-vuport.c:75:24: warning: 'vuport_driver_init' defined but not used [-Wunused-function]
module_platform_driver(vuport_driver);
^
include/linux/device.h:1333:19: note: in definition of macro 'module_driver'
static int __init __driver##_init(void) \
^
drivers/mfd/intel-vuport.c:75:1: note: in expansion of macro 'module_platform_driver'
module_platform_driver(vuport_driver);
^
drivers/mfd/intel-vuport.c:75:24: warning: 'vuport_driver_exit' defined but not used [-Wunused-function]
module_platform_driver(vuport_driver);
^
include/linux/device.h:1338:20: note: in definition of macro 'module_driver'
static void __exit __driver##_exit(void) \
^
drivers/mfd/intel-vuport.c:75:1: note: in expansion of macro 'module_platform_driver'
module_platform_driver(vuport_driver);
^cc1: some warnings being treated as errors
vim +63 drivers/mfd/intel-vuport.c
33 .name = "intel-mux-gpio",
34 },
35 };
36
37 static int vuport_probe(struct platform_device *pdev)
38 {
> 39 struct device *dev = &pdev->dev;
40 int ret;
41
42 ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), acpi_usb_gpios);
43 if (ret)
44 return ret;
45
46 return mfd_add_devices(&pdev->dev, 0, intel_vuport_mfd_cells,
47 ARRAY_SIZE(intel_vuport_mfd_cells), NULL, 0,
48 NULL);
49 }
50
51 static int vuport_remove(struct platform_device *pdev)
52 {
53 mfd_remove_devices(&pdev->dev);
54 acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pdev->dev));
55
56 return 0;
57 }
58
59 static struct acpi_device_id vuport_acpi_match[] = {
60 { "INT3496" },
61 { }
62 };
> 63 MODULE_DEVICE_TABLE(acpi, vuport_acpi_match);
64
65 static struct platform_driver vuport_driver = {
66 .driver = {
67 .name = "intel-vuport",
68 .owner = THIS_MODULE,
69 .acpi_match_table = ACPI_PTR(vuport_acpi_match),
70 },
71 .probe = vuport_probe,
72 .remove = vuport_remove,
73 };
74
> 75 module_platform_driver(vuport_driver);
76
> 77 MODULE_AUTHOR("Lu Baolu <[email protected]>");
78 MODULE_DESCRIPTION("Intel virtual USB port");
79 MODULE_LICENSE("GPL v2");---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation