root/drivers/ata/pata_rb532_cf.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rb532_pata_irq_handler
  2. rb532_pata_setup_ports
  3. rb532_pata_driver_probe
  4. rb532_pata_driver_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  A low-level PATA driver to handle a Compact Flash connected on the
   4  *  Mikrotik's RouterBoard 532 board.
   5  *
   6  *  Copyright (C) 2007 Gabor Juhos <juhosg at openwrt.org>
   7  *  Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
   8  *
   9  *  This file was based on: drivers/ata/pata_ixp4xx_cf.c
  10  *      Copyright (C) 2006-07 Tower Technologies
  11  *      Author: Alessandro Zummo <a.zummo@towertech.it>
  12  *
  13  *  Also was based on the driver for Linux 2.4.xx published by Mikrotik for
  14  *  their RouterBoard 1xx and 5xx series devices. The original Mikrotik code
  15  *  seems not to have a license.
  16  */
  17 
  18 #include <linux/gfp.h>
  19 #include <linux/kernel.h>
  20 #include <linux/module.h>
  21 #include <linux/platform_device.h>
  22 
  23 #include <linux/io.h>
  24 #include <linux/interrupt.h>
  25 #include <linux/irq.h>
  26 #include <linux/gpio/consumer.h>
  27 
  28 #include <linux/libata.h>
  29 #include <scsi/scsi_host.h>
  30 
  31 #include <asm/mach-rc32434/rb.h>
  32 
  33 #define DRV_NAME        "pata-rb532-cf"
  34 #define DRV_VERSION     "0.1.0"
  35 #define DRV_DESC        "PATA driver for RouterBOARD 532 Compact Flash"
  36 
  37 #define RB500_CF_MAXPORTS       1
  38 #define RB500_CF_IO_DELAY       400
  39 
  40 #define RB500_CF_REG_BASE       0x0800
  41 #define RB500_CF_REG_ERR        0x080D
  42 #define RB500_CF_REG_CTRL       0x080E
  43 /* 32bit buffered data register offset */
  44 #define RB500_CF_REG_DBUF32     0x0C00
  45 
  46 struct rb532_cf_info {
  47         void __iomem    *iobase;
  48         struct gpio_desc *gpio_line;
  49         unsigned int    irq;
  50 };
  51 
  52 /* ------------------------------------------------------------------------ */
  53 
  54 static irqreturn_t rb532_pata_irq_handler(int irq, void *dev_instance)
  55 {
  56         struct ata_host *ah = dev_instance;
  57         struct rb532_cf_info *info = ah->private_data;
  58 
  59         if (gpiod_get_value(info->gpio_line)) {
  60                 irq_set_irq_type(info->irq, IRQ_TYPE_LEVEL_LOW);
  61                 ata_sff_interrupt(info->irq, dev_instance);
  62         } else {
  63                 irq_set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH);
  64         }
  65 
  66         return IRQ_HANDLED;
  67 }
  68 
  69 static struct ata_port_operations rb532_pata_port_ops = {
  70         .inherits               = &ata_sff_port_ops,
  71         .sff_data_xfer          = ata_sff_data_xfer32,
  72 };
  73 
  74 /* ------------------------------------------------------------------------ */
  75 
  76 static struct scsi_host_template rb532_pata_sht = {
  77         ATA_PIO_SHT(DRV_NAME),
  78 };
  79 
  80 /* ------------------------------------------------------------------------ */
  81 
  82 static void rb532_pata_setup_ports(struct ata_host *ah)
  83 {
  84         struct rb532_cf_info *info = ah->private_data;
  85         struct ata_port *ap;
  86 
  87         ap = ah->ports[0];
  88 
  89         ap->ops         = &rb532_pata_port_ops;
  90         ap->pio_mask    = ATA_PIO4;
  91 
  92         ap->ioaddr.cmd_addr     = info->iobase + RB500_CF_REG_BASE;
  93         ap->ioaddr.ctl_addr     = info->iobase + RB500_CF_REG_CTRL;
  94         ap->ioaddr.altstatus_addr = info->iobase + RB500_CF_REG_CTRL;
  95 
  96         ata_sff_std_ports(&ap->ioaddr);
  97 
  98         ap->ioaddr.data_addr    = info->iobase + RB500_CF_REG_DBUF32;
  99         ap->ioaddr.error_addr   = info->iobase + RB500_CF_REG_ERR;
 100 }
 101 
 102 static int rb532_pata_driver_probe(struct platform_device *pdev)
 103 {
 104         int irq;
 105         struct gpio_desc *gpiod;
 106         struct resource *res;
 107         struct ata_host *ah;
 108         struct rb532_cf_info *info;
 109         int ret;
 110 
 111         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 112         if (!res) {
 113                 dev_err(&pdev->dev, "no IOMEM resource found\n");
 114                 return -EINVAL;
 115         }
 116 
 117         irq = platform_get_irq(pdev, 0);
 118         if (irq <= 0) {
 119                 dev_err(&pdev->dev, "no IRQ resource found\n");
 120                 return -ENOENT;
 121         }
 122 
 123         gpiod = devm_gpiod_get(&pdev->dev, NULL, GPIOD_IN);
 124         if (IS_ERR(gpiod)) {
 125                 dev_err(&pdev->dev, "no GPIO found for irq%d\n", irq);
 126                 return PTR_ERR(gpiod);
 127         }
 128         gpiod_set_consumer_name(gpiod, DRV_NAME);
 129 
 130         /* allocate host */
 131         ah = ata_host_alloc(&pdev->dev, RB500_CF_MAXPORTS);
 132         if (!ah)
 133                 return -ENOMEM;
 134 
 135         info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
 136         if (!info)
 137                 return -ENOMEM;
 138 
 139         ah->private_data = info;
 140         info->gpio_line = gpiod;
 141         info->irq = irq;
 142 
 143         info->iobase = devm_ioremap_nocache(&pdev->dev, res->start,
 144                                 resource_size(res));
 145         if (!info->iobase)
 146                 return -ENOMEM;
 147 
 148         rb532_pata_setup_ports(ah);
 149 
 150         ret = ata_host_activate(ah, irq, rb532_pata_irq_handler,
 151                                 IRQF_TRIGGER_LOW, &rb532_pata_sht);
 152         if (ret)
 153                 return ret;
 154 
 155         return 0;
 156 }
 157 
 158 static int rb532_pata_driver_remove(struct platform_device *pdev)
 159 {
 160         struct ata_host *ah = platform_get_drvdata(pdev);
 161 
 162         ata_host_detach(ah);
 163 
 164         return 0;
 165 }
 166 
 167 static struct platform_driver rb532_pata_platform_driver = {
 168         .probe          = rb532_pata_driver_probe,
 169         .remove         = rb532_pata_driver_remove,
 170         .driver  = {
 171                 .name   = DRV_NAME,
 172         },
 173 };
 174 
 175 #define DRV_INFO DRV_DESC " version " DRV_VERSION
 176 
 177 module_platform_driver(rb532_pata_platform_driver);
 178 
 179 MODULE_AUTHOR("Gabor Juhos <juhosg at openwrt.org>");
 180 MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
 181 MODULE_DESCRIPTION(DRV_DESC);
 182 MODULE_VERSION(DRV_VERSION);
 183 MODULE_LICENSE("GPL");
 184 MODULE_ALIAS("platform:" DRV_NAME);

/* [<][>][^][v][top][bottom][index][help] */