aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/extcon
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/extcon')
-rw-r--r--drivers/extcon/Kconfig4
-rw-r--r--drivers/extcon/extcon-adc-jack.c49
-rw-r--r--drivers/extcon/extcon-arizona.c40
-rw-r--r--drivers/extcon/extcon-class.c151
-rw-r--r--drivers/extcon/extcon-gpio.c37
-rw-r--r--drivers/extcon/extcon-max14577.c199
-rw-r--r--drivers/extcon/extcon-max77693.c23
-rw-r--r--drivers/extcon/extcon-max8997.c16
-rw-r--r--drivers/extcon/extcon-palmas.c41
9 files changed, 386 insertions, 174 deletions
diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig
index be56e8ac95e6..aebde489c291 100644
--- a/drivers/extcon/Kconfig
+++ b/drivers/extcon/Kconfig
@@ -28,13 +28,13 @@ config EXTCON_ADC_JACK
28 Say Y here to enable extcon device driver based on ADC values. 28 Say Y here to enable extcon device driver based on ADC values.
29 29
30config EXTCON_MAX14577 30config EXTCON_MAX14577
31 tristate "MAX14577 EXTCON Support" 31 tristate "MAX14577/77836 EXTCON Support"
32 depends on MFD_MAX14577 32 depends on MFD_MAX14577
33 select IRQ_DOMAIN 33 select IRQ_DOMAIN
34 select REGMAP_I2C 34 select REGMAP_I2C
35 help 35 help
36 If you say yes here you get support for the MUIC device of 36 If you say yes here you get support for the MUIC device of
37 Maxim MAX14577 PMIC. The MAX14577 MUIC is a USB port accessory 37 Maxim MAX14577/77836. The MAX14577/77836 MUIC is a USB port accessory
38 detector and switch. 38 detector and switch.
39 39
40config EXTCON_MAX77693 40config EXTCON_MAX77693
diff --git a/drivers/extcon/extcon-adc-jack.c b/drivers/extcon/extcon-adc-jack.c
index e23f1c2e5053..e18f95be3733 100644
--- a/drivers/extcon/extcon-adc-jack.c
+++ b/drivers/extcon/extcon-adc-jack.c
@@ -39,7 +39,7 @@
39 * @chan: iio channel being queried. 39 * @chan: iio channel being queried.
40 */ 40 */
41struct adc_jack_data { 41struct adc_jack_data {
42 struct extcon_dev edev; 42 struct extcon_dev *edev;
43 43
44 const char **cable_names; 44 const char **cable_names;
45 int num_cables; 45 int num_cables;
@@ -64,7 +64,7 @@ static void adc_jack_handler(struct work_struct *work)
64 64
65 ret = iio_read_channel_raw(data->chan, &adc_val); 65 ret = iio_read_channel_raw(data->chan, &adc_val);
66 if (ret < 0) { 66 if (ret < 0) {
67 dev_err(&data->edev.dev, "read channel() error: %d\n", ret); 67 dev_err(&data->edev->dev, "read channel() error: %d\n", ret);
68 return; 68 return;
69 } 69 }
70 70
@@ -80,7 +80,7 @@ static void adc_jack_handler(struct work_struct *work)
80 } 80 }
81 /* if no def has met, it means state = 0 (no cables attached) */ 81 /* if no def has met, it means state = 0 (no cables attached) */
82 82
83 extcon_set_state(&data->edev, state); 83 extcon_set_state(data->edev, state);
84} 84}
85 85
86static irqreturn_t adc_jack_irq_thread(int irq, void *_data) 86static irqreturn_t adc_jack_irq_thread(int irq, void *_data)
@@ -102,33 +102,33 @@ static int adc_jack_probe(struct platform_device *pdev)
102 if (!data) 102 if (!data)
103 return -ENOMEM; 103 return -ENOMEM;
104 104
105 data->edev.name = pdata->name;
106
107 if (!pdata->cable_names) { 105 if (!pdata->cable_names) {
108 err = -EINVAL;
109 dev_err(&pdev->dev, "error: cable_names not defined.\n"); 106 dev_err(&pdev->dev, "error: cable_names not defined.\n");
110 goto out; 107 return -EINVAL;
111 } 108 }
112 109
113 data->edev.dev.parent = &pdev->dev; 110 data->edev = devm_extcon_dev_allocate(&pdev->dev, pdata->cable_names);
114 data->edev.supported_cable = pdata->cable_names; 111 if (IS_ERR(data->edev)) {
112 dev_err(&pdev->dev, "failed to allocate extcon device\n");
113 return -ENOMEM;
114 }
115 data->edev->dev.parent = &pdev->dev;
116 data->edev->name = pdata->name;
115 117
116 /* Check the length of array and set num_cables */ 118 /* Check the length of array and set num_cables */
117 for (i = 0; data->edev.supported_cable[i]; i++) 119 for (i = 0; data->edev->supported_cable[i]; i++)
118 ; 120 ;
119 if (i == 0 || i > SUPPORTED_CABLE_MAX) { 121 if (i == 0 || i > SUPPORTED_CABLE_MAX) {
120 err = -EINVAL;
121 dev_err(&pdev->dev, "error: pdata->cable_names size = %d\n", 122 dev_err(&pdev->dev, "error: pdata->cable_names size = %d\n",
122 i - 1); 123 i - 1);
123 goto out; 124 return -EINVAL;
124 } 125 }
125 data->num_cables = i; 126 data->num_cables = i;
126 127
127 if (!pdata->adc_conditions || 128 if (!pdata->adc_conditions ||
128 !pdata->adc_conditions[0].state) { 129 !pdata->adc_conditions[0].state) {
129 err = -EINVAL;
130 dev_err(&pdev->dev, "error: adc_conditions not defined.\n"); 130 dev_err(&pdev->dev, "error: adc_conditions not defined.\n");
131 goto out; 131 return -EINVAL;
132 } 132 }
133 data->adc_conditions = pdata->adc_conditions; 133 data->adc_conditions = pdata->adc_conditions;
134 134
@@ -138,10 +138,8 @@ static int adc_jack_probe(struct platform_device *pdev)
138 data->num_conditions = i; 138 data->num_conditions = i;
139 139
140 data->chan = iio_channel_get(&pdev->dev, pdata->consumer_channel); 140 data->chan = iio_channel_get(&pdev->dev, pdata->consumer_channel);
141 if (IS_ERR(data->chan)) { 141 if (IS_ERR(data->chan))
142 err = PTR_ERR(data->chan); 142 return PTR_ERR(data->chan);
143 goto out;
144 }
145 143
146 data->handling_delay = msecs_to_jiffies(pdata->handling_delay_ms); 144 data->handling_delay = msecs_to_jiffies(pdata->handling_delay_ms);
147 145
@@ -149,15 +147,14 @@ static int adc_jack_probe(struct platform_device *pdev)
149 147
150 platform_set_drvdata(pdev, data); 148 platform_set_drvdata(pdev, data);
151 149
152 err = extcon_dev_register(&data->edev); 150 err = devm_extcon_dev_register(&pdev->dev, data->edev);
153 if (err) 151 if (err)
154 goto out; 152 return err;
155 153
156 data->irq = platform_get_irq(pdev, 0); 154 data->irq = platform_get_irq(pdev, 0);
157 if (!data->irq) { 155 if (!data->irq) {
158 dev_err(&pdev->dev, "platform_get_irq failed\n"); 156 dev_err(&pdev->dev, "platform_get_irq failed\n");
159 err = -ENODEV; 157 return -ENODEV;
160 goto err_irq;
161 } 158 }
162 159
163 err = request_any_context_irq(data->irq, adc_jack_irq_thread, 160 err = request_any_context_irq(data->irq, adc_jack_irq_thread,
@@ -165,15 +162,10 @@ static int adc_jack_probe(struct platform_device *pdev)
165 162
166 if (err < 0) { 163 if (err < 0) {
167 dev_err(&pdev->dev, "error: irq %d\n", data->irq); 164 dev_err(&pdev->dev, "error: irq %d\n", data->irq);
168 goto err_irq; 165 return err;
169 } 166 }
170 167
171 return 0; 168 return 0;
172
173err_irq:
174 extcon_dev_unregister(&data->edev);
175out:
176 return err;
177} 169}
178 170
179static int adc_jack_remove(struct platform_device *pdev) 171static int adc_jack_remove(struct platform_device *pdev)
@@ -182,7 +174,6 @@ static int adc_jack_remove(struct platform_device *pdev)
182 174
183 free_irq(data->irq, data); 175 free_irq(data->irq, data);
184 cancel_work_sync(&data->handler.work); 176 cancel_work_sync(&data->handler.work);
185 extcon_dev_unregister(&data->edev);
186 177
187 return 0; 178 return 0;
188} 179}
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index 98a14f6143a7..6c84e3d12043 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -91,7 +91,7 @@ struct arizona_extcon_info {
91 91
92 int hpdet_ip; 92 int hpdet_ip;
93 93
94 struct extcon_dev edev; 94 struct extcon_dev *edev;
95}; 95};
96 96
97static const struct arizona_micd_config micd_default_modes[] = { 97static const struct arizona_micd_config micd_default_modes[] = {
@@ -546,7 +546,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
546 } 546 }
547 547
548 /* If the cable was removed while measuring ignore the result */ 548 /* If the cable was removed while measuring ignore the result */
549 ret = extcon_get_cable_state_(&info->edev, ARIZONA_CABLE_MECHANICAL); 549 ret = extcon_get_cable_state_(info->edev, ARIZONA_CABLE_MECHANICAL);
550 if (ret < 0) { 550 if (ret < 0) {
551 dev_err(arizona->dev, "Failed to check cable state: %d\n", 551 dev_err(arizona->dev, "Failed to check cable state: %d\n",
552 ret); 552 ret);
@@ -581,7 +581,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
581 else 581 else
582 report = ARIZONA_CABLE_HEADPHONE; 582 report = ARIZONA_CABLE_HEADPHONE;
583 583
584 ret = extcon_set_cable_state_(&info->edev, report, true); 584 ret = extcon_set_cable_state_(info->edev, report, true);
585 if (ret != 0) 585 if (ret != 0)
586 dev_err(arizona->dev, "Failed to report HP/line: %d\n", 586 dev_err(arizona->dev, "Failed to report HP/line: %d\n",
587 ret); 587 ret);
@@ -664,7 +664,7 @@ err:
664 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC); 664 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
665 665
666 /* Just report headphone */ 666 /* Just report headphone */
667 ret = extcon_update_state(&info->edev, 667 ret = extcon_update_state(info->edev,
668 1 << ARIZONA_CABLE_HEADPHONE, 668 1 << ARIZONA_CABLE_HEADPHONE,
669 1 << ARIZONA_CABLE_HEADPHONE); 669 1 << ARIZONA_CABLE_HEADPHONE);
670 if (ret != 0) 670 if (ret != 0)
@@ -723,7 +723,7 @@ err:
723 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC); 723 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
724 724
725 /* Just report headphone */ 725 /* Just report headphone */
726 ret = extcon_update_state(&info->edev, 726 ret = extcon_update_state(info->edev,
727 1 << ARIZONA_CABLE_HEADPHONE, 727 1 << ARIZONA_CABLE_HEADPHONE,
728 1 << ARIZONA_CABLE_HEADPHONE); 728 1 << ARIZONA_CABLE_HEADPHONE);
729 if (ret != 0) 729 if (ret != 0)
@@ -764,7 +764,7 @@ static void arizona_micd_detect(struct work_struct *work)
764 mutex_lock(&info->lock); 764 mutex_lock(&info->lock);
765 765
766 /* If the cable was removed while measuring ignore the result */ 766 /* If the cable was removed while measuring ignore the result */
767 ret = extcon_get_cable_state_(&info->edev, ARIZONA_CABLE_MECHANICAL); 767 ret = extcon_get_cable_state_(info->edev, ARIZONA_CABLE_MECHANICAL);
768 if (ret < 0) { 768 if (ret < 0) {
769 dev_err(arizona->dev, "Failed to check cable state: %d\n", 769 dev_err(arizona->dev, "Failed to check cable state: %d\n",
770 ret); 770 ret);
@@ -812,7 +812,7 @@ static void arizona_micd_detect(struct work_struct *work)
812 if (info->detecting && (val & ARIZONA_MICD_LVL_8)) { 812 if (info->detecting && (val & ARIZONA_MICD_LVL_8)) {
813 arizona_identify_headphone(info); 813 arizona_identify_headphone(info);
814 814
815 ret = extcon_update_state(&info->edev, 815 ret = extcon_update_state(info->edev,
816 1 << ARIZONA_CABLE_MICROPHONE, 816 1 << ARIZONA_CABLE_MICROPHONE,
817 1 << ARIZONA_CABLE_MICROPHONE); 817 1 << ARIZONA_CABLE_MICROPHONE);
818 818
@@ -999,7 +999,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
999 999
1000 if (info->last_jackdet == present) { 1000 if (info->last_jackdet == present) {
1001 dev_dbg(arizona->dev, "Detected jack\n"); 1001 dev_dbg(arizona->dev, "Detected jack\n");
1002 ret = extcon_set_cable_state_(&info->edev, 1002 ret = extcon_set_cable_state_(info->edev,
1003 ARIZONA_CABLE_MECHANICAL, true); 1003 ARIZONA_CABLE_MECHANICAL, true);
1004 1004
1005 if (ret != 0) 1005 if (ret != 0)
@@ -1038,7 +1038,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
1038 info->micd_ranges[i].key, 0); 1038 info->micd_ranges[i].key, 0);
1039 input_sync(info->input); 1039 input_sync(info->input);
1040 1040
1041 ret = extcon_update_state(&info->edev, 0xffffffff, 0); 1041 ret = extcon_update_state(info->edev, 0xffffffff, 0);
1042 if (ret != 0) 1042 if (ret != 0)
1043 dev_err(arizona->dev, "Removal report failed: %d\n", 1043 dev_err(arizona->dev, "Removal report failed: %d\n",
1044 ret); 1044 ret);
@@ -1105,15 +1105,14 @@ static int arizona_extcon_probe(struct platform_device *pdev)
1105 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); 1105 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
1106 if (!info) { 1106 if (!info) {
1107 dev_err(&pdev->dev, "Failed to allocate memory\n"); 1107 dev_err(&pdev->dev, "Failed to allocate memory\n");
1108 ret = -ENOMEM; 1108 return -ENOMEM;
1109 goto err;
1110 } 1109 }
1111 1110
1112 info->micvdd = devm_regulator_get(arizona->dev, "MICVDD"); 1111 info->micvdd = devm_regulator_get(arizona->dev, "MICVDD");
1113 if (IS_ERR(info->micvdd)) { 1112 if (IS_ERR(info->micvdd)) {
1114 ret = PTR_ERR(info->micvdd); 1113 ret = PTR_ERR(info->micvdd);
1115 dev_err(arizona->dev, "Failed to get MICVDD: %d\n", ret); 1114 dev_err(arizona->dev, "Failed to get MICVDD: %d\n", ret);
1116 goto err; 1115 return ret;
1117 } 1116 }
1118 1117
1119 mutex_init(&info->lock); 1118 mutex_init(&info->lock);
@@ -1151,15 +1150,19 @@ static int arizona_extcon_probe(struct platform_device *pdev)
1151 break; 1150 break;
1152 } 1151 }
1153 1152
1154 info->edev.name = "Headset Jack"; 1153 info->edev = devm_extcon_dev_allocate(&pdev->dev, arizona_cable);
1155 info->edev.dev.parent = arizona->dev; 1154 if (IS_ERR(info->edev)) {
1156 info->edev.supported_cable = arizona_cable; 1155 dev_err(&pdev->dev, "failed to allocate extcon device\n");
1156 return -ENOMEM;
1157 }
1158 info->edev->name = "Headset Jack";
1159 info->edev->dev.parent = arizona->dev;
1157 1160
1158 ret = extcon_dev_register(&info->edev); 1161 ret = devm_extcon_dev_register(&pdev->dev, info->edev);
1159 if (ret < 0) { 1162 if (ret < 0) {
1160 dev_err(arizona->dev, "extcon_dev_register() failed: %d\n", 1163 dev_err(arizona->dev, "extcon_dev_register() failed: %d\n",
1161 ret); 1164 ret);
1162 goto err; 1165 return ret;
1163 } 1166 }
1164 1167
1165 info->input = devm_input_allocate_device(&pdev->dev); 1168 info->input = devm_input_allocate_device(&pdev->dev);
@@ -1410,8 +1413,6 @@ err_rise:
1410err_input: 1413err_input:
1411err_register: 1414err_register:
1412 pm_runtime_disable(&pdev->dev); 1415 pm_runtime_disable(&pdev->dev);
1413 extcon_dev_unregister(&info->edev);
1414err:
1415 return ret; 1416 return ret;
1416} 1417}
1417 1418
@@ -1445,7 +1446,6 @@ static int arizona_extcon_remove(struct platform_device *pdev)
1445 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, 1446 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
1446 ARIZONA_JD1_ENA, 0); 1447 ARIZONA_JD1_ENA, 0);
1447 arizona_clk32k_disable(arizona); 1448 arizona_clk32k_disable(arizona);
1448 extcon_dev_unregister(&info->edev);
1449 1449
1450 return 0; 1450 return 0;
1451} 1451}
diff --git a/drivers/extcon/extcon-class.c b/drivers/extcon/extcon-class.c
index 7ab21aa6eaa1..18d42c0e4581 100644
--- a/drivers/extcon/extcon-class.c
+++ b/drivers/extcon/extcon-class.c
@@ -565,6 +565,100 @@ static void dummy_sysfs_dev_release(struct device *dev)
565{ 565{
566} 566}
567 567
568/*
569 * extcon_dev_allocate() - Allocate the memory of extcon device.
570 * @supported_cable: Array of supported cable names ending with NULL.
571 * If supported_cable is NULL, cable name related APIs
572 * are disabled.
573 *
574 * This function allocates the memory for extcon device without allocating
575 * memory in each extcon provider driver and initialize default setting for
576 * extcon device.
577 *
578 * Return the pointer of extcon device if success or ERR_PTR(err) if fail
579 */
580struct extcon_dev *extcon_dev_allocate(const char **supported_cable)
581{
582 struct extcon_dev *edev;
583
584 edev = kzalloc(sizeof(*edev), GFP_KERNEL);
585 if (!edev)
586 return ERR_PTR(-ENOMEM);
587
588 edev->max_supported = 0;
589 edev->supported_cable = supported_cable;
590
591 return edev;
592}
593
594/*
595 * extcon_dev_free() - Free the memory of extcon device.
596 * @edev: the extcon device to free
597 */
598void extcon_dev_free(struct extcon_dev *edev)
599{
600 kfree(edev);
601}
602EXPORT_SYMBOL_GPL(extcon_dev_free);
603
604static int devm_extcon_dev_match(struct device *dev, void *res, void *data)
605{
606 struct extcon_dev **r = res;
607
608 if (WARN_ON(!r || !*r))
609 return 0;
610
611 return *r == data;
612}
613
614static void devm_extcon_dev_release(struct device *dev, void *res)
615{
616 extcon_dev_free(*(struct extcon_dev **)res);
617}
618
619/**
620 * devm_extcon_dev_allocate - Allocate managed extcon device
621 * @dev: device owning the extcon device being created
622 * @supported_cable: Array of supported cable names ending with NULL.
623 * If supported_cable is NULL, cable name related APIs
624 * are disabled.
625 *
626 * This function manages automatically the memory of extcon device using device
627 * resource management and simplify the control of freeing the memory of extcon
628 * device.
629 *
630 * Returns the pointer memory of allocated extcon_dev if success
631 * or ERR_PTR(err) if fail
632 */
633struct extcon_dev *devm_extcon_dev_allocate(struct device *dev,
634 const char **supported_cable)
635{
636 struct extcon_dev **ptr, *edev;
637
638 ptr = devres_alloc(devm_extcon_dev_release, sizeof(*ptr), GFP_KERNEL);
639 if (!ptr)
640 return ERR_PTR(-ENOMEM);
641
642 edev = extcon_dev_allocate(supported_cable);
643 if (IS_ERR(edev)) {
644 devres_free(ptr);
645 return edev;
646 }
647
648 *ptr = edev;
649 devres_add(dev, ptr);
650
651 return edev;
652}
653EXPORT_SYMBOL_GPL(devm_extcon_dev_allocate);
654
655void devm_extcon_dev_free(struct device *dev, struct extcon_dev *edev)
656{
657 WARN_ON(devres_release(dev, devm_extcon_dev_release,
658 devm_extcon_dev_match, edev));
659}
660EXPORT_SYMBOL_GPL(devm_extcon_dev_free);
661
568/** 662/**
569 * extcon_dev_register() - Register a new extcon device 663 * extcon_dev_register() - Register a new extcon device
570 * @edev : the new extcon device (should be allocated before calling) 664 * @edev : the new extcon device (should be allocated before calling)
@@ -819,6 +913,63 @@ void extcon_dev_unregister(struct extcon_dev *edev)
819} 913}
820EXPORT_SYMBOL_GPL(extcon_dev_unregister); 914EXPORT_SYMBOL_GPL(extcon_dev_unregister);
821 915
916static void devm_extcon_dev_unreg(struct device *dev, void *res)
917{
918 extcon_dev_unregister(*(struct extcon_dev **)res);
919}
920
921/**
922 * devm_extcon_dev_register() - Resource-managed extcon_dev_register()
923 * @dev: device to allocate extcon device
924 * @edev: the new extcon device to register
925 *
926 * Managed extcon_dev_register() function. If extcon device is attached with
927 * this function, that extcon device is automatically unregistered on driver
928 * detach. Internally this function calls extcon_dev_register() function.
929 * To get more information, refer that function.
930 *
931 * If extcon device is registered with this function and the device needs to be
932 * unregistered separately, devm_extcon_dev_unregister() should be used.
933 *
934 * Returns 0 if success or negaive error number if failure.
935 */
936int devm_extcon_dev_register(struct device *dev, struct extcon_dev *edev)
937{
938 struct extcon_dev **ptr;
939 int ret;
940
941 ptr = devres_alloc(devm_extcon_dev_unreg, sizeof(*ptr), GFP_KERNEL);
942 if (!ptr)
943 return -ENOMEM;
944
945 ret = extcon_dev_register(edev);
946 if (ret) {
947 devres_free(ptr);
948 return ret;
949 }
950
951 *ptr = edev;
952 devres_add(dev, ptr);
953
954 return 0;
955}
956EXPORT_SYMBOL_GPL(devm_extcon_dev_register);
957
958/**
959 * devm_extcon_dev_unregister() - Resource-managed extcon_dev_unregister()
960 * @dev: device the extcon belongs to
961 * @edev: the extcon device to unregister
962 *
963 * Unregister extcon device that is registered with devm_extcon_dev_register()
964 * function.
965 */
966void devm_extcon_dev_unregister(struct device *dev, struct extcon_dev *edev)
967{
968 WARN_ON(devres_release(dev, devm_extcon_dev_unreg,
969 devm_extcon_dev_match, edev));
970}
971EXPORT_SYMBOL_GPL(devm_extcon_dev_unregister);
972
822#ifdef CONFIG_OF 973#ifdef CONFIG_OF
823/* 974/*
824 * extcon_get_edev_by_phandle - Get the extcon device from devicetree 975 * extcon_get_edev_by_phandle - Get the extcon device from devicetree
diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c
index 13d522255d81..645b28356819 100644
--- a/drivers/extcon/extcon-gpio.c
+++ b/drivers/extcon/extcon-gpio.c
@@ -32,7 +32,7 @@
32#include <linux/extcon/extcon-gpio.h> 32#include <linux/extcon/extcon-gpio.h>
33 33
34struct gpio_extcon_data { 34struct gpio_extcon_data {
35 struct extcon_dev edev; 35 struct extcon_dev *edev;
36 unsigned gpio; 36 unsigned gpio;
37 bool gpio_active_low; 37 bool gpio_active_low;
38 const char *state_on; 38 const char *state_on;
@@ -53,7 +53,7 @@ static void gpio_extcon_work(struct work_struct *work)
53 state = gpio_get_value(data->gpio); 53 state = gpio_get_value(data->gpio);
54 if (data->gpio_active_low) 54 if (data->gpio_active_low)
55 state = !state; 55 state = !state;
56 extcon_set_state(&data->edev, state); 56 extcon_set_state(data->edev, state);
57} 57}
58 58
59static irqreturn_t gpio_irq_handler(int irq, void *dev_id) 59static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
@@ -67,9 +67,10 @@ static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
67 67
68static ssize_t extcon_gpio_print_state(struct extcon_dev *edev, char *buf) 68static ssize_t extcon_gpio_print_state(struct extcon_dev *edev, char *buf)
69{ 69{
70 struct gpio_extcon_data *extcon_data = 70 struct device *dev = edev->dev.parent;
71 container_of(edev, struct gpio_extcon_data, edev); 71 struct gpio_extcon_data *extcon_data = dev_get_drvdata(dev);
72 const char *state; 72 const char *state;
73
73 if (extcon_get_state(edev)) 74 if (extcon_get_state(edev))
74 state = extcon_data->state_on; 75 state = extcon_data->state_on;
75 else 76 else
@@ -98,15 +99,21 @@ static int gpio_extcon_probe(struct platform_device *pdev)
98 if (!extcon_data) 99 if (!extcon_data)
99 return -ENOMEM; 100 return -ENOMEM;
100 101
101 extcon_data->edev.name = pdata->name; 102 extcon_data->edev = devm_extcon_dev_allocate(&pdev->dev, NULL);
102 extcon_data->edev.dev.parent = &pdev->dev; 103 if (IS_ERR(extcon_data->edev)) {
104 dev_err(&pdev->dev, "failed to allocate extcon device\n");
105 return -ENOMEM;
106 }
107 extcon_data->edev->name = pdata->name;
108 extcon_data->edev->dev.parent = &pdev->dev;
109
103 extcon_data->gpio = pdata->gpio; 110 extcon_data->gpio = pdata->gpio;
104 extcon_data->gpio_active_low = pdata->gpio_active_low; 111 extcon_data->gpio_active_low = pdata->gpio_active_low;
105 extcon_data->state_on = pdata->state_on; 112 extcon_data->state_on = pdata->state_on;
106 extcon_data->state_off = pdata->state_off; 113 extcon_data->state_off = pdata->state_off;
107 extcon_data->check_on_resume = pdata->check_on_resume; 114 extcon_data->check_on_resume = pdata->check_on_resume;
108 if (pdata->state_on && pdata->state_off) 115 if (pdata->state_on && pdata->state_off)
109 extcon_data->edev.print_state = extcon_gpio_print_state; 116 extcon_data->edev->print_state = extcon_gpio_print_state;
110 117
111 ret = devm_gpio_request_one(&pdev->dev, extcon_data->gpio, GPIOF_DIR_IN, 118 ret = devm_gpio_request_one(&pdev->dev, extcon_data->gpio, GPIOF_DIR_IN,
112 pdev->name); 119 pdev->name);
@@ -121,34 +128,27 @@ static int gpio_extcon_probe(struct platform_device *pdev)
121 msecs_to_jiffies(pdata->debounce); 128 msecs_to_jiffies(pdata->debounce);
122 } 129 }
123 130
124 ret = extcon_dev_register(&extcon_data->edev); 131 ret = devm_extcon_dev_register(&pdev->dev, extcon_data->edev);
125 if (ret < 0) 132 if (ret < 0)
126 return ret; 133 return ret;
127 134
128 INIT_DELAYED_WORK(&extcon_data->work, gpio_extcon_work); 135 INIT_DELAYED_WORK(&extcon_data->work, gpio_extcon_work);
129 136
130 extcon_data->irq = gpio_to_irq(extcon_data->gpio); 137 extcon_data->irq = gpio_to_irq(extcon_data->gpio);
131 if (extcon_data->irq < 0) { 138 if (extcon_data->irq < 0)
132 ret = extcon_data->irq; 139 return extcon_data->irq;
133 goto err;
134 }
135 140
136 ret = request_any_context_irq(extcon_data->irq, gpio_irq_handler, 141 ret = request_any_context_irq(extcon_data->irq, gpio_irq_handler,
137 pdata->irq_flags, pdev->name, 142 pdata->irq_flags, pdev->name,
138 extcon_data); 143 extcon_data);
139 if (ret < 0) 144 if (ret < 0)
140 goto err; 145 return ret;
141 146
142 platform_set_drvdata(pdev, extcon_data); 147 platform_set_drvdata(pdev, extcon_data);
143 /* Perform initial detection */ 148 /* Perform initial detection */
144 gpio_extcon_work(&extcon_data->work.work); 149 gpio_extcon_work(&extcon_data->work.work);
145 150
146 return 0; 151 return 0;
147
148err:
149 extcon_dev_unregister(&extcon_data->edev);
150
151 return ret;
152} 152}
153 153
154static int gpio_extcon_remove(struct platform_device *pdev) 154static int gpio_extcon_remove(struct platform_device *pdev)
@@ -157,7 +157,6 @@ static int gpio_extcon_remove(struct platform_device *pdev)
157 157
158 cancel_delayed_work_sync(&extcon_data->work); 158 cancel_delayed_work_sync(&extcon_data->work);
159 free_irq(extcon_data->irq, extcon_data); 159 free_irq(extcon_data->irq, extcon_data);
160 extcon_dev_unregister(&extcon_data->edev);
161 160
162 return 0; 161 return 0;
163} 162}
diff --git a/drivers/extcon/extcon-max14577.c b/drivers/extcon/extcon-max14577.c
index 3846941801b8..d49e891b5675 100644
--- a/drivers/extcon/extcon-max14577.c
+++ b/drivers/extcon/extcon-max14577.c
@@ -1,8 +1,9 @@
1/* 1/*
2 * extcon-max14577.c - MAX14577 extcon driver to support MAX14577 MUIC 2 * extcon-max14577.c - MAX14577/77836 extcon driver to support MUIC
3 * 3 *
4 * Copyright (C) 2013 Samsung Electrnoics 4 * Copyright (C) 2013,2014 Samsung Electrnoics
5 * Chanwoo Choi <cw00.choi@samsung.com> 5 * Chanwoo Choi <cw00.choi@samsung.com>
6 * Krzysztof Kozlowski <k.kozlowski@samsung.com>
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -24,7 +25,6 @@
24#include <linux/mfd/max14577-private.h> 25#include <linux/mfd/max14577-private.h>
25#include <linux/extcon.h> 26#include <linux/extcon.h>
26 27
27#define DEV_NAME "max14577-muic"
28#define DELAY_MS_DEFAULT 17000 /* unit: millisecond */ 28#define DELAY_MS_DEFAULT 17000 /* unit: millisecond */
29 29
30enum max14577_muic_adc_debounce_time { 30enum max14577_muic_adc_debounce_time {
@@ -40,6 +40,42 @@ enum max14577_muic_status {
40 MAX14577_MUIC_STATUS_END, 40 MAX14577_MUIC_STATUS_END,
41}; 41};
42 42
43/**
44 * struct max14577_muic_irq
45 * @irq: the index of irq list of MUIC device.
46 * @name: the name of irq.
47 * @virq: the virtual irq to use irq domain
48 */
49struct max14577_muic_irq {
50 unsigned int irq;
51 const char *name;
52 unsigned int virq;
53};
54
55static struct max14577_muic_irq max14577_muic_irqs[] = {
56 { MAX14577_IRQ_INT1_ADC, "muic-ADC" },
57 { MAX14577_IRQ_INT1_ADCLOW, "muic-ADCLOW" },
58 { MAX14577_IRQ_INT1_ADCERR, "muic-ADCError" },
59 { MAX14577_IRQ_INT2_CHGTYP, "muic-CHGTYP" },
60 { MAX14577_IRQ_INT2_CHGDETRUN, "muic-CHGDETRUN" },
61 { MAX14577_IRQ_INT2_DCDTMR, "muic-DCDTMR" },
62 { MAX14577_IRQ_INT2_DBCHG, "muic-DBCHG" },
63 { MAX14577_IRQ_INT2_VBVOLT, "muic-VBVOLT" },
64};
65
66static struct max14577_muic_irq max77836_muic_irqs[] = {
67 { MAX14577_IRQ_INT1_ADC, "muic-ADC" },
68 { MAX14577_IRQ_INT1_ADCLOW, "muic-ADCLOW" },
69 { MAX14577_IRQ_INT1_ADCERR, "muic-ADCError" },
70 { MAX77836_IRQ_INT1_ADC1K, "muic-ADC1K" },
71 { MAX14577_IRQ_INT2_CHGTYP, "muic-CHGTYP" },
72 { MAX14577_IRQ_INT2_CHGDETRUN, "muic-CHGDETRUN" },
73 { MAX14577_IRQ_INT2_DCDTMR, "muic-DCDTMR" },
74 { MAX14577_IRQ_INT2_DBCHG, "muic-DBCHG" },
75 { MAX14577_IRQ_INT2_VBVOLT, "muic-VBVOLT" },
76 { MAX77836_IRQ_INT2_VIDRM, "muic-VIDRM" },
77};
78
43struct max14577_muic_info { 79struct max14577_muic_info {
44 struct device *dev; 80 struct device *dev;
45 struct max14577 *max14577; 81 struct max14577 *max14577;
@@ -48,6 +84,8 @@ struct max14577_muic_info {
48 int prev_chg_type; 84 int prev_chg_type;
49 u8 status[MAX14577_MUIC_STATUS_END]; 85 u8 status[MAX14577_MUIC_STATUS_END];
50 86
87 struct max14577_muic_irq *muic_irqs;
88 unsigned int muic_irqs_num;
51 bool irq_adc; 89 bool irq_adc;
52 bool irq_chg; 90 bool irq_chg;
53 struct work_struct irq_work; 91 struct work_struct irq_work;
@@ -74,29 +112,6 @@ enum max14577_muic_cable_group {
74 MAX14577_CABLE_GROUP_CHG, 112 MAX14577_CABLE_GROUP_CHG,
75}; 113};
76 114
77/**
78 * struct max14577_muic_irq
79 * @irq: the index of irq list of MUIC device.
80 * @name: the name of irq.
81 * @virq: the virtual irq to use irq domain
82 */
83struct max14577_muic_irq {
84 unsigned int irq;
85 const char *name;
86 unsigned int virq;
87};
88
89static struct max14577_muic_irq muic_irqs[] = {
90 { MAX14577_IRQ_INT1_ADC, "muic-ADC" },
91 { MAX14577_IRQ_INT1_ADCLOW, "muic-ADCLOW" },
92 { MAX14577_IRQ_INT1_ADCERR, "muic-ADCError" },
93 { MAX14577_IRQ_INT2_CHGTYP, "muic-CHGTYP" },
94 { MAX14577_IRQ_INT2_CHGDETRUN, "muic-CHGDETRUN" },
95 { MAX14577_IRQ_INT2_DCDTMR, "muic-DCDTMR" },
96 { MAX14577_IRQ_INT2_DBCHG, "muic-DBCHG" },
97 { MAX14577_IRQ_INT2_VBVOLT, "muic-VBVOLT" },
98};
99
100/* Define supported accessory type */ 115/* Define supported accessory type */
101enum max14577_muic_acc_type { 116enum max14577_muic_acc_type {
102 MAX14577_MUIC_ADC_GROUND = 0x0, 117 MAX14577_MUIC_ADC_GROUND = 0x0,
@@ -528,21 +543,12 @@ static void max14577_muic_irq_work(struct work_struct *work)
528 return; 543 return;
529} 544}
530 545
531static irqreturn_t max14577_muic_irq_handler(int irq, void *data) 546/*
547 * Sets irq_adc or irq_chg in max14577_muic_info and returns 1.
548 * Returns 0 if irq_type does not match registered IRQ for this device type.
549 */
550static int max14577_parse_irq(struct max14577_muic_info *info, int irq_type)
532{ 551{
533 struct max14577_muic_info *info = data;
534 int i, irq_type = -1;
535
536 /*
537 * We may be called multiple times for different nested IRQ-s.
538 * Including changes in INT1_ADC and INT2_CGHTYP at once.
539 * However we only need to know whether it was ADC, charger
540 * or both interrupts so decode IRQ and turn on proper flags.
541 */
542 for (i = 0; i < ARRAY_SIZE(muic_irqs); i++)
543 if (irq == muic_irqs[i].virq)
544 irq_type = muic_irqs[i].irq;
545
546 switch (irq_type) { 552 switch (irq_type) {
547 case MAX14577_IRQ_INT1_ADC: 553 case MAX14577_IRQ_INT1_ADC:
548 case MAX14577_IRQ_INT1_ADCLOW: 554 case MAX14577_IRQ_INT1_ADCLOW:
@@ -550,7 +556,7 @@ static irqreturn_t max14577_muic_irq_handler(int irq, void *data)
550 /* Handle all of accessory except for 556 /* Handle all of accessory except for
551 type of charger accessory */ 557 type of charger accessory */
552 info->irq_adc = true; 558 info->irq_adc = true;
553 break; 559 return 1;
554 case MAX14577_IRQ_INT2_CHGTYP: 560 case MAX14577_IRQ_INT2_CHGTYP:
555 case MAX14577_IRQ_INT2_CHGDETRUN: 561 case MAX14577_IRQ_INT2_CHGDETRUN:
556 case MAX14577_IRQ_INT2_DCDTMR: 562 case MAX14577_IRQ_INT2_DCDTMR:
@@ -558,8 +564,62 @@ static irqreturn_t max14577_muic_irq_handler(int irq, void *data)
558 case MAX14577_IRQ_INT2_VBVOLT: 564 case MAX14577_IRQ_INT2_VBVOLT:
559 /* Handle charger accessory */ 565 /* Handle charger accessory */
560 info->irq_chg = true; 566 info->irq_chg = true;
567 return 1;
568 default:
569 return 0;
570 }
571}
572
573/*
574 * Sets irq_adc or irq_chg in max14577_muic_info and returns 1.
575 * Returns 0 if irq_type does not match registered IRQ for this device type.
576 */
577static int max77836_parse_irq(struct max14577_muic_info *info, int irq_type)
578{
579 /* First check common max14577 interrupts */
580 if (max14577_parse_irq(info, irq_type))
581 return 1;
582
583 switch (irq_type) {
584 case MAX77836_IRQ_INT1_ADC1K:
585 info->irq_adc = true;
586 return 1;
587 case MAX77836_IRQ_INT2_VIDRM:
588 /* Handle charger accessory */
589 info->irq_chg = true;
590 return 1;
591 default:
592 return 0;
593 }
594}
595
596static irqreturn_t max14577_muic_irq_handler(int irq, void *data)
597{
598 struct max14577_muic_info *info = data;
599 int i, irq_type = -1;
600 bool irq_parsed;
601
602 /*
603 * We may be called multiple times for different nested IRQ-s.
604 * Including changes in INT1_ADC and INT2_CGHTYP at once.
605 * However we only need to know whether it was ADC, charger
606 * or both interrupts so decode IRQ and turn on proper flags.
607 */
608 for (i = 0; i < info->muic_irqs_num; i++)
609 if (irq == info->muic_irqs[i].virq)
610 irq_type = info->muic_irqs[i].irq;
611
612 switch (info->max14577->dev_type) {
613 case MAXIM_DEVICE_TYPE_MAX77836:
614 irq_parsed = max77836_parse_irq(info, irq_type);
561 break; 615 break;
616 case MAXIM_DEVICE_TYPE_MAX14577:
562 default: 617 default:
618 irq_parsed = max14577_parse_irq(info, irq_type);
619 break;
620 }
621
622 if (!irq_parsed) {
563 dev_err(info->dev, "muic interrupt: irq %d occurred, skipped\n", 623 dev_err(info->dev, "muic interrupt: irq %d occurred, skipped\n",
564 irq_type); 624 irq_type);
565 return IRQ_HANDLED; 625 return IRQ_HANDLED;
@@ -644,13 +704,24 @@ static int max14577_muic_probe(struct platform_device *pdev)
644 704
645 INIT_WORK(&info->irq_work, max14577_muic_irq_work); 705 INIT_WORK(&info->irq_work, max14577_muic_irq_work);
646 706
707 switch (max14577->dev_type) {
708 case MAXIM_DEVICE_TYPE_MAX77836:
709 info->muic_irqs = max77836_muic_irqs;
710 info->muic_irqs_num = ARRAY_SIZE(max77836_muic_irqs);
711 break;
712 case MAXIM_DEVICE_TYPE_MAX14577:
713 default:
714 info->muic_irqs = max14577_muic_irqs;
715 info->muic_irqs_num = ARRAY_SIZE(max14577_muic_irqs);
716 }
717
647 /* Support irq domain for max14577 MUIC device */ 718 /* Support irq domain for max14577 MUIC device */
648 for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) { 719 for (i = 0; i < info->muic_irqs_num; i++) {
649 struct max14577_muic_irq *muic_irq = &muic_irqs[i]; 720 struct max14577_muic_irq *muic_irq = &info->muic_irqs[i];
650 unsigned int virq = 0; 721 unsigned int virq = 0;
651 722
652 virq = regmap_irq_get_virq(max14577->irq_data, muic_irq->irq); 723 virq = regmap_irq_get_virq(max14577->irq_data, muic_irq->irq);
653 if (!virq) 724 if (virq <= 0)
654 return -EINVAL; 725 return -EINVAL;
655 muic_irq->virq = virq; 726 muic_irq->virq = virq;
656 727
@@ -668,14 +739,16 @@ static int max14577_muic_probe(struct platform_device *pdev)
668 } 739 }
669 740
670 /* Initialize extcon device */ 741 /* Initialize extcon device */
671 info->edev = devm_kzalloc(&pdev->dev, sizeof(*info->edev), GFP_KERNEL); 742 info->edev = devm_extcon_dev_allocate(&pdev->dev,
672 if (!info->edev) { 743 max14577_extcon_cable);
744 if (IS_ERR(info->edev)) {
673 dev_err(&pdev->dev, "failed to allocate memory for extcon\n"); 745 dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
674 return -ENOMEM; 746 return -ENOMEM;
675 } 747 }
676 info->edev->name = DEV_NAME; 748
677 info->edev->supported_cable = max14577_extcon_cable; 749 info->edev->name = dev_name(&pdev->dev);
678 ret = extcon_dev_register(info->edev); 750
751 ret = devm_extcon_dev_register(&pdev->dev, info->edev);
679 if (ret) { 752 if (ret) {
680 dev_err(&pdev->dev, "failed to register extcon device\n"); 753 dev_err(&pdev->dev, "failed to register extcon device\n");
681 return ret; 754 return ret;
@@ -694,7 +767,7 @@ static int max14577_muic_probe(struct platform_device *pdev)
694 MAX14577_REG_DEVICEID, &id); 767 MAX14577_REG_DEVICEID, &id);
695 if (ret < 0) { 768 if (ret < 0) {
696 dev_err(&pdev->dev, "failed to read revision number\n"); 769 dev_err(&pdev->dev, "failed to read revision number\n");
697 goto err_extcon; 770 return ret;
698 } 771 }
699 dev_info(info->dev, "device ID : 0x%x\n", id); 772 dev_info(info->dev, "device ID : 0x%x\n", id);
700 773
@@ -710,19 +783,10 @@ static int max14577_muic_probe(struct platform_device *pdev)
710 * driver should notify cable state to upper layer. 783 * driver should notify cable state to upper layer.
711 */ 784 */
712 INIT_DELAYED_WORK(&info->wq_detcable, max14577_muic_detect_cable_wq); 785 INIT_DELAYED_WORK(&info->wq_detcable, max14577_muic_detect_cable_wq);
713 ret = queue_delayed_work(system_power_efficient_wq, &info->wq_detcable, 786 queue_delayed_work(system_power_efficient_wq, &info->wq_detcable,
714 delay_jiffies); 787 delay_jiffies);
715 if (ret < 0) {
716 dev_err(&pdev->dev,
717 "failed to schedule delayed work for cable detect\n");
718 goto err_extcon;
719 }
720 788
721 return ret; 789 return ret;
722
723err_extcon:
724 extcon_dev_unregister(info->edev);
725 return ret;
726} 790}
727 791
728static int max14577_muic_remove(struct platform_device *pdev) 792static int max14577_muic_remove(struct platform_device *pdev)
@@ -730,23 +794,30 @@ static int max14577_muic_remove(struct platform_device *pdev)
730 struct max14577_muic_info *info = platform_get_drvdata(pdev); 794 struct max14577_muic_info *info = platform_get_drvdata(pdev);
731 795
732 cancel_work_sync(&info->irq_work); 796 cancel_work_sync(&info->irq_work);
733 extcon_dev_unregister(info->edev);
734 797
735 return 0; 798 return 0;
736} 799}
737 800
801static const struct platform_device_id max14577_muic_id[] = {
802 { "max14577-muic", MAXIM_DEVICE_TYPE_MAX14577, },
803 { "max77836-muic", MAXIM_DEVICE_TYPE_MAX77836, },
804 { }
805};
806MODULE_DEVICE_TABLE(platform, max14577_muic_id);
807
738static struct platform_driver max14577_muic_driver = { 808static struct platform_driver max14577_muic_driver = {
739 .driver = { 809 .driver = {
740 .name = DEV_NAME, 810 .name = "max14577-muic",
741 .owner = THIS_MODULE, 811 .owner = THIS_MODULE,
742 }, 812 },
743 .probe = max14577_muic_probe, 813 .probe = max14577_muic_probe,
744 .remove = max14577_muic_remove, 814 .remove = max14577_muic_remove,
815 .id_table = max14577_muic_id,
745}; 816};
746 817
747module_platform_driver(max14577_muic_driver); 818module_platform_driver(max14577_muic_driver);
748 819
749MODULE_DESCRIPTION("MAXIM 14577 Extcon driver"); 820MODULE_DESCRIPTION("Maxim 14577/77836 Extcon driver");
750MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>"); 821MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>, Krzysztof Kozlowski <k.kozlowski@samsung.com>");
751MODULE_LICENSE("GPL"); 822MODULE_LICENSE("GPL");
752MODULE_ALIAS("platform:extcon-max14577"); 823MODULE_ALIAS("platform:extcon-max14577");
diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c
index da268fbc901b..2c7c3e191591 100644
--- a/drivers/extcon/extcon-max77693.c
+++ b/drivers/extcon/extcon-max77693.c
@@ -1175,25 +1175,24 @@ static int max77693_muic_probe(struct platform_device *pdev)
1175 } 1175 }
1176 1176
1177 /* Initialize extcon device */ 1177 /* Initialize extcon device */
1178 info->edev = devm_kzalloc(&pdev->dev, sizeof(struct extcon_dev), 1178 info->edev = devm_extcon_dev_allocate(&pdev->dev,
1179 GFP_KERNEL); 1179 max77693_extcon_cable);
1180 if (!info->edev) { 1180 if (IS_ERR(info->edev)) {
1181 dev_err(&pdev->dev, "failed to allocate memory for extcon\n"); 1181 dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
1182 ret = -ENOMEM; 1182 ret = -ENOMEM;
1183 goto err_irq; 1183 goto err_irq;
1184 } 1184 }
1185 info->edev->name = DEV_NAME; 1185 info->edev->name = DEV_NAME;
1186 info->edev->dev.parent = &pdev->dev; 1186 info->edev->dev.parent = &pdev->dev;
1187 info->edev->supported_cable = max77693_extcon_cable; 1187
1188 ret = extcon_dev_register(info->edev); 1188 ret = devm_extcon_dev_register(&pdev->dev, info->edev);
1189 if (ret) { 1189 if (ret) {
1190 dev_err(&pdev->dev, "failed to register extcon device\n"); 1190 dev_err(&pdev->dev, "failed to register extcon device\n");
1191 goto err_irq; 1191 goto err_irq;
1192 } 1192 }
1193 1193
1194
1195 /* Initialize MUIC register by using platform data or default data */ 1194 /* Initialize MUIC register by using platform data or default data */
1196 if (pdata->muic_data) { 1195 if (pdata && pdata->muic_data) {
1197 init_data = pdata->muic_data->init_data; 1196 init_data = pdata->muic_data->init_data;
1198 num_init_data = pdata->muic_data->num_init_data; 1197 num_init_data = pdata->muic_data->num_init_data;
1199 } else { 1198 } else {
@@ -1226,7 +1225,7 @@ static int max77693_muic_probe(struct platform_device *pdev)
1226 = init_data[i].data; 1225 = init_data[i].data;
1227 } 1226 }
1228 1227
1229 if (pdata->muic_data) { 1228 if (pdata && pdata->muic_data) {
1230 struct max77693_muic_platform_data *muic_pdata 1229 struct max77693_muic_platform_data *muic_pdata
1231 = pdata->muic_data; 1230 = pdata->muic_data;
1232 1231
@@ -1267,7 +1266,7 @@ static int max77693_muic_probe(struct platform_device *pdev)
1267 MAX77693_MUIC_REG_ID, &id); 1266 MAX77693_MUIC_REG_ID, &id);
1268 if (ret < 0) { 1267 if (ret < 0) {
1269 dev_err(&pdev->dev, "failed to read revision number\n"); 1268 dev_err(&pdev->dev, "failed to read revision number\n");
1270 goto err_extcon; 1269 goto err_irq;
1271 } 1270 }
1272 dev_info(info->dev, "device ID : 0x%x\n", id); 1271 dev_info(info->dev, "device ID : 0x%x\n", id);
1273 1272
@@ -1283,12 +1282,11 @@ static int max77693_muic_probe(struct platform_device *pdev)
1283 * driver should notify cable state to upper layer. 1282 * driver should notify cable state to upper layer.
1284 */ 1283 */
1285 INIT_DELAYED_WORK(&info->wq_detcable, max77693_muic_detect_cable_wq); 1284 INIT_DELAYED_WORK(&info->wq_detcable, max77693_muic_detect_cable_wq);
1286 schedule_delayed_work(&info->wq_detcable, delay_jiffies); 1285 queue_delayed_work(system_power_efficient_wq, &info->wq_detcable,
1286 delay_jiffies);
1287 1287
1288 return ret; 1288 return ret;
1289 1289
1290err_extcon:
1291 extcon_dev_unregister(info->edev);
1292err_irq: 1290err_irq:
1293 while (--i >= 0) 1291 while (--i >= 0)
1294 free_irq(muic_irqs[i].virq, info); 1292 free_irq(muic_irqs[i].virq, info);
@@ -1304,7 +1302,6 @@ static int max77693_muic_remove(struct platform_device *pdev)
1304 free_irq(muic_irqs[i].virq, info); 1302 free_irq(muic_irqs[i].virq, info);
1305 cancel_work_sync(&info->irq_work); 1303 cancel_work_sync(&info->irq_work);
1306 input_unregister_device(info->dock); 1304 input_unregister_device(info->dock);
1307 extcon_dev_unregister(info->edev);
1308 1305
1309 return 0; 1306 return 0;
1310} 1307}
diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c
index 6a00464658c5..d9f7f1baaa03 100644
--- a/drivers/extcon/extcon-max8997.c
+++ b/drivers/extcon/extcon-max8997.c
@@ -699,23 +699,22 @@ static int max8997_muic_probe(struct platform_device *pdev)
699 } 699 }
700 700
701 /* External connector */ 701 /* External connector */
702 info->edev = devm_kzalloc(&pdev->dev, sizeof(struct extcon_dev), 702 info->edev = devm_extcon_dev_allocate(&pdev->dev, max8997_extcon_cable);
703 GFP_KERNEL); 703 if (IS_ERR(info->edev)) {
704 if (!info->edev) {
705 dev_err(&pdev->dev, "failed to allocate memory for extcon\n"); 704 dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
706 ret = -ENOMEM; 705 ret = -ENOMEM;
707 goto err_irq; 706 goto err_irq;
708 } 707 }
709 info->edev->name = DEV_NAME; 708 info->edev->name = DEV_NAME;
710 info->edev->dev.parent = &pdev->dev; 709 info->edev->dev.parent = &pdev->dev;
711 info->edev->supported_cable = max8997_extcon_cable; 710
712 ret = extcon_dev_register(info->edev); 711 ret = devm_extcon_dev_register(&pdev->dev, info->edev);
713 if (ret) { 712 if (ret) {
714 dev_err(&pdev->dev, "failed to register extcon device\n"); 713 dev_err(&pdev->dev, "failed to register extcon device\n");
715 goto err_irq; 714 goto err_irq;
716 } 715 }
717 716
718 if (pdata->muic_pdata) { 717 if (pdata && pdata->muic_pdata) {
719 struct max8997_muic_platform_data *muic_pdata 718 struct max8997_muic_platform_data *muic_pdata
720 = pdata->muic_pdata; 719 = pdata->muic_pdata;
721 720
@@ -770,7 +769,8 @@ static int max8997_muic_probe(struct platform_device *pdev)
770 * driver should notify cable state to upper layer. 769 * driver should notify cable state to upper layer.
771 */ 770 */
772 INIT_DELAYED_WORK(&info->wq_detcable, max8997_muic_detect_cable_wq); 771 INIT_DELAYED_WORK(&info->wq_detcable, max8997_muic_detect_cable_wq);
773 schedule_delayed_work(&info->wq_detcable, delay_jiffies); 772 queue_delayed_work(system_power_efficient_wq, &info->wq_detcable,
773 delay_jiffies);
774 774
775 return 0; 775 return 0;
776 776
@@ -789,8 +789,6 @@ static int max8997_muic_remove(struct platform_device *pdev)
789 free_irq(muic_irqs[i].virq, info); 789 free_irq(muic_irqs[i].virq, info);
790 cancel_work_sync(&info->irq_work); 790 cancel_work_sync(&info->irq_work);
791 791
792 extcon_dev_unregister(info->edev);
793
794 return 0; 792 return 0;
795} 793}
796 794
diff --git a/drivers/extcon/extcon-palmas.c b/drivers/extcon/extcon-palmas.c
index ddff2b72f0a8..7417ce84eb2d 100644
--- a/drivers/extcon/extcon-palmas.c
+++ b/drivers/extcon/extcon-palmas.c
@@ -23,6 +23,7 @@
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/slab.h>
26#include <linux/err.h> 27#include <linux/err.h>
27#include <linux/mfd/palmas.h> 28#include <linux/mfd/palmas.h>
28#include <linux/of.h> 29#include <linux/of.h>
@@ -56,7 +57,7 @@ static irqreturn_t palmas_vbus_irq_handler(int irq, void *_palmas_usb)
56 if (vbus_line_state & PALMAS_INT3_LINE_STATE_VBUS) { 57 if (vbus_line_state & PALMAS_INT3_LINE_STATE_VBUS) {
57 if (palmas_usb->linkstat != PALMAS_USB_STATE_VBUS) { 58 if (palmas_usb->linkstat != PALMAS_USB_STATE_VBUS) {
58 palmas_usb->linkstat = PALMAS_USB_STATE_VBUS; 59 palmas_usb->linkstat = PALMAS_USB_STATE_VBUS;
59 extcon_set_cable_state(&palmas_usb->edev, "USB", true); 60 extcon_set_cable_state(palmas_usb->edev, "USB", true);
60 dev_info(palmas_usb->dev, "USB cable is attached\n"); 61 dev_info(palmas_usb->dev, "USB cable is attached\n");
61 } else { 62 } else {
62 dev_dbg(palmas_usb->dev, 63 dev_dbg(palmas_usb->dev,
@@ -65,7 +66,7 @@ static irqreturn_t palmas_vbus_irq_handler(int irq, void *_palmas_usb)
65 } else if (!(vbus_line_state & PALMAS_INT3_LINE_STATE_VBUS)) { 66 } else if (!(vbus_line_state & PALMAS_INT3_LINE_STATE_VBUS)) {
66 if (palmas_usb->linkstat == PALMAS_USB_STATE_VBUS) { 67 if (palmas_usb->linkstat == PALMAS_USB_STATE_VBUS) {
67 palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT; 68 palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT;
68 extcon_set_cable_state(&palmas_usb->edev, "USB", false); 69 extcon_set_cable_state(palmas_usb->edev, "USB", false);
69 dev_info(palmas_usb->dev, "USB cable is detached\n"); 70 dev_info(palmas_usb->dev, "USB cable is detached\n");
70 } else { 71 } else {
71 dev_dbg(palmas_usb->dev, 72 dev_dbg(palmas_usb->dev,
@@ -92,7 +93,7 @@ static irqreturn_t palmas_id_irq_handler(int irq, void *_palmas_usb)
92 PALMAS_USB_ID_INT_LATCH_CLR, 93 PALMAS_USB_ID_INT_LATCH_CLR,
93 PALMAS_USB_ID_INT_EN_HI_CLR_ID_GND); 94 PALMAS_USB_ID_INT_EN_HI_CLR_ID_GND);
94 palmas_usb->linkstat = PALMAS_USB_STATE_ID; 95 palmas_usb->linkstat = PALMAS_USB_STATE_ID;
95 extcon_set_cable_state(&palmas_usb->edev, "USB-HOST", true); 96 extcon_set_cable_state(palmas_usb->edev, "USB-HOST", true);
96 dev_info(palmas_usb->dev, "USB-HOST cable is attached\n"); 97 dev_info(palmas_usb->dev, "USB-HOST cable is attached\n");
97 } else if ((set & PALMAS_USB_ID_INT_SRC_ID_FLOAT) && 98 } else if ((set & PALMAS_USB_ID_INT_SRC_ID_FLOAT) &&
98 (id_src & PALMAS_USB_ID_INT_SRC_ID_FLOAT)) { 99 (id_src & PALMAS_USB_ID_INT_SRC_ID_FLOAT)) {
@@ -100,17 +101,17 @@ static irqreturn_t palmas_id_irq_handler(int irq, void *_palmas_usb)
100 PALMAS_USB_ID_INT_LATCH_CLR, 101 PALMAS_USB_ID_INT_LATCH_CLR,
101 PALMAS_USB_ID_INT_EN_HI_CLR_ID_FLOAT); 102 PALMAS_USB_ID_INT_EN_HI_CLR_ID_FLOAT);
102 palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT; 103 palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT;
103 extcon_set_cable_state(&palmas_usb->edev, "USB-HOST", false); 104 extcon_set_cable_state(palmas_usb->edev, "USB-HOST", false);
104 dev_info(palmas_usb->dev, "USB-HOST cable is detached\n"); 105 dev_info(palmas_usb->dev, "USB-HOST cable is detached\n");
105 } else if ((palmas_usb->linkstat == PALMAS_USB_STATE_ID) && 106 } else if ((palmas_usb->linkstat == PALMAS_USB_STATE_ID) &&
106 (!(set & PALMAS_USB_ID_INT_SRC_ID_GND))) { 107 (!(set & PALMAS_USB_ID_INT_SRC_ID_GND))) {
107 palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT; 108 palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT;
108 extcon_set_cable_state(&palmas_usb->edev, "USB-HOST", false); 109 extcon_set_cable_state(palmas_usb->edev, "USB-HOST", false);
109 dev_info(palmas_usb->dev, "USB-HOST cable is detached\n"); 110 dev_info(palmas_usb->dev, "USB-HOST cable is detached\n");
110 } else if ((palmas_usb->linkstat == PALMAS_USB_STATE_DISCONNECT) && 111 } else if ((palmas_usb->linkstat == PALMAS_USB_STATE_DISCONNECT) &&
111 (id_src & PALMAS_USB_ID_INT_SRC_ID_GND)) { 112 (id_src & PALMAS_USB_ID_INT_SRC_ID_GND)) {
112 palmas_usb->linkstat = PALMAS_USB_STATE_ID; 113 palmas_usb->linkstat = PALMAS_USB_STATE_ID;
113 extcon_set_cable_state(&palmas_usb->edev, "USB-HOST", true); 114 extcon_set_cable_state(palmas_usb->edev, "USB-HOST", true);
114 dev_info(palmas_usb->dev, " USB-HOST cable is attached\n"); 115 dev_info(palmas_usb->dev, " USB-HOST cable is attached\n");
115 } 116 }
116 117
@@ -186,13 +187,20 @@ static int palmas_usb_probe(struct platform_device *pdev)
186 187
187 platform_set_drvdata(pdev, palmas_usb); 188 platform_set_drvdata(pdev, palmas_usb);
188 189
189 palmas_usb->edev.supported_cable = palmas_extcon_cable; 190 palmas_usb->edev = devm_extcon_dev_allocate(&pdev->dev,
190 palmas_usb->edev.dev.parent = palmas_usb->dev; 191 palmas_extcon_cable);
191 palmas_usb->edev.mutually_exclusive = mutually_exclusive; 192 if (IS_ERR(palmas_usb->edev)) {
193 dev_err(&pdev->dev, "failed to allocate extcon device\n");
194 return -ENOMEM;
195 }
196 palmas_usb->edev->name = kstrdup(node->name, GFP_KERNEL);
197 palmas_usb->edev->dev.parent = palmas_usb->dev;
198 palmas_usb->edev->mutually_exclusive = mutually_exclusive;
192 199
193 status = extcon_dev_register(&palmas_usb->edev); 200 status = devm_extcon_dev_register(&pdev->dev, palmas_usb->edev);
194 if (status) { 201 if (status) {
195 dev_err(&pdev->dev, "failed to register extcon device\n"); 202 dev_err(&pdev->dev, "failed to register extcon device\n");
203 kfree(palmas_usb->edev->name);
196 return status; 204 return status;
197 } 205 }
198 206
@@ -206,7 +214,8 @@ static int palmas_usb_probe(struct platform_device *pdev)
206 if (status < 0) { 214 if (status < 0) {
207 dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", 215 dev_err(&pdev->dev, "can't get IRQ %d, err %d\n",
208 palmas_usb->id_irq, status); 216 palmas_usb->id_irq, status);
209 goto fail_extcon; 217 kfree(palmas_usb->edev->name);
218 return status;
210 } 219 }
211 } 220 }
212 221
@@ -220,25 +229,21 @@ static int palmas_usb_probe(struct platform_device *pdev)
220 if (status < 0) { 229 if (status < 0) {
221 dev_err(&pdev->dev, "can't get IRQ %d, err %d\n", 230 dev_err(&pdev->dev, "can't get IRQ %d, err %d\n",
222 palmas_usb->vbus_irq, status); 231 palmas_usb->vbus_irq, status);
223 goto fail_extcon; 232 kfree(palmas_usb->edev->name);
233 return status;
224 } 234 }
225 } 235 }
226 236
227 palmas_enable_irq(palmas_usb); 237 palmas_enable_irq(palmas_usb);
228 device_set_wakeup_capable(&pdev->dev, true); 238 device_set_wakeup_capable(&pdev->dev, true);
229 return 0; 239 return 0;
230
231fail_extcon:
232 extcon_dev_unregister(&palmas_usb->edev);
233
234 return status;
235} 240}
236 241
237static int palmas_usb_remove(struct platform_device *pdev) 242static int palmas_usb_remove(struct platform_device *pdev)
238{ 243{
239 struct palmas_usb *palmas_usb = platform_get_drvdata(pdev); 244 struct palmas_usb *palmas_usb = platform_get_drvdata(pdev);
240 245
241 extcon_dev_unregister(&palmas_usb->edev); 246 kfree(palmas_usb->edev->name);
242 247
243 return 0; 248 return 0;
244} 249}