diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-03-19 01:28:40 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-03-19 01:28:40 +0000 |
commit | 8abb719409c9060a7c0676f76e9182c1e0b8ca46 (patch) | |
tree | b88cc5a6cd513a04a512b7e6215c873c90a1c5dd /drivers/parport | |
parent | f01bd7aeafd95a08aafc9e3636bb26974df69d82 (diff) |
Merge with 2.3.99-pre1.
Diffstat (limited to 'drivers/parport')
-rw-r--r-- | drivers/parport/ChangeLog | 21 | ||||
-rw-r--r-- | drivers/parport/Config.in | 3 | ||||
-rw-r--r-- | drivers/parport/parport_pc.c | 119 |
3 files changed, 114 insertions, 29 deletions
diff --git a/drivers/parport/ChangeLog b/drivers/parport/ChangeLog index 7429ec38b..8d01df21e 100644 --- a/drivers/parport/ChangeLog +++ b/drivers/parport/ChangeLog @@ -1,3 +1,24 @@ +2000-03-13 <twaugh@redhat.com> + + * parport_pc.c (parport_pc_init): Moved from asm/parport.h. + + * Config.in: CONFIG_PARPORT_PC_SUPERIO: new option. + + * parport_pc.c (show_parconfig_smsc37c669): Make __devinit. + (show_parconfig_winbond): Likewise. + (decode_winbond): Likewise. + (decode_smsc): Likewise. + (winbond_check): Likewise. + (winbond_check2): Likewise. + (smsc_check): Likewise. + (detect_and_report_winbond): Likewise. + (detect_and_report_smsc): Likewise. + (get_superio_dma): Likewise. + (get_superio_irq): Likewise. + (parport_pc_find_isa_ports): New function. + (parport_pc_find_ports): New function. + (init_module): Make superio a config option, not a parameter. + 2000-03-10 <twaugh@redhat.com> * parport_pc.c (decode_winbond): Use correct 83877ATF chip ID. diff --git a/drivers/parport/Config.in b/drivers/parport/Config.in index d4222f353..1e486c6b3 100644 --- a/drivers/parport/Config.in +++ b/drivers/parport/Config.in @@ -13,6 +13,9 @@ if [ "$CONFIG_PARPORT" != "n" ]; then dep_tristate ' PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT if [ "$CONFIG_PARPORT_PC" != "n" ]; then bool ' Use FIFO/DMA if available' CONFIG_PARPORT_PC_FIFO + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool ' SuperIO chipset support (EXPERIMENTAL)' CONFIG_PARPORT_PC_SUPERIO + fi fi if [ "$CONFIG_PARPORT_PC" = "y" ]; then # Don't bother with this if parport_pc is a module; it only affects diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index 86fc6f874..7117c847e 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c @@ -60,6 +60,8 @@ #include <linux/parport_pc.h> #include <asm/parport.h> +#define PARPORT_PC_MAX_PORTS PARPORT_MAX + /* ECR modes */ #define ECR_SPP 00 #define ECR_PS2 01 @@ -84,8 +86,10 @@ static struct superio_struct { /* For Super-IO chips autodetection */ int io; int irq; int dma; -} superios[NR_SUPERIOS]= { {0,},}; - +} superios[NR_SUPERIOS] __devinitdata = { {0,},}; + +static int user_specified __devinitdata = 0; + /* frob_control, but for ECR */ static void frob_econtrol (struct parport *pb, unsigned char m, unsigned char v) @@ -1015,9 +1019,9 @@ struct parport_operations parport_pc_ops = parport_ieee1284_read_byte, }; +#ifdef CONFIG_PARPORT_PC_SUPERIO /* Super-IO chipset detection, Winbond, SMSC */ - -static void show_parconfig_smsc37c669(int io, int key) +static void __devinit show_parconfig_smsc37c669(int io, int key) { int cr1,cr4,cra,cr23,cr26,cr27,i=0; char *modes[]={ "SPP and Bidirectional (PS/2)", @@ -1092,7 +1096,7 @@ static void show_parconfig_smsc37c669(int io, int key) } -static void show_parconfig_winbond(int io, int key) +static void __devinit show_parconfig_winbond(int io, int key) { int cr30,cr60,cr61,cr70,cr74,crf0,i=0; char *modes[]={ "Standard (SPP) and Bidirectional(PS/2)", /* 0 */ @@ -1152,7 +1156,7 @@ static void show_parconfig_winbond(int io, int key) } } -static void decode_winbond(int efer, int key, int devid, int devrev, int oldid) +static void __devinit decode_winbond(int efer, int key, int devid, int devrev, int oldid) { char *type=NULL; int id,progif=2; @@ -1188,7 +1192,7 @@ static void decode_winbond(int efer, int key, int devid, int devrev, int oldid) return; } -static void decode_smsc(int efer, int key, int devid, int devrev) +static void __devinit decode_smsc(int efer, int key, int devid, int devrev) { char *type=NULL; void (*func)(int io, int key); @@ -1219,7 +1223,7 @@ static void decode_smsc(int efer, int key, int devid, int devrev) } -static void winbond_check(int io, int key) +static void __devinit winbond_check(int io, int key) { int devid,devrev,oldid; @@ -1237,7 +1241,7 @@ static void winbond_check(int io, int key) decode_winbond(io,key,devid,devrev,oldid); } -static void winbond_check2(int io,int key) +static void __devinit winbond_check2(int io,int key) { int devid,devrev,oldid; @@ -1254,7 +1258,7 @@ static void winbond_check2(int io,int key) decode_winbond(io,key,devid,devrev,oldid); } -static void smsc_check(int io, int key) +static void __devinit smsc_check(int io, int key) { int devid,devrev; @@ -1271,7 +1275,7 @@ static void smsc_check(int io, int key) } -static void detect_and_report_winbond (void) +static void __devinit detect_and_report_winbond (void) { printk("Winbond Super-IO detection, now testing ports 3F0,370,250,4E,2E ...\n"); @@ -1284,7 +1288,7 @@ static void detect_and_report_winbond (void) winbond_check2(0x250,0x89); } -static void detect_and_report_smsc (void) +static void __devinit detect_and_report_smsc (void) { printk("SMSC Super-IO detection, now testing Ports 2F0, 370 ...\n"); smsc_check(0x3f0,0x55); @@ -1292,8 +1296,9 @@ static void detect_and_report_smsc (void) smsc_check(0x3f0,0x44); smsc_check(0x370,0x44); } +#endif /* CONFIG_PARPORT_PC_SUPERIO */ -static int get_superio_dma (struct parport *p) +static int __devinit get_superio_dma (struct parport *p) { int i=0; while( (superios[i].io != p->base) && (i<NR_SUPERIOS)) @@ -1303,7 +1308,7 @@ static int get_superio_dma (struct parport *p) return PARPORT_DMA_NONE; } -static int get_superio_irq (struct parport *p) +static int __devinit get_superio_irq (struct parport *p) { int i=0; while( (superios[i].io != p->base) && (i<NR_SUPERIOS)) @@ -2330,7 +2335,7 @@ static struct pci_driver parport_pc_pci_driver = { probe: parport_pc_pci_probe, }; -static int __devinit parport_pc_init_superio (void) +static int __init parport_pc_init_superio (void) { #ifdef CONFIG_PCI const struct pci_device_id *id; @@ -2348,6 +2353,74 @@ static int __devinit parport_pc_init_superio (void) return 0; /* zero devices found */ } +/* This is called by parport_pc_find_nonpci_ports (in asm/parport.h) */ +static int __init __attribute__((unused)) +parport_pc_find_isa_ports (int autoirq, int autodma) +{ + int count = 0; + + if (parport_pc_probe_port(0x3bc, 0x7bc, autoirq, autodma, NULL)) + count++; + if (parport_pc_probe_port(0x378, 0x778, autoirq, autodma, NULL)) + count++; + if (parport_pc_probe_port(0x278, 0x678, autoirq, autodma, NULL)) + count++; + + return count; +} + +/* This function is called by parport_pc_init if the user didn't + * specify any ports to probe. Its job is to find some ports. Order + * is important here -- we want ISA ports to be registered first, + * followed by PCI cards (for least surprise), but before that we want + * to do chipset-specific tests for some onboard ports that we know + * about. + * + * autoirq is PARPORT_IRQ_NONE, PARPORT_IRQ_AUTO, or PARPORT_IRQ_PROBEONLY + * autodma is PARPORT_DMA_NONE or PARPORT_DMA_AUTO + */ +static int __init parport_pc_find_ports (int autoirq, int autodma) +{ + int count = 0, r; + +#ifdef CONFIG_PARPORT_PC_SUPERIO + detect_and_report_winbond (); + detect_and_report_smsc (); +#endif + + /* Onboard SuperIO chipsets that show themselves on the PCI bus. */ + count += parport_pc_init_superio (); + + /* ISA ports and whatever (see asm/parport.h). */ + count += parport_pc_find_nonpci_ports (autoirq, autodma); + + r = pci_register_driver (&parport_pc_pci_driver); + if (r > 0) + count += r; + + return count; +} + +int __init parport_pc_init (int *io, int *io_hi, int *irq, int *dma) +{ + int count = 0, i = 0; + + if (io && *io) { + /* Only probe the ports we were given. */ + user_specified = 1; + do { + if (!*io_hi) *io_hi = 0x400 + *io; + if (parport_pc_probe_port(*(io++), *(io_hi++), + *(irq++), *(dma++), NULL)) + count++; + } while (*io && (++i < PARPORT_PC_MAX_PORTS)); + } else { + count += parport_pc_find_ports (irq[0], dma[0]); + } + + return count; +} + /* Exported symbols. */ #ifdef CONFIG_PARPORT_PC_PCMCIA @@ -2367,7 +2440,6 @@ static int dmaval[PARPORT_PC_MAX_PORTS] = { [0 ... PARPORT_PC_MAX_PORTS-1] = PAR static int irqval[PARPORT_PC_MAX_PORTS] = { [0 ... PARPORT_PC_MAX_PORTS-1] = PARPORT_IRQ_PROBEONLY }; static const char *irq[PARPORT_PC_MAX_PORTS] = { NULL, }; static const char *dma[PARPORT_PC_MAX_PORTS] = { NULL, }; -static int superio = 0; MODULE_AUTHOR("Phil Blundell, Tim Waugh, others"); MODULE_DESCRIPTION("PC-style parallel port driver"); @@ -2379,18 +2451,12 @@ MODULE_PARM_DESC(irq, "IRQ line"); MODULE_PARM(irq, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "s"); MODULE_PARM_DESC(dma, "DMA channel"); MODULE_PARM(dma, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "s"); -MODULE_PARM_DESC(superio, "Enable Super-IO chipset probe"); -MODULE_PARM(superio, "i"); int init_module(void) { /* Work out how many ports we have, then get parport_share to parse the irq values. */ - unsigned int i, n; - if (superio) { - detect_and_report_winbond (); - detect_and_report_smsc (); - } + unsigned int i; for (i = 0; i < PARPORT_PC_MAX_PORTS && io[i]; i++); if (i) { if (parport_parse_irqs(i, irq, irqval)) return 1; @@ -2415,12 +2481,7 @@ int init_module(void) } } - n = parport_pc_init_superio (); - n += parport_pc_init (io, io_hi, irqval, dmaval); - i = pci_register_driver (&parport_pc_pci_driver); - - if (i > 0) n += i; - return !n; + return !parport_pc_init (io, io_hi, irqval, dmaval); } void cleanup_module(void) |