示例#1
0
static int bfin_sir_resume(struct platform_device *pdev)
{
	struct bfin_sir_port *sir_port;
	struct net_device *dev;
	struct bfin_sir_self *self;
	struct bfin_sir_port *port;

	sir_port = platform_get_drvdata(pdev);
	if (!sir_port)
		return 0;

	dev = sir_port->dev;
	self = netdev_priv(dev);
	port = self->sir_port;
	if (self->open) {
		if (self->newspeed) {
			self->speed = self->newspeed;
			self->newspeed = 0;
		}
		bfin_sir_startup(port, dev);
		bfin_sir_set_speed(port, 9600);
		bfin_sir_enable_rx(port);
		netif_device_attach(dev);
	}
	return 0;
}
示例#2
0
static irqreturn_t bfin_sir_dma_tx_int(int irq, void *dev_id)
{
	struct net_device *dev = dev_id;
	struct bfin_sir_self *self = netdev_priv(dev);
	struct bfin_sir_port *port = self->sir_port;

	spin_lock(&self->lock);
	if (!(get_dma_curr_irqstat(port->tx_dma_channel) & DMA_RUN)) {
		clear_dma_irqstat(port->tx_dma_channel);
		bfin_sir_stop_tx(port);

		self->stats.tx_packets++;
		self->stats.tx_bytes += self->tx_buff.len;
		self->tx_buff.len = 0;
		if (self->newspeed) {
			bfin_sir_set_speed(port, self->newspeed);
			self->speed = self->newspeed;
			self->newspeed = 0;
		}
		bfin_sir_enable_rx(port);
		/* I'm hungry! */
		netif_wake_queue(dev);
		port->tx_done = 1;
	}
	spin_unlock(&self->lock);

	return IRQ_HANDLED;
}
示例#3
0
static void bfin_sir_dma_tx_chars(struct net_device *dev)
{
	struct bfin_sir_self *self = netdev_priv(dev);
	struct bfin_sir_port *port = self->sir_port;

	if (!port->tx_done)
		return;
	port->tx_done = 0;

	if (self->tx_buff.len == 0) {
		self->stats.tx_packets++;
		if (self->newspeed) {
			bfin_sir_set_speed(port, self->newspeed);
			self->speed = self->newspeed;
			self->newspeed = 0;
		}
		bfin_sir_enable_rx(port);
		port->tx_done = 1;
		netif_wake_queue(dev);
		return;
	}

	blackfin_dcache_flush_range((unsigned long)(self->tx_buff.data),
		(unsigned long)(self->tx_buff.data+self->tx_buff.len));
	set_dma_config(port->tx_dma_channel,
		set_bfin_dma_config(DIR_READ, DMA_FLOW_STOP,
			INTR_ON_BUF, DIMENSION_LINEAR, DATA_SIZE_8,
			DMA_SYNC_RESTART));
	set_dma_start_addr(port->tx_dma_channel,
		(unsigned long)(self->tx_buff.data));
	set_dma_x_count(port->tx_dma_channel, self->tx_buff.len);
	set_dma_x_modify(port->tx_dma_channel, 1);
	enable_dma(port->tx_dma_channel);
}
示例#4
0
static void bfin_sir_tx_chars(struct net_device *dev)
{
	unsigned int chr;
	struct bfin_sir_self *self = netdev_priv(dev);
	struct bfin_sir_port *port = self->sir_port;

	if (self->tx_buff.len != 0) {
		chr = *(self->tx_buff.data);
		SIR_UART_PUT_CHAR(port, chr);
		self->tx_buff.data++;
		self->tx_buff.len--;
	} else {
		self->stats.tx_packets++;
		self->stats.tx_bytes += self->tx_buff.data - self->tx_buff.head;
		if (self->newspeed) {
			bfin_sir_set_speed(port, self->newspeed);
			self->speed = self->newspeed;
			self->newspeed = 0;
		}
		bfin_sir_stop_tx(port);
		bfin_sir_enable_rx(port);
		/* I'm hungry! */
		netif_wake_queue(dev);
	}
}
示例#5
0
static int bfin_sir_open(struct net_device *dev)
{
	struct bfin_sir_self *self = netdev_priv(dev);
	struct bfin_sir_port *port = self->sir_port;
	int err;

	self->newspeed = 0;
	self->speed = 9600;

	spin_lock_init(&self->lock);

	err = bfin_sir_startup(port, dev);
	if (err)
		goto err_startup;

	bfin_sir_set_speed(port, 9600);

	self->irlap = irlap_open(dev, &self->qos, DRIVER_NAME);
	if (!self->irlap) {
		err = -ENOMEM;
		goto err_irlap;
	}

	INIT_WORK(&self->work, bfin_sir_send_work);

	/*
	 * Now enable the interrupt then start the queue
	 */
	self->open = 1;
	bfin_sir_enable_rx(port);

	netif_start_queue(dev);

	return 0;

err_irlap:
	self->open = 0;
	bfin_sir_shutdown(port, dev);
err_startup:
	return err;
}
示例#6
0
static int bfin_sir_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
{
	struct if_irda_req *rq = (struct if_irda_req *)ifreq;
	struct bfin_sir_self *self = netdev_priv(dev);
	struct bfin_sir_port *port = self->sir_port;
	int ret = 0;

	switch (cmd) {
	case SIOCSBANDWIDTH:
		if (capable(CAP_NET_ADMIN)) {
			if (self->open) {
				ret = bfin_sir_set_speed(port, rq->ifr_baudrate);
				bfin_sir_enable_rx(port);
			} else {
				dev_warn(&dev->dev, "SIOCSBANDWIDTH: !netif_running\n");
				ret = 0;
			}
		}
		break;

	case SIOCSMEDIABUSY:
		ret = -EPERM;
		if (capable(CAP_NET_ADMIN)) {
			irda_device_set_media_busy(dev, TRUE);
			ret = 0;
		}
		break;

	case SIOCGRECEIVING:
		rq->ifr_receiving = bfin_sir_is_receiving(dev);
		break;

	default:
		ret = -EOPNOTSUPP;
		break;
	}

	return ret;
}