diff options
| author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2005-07-27 11:41:18 +0100 | 
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-07-27 11:41:18 +0100 | 
| commit | 05caac585f8abd6c0113856bc8858e3ef214d8a6 (patch) | |
| tree | ac9f8f2cc032281af09200da514257d120510906 | |
| parent | 241fc4367b3ca5d407b043599ed980304a70b91f (diff) | |
| download | olio-linux-3.10-05caac585f8abd6c0113856bc8858e3ef214d8a6.tar.xz olio-linux-3.10-05caac585f8abd6c0113856bc8858e3ef214d8a6.zip  | |
[SERIAL] Convert parport_serial to use new 8250_pci interfaces
Convert parport_serial to use the new 8250_pci interface, converting
the table to a pciserial_board table.  This also unuses the SPCI_*
definitions in serialP.h, which can now be removed.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
| -rw-r--r-- | drivers/parport/parport_serial.c | 339 | ||||
| -rw-r--r-- | drivers/serial/8250_pci.c | 21 | ||||
| -rw-r--r-- | include/linux/8250_pci.h | 3 | ||||
| -rw-r--r-- | include/linux/serialP.h | 40 | 
4 files changed, 167 insertions, 236 deletions
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index 00498e2f120..d3dad0aac7c 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c @@ -23,13 +23,8 @@  #include <linux/pci.h>  #include <linux/parport.h>  #include <linux/parport_pc.h> -#include <linux/serial.h> -#include <linux/serialP.h> -#include <linux/list.h>  #include <linux/8250_pci.h> -#include <asm/serial.h> -  enum parport_pc_pci_cards {  	titan_110l = 0,  	titan_210l, @@ -168,182 +163,147 @@ static struct pci_device_id parport_serial_pci_tbl[] = {  };  MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl); -struct pci_board_no_ids { -	int flags; -	int num_ports; -	int base_baud; -	int uart_offset; -	int reg_shift; -	int (*init_fn)(struct pci_dev *dev, struct pci_board_no_ids *board, -			int enable); -	int first_uart_offset; -}; - -static int __devinit siig10x_init_fn(struct pci_dev *dev, struct pci_board_no_ids *board, int enable) -{ -	return pci_siig10x_fn(dev, enable); -} - -static int __devinit siig20x_init_fn(struct pci_dev *dev, struct pci_board_no_ids *board, int enable) -{ -	return pci_siig20x_fn(dev, enable); -} - -static int __devinit netmos_serial_init(struct pci_dev *dev, struct pci_board_no_ids *board, int enable) -{ -	board->num_ports = dev->subsystem_device & 0xf; -	return 0; -} - -static struct pci_board_no_ids pci_boards[] __devinitdata = { -	/* -	 * PCI Flags, Number of Ports, Base (Maximum) Baud Rate, -	 * Offset to get to next UART's registers, -	 * Register shift to use for memory-mapped I/O, -	 * Initialization function, first UART offset -	 */ - -// Cards not tested are marked n/t -// If you have one of these cards and it works for you, please tell me.. - -/* titan_110l */	{ SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 1, 921600 }, -/* titan_210l */	{ SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 2, 921600 }, -/* netmos_9xx5_combo */	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200, 0, 0, netmos_serial_init }, -/* netmos_9855 */	{ SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 1, 115200, 0, 0, netmos_serial_init }, -/* avlab_1s1p (n/t) */	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, -/* avlab_1s1p_650 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, -/* avlab_1s1p_850 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, -/* avlab_1s2p (n/t) */	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, -/* avlab_1s2p_650 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, -/* avlab_1s2p_850 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, -/* avlab_2s1p (n/t) */	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, -/* avlab_2s1p_650 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, -/* avlab_2s1p_850 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, -/* siig_1s1p_10x */	{ SPCI_FL_BASE2, 1, 460800, 0, 0, siig10x_init_fn }, -/* siig_2s1p_10x */	{ SPCI_FL_BASE2, 1, 921600, 0, 0, siig10x_init_fn }, -/* siig_2p1s_20x */	{ SPCI_FL_BASE0, 1, 921600, 0, 0, siig20x_init_fn }, -/* siig_1s1p_20x */	{ SPCI_FL_BASE0, 1, 921600, 0, 0, siig20x_init_fn }, -/* siig_2s1p_20x */	{ SPCI_FL_BASE0, 1, 921600, 0, 0, siig20x_init_fn }, +/* + * This table describes the serial "geometry" of these boards.  Any + * quirks for these can be found in drivers/serial/8250_pci.c + * + * Cards not tested are marked n/t + * If you have one of these cards and it works for you, please tell me.. + */ +static struct pciserial_board pci_parport_serial_boards[] __devinitdata = { +	[titan_110l] = { +		.flags		= FL_BASE1 | FL_BASE_BARS, +		.num_ports	= 1, +		.base_baud	= 921600, +		.uart_offset	= 8, +	}, +	[titan_210l] = { +		.flags		= FL_BASE1 | FL_BASE_BARS, +		.num_ports	= 2, +		.base_baud	= 921600, +		.uart_offset	= 8, +	}, +	[netmos_9xx5_combo] = { +		.flags		= FL_BASE0 | FL_BASE_BARS, +		.num_ports	= 1, +		.base_baud	= 115200, +		.uart_offset	= 8, +	}, +	[netmos_9855] = { +		.flags		= FL_BASE2 | FL_BASE_BARS, +		.num_ports	= 1, +		.base_baud	= 115200, +		.uart_offset	= 8, +	}, +	[avlab_1s1p] = { /* n/t */ +		.flags		= FL_BASE0 | FL_BASE_BARS, +		.num_ports	= 1, +		.base_baud	= 115200, +		.uart_offset	= 8, +	}, +	[avlab_1s1p_650] = { /* nt */ +		.flags		= FL_BASE0 | FL_BASE_BARS, +		.num_ports	= 1, +		.base_baud	= 115200, +		.uart_offset	= 8, +	}, +	[avlab_1s1p_850] = { /* nt */ +		.flags		= FL_BASE0 | FL_BASE_BARS, +		.num_ports	= 1, +		.base_baud	= 115200, +		.uart_offset	= 8, +	}, +	[avlab_1s2p] = { /* n/t */ +		.flags		= FL_BASE0 | FL_BASE_BARS, +		.num_ports	= 1, +		.base_baud	= 115200, +		.uart_offset	= 8, +	}, +	[avlab_1s2p_650] = { /* nt */ +		.flags		= FL_BASE0 | FL_BASE_BARS, +		.num_ports	= 1, +		.base_baud	= 115200, +		.uart_offset	= 8, +	}, +	[avlab_1s2p_850] = { /* nt */ +		.flags		= FL_BASE0 | FL_BASE_BARS, +		.num_ports	= 1, +		.base_baud	= 115200, +		.uart_offset	= 8, +	}, +	[avlab_2s1p] = { /* n/t */ +		.flags		= FL_BASE0 | FL_BASE_BARS, +		.num_ports	= 2, +		.base_baud	= 115200, +		.uart_offset	= 8, +	}, +	[avlab_2s1p_650] = { /* nt */ +		.flags		= FL_BASE0 | FL_BASE_BARS, +		.num_ports	= 2, +		.base_baud	= 115200, +		.uart_offset	= 8, +	}, +	[avlab_2s1p_850] = { /* nt */ +		.flags		= FL_BASE0 | FL_BASE_BARS, +		.num_ports	= 2, +		.base_baud	= 115200, +		.uart_offset	= 8, +	}, +	[siig_1s1p_10x] = { +		.flags		= FL_BASE2, +		.num_ports	= 1, +		.base_baud	= 460800, +		.uart_offset	= 8, +	}, +	[siig_2s1p_10x] = { +		.flags		= FL_BASE2, +		.num_ports	= 1, +		.base_baud	= 921600, +		.uart_offset	= 8, +	}, +	[siig_2p1s_20x] = { +		.flags		= FL_BASE0, +		.num_ports	= 1, +		.base_baud	= 921600, +		.uart_offset	= 8, +	}, +	[siig_1s1p_20x] = { +		.flags		= FL_BASE0, +		.num_ports	= 1, +		.base_baud	= 921600, +		.uart_offset	= 8, +	}, +	[siig_2s1p_20x] = { +		.flags		= FL_BASE0, +		.num_ports	= 1, +		.base_baud	= 921600, +		.uart_offset	= 8, +	},  };  struct parport_serial_private { -	int num_ser; -	int line[20]; -	struct pci_board_no_ids ser; +	struct serial_private	*serial;  	int num_par;  	struct parport *port[PARPORT_MAX];  	struct parport_pc_pci par;  }; -static int __devinit get_pci_port (struct pci_dev *dev, -				   struct pci_board_no_ids *board, -				   struct serial_struct *req, -				   int idx) -{ -	unsigned long port; -	int base_idx; -	int max_port; -	int offset; - -	base_idx = SPCI_FL_GET_BASE(board->flags); -	if (board->flags & SPCI_FL_BASE_TABLE) -		base_idx += idx; - -	if (board->flags & SPCI_FL_REGION_SZ_CAP) { -		max_port = pci_resource_len(dev, base_idx) / 8; -		if (idx >= max_port) -			return 1; -	} -			 -	offset = board->first_uart_offset; - -	/* Timedia/SUNIX uses a mixture of BARs and offsets */ -	/* Ugh, this is ugly as all hell --- TYT */ -	if(dev->vendor == PCI_VENDOR_ID_TIMEDIA )  /* 0x1409 */ -		switch(idx) { -			case 0: base_idx=0; -				break; -			case 1: base_idx=0; offset=8; -				break; -			case 2: base_idx=1;  -				break; -			case 3: base_idx=1; offset=8; -				break; -			case 4: /* BAR 2*/ -			case 5: /* BAR 3 */ -			case 6: /* BAR 4*/ -			case 7: base_idx=idx-2; /* BAR 5*/ -		} -   -	port =  pci_resource_start(dev, base_idx) + offset; - -	if ((board->flags & SPCI_FL_BASE_TABLE) == 0) -		port += idx * (board->uart_offset ? board->uart_offset : 8); - -	if (pci_resource_flags (dev, base_idx) & IORESOURCE_IO) { -		int high_bits_offset = ((sizeof(long)-sizeof(int))*8); -		req->port = port; -		if (high_bits_offset) -			req->port_high = port >> high_bits_offset; -		else -			req->port_high = 0; -		return 0; -	} -	req->io_type = SERIAL_IO_MEM; -	req->iomem_base = ioremap(port, board->uart_offset); -	req->iomem_reg_shift = board->reg_shift; -	req->port = 0; -	return req->iomem_base ? 0 : 1; -} -  /* Register the serial port(s) of a PCI card. */  static int __devinit serial_register (struct pci_dev *dev,  				      const struct pci_device_id *id)  { -	struct pci_board_no_ids *board;  	struct parport_serial_private *priv = pci_get_drvdata (dev); -	struct serial_struct serial_req; -	int base_baud; -	int k; -	int success = 0; +	struct pciserial_board *board; +	struct serial_private *serial; -	priv->ser = pci_boards[id->driver_data]; -	board = &priv->ser; -	if (board->init_fn && ((board->init_fn) (dev, board, 1) != 0)) -		return 1; +	board = &pci_parport_serial_boards[id->driver_data]; +	serial = pciserial_init_ports(dev, board); -	base_baud = board->base_baud; -	if (!base_baud) -		base_baud = BASE_BAUD; -	memset (&serial_req, 0, sizeof (serial_req)); +	if (IS_ERR(serial)) +		return PTR_ERR(serial); -	for (k = 0; k < board->num_ports; k++) { -		int line; - -		if (priv->num_ser == ARRAY_SIZE (priv->line)) { -			printk (KERN_WARNING -				"parport_serial: %s: only %u serial lines " -				"supported (%d reported)\n", pci_name (dev), -				ARRAY_SIZE (priv->line), board->num_ports); -			break; -		} - -		serial_req.irq = dev->irq; -		if (get_pci_port (dev, board, &serial_req, k)) -			break; -		serial_req.flags = ASYNC_SKIP_TEST | ASYNC_AUTOPROBE; -		serial_req.baud_base = base_baud; -		line = register_serial (&serial_req); -		if (line < 0) { -			printk (KERN_DEBUG -				"parport_serial: register_serial failed\n"); -			continue; -		} -		priv->line[priv->num_ser++] = line; -		success = 1; -	} - -	return success ? 0 : 1; +	priv->serial = serial; +	return 0;  }  /* Register the parallel port(s) of a PCI card. */ @@ -411,7 +371,7 @@ static int __devinit parport_serial_pci_probe (struct pci_dev *dev,  	priv = kmalloc (sizeof *priv, GFP_KERNEL);  	if (!priv)  		return -ENOMEM; -	priv->num_ser = priv->num_par = 0; +	memset(priv, 0, sizeof(struct parport_serial_private));  	pci_set_drvdata (dev, priv);  	err = pci_enable_device (dev); @@ -444,15 +404,12 @@ static void __devexit parport_serial_pci_remove (struct pci_dev *dev)  	struct parport_serial_private *priv = pci_get_drvdata (dev);  	int i; +	pci_set_drvdata(dev, NULL); +  	// Serial ports -	for (i = 0; i < priv->num_ser; i++) { -		unregister_serial (priv->line[i]); +	if (priv->serial) +		pciserial_remove_ports(priv->serial); -		if (priv->ser.init_fn) -			(priv->ser.init_fn) (dev, &priv->ser, 0); -	} -	pci_set_drvdata (dev, NULL); -	  	// Parallel ports  	for (i = 0; i < priv->num_par; i++)  		parport_pc_unregister_port (priv->port[i]); @@ -461,11 +418,47 @@ static void __devexit parport_serial_pci_remove (struct pci_dev *dev)  	return;  } +static int parport_serial_pci_suspend(struct pci_dev *dev, pm_message_t state) +{ +	struct parport_serial_private *priv = pci_get_drvdata(dev); + +	if (priv->serial) +		pciserial_suspend_ports(priv->serial); + +	/* FIXME: What about parport? */ + +	pci_save_state(dev); +	pci_set_power_state(dev, pci_choose_state(dev, state)); +	return 0; +} + +static int parport_serial_pci_resume(struct pci_dev *dev) +{ +	struct parport_serial_private *priv = pci_get_drvdata(dev); + +	pci_set_power_state(dev, PCI_D0); +	pci_restore_state(dev); + +	/* +	 * The device may have been disabled.  Re-enable it. +	 */ +	pci_enable_device(dev); + +	if (priv->serial) +		pciserial_resume_ports(priv->serial); + +	/* FIXME: What about parport? */ + +	return 0; +} +  static struct pci_driver parport_serial_pci_driver = {  	.name		= "parport_serial",  	.id_table	= parport_serial_pci_tbl,  	.probe		= parport_serial_pci_probe,  	.remove		= __devexit_p(parport_serial_pci_remove), +	.suspend	= parport_serial_pci_suspend, +	.resume		= parport_serial_pci_resume,  }; diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 4e9084edfc7..52b0a0558ed 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c @@ -46,7 +46,7 @@ struct pci_serial_quirk {  	u32	subdevice;  	int	(*init)(struct pci_dev *dev);  	int	(*setup)(struct serial_private *, struct pciserial_board *, -			 struct uart_port *port, int idx); +			 struct uart_port *, int);  	void	(*exit)(struct pci_dev *dev);  }; @@ -436,25 +436,6 @@ static int pci_siig_init(struct pci_dev *dev)  	return -ENODEV;  } -int pci_siig10x_fn(struct pci_dev *dev, int enable) -{ -	int ret = 0; -	if (enable) -		ret = pci_siig10x_init(dev); -	return ret; -} - -int pci_siig20x_fn(struct pci_dev *dev, int enable) -{ -	int ret = 0; -	if (enable) -		ret = pci_siig20x_init(dev); -	return ret; -} - -EXPORT_SYMBOL(pci_siig10x_fn); -EXPORT_SYMBOL(pci_siig20x_fn); -  /*   * Timedia has an explosion of boards, and to avoid the PCI table from   * growing *huge*, we use this function to collapse some 70 entries diff --git a/include/linux/8250_pci.h b/include/linux/8250_pci.h index 192c0ff7a77..3209dd46ea7 100644 --- a/include/linux/8250_pci.h +++ b/include/linux/8250_pci.h @@ -35,6 +35,3 @@ pciserial_init_ports(struct pci_dev *dev, struct pciserial_board *board);  void pciserial_remove_ports(struct serial_private *priv);  void pciserial_suspend_ports(struct serial_private *priv);  void pciserial_resume_ports(struct serial_private *priv); - -int pci_siig10x_fn(struct pci_dev *dev, int enable); -int pci_siig20x_fn(struct pci_dev *dev, int enable); diff --git a/include/linux/serialP.h b/include/linux/serialP.h index 2b2f35a64d7..2b9e6b9554d 100644 --- a/include/linux/serialP.h +++ b/include/linux/serialP.h @@ -140,44 +140,4 @@ struct rs_multiport_struct {  #define ALPHA_KLUDGE_MCR 0  #endif -/* - * Definitions for PCI support. - */ -#define SPCI_FL_BASE_MASK	0x0007 -#define SPCI_FL_BASE0	0x0000 -#define SPCI_FL_BASE1	0x0001 -#define SPCI_FL_BASE2	0x0002 -#define SPCI_FL_BASE3	0x0003 -#define SPCI_FL_BASE4	0x0004 -#define SPCI_FL_GET_BASE(x)	(x & SPCI_FL_BASE_MASK) - -#define SPCI_FL_IRQ_MASK       (0x0007 << 4) -#define SPCI_FL_IRQBASE0       (0x0000 << 4) -#define SPCI_FL_IRQBASE1       (0x0001 << 4) -#define SPCI_FL_IRQBASE2       (0x0002 << 4) -#define SPCI_FL_IRQBASE3       (0x0003 << 4) -#define SPCI_FL_IRQBASE4       (0x0004 << 4) -#define SPCI_FL_GET_IRQBASE(x)        ((x & SPCI_FL_IRQ_MASK) >> 4) - -/* Use successive BARs (PCI base address registers),  -   else use offset into some specified BAR */ -#define SPCI_FL_BASE_TABLE	0x0100 - -/* Use successive entries in the irq resource table */ -#define SPCI_FL_IRQ_TABLE	0x0200 - -/* Use the irq resource table instead of dev->irq */ -#define SPCI_FL_IRQRESOURCE	0x0400 - -/* Use the Base address register size to cap number of ports */ -#define SPCI_FL_REGION_SZ_CAP	0x0800 - -/* Do not use irq sharing for this device */ -#define SPCI_FL_NO_SHIRQ	0x1000 - -/* This is a PNP device */ -#define SPCI_FL_ISPNP		0x2000 - -#define SPCI_FL_PNPDEFAULT	(SPCI_FL_IRQRESOURCE|SPCI_FL_ISPNP) -  #endif /* _LINUX_SERIAL_H */  |