Commit 39abbaef authored by sjur.brandeland@stericsson.com's avatar sjur.brandeland@stericsson.com Committed by David S. Miller

caif-hsi: Postpone init of HSI until open()

Do the initialization of the HSI interface when the
interface is opened, instead of upon registration.
When the interface is closed the HSI interface is
de-initialized, allowing other modules to use the
HSI interface.
Signed-off-by: default avatarSjur Brændeland <sjur.brandeland@stericsson.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2df1fe7f
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
* License terms: GNU General Public License (GPL) version 2. * License terms: GNU General Public License (GPL) version 2.
*/ */
#define pr_fmt(fmt) KBUILD_MODNAME fmt
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/device.h> #include <linux/device.h>
...@@ -1127,21 +1129,7 @@ static int cfhsi_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1127,21 +1129,7 @@ static int cfhsi_xmit(struct sk_buff *skb, struct net_device *dev)
return 0; return 0;
} }
static int cfhsi_open(struct net_device *dev) static const struct net_device_ops cfhsi_ops;
{
return 0;
}
static int cfhsi_close(struct net_device *dev)
{
return 0;
}
static const struct net_device_ops cfhsi_ops = {
.ndo_open = cfhsi_open,
.ndo_stop = cfhsi_close,
.ndo_start_xmit = cfhsi_xmit
};
static void cfhsi_setup(struct net_device *dev) static void cfhsi_setup(struct net_device *dev)
{ {
...@@ -1167,7 +1155,7 @@ int cfhsi_probe(struct platform_device *pdev) ...@@ -1167,7 +1155,7 @@ int cfhsi_probe(struct platform_device *pdev)
{ {
struct cfhsi *cfhsi = NULL; struct cfhsi *cfhsi = NULL;
struct net_device *ndev; struct net_device *ndev;
struct cfhsi_dev *dev;
int res; int res;
ndev = alloc_netdev(sizeof(struct cfhsi), "cfhsi%d", cfhsi_setup); ndev = alloc_netdev(sizeof(struct cfhsi), "cfhsi%d", cfhsi_setup);
...@@ -1178,6 +1166,34 @@ int cfhsi_probe(struct platform_device *pdev) ...@@ -1178,6 +1166,34 @@ int cfhsi_probe(struct platform_device *pdev)
cfhsi->ndev = ndev; cfhsi->ndev = ndev;
cfhsi->pdev = pdev; cfhsi->pdev = pdev;
/* Assign the HSI device. */
cfhsi->dev = pdev->dev.platform_data;
/* Assign the driver to this HSI device. */
cfhsi->dev->drv = &cfhsi->drv;
/* Register network device. */
res = register_netdev(ndev);
if (res) {
dev_err(&ndev->dev, "%s: Registration error: %d.\n",
__func__, res);
free_netdev(ndev);
}
/* Add CAIF HSI device to list. */
spin_lock(&cfhsi_list_lock);
list_add_tail(&cfhsi->list, &cfhsi_list);
spin_unlock(&cfhsi_list_lock);
return res;
}
static int cfhsi_open(struct net_device *ndev)
{
struct cfhsi *cfhsi = netdev_priv(ndev);
int res;
clear_bit(CFHSI_SHUTDOWN, &cfhsi->bits);
/* Initialize state vaiables. */ /* Initialize state vaiables. */
cfhsi->tx_state = CFHSI_TX_STATE_IDLE; cfhsi->tx_state = CFHSI_TX_STATE_IDLE;
cfhsi->rx_state.state = CFHSI_RX_STATE_DESC; cfhsi->rx_state.state = CFHSI_RX_STATE_DESC;
...@@ -1187,12 +1203,6 @@ int cfhsi_probe(struct platform_device *pdev) ...@@ -1187,12 +1203,6 @@ int cfhsi_probe(struct platform_device *pdev)
cfhsi->q_low_mark = LOW_WATER_MARK; cfhsi->q_low_mark = LOW_WATER_MARK;
cfhsi->q_high_mark = HIGH_WATER_MARK; cfhsi->q_high_mark = HIGH_WATER_MARK;
/* Assign the HSI device. */
dev = (struct cfhsi_dev *)pdev->dev.platform_data;
cfhsi->dev = dev;
/* Assign the driver to this HSI device. */
dev->drv = &cfhsi->drv;
/* /*
* Allocate a TX buffer with the size of a HSI packet descriptors * Allocate a TX buffer with the size of a HSI packet descriptors
...@@ -1260,9 +1270,9 @@ int cfhsi_probe(struct platform_device *pdev) ...@@ -1260,9 +1270,9 @@ int cfhsi_probe(struct platform_device *pdev)
clear_bit(CFHSI_AWAKE, &cfhsi->bits); clear_bit(CFHSI_AWAKE, &cfhsi->bits);
/* Create work thread. */ /* Create work thread. */
cfhsi->wq = create_singlethread_workqueue(pdev->name); cfhsi->wq = create_singlethread_workqueue(cfhsi->pdev->name);
if (!cfhsi->wq) { if (!cfhsi->wq) {
dev_err(&ndev->dev, "%s: Failed to create work queue.\n", dev_err(&cfhsi->ndev->dev, "%s: Failed to create work queue.\n",
__func__); __func__);
res = -ENODEV; res = -ENODEV;
goto err_create_wq; goto err_create_wq;
...@@ -1286,11 +1296,6 @@ int cfhsi_probe(struct platform_device *pdev) ...@@ -1286,11 +1296,6 @@ int cfhsi_probe(struct platform_device *pdev)
cfhsi->aggregation_timer.data = (unsigned long)cfhsi; cfhsi->aggregation_timer.data = (unsigned long)cfhsi;
cfhsi->aggregation_timer.function = cfhsi_aggregation_tout; cfhsi->aggregation_timer.function = cfhsi_aggregation_tout;
/* Add CAIF HSI device to list. */
spin_lock(&cfhsi_list_lock);
list_add_tail(&cfhsi->list, &cfhsi_list);
spin_unlock(&cfhsi_list_lock);
/* Activate HSI interface. */ /* Activate HSI interface. */
res = cfhsi->dev->cfhsi_up(cfhsi->dev); res = cfhsi->dev->cfhsi_up(cfhsi->dev);
if (res) { if (res) {
...@@ -1303,15 +1308,7 @@ int cfhsi_probe(struct platform_device *pdev) ...@@ -1303,15 +1308,7 @@ int cfhsi_probe(struct platform_device *pdev)
/* Flush FIFO */ /* Flush FIFO */
res = cfhsi_flush_fifo(cfhsi); res = cfhsi_flush_fifo(cfhsi);
if (res) { if (res) {
dev_err(&ndev->dev, "%s: Can't flush FIFO: %d.\n", dev_err(&cfhsi->ndev->dev, "%s: Can't flush FIFO: %d.\n",
__func__, res);
goto err_net_reg;
}
/* Register network device. */
res = register_netdev(ndev);
if (res) {
dev_err(&ndev->dev, "%s: Registration error: %d.\n",
__func__, res); __func__, res);
goto err_net_reg; goto err_net_reg;
} }
...@@ -1328,13 +1325,12 @@ int cfhsi_probe(struct platform_device *pdev) ...@@ -1328,13 +1325,12 @@ int cfhsi_probe(struct platform_device *pdev)
err_alloc_rx: err_alloc_rx:
kfree(cfhsi->tx_buf); kfree(cfhsi->tx_buf);
err_alloc_tx: err_alloc_tx:
free_netdev(ndev);
return res; return res;
} }
static void cfhsi_shutdown(struct cfhsi *cfhsi) static int cfhsi_close(struct net_device *ndev)
{ {
struct cfhsi *cfhsi = netdev_priv(ndev);
u8 *tx_buf, *rx_buf, *flip_buf; u8 *tx_buf, *rx_buf, *flip_buf;
/* going to shutdown driver */ /* going to shutdown driver */
...@@ -1364,15 +1360,19 @@ static void cfhsi_shutdown(struct cfhsi *cfhsi) ...@@ -1364,15 +1360,19 @@ static void cfhsi_shutdown(struct cfhsi *cfhsi)
/* Deactivate interface */ /* Deactivate interface */
cfhsi->dev->cfhsi_down(cfhsi->dev); cfhsi->dev->cfhsi_down(cfhsi->dev);
/* Finally unregister the network device. */
unregister_netdev(cfhsi->ndev);
/* Free buffers. */ /* Free buffers. */
kfree(tx_buf); kfree(tx_buf);
kfree(rx_buf); kfree(rx_buf);
kfree(flip_buf); kfree(flip_buf);
return 0;
} }
static const struct net_device_ops cfhsi_ops = {
.ndo_open = cfhsi_open,
.ndo_stop = cfhsi_close,
.ndo_start_xmit = cfhsi_xmit
};
int cfhsi_remove(struct platform_device *pdev) int cfhsi_remove(struct platform_device *pdev)
{ {
struct list_head *list_node; struct list_head *list_node;
...@@ -1389,10 +1389,6 @@ int cfhsi_remove(struct platform_device *pdev) ...@@ -1389,10 +1389,6 @@ int cfhsi_remove(struct platform_device *pdev)
/* Remove from list. */ /* Remove from list. */
list_del(list_node); list_del(list_node);
spin_unlock(&cfhsi_list_lock); spin_unlock(&cfhsi_list_lock);
/* Shutdown driver. */
cfhsi_shutdown(cfhsi);
return 0; return 0;
} }
} }
...@@ -1423,8 +1419,7 @@ static void __exit cfhsi_exit_module(void) ...@@ -1423,8 +1419,7 @@ static void __exit cfhsi_exit_module(void)
list_del(list_node); list_del(list_node);
spin_unlock(&cfhsi_list_lock); spin_unlock(&cfhsi_list_lock);
/* Shutdown driver. */ unregister_netdevice(cfhsi->ndev);
cfhsi_shutdown(cfhsi);
spin_lock(&cfhsi_list_lock); spin_lock(&cfhsi_list_lock);
} }
...@@ -1449,8 +1444,6 @@ static int __init cfhsi_init_module(void) ...@@ -1449,8 +1444,6 @@ static int __init cfhsi_init_module(void)
goto err_dev_register; goto err_dev_register;
} }
return result;
err_dev_register: err_dev_register:
return result; return result;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment