Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d94a0147 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'for-davem' of git://gitorious.org/linux-can/linux-can-next



Marc Kleine-Budde says:

====================
this pull-request for net-next consists of a series by Alexander
Shiyan, he cleans up the mcp251x driver. As the first patch touches
arch/arm/mach-pxa, it's acked by Haojian Zhuang.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 327dfd88 b1ef05a5
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -73,9 +73,6 @@ static struct pxa2xx_spi_chip mcp251x_chip_info4 = {

static struct mcp251x_platform_data mcp251x_info = {
	.oscillator_frequency = 16E6,
	.board_specific_setup = NULL,
	.power_enable         = NULL,
	.transceiver_enable   = NULL
};

static struct spi_board_info mcp251x_board_info[] = {
+25 −21
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@
#include <linux/i2c/pca953x.h>
#include <linux/apm-emulation.h>
#include <linux/can/platform/mcp251x.h>
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>

#include <asm/mach-types.h>
#include <asm/suspend.h>
@@ -391,33 +393,34 @@ static struct pxa2xx_spi_master pxa2xx_spi_ssp3_master_info = {
};

/* CAN bus on SPI */
static int zeus_mcp2515_setup(struct spi_device *sdev)
{
	int err;
static struct regulator_consumer_supply can_regulator_consumer =
	REGULATOR_SUPPLY("vdd", "spi3.0");

	err = gpio_request(ZEUS_CAN_SHDN_GPIO, "CAN shutdown");
	if (err)
		return err;

	err = gpio_direction_output(ZEUS_CAN_SHDN_GPIO, 1);
	if (err) {
		gpio_free(ZEUS_CAN_SHDN_GPIO);
		return err;
	}
static struct regulator_init_data can_regulator_init_data = {
	.constraints	= {
		.valid_ops_mask	= REGULATOR_CHANGE_STATUS,
	},
	.consumer_supplies	= &can_regulator_consumer,
	.num_consumer_supplies	= 1,
};

	return 0;
}
static struct fixed_voltage_config can_regulator_pdata = {
	.supply_name	= "CAN_SHDN",
	.microvolts	= 3300000,
	.gpio		= ZEUS_CAN_SHDN_GPIO,
	.init_data	= &can_regulator_init_data,
};

static int zeus_mcp2515_transceiver_enable(int enable)
{
	gpio_set_value(ZEUS_CAN_SHDN_GPIO, !enable);
	return 0;
}
static struct platform_device can_regulator_device = {
	.name	= "reg-fixed-volage",
	.id	= -1,
	.dev	= {
		.platform_data	= &can_regulator_pdata,
	},
};

static struct mcp251x_platform_data zeus_mcp2515_pdata = {
	.oscillator_frequency	= 16*1000*1000,
	.board_specific_setup	= zeus_mcp2515_setup,
	.power_enable		= zeus_mcp2515_transceiver_enable,
};

static struct spi_board_info zeus_spi_board_info[] = {
@@ -516,6 +519,7 @@ static struct platform_device *zeus_devices[] __initdata = {
	&zeus_leds_device,
	&zeus_pcmcia_device,
	&zeus_max6369_device,
	&can_regulator_device,
};

/* AC'97 */
+49 −49
Original line number Diff line number Diff line
@@ -37,9 +37,6 @@
 *
 * static struct mcp251x_platform_data mcp251x_info = {
 *         .oscillator_frequency = 8000000,
 *         .board_specific_setup = &mcp251x_setup,
 *         .power_enable = mcp251x_power_enable,
 *         .transceiver_enable = NULL,
 * };
 *
 * static struct spi_board_info spi_board_info[] = {
@@ -76,6 +73,7 @@
#include <linux/slab.h>
#include <linux/spi/spi.h>
#include <linux/uaccess.h>
#include <linux/regulator/consumer.h>

/* SPI interface instruction set */
#define INSTRUCTION_WRITE	0x02
@@ -264,6 +262,8 @@ struct mcp251x_priv {
#define AFTER_SUSPEND_POWER 4
#define AFTER_SUSPEND_RESTART 8
	int restart_tx;
	struct regulator *power;
	struct regulator *transceiver;
};

#define MCP251X_IS(_model) \
@@ -667,16 +667,25 @@ static int mcp251x_hw_probe(struct spi_device *spi)
	return (st1 == 0x80 && st2 == 0x07) ? 1 : 0;
}

static int mcp251x_power_enable(struct regulator *reg, int enable)
{
	if (IS_ERR(reg))
		return 0;

	if (enable)
		return regulator_enable(reg);
	else
		return regulator_disable(reg);
}

static void mcp251x_open_clean(struct net_device *net)
{
	struct mcp251x_priv *priv = netdev_priv(net);
	struct spi_device *spi = priv->spi;
	struct mcp251x_platform_data *pdata = spi->dev.platform_data;

	free_irq(spi->irq, priv);
	mcp251x_hw_sleep(spi);
	if (pdata->transceiver_enable)
		pdata->transceiver_enable(0);
	mcp251x_power_enable(priv->transceiver, 0);
	close_candev(net);
}

@@ -684,7 +693,6 @@ static int mcp251x_stop(struct net_device *net)
{
	struct mcp251x_priv *priv = netdev_priv(net);
	struct spi_device *spi = priv->spi;
	struct mcp251x_platform_data *pdata = spi->dev.platform_data;

	close_candev(net);

@@ -704,8 +712,7 @@ static int mcp251x_stop(struct net_device *net)

	mcp251x_hw_sleep(spi);

	if (pdata->transceiver_enable)
		pdata->transceiver_enable(0);
	mcp251x_power_enable(priv->transceiver, 0);

	priv->can.state = CAN_STATE_STOPPED;

@@ -928,8 +935,7 @@ static int mcp251x_open(struct net_device *net)
{
	struct mcp251x_priv *priv = netdev_priv(net);
	struct spi_device *spi = priv->spi;
	struct mcp251x_platform_data *pdata = spi->dev.platform_data;
	unsigned long flags;
	unsigned long flags = IRQF_ONESHOT | IRQF_TRIGGER_FALLING;
	int ret;

	ret = open_candev(net);
@@ -939,25 +945,17 @@ static int mcp251x_open(struct net_device *net)
	}

	mutex_lock(&priv->mcp_lock);
	if (pdata->transceiver_enable)
		pdata->transceiver_enable(1);
	mcp251x_power_enable(priv->transceiver, 1);

	priv->force_quit = 0;
	priv->tx_skb = NULL;
	priv->tx_len = 0;

	flags = IRQF_ONESHOT;
	if (pdata->irq_flags)
		flags |= pdata->irq_flags;
	else
		flags |= IRQF_TRIGGER_FALLING;

	ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist,
				   flags, DEVICE_NAME, priv);
	if (ret) {
		dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);
		if (pdata->transceiver_enable)
			pdata->transceiver_enable(0);
		mcp251x_power_enable(priv->transceiver, 0);
		close_candev(net);
		goto open_unlock;
	}
@@ -1026,6 +1024,19 @@ static int mcp251x_can_probe(struct spi_device *spi)
		CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY;
	priv->model = spi_get_device_id(spi)->driver_data;
	priv->net = net;

	priv->power = devm_regulator_get(&spi->dev, "vdd");
	priv->transceiver = devm_regulator_get(&spi->dev, "xceiver");
	if ((PTR_ERR(priv->power) == -EPROBE_DEFER) ||
	    (PTR_ERR(priv->transceiver) == -EPROBE_DEFER)) {
		ret = -EPROBE_DEFER;
		goto error_power;
	}

	ret = mcp251x_power_enable(priv->power, 1);
	if (ret)
		goto error_power;

	spi_set_drvdata(spi, priv);

	priv->spi = spi;
@@ -1068,30 +1079,24 @@ static int mcp251x_can_probe(struct spi_device *spi)
		}
	}

	if (pdata->power_enable)
		pdata->power_enable(1);

	/* Call out to platform specific setup */
	if (pdata->board_specific_setup)
		pdata->board_specific_setup(spi);

	SET_NETDEV_DEV(net, &spi->dev);

	/* Configure the SPI bus */
	spi->mode = SPI_MODE_0;
	spi->mode = spi->mode ? : SPI_MODE_0;
	if (mcp251x_is_2510(spi))
		spi->max_speed_hz = spi->max_speed_hz ? : 5 * 1000 * 1000;
	else
		spi->max_speed_hz = spi->max_speed_hz ? : 10 * 1000 * 1000;
	spi->bits_per_word = 8;
	spi_setup(spi);

	/* Here is OK to not lock the MCP, no one knows about it yet */
	if (!mcp251x_hw_probe(spi)) {
		dev_info(&spi->dev, "Probe failed\n");
		ret = -ENODEV;
		goto error_probe;
	}
	mcp251x_hw_sleep(spi);

	if (pdata->transceiver_enable)
		pdata->transceiver_enable(0);

	ret = register_candev(net);
	if (ret)
		goto error_probe;
@@ -1109,13 +1114,13 @@ static int mcp251x_can_probe(struct spi_device *spi)
	if (!mcp251x_enable_dma)
		kfree(priv->spi_tx_buf);
error_tx_buf:
	free_candev(net);
	if (mcp251x_enable_dma)
		dma_free_coherent(&spi->dev, PAGE_SIZE,
				  priv->spi_tx_buf, priv->spi_tx_dma);
	mcp251x_power_enable(priv->power, 0);
error_power:
	free_candev(net);
error_alloc:
	if (pdata->power_enable)
		pdata->power_enable(0);
	dev_err(&spi->dev, "probe failed\n");
error_out:
	return ret;
@@ -1123,12 +1128,10 @@ static int mcp251x_can_probe(struct spi_device *spi)

static int mcp251x_can_remove(struct spi_device *spi)
{
	struct mcp251x_platform_data *pdata = spi->dev.platform_data;
	struct mcp251x_priv *priv = spi_get_drvdata(spi);
	struct net_device *net = priv->net;

	unregister_candev(net);
	free_candev(net);

	if (mcp251x_enable_dma) {
		dma_free_coherent(&spi->dev, PAGE_SIZE,
@@ -1138,8 +1141,9 @@ static int mcp251x_can_remove(struct spi_device *spi)
		kfree(priv->spi_rx_buf);
	}

	if (pdata->power_enable)
		pdata->power_enable(0);
	mcp251x_power_enable(priv->power, 0);

	free_candev(net);

	return 0;
}
@@ -1149,7 +1153,6 @@ static int mcp251x_can_remove(struct spi_device *spi)
static int mcp251x_can_suspend(struct device *dev)
{
	struct spi_device *spi = to_spi_device(dev);
	struct mcp251x_platform_data *pdata = spi->dev.platform_data;
	struct mcp251x_priv *priv = spi_get_drvdata(spi);
	struct net_device *net = priv->net;

@@ -1163,15 +1166,14 @@ static int mcp251x_can_suspend(struct device *dev)
		netif_device_detach(net);

		mcp251x_hw_sleep(spi);
		if (pdata->transceiver_enable)
			pdata->transceiver_enable(0);
		mcp251x_power_enable(priv->transceiver, 0);
		priv->after_suspend = AFTER_SUSPEND_UP;
	} else {
		priv->after_suspend = AFTER_SUSPEND_DOWN;
	}

	if (pdata->power_enable) {
		pdata->power_enable(0);
	if (!IS_ERR(priv->power)) {
		regulator_disable(priv->power);
		priv->after_suspend |= AFTER_SUSPEND_POWER;
	}

@@ -1181,16 +1183,14 @@ static int mcp251x_can_suspend(struct device *dev)
static int mcp251x_can_resume(struct device *dev)
{
	struct spi_device *spi = to_spi_device(dev);
	struct mcp251x_platform_data *pdata = spi->dev.platform_data;
	struct mcp251x_priv *priv = spi_get_drvdata(spi);

	if (priv->after_suspend & AFTER_SUSPEND_POWER) {
		pdata->power_enable(1);
		mcp251x_power_enable(priv->power, 1);
		queue_work(priv->wq, &priv->restart_work);
	} else {
		if (priv->after_suspend & AFTER_SUSPEND_UP) {
			if (pdata->transceiver_enable)
				pdata->transceiver_enable(1);
			mcp251x_power_enable(priv->transceiver, 1);
			queue_work(priv->wq, &priv->restart_work);
		} else {
			priv->after_suspend = 0;
+1 −14
Original line number Diff line number Diff line
@@ -9,26 +9,13 @@

#include <linux/spi/spi.h>

/**
/*
 * struct mcp251x_platform_data - MCP251X SPI CAN controller platform data
 * @oscillator_frequency:       - oscillator frequency in Hz
 * @irq_flags:                  - IRQF configuration flags
 * @board_specific_setup:       - called before probing the chip (power,reset)
 * @transceiver_enable:         - called to power on/off the transceiver
 * @power_enable:               - called to power on/off the mcp *and* the
 *                                transceiver
 *
 * Please note that you should define power_enable or transceiver_enable or
 * none of them. Defining both of them is no use.
 *
 */

struct mcp251x_platform_data {
	unsigned long oscillator_frequency;
	unsigned long irq_flags;
	int (*board_specific_setup)(struct spi_device *spi);
	int (*transceiver_enable)(int enable);
	int (*power_enable) (int enable);
};

#endif /* __CAN_PLATFORM_MCP251X_H__ */