Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * OF-platform PATA driver
0004  *
0005  * Copyright (c) 2007  MontaVista Software, Inc.
0006  *                     Anton Vorontsov <avorontsov@ru.mvista.com>
0007  */
0008 
0009 #include <linux/kernel.h>
0010 #include <linux/module.h>
0011 #include <linux/of_address.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/ata_platform.h>
0014 #include <linux/libata.h>
0015 
0016 #define DRV_NAME "pata_of_platform"
0017 
0018 static struct scsi_host_template pata_platform_sht = {
0019     ATA_PIO_SHT(DRV_NAME),
0020 };
0021 
0022 static int pata_of_platform_probe(struct platform_device *ofdev)
0023 {
0024     int ret;
0025     struct device_node *dn = ofdev->dev.of_node;
0026     struct resource io_res;
0027     struct resource ctl_res;
0028     struct resource irq_res;
0029     unsigned int reg_shift = 0;
0030     int pio_mode = 0;
0031     int pio_mask;
0032     bool use16bit;
0033     int irq;
0034 
0035     ret = of_address_to_resource(dn, 0, &io_res);
0036     if (ret) {
0037         dev_err(&ofdev->dev, "can't get IO address from "
0038             "device tree\n");
0039         return -EINVAL;
0040     }
0041 
0042     ret = of_address_to_resource(dn, 1, &ctl_res);
0043     if (ret) {
0044         dev_err(&ofdev->dev, "can't get CTL address from "
0045             "device tree\n");
0046         return -EINVAL;
0047     }
0048 
0049     memset(&irq_res, 0, sizeof(irq_res));
0050 
0051     irq = platform_get_irq_optional(ofdev, 0);
0052     if (irq < 0 && irq != -ENXIO)
0053         return irq;
0054     if (irq > 0) {
0055         irq_res.start = irq;
0056         irq_res.end = irq;
0057     }
0058 
0059     of_property_read_u32(dn, "reg-shift", &reg_shift);
0060 
0061     if (!of_property_read_u32(dn, "pio-mode", &pio_mode)) {
0062         if (pio_mode > 6) {
0063             dev_err(&ofdev->dev, "invalid pio-mode\n");
0064             return -EINVAL;
0065         }
0066     } else {
0067         dev_info(&ofdev->dev, "pio-mode unspecified, assuming PIO0\n");
0068     }
0069 
0070     use16bit = of_property_read_bool(dn, "ata-generic,use16bit");
0071 
0072     pio_mask = 1 << pio_mode;
0073     pio_mask |= (1 << pio_mode) - 1;
0074 
0075     return __pata_platform_probe(&ofdev->dev, &io_res, &ctl_res, irq > 0 ? &irq_res : NULL,
0076                      reg_shift, pio_mask, &pata_platform_sht,
0077                      use16bit);
0078 }
0079 
0080 static const struct of_device_id pata_of_platform_match[] = {
0081     { .compatible = "ata-generic", },
0082     { /* sentinel */ }
0083 };
0084 MODULE_DEVICE_TABLE(of, pata_of_platform_match);
0085 
0086 static struct platform_driver pata_of_platform_driver = {
0087     .driver = {
0088         .name = DRV_NAME,
0089         .of_match_table = pata_of_platform_match,
0090     },
0091     .probe      = pata_of_platform_probe,
0092     .remove     = ata_platform_remove_one,
0093 };
0094 
0095 module_platform_driver(pata_of_platform_driver);
0096 
0097 MODULE_DESCRIPTION("OF-platform PATA driver");
0098 MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>");
0099 MODULE_LICENSE("GPL");