aboutsummaryrefslogtreecommitdiff
path: root/drivers/extcon
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/extcon')
-rw-r--r--drivers/extcon/extcon-max8997.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c
index 349f65f6a4a..e636d950ad6 100644
--- a/drivers/extcon/extcon-max8997.c
+++ b/drivers/extcon/extcon-max8997.c
@@ -29,6 +29,7 @@
#include <linux/irqdomain.h>
#define DEV_NAME "max8997-muic"
+#define DELAY_MS_DEFAULT 20000 /* unit: millisecond */
enum max8997_muic_adc_debounce_time {
ADC_DEBOUNCE_TIME_0_5MS = 0, /* 0.5ms */
@@ -129,6 +130,14 @@ struct max8997_muic_info {
enum max8997_muic_charger_type pre_charger_type;
/*
+ * Use delayed workqueue to detect cable state and then
+ * notify cable state to notifiee/platform through uevent.
+ * After completing the booting of platform, the extcon provider
+ * driver should notify cable state to upper layer.
+ */
+ struct delayed_work wq_detcable;
+
+ /*
* Default usb/uart path whether UART/USB or AUX_UART/AUX_USB
* h/w path of COMP2/COMN1 on CONTROL1 register.
*/
@@ -629,11 +638,23 @@ static int max8997_muic_detect_dev(struct max8997_muic_info *info)
return 0;
}
+static void max8997_muic_detect_cable_wq(struct work_struct *work)
+{
+ struct max8997_muic_info *info = container_of(to_delayed_work(work),
+ struct max8997_muic_info, wq_detcable);
+ int ret;
+
+ ret = max8997_muic_detect_dev(info);
+ if (ret < 0)
+ pr_err("failed to detect cable type\n");
+}
+
static int max8997_muic_probe(struct platform_device *pdev)
{
struct max8997_dev *max8997 = dev_get_drvdata(pdev->dev.parent);
struct max8997_platform_data *pdata = dev_get_platdata(max8997->dev);
struct max8997_muic_info *info;
+ int delay_jiffies;
int ret, i;
info = devm_kzalloc(&pdev->dev, sizeof(struct max8997_muic_info),
@@ -721,17 +742,23 @@ static int max8997_muic_probe(struct platform_device *pdev)
/* Set ADC debounce time */
max8997_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS);
- /* Initial device detection */
- ret = max8997_muic_detect_dev(info);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to detect cable type\n");
- goto err_extcon;
- }
+ /*
+ * Detect accessory after completing the initialization of platform
+ *
+ * - Use delayed workqueue to detect cable state and then
+ * notify cable state to notifiee/platform through uevent.
+ * After completing the booting of platform, the extcon provider
+ * driver should notify cable state to upper layer.
+ */
+ INIT_DELAYED_WORK(&info->wq_detcable, max8997_muic_detect_cable_wq);
+ if (pdata->muic_pdata->detcable_delay_ms)
+ delay_jiffies = msecs_to_jiffies(pdata->muic_pdata->detcable_delay_ms);
+ else
+ delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
+ schedule_delayed_work(&info->wq_detcable, delay_jiffies);
- return ret;
+ return 0;
-err_extcon:
- extcon_dev_unregister(info->edev);
err_irq:
while (--i >= 0)
free_irq(muic_irqs[i].virq, info);