Esempio n. 1
0
/* Extract info for Tcp socket info provided via netlink. */
static void tcp_illinois_info(struct sock *sk, u32 ext,
			      struct sk_buff *skb)
{
	const struct illinois *ca = (struct illinois *) inet_csk_ca(sk);

	if (ext & (1 << (INET_DIAG_VEGASINFO - 1))) {
		struct tcpvegas_info info = {
			.tcpv_enabled = 1,
			.tcpv_rttcnt = ca->cnt_rtt,
			.tcpv_minrtt = ca->base_rtt,
		};
		u64 t = ca->sum_rtt;

		do_div(t, ca->cnt_rtt);
		info.tcpv_rtt = t;

		nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info);
	}
}

static struct tcp_congestion_ops tcp_illinois = {
	.flags		= TCP_CONG_RTT_STAMP,
	.init		= tcp_illinois_init,
	.ssthresh	= tcp_illinois_ssthresh,
	.min_cwnd	= tcp_reno_min_cwnd,
	.cong_avoid	= tcp_illinois_cong_avoid,
	.set_state	= tcp_illinois_state,
	.get_info	= tcp_illinois_info,
	.pkts_acked	= tcp_illinois_acked,

	.owner		= THIS_MODULE,
	.name		= "illinois",
};

static int __init tcp_illinois_register(void)
{
	BUILD_BUG_ON(sizeof(struct illinois) > ICSK_CA_PRIV_SIZE);
	return tcp_register_congestion_control(&tcp_illinois);
}

/*static void __exit tcp_illinois_unregister(void)
{
	tcp_unregister_congestion_control(&tcp_illinois);
}*/

module_init(tcp_illinois_register);
module_exit(tcp_illinois_unregister);

MODULE_AUTHOR("Stephen Hemminger, Shao Liu");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("TCP Illinois");
MODULE_VERSION("1.0");
/*
 * keypad controller should be initialized in the following sequence
 * only, otherwise it might get into FSM stuck state.
 *
 * - Initialize keypad control parameters, like no. of rows, columns,
 *   timing values etc.,
 * - configure rows and column gpios pull up/down.
 * - set irq edge type.
 * - enable the keypad controller.
 */
static int __devinit pmic8xxx_kp_probe(struct platform_device *pdev)
{
	const struct pm8xxx_keypad_platform_data *pdata =
					dev_get_platdata(&pdev->dev);
	const struct matrix_keymap_data *keymap_data;
	struct pmic8xxx_kp *kp;
	int rc;
	u8 ctrl_val;

	struct pm_gpio kypd_drv = {
		.direction	= PM_GPIO_DIR_OUT,
		.output_buffer	= PM_GPIO_OUT_BUF_OPEN_DRAIN,
		.output_value	= 0,
		.pull		= PM_GPIO_PULL_NO,
		.vin_sel	= PM_GPIO_VIN_S4,
		.out_strength	= PM_GPIO_STRENGTH_LOW,
		.function	= PM_GPIO_FUNC_1,
		.inv_int_pol	= 1,
	};

	struct pm_gpio kypd_sns = {
		.direction	= PM_GPIO_DIR_IN,
		.pull		= PM_GPIO_PULL_UP_31P5,
		.vin_sel	= PM_GPIO_VIN_S4,
		.out_strength	= PM_GPIO_STRENGTH_NO,
		.function	= PM_GPIO_FUNC_NORMAL,
		.inv_int_pol	= 1,
	};


	if (!pdata || !pdata->num_cols || !pdata->num_rows ||
		pdata->num_cols > PM8XXX_MAX_COLS ||
		pdata->num_rows > PM8XXX_MAX_ROWS ||
		pdata->num_cols < PM8XXX_MIN_COLS) {
		dev_err(&pdev->dev, "invalid platform data\n");
		return -EINVAL;
	}

	if (!pdata->scan_delay_ms ||
		pdata->scan_delay_ms > MAX_SCAN_DELAY ||
		pdata->scan_delay_ms < MIN_SCAN_DELAY ||
		!is_power_of_2(pdata->scan_delay_ms)) {
		dev_err(&pdev->dev, "invalid keypad scan time supplied\n");
		return -EINVAL;
	}

	if (!pdata->row_hold_ns ||
		pdata->row_hold_ns > MAX_ROW_HOLD_DELAY ||
		pdata->row_hold_ns < MIN_ROW_HOLD_DELAY ||
		((pdata->row_hold_ns % MIN_ROW_HOLD_DELAY) != 0)) {
		dev_err(&pdev->dev, "invalid keypad row hold time supplied\n");
		return -EINVAL;
	}

	if (!pdata->debounce_ms ||
		((pdata->debounce_ms % 5) != 0) ||
		pdata->debounce_ms > MAX_DEBOUNCE_TIME ||
		pdata->debounce_ms < MIN_DEBOUNCE_TIME) {
		dev_err(&pdev->dev, "invalid debounce time supplied\n");
		return -EINVAL;
	}

	keymap_data = pdata->keymap_data;
	if (!keymap_data) {
		dev_err(&pdev->dev, "no keymap data supplied\n");
		return -EINVAL;
	}

	kp = kzalloc(sizeof(*kp), GFP_KERNEL);
	if (!kp)
		return -ENOMEM;

	platform_set_drvdata(pdev, kp);

	kp->pdata	= pdata;
	kp->dev		= &pdev->dev;

	kp->input = input_allocate_device();
	if (!kp->input) {
		dev_err(&pdev->dev, "unable to allocate input device\n");
		rc = -ENOMEM;
		goto err_alloc_device;
	}

	kp->key_sense_irq = platform_get_irq(pdev, 0);
	if (kp->key_sense_irq < 0) {
		dev_err(&pdev->dev, "unable to get keypad sense irq\n");
		rc = -ENXIO;
		goto err_get_irq;
	}

	kp->key_stuck_irq = platform_get_irq(pdev, 1);
	if (kp->key_stuck_irq < 0) {
		dev_err(&pdev->dev, "unable to get keypad stuck irq\n");
		rc = -ENXIO;
		goto err_get_irq;
	}

	kp->input->name = pdata->input_name ? : "PMIC8XXX keypad";
	kp->input->phys = pdata->input_phys_device ? : "pmic8xxx_keypad/input0";

	kp->input->dev.parent	= &pdev->dev;

	kp->input->id.bustype	= BUS_I2C;
	kp->input->id.version	= 0x0001;
	kp->input->id.product	= 0x0001;
	kp->input->id.vendor	= 0x0001;

	kp->input->evbit[0]	= BIT_MASK(EV_KEY);

	if (pdata->rep)
		__set_bit(EV_REP, kp->input->evbit);

	kp->input->keycode	= kp->keycodes;
	kp->input->keycodemax	= PM8XXX_MATRIX_MAX_SIZE;
	kp->input->keycodesize	= sizeof(kp->keycodes);
	kp->input->open		= pmic8xxx_kp_open;
	kp->input->close	= pmic8xxx_kp_close;

	matrix_keypad_build_keymap(keymap_data, PM8XXX_ROW_SHIFT,
					kp->input->keycode, kp->input->keybit);

	input_set_capability(kp->input, EV_MSC, MSC_SCAN);
	input_set_drvdata(kp->input, kp);

	/* initialize keypad state */
	memset(kp->keystate, 0xff, sizeof(kp->keystate));
	memset(kp->stuckstate, 0xff, sizeof(kp->stuckstate));

	rc = pmic8xxx_kpd_init(kp);
	if (rc < 0) {
		dev_err(&pdev->dev, "unable to initialize keypad controller\n");
		goto err_get_irq;
	}

	rc = pmic8xxx_kp_config_gpio(pdata->cols_gpio_start,
					pdata->num_cols, kp, &kypd_sns);
	if (rc < 0) {
		dev_err(&pdev->dev, "unable to configure keypad sense lines\n");
		goto err_gpio_config;
	}

	rc = pmic8xxx_kp_config_gpio(pdata->rows_gpio_start,
					pdata->num_rows, kp, &kypd_drv);
	if (rc < 0) {
		dev_err(&pdev->dev, "unable to configure keypad drive lines\n");
		goto err_gpio_config;
	}

	rc = request_any_context_irq(kp->key_sense_irq, pmic8xxx_kp_irq,
				 IRQF_TRIGGER_RISING, "pmic-keypad", kp);
	if (rc < 0) {
		dev_err(&pdev->dev, "failed to request keypad sense irq\n");
		goto err_get_irq;
	}

	rc = request_any_context_irq(kp->key_stuck_irq, pmic8xxx_kp_stuck_irq,
				 IRQF_TRIGGER_RISING, "pmic-keypad-stuck", kp);
	if (rc < 0) {
		dev_err(&pdev->dev, "failed to request keypad stuck irq\n");
		goto err_req_stuck_irq;
	}

	rc = pmic8xxx_kp_read_u8(kp, &ctrl_val, KEYP_CTRL);
	if (rc < 0) {
		dev_err(&pdev->dev, "failed to read KEYP_CTRL register\n");
		goto err_pmic_reg_read;
	}

	kp->ctrl_reg = ctrl_val;

	rc = input_register_device(kp->input);
	if (rc < 0) {
		dev_err(&pdev->dev, "unable to register keypad input device\n");
		goto err_pmic_reg_read;
	}

	device_init_wakeup(&pdev->dev, pdata->wakeup);
#if defined(CONFIG_MACH_KS02)
	/*sysfs*/
	kp->sec_keypad = device_create(sec_class, NULL, 0, kp, "sec_keypad");
	if (IS_ERR(kp->sec_keypad))
		dev_err(&pdev->dev, "Failed to create sec_key device\n");

	rc = sysfs_create_group(&kp->sec_keypad->kobj, &key_attr_group);
	if (rc) {
		dev_err(&pdev->dev, "Failed to create the test sysfs: %d\n",
			rc);
	}
#endif
	return 0;

err_pmic_reg_read:
	free_irq(kp->key_stuck_irq, kp);
err_req_stuck_irq:
	free_irq(kp->key_sense_irq, kp);
err_gpio_config:
err_get_irq:
	input_free_device(kp->input);
err_alloc_device:
	platform_set_drvdata(pdev, NULL);
	kfree(kp);
	return rc;
}

static int __devexit pmic8xxx_kp_remove(struct platform_device *pdev)
{
	struct pmic8xxx_kp *kp = platform_get_drvdata(pdev);

	device_init_wakeup(&pdev->dev, 0);
	free_irq(kp->key_stuck_irq, kp);
	free_irq(kp->key_sense_irq, kp);
	input_unregister_device(kp->input);
	kfree(kp);

	platform_set_drvdata(pdev, NULL);
	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int pmic8xxx_kp_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct pmic8xxx_kp *kp = platform_get_drvdata(pdev);
	struct input_dev *input_dev = kp->input;

	if (device_may_wakeup(dev)) {
		enable_irq_wake(kp->key_sense_irq);
	} else {
		mutex_lock(&input_dev->mutex);

		if (input_dev->users)
			pmic8xxx_kp_disable(kp);

		mutex_unlock(&input_dev->mutex);
	}

	key_suspend = 1;

	return 0;
}

static int pmic8xxx_kp_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct pmic8xxx_kp *kp = platform_get_drvdata(pdev);
	struct input_dev *input_dev = kp->input;

	if (device_may_wakeup(dev)) {
		disable_irq_wake(kp->key_sense_irq);
	} else {
		mutex_lock(&input_dev->mutex);

		if (input_dev->users)
			pmic8xxx_kp_enable(kp);

		mutex_unlock(&input_dev->mutex);
	}

	key_suspend = 0;

	return 0;
}
#endif

static SIMPLE_DEV_PM_OPS(pm8xxx_kp_pm_ops,
			 pmic8xxx_kp_suspend, pmic8xxx_kp_resume);

static struct platform_driver pmic8xxx_kp_driver = {
	.probe		= pmic8xxx_kp_probe,
	.remove		= __devexit_p(pmic8xxx_kp_remove),
	.driver		= {
		.name = PM8XXX_KEYPAD_DEV_NAME,
		.owner = THIS_MODULE,
		.pm = &pm8xxx_kp_pm_ops,
	},
};
module_platform_driver(pmic8xxx_kp_driver);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("PMIC8XXX keypad driver");
MODULE_VERSION("1.0");
MODULE_ALIAS("platform:pmic8xxx_keypad");
MODULE_AUTHOR("Trilok Soni <*****@*****.**>");
Esempio n. 3
0
static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
	static struct ata_port_info info = {
		.sht = &cs5530_sht,
		.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
		.pio_mask = 0x1f,
		.mwdma_mask = 0x07,
		.udma_mask = 0x07,
		.port_ops = &cs5530_port_ops
	};
	/* The docking connector doesn't do UDMA, and it seems not MWDMA */
	static struct ata_port_info info_palmax_secondary = {
		.sht = &cs5530_sht,
		.flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
		.pio_mask = 0x1f,
		.port_ops = &cs5530_port_ops
	};
	static struct ata_port_info *port_info[2] = { &info, &info };
	
	/* Chip initialisation */
	if (cs5530_init_chip())
		return -ENODEV;
		
	if (cs5530_is_palmax())
		port_info[1] = &info_palmax_secondary;

	/* Now kick off ATA set up */
	return ata_pci_init_one(pdev, port_info, 2);
}

static int cs5530_reinit_one(struct pci_dev *pdev)
{
	/* If we fail on resume we are doomed */
	if (cs5530_init_chip())
		BUG();
	return ata_pci_device_resume(pdev);
}
	
static const struct pci_device_id cs5530[] = {
	{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), },

	{ },
};

static struct pci_driver cs5530_pci_driver = {
	.name 		= DRV_NAME,
	.id_table	= cs5530,
	.probe 		= cs5530_init_one,
	.remove		= ata_pci_remove_one,
	.suspend	= ata_pci_device_suspend,
	.resume		= cs5530_reinit_one,
};

static int __init cs5530_init(void)
{
	return pci_register_driver(&cs5530_pci_driver);
}

static void __exit cs5530_exit(void)
{
	pci_unregister_driver(&cs5530_pci_driver);
}

MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for the Cyrix/NS/AMD 5530");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, cs5530);
MODULE_VERSION(DRV_VERSION);

module_init(cs5530_init);
module_exit(cs5530_exit);
Esempio n. 4
0
static int create_pipe(int nr)
{
	int minor_in, minor_out , ret;
		
	if (dev_offset == -1) {
		if (inminor == -1) {
		    minor_in  = -1;
		} else {
		    minor_in  = inminor+nr;
		}
		if (outminor == -1) {
		    minor_out = -1;
		} else {
		    minor_out = outminor+nr;
		}
	} else {
		minor_in  = 2*nr   + dev_offset;
		minor_out = 2*nr+1 + dev_offset;
	}

	/* allocate space for this pipe */
	loops[nr]= kmalloc(sizeof(struct vloopback_pipe), GFP_KERNEL);
	if (!loops[nr])
		return -ENOMEM;
	/* set up a new video device plus our private area */
	loops[nr]->vloopin= video_device_alloc();
	if (loops[nr]->vloopin == NULL)
		return -ENOMEM;
	*loops[nr]->vloopin = vloopback_template;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
	video_set_drvdata(loops[nr]->vloopin,kmalloc(sizeof(struct vloopback_private),GFP_KERNEL));
#else
	loops[nr]->vloopin->priv= kmalloc(sizeof(struct vloopback_private),GFP_KERNEL);
#endif	
	
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
	if ((priv_ptr)video_get_drvdata(loops[nr]->vloopin) == NULL) {
#else
	if (loops[nr]->vloopin->priv == NULL) {
#endif	
		kfree(loops[nr]->vloopin);
		return -ENOMEM;
	}
	/* repeat for the output device */
	loops[nr]->vloopout= video_device_alloc();
	if (loops[nr]->vloopout == NULL) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
		kfree((priv_ptr)video_get_drvdata(loops[nr]->vloopin));
#else
		kfree(loops[nr]->vloopin->priv);
#endif	
		kfree(loops[nr]->vloopin);
		return -ENOMEM;
	}
	*loops[nr]->vloopout = vloopback_template;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
	video_set_drvdata(loops[nr]->vloopout,kmalloc(sizeof(struct vloopback_private),GFP_KERNEL));
#else
	loops[nr]->vloopout->priv= kmalloc(sizeof(struct vloopback_private),GFP_KERNEL);
#endif	

	if ((priv_ptr)video_get_drvdata(loops[nr]->vloopout) == NULL) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
		kfree((priv_ptr)video_get_drvdata(loops[nr]->vloopin));
#else
		kfree(loops[nr]->vloopin->priv);
#endif	
		kfree(loops[nr]->vloopin);
		kfree(loops[nr]->vloopout);
		return -ENOMEM;
	}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
	((priv_ptr)video_get_drvdata(loops[nr]->vloopin))->pipenr=nr;
	((priv_ptr)video_get_drvdata(loops[nr]->vloopout))->pipenr=nr;
#else
	((priv_ptr)loops[nr]->vloopin->priv)->pipenr=nr;
	((priv_ptr)loops[nr]->vloopout->priv)->pipenr=nr;
#endif	

	loops[nr]->invalid_ioctl = 0; /* tibit */
	loops[nr]->buffer=NULL;
	loops[nr]->width=0;
	loops[nr]->height=0;
	loops[nr]->palette=0;
	loops[nr]->frameswrite=0;
	loops[nr]->framesread=0;
	loops[nr]->framesdumped=0;
	loops[nr]->wopen=0;
	loops[nr]->ropen=0;
	loops[nr]->frame=0;
	loops[nr]->pendingread=0;
	
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
	((priv_ptr)video_get_drvdata(loops[nr]->vloopin))->in=1;
	((priv_ptr)video_get_drvdata(loops[nr]->vloopout))->in=0;
#else
	((priv_ptr)loops[nr]->vloopin->priv)->in=1;
	((priv_ptr)loops[nr]->vloopout->priv)->in=0;
#endif	
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
	loops[nr]->vloopin->type=0;
#endif
	sprintf(loops[nr]->vloopin->name, "Video loopback %d input", nr);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
	loops[nr]->vloopout->type=VID_TYPE_CAPTURE;
#endif
	sprintf(loops[nr]->vloopout->name, "Video loopback %d output", nr);
	init_waitqueue_head(&loops[nr]->wait);
	init_MUTEX(&loops[nr]->lock);
	
	ret = video_register_device(loops[nr]->vloopout, VFL_TYPE_GRABBER, minor_out);
	
	if ((ret ==-1) || (ret == -23)) {
		info("error registering device %s", loops[nr]->vloopout->name);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
		kfree(((priv_ptr)video_get_drvdata(loops[nr]->vloopin)));
		video_unregister_device(loops[nr]->vloopin);
		kfree(((priv_ptr)video_get_drvdata(loops[nr]->vloopout)));
#else
		kfree(loops[nr]->vloopin->priv);
		video_unregister_device(loops[nr]->vloopin);
		kfree(loops[nr]->vloopout->priv);
#endif	
		kfree(loops[nr]->vloopout);
		kfree(loops[nr]);
		loops[nr]=NULL;
		return ret;
	}
	
	ret = video_register_device(loops[nr]->vloopin, VFL_TYPE_GRABBER, minor_in);

	if ((ret == -1 ) || ( ret == -23 )) {
		info("error registering device %s",loops[nr]->vloopin->name);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
		kfree(((priv_ptr)video_get_drvdata(loops[nr]->vloopin)));
		kfree(((priv_ptr)video_get_drvdata(loops[nr]->vloopout)));
#else
		kfree(loops[nr]->vloopin->priv);
		kfree(loops[nr]->vloopout->priv);
#endif	

		kfree(loops[nr]->vloopin);
		kfree(loops[nr]->vloopout);
		kfree(loops[nr]);
		loops[nr]=NULL;
		return ret;
	}
	
	loops[nr]->ioctldata=kmalloc(1024, GFP_KERNEL);
	loops[nr]->ioctlretdata=kmalloc(1024, GFP_KERNEL);
	return 0;
}


/****************************************************************************
 *	init stuff
 ****************************************************************************/


MODULE_AUTHOR("J.B. Vreeken ([email protected])");
MODULE_DESCRIPTION("Video4linux loopback device.");

#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
module_param(pipes, int, 000);
#else
MODULE_PARM(pipes, "i");
#endif

MODULE_PARM_DESC(pipes, "Nr of pipes to create (each pipe uses two video devices)");

#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
module_param(spares, int, 000);
#else
MODULE_PARM(spares, "i");
#endif

MODULE_PARM_DESC(spares, "Nr of spare pipes that should be created");

#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
module_param(dev_offset, int, 000);
#else
MODULE_PARM(dev_offset_param, "i");
#endif

#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
module_param(inminor, int, 000);
#else
MODULE_PARM(inminor, "i");
#endif

#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
module_param(outminor, int, 000);
#else
MODULE_PARM(outminor, "i");
#endif

MODULE_PARM_DESC(dev_offset, "Prefered offset for video device numbers");
MODULE_LICENSE("GPL");
MODULE_VERSION( VLOOPBACK_VERSION );

static int __init vloopback_init(void)
{
	int i,ret;

	info("Video4linux loopback driver v"VLOOPBACK_VERSION);

	if (pipes==-1) pipes=1;
	if (pipes > MAX_PIPES) {
		pipes=MAX_PIPES;
		info("Nr of pipes is limited to: %d", MAX_PIPES);
	}

	for (i=0; i<pipes; i++) {
		
		ret = create_pipe(i);

		if (ret == 0) {
			info("Loopback %d registered, input: video%d, output: video%d",
			     i, loops[i]->vloopin->minor,
			     loops[i]->vloopout->minor);
			nr_o_pipes=i+1;
		}else{
			return ret;
		}
	}
	return 0;
}
Esempio n. 5
0
static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
{
	static int printed_version;
	static struct ata_port_info info_6210 = {
		.sht		= &artop_sht,
		.flags		= ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
		.pio_mask	= 0x1f,	/* pio0-4 */
		.mwdma_mask	= 0x07, /* mwdma0-2 */
		.udma_mask 	= ATA_UDMA2,
		.port_ops	= &artop6210_ops,
	};
	static struct ata_port_info info_626x = {
		.sht		= &artop_sht,
		.flags		= ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
		.pio_mask	= 0x1f,	/* pio0-4 */
		.mwdma_mask	= 0x07, /* mwdma0-2 */
		.udma_mask 	= ATA_UDMA4,
		.port_ops	= &artop6260_ops,
	};
	static struct ata_port_info info_626x_fast = {
		.sht		= &artop_sht,
		.flags		= ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
		.pio_mask	= 0x1f,	/* pio0-4 */
		.mwdma_mask	= 0x07, /* mwdma0-2 */
		.udma_mask 	= ATA_UDMA5,
		.port_ops	= &artop6260_ops,
	};
	struct ata_port_info *port_info[2];
	struct ata_port_info *info = NULL;
	int ports = 2;

	if (!printed_version++)
		dev_printk(KERN_DEBUG, &pdev->dev,
			   "version " DRV_VERSION "\n");

	if (id->driver_data == 0) {	/* 6210 variant */
		info = &info_6210;
		/* BIOS may have left us in UDMA, clear it before libata probe */
		pci_write_config_byte(pdev, 0x54, 0);
		/* For the moment (also lacks dsc) */
		printk(KERN_WARNING "ARTOP 6210 requires serialize functionality not yet supported by libata.\n");
		printk(KERN_WARNING "Secondary ATA ports will not be activated.\n");
		ports = 1;
	}
	else if (id->driver_data == 1)	/* 6260 */
		info = &info_626x;
	else if (id->driver_data == 2)	{ /* 6260 or 6260 + fast */
		unsigned long io = pci_resource_start(pdev, 4);
		u8 reg;

		info = &info_626x;
		if (inb(io) & 0x10)
			info = &info_626x_fast;
		/* Mac systems come up with some registers not set as we
		   will need them */

		/* Clear reset & test bits */
		pci_read_config_byte(pdev, 0x49, &reg);
		pci_write_config_byte(pdev, 0x49, reg & ~ 0x30);

		/* PCI latency must be > 0x80 for burst mode, tweak it
		 * if required.
		 */
		pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &reg);
		if (reg <= 0x80)
			pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x90);

		/* Enable IRQ output and burst mode */
		pci_read_config_byte(pdev, 0x4a, &reg);
		pci_write_config_byte(pdev, 0x4a, (reg & ~0x01) | 0x80);

	}

	BUG_ON(info == NULL);

	port_info[0] = port_info[1] = info;
	return ata_pci_init_one(pdev, port_info, ports);
}

static const struct pci_device_id artop_pci_tbl[] = {
	{ PCI_VDEVICE(ARTOP, 0x0005), 0 },
	{ PCI_VDEVICE(ARTOP, 0x0006), 1 },
	{ PCI_VDEVICE(ARTOP, 0x0007), 1 },
	{ PCI_VDEVICE(ARTOP, 0x0008), 2 },
	{ PCI_VDEVICE(ARTOP, 0x0009), 2 },

	{ }	/* terminate list */
};

static struct pci_driver artop_pci_driver = {
	.name			= DRV_NAME,
	.id_table		= artop_pci_tbl,
	.probe			= artop_init_one,
	.remove			= ata_pci_remove_one,
};

static int __init artop_init(void)
{
	return pci_register_driver(&artop_pci_driver);
}

static void __exit artop_exit(void)
{
	pci_unregister_driver(&artop_pci_driver);
}

module_init(artop_init);
module_exit(artop_exit);

MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("SCSI low-level driver for ARTOP PATA");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, artop_pci_tbl);
MODULE_VERSION(DRV_VERSION);
Esempio n. 6
0
static int hvfb_probe(struct hv_device *hdev,
		      const struct hv_vmbus_device_id *dev_id)
{
	struct fb_info *info;
	struct hvfb_par *par;
	int ret;

	info = framebuffer_alloc(sizeof(struct hvfb_par), &hdev->device);
	if (!info) {
		pr_err("No memory for framebuffer info\n");
		return -ENOMEM;
	}

	par = info->par;
	par->info = info;
	par->fb_ready = false;
	init_completion(&par->wait);
	INIT_DELAYED_WORK(&par->dwork, hvfb_update_work);

	/* Connect to VSP */
	hv_set_drvdata(hdev, info);
	ret = synthvid_connect_vsp(hdev);
	if (ret) {
		pr_err("Unable to connect to VSP\n");
		goto error1;
	}

	ret = hvfb_getmem(info);
	if (ret) {
		pr_err("No memory for framebuffer\n");
		goto error2;
	}

	hvfb_get_option(info);
	pr_info("Screen resolution: %dx%d, Color depth: %d\n",
		screen_width, screen_height, screen_depth);


	/* Set up fb_info */
	info->flags = FBINFO_DEFAULT;

	info->var.xres_virtual = info->var.xres = screen_width;
	info->var.yres_virtual = info->var.yres = screen_height;
	info->var.bits_per_pixel = screen_depth;

	if (info->var.bits_per_pixel == 16) {
		info->var.red = (struct fb_bitfield){11, 5, 0};
		info->var.green = (struct fb_bitfield){5, 6, 0};
		info->var.blue = (struct fb_bitfield){0, 5, 0};
		info->var.transp = (struct fb_bitfield){0, 0, 0};
	} else {
		info->var.red = (struct fb_bitfield){16, 8, 0};
		info->var.green = (struct fb_bitfield){8, 8, 0};
		info->var.blue = (struct fb_bitfield){0, 8, 0};
		info->var.transp = (struct fb_bitfield){24, 8, 0};
	}

	info->var.activate = FB_ACTIVATE_NOW;
	info->var.height = -1;
	info->var.width = -1;
	info->var.vmode = FB_VMODE_NONINTERLACED;

	strcpy(info->fix.id, KBUILD_MODNAME);
	info->fix.type = FB_TYPE_PACKED_PIXELS;
	info->fix.visual = FB_VISUAL_TRUECOLOR;
	info->fix.line_length = screen_width * screen_depth / 8;
	info->fix.accel = FB_ACCEL_NONE;

	info->fbops = &hvfb_ops;
	info->pseudo_palette = par->pseudo_palette;

	/* Send config to host */
	ret = synthvid_send_config(hdev);
	if (ret)
		goto error;

	ret = register_framebuffer(info);
	if (ret) {
		pr_err("Unable to register framebuffer\n");
		goto error;
	}

	par->fb_ready = true;

	par->synchronous_fb = false;
	par->hvfb_panic_nb.notifier_call = hvfb_on_panic;
	atomic_notifier_chain_register(&panic_notifier_list,
				       &par->hvfb_panic_nb);

	return 0;

error:
	hvfb_putmem(info);
error2:
	vmbus_close(hdev->channel);
error1:
	cancel_delayed_work_sync(&par->dwork);
	hv_set_drvdata(hdev, NULL);
	framebuffer_release(info);
	return ret;
}


static int hvfb_remove(struct hv_device *hdev)
{
	struct fb_info *info = hv_get_drvdata(hdev);
	struct hvfb_par *par = info->par;

	atomic_notifier_chain_unregister(&panic_notifier_list,
					 &par->hvfb_panic_nb);

	par->update = false;
	par->fb_ready = false;

	unregister_framebuffer(info);
	cancel_delayed_work_sync(&par->dwork);

	vmbus_close(hdev->channel);
	hv_set_drvdata(hdev, NULL);

	hvfb_putmem(info);
	framebuffer_release(info);

	return 0;
}


static const struct pci_device_id pci_stub_id_table[] = {
	{
		.vendor      = PCI_VENDOR_ID_MICROSOFT,
		.device      = PCI_DEVICE_ID_HYPERV_VIDEO,
	},
	{ /* end of list */ }
};

static const struct hv_vmbus_device_id id_table[] = {
	/* Synthetic Video Device GUID */
	{HV_SYNTHVID_GUID},
	{}
};

MODULE_DEVICE_TABLE(pci, pci_stub_id_table);
MODULE_DEVICE_TABLE(vmbus, id_table);

static struct hv_driver hvfb_drv = {
	.name = KBUILD_MODNAME,
	.id_table = id_table,
	.probe = hvfb_probe,
	.remove = hvfb_remove,
};

static int hvfb_pci_stub_probe(struct pci_dev *pdev,
			       const struct pci_device_id *ent)
{
	return 0;
}

static void hvfb_pci_stub_remove(struct pci_dev *pdev)
{
}

static struct pci_driver hvfb_pci_stub_driver = {
	.name =		KBUILD_MODNAME,
	.id_table =	pci_stub_id_table,
	.probe =	hvfb_pci_stub_probe,
	.remove =	hvfb_pci_stub_remove,
};

static int __init hvfb_drv_init(void)
{
	int ret;

	ret = vmbus_driver_register(&hvfb_drv);
	if (ret != 0)
		return ret;

	ret = pci_register_driver(&hvfb_pci_stub_driver);
	if (ret != 0) {
		vmbus_driver_unregister(&hvfb_drv);
		return ret;
	}

	return 0;
}

static void __exit hvfb_drv_exit(void)
{
	pci_unregister_driver(&hvfb_pci_stub_driver);
	vmbus_driver_unregister(&hvfb_drv);
}

module_init(hvfb_drv_init);
module_exit(hvfb_drv_exit);

MODULE_LICENSE("GPL");
MODULE_VERSION(HV_DRV_VERSION);
MODULE_DESCRIPTION("Microsoft Hyper-V Synthetic Video Frame Buffer Driver");
Esempio n. 7
0
static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
{
	static const struct ata_port_info info = {
		.sht		= &marvell_sht,
		.flags		= ATA_FLAG_SLAVE_POSS,

		.pio_mask	= 0x1f,
		.mwdma_mask	= 0x07,
		.udma_mask 	= ATA_UDMA5,

		.port_ops	= &marvell_ops,
	};
	static const struct ata_port_info info_sata = {
		.sht		= &marvell_sht,
		/* Slave possible as its magically mapped not real */
		.flags		= ATA_FLAG_SLAVE_POSS,

		.pio_mask	= 0x1f,
		.mwdma_mask	= 0x07,
		.udma_mask 	= ATA_UDMA6,

		.port_ops	= &marvell_ops,
	};
	const struct ata_port_info *ppi[] = { &info, &info_sata };

	if (pdev->device == 0x6101)
		ppi[1] = &ata_dummy_port_info;

	return ata_pci_init_one(pdev, ppi);
}

static const struct pci_device_id marvell_pci_tbl[] = {
	{ PCI_DEVICE(0x11AB, 0x6101), },
	{ PCI_DEVICE(0x11AB, 0x6121), },
	{ PCI_DEVICE(0x11AB, 0x6123), },
	{ PCI_DEVICE(0x11AB, 0x6145), },
	{ }	/* terminate list */
};

static struct pci_driver marvell_pci_driver = {
	.name			= DRV_NAME,
	.id_table		= marvell_pci_tbl,
	.probe			= marvell_init_one,
	.remove			= ata_pci_remove_one,
#ifdef CONFIG_PM
	.suspend		= ata_pci_device_suspend,
	.resume			= ata_pci_device_resume,
#endif
};

static int __init marvell_init(void)
{
	return pci_register_driver(&marvell_pci_driver);
}

static void __exit marvell_exit(void)
{
	pci_unregister_driver(&marvell_pci_driver);
}

module_init(marvell_init);
module_exit(marvell_exit);

MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("SCSI low-level driver for Marvell ATA in legacy mode");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, marvell_pci_tbl);
MODULE_VERSION(DRV_VERSION);
Esempio n. 8
0
static int __devinit sil680_init_one(struct pci_dev *pdev,
				     const struct pci_device_id *id)
{
	static const struct ata_port_info info = {
		.flags = ATA_FLAG_SLAVE_POSS,
		.pio_mask = 0x1f,
		.mwdma_mask = 0x07,
		.udma_mask = ATA_UDMA6,
		.port_ops = &sil680_port_ops
	};
	static const struct ata_port_info info_slow = {
		.flags = ATA_FLAG_SLAVE_POSS,
		.pio_mask = 0x1f,
		.mwdma_mask = 0x07,
		.udma_mask = ATA_UDMA5,
		.port_ops = &sil680_port_ops
	};
	const struct ata_port_info *ppi[] = { &info, NULL };
	static int printed_version;
	struct ata_host *host;
	void __iomem *mmio_base;
	int rc, try_mmio;
	struct pci_dev *drac;

	/* DRAC only filter */

	drac = pci_get_device(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_RAC4,
			      NULL);

	if (drac == NULL) {
        /* There are two common devices on DRACs. See if we can *
	 * find the second one if couldn't find the first.      */
		printk(KERN_INFO "sil680: Trying SMIC device.\n");
		drac = pci_get_device(PCI_VENDOR_ID_DELL, 0x0014, NULL);
	}

	if (drac == NULL)
		return -ENODEV;
	
	if (drac->bus != pdev->bus)     /* Not the right SIL680 */
	{
		pci_dev_put(drac);
		return -ENODEV;
	}
	pci_dev_put(drac);

        /* Back to original code */

	if (!printed_version++)
		dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");

	rc = pcim_enable_device(pdev);
	if (rc)
		return rc;

	switch (sil680_init_chip(pdev, &try_mmio)) {
		case 0:
			ppi[0] = &info_slow;
			break;
		case 0x30:
			return -ENODEV;
	}

	if (!try_mmio)
		goto use_ioports;

	/* Try to acquire MMIO resources and fallback to PIO if
	 * that fails
	 */
	rc = pcim_enable_device(pdev);
	if (rc)
		return rc;
	rc = pcim_iomap_regions(pdev, 1 << SIL680_MMIO_BAR, DRV_NAME);
	if (rc)
		goto use_ioports;

	/* Allocate host and set it up */
	host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
	if (!host)
		return -ENOMEM;
	host->iomap = pcim_iomap_table(pdev);

	/* Setup DMA masks */
	rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
	if (rc)
		return rc;
	rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
	if (rc)
		return rc;
	pci_set_master(pdev);

	/* Get MMIO base and initialize port addresses */
	mmio_base = host->iomap[SIL680_MMIO_BAR];
	host->ports[0]->ioaddr.bmdma_addr = mmio_base + 0x00;
	host->ports[0]->ioaddr.cmd_addr = mmio_base + 0x80;
	host->ports[0]->ioaddr.ctl_addr = mmio_base + 0x8a;
	host->ports[0]->ioaddr.altstatus_addr = mmio_base + 0x8a;
	ata_sff_std_ports(&host->ports[0]->ioaddr);
	host->ports[1]->ioaddr.bmdma_addr = mmio_base + 0x08;
	host->ports[1]->ioaddr.cmd_addr = mmio_base + 0xc0;
	host->ports[1]->ioaddr.ctl_addr = mmio_base + 0xca;
	host->ports[1]->ioaddr.altstatus_addr = mmio_base + 0xca;
	ata_sff_std_ports(&host->ports[1]->ioaddr);

	/* Register & activate */
	return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
				 IRQF_SHARED, &sil680_sht);

use_ioports:
	return ata_pci_sff_init_one(pdev, ppi, &sil680_sht, NULL);
}

#ifdef CONFIG_PM
static int sil680_reinit_one(struct pci_dev *pdev)
{
	struct ata_host *host = dev_get_drvdata(&pdev->dev);
	int try_mmio, rc;

	rc = ata_pci_device_do_resume(pdev);
	if (rc)
		return rc;
	sil680_init_chip(pdev, &try_mmio);
	ata_host_resume(host);
	return 0;
}
#endif

static const struct pci_device_id sil680[] = {
	{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_680), },

	{ },
};

static struct pci_driver sil680_pci_driver = {
	.name 		= DRV_NAME,
	.id_table	= sil680,
	.probe 		= sil680_init_one,
	.remove		= ata_pci_remove_one,
#ifdef CONFIG_PM
	.suspend	= ata_pci_device_suspend,
	.resume		= sil680_reinit_one,
#endif
};

static int __init sil680_init(void)
{
	return pci_register_driver(&sil680_pci_driver);
}

static void __exit sil680_exit(void)
{
	pci_unregister_driver(&sil680_pci_driver);
}

MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for SI680 PATA");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, sil680);
MODULE_VERSION(DRV_VERSION);

module_init(sil680_init);
module_exit(sil680_exit);
Esempio n. 9
0
static int create_pipe(int nr)
{
    int minor_in, minor_out , ret;

    if (debug > LOG_NODEBUG)
        info("Video loopback %d", nr);

    if (dev_offset == -1) {
        minor_in  = minor_out = -1; /* autoassign */
    } else {
        minor_in  = 2 * nr + dev_offset;
        minor_out = 2 * nr + 1 + dev_offset;
    }
    /* allocate space for this pipe */
    loops[nr]= kmalloc(sizeof(struct vloopback_pipe), GFP_KERNEL);

    if (!loops[nr])
        return -ENOMEM;
    /* set up a new video device plus our private area */
    loops[nr]->vloopin = video_device_alloc();

    if (loops[nr]->vloopin == NULL)
        return -ENOMEM;
    *loops[nr]->vloopin = vloopback_template;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)    
    priv_ptr ptr_in = kmalloc(sizeof(struct vloopback_private), 
                                                  GFP_KERNEL);
    if (ptr_in == NULL) {
        kfree(ptr_in);
#else
    loops[nr]->vloopin->vd_private_data = kmalloc(sizeof(struct vloopback_private),
                                                  GFP_KERNEL);
    if (loops[nr]->vloopin->vd_private_data == NULL) {
        kfree(loops[nr]->vloopin);
#endif    
        return -ENOMEM;
    }
    /* repeat for the output device */
    loops[nr]->vloopout = video_device_alloc();

    if (loops[nr]->vloopout == NULL) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
        kfree(ptr_in);
#else        
        kfree(loops[nr]->vloopin->vd_private_data);
#endif        
        kfree(loops[nr]->vloopin);
        return -ENOMEM;
    }
    *loops[nr]->vloopout = vloopback_template;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)    
    priv_ptr ptr_out = kmalloc(sizeof(struct vloopback_private),
                                                   GFP_KERNEL);
    if (ptr_out == NULL) {
        kfree(ptr_in);
        kfree(ptr_out);
#else
    loops[nr]->vloopout->vd_private_data = kmalloc(sizeof(struct vloopback_private),
                                                   GFP_KERNEL);
    if (loops[nr]->vloopout->vd_private_data == NULL) {
        kfree(loops[nr]->vloopin->vd_private_data);
#endif    
        kfree(loops[nr]->vloopin);
        kfree(loops[nr]->vloopout);
        return -ENOMEM;
    }

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
    ptr_in->pipenr = nr;
    ptr_out->pipenr = nr;
#else
    ((priv_ptr)loops[nr]->vloopin->vd_private_data)->pipenr = nr;
    ((priv_ptr)loops[nr]->vloopout->vd_private_data)->pipenr = nr;
#endif    
    loops[nr]->invalid_ioctl = 0; /* tibit */
    loops[nr]->buffer = NULL;
    loops[nr]->width = 0;
    loops[nr]->height = 0;
    loops[nr]->palette = 0;
    loops[nr]->frameswrite = 0;
    loops[nr]->framesread = 0;
    loops[nr]->framesdumped = 0;
    loops[nr]->wopen = 0;
    loops[nr]->ropen = 0;
    loops[nr]->frame = 0;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)    
    ptr_in->in = 1;
    ptr_out->in = 0;
    dev_set_drvdata(&loops[nr]->vloopin->dev, ptr_in);
    dev_set_drvdata(&loops[nr]->vloopout->dev, ptr_out);
#else
    ((priv_ptr)loops[nr]->vloopin->vd_private_data)->in = 1;
    ((priv_ptr)loops[nr]->vloopout->vd_private_data)->in = 0;
#endif

    sprintf(loops[nr]->vloopin->name, "Video loopback %d input", nr);
    sprintf(loops[nr]->vloopout->name, "Video loopback %d output", nr);

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
    loops[nr]->vloopin->type = 0;
    loops[nr]->vloopout->type = VID_TYPE_CAPTURE;
#endif
    loops[nr]->vloopout->minor = minor_out;
    loops[nr]->vloopin->minor = minor_in;

    init_waitqueue_head(&loops[nr]->wait);

    init_MUTEX(&loops[nr]->lock);

    ret = video_register_device(loops[nr]->vloopin, VFL_TYPE_GRABBER, minor_in);
    
    if ((ret == -1 ) || ( ret == -23 )) {
        info("error registering device %s", loops[nr]->vloopin->name);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)        
        kfree(ptr_in);
        dev_set_drvdata(&loops[nr]->vloopin->dev, NULL);
#else
        kfree(loops[nr]->vloopin->vd_private_data);
#endif        
        kfree(loops[nr]->vloopin);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)        
        kfree(ptr_out);
        dev_set_drvdata(&loops[nr]->vloopout->dev, NULL);
#else   
        kfree(loops[nr]->vloopout->vd_private_data);
#endif
        kfree(loops[nr]->vloopout);
        kfree(loops[nr]);
        loops[nr] = NULL;
        return ret;
    }
    
    ret = video_register_device(loops[nr]->vloopout, VFL_TYPE_GRABBER, minor_out);
    
    if ((ret ==-1) || (ret == -23)) {
        info("error registering device %s", loops[nr]->vloopout->name);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)        
        kfree(ptr_in);
        dev_set_drvdata(&loops[nr]->vloopin->dev, NULL);
#else
        kfree(loops[nr]->vloopin->vd_private_data);
#endif        
        video_unregister_device(loops[nr]->vloopin);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)        
        kfree(ptr_out);
        dev_set_drvdata(&loops[nr]->vloopout->dev, NULL);
#else   
        kfree(loops[nr]->vloopout->vd_private_data);
#endif        
        kfree(loops[nr]->vloopout);
        kfree(loops[nr]);
        loops[nr] = NULL;
        return ret;
    }
    
    loops[nr]->ioctldata = kmalloc(1024, GFP_KERNEL);
    loops[nr]->ioctlretdata = kmalloc(1024, GFP_KERNEL);
    return 0;
}


/****************************************************************************
 *    init stuff
 ****************************************************************************/


MODULE_AUTHOR("J.B. Vreeken ([email protected])");
MODULE_DESCRIPTION("Video4linux loopback device.");

#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
module_param(pipes, int, 000);
#else
MODULE_PARM(pipes, "i");
#endif

MODULE_PARM_DESC(pipes, " Nr of pipes to create (each pipe uses two video devices)");

#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
module_param(spares, int, 000);
#else
MODULE_PARM(spares, "i");
#endif

MODULE_PARM_DESC(spares, " Nr of spare pipes that should be created");

#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
module_param(num_buffers, int, 000);
#else
MODULE_PARM(num_buffers, "i");
#endif

MODULE_PARM_DESC(num_buffers, " Prefered numbers of internal buffers to map (default 2)");


#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
module_param(dev_offset, int, 000);
#else
MODULE_PARM(dev_offset_param, "i");
#endif

MODULE_PARM_DESC(dev_offset, " Prefered offset for video device numbers");


#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
module_param(debug, int, 000);
#else
MODULE_PARM(debug_param, "i");
#endif

MODULE_PARM_DESC(debug, " Enable module debug level 0-3 (by default 0)");

MODULE_LICENSE("GPL");
MODULE_VERSION( VLOOPBACK_VERSION );

static int __init vloopback_init(void)
{
    int i, ret;

    info("video4linux loopback driver v"VLOOPBACK_VERSION);

    if (pipes == -1) 
        pipes = 1;

    if (pipes > MAX_PIPES) {
        pipes = MAX_PIPES;
        info("Nr of pipes is limited to: %d", MAX_PIPES);
    }

    if (num_buffers < N_BUFFS) {
        num_buffers = N_BUFFS;
        info("Nr of buffer set to default value %d", N_BUFFS);
    }

    for (i = 0; i < pipes; i++) {
        
        ret = create_pipe(i);

        if (ret == 0) {
            info("Loopback %d registered, input: video%d,"
                 " output: video%d",
                 i, loops[i]->vloopin->minor,
                 loops[i]->vloopout->minor);
            info("Loopback %d , Using %d buffers", i, num_buffers);
            nr_o_pipes = i + 1;
        } else {
            return ret;
        }
    }
    return 0;
}
Esempio n. 10
0
static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
	static struct ata_port_info info = {
		.sht = &sil680_sht,
		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
		.pio_mask = 0x1f,
		.mwdma_mask = 0x07,
		.udma_mask = 0x7f,
		.port_ops = &sil680_port_ops
	};
	static struct ata_port_info info_slow = {
		.sht = &sil680_sht,
		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
		.pio_mask = 0x1f,
		.mwdma_mask = 0x07,
		.udma_mask = 0x3f,
		.port_ops = &sil680_port_ops
	};
	static struct ata_port_info *port_info[2] = {&info, &info};
	static int printed_version;
	u32 class_rev	= 0;
	u8 tmpbyte	= 0;

	if (!printed_version++)
		dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");

        pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev);
        class_rev &= 0xff;
        /* FIXME: double check */
	pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, (class_rev) ? 1 : 255);

	pci_write_config_byte(pdev, 0x80, 0x00);
	pci_write_config_byte(pdev, 0x84, 0x00);

	pci_read_config_byte(pdev, 0x8A, &tmpbyte);

	printk(KERN_INFO "sil680: BA5_EN = %d clock = %02X\n",
			tmpbyte & 1, tmpbyte & 0x30);

	switch(tmpbyte & 0x30) {
		case 0x00:
			/* 133 clock attempt to force it on */
			pci_write_config_byte(pdev, 0x8A, tmpbyte|0x10);
			break;
		case 0x30:
			/* if clocking is disabled */
			/* 133 clock attempt to force it on */
			pci_write_config_byte(pdev, 0x8A, tmpbyte & ~0x20);
			break;
		case 0x10:
			/* 133 already */
			break;
		case 0x20:
			/* BIOS set PCI x2 clocking */
			break;
	}

	pci_read_config_byte(pdev,   0x8A, &tmpbyte);
	printk(KERN_INFO "sil680: BA5_EN = %d clock = %02X\n",
			tmpbyte & 1, tmpbyte & 0x30);
	if ((tmpbyte & 0x30) == 0)
		port_info[0] = port_info[1] = &info_slow;

	pci_write_config_byte(pdev,  0xA1, 0x72);
	pci_write_config_word(pdev,  0xA2, 0x328A);
	pci_write_config_dword(pdev, 0xA4, 0x62DD62DD);
	pci_write_config_dword(pdev, 0xA8, 0x43924392);
	pci_write_config_dword(pdev, 0xAC, 0x40094009);
	pci_write_config_byte(pdev,  0xB1, 0x72);
	pci_write_config_word(pdev,  0xB2, 0x328A);
	pci_write_config_dword(pdev, 0xB4, 0x62DD62DD);
	pci_write_config_dword(pdev, 0xB8, 0x43924392);
	pci_write_config_dword(pdev, 0xBC, 0x40094009);

	switch(tmpbyte & 0x30) {
		case 0x00: printk(KERN_INFO "sil680: 100MHz clock.\n");break;
		case 0x10: printk(KERN_INFO "sil680: 133MHz clock.\n");break;
		case 0x20: printk(KERN_INFO "sil680: Using PCI clock.\n");break;
		/* This last case is _NOT_ ok */
		case 0x30: printk(KERN_ERR "sil680: Clock disabled ?\n");
			return -EIO;
	}
	return ata_pci_init_one(pdev, port_info, 2);
}

static const struct pci_device_id sil680[] = {
	{ PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_680), },

	{ },
};

static struct pci_driver sil680_pci_driver = {
	.name 		= DRV_NAME,
	.id_table	= sil680,
	.probe 		= sil680_init_one,
	.remove		= ata_pci_remove_one
};

static int __init sil680_init(void)
{
	return pci_register_driver(&sil680_pci_driver);
}

static void __exit sil680_exit(void)
{
	pci_unregister_driver(&sil680_pci_driver);
}

MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for SI680 PATA");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, sil680);
MODULE_VERSION(DRV_VERSION);

module_init(sil680_init);
module_exit(sil680_exit);
Esempio n. 11
0
static int ns87415_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
    static int printed_version;
    static const struct ata_port_info info = {
        .sht		= &ns87415_sht,
        .flags		= ATA_FLAG_SLAVE_POSS,
        .pio_mask	= 0x1f,	/* pio0-4 */
        .mwdma_mask	= 0x07, /* mwdma0-2 */
        .port_ops	= &ns87415_pata_ops,
    };
    const struct ata_port_info *ppi[] = { &info, NULL };
#if defined(CONFIG_SUPERIO)
    static const struct ata_port_info info87560 = {
        .sht		= &ns87415_sht,
        .flags		= ATA_FLAG_SLAVE_POSS,
        .pio_mask	= 0x1f,	/* pio0-4 */
        .mwdma_mask	= 0x07, /* mwdma0-2 */
        .port_ops	= &ns87560_pata_ops,
    };

    if (PCI_SLOT(pdev->devfn) == 0x0E)
        ppi[0] = &info87560;
#endif
    if (!printed_version++)
        dev_printk(KERN_DEBUG, &pdev->dev,
                   "version " DRV_VERSION "\n");
    /* Select 512 byte sectors */
    pci_write_config_byte(pdev, 0x55, 0xEE);
    /* Select PIO0 8bit clocking */
    pci_write_config_byte(pdev, 0x54, 0xB7);
    return ata_pci_init_one(pdev, ppi);
}

static const struct pci_device_id ns87415_pci_tbl[] = {
    { PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_87415), },

    { }	/* terminate list */
};

static struct pci_driver ns87415_pci_driver = {
    .name			= DRV_NAME,
    .id_table		= ns87415_pci_tbl,
    .probe			= ns87415_init_one,
    .remove			= ata_pci_remove_one,
#ifdef CONFIG_PM
    .suspend		= ata_pci_device_suspend,
    .resume			= ata_pci_device_resume,
#endif
};

static int __init ns87415_init(void)
{
    return pci_register_driver(&ns87415_pci_driver);
}

static void __exit ns87415_exit(void)
{
    pci_unregister_driver(&ns87415_pci_driver);
}

module_init(ns87415_init);
module_exit(ns87415_exit);

MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("ATA low-level driver for NS87415 controllers");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, ns87415_pci_tbl);
MODULE_VERSION(DRV_VERSION);
static int __devinit pmic8xxx_kp_probe(struct platform_device *pdev)
{
	const struct pm8xxx_keypad_platform_data *pdata =
					dev_get_platdata(&pdev->dev);
	const struct matrix_keymap_data *keymap_data;
	struct pmic8xxx_kp *kp;
	int rc;
	u8 ctrl_val;
	struct device *sec_key;

	struct pm_gpio kypd_drv = {
		.direction	= PM_GPIO_DIR_OUT,
		.output_buffer	= PM_GPIO_OUT_BUF_OPEN_DRAIN,
		.output_value	= 0,
		.pull		= PM_GPIO_PULL_NO,
		.vin_sel	= PM_GPIO_VIN_S4,
		.out_strength	= PM_GPIO_STRENGTH_LOW,
		.function	= PM_GPIO_FUNC_1,
		.inv_int_pol	= 1,
	};

	struct pm_gpio kypd_sns = {
		.direction	= PM_GPIO_DIR_IN,
		.pull		= PM_GPIO_PULL_UP_31P5,
		.vin_sel	= PM_GPIO_VIN_S4,
		.out_strength	= PM_GPIO_STRENGTH_NO,
		.function	= PM_GPIO_FUNC_NORMAL,
		.inv_int_pol	= 1,
	};


	if (!pdata || !pdata->num_cols || !pdata->num_rows ||
		pdata->num_cols > PM8XXX_MAX_COLS ||
		pdata->num_rows > PM8XXX_MAX_ROWS ||
		pdata->num_cols < PM8XXX_MIN_COLS) {
		dev_err(&pdev->dev, "invalid platform data\n");
		return -EINVAL;
	}

	if (!pdata->scan_delay_ms ||
		pdata->scan_delay_ms > MAX_SCAN_DELAY ||
		pdata->scan_delay_ms < MIN_SCAN_DELAY ||
		!is_power_of_2(pdata->scan_delay_ms)) {
		dev_err(&pdev->dev, "invalid keypad scan time supplied\n");
		return -EINVAL;
	}

	if (!pdata->row_hold_ns ||
		pdata->row_hold_ns > MAX_ROW_HOLD_DELAY ||
		pdata->row_hold_ns < MIN_ROW_HOLD_DELAY ||
		((pdata->row_hold_ns % MIN_ROW_HOLD_DELAY) != 0)) {
		dev_err(&pdev->dev, "invalid keypad row hold time supplied\n");
		return -EINVAL;
	}

	if (!pdata->debounce_ms ||
		((pdata->debounce_ms % 5) != 0) ||
		pdata->debounce_ms > MAX_DEBOUNCE_TIME ||
		pdata->debounce_ms < MIN_DEBOUNCE_TIME) {
		dev_err(&pdev->dev, "invalid debounce time supplied\n");
		return -EINVAL;
	}

	keymap_data = pdata->keymap_data;
	if (!keymap_data) {
		dev_err(&pdev->dev, "no keymap data supplied\n");
		return -EINVAL;
	}

	kp = kzalloc(sizeof(*kp), GFP_KERNEL);
	if (!kp)
		return -ENOMEM;

	platform_set_drvdata(pdev, kp);

	kp->pdata	= pdata;
	kp->dev		= &pdev->dev;

	kp->input = input_allocate_device();
	if (!kp->input) {
		dev_err(&pdev->dev, "unable to allocate input device\n");
		rc = -ENOMEM;
		goto err_alloc_device;
	}

	kp->key_sense_irq = platform_get_irq(pdev, 0);
	if (kp->key_sense_irq < 0) {
		dev_err(&pdev->dev, "unable to get keypad sense irq\n");
		rc = -ENXIO;
		goto err_get_irq;
	}

	kp->key_stuck_irq = platform_get_irq(pdev, 1);
	if (kp->key_stuck_irq < 0) {
		dev_err(&pdev->dev, "unable to get keypad stuck irq\n");
		rc = -ENXIO;
		goto err_get_irq;
	}

	kp->input->name = pdata->input_name ? : "PMIC8XXX keypad";
	kp->input->phys = pdata->input_phys_device ? : "pmic8xxx_keypad/input0";

	kp->input->dev.parent	= &pdev->dev;

	kp->input->id.bustype	= BUS_I2C;
	kp->input->id.version	= 0x0001;
	kp->input->id.product	= 0x0001;
	kp->input->id.vendor	= 0x0001;

	kp->input->evbit[0]	= BIT_MASK(EV_KEY);

	if (pdata->rep)
		__set_bit(EV_REP, kp->input->evbit);

	kp->input->keycode	= kp->keycodes;
	kp->input->keycodemax	= PM8XXX_MATRIX_MAX_SIZE;
	kp->input->keycodesize	= sizeof(kp->keycodes);
	kp->input->open		= pmic8xxx_kp_open;
	kp->input->close	= pmic8xxx_kp_close;

	matrix_keypad_build_keymap(keymap_data, PM8XXX_ROW_SHIFT,
					kp->input->keycode, kp->input->keybit);

	get_volumekey_matrix(keymap_data,
					&volup_matrix, &voldown_matrix);

	input_set_capability(kp->input, EV_MSC, MSC_SCAN);
	input_set_drvdata(kp->input, kp);

	/* initialize keypad state */
	memset(kp->keystate, 0xff, sizeof(kp->keystate));
	memset(kp->stuckstate, 0xff, sizeof(kp->stuckstate));

	rc = pmic8xxx_kpd_init(kp);
	if (rc < 0) {
		dev_err(&pdev->dev, "unable to initialize keypad controller\n");
		goto err_get_irq;
	}

	rc = pmic8xxx_kp_config_gpio(pdata->cols_gpio_start,
					pdata->num_cols, kp, &kypd_sns);
	if (rc < 0) {
		dev_err(&pdev->dev, "unable to configure keypad sense lines\n");
		goto err_gpio_config;
	}

	rc = pmic8xxx_kp_config_gpio(pdata->rows_gpio_start,
					pdata->num_rows, kp, &kypd_drv);
	if (rc < 0) {
		dev_err(&pdev->dev, "unable to configure keypad drive lines\n");
		goto err_gpio_config;
	}

	rc = request_any_context_irq(kp->key_sense_irq, pmic8xxx_kp_irq,
				 IRQF_TRIGGER_RISING, "pmic-keypad", kp);
	if (rc < 0) {
		dev_err(&pdev->dev, "failed to request keypad sense irq\n");
		goto err_get_irq;
	}

	rc = request_any_context_irq(kp->key_stuck_irq, pmic8xxx_kp_stuck_irq,
				 IRQF_TRIGGER_RISING, "pmic-keypad-stuck", kp);
	if (rc < 0) {
		dev_err(&pdev->dev, "failed to request keypad stuck irq\n");
		goto err_req_stuck_irq;
	}

	rc = pmic8xxx_kp_read_u8(kp, &ctrl_val, KEYP_CTRL);
	if (rc < 0) {
		dev_err(&pdev->dev, "failed to read KEYP_CTRL register\n");
		goto err_pmic_reg_read;
	}

	rc = request_threaded_irq(MSM_GPIO_KEY_VOLUP_IRQ ,
		NULL, pmic8058_volume_up_irq, IRQF_TRIGGER_RISING |
		IRQF_TRIGGER_FALLING, "vol_up", kp);

	if (rc < 0) {
				dev_err(&pdev->dev, "failed to request vol_up irq\n");
		goto err_req_sense_irq;
	}

	rc = request_threaded_irq(MSM_GPIO_KEY_VOLDOWN_IRQ ,
		NULL, pmic8058_volume_down_irq, IRQF_TRIGGER_RISING |
		IRQF_TRIGGER_FALLING, "vol_down", kp);

	if (rc < 0) {
		dev_err(&pdev->dev, "failed to request vol_down irq\n");
		goto err_req_sense_irq;
	}
	kp->ctrl_reg = ctrl_val;

#if defined CONFIG_MACH_VITAL2REFRESH


	gpio_tlmm_config(GPIO_CFG(MSM_HALL_IC, 1, GPIO_CFG_INPUT,
		GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE);

	input_set_capability(kp->input, EV_SW, SW_LID);

	if (gpio_get_value(MSM_HALL_IC)) {
		input_report_switch(kp->input, SW_LID, 1);
	}
	else {
		input_report_switch(kp->input, SW_LID, 0);
	}

	input_sync(kp->input);

	printk(KERN_INFO "[input_report_switch] slide_int - !gpio_hall_ic %s\n",
			gpio_get_value(MSM_HALL_IC) == 0 ? "OPEN" : "CLOSE");

	rc = request_threaded_irq(MSM_GPIO_TO_INT(MSM_HALL_IC), NULL,
		hall_ic_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
							"hall_ic", kp);

	if (rc < 0) {
		dev_err(&pdev->dev, "failed to request hall_ic irq\n");
		goto err_hall_ic_irq;
	}

#endif
	rc = input_register_device(kp->input);
	if (rc < 0) {
		dev_err(&pdev->dev, "unable to register keypad input device\n");
		goto err_pmic_reg_read;
	}

	sec_key = device_create(sec_class, NULL, 0, NULL, "sec_key");
	if (IS_ERR(sec_key))
		pr_err("Failed to create device(sec_key)!\n");

	rc = device_create_file(sec_key, &dev_attr_sec_key_pressed);
	if (rc) {
		pr_err("Failed to create device file - pressed(%s), err(%d)!\n",
				dev_attr_sec_key_pressed.attr.name, rc);
	}

	dev_set_drvdata(sec_key, kp);

	device_init_wakeup(&pdev->dev, pdata->wakeup);

	return 0;

err_pmic_reg_read:
	free_irq(kp->key_stuck_irq, kp);
err_req_stuck_irq:
	free_irq(kp->key_sense_irq, kp);
#if defined CONFIG_MACH_VITAL2REFRESH
err_hall_ic_irq:
#endif
err_req_sense_irq:
err_gpio_config:
err_get_irq:
	input_free_device(kp->input);
err_alloc_device:
	platform_set_drvdata(pdev, NULL);
	kfree(kp);
	return rc;
}

static int __devexit pmic8xxx_kp_remove(struct platform_device *pdev)
{
	struct pmic8xxx_kp *kp = platform_get_drvdata(pdev);

	device_init_wakeup(&pdev->dev, 0);
	free_irq(kp->key_stuck_irq, kp);
	free_irq(kp->key_sense_irq, kp);
	input_unregister_device(kp->input);
	kfree(kp);

	platform_set_drvdata(pdev, NULL);
	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int pmic8xxx_kp_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct pmic8xxx_kp *kp = platform_get_drvdata(pdev);
	struct input_dev *input_dev = kp->input;

	if (device_may_wakeup(dev)) {
		enable_irq_wake(kp->key_sense_irq);
	} else {
		mutex_lock(&input_dev->mutex);

#if defined CONFIG_MACH_VITAL2REFRESH
	enable_irq_wake(MSM_GPIO_TO_INT(MSM_HALL_IC));
	/* to wakeup in case of sleep */
#endif
		if (input_dev->users)
			pmic8xxx_kp_disable(kp);

		mutex_unlock(&input_dev->mutex);
	}

	return 0;
}

static int pmic8xxx_kp_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct pmic8xxx_kp *kp = platform_get_drvdata(pdev);
	struct input_dev *input_dev = kp->input;

	if (device_may_wakeup(dev)) {
		disable_irq_wake(kp->key_sense_irq);
	} else {
		mutex_lock(&input_dev->mutex);

#if defined CONFIG_MACH_VITAL2REFRESH
	disable_irq_wake(MSM_GPIO_TO_INT(MSM_HALL_IC)); /* to match irq pair */
#endif
	if (input_dev->users)
		pmic8xxx_kp_enable(kp);
		mutex_unlock(&input_dev->mutex);
	}

	return 0;
}
#endif

static SIMPLE_DEV_PM_OPS(pm8xxx_kp_pm_ops,
			 pmic8xxx_kp_suspend, pmic8xxx_kp_resume);

static struct platform_driver pmic8xxx_kp_driver = {
	.probe		= pmic8xxx_kp_probe,
	.remove		= __devexit_p(pmic8xxx_kp_remove),
	.driver		= {
		.name = PM8XXX_KEYPAD_DEV_NAME,
		.owner = THIS_MODULE,
		.pm = &pm8xxx_kp_pm_ops,
	},
};

static int __init pmic8xxx_kp_init(void)
{
	return platform_driver_register(&pmic8xxx_kp_driver);
}
module_init(pmic8xxx_kp_init);

static void __exit pmic8xxx_kp_exit(void)
{
	platform_driver_unregister(&pmic8xxx_kp_driver);
}
module_exit(pmic8xxx_kp_exit);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("PMIC8XXX keypad driver");
MODULE_VERSION("1.0");
MODULE_ALIAS("platform:pmic8xxx_keypad");
MODULE_AUTHOR("Trilok Soni <*****@*****.**>");
Esempio n. 13
0
static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
	static const struct ata_port_info info = {
		.flags = ATA_FLAG_SLAVE_POSS,
		.pio_mask = 0x1f,
		.mwdma_mask = 0x07,
		.udma_mask = 0x07,
		.port_ops = &cs5530_port_ops
	};
	/* The docking connector doesn't do UDMA, and it seems not MWDMA */
	static const struct ata_port_info info_palmax_secondary = {
		.flags = ATA_FLAG_SLAVE_POSS,
		.pio_mask = 0x1f,
		.port_ops = &cs5530_port_ops
	};
	const struct ata_port_info *ppi[] = { &info, NULL };
	int rc;

	rc = pcim_enable_device(pdev);
	if (rc)
		return rc;

	/* Chip initialisation */
	if (cs5530_init_chip())
		return -ENODEV;

	if (cs5530_is_palmax())
		ppi[1] = &info_palmax_secondary;

	/* Now kick off ATA set up */
	return ata_pci_sff_init_one(pdev, ppi, &cs5530_sht, NULL);
}

#ifdef CONFIG_PM
static int cs5530_reinit_one(struct pci_dev *pdev)
{
	struct ata_host *host = dev_get_drvdata(&pdev->dev);
	int rc;

	rc = ata_pci_device_do_resume(pdev);
	if (rc)
		return rc;

	/* If we fail on resume we are doomed */
	if (cs5530_init_chip())
		return -EIO;

	ata_host_resume(host);
	return 0;
}
#endif /* CONFIG_PM */

static const struct pci_device_id cs5530[] = {
	{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), },

	{ },
};

static struct pci_driver cs5530_pci_driver = {
	.name 		= DRV_NAME,
	.id_table	= cs5530,
	.probe 		= cs5530_init_one,
	.remove		= ata_pci_remove_one,
#ifdef CONFIG_PM
	.suspend	= ata_pci_device_suspend,
	.resume		= cs5530_reinit_one,
#endif
};

static int __init cs5530_init(void)
{
	return pci_register_driver(&cs5530_pci_driver);
}

static void __exit cs5530_exit(void)
{
	pci_unregister_driver(&cs5530_pci_driver);
}

MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for the Cyrix/NS/AMD 5530");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, cs5530);
MODULE_VERSION(DRV_VERSION);

module_init(cs5530_init);
module_exit(cs5530_exit);
Esempio n. 14
0
static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
	static const struct ata_port_info info_82c700 = {
		.flags = ATA_FLAG_SLAVE_POSS,
		.pio_mask = 0x1f,
		.mwdma_mask = 0x07,
		.port_ops = &optidma_port_ops
	};
	static const struct ata_port_info info_82c700_udma = {
		.flags = ATA_FLAG_SLAVE_POSS,
		.pio_mask = 0x1f,
		.mwdma_mask = 0x07,
		.udma_mask = 0x07,
		.port_ops = &optiplus_port_ops
	};
	const struct ata_port_info *ppi[] = { &info_82c700, NULL };
	static int printed_version;
	int rc;

	if (!printed_version++)
		dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n");

	rc = pcim_enable_device(dev);
	if (rc)
		return rc;

	/* Fixed location chipset magic */
	inw(0x1F1);
	inw(0x1F1);
	pci_clock = inb(0x1F5) & 1;		/* 0 = 33Mhz, 1 = 25Mhz */

	if (optiplus_with_udma(dev))
		ppi[0] = &info_82c700_udma;

	return ata_pci_sff_init_one(dev, ppi, &optidma_sht, NULL);
}

static const struct pci_device_id optidma[] = {
	{ PCI_VDEVICE(OPTI, 0xD568), },		/* Opti 82C700 */

	{ },
};

static struct pci_driver optidma_pci_driver = {
	.name 		= DRV_NAME,
	.id_table	= optidma,
	.probe 		= optidma_init_one,
	.remove		= ata_pci_remove_one,
#ifdef CONFIG_PM
	.suspend	= ata_pci_device_suspend,
	.resume		= ata_pci_device_resume,
#endif
};

static int __init optidma_init(void)
{
	return pci_register_driver(&optidma_pci_driver);
}

static void __exit optidma_exit(void)
{
	pci_unregister_driver(&optidma_pci_driver);
}

MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("low-level driver for Opti Firestar/Firestar Plus");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, optidma);
MODULE_VERSION(DRV_VERSION);

module_init(optidma_init);
module_exit(optidma_exit);