Commit 12ce6b0d authored by Max Staudt's avatar Max Staudt Committed by Jens Axboe
Browse files

ata/pata_buddha: Probe via modalias instead of initcall



Up until now, the pata_buddha driver would only check for cards on
initcall time. Now, the kernel will call its probe function as soon
as a compatible card is detected.

v7: Removed suppress_bind_attrs that slipped in

v6: Only do the drvdata workaround for X-Surf (remove breaks otherwise)
    Style

v5: Remove module_exit(): There's no good way to handle the X-Surf hack.
    Also include a workaround to save X-Surf's drvdata in case zorro8390
    is active.

v4: Clean up pata_buddha_probe() by using ent->driver_data.
    Support X-Surf via late_initcall()

v3: Clean up devm_*, implement device removal.

v2: Rename 'zdev' to 'z' to make the patch easy to analyse with
    git diff --ignore-space-change

Signed-off-by: default avatarMax Staudt <max@enpas.org>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent e21a712a
Loading
Loading
Loading
Loading
+135 −93
Original line number Diff line number Diff line
@@ -18,7 +18,9 @@
#include <linux/kernel.h>
#include <linux/libata.h>
#include <linux/mm.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/zorro.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_host.h>
@@ -29,7 +31,7 @@
#include <asm/setup.h>

#define DRV_NAME "pata_buddha"
#define DRV_VERSION "0.1.0"
#define DRV_VERSION "0.1.1"

#define BUDDHA_BASE1	0x800
#define BUDDHA_BASE2	0xa00
@@ -47,11 +49,11 @@ enum {
	BOARD_XSURF
};

static unsigned int buddha_bases[3] __initdata = {
static unsigned int buddha_bases[3] = {
	BUDDHA_BASE1, BUDDHA_BASE2, BUDDHA_BASE3
};

static unsigned int xsurf_bases[2] __initdata = {
static unsigned int xsurf_bases[2] = {
	XSURF_BASE1, XSURF_BASE2
};

@@ -145,29 +147,20 @@ static struct ata_port_operations pata_xsurf_ops = {
	.set_mode	= pata_buddha_set_mode,
};

static int __init pata_buddha_init_one(void)
static int pata_buddha_probe(struct zorro_dev *z,
			     const struct zorro_device_id *ent)
{
	struct zorro_dev *z = NULL;

	while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
		static const char *board_name[]
			= { "Buddha", "Catweasel", "X-Surf" };
	static const char * const board_name[] = {
		"Buddha", "Catweasel", "X-Surf"
	};
	struct ata_host *host;
	void __iomem *buddha_board;
	unsigned long board;
		unsigned int type, nr_ports = 2;
	unsigned int type = ent->driver_data;
	unsigned int nr_ports = (type == BOARD_CATWEASEL) ? 3 : 2;
	void *old_drvdata;
	int i;

		if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) {
			type = BOARD_BUDDHA;
		} else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL) {
			type = BOARD_CATWEASEL;
			nr_ports++;
		} else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF) {
			type = BOARD_XSURF;
		} else
			continue;

	dev_info(&z->dev, "%s IDE controller\n", board_name[type]);

	board = z->resource.start;
@@ -176,22 +169,28 @@ static int __init pata_buddha_init_one(void)
		if (!devm_request_mem_region(&z->dev,
					     board + BUDDHA_BASE1,
					     0x800, DRV_NAME))
				continue;
			return -ENXIO;
	} else {
		if (!devm_request_mem_region(&z->dev,
					     board + XSURF_BASE1,
					     0x1000, DRV_NAME))
				continue;
			return -ENXIO;
		if (!devm_request_mem_region(&z->dev,
					     board + XSURF_BASE2,
						     0x1000, DRV_NAME))
				continue;
					     0x1000, DRV_NAME)) {
		}
	}

	/* Workaround for X-Surf: Save drvdata in case zorro8390 has set it */
	if (type == BOARD_XSURF)
		old_drvdata = dev_get_drvdata(&z->dev);

	/* allocate host */
	host = ata_host_alloc(&z->dev, nr_ports);
	if (type == BOARD_XSURF)
		dev_set_drvdata(&z->dev, old_drvdata);
	if (!host)
			continue;
		return -ENXIO;

	buddha_board = ZTWO_VADDR(board);

@@ -244,12 +243,55 @@ static int __init pata_buddha_init_one(void)
	ata_host_activate(host, IRQ_AMIGA_PORTS, ata_sff_interrupt,
			  IRQF_SHARED, &pata_buddha_sht);

	return 0;
}

	return 0;
static void pata_buddha_remove(struct zorro_dev *z)
{
	struct ata_host *host = dev_get_drvdata(&z->dev);

	ata_host_detach(host);
}

module_init(pata_buddha_init_one);
static const struct zorro_device_id pata_buddha_zorro_tbl[] = {
	{ ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA, BOARD_BUDDHA},
	{ ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL, BOARD_CATWEASEL},
	{ 0 }
};
MODULE_DEVICE_TABLE(zorro, pata_buddha_zorro_tbl);

static struct zorro_driver pata_buddha_driver = {
	.name           = "pata_buddha",
	.id_table       = pata_buddha_zorro_tbl,
	.probe          = pata_buddha_probe,
	.remove         = pata_buddha_remove,
};

/*
 * We cannot have a modalias for X-Surf boards, as it competes with the
 * zorro8390 network driver. As a stopgap measure until we have proper
 * MFD support for this board, we manually attach to it late after Zorro
 * has enumerated its boards.
 */
static int __init pata_buddha_late_init(void)
{
	struct zorro_dev *z = NULL;

	/* Auto-bind to regular boards */
	zorro_register_driver(&pata_buddha_driver);

	/* Manually bind to all X-Surf boards */
	while ((z = zorro_find_device(ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF, z))) {
		static struct zorro_device_id xsurf_ent = {
			ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF, BOARD_XSURF
		};

		pata_buddha_probe(z, &xsurf_ent);
	}

	return 0;
}
late_initcall(pata_buddha_late_init);

MODULE_AUTHOR("Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("low-level driver for Buddha/Catweasel/X-Surf PATA");