From patchwork Wed Apr 22 08:51:21 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuninori Morimoto X-Patchwork-Id: 6255261 Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 448F29F1BE for ; Wed, 22 Apr 2015 08:51:53 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2D601202F2 for ; Wed, 22 Apr 2015 08:51:52 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id 0921B2025B for ; Wed, 22 Apr 2015 08:51:50 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 9F1AD26057B; Wed, 22 Apr 2015 10:51:48 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from alsa0.perex.cz (localhost [IPv6:::1]) by alsa0.perex.cz (Postfix) with ESMTP id 43429260544; Wed, 22 Apr 2015 10:51:40 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id 0CCFA260555; Wed, 22 Apr 2015 10:51:39 +0200 (CEST) Received: from relmlie3.idc.renesas.com (relmlor4.renesas.com [210.160.252.174]) by alsa0.perex.cz (Postfix) with ESMTP id 99C66260525 for ; Wed, 22 Apr 2015 10:51:31 +0200 (CEST) Received: from unknown (HELO relmlir2.idc.renesas.com) ([10.200.68.152]) by relmlie3.idc.renesas.com with ESMTP; 22 Apr 2015 17:51:24 +0900 Received: from relmlac1.idc.renesas.com (relmlac1.idc.renesas.com [10.200.69.21]) by relmlir2.idc.renesas.com (Postfix) with ESMTP id 45ED2480EF; Wed, 22 Apr 2015 17:51:24 +0900 (JST) Received: by relmlac1.idc.renesas.com (Postfix, from userid 0) id 2B26D8002E; Wed, 22 Apr 2015 17:51:24 +0900 (JST) Received: from relmlac1.idc.renesas.com (localhost [127.0.0.1]) by relmlac1.idc.renesas.com (Postfix) with ESMTP id 26B4B8002D; Wed, 22 Apr 2015 17:51:24 +0900 (JST) Received: from relmlii1.idc.renesas.com [10.200.68.65] by relmlac1.idc.renesas.com with ESMTP id TAX15290; Wed, 22 Apr 2015 17:51:24 +0900 X-IronPort-AV: E=Sophos;i="5.11,622,1422889200"; d="scan'208";a="184598544" Received: from mail-sg1lp0088.outbound.protection.outlook.com (HELO APAC01-SG1-obe.outbound.protection.outlook.com) ([207.46.51.88]) by relmlii1.idc.renesas.com with ESMTP/TLS/AES256-SHA; 22 Apr 2015 17:51:23 +0900 Authentication-Results: suse.de; dkim=none (message not signed) header.d=none; Received: from morimoto-PC.renesas.com (211.11.155.132) by SIXPR06MB318.apcprd06.prod.outlook.com (10.141.125.144) with Microsoft SMTP Server (TLS) id 15.1.136.25; Wed, 22 Apr 2015 08:51:21 +0000 Message-ID: <87383sh7i6.wl%kuninori.morimoto.gx@renesas.com> From: Kuninori Morimoto To: Takashi Iwai , Mark Brown , Lars-Peter Clausen User-Agent: Wanderlust/2.15.9 Emacs/24.3 Mule/6.0 MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Date: Wed, 22 Apr 2015 08:51:21 +0000 X-Originating-IP: [211.11.155.132] X-ClientProxiedBy: OS2PR01CA0035.jpnprd01.prod.outlook.com (25.164.161.145) To SIXPR06MB318.apcprd06.prod.outlook.com (10.141.125.144) X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:SIXPR06MB318; X-Microsoft-Antispam-PRVS: X-Forefront-Antispam-Report: BMV:1; SFV:NSPM; SFS:(10019020)(6009001)(40100003)(87976001)(83506001)(92566002)(50466002)(54356999)(66066001)(42186005)(47776003)(46406003)(19580395003)(229853001)(36756003)(4001350100001)(23726002)(62966003)(77096005)(122386002)(575784001)(46102003)(5890100001)(50986999)(77156002)(15975445007)(53416004)(19580405001)(86362001)(33646002)(5001770100001)(21314002); DIR:OUT; SFP:1102; SCL:1; SRVR:SIXPR06MB318; H:morimoto-PC.renesas.com; FPR:; SPF:None; MLV:sfv; LANG:en; X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(5005006)(5002010); SRVR:SIXPR06MB318; BCL:0; PCL:0; RULEID:; SRVR:SIXPR06MB318; X-Forefront-PRVS: 0554B1F54F X-OriginatorOrg: renesas.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Apr 2015 08:51:21.9112 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: SIXPR06MB318 Cc: Linux-ALSA Subject: [alsa-devel] [RFC] bind/unbind SoC devices with deferred list X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP Hi Takashi, Mark, Lars I worked for bind/unbind issue which was discussed before http://thread.gmane.org/gmane.linux.alsa.devel/134062/focus=134076 http://thread.gmane.org/gmane.linux.alsa.devel/134283/focus=134287 I would like to know your opinion before sending patch to Greg The problem is ASoC has card/platform/cpu/codec relationship for each other, but, we can unbind one of them, and then, other related devices doesn't know about it. Thus, kernel will error if we use sound after that. Here is example of this issue. It unbind cpu (= rcar_sound), playback sound, and, error. And, we can't re-bind after this. // check current sound card > aplay -l **** List of PLAYBACK Hardware Devices **** card 0: rsnddai0ak4642h [rsnd-dai.0-ak4642-hifi], device 0: rsnd-dai.0-ak4642-hifi ak4642-hifi-0 [] Subdevices: 1/1 Subdevice #0: subdevice #0 // unbind cpu (= rcar_sound) > echo ec500000.rcar_sound > /sys/bus/platform/drivers/rcar_sound/unbind // recheck sound card // card doesn't know cpu was removed > aplay -l **** List of PLAYBACK Hardware Devices **** card 0: rsnddai0ak4642h [rsnd-dai.0-ak4642-hifi], device 0: rsnd-dai.0-ak4642-hifi ak4642-hifi-0 [] Subdevices: 1/1 Subdevice #0: subdevice #0 // kernel error happen if playback > aplay xxx.wav Unable to handle kernel NULL pointer dereference at virtual address 00000100 pgd = ee97c000 ... // we can't re-bind cpu > echo ec500000.rcar_sound > /sys/bus/platform/drivers/rcar_sound/bind -- freeze -- I hacked this issue to using deferred list, and created attached patch. it is all-in-one patch. but it solved my issue. I would like to know your opinion about this. // check current sound card > aplay -l **** List of PLAYBACK Hardware Devices **** card 0: rsnddai0ak4642h [rsnd-dai.0-ak4642-hifi], device 0: rsnd-dai.0-ak4642-hifi ak4642-hifi-0 [] Subdevices: 1/1 Subdevice #0: subdevice #0 // unbind cpu (= rcar_sound) > echo ec500000.rcar_sound > /sys/bus/platform/drivers/rcar_sound/unbind (local debug message) release ec500000.rcar_sound (local debug message) release related device - sound (local debug message) related related device - 6-0012 // recheck sound card // it knows there is no available card > aplay -l aplay: device_list:268: no soundcards found... // re-bind lost cpu (= rcar_sound) // it re-bind sound card > echo ec500000.rcar_sound > /sys/bus/platform/drivers/rcar_sound/bind rcar_sound ec500000.rcar_sound: probed asoc-simple-card sound: ak4642-hifi <-> ec500000.rcar_sound mapping ok // let's unbind codec side (= ak4642) this time > echo 6-0012 > /sys/bus/i2c/drivers/ak4642-codec/unbind (local debug message) release 6-0012 (local debug message) release related device - ec500000.rcar_sound (local debug message) related related device - sound // recheck sound card // it knows there is no available card > aplay -l aplay: device_list:268: no soundcards found... // re-bind lost codec (= ak4642) // it re-bind sound card > echo 6-0012 > /sys/bus/i2c/drivers/ak4642-codec/bind rcar_sound ec500000.rcar_sound: probed asoc-simple-card sound: ak4642-hifi <-> ec500000.rcar_sound mapping ok --- patch --- From 9da5324a659ff596a2733f14b768b6b8c5a04f3b Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 22 Apr 2015 16:53:49 +0900 Subject: [PATCH] no Subject at this point Signed-off-by: Kuninori Morimoto --- drivers/base/base.h | 1 + drivers/base/core.c | 9 +++++++++ drivers/base/dd.c | 21 ++++++++++++++++++++- include/linux/device.h | 1 + sound/soc/soc-core.c | 4 ++++ 5 files changed, 35 insertions(+), 1 deletion(-) diff --git a/drivers/base/base.h b/drivers/base/base.h index 251c5d3..1a71a52 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -74,6 +74,7 @@ struct device_private { struct klist_node knode_driver; struct klist_node knode_bus; struct list_head deferred_probe; + struct list_head related_dev; struct device *device; }; #define to_device_private_parent(obj) \ diff --git a/drivers/base/core.c b/drivers/base/core.c index 21d1303..643146f 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -948,9 +948,18 @@ int device_private_init(struct device *dev) klist_init(&dev->p->klist_children, klist_children_get, klist_children_put); INIT_LIST_HEAD(&dev->p->deferred_probe); + INIT_LIST_HEAD(&dev->p->related_dev); + return 0; } +void device_related_device(struct device *dev, struct device *node) +{ + if (list_empty(&node->p->related_dev)) + list_add(&node->p->related_dev, &dev->p->related_dev); +} +EXPORT_SYMBOL_GPL(device_related_device); + /** * device_add - add device to device hierarchy. * @dev: device. diff --git a/drivers/base/dd.c b/drivers/base/dd.c index e843fdb..3d218c6 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -516,7 +516,7 @@ EXPORT_SYMBOL_GPL(driver_attach); * __device_release_driver() must be called with @dev lock held. * When called for a USB interface, @dev->parent lock must be held as well. */ -static void __device_release_driver(struct device *dev) +static void _device_release_driver(struct device *dev) { struct device_driver *drv; @@ -552,6 +552,25 @@ static void __device_release_driver(struct device *dev) } } +static void __device_release_driver(struct device *dev) +{ + struct device_private *dp, *d; + + /* release dev itself */ + _device_release_driver(dev); + + list_for_each_entry_safe(dp, d, &dev->p->related_dev, related_dev) { + /* + * temporarily, release related device. + * these are push to deferred_probe_pending_list. + * It can be re-probed if it didn't call device_del() + */ + _device_release_driver(dp->device); + driver_deferred_probe_add(dp->device); + list_del_init(&dp->related_dev); + } +} + /** * device_release_driver - manually detach device from driver. * @dev: device. diff --git a/include/linux/device.h b/include/linux/device.h index 6558af9..2b81804 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -924,6 +924,7 @@ void driver_init(void); extern int __must_check device_register(struct device *dev); extern void device_unregister(struct device *dev); extern void device_initialize(struct device *dev); +extern void device_related_device(struct device *dev, struct device *node); extern int __must_check device_add(struct device *dev); extern void device_del(struct device *dev); extern int device_for_each_child(struct device *dev, void *data, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 2373252..01c0d56 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -22,6 +22,7 @@ * o Support TDM on PCM and I2S */ +#include #include #include #include @@ -946,6 +947,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) dai_link->cpu_dai_name); return -EPROBE_DEFER; } + device_related_device(card->dev, rtd->cpu_dai->dev); rtd->num_codecs = dai_link->num_codecs; @@ -962,6 +964,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) /* Single codec links expect codec and codec_dai in runtime data */ rtd->codec_dai = codec_dais[0]; rtd->codec = rtd->codec_dai->codec; + device_related_device(card->dev, rtd->codec->dev); /* if there's no platform we match on the empty platform */ platform_name = dai_link->platform_name; @@ -986,6 +989,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) dai_link->platform_name); return -EPROBE_DEFER; } + device_related_device(card->dev, rtd->platform->dev); card->num_rtd++;