msm: smd_pkt: Register the platform driver while performing open operation
Defer registering the platform driver for an SMD channel until the SMD_PKT
driver open operation is invoked.
Previously during initializaton, SMD_PKT driver would register a platform
driver for all SMD channels in the configuration table. This prevented
other drivers from being able to register for the same SMD channel, even
if the SMD_PKT driver never uses that channel.
Change-Id: Ie9b80329093c0b14bf0f74280fb30bdd3d3aa7a9
Signed-off-by: Karthikeyan Ramasubramanian <kramasub@codeaurora.org>
diff --git a/arch/arm/mach-msm/smd_pkt.c b/arch/arm/mach-msm/smd_pkt.c
index 158015a..542d224 100644
--- a/arch/arm/mach-msm/smd_pkt.c
+++ b/arch/arm/mach-msm/smd_pkt.c
@@ -622,13 +622,25 @@
mutex_lock(&smd_pkt_devp->ch_lock);
if (smd_pkt_devp->ch == 0) {
+ init_completion(&smd_pkt_devp->ch_allocated);
+ smd_pkt_devp->driver.probe = smd_pkt_dummy_probe;
+ smd_pkt_devp->driver.driver.name =
+ smd_ch_name[smd_pkt_devp->i];
+ smd_pkt_devp->driver.driver.owner = THIS_MODULE;
+ r = platform_driver_register(&smd_pkt_devp->driver);
+ if (r) {
+ pr_err("%s: %s Platform driver reg. failed\n",
+ __func__, smd_ch_name[smd_pkt_devp->i]);
+ goto out;
+ }
+
peripheral = smd_edge_to_subsystem(
smd_ch_edge[smd_pkt_devp->i]);
if (peripheral) {
smd_pkt_devp->pil = pil_get(peripheral);
if (IS_ERR(smd_pkt_devp->pil)) {
r = PTR_ERR(smd_pkt_devp->pil);
- goto out;
+ goto release_pd;
}
/* Wait for the modem SMSM to be inited for the SMD
@@ -697,6 +709,10 @@
release_pil:
if (peripheral && (r < 0))
pil_put(smd_pkt_devp->pil);
+
+release_pd:
+ if (r < 0)
+ platform_driver_unregister(&smd_pkt_devp->driver);
out:
mutex_unlock(&smd_pkt_devp->ch_lock);
@@ -722,6 +738,7 @@
smd_pkt_devp->ch = 0;
smd_pkt_devp->blocking_write = 0;
smd_pkt_devp->poll_mode = 0;
+ platform_driver_unregister(&smd_pkt_devp->driver);
if (smd_pkt_devp->pil)
pil_put(smd_pkt_devp->pil);
}
@@ -798,7 +815,6 @@
mutex_init(&smd_pkt_devp[i]->ch_lock);
mutex_init(&smd_pkt_devp[i]->rx_lock);
mutex_init(&smd_pkt_devp[i]->tx_lock);
- init_completion(&smd_pkt_devp[i]->ch_allocated);
cdev_init(&smd_pkt_devp[i]->cdev, &smd_pkt_fops);
smd_pkt_devp[i]->cdev.owner = THIS_MODULE;
@@ -839,13 +855,6 @@
&dev_attr_open_timeout))
pr_err("%s: unable to create device attr on #%d\n",
__func__, i);
-
- smd_pkt_devp[i]->driver.probe = smd_pkt_dummy_probe;
- smd_pkt_devp[i]->driver.driver.name = smd_ch_name[i];
- smd_pkt_devp[i]->driver.driver.owner = THIS_MODULE;
- r = platform_driver_register(&smd_pkt_devp[i]->driver);
- if (r)
- goto error2;
}
INIT_DELAYED_WORK(&loopback_work, loopback_probe_worker);
@@ -856,7 +865,6 @@
error2:
if (i > 0) {
while (--i >= 0) {
- platform_driver_unregister(&smd_pkt_devp[i]->driver);
cdev_del(&smd_pkt_devp[i]->cdev);
kfree(smd_pkt_devp[i]);
device_destroy(smd_pkt_classp,
@@ -876,7 +884,6 @@
int i;
for (i = 0; i < NUM_SMD_PKT_PORTS; ++i) {
- platform_driver_unregister(&smd_pkt_devp[i]->driver);
cdev_del(&smd_pkt_devp[i]->cdev);
kfree(smd_pkt_devp[i]);
device_destroy(smd_pkt_classp,