diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-26 20:08:27 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-26 20:08:27 +0200 |
commit | c11d716218910c3aa2bac1bb641e6086ad649555 (patch) | |
tree | 13c9ea4c82360ab6150432c219430e6bc7e8bc18 /drivers/ata | |
parent | Merge branch 'akpm' (patches from Andrew) (diff) | |
parent | Merge branch 'for-arm-soc' of http://ftp.arm.linux.org.uk/pub/armlinux/kernel... (diff) | |
download | linux-c11d716218910c3aa2bac1bb641e6086ad649555.tar.xz linux-c11d716218910c3aa2bac1bb641e6086ad649555.zip |
Merge tag 'armsoc-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC cleanups from Kevin Hilman:
"A relatively small setup of cleanups this time around, and similar to
last time the bulk of it is removal of legacy board support:
- OMAP: removal of legacy (non-DT) booting for several platforms
- i.MX: remove some legacy board files"
* tag 'armsoc-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (36 commits)
ARM: fix EFM32 build breakage caused by cpu_resume_arm
ARM: 8389/1: Add cpu_resume_arm() for firmwares that resume in ARM state
ARM: v7 setup function should invalidate L1 cache
mach-omap2: Remove use of deprecated marco, PTR_RET in devices.c
ARM: OMAP2+: Remove calls to deprecacted marco,PTR_RET in the files,fb.c and pmu.c
ARM: OMAP2+: Constify irq_domain_ops
ARM: OMAP2+: use symbolic defines for console loglevels instead of numbers
ARM: at91: remove useless Makefile.boot
ARM: at91: remove at91rm9200_sdramc.h
ARM: at91: remove mach/at91_ramc.h and mach/at91rm9200_mc.h
ARM: at91/pm: use the atmel-mc syscon defines
pcmcia: at91_cf: Use syscon to configure the MC/smc
ARM: at91: declare the at91rm9200 memory controller as a syscon
mfd: syscon: Add Atmel MC (Memory Controller) registers definition
ARM: at91: drop sam9_smc.c
ata: at91: use syscon to configure the smc
ARM: ux500: delete static resource defines
ARM: ux500: rename ux500_map_io
ARM: ux500: look up PRCMU resource from DT
ARM: ux500: kill off L2CC static map
...
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/Kconfig | 1 | ||||
-rw-r--r-- | drivers/ata/pata_at91.c | 92 |
2 files changed, 71 insertions, 22 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index b11470a7bd8f..6d17a3b65ef7 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -845,7 +845,6 @@ config PATA_AT32 config PATA_AT91 tristate "PATA support for AT91SAM9260" depends on ARM && SOC_AT91SAM9 - depends on !ARCH_MULTIPLATFORM help This option enables support for IDE devices on the Atmel AT91SAM9260 SoC. diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c index 9e85937d36a9..ace0a4de3449 100644 --- a/drivers/ata/pata_at91.c +++ b/drivers/ata/pata_at91.c @@ -24,11 +24,13 @@ #include <linux/ata.h> #include <linux/clk.h> #include <linux/libata.h> +#include <linux/mfd/syscon.h> +#include <linux/mfd/syscon/atmel-smc.h> #include <linux/platform_device.h> #include <linux/ata_platform.h> #include <linux/platform_data/atmel.h> +#include <linux/regmap.h> -#include <mach/at91sam9_smc.h> #include <asm/gpio.h> #define DRV_NAME "pata_at91" @@ -57,6 +59,15 @@ struct smc_range { 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 @@ -206,7 +217,6 @@ static void set_smc_timing(struct device *dev, struct ata_device *adev, { int ret = 0; int use_iordy; - struct sam9_smc_config smc; 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 */ @@ -244,19 +254,21 @@ static void set_smc_timing(struct device *dev, struct ata_device *adev, dev_dbg(dev, "Use IORDY=%u, TDF Cycles=%u\n", use_iordy, tdf_cycles); - /* SMC Setup Register */ - smc.nwe_setup = smc.nrd_setup = setup; - smc.ncs_write_setup = smc.ncs_read_setup = 0; - /* SMC Pulse Register */ - smc.nwe_pulse = smc.nrd_pulse = pulse; - smc.ncs_write_pulse = smc.ncs_read_pulse = cs_pulse; - /* SMC Cycle Register */ - smc.write_cycle = smc.read_cycle = cycle; - /* SMC Mode Register*/ - smc.tdf_cycles = tdf_cycles; - smc.mode = info->mode; - - sam9_smc_configure(0, info->cs, &smc); + 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) @@ -280,21 +292,21 @@ static unsigned int pata_at91_data_xfer_noirq(struct ata_device *dev, { struct at91_ide_info *info = dev->link->ap->host->private_data; unsigned int consumed; + unsigned int mode; unsigned long flags; - struct sam9_smc_config smc; local_irq_save(flags); - sam9_smc_read_mode(0, info->cs, &smc); + regmap_fields_read(fields.mode, info->cs, &mode); /* set 16bit mode before writing data */ - smc.mode = (smc.mode & ~AT91_SMC_DBW) | AT91_SMC_DBW_16; - sam9_smc_write_mode(0, info->cs, &smc); + regmap_fields_write(fields.mode, info->cs, (mode & ~AT91_SMC_DBW) | + AT91_SMC_DBW_16); consumed = ata_sff_data_xfer(dev, buf, buflen, rw); /* restore 8bit mode after data is written */ - smc.mode = (smc.mode & ~AT91_SMC_DBW) | AT91_SMC_DBW_8; - sam9_smc_write_mode(0, info->cs, &smc); + regmap_fields_write(fields.mode, info->cs, (mode & ~AT91_SMC_DBW) | + AT91_SMC_DBW_8); local_irq_restore(flags); return consumed; @@ -312,6 +324,36 @@ static struct ata_port_operations pata_at91_port_ops = { .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); + if (IS_ERR(fields.mode)) + return PTR_ERR(fields.mode); + + return 0; +} + static int pata_at91_probe(struct platform_device *pdev) { struct at91_cf_data *board = dev_get_platdata(&pdev->dev); @@ -341,6 +383,14 @@ static int pata_at91_probe(struct platform_device *pdev) 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); |