diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-03-22 07:03:17 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-03-22 07:03:17 -0400 |
commit | 5c1724c42dc1d60addaa67106a4f25c2a9a140de (patch) | |
tree | cfc93ca64d0d5ee1075c5a2d7ed2b83f22b77edd | |
parent | c3423563c68fc454b805b46cb69fd4816db933e2 (diff) | |
parent | 70216fd937fea79c20705400540fa48f86ddf1c5 (diff) |
Merge tag 'extcon-fixes-for-4.11-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon into char-misc-linus
Chanwoo writes:
Update extcon for v4.11-rc3
This patch fixes issues for Intel INT3496 ACPI device as following:
- Propagate error code of gpiod_to_irq().
- Set the ID pin as the input direction if firmware has the bug
- Rename the gpio name for bining according to the documentation.
- Add gpio acpi mapping table and the dependency on X86.
- Use the devm_gpiod_get() instead of gpiod_get_index because of
acpi mapping table.
-rw-r--r-- | Documentation/extcon/intel-int3496.txt | 5 | ||||
-rw-r--r-- | drivers/extcon/Kconfig | 2 | ||||
-rw-r--r-- | drivers/extcon/extcon-intel-int3496.c | 39 |
3 files changed, 34 insertions, 12 deletions
diff --git a/Documentation/extcon/intel-int3496.txt b/Documentation/extcon/intel-int3496.txt index af0b366c25b7..8155dbc7fad3 100644 --- a/Documentation/extcon/intel-int3496.txt +++ b/Documentation/extcon/intel-int3496.txt | |||
@@ -20,3 +20,8 @@ Index 1: The output gpio for enabling Vbus output from the device to the otg | |||
20 | Index 2: The output gpio for muxing of the data pins between the USB host and | 20 | Index 2: The output gpio for muxing of the data pins between the USB host and |
21 | the USB peripheral controller, write 1 to mux to the peripheral | 21 | the USB peripheral controller, write 1 to mux to the peripheral |
22 | controller | 22 | controller |
23 | |||
24 | There is a mapping between indices and GPIO connection IDs as follows | ||
25 | id index 0 | ||
26 | vbus index 1 | ||
27 | mux index 2 | ||
diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig index 96bbae579c0b..fc09c76248b4 100644 --- a/drivers/extcon/Kconfig +++ b/drivers/extcon/Kconfig | |||
@@ -44,7 +44,7 @@ config EXTCON_GPIO | |||
44 | 44 | ||
45 | config EXTCON_INTEL_INT3496 | 45 | config EXTCON_INTEL_INT3496 |
46 | tristate "Intel INT3496 ACPI device extcon driver" | 46 | tristate "Intel INT3496 ACPI device extcon driver" |
47 | depends on GPIOLIB && ACPI | 47 | depends on GPIOLIB && ACPI && (X86 || COMPILE_TEST) |
48 | help | 48 | help |
49 | Say Y here to enable extcon support for USB OTG ports controlled by | 49 | Say Y here to enable extcon support for USB OTG ports controlled by |
50 | an Intel INT3496 ACPI device. | 50 | an Intel INT3496 ACPI device. |
diff --git a/drivers/extcon/extcon-intel-int3496.c b/drivers/extcon/extcon-intel-int3496.c index a3131b036de6..9d17984bbbd4 100644 --- a/drivers/extcon/extcon-intel-int3496.c +++ b/drivers/extcon/extcon-intel-int3496.c | |||
@@ -45,6 +45,17 @@ static const unsigned int int3496_cable[] = { | |||
45 | EXTCON_NONE, | 45 | EXTCON_NONE, |
46 | }; | 46 | }; |
47 | 47 | ||
48 | static const struct acpi_gpio_params id_gpios = { INT3496_GPIO_USB_ID, 0, false }; | ||
49 | static const struct acpi_gpio_params vbus_gpios = { INT3496_GPIO_VBUS_EN, 0, false }; | ||
50 | static const struct acpi_gpio_params mux_gpios = { INT3496_GPIO_USB_MUX, 0, false }; | ||
51 | |||
52 | static const struct acpi_gpio_mapping acpi_int3496_default_gpios[] = { | ||
53 | { "id-gpios", &id_gpios, 1 }, | ||
54 | { "vbus-gpios", &vbus_gpios, 1 }, | ||
55 | { "mux-gpios", &mux_gpios, 1 }, | ||
56 | { }, | ||
57 | }; | ||
58 | |||
48 | static void int3496_do_usb_id(struct work_struct *work) | 59 | static void int3496_do_usb_id(struct work_struct *work) |
49 | { | 60 | { |
50 | struct int3496_data *data = | 61 | struct int3496_data *data = |
@@ -83,6 +94,13 @@ static int int3496_probe(struct platform_device *pdev) | |||
83 | struct int3496_data *data; | 94 | struct int3496_data *data; |
84 | int ret; | 95 | int ret; |
85 | 96 | ||
97 | ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), | ||
98 | acpi_int3496_default_gpios); | ||
99 | if (ret) { | ||
100 | dev_err(dev, "can't add GPIO ACPI mapping\n"); | ||
101 | return ret; | ||
102 | } | ||
103 | |||
86 | data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); | 104 | data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); |
87 | if (!data) | 105 | if (!data) |
88 | return -ENOMEM; | 106 | return -ENOMEM; |
@@ -90,30 +108,27 @@ static int int3496_probe(struct platform_device *pdev) | |||
90 | data->dev = dev; | 108 | data->dev = dev; |
91 | INIT_DELAYED_WORK(&data->work, int3496_do_usb_id); | 109 | INIT_DELAYED_WORK(&data->work, int3496_do_usb_id); |
92 | 110 | ||
93 | data->gpio_usb_id = devm_gpiod_get_index(dev, "id", | 111 | data->gpio_usb_id = devm_gpiod_get(dev, "id", GPIOD_IN); |
94 | INT3496_GPIO_USB_ID, | ||
95 | GPIOD_IN); | ||
96 | if (IS_ERR(data->gpio_usb_id)) { | 112 | if (IS_ERR(data->gpio_usb_id)) { |
97 | ret = PTR_ERR(data->gpio_usb_id); | 113 | ret = PTR_ERR(data->gpio_usb_id); |
98 | dev_err(dev, "can't request USB ID GPIO: %d\n", ret); | 114 | dev_err(dev, "can't request USB ID GPIO: %d\n", ret); |
99 | return ret; | 115 | return ret; |
116 | } else if (gpiod_get_direction(data->gpio_usb_id) != GPIOF_DIR_IN) { | ||
117 | dev_warn(dev, FW_BUG "USB ID GPIO not in input mode, fixing\n"); | ||
118 | gpiod_direction_input(data->gpio_usb_id); | ||
100 | } | 119 | } |
101 | 120 | ||
102 | data->usb_id_irq = gpiod_to_irq(data->gpio_usb_id); | 121 | data->usb_id_irq = gpiod_to_irq(data->gpio_usb_id); |
103 | if (data->usb_id_irq <= 0) { | 122 | if (data->usb_id_irq < 0) { |
104 | dev_err(dev, "can't get USB ID IRQ: %d\n", data->usb_id_irq); | 123 | dev_err(dev, "can't get USB ID IRQ: %d\n", data->usb_id_irq); |
105 | return -EINVAL; | 124 | return data->usb_id_irq; |
106 | } | 125 | } |
107 | 126 | ||
108 | data->gpio_vbus_en = devm_gpiod_get_index(dev, "vbus en", | 127 | data->gpio_vbus_en = devm_gpiod_get(dev, "vbus", GPIOD_ASIS); |
109 | INT3496_GPIO_VBUS_EN, | ||
110 | GPIOD_ASIS); | ||
111 | if (IS_ERR(data->gpio_vbus_en)) | 128 | if (IS_ERR(data->gpio_vbus_en)) |
112 | dev_info(dev, "can't request VBUS EN GPIO\n"); | 129 | dev_info(dev, "can't request VBUS EN GPIO\n"); |
113 | 130 | ||
114 | data->gpio_usb_mux = devm_gpiod_get_index(dev, "usb mux", | 131 | data->gpio_usb_mux = devm_gpiod_get(dev, "mux", GPIOD_ASIS); |
115 | INT3496_GPIO_USB_MUX, | ||
116 | GPIOD_ASIS); | ||
117 | if (IS_ERR(data->gpio_usb_mux)) | 132 | if (IS_ERR(data->gpio_usb_mux)) |
118 | dev_info(dev, "can't request USB MUX GPIO\n"); | 133 | dev_info(dev, "can't request USB MUX GPIO\n"); |
119 | 134 | ||
@@ -154,6 +169,8 @@ static int int3496_remove(struct platform_device *pdev) | |||
154 | devm_free_irq(&pdev->dev, data->usb_id_irq, data); | 169 | devm_free_irq(&pdev->dev, data->usb_id_irq, data); |
155 | cancel_delayed_work_sync(&data->work); | 170 | cancel_delayed_work_sync(&data->work); |
156 | 171 | ||
172 | acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pdev->dev)); | ||
173 | |||
157 | return 0; | 174 | return 0; |
158 | } | 175 | } |
159 | 176 | ||