drivers/ata/pata_rb532_cf.c

Source file repositories/reference/linux-study-clean/drivers/ata/pata_rb532_cf.c

File Facts

System
Linux kernel
Corpus path
drivers/ata/pata_rb532_cf.c
Extension
.c
Size
4621 bytes
Lines
183
Domain
Driver Families
Bucket
drivers/ata
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct rb532_cf_info {
	void __iomem	*iobase;
	struct gpio_desc *gpio_line;
	unsigned int	irq;
};

/* ------------------------------------------------------------------------ */

static irqreturn_t rb532_pata_irq_handler(int irq, void *dev_instance)
{
	struct ata_host *ah = dev_instance;
	struct rb532_cf_info *info = ah->private_data;

	if (gpiod_get_value(info->gpio_line)) {
		irq_set_irq_type(info->irq, IRQ_TYPE_LEVEL_LOW);
		ata_sff_interrupt(info->irq, dev_instance);
	} else {
		irq_set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH);
	}

	return IRQ_HANDLED;
}

static struct ata_port_operations rb532_pata_port_ops = {
	.inherits		= &ata_sff_port_ops,
	.sff_data_xfer		= ata_sff_data_xfer32,
};

/* ------------------------------------------------------------------------ */

static const struct scsi_host_template rb532_pata_sht = {
	ATA_PIO_SHT(DRV_NAME),
};

/* ------------------------------------------------------------------------ */

static void rb532_pata_setup_ports(struct ata_host *ah)
{
	struct rb532_cf_info *info = ah->private_data;
	struct ata_port *ap;

	ap = ah->ports[0];

	ap->ops		= &rb532_pata_port_ops;
	ap->pio_mask	= ATA_PIO4;

	ap->ioaddr.cmd_addr	= info->iobase + RB500_CF_REG_BASE;
	ap->ioaddr.ctl_addr	= info->iobase + RB500_CF_REG_CTRL;
	ap->ioaddr.altstatus_addr = info->iobase + RB500_CF_REG_CTRL;

	ata_sff_std_ports(&ap->ioaddr);

	ap->ioaddr.data_addr	= info->iobase + RB500_CF_REG_DBUF32;
	ap->ioaddr.error_addr	= info->iobase + RB500_CF_REG_ERR;
}

static int rb532_pata_driver_probe(struct platform_device *pdev)
{
	int irq;
	struct gpio_desc *gpiod;
	struct resource *res;
	struct ata_host *ah;
	struct rb532_cf_info *info;
	int ret;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "no IOMEM resource found\n");
		return -EINVAL;
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;
	if (!irq)
		return -EINVAL;

	gpiod = devm_gpiod_get(&pdev->dev, NULL, GPIOD_IN);
	if (IS_ERR(gpiod)) {
		dev_err(&pdev->dev, "no GPIO found for irq%d\n", irq);
		return PTR_ERR(gpiod);
	}
	gpiod_set_consumer_name(gpiod, DRV_NAME);

	/* allocate host */
	ah = ata_host_alloc(&pdev->dev, RB500_CF_MAXPORTS);
	if (!ah)
		return -ENOMEM;

	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);

Annotation

Implementation Notes