Ejemplo n.º 1
0
static void reserve_resources_of_dev(struct pnp_dev *dev)
{
	struct resource *res;
	int i;

	for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
		if (res->flags & IORESOURCE_DISABLED)
			continue;
		if (res->start == 0)
			continue;	/* disabled */
		if (res->start < 0x100)
			/*
			 * Below 0x100 is only standard PC hardware
			 * (pics, kbd, timer, dma, ...)
			 * We should not get resource conflicts there,
			 * and the kernel reserves these anyway
			 * (see arch/i386/kernel/setup.c).
			 * So, do nothing
			 */
			continue;
		if (res->end < res->start)
			continue;	/* invalid */

		reserve_range(dev, res, 1);
	}

	for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
		if (res->flags & IORESOURCE_DISABLED)
			continue;

		reserve_range(dev, res, 0);
	}
}
Ejemplo n.º 2
0
static void reserve_resources_of_dev(struct pnp_dev *dev)
{
	struct resource *res;
	int i;

	for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
		if (res->flags & IORESOURCE_DISABLED)
			continue;
		if (res->start == 0)
			continue;	
		if (res->start < 0x100)
			continue;
		if (res->end < res->start)
			continue;	

		reserve_range(dev, res, 1);
	}

	for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
		if (res->flags & IORESOURCE_DISABLED)
			continue;

		reserve_range(dev, res, 0);
	}
}
Ejemplo n.º 3
0
static int
serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
{
	struct uart_8250_port uart;
	int ret, line, flags = dev_id->driver_data;
	struct resource *res = NULL;

	if (flags & UNKNOWN_DEV) {
		ret = serial_pnp_guess_board(dev);
		if (ret < 0)
			return ret;
	}

	memset(&uart, 0, sizeof(uart));
	if (pnp_irq_valid(dev, 0))
		uart.port.irq = pnp_irq(dev, 0);
	if ((flags & CIR_PORT) && pnp_port_valid(dev, 2))
		res = pnp_get_resource(dev, IORESOURCE_IO, 2);
	else if (pnp_port_valid(dev, 0))
		res = pnp_get_resource(dev, IORESOURCE_IO, 0);
	if (pnp_resource_enabled(res)) {
		uart.port.iobase = res->start;
		uart.port.iotype = UPIO_PORT;
	} else if (pnp_mem_valid(dev, 0)) {
		uart.port.mapbase = pnp_mem_start(dev, 0);
		uart.port.iotype = UPIO_MEM;
		uart.port.flags = UPF_IOREMAP;
	} else
		return -ENODEV;

#ifdef SERIAL_DEBUG_PNP
	printk(KERN_DEBUG
		"Setup PNP port: port %x, mem 0x%lx, irq %d, type %d\n",
		       uart.port.iobase, uart.port.mapbase, uart.port.irq, uart.port.iotype);
#endif
	if (flags & CIR_PORT) {
		uart.port.flags |= UPF_FIXED_PORT | UPF_FIXED_TYPE;
		uart.port.type = PORT_8250_CIR;
	}

	uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
	if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE)
		uart.port.flags |= UPF_SHARE_IRQ;
	uart.port.uartclk = 1843200;
	uart.port.dev = &dev->dev;

	line = serial8250_register_8250_port(&uart);
	if (line < 0 || (flags & CIR_PORT))
		return -ENODEV;

	pnp_set_drvdata(dev, (void *)((long)line + 1));
	return 0;
}
Ejemplo n.º 4
0
static int __devinit
cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
{
	cmos_wake_setup(&pnp->dev);

	if (pnp_port_start(pnp,0) == 0x70 && !pnp_irq_valid(pnp,0))
		return cmos_do_probe(&pnp->dev,
				pnp_get_resource(pnp, IORESOURCE_IO, 0), 8);
	else
		return cmos_do_probe(&pnp->dev,
				pnp_get_resource(pnp, IORESOURCE_IO, 0),
				pnp_irq(pnp, 0));
}
Ejemplo n.º 5
0
static int __devinit
cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
{
	if (pnp_port_start(pnp,0) == 0x70 && !pnp_irq_valid(pnp,0))
		/* Some machines contain a PNP entry for the RTC, but
		 * don't define the IRQ. It should always be safe to
		 * hardcode it in these cases
		 */
		return cmos_do_probe(&pnp->dev,
				pnp_get_resource(pnp, IORESOURCE_IO, 0), 8);
	else
		return cmos_do_probe(&pnp->dev,
				pnp_get_resource(pnp, IORESOURCE_IO, 0),
				pnp_irq(pnp, 0));
}
Ejemplo n.º 6
0
int pnpacpi_encode_resources(struct pnp_dev *dev, struct acpi_buffer *buffer)
{
	int i = 0;
	/* pnpacpi_build_resource_template allocates extra mem */
	int res_cnt = (buffer->length - 1) / sizeof(struct acpi_resource) - 1;
	struct acpi_resource *resource = buffer->pointer;
	int port = 0, irq = 0, dma = 0, mem = 0;

	pnp_dbg(&dev->dev, "encode %d resources\n", res_cnt);
	while (i < res_cnt) {
		switch (resource->type) {
		case ACPI_RESOURCE_TYPE_IRQ:
			pnpacpi_encode_irq(dev, resource,
			       pnp_get_resource(dev, IORESOURCE_IRQ, irq));
			irq++;
			break;

		case ACPI_RESOURCE_TYPE_DMA:
			pnpacpi_encode_dma(dev, resource,
				pnp_get_resource(dev, IORESOURCE_DMA, dma));
			dma++;
			break;
		case ACPI_RESOURCE_TYPE_IO:
			pnpacpi_encode_io(dev, resource,
				pnp_get_resource(dev, IORESOURCE_IO, port));
			port++;
			break;
		case ACPI_RESOURCE_TYPE_FIXED_IO:
			pnpacpi_encode_fixed_io(dev, resource,
				pnp_get_resource(dev, IORESOURCE_IO, port));
			port++;
			break;
		case ACPI_RESOURCE_TYPE_MEMORY24:
			pnpacpi_encode_mem24(dev, resource,
				pnp_get_resource(dev, IORESOURCE_MEM, mem));
			mem++;
			break;
		case ACPI_RESOURCE_TYPE_MEMORY32:
			pnpacpi_encode_mem32(dev, resource,
				pnp_get_resource(dev, IORESOURCE_MEM, mem));
			mem++;
			break;
		case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
			pnpacpi_encode_fixed_mem32(dev, resource,
				pnp_get_resource(dev, IORESOURCE_MEM, mem));
			mem++;
			break;
		case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
			pnpacpi_encode_ext_irq(dev, resource,
				pnp_get_resource(dev, IORESOURCE_IRQ, irq));
			irq++;
			break;
		case ACPI_RESOURCE_TYPE_START_DEPENDENT:
		case ACPI_RESOURCE_TYPE_END_DEPENDENT:
		case ACPI_RESOURCE_TYPE_VENDOR:
		case ACPI_RESOURCE_TYPE_END_TAG:
		case ACPI_RESOURCE_TYPE_ADDRESS16:
		case ACPI_RESOURCE_TYPE_ADDRESS32:
		case ACPI_RESOURCE_TYPE_ADDRESS64:
		case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64:
		case ACPI_RESOURCE_TYPE_GENERIC_REGISTER:
		default:	/* other type */
			dev_warn(&dev->dev, "can't encode unknown resource "
				 "type %d\n", resource->type);
			return -EINVAL;
		}
		resource++;
		i++;
	}
	return 0;
}
Ejemplo n.º 7
0
static int __devinit gmux_probe(struct pnp_dev *pnp,
				const struct pnp_device_id *id)
{
	struct apple_gmux_data *gmux_data;
	struct resource *res;
	struct backlight_properties props;
	struct backlight_device *bdev;
	u8 ver_major, ver_minor, ver_release;
	int ret = -ENXIO;

	gmux_data = kzalloc(sizeof(*gmux_data), GFP_KERNEL);
	if (!gmux_data)
		return -ENOMEM;
	pnp_set_drvdata(pnp, gmux_data);

	res = pnp_get_resource(pnp, IORESOURCE_IO, 0);
	if (!res) {
		pr_err("Failed to find gmux I/O resource\n");
		goto err_free;
	}

	gmux_data->iostart = res->start;
	gmux_data->iolen = res->end - res->start;

	if (gmux_data->iolen < GMUX_MIN_IO_LEN) {
		pr_err("gmux I/O region too small (%lu < %u)\n",
		       gmux_data->iolen, GMUX_MIN_IO_LEN);
		goto err_free;
	}

	if (!request_region(gmux_data->iostart, gmux_data->iolen,
			    "Apple gmux")) {
		pr_err("gmux I/O already in use\n");
		goto err_free;
	}

	/*
	 * On some machines the gmux is in ACPI even thought the machine
	 * doesn't really have a gmux. Check for invalid version information
	 * to detect this.
	 */
	ver_major = gmux_read8(gmux_data, GMUX_PORT_VERSION_MAJOR);
	ver_minor = gmux_read8(gmux_data, GMUX_PORT_VERSION_MINOR);
	ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE);
	if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) {
		pr_info("gmux device not present\n");
		ret = -ENODEV;
		goto err_release;
	}

	pr_info("Found gmux version %d.%d.%d\n", ver_major, ver_minor,
		ver_release);

	memset(&props, 0, sizeof(props));
	props.type = BACKLIGHT_PLATFORM;
	props.max_brightness = gmux_read32(gmux_data, GMUX_PORT_MAX_BRIGHTNESS);

	/*
	 * Currently it's assumed that the maximum brightness is less than
	 * 2^24 for compatibility with old gmux versions. Cap the max
	 * brightness at this value, but print a warning if the hardware
	 * reports something higher so that it can be fixed.
	 */
	if (WARN_ON(props.max_brightness > GMUX_MAX_BRIGHTNESS))
		props.max_brightness = GMUX_MAX_BRIGHTNESS;

	bdev = backlight_device_register("gmux_backlight", &pnp->dev,
					 gmux_data, &gmux_bl_ops, &props);
	if (IS_ERR(bdev)) {
		ret = PTR_ERR(bdev);
		goto err_release;
	}

	gmux_data->bdev = bdev;
	bdev->props.brightness = gmux_get_brightness(bdev);
	backlight_update_status(bdev);

	/*
	 * The backlight situation on Macs is complicated. If the gmux is
	 * present it's the best choice, because it always works for
	 * backlight control and supports more levels than other options.
	 * Disable the other backlight choices.
	 */
	acpi_video_dmi_promote_vendor();
#ifdef CONFIG_ACPI_VIDEO
	acpi_video_unregister();
#endif
	apple_bl_unregister();

	return 0;

err_release:
	release_region(gmux_data->iostart, gmux_data->iolen);
err_free:
	kfree(gmux_data);
	return ret;
}
Ejemplo n.º 8
0
Archivo: quirks.c Proyecto: 274914765/C
static void quirk_system_pci_resources(struct pnp_dev *dev)
{
    struct pci_dev *pdev = NULL;
    struct resource *res;
    resource_size_t pnp_start, pnp_end, pci_start, pci_end;
    int i, j;

    /*
     * Some BIOSes have PNP motherboard devices with resources that
     * partially overlap PCI BARs.  The PNP system driver claims these
     * motherboard resources, which prevents the normal PCI driver from
     * requesting them later.
     *
     * This patch disables the PNP resources that conflict with PCI BARs
     * so they won't be claimed by the PNP system driver.
     */
    for_each_pci_dev(pdev) {
        for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
            if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM) ||
                pci_resource_len(pdev, i) == 0)
                continue;

            pci_start = pci_resource_start(pdev, i);
            pci_end = pci_resource_end(pdev, i);
            for (j = 0;
                 (res = pnp_get_resource(dev, IORESOURCE_MEM, j));
                 j++) {
                if (res->flags & IORESOURCE_UNSET ||
                    (res->start == 0 && res->end == 0))
                    continue;

                pnp_start = res->start;
                pnp_end = res->end;

                /*
                 * If the PNP region doesn't overlap the PCI
                 * region at all, there's no problem.
                 */
                if (pnp_end < pci_start || pnp_start > pci_end)
                    continue;

                /*
                 * If the PNP region completely encloses (or is
                 * at least as large as) the PCI region, that's
                 * also OK.  For example, this happens when the
                 * PNP device describes a bridge with PCI
                 * behind it.
                 */
                if (pnp_start <= pci_start &&
                    pnp_end >= pci_end)
                    continue;

                /*
                 * Otherwise, the PNP region overlaps *part* of
                 * the PCI region, and that might prevent a PCI
                 * driver from requesting its resources.
                 */
                dev_warn(&dev->dev, "mem resource "
                    "(0x%llx-0x%llx) overlaps %s BAR %d "
                    "(0x%llx-0x%llx), disabling\n",
                    (unsigned long long) pnp_start,
                    (unsigned long long) pnp_end,
                    pci_name(pdev), i,
                    (unsigned long long) pci_start,
                    (unsigned long long) pci_end);
                res->flags |= IORESOURCE_DISABLED;
            }
        }
    }
}