Skip to content

Commit

Permalink
caif-hsi: Postpone init of HSI until open()
Browse files Browse the repository at this point in the history
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: Sjur Brændeland <sjur.brandeland@stericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
sjur.brandeland@stericsson.com authored and David S. Miller committed Apr 13, 2012
1 parent 2df1fe7 commit 39abbae
Showing 1 changed file with 45 additions and 52 deletions.
97 changes: 45 additions & 52 deletions drivers/net/caif/caif_hsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
* License terms: GNU General Public License (GPL) version 2.
*/

#define pr_fmt(fmt) KBUILD_MODNAME fmt

#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
Expand Down Expand Up @@ -1127,21 +1129,7 @@ static int cfhsi_xmit(struct sk_buff *skb, struct net_device *dev)
return 0;
}

static int cfhsi_open(struct net_device *dev)
{
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 const struct net_device_ops cfhsi_ops;

static void cfhsi_setup(struct net_device *dev)
{
Expand All @@ -1167,7 +1155,7 @@ int cfhsi_probe(struct platform_device *pdev)
{
struct cfhsi *cfhsi = NULL;
struct net_device *ndev;
struct cfhsi_dev *dev;

int res;

ndev = alloc_netdev(sizeof(struct cfhsi), "cfhsi%d", cfhsi_setup);
Expand All @@ -1178,6 +1166,34 @@ int cfhsi_probe(struct platform_device *pdev)
cfhsi->ndev = ndev;
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. */
cfhsi->tx_state = CFHSI_TX_STATE_IDLE;
cfhsi->rx_state.state = CFHSI_RX_STATE_DESC;
Expand All @@ -1187,12 +1203,6 @@ int cfhsi_probe(struct platform_device *pdev)
cfhsi->q_low_mark = LOW_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
Expand Down Expand Up @@ -1260,9 +1270,9 @@ int cfhsi_probe(struct platform_device *pdev)
clear_bit(CFHSI_AWAKE, &cfhsi->bits);

/* Create work thread. */
cfhsi->wq = create_singlethread_workqueue(pdev->name);
cfhsi->wq = create_singlethread_workqueue(cfhsi->pdev->name);
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__);
res = -ENODEV;
goto err_create_wq;
Expand All @@ -1286,11 +1296,6 @@ int cfhsi_probe(struct platform_device *pdev)
cfhsi->aggregation_timer.data = (unsigned long)cfhsi;
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. */
res = cfhsi->dev->cfhsi_up(cfhsi->dev);
if (res) {
Expand All @@ -1303,15 +1308,7 @@ int cfhsi_probe(struct platform_device *pdev)
/* Flush FIFO */
res = cfhsi_flush_fifo(cfhsi);
if (res) {
dev_err(&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",
dev_err(&cfhsi->ndev->dev, "%s: Can't flush FIFO: %d.\n",
__func__, res);
goto err_net_reg;
}
Expand All @@ -1328,13 +1325,12 @@ int cfhsi_probe(struct platform_device *pdev)
err_alloc_rx:
kfree(cfhsi->tx_buf);
err_alloc_tx:
free_netdev(ndev);

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;

/* going to shutdown driver */
Expand Down Expand Up @@ -1364,15 +1360,19 @@ static void cfhsi_shutdown(struct cfhsi *cfhsi)
/* Deactivate interface */
cfhsi->dev->cfhsi_down(cfhsi->dev);

/* Finally unregister the network device. */
unregister_netdev(cfhsi->ndev);

/* Free buffers. */
kfree(tx_buf);
kfree(rx_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)
{
struct list_head *list_node;
Expand All @@ -1389,10 +1389,6 @@ int cfhsi_remove(struct platform_device *pdev)
/* Remove from list. */
list_del(list_node);
spin_unlock(&cfhsi_list_lock);

/* Shutdown driver. */
cfhsi_shutdown(cfhsi);

return 0;
}
}
Expand Down Expand Up @@ -1423,8 +1419,7 @@ static void __exit cfhsi_exit_module(void)
list_del(list_node);
spin_unlock(&cfhsi_list_lock);

/* Shutdown driver. */
cfhsi_shutdown(cfhsi);
unregister_netdevice(cfhsi->ndev);

spin_lock(&cfhsi_list_lock);
}
Expand All @@ -1449,8 +1444,6 @@ static int __init cfhsi_init_module(void)
goto err_dev_register;
}

return result;

err_dev_register:
return result;
}
Expand Down

0 comments on commit 39abbae

Please sign in to comment.