Commit 57fd51a8 authored by Bjorn Helgaas's avatar Bjorn Helgaas Committed by Andi Kleen
Browse files

PNP: add pnp_possible_config() -- can a device could be configured this way?



As part of a heuristic to identify modem devices, 8250_pnp.c
checks to see whether a device can be configured at any of the
legacy COM port addresses.

This patch moves the code that traverses the PNP "possible resource
options" from 8250_pnp.c to the PNP subsystem.  This encapsulation
is important because a future patch will change the implementation
of those resource options.

Signed-off-by: default avatarBjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: default avatarAndi Kleen <ak@linux.intel.com>
Acked-by: default avatarRene Herman <rene.herman@gmail.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent f61ed7e3
Loading
Loading
Loading
Loading
+62 −0
Original line number Diff line number Diff line
@@ -624,6 +624,68 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
	return pnp_res;
}

static int pnp_possible_option(struct pnp_option *option, int type,
			       resource_size_t start, resource_size_t size)
{
	struct pnp_option *tmp;
	struct pnp_port *port;
	struct pnp_mem *mem;
	struct pnp_irq *irq;
	struct pnp_dma *dma;

	if (!option)
		return 0;

	for (tmp = option; tmp; tmp = tmp->next) {
		switch (type) {
		case IORESOURCE_IO:
			for (port = tmp->port; port; port = port->next) {
				if (port->min == start && port->size == size)
					return 1;
			}
			break;
		case IORESOURCE_MEM:
			for (mem = tmp->mem; mem; mem = mem->next) {
				if (mem->min == start && mem->size == size)
					return 1;
			}
			break;
		case IORESOURCE_IRQ:
			for (irq = tmp->irq; irq; irq = irq->next) {
				if (start < PNP_IRQ_NR &&
				    test_bit(start, irq->map))
					return 1;
			}
			break;
		case IORESOURCE_DMA:
			for (dma = tmp->dma; dma; dma = dma->next) {
				if (dma->map & (1 << start))
					return 1;
			}
			break;
		}
	}

	return 0;
}

/*
 * Determine whether the specified resource is a possible configuration
 * for this device.
 */
int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start,
			resource_size_t size)
{
	if (pnp_possible_option(dev->independent, type, start, size))
		return 1;

	if (pnp_possible_option(dev->dependent, type, start, size))
		return 1;

	return 0;
}
EXPORT_SYMBOL(pnp_possible_config);

/* format is: pnp_reserve_irq=irq1[,irq2] .... */
static int __init pnp_setup_reserve_irq(char *str)
{
+7 −17
Original line number Diff line number Diff line
@@ -383,20 +383,13 @@ static int __devinit check_name(char *name)
	return 0;
}

static int __devinit check_resources(struct pnp_option *option)
static int __devinit check_resources(struct pnp_dev *dev)
{
	struct pnp_option *tmp;
	if (!option)
		return 0;
	resource_size_t base[] = {0x2f8, 0x3f8, 0x2e8, 0x3e8};
	int i;

	for (tmp = option; tmp; tmp = tmp->next) {
		struct pnp_port *port;
		for (port = tmp->port; port; port = port->next)
			if ((port->size == 8) &&
			    ((port->min == 0x2f8) ||
			     (port->min == 0x3f8) ||
			     (port->min == 0x2e8) ||
			     (port->min == 0x3e8)))
	for (i = 0; i < ARRAY_SIZE(base); i++) {
		if (pnp_possible_config(dev, IORESOURCE_IO, base[i], 8))
			return 1;
	}

@@ -420,10 +413,7 @@ static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags)
		(dev->card && check_name(dev->card->name))))
			return -ENODEV;

	if (check_resources(dev->independent))
		return 0;

	if (check_resources(dev->dependent))
	if (check_resources(dev))
		return 0;

	return -ENODEV;
+5 −0
Original line number Diff line number Diff line
@@ -479,6 +479,8 @@ void pnp_unregister_card_driver(struct pnp_card_driver *drv);
extern struct list_head pnp_cards;

/* resource management */
int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t base,
			resource_size_t size);
int pnp_auto_config_dev(struct pnp_dev *dev);
int pnp_start_dev(struct pnp_dev *dev);
int pnp_stop_dev(struct pnp_dev *dev);
@@ -506,6 +508,9 @@ static inline int pnp_register_card_driver(struct pnp_card_driver *drv) { return
static inline void pnp_unregister_card_driver(struct pnp_card_driver *drv) { }

/* resource management */
static inline int pnp_possible_config(struct pnp_dev *dev, int type,
				      resource_size_t base,
				      resource_size_t size) { return 0; }
static inline int pnp_auto_config_dev(struct pnp_dev *dev) { return -ENODEV; }
static inline int pnp_start_dev(struct pnp_dev *dev) { return -ENODEV; }
static inline int pnp_stop_dev(struct pnp_dev *dev) { return -ENODEV; }