static int sonypi_probe()

in sonypi.c [1288:1410]


static int sonypi_probe(struct platform_device *dev)
{
	const struct sonypi_ioport_list *ioport_list;
	const struct sonypi_irq_list *irq_list;
	struct pci_dev *pcidev;
	int error;

	printk(KERN_WARNING "sonypi: please try the sony-laptop module instead "
			"and report failures, see also "
			"http://www.linux.it/~malattia/wiki/index.php/Sony_drivers\n");

	spin_lock_init(&sonypi_device.fifo_lock);
	error = kfifo_alloc(&sonypi_device.fifo, SONYPI_BUF_SIZE, GFP_KERNEL);
	if (error) {
		printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
		return error;
	}

	init_waitqueue_head(&sonypi_device.fifo_proc_list);
	mutex_init(&sonypi_device.lock);
	sonypi_device.bluetooth_power = -1;

	if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
				     PCI_DEVICE_ID_INTEL_82371AB_3, NULL)))
		sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE1;
	else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
					  PCI_DEVICE_ID_INTEL_ICH6_1, NULL)))
		sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3;
	else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
					  PCI_DEVICE_ID_INTEL_ICH7_1, NULL)))
		sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3;
	else
		sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE2;

	if (pcidev && pci_enable_device(pcidev)) {
		printk(KERN_ERR "sonypi: pci_enable_device failed\n");
		error = -EIO;
		goto err_put_pcidev;
	}

	sonypi_device.dev = pcidev;

	if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) {
		ioport_list = sonypi_type1_ioport_list;
		sonypi_device.region_size = SONYPI_TYPE1_REGION_SIZE;
		sonypi_device.evtype_offset = SONYPI_TYPE1_EVTYPE_OFFSET;
		irq_list = sonypi_type1_irq_list;
	} else if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) {
		ioport_list = sonypi_type2_ioport_list;
		sonypi_device.region_size = SONYPI_TYPE2_REGION_SIZE;
		sonypi_device.evtype_offset = SONYPI_TYPE2_EVTYPE_OFFSET;
		irq_list = sonypi_type2_irq_list;
	} else {
		ioport_list = sonypi_type3_ioport_list;
		sonypi_device.region_size = SONYPI_TYPE3_REGION_SIZE;
		sonypi_device.evtype_offset = SONYPI_TYPE3_EVTYPE_OFFSET;
		irq_list = sonypi_type3_irq_list;
	}

	error = sonypi_setup_ioports(&sonypi_device, ioport_list);
	if (error) {
		printk(KERN_ERR "sonypi: failed to request ioports\n");
		goto err_disable_pcidev;
	}

	error = sonypi_setup_irq(&sonypi_device, irq_list);
	if (error) {
		printk(KERN_ERR "sonypi: request_irq failed\n");
		goto err_free_ioports;
	}

	if (minor != -1)
		sonypi_misc_device.minor = minor;
	error = misc_register(&sonypi_misc_device);
	if (error) {
		printk(KERN_ERR "sonypi: misc_register failed\n");
		goto err_free_irq;
	}

	sonypi_display_info();

	if (useinput) {

		error = sonypi_create_input_devices(dev);
		if (error) {
			printk(KERN_ERR
				"sonypi: failed to create input devices\n");
			goto err_miscdev_unregister;
		}

		spin_lock_init(&sonypi_device.input_fifo_lock);
		error = kfifo_alloc(&sonypi_device.input_fifo, SONYPI_BUF_SIZE,
				GFP_KERNEL);
		if (error) {
			printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
			goto err_inpdev_unregister;
		}

		INIT_WORK(&sonypi_device.input_work, input_keyrelease);
	}

	sonypi_enable(0);

	return 0;

 err_inpdev_unregister:
	input_unregister_device(sonypi_device.input_key_dev);
	input_unregister_device(sonypi_device.input_jog_dev);
 err_miscdev_unregister:
	misc_deregister(&sonypi_misc_device);
 err_free_irq:
	free_irq(sonypi_device.irq, sonypi_irq);
 err_free_ioports:
	release_region(sonypi_device.ioport1, sonypi_device.region_size);
 err_disable_pcidev:
	if (pcidev)
		pci_disable_device(pcidev);
 err_put_pcidev:
	pci_dev_put(pcidev);
	kfifo_free(&sonypi_device.fifo);

	return error;
}