Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6971c635 authored by Guainluca Anzolin's avatar Guainluca Anzolin Committed by Greg Kroah-Hartman
Browse files

parport_serial: Add support for the WCH353 2S/1P multi-IO card



To allow parport_serial to handle the card the same PCI ids are blacklisted
in 8250_pci.c using the existing software blacklist mechanism.

The blacklist array is also renamed because it now covers this new use
case.

Since the two serial ports are auto-detected as XScale instead of 16550A
clones, we also add a quirk to 8250_pci.c to skip autodetection and set the
correct port type.

Signed-off-by: default avatarGianluca Anzolin <gianluca@sottospazio.it>
[Fold in fixes for the uart_8250 change]
Signed-off-by: default avatarAlan Cox <alan@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 9303ac15
Loading
Loading
Loading
Loading
+10 −1
Original line number Original line Diff line number Diff line
@@ -62,6 +62,7 @@ enum parport_pc_pci_cards {
	timedia_9079a,
	timedia_9079a,
	timedia_9079b,
	timedia_9079b,
	timedia_9079c,
	timedia_9079c,
	wch_ch353_2s1p,
};
};


/* each element directly indexed from enum list, above */
/* each element directly indexed from enum list, above */
@@ -145,6 +146,7 @@ static struct parport_pc_pci cards[] __devinitdata = {
	/* timedia_9079a */             { 1, { { 2, 3 }, } },
	/* timedia_9079a */             { 1, { { 2, 3 }, } },
	/* timedia_9079b */             { 1, { { 2, 3 }, } },
	/* timedia_9079b */             { 1, { { 2, 3 }, } },
	/* timedia_9079c */             { 1, { { 2, 3 }, } },
	/* timedia_9079c */             { 1, { { 2, 3 }, } },
	/* wch_ch353_2s1p*/             { 1, { { 2, -1}, } },
};
};


static struct pci_device_id parport_serial_pci_tbl[] = {
static struct pci_device_id parport_serial_pci_tbl[] = {
@@ -243,7 +245,8 @@ static struct pci_device_id parport_serial_pci_tbl[] = {
	{ 0x1409, 0x7168, 0x1409, 0xb079, 0, 0, timedia_9079a },
	{ 0x1409, 0x7168, 0x1409, 0xb079, 0, 0, timedia_9079a },
	{ 0x1409, 0x7168, 0x1409, 0xc079, 0, 0, timedia_9079b },
	{ 0x1409, 0x7168, 0x1409, 0xc079, 0, 0, timedia_9079b },
	{ 0x1409, 0x7168, 0x1409, 0xd079, 0, 0, timedia_9079c },
	{ 0x1409, 0x7168, 0x1409, 0xd079, 0, 0, timedia_9079c },

	/* WCH CARDS */
	{ 0x4348, 0x7053, 0x4348, 0x3253, 0, 0, wch_ch353_2s1p},
	{ 0, } /* terminate list */
	{ 0, } /* terminate list */
};
};
MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl);
MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl);
@@ -460,6 +463,12 @@ static struct pciserial_board pci_parport_serial_boards[] __devinitdata = {
		.base_baud	= 921600,
		.base_baud	= 921600,
		.uart_offset	= 8,
		.uart_offset	= 8,
	},
	},
	[wch_ch353_2s1p] = {
		.flags          = FL_BASE0|FL_BASE_BARS,
		.num_ports      = 2,
		.base_baud      = 115200,
		.uart_offset    = 8,
	},
};
};


struct parport_serial_private {
struct parport_serial_private {
+30 −8
Original line number Original line Diff line number Diff line
@@ -1164,6 +1164,16 @@ pci_xr17c154_setup(struct serial_private *priv,
	return pci_default_setup(priv, board, port, idx);
	return pci_default_setup(priv, board, port, idx);
}
}


static int
pci_wch_ch353_setup(struct serial_private *priv,
                    const struct pciserial_board *board,
                    struct uart_8250_port *port, int idx)
{
	port->port.flags |= UPF_FIXED_TYPE;
	port->port.type = PORT_16550A;
	return pci_default_setup(priv, board, port, idx);
}

#define PCI_VENDOR_ID_SBSMODULARIO	0x124B
#define PCI_VENDOR_ID_SBSMODULARIO	0x124B
#define PCI_SUBVENDOR_ID_SBSMODULARIO	0x124B
#define PCI_SUBVENDOR_ID_SBSMODULARIO	0x124B
#define PCI_DEVICE_ID_OCTPRO		0x0001
#define PCI_DEVICE_ID_OCTPRO		0x0001
@@ -1737,6 +1747,14 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
		.subdevice	= PCI_ANY_ID,
		.subdevice	= PCI_ANY_ID,
		.setup		= pci_omegapci_setup,
		.setup		= pci_omegapci_setup,
	},
	},
	/* WCH CH353 2S1P card (16550 clone) */
	{
		.vendor         = 0x4348,
		.device         = 0x7053,
		.subvendor      = 0x4348,
		.subdevice      = 0x3253,
		.setup          = pci_wch_ch353_setup,
	},
	/*
	/*
	 * ASIX devices with FIFO bug
	 * ASIX devices with FIFO bug
	 */
	 */
@@ -2636,10 +2654,14 @@ static struct pciserial_board pci_boards[] __devinitdata = {
	},
	},
};
};


static const struct pci_device_id softmodem_blacklist[] = {
static const struct pci_device_id blacklist[] = {
	/* softmodems */
	{ PCI_VDEVICE(AL, 0x5457), }, /* ALi Corporation M5457 AC'97 Modem */
	{ PCI_VDEVICE(AL, 0x5457), }, /* ALi Corporation M5457 AC'97 Modem */
	{ PCI_VDEVICE(MOTOROLA, 0x3052), }, /* Motorola Si3052-based modem */
	{ PCI_VDEVICE(MOTOROLA, 0x3052), }, /* Motorola Si3052-based modem */
	{ PCI_DEVICE(0x1543, 0x3052), }, /* Si3052-based modem, default IDs */
	{ PCI_DEVICE(0x1543, 0x3052), }, /* Si3052-based modem, default IDs */

	/* multi-io cards handled by parport_serial */
	{ PCI_DEVICE(0x4348, 0x7053), }, /* WCH CH353 2S1P */
};
};


/*
/*
@@ -2650,7 +2672,7 @@ static const struct pci_device_id softmodem_blacklist[] = {
static int __devinit
static int __devinit
serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
{
{
	const struct pci_device_id *blacklist;
	const struct pci_device_id *bldev;
	int num_iomem, num_port, first_port = -1, i;
	int num_iomem, num_port, first_port = -1, i;


	/*
	/*
@@ -2667,13 +2689,13 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)


	/*
	/*
	 * Do not access blacklisted devices that are known not to
	 * Do not access blacklisted devices that are known not to
	 * feature serial ports.
	 * feature serial ports or are handled by other modules.
	 */
	 */
	for (blacklist = softmodem_blacklist;
	for (bldev = blacklist;
	     blacklist < softmodem_blacklist + ARRAY_SIZE(softmodem_blacklist);
	     bldev < blacklist + ARRAY_SIZE(blacklist);
	     blacklist++) {
	     bldev++) {
		if (dev->vendor == blacklist->vendor &&
		if (dev->vendor == bldev->vendor &&
		    dev->device == blacklist->device)
		    dev->device == bldev->device)
			return -ENODEV;
			return -ENODEV;
	}
	}