--- zzzz-none-000/linux-3.10.107/drivers/ata/pata_at91.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/ata/pata_at91.c 2021-02-04 17:41:59.000000000 +0000 @@ -18,18 +18,19 @@ #include #include -#include #include #include #include #include #include #include +#include +#include #include #include #include +#include -#include #include #define DRV_NAME "pata_at91" @@ -58,6 +59,15 @@ 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 @@ -207,7 +217,6 @@ { 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 */ @@ -245,19 +254,21 @@ 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) @@ -281,21 +292,21 @@ { 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; @@ -313,9 +324,39 @@ .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 = pdev->dev.platform_data; + struct at91_cf_data *board = dev_get_platdata(&pdev->dev); struct device *dev = &pdev->dev; struct at91_ide_info *info; struct resource *mem_res; @@ -342,6 +383,14 @@ 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); @@ -423,7 +472,7 @@ static int pata_at91_remove(struct platform_device *pdev) { - struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct ata_host *host = platform_get_drvdata(pdev); struct at91_ide_info *info; if (!host) @@ -445,7 +494,6 @@ .remove = pata_at91_remove, .driver = { .name = DRV_NAME, - .owner = THIS_MODULE, }, };