From e3779f6a4e7359bc0f83c3e2d34702a6c495e66e Mon Sep 17 00:00:00 2001 From: Bhumika Goyal Date: Thu, 2 Mar 2017 01:03:28 +0530 Subject: ata: constify of_device_id structures Declare of_device_id structures as const as they are either passed to the macro MODULE_DEVICE_TABLE or stored in the of_match_table field of a device_driver structure. This field is of type const, so of_device_id structures having this property can be made const too. Cross compiled the files drivers/ata/pata_macio.c and drivers/ata/pata_mpc52xx.c for powerpc architecture. Signed-off-by: Bhumika Goyal Signed-off-by: Tejun Heo --- drivers/ata/pata_macio.c | 2 +- drivers/ata/pata_mpc52xx.c | 2 +- drivers/ata/pata_of_platform.c | 2 +- drivers/ata/sata_fsl.c | 2 +- drivers/ata/sata_mv.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c index e347e7acd8ed..0adcb40d2794 100644 --- a/drivers/ata/pata_macio.c +++ b/drivers/ata/pata_macio.c @@ -1328,7 +1328,7 @@ static int pata_macio_pci_resume(struct pci_dev *pdev) } #endif /* CONFIG_PM_SLEEP */ -static struct of_device_id pata_macio_match[] = +static const struct of_device_id pata_macio_match[] = { { .name = "IDE", diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index 252ba27fa63b..9730125530f6 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -847,7 +847,7 @@ mpc52xx_ata_resume(struct platform_device *op) } #endif -static struct of_device_id mpc52xx_ata_of_match[] = { +static const struct of_device_id mpc52xx_ata_of_match[] = { { .compatible = "fsl,mpc5200-ata", }, { .compatible = "mpc5200-ata", }, {}, diff --git a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c index 201a32d0627f..01161c1aef4d 100644 --- a/drivers/ata/pata_of_platform.c +++ b/drivers/ata/pata_of_platform.c @@ -67,7 +67,7 @@ static int pata_of_platform_probe(struct platform_device *ofdev) reg_shift, pio_mask, &pata_platform_sht); } -static struct of_device_id pata_of_platform_match[] = { +static const struct of_device_id pata_of_platform_match[] = { { .compatible = "ata-generic", }, { }, }; diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index a723ae929783..01734d54c69c 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -1612,7 +1612,7 @@ static int sata_fsl_resume(struct platform_device *op) } #endif -static struct of_device_id fsl_sata_match[] = { +static const struct of_device_id fsl_sata_match[] = { { .compatible = "fsl,pq-sata", }, diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 00ce26d0c047..b66bcda88320 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -4286,7 +4286,7 @@ static int mv_platform_resume(struct platform_device *pdev) #endif #ifdef CONFIG_OF -static struct of_device_id mv_sata_dt_ids[] = { +static const struct of_device_id mv_sata_dt_ids[] = { { .compatible = "marvell,armada-370-sata", }, { .compatible = "marvell,orion-sata", }, {}, -- cgit v1.2.3 From 487d499c6758d81954d684f1dd8edc54257cad0f Mon Sep 17 00:00:00 2001 From: Belen Sarabia Date: Mon, 27 Feb 2017 22:41:18 +0100 Subject: Delete redundant return value check of platform_get_resource() Delete error handling from the result of a call to platform_get_resource() when the value is immediately passed to devm_ioremap_resource(). Signed-off-by: Belen Sarabia Signed-off-by: Tejun Heo --- drivers/ata/ahci_octeon.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/ahci_octeon.c b/drivers/ata/ahci_octeon.c index ea865fe953e1..5a44e089c6bb 100644 --- a/drivers/ata/ahci_octeon.c +++ b/drivers/ata/ahci_octeon.c @@ -38,11 +38,6 @@ static int ahci_octeon_probe(struct platform_device *pdev) int ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Platform resource[0] is missing\n"); - return -ENODEV; - } - base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(base)) return PTR_ERR(base); -- cgit v1.2.3 From b2a4b7862d6ba5c90746fc625e494b8ec5937fa1 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 7 Mar 2017 14:56:40 +0100 Subject: ata: allow subsystem to be used on m32r and s390 archs Both archs should work just fine with libata subsystem nowadays. Suggested-by: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Tejun Heo --- drivers/ata/Kconfig | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 70b57d2229d6..7e0fc9888f96 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -14,7 +14,6 @@ menuconfig ATA tristate "Serial ATA and Parallel ATA drivers (libata)" depends on HAS_IOMEM depends on BLOCK - depends on !(M32R || S390) || BROKEN select SCSI select GLOB ---help--- -- cgit v1.2.3 From 7c92357c91a917fd882801604bba2cb1f1fdde23 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Sat, 11 Mar 2017 08:47:01 +0800 Subject: libata: use setup_deferrable_timer Use setup_deferrable_timer() instead of init_timer_deferrable() to simplify the code. Signed-off-by: Geliang Tang Signed-off-by: Tejun Heo --- drivers/ata/libata-core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index ca75823697dd..55d3c8b8b35b 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5902,9 +5902,9 @@ struct ata_port *ata_port_alloc(struct ata_host *host) INIT_LIST_HEAD(&ap->eh_done_q); init_waitqueue_head(&ap->eh_wait_q); init_completion(&ap->park_req_pending); - init_timer_deferrable(&ap->fastdrain_timer); - ap->fastdrain_timer.function = ata_eh_fastdrain_timerfn; - ap->fastdrain_timer.data = (unsigned long)ap; + setup_deferrable_timer(&ap->fastdrain_timer, + ata_eh_fastdrain_timerfn, + (unsigned long)ap); ap->cbl = ATA_CBL_NONE; -- cgit v1.2.3 From af27e01cfcfcdf7f45488e023b474eb6de5f732e Mon Sep 17 00:00:00 2001 From: Jason Yan Date: Fri, 10 Mar 2017 10:05:40 +0800 Subject: libata: make ata_sg_clean static over again Fixes the following sparse warning: drivers/ata/libata-core.c:4913:6: warning: symbol 'ata_sg_clean' was not declared. Should it be static? Signed-off-by: Jason Yan --- drivers/ata/libata-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 55d3c8b8b35b..2d83b8c75965 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4910,7 +4910,7 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, * LOCKING: * spin_lock_irqsave(host lock) */ -void ata_sg_clean(struct ata_queued_cmd *qc) +static void ata_sg_clean(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct scatterlist *sg = qc->sg; -- cgit v1.2.3 From 3075b62d15df424b8e87447eb13e1604240293f2 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 15 Mar 2017 14:39:11 +0100 Subject: pata: remove the at91 driver This driver is orphan since commit b2026f708e09 ("ARM: at91: remove at91sam9260/at91sam9g20 legacy board support"). Given that nobody cared adding DT support to it, it probably means it's no longer used and is thus a good candidate for removal. Signed-off-by: Boris Brezillon Acked-by: Bartlomiej Zolnierkiewicz Acked-by: Nicolas Ferre Signed-off-by: Tejun Heo --- drivers/ata/Kconfig | 8 - drivers/ata/Makefile | 1 - drivers/ata/pata_at91.c | 503 ------------------------------------------------ 3 files changed, 512 deletions(-) delete mode 100644 drivers/ata/pata_at91.c (limited to 'drivers') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 7e0fc9888f96..19069feb196d 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -884,14 +884,6 @@ config PATA_AT32 If unsure, say N. -config PATA_AT91 - tristate "PATA support for AT91SAM9260" - depends on ARM && SOC_AT91SAM9 - help - This option enables support for IDE devices on the Atmel AT91SAM9260 SoC. - - If unsure, say N. - config PATA_CMD640_PCI tristate "CMD640 PCI PATA support (Experimental)" depends on PCI diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 89a0a1915d36..e29feb16bda1 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -91,7 +91,6 @@ obj-$(CONFIG_PATA_WINBOND) += pata_sl82c105.o # SFF PIO only obj-$(CONFIG_PATA_AT32) += pata_at32.o -obj-$(CONFIG_PATA_AT91) += pata_at91.o obj-$(CONFIG_PATA_CMD640_PCI) += pata_cmd640.o obj-$(CONFIG_PATA_FALCON) += pata_falcon.o obj-$(CONFIG_PATA_ISAPNP) += pata_isapnp.o diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c deleted file mode 100644 index fd5b34f0d007..000000000000 --- a/drivers/ata/pata_at91.c +++ /dev/null @@ -1,503 +0,0 @@ -/* - * PATA driver for AT91SAM9260 Static Memory Controller - * with CompactFlash interface in True IDE mode - * - * Copyright (C) 2009 Matyukevich Sergey - * 2011 Igor Plyatov - * - * Based on: - * * generic platform driver by Paul Mundt: drivers/ata/pata_platform.c - * * pata_at32 driver by Kristoffer Nyborg Gregertsen - * * at91_ide driver by Stanislaw Gruszka - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRV_NAME "pata_at91" -#define DRV_VERSION "0.3" - -#define CF_IDE_OFFSET 0x00c00000 -#define CF_ALT_IDE_OFFSET 0x00e00000 -#define CF_IDE_RES_SIZE 0x08 -#define CS_PULSE_MAXIMUM 319 -#define ER_SMC_CALC 1 -#define ER_SMC_RECALC 2 - -struct at91_ide_info { - unsigned long mode; - unsigned int cs; - struct clk *mck; - void __iomem *ide_addr; - void __iomem *alt_addr; -}; - -/** - * struct smc_range - range of valid values for SMC register. - */ -struct smc_range { - int min; - int max; -}; - -struct regmap *smc; - -struct at91sam9_smc_generic_fields { - struct regmap_field *setup; - struct regmap_field *pulse; - struct regmap_field *cycle; - struct regmap_field *mode; -} fields; - -/** - * adjust_smc_value - adjust value for one of SMC registers. - * @value: adjusted value - * @range: array of SMC ranges with valid values - * @size: SMC ranges array size - * - * This returns the difference between input and output value or negative - * in case of invalid input value. - * If negative returned, then output value = maximal possible from ranges. - */ -static int adjust_smc_value(int *value, struct smc_range *range, int size) -{ - int maximum = (range + size - 1)->max; - int remainder; - - do { - if (*value < range->min) { - remainder = range->min - *value; - *value = range->min; /* nearest valid value */ - return remainder; - } else if ((range->min <= *value) && (*value <= range->max)) - return 0; - - range++; - } while (--size); - *value = maximum; - - return -1; /* invalid value */ -} - -/** - * calc_smc_vals - calculate SMC register values - * @dev: ATA device - * @setup: SMC_SETUP register value - * @pulse: SMC_PULSE register value - * @cycle: SMC_CYCLE register value - * - * This returns negative in case of invalid values for SMC registers: - * -ER_SMC_RECALC - recalculation required for SMC values, - * -ER_SMC_CALC - calculation failed (invalid input values). - * - * SMC use special coding scheme, see "Coding and Range of Timing - * Parameters" table from AT91SAM9 datasheets. - * - * SMC_SETUP = 128*setup[5] + setup[4:0] - * SMC_PULSE = 256*pulse[6] + pulse[5:0] - * SMC_CYCLE = 256*cycle[8:7] + cycle[6:0] - */ -static int calc_smc_vals(struct device *dev, - int *setup, int *pulse, int *cycle, int *cs_pulse) -{ - int ret_val; - int err = 0; - struct smc_range range_setup[] = { /* SMC_SETUP valid values */ - {.min = 0, .max = 31}, /* first range */ - {.min = 128, .max = 159} /* second range */ - }; - struct smc_range range_pulse[] = { /* SMC_PULSE valid values */ - {.min = 0, .max = 63}, /* first range */ - {.min = 256, .max = 319} /* second range */ - }; - struct smc_range range_cycle[] = { /* SMC_CYCLE valid values */ - {.min = 0, .max = 127}, /* first range */ - {.min = 256, .max = 383}, /* second range */ - {.min = 512, .max = 639}, /* third range */ - {.min = 768, .max = 895} /* fourth range */ - }; - - ret_val = adjust_smc_value(setup, range_setup, ARRAY_SIZE(range_setup)); - if (ret_val < 0) - dev_warn(dev, "maximal SMC Setup value\n"); - else - *cycle += ret_val; - - ret_val = adjust_smc_value(pulse, range_pulse, ARRAY_SIZE(range_pulse)); - if (ret_val < 0) - dev_warn(dev, "maximal SMC Pulse value\n"); - else - *cycle += ret_val; - - ret_val = adjust_smc_value(cycle, range_cycle, ARRAY_SIZE(range_cycle)); - if (ret_val < 0) - dev_warn(dev, "maximal SMC Cycle value\n"); - - *cs_pulse = *cycle; - if (*cs_pulse > CS_PULSE_MAXIMUM) { - dev_err(dev, "unable to calculate valid SMC settings\n"); - return -ER_SMC_CALC; - } - - ret_val = adjust_smc_value(cs_pulse, range_pulse, - ARRAY_SIZE(range_pulse)); - if (ret_val < 0) { - dev_warn(dev, "maximal SMC CS Pulse value\n"); - } else if (ret_val != 0) { - *cycle = *cs_pulse; - dev_warn(dev, "SMC Cycle extended\n"); - err = -ER_SMC_RECALC; - } - - return err; -} - -/** - * to_smc_format - convert values into SMC format - * @setup: SETUP value of SMC Setup Register - * @pulse: PULSE value of SMC Pulse Register - * @cycle: CYCLE value of SMC Cycle Register - * @cs_pulse: NCS_PULSE value of SMC Pulse Register - */ -static void to_smc_format(int *setup, int *pulse, int *cycle, int *cs_pulse) -{ - *setup = (*setup & 0x1f) | ((*setup & 0x80) >> 2); - *pulse = (*pulse & 0x3f) | ((*pulse & 0x100) >> 2); - *cycle = (*cycle & 0x7f) | ((*cycle & 0x300) >> 1); - *cs_pulse = (*cs_pulse & 0x3f) | ((*cs_pulse & 0x100) >> 2); -} - -static unsigned long calc_mck_cycles(unsigned long ns, unsigned long mck_hz) -{ - unsigned long mul; - - /* - * cycles = x [nsec] * f [Hz] / 10^9 [ns in sec] = - * x * (f / 1_000_000_000) = - * x * ((f * 65536) / 1_000_000_000) / 65536 = - * x * (((f / 10_000) * 65536) / 100_000) / 65536 = - */ - - mul = (mck_hz / 10000) << 16; - mul /= 100000; - - return (ns * mul + 65536) >> 16; /* rounding */ -} - -/** - * set_smc_timing - SMC timings setup. - * @dev: device - * @info: AT91 IDE info - * @ata: ATA timings - * - * Its assumed that write timings are same as read timings, - * cs_setup = 0 and cs_pulse = cycle. - */ -static void set_smc_timing(struct device *dev, struct ata_device *adev, - struct at91_ide_info *info, const struct ata_timing *ata) -{ - int ret = 0; - int use_iordy; - unsigned int t6z; /* data tristate time in ns */ - unsigned int cycle; /* SMC Cycle width in MCK ticks */ - unsigned int setup; /* SMC Setup width in MCK ticks */ - unsigned int pulse; /* CFIOR and CFIOW pulse width in MCK ticks */ - unsigned int cs_pulse; /* CS4 or CS5 pulse width in MCK ticks*/ - unsigned int tdf_cycles; /* SMC TDF MCK ticks */ - unsigned long mck_hz; /* MCK frequency in Hz */ - - t6z = (ata->mode < XFER_PIO_5) ? 30 : 20; - mck_hz = clk_get_rate(info->mck); - cycle = calc_mck_cycles(ata->cyc8b, mck_hz); - setup = calc_mck_cycles(ata->setup, mck_hz); - pulse = calc_mck_cycles(ata->act8b, mck_hz); - tdf_cycles = calc_mck_cycles(t6z, mck_hz); - - do { - ret = calc_smc_vals(dev, &setup, &pulse, &cycle, &cs_pulse); - } while (ret == -ER_SMC_RECALC); - - if (ret == -ER_SMC_CALC) - dev_err(dev, "Interface may not operate correctly\n"); - - dev_dbg(dev, "SMC Setup=%u, Pulse=%u, Cycle=%u, CS Pulse=%u\n", - setup, pulse, cycle, cs_pulse); - to_smc_format(&setup, &pulse, &cycle, &cs_pulse); - /* disable or enable waiting for IORDY signal */ - use_iordy = ata_pio_need_iordy(adev); - if (use_iordy) - info->mode |= AT91_SMC_EXNWMODE_READY; - - if (tdf_cycles > 15) { - tdf_cycles = 15; - dev_warn(dev, "maximal SMC TDF Cycles value\n"); - } - - dev_dbg(dev, "Use IORDY=%u, TDF Cycles=%u\n", use_iordy, tdf_cycles); - - regmap_fields_write(fields.setup, info->cs, - AT91SAM9_SMC_NRDSETUP(setup) | - AT91SAM9_SMC_NWESETUP(setup) | - AT91SAM9_SMC_NCS_NRDSETUP(0) | - AT91SAM9_SMC_NCS_WRSETUP(0)); - regmap_fields_write(fields.pulse, info->cs, - AT91SAM9_SMC_NRDPULSE(pulse) | - AT91SAM9_SMC_NWEPULSE(pulse) | - AT91SAM9_SMC_NCS_NRDPULSE(cs_pulse) | - AT91SAM9_SMC_NCS_WRPULSE(cs_pulse)); - regmap_fields_write(fields.cycle, info->cs, - AT91SAM9_SMC_NRDCYCLE(cycle) | - AT91SAM9_SMC_NWECYCLE(cycle)); - regmap_fields_write(fields.mode, info->cs, info->mode | - AT91_SMC_TDF_(tdf_cycles)); -} - -static void pata_at91_set_piomode(struct ata_port *ap, struct ata_device *adev) -{ - struct at91_ide_info *info = ap->host->private_data; - struct ata_timing timing; - int ret; - - /* Compute ATA timing and set it to SMC */ - ret = ata_timing_compute(adev, adev->pio_mode, &timing, 1000, 0); - if (ret) { - dev_warn(ap->dev, "Failed to compute ATA timing %d, " - "set PIO_0 timing\n", ret); - timing = *ata_timing_find_mode(XFER_PIO_0); - } - set_smc_timing(ap->dev, adev, info, &timing); -} - -static unsigned int pata_at91_data_xfer_noirq(struct ata_queued_cmd *qc, - unsigned char *buf, unsigned int buflen, int rw) -{ - struct at91_ide_info *info = qc->dev->link->ap->host->private_data; - unsigned int consumed; - unsigned int mode; - unsigned long flags; - - local_irq_save(flags); - regmap_fields_read(fields.mode, info->cs, &mode); - - /* set 16bit mode before writing data */ - regmap_fields_write(fields.mode, info->cs, (mode & ~AT91_SMC_DBW) | - AT91_SMC_DBW_16); - - consumed = ata_sff_data_xfer(qc, buf, buflen, rw); - - /* restore 8bit mode after data is written */ - regmap_fields_write(fields.mode, info->cs, (mode & ~AT91_SMC_DBW) | - AT91_SMC_DBW_8); - - local_irq_restore(flags); - return consumed; -} - -static struct scsi_host_template pata_at91_sht = { - ATA_PIO_SHT(DRV_NAME), -}; - -static struct ata_port_operations pata_at91_port_ops = { - .inherits = &ata_sff_port_ops, - - .sff_data_xfer = pata_at91_data_xfer_noirq, - .set_piomode = pata_at91_set_piomode, - .cable_detect = ata_cable_40wire, -}; - -static int at91sam9_smc_fields_init(struct device *dev) -{ - struct reg_field field = REG_FIELD(0, 0, 31); - - field.id_size = 8; - field.id_offset = AT91SAM9_SMC_GENERIC_BLK_SZ; - - field.reg = AT91SAM9_SMC_SETUP(AT91SAM9_SMC_GENERIC); - fields.setup = devm_regmap_field_alloc(dev, smc, field); - if (IS_ERR(fields.setup)) - return PTR_ERR(fields.setup); - - field.reg = AT91SAM9_SMC_PULSE(AT91SAM9_SMC_GENERIC); - fields.pulse = devm_regmap_field_alloc(dev, smc, field); - if (IS_ERR(fields.pulse)) - return PTR_ERR(fields.pulse); - - field.reg = AT91SAM9_SMC_CYCLE(AT91SAM9_SMC_GENERIC); - fields.cycle = devm_regmap_field_alloc(dev, smc, field); - if (IS_ERR(fields.cycle)) - return PTR_ERR(fields.cycle); - - field.reg = AT91SAM9_SMC_MODE(AT91SAM9_SMC_GENERIC); - fields.mode = devm_regmap_field_alloc(dev, smc, field); - - return PTR_ERR_OR_ZERO(fields.mode); -} - -static int pata_at91_probe(struct platform_device *pdev) -{ - struct at91_cf_data *board = dev_get_platdata(&pdev->dev); - struct device *dev = &pdev->dev; - struct at91_ide_info *info; - struct resource *mem_res; - struct ata_host *host; - struct ata_port *ap; - - int irq_flags = 0; - int irq = 0; - int ret; - - /* get platform resources: IO/CTL memories and irq/rst pins */ - - if (pdev->num_resources != 1) { - dev_err(&pdev->dev, "invalid number of resources\n"); - return -EINVAL; - } - - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - if (!mem_res) { - dev_err(dev, "failed to get mem resource\n"); - return -EINVAL; - } - - irq = board->irq_pin; - - smc = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "atmel,smc"); - if (IS_ERR(smc)) - return PTR_ERR(smc); - - ret = at91sam9_smc_fields_init(dev); - if (ret < 0) - return ret; - - /* init ata host */ - - host = ata_host_alloc(dev, 1); - - if (!host) - return -ENOMEM; - - ap = host->ports[0]; - ap->ops = &pata_at91_port_ops; - ap->flags |= ATA_FLAG_SLAVE_POSS; - ap->pio_mask = ATA_PIO4; - - if (!gpio_is_valid(irq)) { - ap->flags |= ATA_FLAG_PIO_POLLING; - ata_port_desc(ap, "no IRQ, using PIO polling"); - } - - info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); - - if (!info) { - dev_err(dev, "failed to allocate memory for private data\n"); - return -ENOMEM; - } - - info->mck = clk_get(NULL, "mck"); - - if (IS_ERR(info->mck)) { - dev_err(dev, "failed to get access to mck clock\n"); - return -ENODEV; - } - - info->cs = board->chipselect; - info->mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | - AT91_SMC_EXNWMODE_READY | AT91_SMC_BAT_SELECT | - AT91_SMC_DBW_8 | AT91_SMC_TDF_(0); - - info->ide_addr = devm_ioremap(dev, - mem_res->start + CF_IDE_OFFSET, CF_IDE_RES_SIZE); - - if (!info->ide_addr) { - dev_err(dev, "failed to map IO base\n"); - ret = -ENOMEM; - goto err_put; - } - - info->alt_addr = devm_ioremap(dev, - mem_res->start + CF_ALT_IDE_OFFSET, CF_IDE_RES_SIZE); - - if (!info->alt_addr) { - dev_err(dev, "failed to map CTL base\n"); - ret = -ENOMEM; - goto err_put; - } - - ap->ioaddr.cmd_addr = info->ide_addr; - ap->ioaddr.ctl_addr = info->alt_addr + 0x06; - ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr; - - ata_sff_std_ports(&ap->ioaddr); - - ata_port_desc(ap, "mmio cmd 0x%llx ctl 0x%llx", - (unsigned long long)mem_res->start + CF_IDE_OFFSET, - (unsigned long long)mem_res->start + CF_ALT_IDE_OFFSET); - - host->private_data = info; - - ret = ata_host_activate(host, gpio_is_valid(irq) ? gpio_to_irq(irq) : 0, - gpio_is_valid(irq) ? ata_sff_interrupt : NULL, - irq_flags, &pata_at91_sht); - if (ret) - goto err_put; - - return 0; - -err_put: - clk_put(info->mck); - return ret; -} - -static int pata_at91_remove(struct platform_device *pdev) -{ - struct ata_host *host = platform_get_drvdata(pdev); - struct at91_ide_info *info; - - if (!host) - return 0; - info = host->private_data; - - ata_host_detach(host); - - if (!info) - return 0; - - clk_put(info->mck); - - return 0; -} - -static struct platform_driver pata_at91_driver = { - .probe = pata_at91_probe, - .remove = pata_at91_remove, - .driver = { - .name = DRV_NAME, - }, -}; - -module_platform_driver(pata_at91_driver); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Driver for CF in True IDE mode on AT91SAM9260 SoC"); -MODULE_AUTHOR("Matyukevich Sergey"); -MODULE_VERSION(DRV_VERSION); - -- cgit v1.2.3 From df46e6a4c06c89a728e59073517001510a63955b Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Tue, 14 Mar 2017 12:04:51 +0100 Subject: ata: ahci: add support for DaVinci DM816 SATA controller This SATA controller is quite similar to the one present on the DA850 SoC, but the PHY configuration is different and it supports two HBA ports. The IP suffers from the same PMP issue the DA850 does - if we enable PMP but don't use it - softreset fails. Appropriate workaround was implemented in this driver as well. Signed-off-by: Bartosz Golaszewski Signed-off-by: Tejun Heo --- drivers/ata/Kconfig | 9 +++ drivers/ata/Makefile | 1 + drivers/ata/ahci_dm816.c | 200 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 210 insertions(+) create mode 100644 drivers/ata/ahci_dm816.c (limited to 'drivers') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 19069feb196d..ff6cb9e4c381 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -117,6 +117,15 @@ config AHCI_DA850 If unsure, say N. +config AHCI_DM816 + tristate "DaVinci DM816 AHCI SATA support" + depends on ARCH_OMAP2PLUS + help + This option enables support for the DaVinci DM816 SoC's + onboard AHCI SATA controller. + + If unsure, say N. + config AHCI_ST tristate "ST AHCI SATA support" depends on ARCH_STI diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index e29feb16bda1..3048cc100a46 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o obj-$(CONFIG_AHCI_BRCM) += ahci_brcm.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_CEVA) += ahci_ceva.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_DA850) += ahci_da850.o libahci.o libahci_platform.o +obj-$(CONFIG_AHCI_DM816) += ahci_dm816.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_IMX) += ahci_imx.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_MVEBU) += ahci_mvebu.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_OCTEON) += ahci_octeon.o diff --git a/drivers/ata/ahci_dm816.c b/drivers/ata/ahci_dm816.c new file mode 100644 index 000000000000..fbd827c3a75c --- /dev/null +++ b/drivers/ata/ahci_dm816.c @@ -0,0 +1,200 @@ +/* + * DaVinci DM816 AHCI SATA platform driver + * + * Copyright (C) 2017 BayLibre SAS + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "ahci.h" + +#define AHCI_DM816_DRV_NAME "ahci-dm816" + +#define AHCI_DM816_PHY_ENPLL(x) ((x) << 0) +#define AHCI_DM816_PHY_MPY(x) ((x) << 1) +#define AHCI_DM816_PHY_LOS(x) ((x) << 12) +#define AHCI_DM816_PHY_RXCDR(x) ((x) << 13) +#define AHCI_DM816_PHY_RXEQ(x) ((x) << 16) +#define AHCI_DM816_PHY_TXSWING(x) ((x) << 23) + +#define AHCI_DM816_P0PHYCR_REG 0x178 +#define AHCI_DM816_P1PHYCR_REG 0x1f8 + +#define AHCI_DM816_PLL_OUT 1500000000LU + +static const unsigned long pll_mpy_table[] = { + 400, 500, 600, 800, 825, 1000, 1200, + 1250, 1500, 1600, 1650, 2000, 2200, 2500 +}; + +static int ahci_dm816_get_mpy_bits(unsigned long refclk_rate) +{ + unsigned long pll_multiplier; + int i; + + /* + * We need to determine the value of the multiplier (MPY) bits. + * In order to include the 8.25 multiplier we need to first divide + * the refclk rate by 100. + */ + pll_multiplier = AHCI_DM816_PLL_OUT / (refclk_rate / 100); + + for (i = 0; i < ARRAY_SIZE(pll_mpy_table); i++) { + if (pll_mpy_table[i] == pll_multiplier) + return i; + } + + /* + * We should have divided evenly - if not, return an invalid + * value. + */ + return -1; +} + +static int ahci_dm816_phy_init(struct ahci_host_priv *hpriv, struct device *dev) +{ + unsigned long refclk_rate; + int mpy; + u32 val; + + /* + * We should have been supplied two clocks: the functional and + * keep-alive clock and the external reference clock. We need the + * rate of the latter to calculate the correct value of MPY bits. + */ + if (!hpriv->clks[1]) { + dev_err(dev, "reference clock not supplied\n"); + return -EINVAL; + } + + refclk_rate = clk_get_rate(hpriv->clks[1]); + if ((refclk_rate % 100) != 0) { + dev_err(dev, "reference clock rate must be divisible by 100\n"); + return -EINVAL; + } + + mpy = ahci_dm816_get_mpy_bits(refclk_rate); + if (mpy < 0) { + dev_err(dev, "can't calculate the MPY bits value\n"); + return -EINVAL; + } + + /* Enable the PHY and configure the first HBA port. */ + val = AHCI_DM816_PHY_MPY(mpy) | AHCI_DM816_PHY_LOS(1) | + AHCI_DM816_PHY_RXCDR(4) | AHCI_DM816_PHY_RXEQ(1) | + AHCI_DM816_PHY_TXSWING(3) | AHCI_DM816_PHY_ENPLL(1); + writel(val, hpriv->mmio + AHCI_DM816_P0PHYCR_REG); + + /* Configure the second HBA port. */ + val = AHCI_DM816_PHY_LOS(1) | AHCI_DM816_PHY_RXCDR(4) | + AHCI_DM816_PHY_RXEQ(1) | AHCI_DM816_PHY_TXSWING(3); + writel(val, hpriv->mmio + AHCI_DM816_P1PHYCR_REG); + + return 0; +} + +static int ahci_dm816_softreset(struct ata_link *link, + unsigned int *class, unsigned long deadline) +{ + int pmp, ret; + + pmp = sata_srst_pmp(link); + + /* + * There's an issue with the SATA controller on DM816 SoC: if we + * enable Port Multiplier support, but the drive is connected directly + * to the board, it can't be detected. As a workaround: if PMP is + * enabled, we first call ahci_do_softreset() and pass it the result of + * sata_srst_pmp(). If this call fails, we retry with pmp = 0. + */ + ret = ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready); + if (pmp && ret == -EBUSY) + return ahci_do_softreset(link, class, 0, + deadline, ahci_check_ready); + + return ret; +} + +static struct ata_port_operations ahci_dm816_port_ops = { + .inherits = &ahci_platform_ops, + .softreset = ahci_dm816_softreset, +}; + +static const struct ata_port_info ahci_dm816_port_info = { + .flags = AHCI_FLAG_COMMON, + .pio_mask = ATA_PIO4, + .udma_mask = ATA_UDMA6, + .port_ops = &ahci_dm816_port_ops, +}; + +static struct scsi_host_template ahci_dm816_platform_sht = { + AHCI_SHT(AHCI_DM816_DRV_NAME), +}; + +static int ahci_dm816_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct ahci_host_priv *hpriv; + int rc; + + hpriv = ahci_platform_get_resources(pdev); + if (IS_ERR(hpriv)) + return PTR_ERR(hpriv); + + rc = ahci_platform_enable_resources(hpriv); + if (rc) + return rc; + + rc = ahci_dm816_phy_init(hpriv, dev); + if (rc) + goto disable_resources; + + rc = ahci_platform_init_host(pdev, hpriv, + &ahci_dm816_port_info, + &ahci_dm816_platform_sht); + if (rc) + goto disable_resources; + + return 0; + +disable_resources: + ahci_platform_disable_resources(hpriv); + + return rc; +} + +static SIMPLE_DEV_PM_OPS(ahci_dm816_pm_ops, + ahci_platform_suspend, + ahci_platform_resume); + +static const struct of_device_id ahci_dm816_of_match[] = { + { .compatible = "ti,dm816-ahci", }, + { }, +}; +MODULE_DEVICE_TABLE(of, ahci_dm816_of_match); + +static struct platform_driver ahci_dm816_driver = { + .probe = ahci_dm816_probe, + .remove = ata_platform_remove_one, + .driver = { + .name = AHCI_DM816_DRV_NAME, + .of_match_table = ahci_dm816_of_match, + .pm = &ahci_dm816_pm_ops, + }, +}; +module_platform_driver(ahci_dm816_driver); + +MODULE_DESCRIPTION("DaVinci DM816 AHCI SATA platform driver"); +MODULE_AUTHOR("Bartosz Golaszewski "); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From c6ade20f5e50e188d20b711a618b20dd1d50457e Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 25 Apr 2017 13:39:54 +0200 Subject: libata: reject passthrough WRITE SAME requests The WRITE SAME to TRIM translation rewrites the DATA OUT buffer. While the SCSI code accomodates for this by passing a read-writable buffer userspace applications don't cater for this behavior. In fact it can be used to rewrite e.g. a readonly file through mmap and should be considered as a security fix. Signed-off-by: Christoph Hellwig Cc: stable@vger.kernel.org Reviewed-by: Martin K. Petersen Signed-off-by: Tejun Heo --- drivers/ata/libata-scsi.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 1ac70744ae7b..50f56d066936 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3462,6 +3462,14 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) if (unlikely(!dev->dma_mode)) goto invalid_opcode; + /* + * We only allow sending this command through the block layer, + * as it modifies the DATA OUT buffer, which would corrupt user + * memory for SG_IO commands. + */ + if (unlikely(blk_rq_is_passthrough(scmd->request))) + goto invalid_opcode; + if (unlikely(scmd->cmd_len < 16)) { fp = 15; goto invalid_fld; -- cgit v1.2.3 From 63ccc191649eb0f14a761074291551d0d2f85389 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 25 Apr 2017 14:26:52 +0200 Subject: libata: remove SCT WRITE SAME support This was already disabled a while ago because it caused I/O errors, and it's severly getting into the way of the discard / write zeroes rework. Signed-off-by: Christoph Hellwig Reviewed-by: Martin K. Petersen Signed-off-by: Tejun Heo --- drivers/ata/libata-scsi.c | 132 ++++++++++------------------------------------ include/linux/ata.h | 5 -- 2 files changed, 29 insertions(+), 108 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 50f56d066936..49ba9834c715 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3392,46 +3392,6 @@ static size_t ata_format_dsm_trim_descr(struct scsi_cmnd *cmd, u32 trmax, return r; } -/** - * ata_format_dsm_trim_descr() - SATL Write Same to ATA SCT Write Same - * @cmd: SCSI command being translated - * @lba: Starting sector - * @num: Number of sectors to be zero'd. - * - * Rewrite the WRITE SAME payload to be an SCT Write Same formatted - * descriptor. - * NOTE: Writes a pattern (0's) in the foreground. - * - * Return: Number of bytes copied into sglist. - */ -static size_t ata_format_sct_write_same(struct scsi_cmnd *cmd, u64 lba, u64 num) -{ - struct scsi_device *sdp = cmd->device; - size_t len = sdp->sector_size; - size_t r; - u16 *buf; - unsigned long flags; - - spin_lock_irqsave(&ata_scsi_rbuf_lock, flags); - buf = ((void *)ata_scsi_rbuf); - - put_unaligned_le16(0x0002, &buf[0]); /* SCT_ACT_WRITE_SAME */ - put_unaligned_le16(0x0101, &buf[1]); /* WRITE PTRN FG */ - put_unaligned_le64(lba, &buf[2]); - put_unaligned_le64(num, &buf[6]); - put_unaligned_le32(0u, &buf[10]); /* pattern */ - - WARN_ON(len > ATA_SCSI_RBUF_SIZE); - - if (len > ATA_SCSI_RBUF_SIZE) - len = ATA_SCSI_RBUF_SIZE; - - r = sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buf, len); - spin_unlock_irqrestore(&ata_scsi_rbuf_lock, flags); - - return r; -} - /** * ata_scsi_write_same_xlat() - SATL Write Same to ATA SCT Write Same * @qc: Command to be translated @@ -3476,26 +3436,17 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) } scsi_16_lba_len(cdb, &block, &n_block); - if (unmap) { - /* If trim is not enabled the cmd is invalid. */ - if ((dev->horkage & ATA_HORKAGE_NOTRIM) || - !ata_id_has_trim(dev->id)) { - fp = 1; - bp = 3; - goto invalid_fld; - } - /* If the request is too large the cmd is invalid */ - if (n_block > 0xffff * trmax) { - fp = 2; - goto invalid_fld; - } - } else { - /* If write same is not available the cmd is invalid */ - if (!ata_id_sct_write_same(dev->id)) { - fp = 1; - bp = 3; - goto invalid_fld; - } + if (!unmap || + (dev->horkage & ATA_HORKAGE_NOTRIM) || + !ata_id_has_trim(dev->id)) { + fp = 1; + bp = 3; + goto invalid_fld; + } + /* If the request is too large the cmd is invalid */ + if (n_block > 0xffff * trmax) { + fp = 2; + goto invalid_fld; } /* @@ -3510,49 +3461,28 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) * For DATA SET MANAGEMENT TRIM in ACS-2 nsect (aka count) * is defined as number of 512 byte blocks to be transferred. */ - if (unmap) { - size = ata_format_dsm_trim_descr(scmd, trmax, block, n_block); - if (size != len) - goto invalid_param_len; - if (ata_ncq_enabled(dev) && ata_fpdma_dsm_supported(dev)) { - /* Newer devices support queued TRIM commands */ - tf->protocol = ATA_PROT_NCQ; - tf->command = ATA_CMD_FPDMA_SEND; - tf->hob_nsect = ATA_SUBCMD_FPDMA_SEND_DSM & 0x1f; - tf->nsect = qc->tag << 3; - tf->hob_feature = (size / 512) >> 8; - tf->feature = size / 512; + size = ata_format_dsm_trim_descr(scmd, trmax, block, n_block); + if (size != len) + goto invalid_param_len; - tf->auxiliary = 1; - } else { - tf->protocol = ATA_PROT_DMA; - tf->hob_feature = 0; - tf->feature = ATA_DSM_TRIM; - tf->hob_nsect = (size / 512) >> 8; - tf->nsect = size / 512; - tf->command = ATA_CMD_DSM; - } - } else { - size = ata_format_sct_write_same(scmd, block, n_block); - if (size != len) - goto invalid_param_len; + if (ata_ncq_enabled(dev) && ata_fpdma_dsm_supported(dev)) { + /* Newer devices support queued TRIM commands */ + tf->protocol = ATA_PROT_NCQ; + tf->command = ATA_CMD_FPDMA_SEND; + tf->hob_nsect = ATA_SUBCMD_FPDMA_SEND_DSM & 0x1f; + tf->nsect = qc->tag << 3; + tf->hob_feature = (size / 512) >> 8; + tf->feature = size / 512; - tf->hob_feature = 0; - tf->feature = 0; - tf->hob_nsect = 0; - tf->nsect = 1; - tf->lbah = 0; - tf->lbam = 0; - tf->lbal = ATA_CMD_STANDBYNOW1; - tf->hob_lbah = 0; - tf->hob_lbam = 0; - tf->hob_lbal = 0; - tf->device = ATA_CMD_STANDBYNOW1; + tf->auxiliary = 1; + } else { tf->protocol = ATA_PROT_DMA; - tf->command = ATA_CMD_WRITE_LOG_DMA_EXT; - if (unlikely(dev->flags & ATA_DFLAG_PIO)) - tf->command = ATA_CMD_WRITE_LOG_EXT; + tf->hob_feature = 0; + tf->feature = ATA_DSM_TRIM; + tf->hob_nsect = (size / 512) >> 8; + tf->nsect = size / 512; + tf->command = ATA_CMD_DSM; } tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 | @@ -3627,10 +3557,6 @@ static unsigned int ata_scsiop_maint_in(struct ata_scsi_args *args, u8 *rbuf) case START_STOP: supported = 3; break; - case WRITE_SAME_16: - if (!ata_id_sct_write_same(dev->id)) - break; - /* fallthrough: if SCT ... only enable for ZBC */ case ZBC_IN: case ZBC_OUT: if (ata_id_zoned_cap(dev->id) || diff --git a/include/linux/ata.h b/include/linux/ata.h index af6859b3a93d..ad7d9ee89ff0 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -817,11 +817,6 @@ static inline bool ata_id_sct_error_recovery_ctrl(const u16 *id) return id[ATA_ID_SCT_CMD_XPORT] & (1 << 3) ? true : false; } -static inline bool ata_id_sct_write_same(const u16 *id) -{ - return id[ATA_ID_SCT_CMD_XPORT] & (1 << 2) ? true : false; -} - static inline bool ata_id_sct_long_sector_access(const u16 *id) { return id[ATA_ID_SCT_CMD_XPORT] & (1 << 1) ? true : false; -- cgit v1.2.3