diff options
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/ahci.c | 32 | ||||
-rw-r--r-- | drivers/ata/ahci_sunxi.c | 16 | ||||
-rw-r--r-- | drivers/ata/libahci.c | 78 | ||||
-rw-r--r-- | drivers/ata/libata-core.c | 20 | ||||
-rw-r--r-- | drivers/ata/libata-eh.c | 7 | ||||
-rw-r--r-- | drivers/ata/libata-scsi.c | 50 | ||||
-rw-r--r-- | drivers/ata/libata-transport.c | 1 | ||||
-rw-r--r-- | drivers/ata/sata_fsl.c | 2 | ||||
-rw-r--r-- | drivers/ata/sata_nv.c | 2 | ||||
-rw-r--r-- | drivers/ata/sata_rcar.c | 15 |
10 files changed, 125 insertions, 98 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 5f039f191067..49f1e6890587 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -60,6 +60,7 @@ enum board_ids { /* board IDs by feature in alphabetical order */ board_ahci, board_ahci_ign_iferr, + board_ahci_nomsi, board_ahci_noncq, board_ahci_nosntf, board_ahci_yes_fbs, @@ -121,6 +122,13 @@ static const struct ata_port_info ahci_port_info[] = { .udma_mask = ATA_UDMA6, .port_ops = &ahci_ops, }, + [board_ahci_nomsi] = { + AHCI_HFLAGS (AHCI_HFLAG_NO_MSI), + .flags = AHCI_FLAG_COMMON, + .pio_mask = ATA_PIO4, + .udma_mask = ATA_UDMA6, + .port_ops = &ahci_ops, + }, [board_ahci_noncq] = { AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ), .flags = AHCI_FLAG_COMMON, @@ -313,6 +321,14 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series RAID */ { PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */ { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series RAID */ + { PCI_VDEVICE(INTEL, 0x9d03), board_ahci }, /* Sunrise Point-LP AHCI */ + { PCI_VDEVICE(INTEL, 0x9d05), board_ahci }, /* Sunrise Point-LP RAID */ + { PCI_VDEVICE(INTEL, 0x9d07), board_ahci }, /* Sunrise Point-LP RAID */ + { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */ + { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H RAID */ + { PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */ + { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */ + { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */ /* JMicron 360/1/3/5/6, match class to avoid IDE function */ { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, @@ -475,10 +491,11 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */ /* - * Samsung SSDs found on some macbooks. NCQ times out. - * https://bugzilla.kernel.org/show_bug.cgi?id=60731 + * Samsung SSDs found on some macbooks. NCQ times out if MSI is + * enabled. https://bugzilla.kernel.org/show_bug.cgi?id=60731 */ - { PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_noncq }, + { PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_nomsi }, + { PCI_VDEVICE(SAMSUNG, 0xa800), board_ahci_nomsi }, /* Enmotus */ { PCI_DEVICE(0x1c44, 0x8000), board_ahci }, @@ -514,12 +531,9 @@ MODULE_PARM_DESC(marvell_enable, "Marvell SATA via AHCI (1 = enabled)"); static void ahci_pci_save_initial_config(struct pci_dev *pdev, struct ahci_host_priv *hpriv) { - unsigned int force_port_map = 0; - unsigned int mask_port_map = 0; - if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) { dev_info(&pdev->dev, "JMB361 has only one port\n"); - force_port_map = 1; + hpriv->force_port_map = 1; } /* @@ -529,9 +543,9 @@ static void ahci_pci_save_initial_config(struct pci_dev *pdev, */ if (hpriv->flags & AHCI_HFLAG_MV_PATA) { if (pdev->device == 0x6121) - mask_port_map = 0x3; + hpriv->mask_port_map = 0x3; else - mask_port_map = 0xf; + hpriv->mask_port_map = 0xf; dev_info(&pdev->dev, "Disabling your PATA port. Use the boot option 'ahci.marvell_enable=0' to avoid this.\n"); } diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c index afe5581e9b1f..e2e0da539a2f 100644 --- a/drivers/ata/ahci_sunxi.c +++ b/drivers/ata/ahci_sunxi.c @@ -27,6 +27,12 @@ #include <linux/regulator/consumer.h> #include "ahci.h" +/* Insmod parameters */ +static bool enable_pmp; +module_param(enable_pmp, bool, 0); +MODULE_PARM_DESC(enable_pmp, + "Enable support for sata port multipliers, only use if you use a pmp!"); + #define AHCI_BISTAFR 0x00a0 #define AHCI_BISTCR 0x00a4 #define AHCI_BISTFCTR 0x00a8 @@ -184,7 +190,15 @@ static int ahci_sunxi_probe(struct platform_device *pdev) goto disable_resources; hpriv->flags = AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI | - AHCI_HFLAG_NO_PMP | AHCI_HFLAG_YES_NCQ; + AHCI_HFLAG_YES_NCQ; + + /* + * The sunxi sata controller seems to be unable to successfully do a + * soft reset if no pmp is attached, so disable pmp use unless + * requested, otherwise directly attached disks do not work. + */ + if (!enable_pmp) + hpriv->flags |= AHCI_HFLAG_NO_PMP; rc = ahci_platform_init_host(pdev, hpriv, &ahci_sunxi_port_info); if (rc) diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 5eb61c9e63da..97683e45ab04 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -1778,16 +1778,15 @@ static void ahci_handle_port_interrupt(struct ata_port *ap, } } -static void ahci_update_intr_status(struct ata_port *ap) +static void ahci_port_intr(struct ata_port *ap) { void __iomem *port_mmio = ahci_port_base(ap); - struct ahci_port_priv *pp = ap->private_data; u32 status; status = readl(port_mmio + PORT_IRQ_STAT); writel(status, port_mmio + PORT_IRQ_STAT); - atomic_or(status, &pp->intr_status); + ahci_handle_port_interrupt(ap, port_mmio, status); } static irqreturn_t ahci_port_thread_fn(int irq, void *dev_instance) @@ -1808,34 +1807,6 @@ static irqreturn_t ahci_port_thread_fn(int irq, void *dev_instance) return IRQ_HANDLED; } -irqreturn_t ahci_thread_fn(int irq, void *dev_instance) -{ - struct ata_host *host = dev_instance; - struct ahci_host_priv *hpriv = host->private_data; - u32 irq_masked = hpriv->port_map; - unsigned int i; - - for (i = 0; i < host->n_ports; i++) { - struct ata_port *ap; - - if (!(irq_masked & (1 << i))) - continue; - - ap = host->ports[i]; - if (ap) { - ahci_port_thread_fn(irq, ap); - VPRINTK("port %u\n", i); - } else { - VPRINTK("port %u (no irq)\n", i); - if (ata_ratelimit()) - dev_warn(host->dev, - "interrupt on disabled port %u\n", i); - } - } - - return IRQ_HANDLED; -} - static irqreturn_t ahci_multi_irqs_intr(int irq, void *dev_instance) { struct ata_port *ap = dev_instance; @@ -1875,6 +1846,8 @@ static irqreturn_t ahci_single_irq_intr(int irq, void *dev_instance) irq_masked = irq_stat & hpriv->port_map; + spin_lock(&host->lock); + for (i = 0; i < host->n_ports; i++) { struct ata_port *ap; @@ -1883,7 +1856,7 @@ static irqreturn_t ahci_single_irq_intr(int irq, void *dev_instance) ap = host->ports[i]; if (ap) { - ahci_update_intr_status(ap); + ahci_port_intr(ap); VPRINTK("port %u\n", i); } else { VPRINTK("port %u (no irq)\n", i); @@ -1906,9 +1879,11 @@ static irqreturn_t ahci_single_irq_intr(int irq, void *dev_instance) */ writel(irq_stat, mmio + HOST_IRQ_STAT); + spin_unlock(&host->lock); + VPRINTK("EXIT\n"); - return handled ? IRQ_WAKE_THREAD : IRQ_NONE; + return IRQ_RETVAL(handled); } unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) @@ -2320,8 +2295,13 @@ static int ahci_port_start(struct ata_port *ap) */ pp->intr_mask = DEF_PORT_IRQ; - spin_lock_init(&pp->lock); - ap->lock = &pp->lock; + /* + * Switch to per-port locking in case each port has its own MSI vector. + */ + if ((hpriv->flags & AHCI_HFLAG_MULTI_MSI)) { + spin_lock_init(&pp->lock); + ap->lock = &pp->lock; + } ap->private_data = pp; @@ -2482,31 +2462,6 @@ out_free_irqs: return rc; } -static int ahci_host_activate_single_irq(struct ata_host *host, int irq, - struct scsi_host_template *sht) -{ - int i, rc; - - rc = ata_host_start(host); - if (rc) - return rc; - - rc = devm_request_threaded_irq(host->dev, irq, ahci_single_irq_intr, - ahci_thread_fn, IRQF_SHARED, - dev_driver_string(host->dev), host); - if (rc) - return rc; - - for (i = 0; i < host->n_ports; i++) - ata_port_desc(host->ports[i], "irq %d", irq); - - rc = ata_host_register(host, sht); - if (rc) - devm_free_irq(host->dev, irq, host); - - return rc; -} - /** * ahci_host_activate - start AHCI host, request IRQs and register it * @host: target ATA host @@ -2532,7 +2487,8 @@ int ahci_host_activate(struct ata_host *host, int irq, if (hpriv->flags & AHCI_HFLAG_MULTI_MSI) rc = ahci_host_activate_multi_irqs(host, irq, sht); else - rc = ahci_host_activate_single_irq(host, irq, sht); + rc = ata_host_activate(host, irq, ahci_single_irq_intr, + IRQF_SHARED, sht); return rc; } EXPORT_SYMBOL_GPL(ahci_host_activate); diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index c5ba15af87d3..5c84fb5c3372 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1043,8 +1043,8 @@ const char *sata_spd_string(unsigned int spd) * None. * * RETURNS: - * Device type, %ATA_DEV_ATA, %ATA_DEV_ATAPI, %ATA_DEV_PMP or - * %ATA_DEV_UNKNOWN the event of failure. + * Device type, %ATA_DEV_ATA, %ATA_DEV_ATAPI, %ATA_DEV_PMP, + * %ATA_DEV_ZAC, or %ATA_DEV_UNKNOWN the event of failure. */ unsigned int ata_dev_classify(const struct ata_taskfile *tf) { @@ -1089,6 +1089,11 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf) return ATA_DEV_SEMB; } + if ((tf->lbam == 0xcd) && (tf->lbah == 0xab)) { + DPRINTK("found ZAC device by sig\n"); + return ATA_DEV_ZAC; + } + DPRINTK("unknown device\n"); return ATA_DEV_UNKNOWN; } @@ -1329,7 +1334,7 @@ static int ata_hpa_resize(struct ata_device *dev) int rc; /* do we need to do it? */ - if (dev->class != ATA_DEV_ATA || + if ((dev->class != ATA_DEV_ATA && dev->class != ATA_DEV_ZAC) || !ata_id_has_lba(dev->id) || !ata_id_hpa_enabled(dev->id) || (dev->horkage & ATA_HORKAGE_BROKEN_HPA)) return 0; @@ -1889,6 +1894,7 @@ retry: case ATA_DEV_SEMB: class = ATA_DEV_ATA; /* some hard drives report SEMB sig */ case ATA_DEV_ATA: + case ATA_DEV_ZAC: tf.command = ATA_CMD_ID_ATA; break; case ATA_DEV_ATAPI: @@ -1980,7 +1986,7 @@ retry: rc = -EINVAL; reason = "device reports invalid type"; - if (class == ATA_DEV_ATA) { + if (class == ATA_DEV_ATA || class == ATA_DEV_ZAC) { if (!ata_id_is_ata(id) && !ata_id_is_cfa(id)) goto err_out; if (ap->host->flags & ATA_HOST_IGNORE_ATA && @@ -2015,7 +2021,8 @@ retry: goto retry; } - if ((flags & ATA_READID_POSTRESET) && class == ATA_DEV_ATA) { + if ((flags & ATA_READID_POSTRESET) && + (class == ATA_DEV_ATA || class == ATA_DEV_ZAC)) { /* * The exact sequence expected by certain pre-ATA4 drives is: * SRST RESET @@ -2280,7 +2287,7 @@ int ata_dev_configure(struct ata_device *dev) sizeof(modelbuf)); /* ATA-specific feature tests */ - if (dev->class == ATA_DEV_ATA) { + if (dev->class == ATA_DEV_ATA || dev->class == ATA_DEV_ZAC) { if (ata_id_is_cfa(id)) { /* CPRM may make this media unusable */ if (id[ATA_ID_CFA_KEY_MGMT] & 1) @@ -4033,6 +4040,7 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, if (ata_class_enabled(new_class) && new_class != ATA_DEV_ATA && new_class != ATA_DEV_ATAPI && + new_class != ATA_DEV_ZAC && new_class != ATA_DEV_SEMB) { ata_dev_info(dev, "class mismatch %u != %u\n", dev->class, new_class); diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index dad83df555c4..3dbec8954c86 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1809,6 +1809,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, switch (qc->dev->class) { case ATA_DEV_ATA: + case ATA_DEV_ZAC: if (err & ATA_ICRC) qc->err_mask |= AC_ERR_ATA_BUS; if (err & (ATA_UNC | ATA_AMNF)) @@ -3792,7 +3793,8 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, struct ata_eh_context *ehc = &link->eh_context; unsigned long tmp; - if (dev->class != ATA_DEV_ATA) + if (dev->class != ATA_DEV_ATA && + dev->class != ATA_DEV_ZAC) continue; if (!(ehc->i.dev_action[dev->devno] & ATA_EH_PARK)) @@ -3873,7 +3875,8 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, /* retry flush if necessary */ ata_for_each_dev(dev, link, ALL) { - if (dev->class != ATA_DEV_ATA) + if (dev->class != ATA_DEV_ATA && + dev->class != ATA_DEV_ZAC) continue; rc = ata_eh_maybe_retry_flush(dev); if (rc) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 0586f66d70fa..e364e86e84d7 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -235,7 +235,8 @@ static ssize_t ata_scsi_park_store(struct device *device, rc = -ENODEV; goto unlock; } - if (dev->class != ATA_DEV_ATA) { + if (dev->class != ATA_DEV_ATA && + dev->class != ATA_DEV_ZAC) { rc = -EOPNOTSUPP; goto unlock; } @@ -1164,7 +1165,7 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, depth = min(sdev->host->can_queue, ata_id_queue_depth(dev->id)); depth = min(ATA_MAX_QUEUE - 1, depth); - scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, depth); + scsi_change_queue_depth(sdev, depth); } blk_queue_flush_queueable(q, false); @@ -1243,21 +1244,17 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev) * @ap: ATA port to which the device change the queue depth * @sdev: SCSI device to configure queue depth for * @queue_depth: new queue depth - * @reason: calling context * * libsas and libata have different approaches for associating a sdev to * its ata_port. * */ int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev, - int queue_depth, int reason) + int queue_depth) { struct ata_device *dev; unsigned long flags; - if (reason != SCSI_QDEPTH_DEFAULT) - return -EOPNOTSUPP; - if (queue_depth < 1 || queue_depth == sdev->queue_depth) return sdev->queue_depth; @@ -1282,15 +1279,13 @@ int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev, if (sdev->queue_depth == queue_depth) return -EINVAL; - scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, queue_depth); - return queue_depth; + return scsi_change_queue_depth(sdev, queue_depth); } /** * ata_scsi_change_queue_depth - SCSI callback for queue depth config * @sdev: SCSI device to configure queue depth for * @queue_depth: new queue depth - * @reason: calling context * * This is libata standard hostt->change_queue_depth callback. * SCSI will call into this callback when user tries to set queue @@ -1302,12 +1297,11 @@ int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev, * RETURNS: * Newly configured queue depth. */ -int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth, - int reason) +int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) { struct ata_port *ap = ata_shost_to_port(sdev->host); - return __ata_change_queue_depth(ap, sdev, queue_depth, reason); + return __ata_change_queue_depth(ap, sdev, queue_depth); } /** @@ -1968,6 +1962,7 @@ static void ata_scsi_rbuf_fill(struct ata_scsi_args *args, static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) { const u8 versions[] = { + 0x00, 0x60, /* SAM-3 (no version claimed) */ 0x03, @@ -1976,6 +1971,20 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) 0x02, 0x60 /* SPC-3 (no version claimed) */ }; + const u8 versions_zbc[] = { + 0x00, + 0xA0, /* SAM-5 (no version claimed) */ + + 0x04, + 0xC0, /* SBC-3 (no version claimed) */ + + 0x04, + 0x60, /* SPC-4 (no version claimed) */ + + 0x60, + 0x20, /* ZBC (no version claimed) */ + }; + u8 hdr[] = { TYPE_DISK, 0, @@ -1990,6 +1999,11 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) if (ata_id_removeable(args->id)) hdr[1] |= (1 << 7); + if (args->dev->class == ATA_DEV_ZAC) { + hdr[0] = TYPE_ZBC; + hdr[2] = 0x6; /* ZBC is defined in SPC-4 */ + } + memcpy(rbuf, hdr, sizeof(hdr)); memcpy(&rbuf[8], "ATA ", 8); ata_id_string(args->id, &rbuf[16], ATA_ID_PROD, 16); @@ -2002,7 +2016,10 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) if (rbuf[32] == 0 || rbuf[32] == ' ') memcpy(&rbuf[32], "n/a ", 4); - memcpy(rbuf + 59, versions, sizeof(versions)); + if (args->dev->class == ATA_DEV_ZAC) + memcpy(rbuf + 58, versions_zbc, sizeof(versions_zbc)); + else + memcpy(rbuf + 58, versions, sizeof(versions)); return 0; } @@ -2571,7 +2588,6 @@ static void atapi_request_sense(struct ata_queued_cmd *qc) DPRINTK("ATAPI request sense\n"); - /* FIXME: is this needed? */ memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); #ifdef CONFIG_ATA_SFF @@ -3412,7 +3428,7 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, ata_xlat_func_t xlat_func; int rc = 0; - if (dev->class == ATA_DEV_ATA) { + if (dev->class == ATA_DEV_ATA || dev->class == ATA_DEV_ZAC) { if (unlikely(!scmd->cmd_len || scmd->cmd_len > dev->cdb_len)) goto bad_cdb_len; @@ -3570,7 +3586,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap); break; - case SERVICE_ACTION_IN: + case SERVICE_ACTION_IN_16: if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16) ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap); else diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c index e37413228228..3227b7c8a05f 100644 --- a/drivers/ata/libata-transport.c +++ b/drivers/ata/libata-transport.c @@ -143,6 +143,7 @@ static struct { { ATA_DEV_PMP_UNSUP, "pmp" }, { ATA_DEV_SEMB, "semb" }, { ATA_DEV_SEMB_UNSUP, "semb" }, + { ATA_DEV_ZAC, "zac" }, { ATA_DEV_NONE, "none" } }; ata_bitfield_name_search(class, ata_class_names) diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 42174158d10f..f9054cd36a72 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -1488,7 +1488,7 @@ static int sata_fsl_probe(struct platform_device *ofdev) host_priv->csr_base = csr_base; irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); - if (irq < 0) { + if (!irq) { dev_err(&ofdev->dev, "invalid irq from platform\n"); goto error_exit_with_cleanup; } diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index cdf99fac139a..1db6f5ce5e89 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -1951,7 +1951,7 @@ static int nv_swncq_slave_config(struct scsi_device *sdev) ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num)); if (strncmp(model_num, "Maxtor", 6) == 0) { - ata_scsi_change_queue_depth(sdev, 1, SCSI_QDEPTH_DEFAULT); + ata_scsi_change_queue_depth(sdev, 1); ata_dev_notice(dev, "Disabling SWNCQ mode (depth %x)\n", sdev->queue_depth); } diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c index ad7725245d39..cb0d2e644af5 100644 --- a/drivers/ata/sata_rcar.c +++ b/drivers/ata/sata_rcar.c @@ -146,6 +146,7 @@ enum sata_rcar_type { RCAR_GEN1_SATA, RCAR_GEN2_SATA, + RCAR_R8A7790_ES1_SATA, }; struct sata_rcar_priv { @@ -763,6 +764,9 @@ static void sata_rcar_setup_port(struct ata_host *host) ap->udma_mask = ATA_UDMA6; ap->flags |= ATA_FLAG_SATA; + if (priv->type == RCAR_R8A7790_ES1_SATA) + ap->flags |= ATA_FLAG_NO_DIPM; + ioaddr->cmd_addr = base + SDATA_REG; ioaddr->ctl_addr = base + SSDEVCON_REG; ioaddr->scr_addr = base + SCRSSTS_REG; @@ -792,6 +796,7 @@ static void sata_rcar_init_controller(struct ata_host *host) sata_rcar_gen1_phy_init(priv); break; case RCAR_GEN2_SATA: + case RCAR_R8A7790_ES1_SATA: sata_rcar_gen2_phy_init(priv); break; default: @@ -838,9 +843,17 @@ static struct of_device_id sata_rcar_match[] = { .data = (void *)RCAR_GEN2_SATA }, { + .compatible = "renesas,sata-r8a7790-es1", + .data = (void *)RCAR_R8A7790_ES1_SATA + }, + { .compatible = "renesas,sata-r8a7791", .data = (void *)RCAR_GEN2_SATA }, + { + .compatible = "renesas,sata-r8a7793", + .data = (void *)RCAR_GEN2_SATA + }, { }, }; MODULE_DEVICE_TABLE(of, sata_rcar_match); @@ -849,7 +862,9 @@ static const struct platform_device_id sata_rcar_id_table[] = { { "sata_rcar", RCAR_GEN1_SATA }, /* Deprecated by "sata-r8a7779" */ { "sata-r8a7779", RCAR_GEN1_SATA }, { "sata-r8a7790", RCAR_GEN2_SATA }, + { "sata-r8a7790-es1", RCAR_R8A7790_ES1_SATA }, { "sata-r8a7791", RCAR_GEN2_SATA }, + { "sata-r8a7793", RCAR_GEN2_SATA }, { }, }; MODULE_DEVICE_TABLE(platform, sata_rcar_id_table); |