From d5653f2b7304f05eeb45d84f123cf02f840b8537 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 9 Apr 2014 15:20:12 +0200 Subject: extcon: max77693: Fix two NULL pointer exceptions on missing pdata Fix NULL pointer exceptions when platform data is not supplied. Trace of one exception: Unable to handle kernel NULL pointer dereference at virtual address 00000008 pgd = c0004000 [00000008] *pgd=00000000 Internal error: Oops: 5 [#1] PREEMPT SMP ARM Modules linked in: CPU: 2 PID: 1 Comm: swapper/0 Not tainted 3.14.0-12045-gead5dd4687a6-dirty #1628 task: eea80000 ti: eea88000 task.ti: eea88000 PC is at max77693_muic_probe+0x27c/0x528 LR is at regmap_write+0x50/0x60 pc : [] lr : [] psr: 20000113 sp : eea89e38 ip : 00000000 fp : c098a834 r10: ee1a5a10 r9 : 00000005 r8 : c098a83c r7 : 0000000a r6 : c098a774 r5 : 00000005 r4 : eeb006d0 r3 : c0697bd8 r2 : 00000000 r1 : 00000001 r0 : 00000000 Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel Control: 10c5387d Table: 4000404a DAC: 00000015 Process swapper/0 (pid: 1, stack limit = 0xeea88240) Stack: (0xeea89e38 to 0xeea8a000) 9e20: c08499fc eeb006d0 9e40: 00000000 00000000 c0915f98 00000001 00000000 ee1a5a10 c098a730 c09a88b8 9e60: 00000000 c098a730 c0915f98 00000000 00000000 c02d6aa0 c02d6a88 ee1a5a10 9e80: c0a712c8 c02d54e4 00001204 c0628b00 ee1a5a10 c098a730 ee1a5a44 00000000 9ea0: eea88000 c02d57b4 00000000 c098a730 c02d5728 c02d3a24 ee813e5c eeb9d534 9ec0: c098a730 ee22f700 c097c720 c02d4b14 c08174ec c098a730 00000006 c098a730 9ee0: 00000006 c092fd30 c09b8500 c02d5df8 00000000 c093cbb8 00000006 c0008928 9f00: 000000c3 ef7fc785 00000000 ef7fc794 00000000 c08af968 00000072 eea89f30 9f20: ef7fc85e c065f198 000000c3 c003e87c 00000003 00000000 c092fd3c 00000000 9f40: c08af618 c0826d58 00000006 00000006 c0956f58 c093cbb8 00000006 c092fd30 9f60: c09b8500 000000c3 c092fd3c c08e8510 00000000 c08e8bb0 00000006 00000006 9f80: c08e8510 c0c0c0c0 00000000 c0628fac 00000000 00000000 00000000 00000000 9fa0: 00000000 c0628fb4 00000000 c000f038 00000000 00000000 00000000 00000000 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000 c0c0c0c0 c0c0c0c0 [] (max77693_muic_probe) from [] (platform_drv_probe+0x18/0x48) [] (platform_drv_probe) from [] (driver_probe_device+0x140/0x384) [] (driver_probe_device) from [] (__driver_attach+0x8c/0x90) [] (__driver_attach) from [] (bus_for_each_dev+0x54/0x88) [] (bus_for_each_dev) from [] (bus_add_driver+0xe8/0x204) [] (bus_add_driver) from [] (driver_register+0x78/0xf4) [] (driver_register) from [] (do_one_initcall+0xc4/0x174) [] (do_one_initcall) from [] (kernel_init_freeable+0xfc/0x1c8) [] (kernel_init_freeable) from [] (kernel_init+0x8/0xec) [] (kernel_init) from [] (ret_from_fork+0x14/0x3c) Code: caffffe7 e59d200c e3550001 b3a05001 (e5923008) ---[ end trace 85db969ce011bde7 ]--- Signed-off-by: Krzysztof Kozlowski Cc: Fixes: 190d7cfc8632 Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-max77693.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/extcon/extcon-max77693.c') diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index da268fbc901b..4657a91acf56 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c @@ -1193,7 +1193,7 @@ static int max77693_muic_probe(struct platform_device *pdev) /* Initialize MUIC register by using platform data or default data */ - if (pdata->muic_data) { + if (pdata && pdata->muic_data) { init_data = pdata->muic_data->init_data; num_init_data = pdata->muic_data->num_init_data; } else { @@ -1226,7 +1226,7 @@ static int max77693_muic_probe(struct platform_device *pdev) = init_data[i].data; } - if (pdata->muic_data) { + if (pdata && pdata->muic_data) { struct max77693_muic_platform_data *muic_pdata = pdata->muic_data; -- cgit v1.2.3 From b8629411bf2c0979ae130511f27fd708e2fd102e Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 9 Apr 2014 15:20:13 +0200 Subject: extcon: max77693: Use power efficient workqueue for delayed cable detection Schedule delayed cable detection work on power efficient workqueue so the scheduler won't wake up idle core for that work. This extends the idle time for CPU cores and conserves power. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-max77693.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/extcon/extcon-max77693.c') diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index 4657a91acf56..39cd095d103c 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c @@ -1283,7 +1283,8 @@ static int max77693_muic_probe(struct platform_device *pdev) * driver should notify cable state to upper layer. */ INIT_DELAYED_WORK(&info->wq_detcable, max77693_muic_detect_cable_wq); - schedule_delayed_work(&info->wq_detcable, delay_jiffies); + queue_delayed_work(system_power_efficient_wq, &info->wq_detcable, + delay_jiffies); return ret; -- cgit v1.2.3 From 10fae1184d00f09696078e572230402543ae34c8 Mon Sep 17 00:00:00 2001 From: Sangjung Woo Date: Mon, 21 Apr 2014 19:10:12 +0900 Subject: extcon: max77693: Use devm_extcon_dev_register() Use the resource-managed extcon device register function (i.e. devm_extcon_dev_register()) instead of extcon_dev_register(). If extcon device is attached with this function, that extcon device is automatically unregistered on driver detach. That reduces tiresome managing code. Signed-off-by: Sangjung Woo Reviewed-by: Krzysztof Kozlowski Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon-max77693.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/extcon/extcon-max77693.c') diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index 39cd095d103c..f0f18e29ae07 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c @@ -1185,7 +1185,7 @@ static int max77693_muic_probe(struct platform_device *pdev) info->edev->name = DEV_NAME; info->edev->dev.parent = &pdev->dev; info->edev->supported_cable = max77693_extcon_cable; - ret = extcon_dev_register(info->edev); + ret = devm_extcon_dev_register(&pdev->dev, info->edev); if (ret) { dev_err(&pdev->dev, "failed to register extcon device\n"); goto err_irq; @@ -1267,7 +1267,7 @@ static int max77693_muic_probe(struct platform_device *pdev) MAX77693_MUIC_REG_ID, &id); if (ret < 0) { dev_err(&pdev->dev, "failed to read revision number\n"); - goto err_extcon; + goto err_irq; } dev_info(info->dev, "device ID : 0x%x\n", id); @@ -1288,8 +1288,6 @@ static int max77693_muic_probe(struct platform_device *pdev) return ret; -err_extcon: - extcon_dev_unregister(info->edev); err_irq: while (--i >= 0) free_irq(muic_irqs[i].virq, info); @@ -1305,7 +1303,6 @@ static int max77693_muic_remove(struct platform_device *pdev) free_irq(muic_irqs[i].virq, info); cancel_work_sync(&info->irq_work); input_unregister_device(info->dock); - extcon_dev_unregister(info->edev); return 0; } -- cgit v1.2.3 From 577bef11048c9dc7ce5f9f18e89bf5305be49554 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 21 Apr 2014 20:39:53 +0900 Subject: extcon: max77693: Use devm_extcon_dev_allocate for extcon_dev This patch use devm_extcon_dev_allocate() to simplify the memory control of extcon device. Signed-off-by: Chanwoo Choi Reviewed-by: Krzysztof Kozlowski Reviewed-by: Felipe Balbi --- drivers/extcon/extcon-max77693.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers/extcon/extcon-max77693.c') diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index f0f18e29ae07..2c7c3e191591 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c @@ -1175,23 +1175,22 @@ static int max77693_muic_probe(struct platform_device *pdev) } /* Initialize extcon device */ - info->edev = devm_kzalloc(&pdev->dev, sizeof(struct extcon_dev), - GFP_KERNEL); - if (!info->edev) { + info->edev = devm_extcon_dev_allocate(&pdev->dev, + max77693_extcon_cable); + if (IS_ERR(info->edev)) { dev_err(&pdev->dev, "failed to allocate memory for extcon\n"); ret = -ENOMEM; goto err_irq; } info->edev->name = DEV_NAME; info->edev->dev.parent = &pdev->dev; - info->edev->supported_cable = max77693_extcon_cable; + ret = devm_extcon_dev_register(&pdev->dev, info->edev); if (ret) { dev_err(&pdev->dev, "failed to register extcon device\n"); goto err_irq; } - /* Initialize MUIC register by using platform data or default data */ if (pdata && pdata->muic_data) { init_data = pdata->muic_data->init_data; -- cgit v1.2.3