+static int winbond_port(struct platform_device *dev,
+ struct legacy_probe *lp, struct legacy_data *ld)
+{
+ if (devm_request_region(&dev->dev, lp->private, 4, "winbond") == NULL)
+ return -EBUSY;
+ ld->timing = lp->private;
+ return 0;
+}
+
+static struct ata_port_operations winbond_port_ops = {
+ .inherits = &legacy_base_port_ops,
+ .set_piomode = winbond_set_piomode,
+ .sff_data_xfer = vlb32_data_xfer,
+};
+
+static struct legacy_controller controllers[] = {
+ {"BIOS", &legacy_port_ops, 0x1F,
+ ATA_FLAG_NO_IORDY, 0, NULL },
+ {"Snooping", &simple_port_ops, 0x1F,
+ 0, 0, NULL },
+ {"PDC20230", &pdc20230_port_ops, 0x7,
+ ATA_FLAG_NO_IORDY,
+ ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, NULL },
+ {"HT6560A", &ht6560a_port_ops, 0x07,
+ ATA_FLAG_NO_IORDY, 0, NULL },
+ {"HT6560B", &ht6560b_port_ops, 0x1F,
+ ATA_FLAG_NO_IORDY, 0, NULL },
+ {"OPTI82C611A", &opti82c611a_port_ops, 0x0F,
+ 0, 0, NULL },
+ {"OPTI82C46X", &opti82c46x_port_ops, 0x0F,
+ 0, 0, NULL },
+ {"QDI6500", &qdi6500_port_ops, 0x07,
+ ATA_FLAG_NO_IORDY,
+ ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port },
+ {"QDI6580", &qdi6580_port_ops, 0x1F,
+ 0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port },
+ {"QDI6580DP", &qdi6580dp_port_ops, 0x1F,
+ 0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port },
+ {"W83759A", &winbond_port_ops, 0x1F,
+ 0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE,
+ winbond_port }
+};
+
+/**
+ * probe_chip_type - Discover controller
+ * @probe: Probe entry to check
+ *
+ * Probe an ATA port and identify the type of controller. We don't
+ * check if the controller appears to be driveless at this point.
+ */
+
+static __init int probe_chip_type(struct legacy_probe *probe)
+{
+ int mask = 1 << probe->slot;
+
+ if (winbond && (probe->port == 0x1F0 || probe->port == 0x170)) {
+ u8 reg = winbond_readcfg(winbond, 0x81);
+ reg |= 0x80; /* jumpered mode off */
+ winbond_writecfg(winbond, 0x81, reg);
+ reg = winbond_readcfg(winbond, 0x83);
+ reg |= 0xF0; /* local control */
+ winbond_writecfg(winbond, 0x83, reg);
+ reg = winbond_readcfg(winbond, 0x85);
+ reg |= 0xF0; /* programmable timing */
+ winbond_writecfg(winbond, 0x85, reg);
+
+ reg = winbond_readcfg(winbond, 0x81);
+
+ if (reg & mask)
+ return W83759A;
+ }
+ if (probe->port == 0x1F0) {
+ unsigned long flags;
+ local_irq_save(flags);