diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-03 14:36:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-03 14:36:27 -0400 |
commit | 1d1fdd95df681f0c065d90ffaafa215a0e8825e2 (patch) | |
tree | 19016e131bb5c7eb280a4cc8dff864ba36e53be4 /drivers/extcon | |
parent | b3b49114c80e799af8b08c0c6d1ff886ea843f03 (diff) | |
parent | 3cc1f95283a125cf54ccf1e25065321d4385133b (diff) |
Merge tag 'char-misc-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc patches from Greg KH:
"Here is the big char/misc driver pull request for 3.12-rc1
Lots of driver updates all over the char/misc tree, full details in
the shortlog"
* tag 'char-misc-3.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (62 commits)
drivers: uio: Kconfig: add MMU dependancy for UIO
drivers: uio: Add driver for Humusoft MF624 DAQ PCI card
drivers: uio_pdrv_genirq: use dev_get_platdata()
drivers: uio_pruss: use dev_get_platdata()
drivers: uio_dmem_genirq: use dev_get_platdata()
drivers: parport: Kconfig: exclude h8300 for PARPORT_PC
drivers: misc: ti-st: fix potential race if st_kim_start fails
Drivers: hv: vmbus: Do not attempt to negoatiate a new version prematurely
misc: vmw_balloon: Remove braces to fix build for clang.
Drivers: hv: vmbus: Fix a bug in the handling of channel offers
vme: vme_ca91cx42.c: fix to pass correct device identity to free_irq()
VMCI: Add support for virtual IOMMU
VMCI: Remove non-blocking/pinned queuepair support
uio: uio_pruss: remove unnecessary platform_set_drvdata()
parport: amiga: remove unnecessary platform_set_drvdata()
vme: vme_vmivme7805.c: add missing __iomem annotation
vme: vme_ca91cx42.c: add missing __iomem annotation
vme: vme_tsi148.c: add missing __iomem annotation
drivers/misc/hpilo: Correct panic when an AUX iLO is detected
uio: drop unused vma_count member in uio_device struct
...
Diffstat (limited to 'drivers/extcon')
-rw-r--r-- | drivers/extcon/Kconfig | 4 | ||||
-rw-r--r-- | drivers/extcon/Makefile | 2 | ||||
-rw-r--r-- | drivers/extcon/extcon-adc-jack.c | 3 | ||||
-rw-r--r-- | drivers/extcon/extcon-arizona.c | 25 | ||||
-rw-r--r-- | drivers/extcon/extcon-class.c | 3 | ||||
-rw-r--r-- | drivers/extcon/extcon-gpio.c | 2 | ||||
-rw-r--r-- | drivers/extcon/extcon-palmas.c | 134 | ||||
-rw-r--r-- | drivers/extcon/of_extcon.c | 64 |
8 files changed, 180 insertions, 57 deletions
diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig index 63f454e20576..f1d54a3985bd 100644 --- a/drivers/extcon/Kconfig +++ b/drivers/extcon/Kconfig | |||
@@ -14,6 +14,10 @@ if EXTCON | |||
14 | 14 | ||
15 | comment "Extcon Device Drivers" | 15 | comment "Extcon Device Drivers" |
16 | 16 | ||
17 | config OF_EXTCON | ||
18 | def_tristate y | ||
19 | depends on OF | ||
20 | |||
17 | config EXTCON_GPIO | 21 | config EXTCON_GPIO |
18 | tristate "GPIO extcon support" | 22 | tristate "GPIO extcon support" |
19 | depends on GPIOLIB | 23 | depends on GPIOLIB |
diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile index 540e2c3a4431..759fdae46f95 100644 --- a/drivers/extcon/Makefile +++ b/drivers/extcon/Makefile | |||
@@ -2,6 +2,8 @@ | |||
2 | # Makefile for external connector class (extcon) devices | 2 | # Makefile for external connector class (extcon) devices |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_OF_EXTCON) += of_extcon.o | ||
6 | |||
5 | obj-$(CONFIG_EXTCON) += extcon-class.o | 7 | obj-$(CONFIG_EXTCON) += extcon-class.o |
6 | obj-$(CONFIG_EXTCON_GPIO) += extcon-gpio.o | 8 | obj-$(CONFIG_EXTCON_GPIO) += extcon-gpio.o |
7 | obj-$(CONFIG_EXTCON_ADC_JACK) += extcon-adc-jack.o | 9 | obj-$(CONFIG_EXTCON_ADC_JACK) += extcon-adc-jack.o |
diff --git a/drivers/extcon/extcon-adc-jack.c b/drivers/extcon/extcon-adc-jack.c index d0233cd18ffa..5985807e52c9 100644 --- a/drivers/extcon/extcon-adc-jack.c +++ b/drivers/extcon/extcon-adc-jack.c | |||
@@ -87,7 +87,8 @@ static irqreturn_t adc_jack_irq_thread(int irq, void *_data) | |||
87 | { | 87 | { |
88 | struct adc_jack_data *data = _data; | 88 | struct adc_jack_data *data = _data; |
89 | 89 | ||
90 | schedule_delayed_work(&data->handler, data->handling_delay); | 90 | queue_delayed_work(system_power_efficient_wq, |
91 | &data->handler, data->handling_delay); | ||
91 | return IRQ_HANDLED; | 92 | return IRQ_HANDLED; |
92 | } | 93 | } |
93 | 94 | ||
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index 7a1b4a7791ba..e55713083c78 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c | |||
@@ -890,8 +890,9 @@ static void arizona_micd_detect(struct work_struct *work) | |||
890 | 890 | ||
891 | handled: | 891 | handled: |
892 | if (info->detecting) | 892 | if (info->detecting) |
893 | schedule_delayed_work(&info->micd_timeout_work, | 893 | queue_delayed_work(system_power_efficient_wq, |
894 | msecs_to_jiffies(info->micd_timeout)); | 894 | &info->micd_timeout_work, |
895 | msecs_to_jiffies(info->micd_timeout)); | ||
895 | 896 | ||
896 | pm_runtime_mark_last_busy(info->dev); | 897 | pm_runtime_mark_last_busy(info->dev); |
897 | mutex_unlock(&info->lock); | 898 | mutex_unlock(&info->lock); |
@@ -912,8 +913,9 @@ static irqreturn_t arizona_micdet(int irq, void *data) | |||
912 | mutex_unlock(&info->lock); | 913 | mutex_unlock(&info->lock); |
913 | 914 | ||
914 | if (debounce) | 915 | if (debounce) |
915 | schedule_delayed_work(&info->micd_detect_work, | 916 | queue_delayed_work(system_power_efficient_wq, |
916 | msecs_to_jiffies(debounce)); | 917 | &info->micd_detect_work, |
918 | msecs_to_jiffies(debounce)); | ||
917 | else | 919 | else |
918 | arizona_micd_detect(&info->micd_detect_work.work); | 920 | arizona_micd_detect(&info->micd_detect_work.work); |
919 | 921 | ||
@@ -967,12 +969,14 @@ static irqreturn_t arizona_jackdet(int irq, void *data) | |||
967 | if (val == info->last_jackdet) { | 969 | if (val == info->last_jackdet) { |
968 | dev_dbg(arizona->dev, "Suppressing duplicate JACKDET\n"); | 970 | dev_dbg(arizona->dev, "Suppressing duplicate JACKDET\n"); |
969 | if (cancelled_hp) | 971 | if (cancelled_hp) |
970 | schedule_delayed_work(&info->hpdet_work, | 972 | queue_delayed_work(system_power_efficient_wq, |
971 | msecs_to_jiffies(HPDET_DEBOUNCE)); | 973 | &info->hpdet_work, |
974 | msecs_to_jiffies(HPDET_DEBOUNCE)); | ||
972 | 975 | ||
973 | if (cancelled_mic) | 976 | if (cancelled_mic) |
974 | schedule_delayed_work(&info->micd_timeout_work, | 977 | queue_delayed_work(system_power_efficient_wq, |
975 | msecs_to_jiffies(info->micd_timeout)); | 978 | &info->micd_timeout_work, |
979 | msecs_to_jiffies(info->micd_timeout)); | ||
976 | 980 | ||
977 | goto out; | 981 | goto out; |
978 | } | 982 | } |
@@ -994,8 +998,9 @@ static irqreturn_t arizona_jackdet(int irq, void *data) | |||
994 | 998 | ||
995 | arizona_start_mic(info); | 999 | arizona_start_mic(info); |
996 | } else { | 1000 | } else { |
997 | schedule_delayed_work(&info->hpdet_work, | 1001 | queue_delayed_work(system_power_efficient_wq, |
998 | msecs_to_jiffies(HPDET_DEBOUNCE)); | 1002 | &info->hpdet_work, |
1003 | msecs_to_jiffies(HPDET_DEBOUNCE)); | ||
999 | } | 1004 | } |
1000 | 1005 | ||
1001 | regmap_update_bits(arizona->regmap, | 1006 | regmap_update_bits(arizona->regmap, |
diff --git a/drivers/extcon/extcon-class.c b/drivers/extcon/extcon-class.c index 18ccadef43fd..1446152bf2e9 100644 --- a/drivers/extcon/extcon-class.c +++ b/drivers/extcon/extcon-class.c | |||
@@ -602,7 +602,8 @@ int extcon_dev_register(struct extcon_dev *edev, struct device *dev) | |||
602 | edev->dev->class = extcon_class; | 602 | edev->dev->class = extcon_class; |
603 | edev->dev->release = extcon_dev_release; | 603 | edev->dev->release = extcon_dev_release; |
604 | 604 | ||
605 | dev_set_name(edev->dev, "%s", edev->name ? edev->name : dev_name(dev)); | 605 | edev->name = edev->name ? edev->name : dev_name(dev); |
606 | dev_set_name(edev->dev, "%s", edev->name); | ||
606 | 607 | ||
607 | if (edev->max_supported) { | 608 | if (edev->max_supported) { |
608 | char buf[10]; | 609 | char buf[10]; |
diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c index 02bec32adde4..f874c30ddbff 100644 --- a/drivers/extcon/extcon-gpio.c +++ b/drivers/extcon/extcon-gpio.c | |||
@@ -56,7 +56,7 @@ static irqreturn_t gpio_irq_handler(int irq, void *dev_id) | |||
56 | { | 56 | { |
57 | struct gpio_extcon_data *extcon_data = dev_id; | 57 | struct gpio_extcon_data *extcon_data = dev_id; |
58 | 58 | ||
59 | schedule_delayed_work(&extcon_data->work, | 59 | queue_delayed_work(system_power_efficient_wq, &extcon_data->work, |
60 | extcon_data->debounce_jiffies); | 60 | extcon_data->debounce_jiffies); |
61 | return IRQ_HANDLED; | 61 | return IRQ_HANDLED; |
62 | } | 62 | } |
diff --git a/drivers/extcon/extcon-palmas.c b/drivers/extcon/extcon-palmas.c index b752a0ad7b63..89fdd05c5fd6 100644 --- a/drivers/extcon/extcon-palmas.c +++ b/drivers/extcon/extcon-palmas.c | |||
@@ -57,6 +57,7 @@ static irqreturn_t palmas_vbus_irq_handler(int irq, void *_palmas_usb) | |||
57 | if (palmas_usb->linkstat != PALMAS_USB_STATE_VBUS) { | 57 | if (palmas_usb->linkstat != PALMAS_USB_STATE_VBUS) { |
58 | palmas_usb->linkstat = PALMAS_USB_STATE_VBUS; | 58 | palmas_usb->linkstat = PALMAS_USB_STATE_VBUS; |
59 | extcon_set_cable_state(&palmas_usb->edev, "USB", true); | 59 | extcon_set_cable_state(&palmas_usb->edev, "USB", true); |
60 | dev_info(palmas_usb->dev, "USB cable is attached\n"); | ||
60 | } else { | 61 | } else { |
61 | dev_dbg(palmas_usb->dev, | 62 | dev_dbg(palmas_usb->dev, |
62 | "Spurious connect event detected\n"); | 63 | "Spurious connect event detected\n"); |
@@ -65,6 +66,7 @@ static irqreturn_t palmas_vbus_irq_handler(int irq, void *_palmas_usb) | |||
65 | if (palmas_usb->linkstat == PALMAS_USB_STATE_VBUS) { | 66 | if (palmas_usb->linkstat == PALMAS_USB_STATE_VBUS) { |
66 | palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT; | 67 | palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT; |
67 | extcon_set_cable_state(&palmas_usb->edev, "USB", false); | 68 | extcon_set_cable_state(&palmas_usb->edev, "USB", false); |
69 | dev_info(palmas_usb->dev, "USB cable is detached\n"); | ||
68 | } else { | 70 | } else { |
69 | dev_dbg(palmas_usb->dev, | 71 | dev_dbg(palmas_usb->dev, |
70 | "Spurious disconnect event detected\n"); | 72 | "Spurious disconnect event detected\n"); |
@@ -84,28 +86,23 @@ static irqreturn_t palmas_id_irq_handler(int irq, void *_palmas_usb) | |||
84 | 86 | ||
85 | if (set & PALMAS_USB_ID_INT_SRC_ID_GND) { | 87 | if (set & PALMAS_USB_ID_INT_SRC_ID_GND) { |
86 | palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE, | 88 | palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE, |
87 | PALMAS_USB_ID_INT_EN_HI_SET, | ||
88 | PALMAS_USB_ID_INT_EN_HI_SET_ID_FLOAT); | ||
89 | palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE, | ||
90 | PALMAS_USB_ID_INT_EN_HI_CLR, | ||
91 | PALMAS_USB_ID_INT_EN_HI_CLR_ID_GND); | ||
92 | palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE, | ||
93 | PALMAS_USB_ID_INT_LATCH_CLR, | 89 | PALMAS_USB_ID_INT_LATCH_CLR, |
94 | PALMAS_USB_ID_INT_EN_HI_CLR_ID_GND); | 90 | PALMAS_USB_ID_INT_EN_HI_CLR_ID_GND); |
95 | palmas_usb->linkstat = PALMAS_USB_STATE_ID; | 91 | palmas_usb->linkstat = PALMAS_USB_STATE_ID; |
96 | extcon_set_cable_state(&palmas_usb->edev, "USB-HOST", true); | 92 | extcon_set_cable_state(&palmas_usb->edev, "USB-HOST", true); |
93 | dev_info(palmas_usb->dev, "USB-HOST cable is attached\n"); | ||
97 | } else if (set & PALMAS_USB_ID_INT_SRC_ID_FLOAT) { | 94 | } else if (set & PALMAS_USB_ID_INT_SRC_ID_FLOAT) { |
98 | palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE, | 95 | palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE, |
99 | PALMAS_USB_ID_INT_EN_HI_SET, | ||
100 | PALMAS_USB_ID_INT_EN_HI_SET_ID_GND); | ||
101 | palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE, | ||
102 | PALMAS_USB_ID_INT_EN_HI_CLR, | ||
103 | PALMAS_USB_ID_INT_EN_HI_CLR_ID_FLOAT); | ||
104 | palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE, | ||
105 | PALMAS_USB_ID_INT_LATCH_CLR, | 96 | PALMAS_USB_ID_INT_LATCH_CLR, |
106 | PALMAS_USB_ID_INT_EN_HI_CLR_ID_FLOAT); | 97 | PALMAS_USB_ID_INT_EN_HI_CLR_ID_FLOAT); |
107 | palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT; | 98 | palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT; |
108 | extcon_set_cable_state(&palmas_usb->edev, "USB-HOST", false); | 99 | extcon_set_cable_state(&palmas_usb->edev, "USB-HOST", false); |
100 | dev_info(palmas_usb->dev, "USB-HOST cable is detached\n"); | ||
101 | } else if ((palmas_usb->linkstat == PALMAS_USB_STATE_ID) && | ||
102 | (!(set & PALMAS_USB_ID_INT_SRC_ID_GND))) { | ||
103 | palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT; | ||
104 | extcon_set_cable_state(&palmas_usb->edev, "USB-HOST", false); | ||
105 | dev_info(palmas_usb->dev, "USB-HOST cable is detached\n"); | ||
109 | } | 106 | } |
110 | 107 | ||
111 | return IRQ_HANDLED; | 108 | return IRQ_HANDLED; |
@@ -122,13 +119,17 @@ static void palmas_enable_irq(struct palmas_usb *palmas_usb) | |||
122 | 119 | ||
123 | palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE, | 120 | palmas_write(palmas_usb->palmas, PALMAS_USB_OTG_BASE, |
124 | PALMAS_USB_ID_INT_EN_HI_SET, | 121 | PALMAS_USB_ID_INT_EN_HI_SET, |
125 | PALMAS_USB_ID_INT_EN_HI_SET_ID_GND); | 122 | PALMAS_USB_ID_INT_EN_HI_SET_ID_GND | |
123 | PALMAS_USB_ID_INT_EN_HI_SET_ID_FLOAT); | ||
126 | 124 | ||
127 | palmas_vbus_irq_handler(palmas_usb->vbus_irq, palmas_usb); | 125 | if (palmas_usb->enable_vbus_detection) |
126 | palmas_vbus_irq_handler(palmas_usb->vbus_irq, palmas_usb); | ||
128 | 127 | ||
129 | /* cold plug for host mode needs this delay */ | 128 | /* cold plug for host mode needs this delay */ |
130 | msleep(30); | 129 | if (palmas_usb->enable_id_detection) { |
131 | palmas_id_irq_handler(palmas_usb->id_irq, palmas_usb); | 130 | msleep(30); |
131 | palmas_id_irq_handler(palmas_usb->id_irq, palmas_usb); | ||
132 | } | ||
132 | } | 133 | } |
133 | 134 | ||
134 | static int palmas_usb_probe(struct platform_device *pdev) | 135 | static int palmas_usb_probe(struct platform_device *pdev) |
@@ -139,21 +140,25 @@ static int palmas_usb_probe(struct platform_device *pdev) | |||
139 | struct palmas_usb *palmas_usb; | 140 | struct palmas_usb *palmas_usb; |
140 | int status; | 141 | int status; |
141 | 142 | ||
142 | if (node && !pdata) { | ||
143 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
144 | |||
145 | if (!pdata) | ||
146 | return -ENOMEM; | ||
147 | |||
148 | pdata->wakeup = of_property_read_bool(node, "ti,wakeup"); | ||
149 | } else if (!pdata) { | ||
150 | return -EINVAL; | ||
151 | } | ||
152 | |||
153 | palmas_usb = devm_kzalloc(&pdev->dev, sizeof(*palmas_usb), GFP_KERNEL); | 143 | palmas_usb = devm_kzalloc(&pdev->dev, sizeof(*palmas_usb), GFP_KERNEL); |
154 | if (!palmas_usb) | 144 | if (!palmas_usb) |
155 | return -ENOMEM; | 145 | return -ENOMEM; |
156 | 146 | ||
147 | if (node && !pdata) { | ||
148 | palmas_usb->wakeup = of_property_read_bool(node, "ti,wakeup"); | ||
149 | palmas_usb->enable_id_detection = of_property_read_bool(node, | ||
150 | "ti,enable-id-detection"); | ||
151 | palmas_usb->enable_vbus_detection = of_property_read_bool(node, | ||
152 | "ti,enable-vbus-detection"); | ||
153 | } else { | ||
154 | palmas_usb->wakeup = true; | ||
155 | palmas_usb->enable_id_detection = true; | ||
156 | palmas_usb->enable_vbus_detection = true; | ||
157 | |||
158 | if (pdata) | ||
159 | palmas_usb->wakeup = pdata->wakeup; | ||
160 | } | ||
161 | |||
157 | palmas->usb = palmas_usb; | 162 | palmas->usb = palmas_usb; |
158 | palmas_usb->palmas = palmas; | 163 | palmas_usb->palmas = palmas; |
159 | 164 | ||
@@ -168,11 +173,10 @@ static int palmas_usb_probe(struct platform_device *pdev) | |||
168 | palmas_usb->vbus_irq = regmap_irq_get_virq(palmas->irq_data, | 173 | palmas_usb->vbus_irq = regmap_irq_get_virq(palmas->irq_data, |
169 | PALMAS_VBUS_IRQ); | 174 | PALMAS_VBUS_IRQ); |
170 | 175 | ||
171 | palmas_usb_wakeup(palmas, pdata->wakeup); | 176 | palmas_usb_wakeup(palmas, palmas_usb->wakeup); |
172 | 177 | ||
173 | platform_set_drvdata(pdev, palmas_usb); | 178 | platform_set_drvdata(pdev, palmas_usb); |
174 | 179 | ||
175 | palmas_usb->edev.name = "palmas-usb"; | ||
176 | palmas_usb->edev.supported_cable = palmas_extcon_cable; | 180 | palmas_usb->edev.supported_cable = palmas_extcon_cable; |
177 | palmas_usb->edev.mutually_exclusive = mutually_exclusive; | 181 | palmas_usb->edev.mutually_exclusive = mutually_exclusive; |
178 | 182 | ||
@@ -182,28 +186,36 @@ static int palmas_usb_probe(struct platform_device *pdev) | |||
182 | return status; | 186 | return status; |
183 | } | 187 | } |
184 | 188 | ||
185 | status = devm_request_threaded_irq(palmas_usb->dev, palmas_usb->id_irq, | 189 | if (palmas_usb->enable_id_detection) { |
186 | NULL, palmas_id_irq_handler, | 190 | status = devm_request_threaded_irq(palmas_usb->dev, |
187 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, | 191 | palmas_usb->id_irq, |
188 | "palmas_usb_id", palmas_usb); | 192 | NULL, palmas_id_irq_handler, |
189 | if (status < 0) { | 193 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | |
190 | dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", | 194 | IRQF_ONESHOT | IRQF_EARLY_RESUME, |
195 | "palmas_usb_id", palmas_usb); | ||
196 | if (status < 0) { | ||
197 | dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", | ||
191 | palmas_usb->id_irq, status); | 198 | palmas_usb->id_irq, status); |
192 | goto fail_extcon; | 199 | goto fail_extcon; |
200 | } | ||
193 | } | 201 | } |
194 | 202 | ||
195 | status = devm_request_threaded_irq(palmas_usb->dev, | 203 | if (palmas_usb->enable_vbus_detection) { |
196 | palmas_usb->vbus_irq, NULL, palmas_vbus_irq_handler, | 204 | status = devm_request_threaded_irq(palmas_usb->dev, |
197 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, | 205 | palmas_usb->vbus_irq, NULL, |
198 | "palmas_usb_vbus", palmas_usb); | 206 | palmas_vbus_irq_handler, |
199 | if (status < 0) { | 207 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | |
200 | dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", | 208 | IRQF_ONESHOT | IRQF_EARLY_RESUME, |
209 | "palmas_usb_vbus", palmas_usb); | ||
210 | if (status < 0) { | ||
211 | dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", | ||
201 | palmas_usb->vbus_irq, status); | 212 | palmas_usb->vbus_irq, status); |
202 | goto fail_extcon; | 213 | goto fail_extcon; |
214 | } | ||
203 | } | 215 | } |
204 | 216 | ||
205 | palmas_enable_irq(palmas_usb); | 217 | palmas_enable_irq(palmas_usb); |
206 | 218 | device_set_wakeup_capable(&pdev->dev, true); | |
207 | return 0; | 219 | return 0; |
208 | 220 | ||
209 | fail_extcon: | 221 | fail_extcon: |
@@ -221,6 +233,39 @@ static int palmas_usb_remove(struct platform_device *pdev) | |||
221 | return 0; | 233 | return 0; |
222 | } | 234 | } |
223 | 235 | ||
236 | #ifdef CONFIG_PM_SLEEP | ||
237 | static int palmas_usb_suspend(struct device *dev) | ||
238 | { | ||
239 | struct palmas_usb *palmas_usb = dev_get_drvdata(dev); | ||
240 | |||
241 | if (device_may_wakeup(dev)) { | ||
242 | if (palmas_usb->enable_vbus_detection) | ||
243 | enable_irq_wake(palmas_usb->vbus_irq); | ||
244 | if (palmas_usb->enable_id_detection) | ||
245 | enable_irq_wake(palmas_usb->id_irq); | ||
246 | } | ||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | static int palmas_usb_resume(struct device *dev) | ||
251 | { | ||
252 | struct palmas_usb *palmas_usb = dev_get_drvdata(dev); | ||
253 | |||
254 | if (device_may_wakeup(dev)) { | ||
255 | if (palmas_usb->enable_vbus_detection) | ||
256 | disable_irq_wake(palmas_usb->vbus_irq); | ||
257 | if (palmas_usb->enable_id_detection) | ||
258 | disable_irq_wake(palmas_usb->id_irq); | ||
259 | } | ||
260 | return 0; | ||
261 | }; | ||
262 | #endif | ||
263 | |||
264 | static const struct dev_pm_ops palmas_pm_ops = { | ||
265 | SET_SYSTEM_SLEEP_PM_OPS(palmas_usb_suspend, | ||
266 | palmas_usb_resume) | ||
267 | }; | ||
268 | |||
224 | static struct of_device_id of_palmas_match_tbl[] = { | 269 | static struct of_device_id of_palmas_match_tbl[] = { |
225 | { .compatible = "ti,palmas-usb", }, | 270 | { .compatible = "ti,palmas-usb", }, |
226 | { .compatible = "ti,twl6035-usb", }, | 271 | { .compatible = "ti,twl6035-usb", }, |
@@ -234,6 +279,7 @@ static struct platform_driver palmas_usb_driver = { | |||
234 | .name = "palmas-usb", | 279 | .name = "palmas-usb", |
235 | .of_match_table = of_palmas_match_tbl, | 280 | .of_match_table = of_palmas_match_tbl, |
236 | .owner = THIS_MODULE, | 281 | .owner = THIS_MODULE, |
282 | .pm = &palmas_pm_ops, | ||
237 | }, | 283 | }, |
238 | }; | 284 | }; |
239 | 285 | ||
diff --git a/drivers/extcon/of_extcon.c b/drivers/extcon/of_extcon.c new file mode 100644 index 000000000000..72173ecbb311 --- /dev/null +++ b/drivers/extcon/of_extcon.c | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * OF helpers for External connector (extcon) framework | ||
3 | * | ||
4 | * Copyright (C) 2013 Texas Instruments, Inc. | ||
5 | * Kishon Vijay Abraham I <kishon@ti.com> | ||
6 | * | ||
7 | * Copyright (C) 2013 Samsung Electronics | ||
8 | * Chanwoo Choi <cw00.choi@samsung.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/slab.h> | ||
18 | #include <linux/err.h> | ||
19 | #include <linux/extcon.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <linux/of_platform.h> | ||
22 | #include <linux/extcon/of_extcon.h> | ||
23 | |||
24 | /* | ||
25 | * of_extcon_get_extcon_dev - Get the name of extcon device from devicetree | ||
26 | * @dev - instance to the given device | ||
27 | * @index - index into list of extcon_dev | ||
28 | * | ||
29 | * return the instance of extcon device | ||
30 | */ | ||
31 | struct extcon_dev *of_extcon_get_extcon_dev(struct device *dev, int index) | ||
32 | { | ||
33 | struct device_node *node; | ||
34 | struct extcon_dev *edev; | ||
35 | struct platform_device *extcon_parent_dev; | ||
36 | |||
37 | if (!dev->of_node) { | ||
38 | dev_dbg(dev, "device does not have a device node entry\n"); | ||
39 | return ERR_PTR(-EINVAL); | ||
40 | } | ||
41 | |||
42 | node = of_parse_phandle(dev->of_node, "extcon", index); | ||
43 | if (!node) { | ||
44 | dev_dbg(dev, "failed to get phandle in %s node\n", | ||
45 | dev->of_node->full_name); | ||
46 | return ERR_PTR(-ENODEV); | ||
47 | } | ||
48 | |||
49 | extcon_parent_dev = of_find_device_by_node(node); | ||
50 | if (!extcon_parent_dev) { | ||
51 | dev_dbg(dev, "unable to find device by node\n"); | ||
52 | return ERR_PTR(-EPROBE_DEFER); | ||
53 | } | ||
54 | |||
55 | edev = extcon_get_extcon_dev(dev_name(&extcon_parent_dev->dev)); | ||
56 | if (!edev) { | ||
57 | dev_dbg(dev, "unable to get extcon device : %s\n", | ||
58 | dev_name(&extcon_parent_dev->dev)); | ||
59 | return ERR_PTR(-ENODEV); | ||
60 | } | ||
61 | |||
62 | return edev; | ||
63 | } | ||
64 | EXPORT_SYMBOL_GPL(of_extcon_get_extcon_dev); | ||