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

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
...@@ -18,7 +18,9 @@ ...@@ -18,7 +18,9 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/libata.h> #include <linux/libata.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/types.h>
#include <linux/zorro.h> #include <linux/zorro.h>
#include <scsi/scsi_cmnd.h> #include <scsi/scsi_cmnd.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
...@@ -29,7 +31,7 @@ ...@@ -29,7 +31,7 @@
#include <asm/setup.h> #include <asm/setup.h>
#define DRV_NAME "pata_buddha" #define DRV_NAME "pata_buddha"
#define DRV_VERSION "0.1.0" #define DRV_VERSION "0.1.1"
#define BUDDHA_BASE1 0x800 #define BUDDHA_BASE1 0x800
#define BUDDHA_BASE2 0xa00 #define BUDDHA_BASE2 0xa00
...@@ -47,11 +49,11 @@ enum { ...@@ -47,11 +49,11 @@ enum {
BOARD_XSURF BOARD_XSURF
}; };
static unsigned int buddha_bases[3] __initdata = { static unsigned int buddha_bases[3] = {
BUDDHA_BASE1, BUDDHA_BASE2, BUDDHA_BASE3 BUDDHA_BASE1, BUDDHA_BASE2, BUDDHA_BASE3
}; };
static unsigned int xsurf_bases[2] __initdata = { static unsigned int xsurf_bases[2] = {
XSURF_BASE1, XSURF_BASE2 XSURF_BASE1, XSURF_BASE2
}; };
...@@ -145,29 +147,20 @@ static struct ata_port_operations pata_xsurf_ops = { ...@@ -145,29 +147,20 @@ static struct ata_port_operations pata_xsurf_ops = {
.set_mode = pata_buddha_set_mode, .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; static const char * const board_name[] = {
"Buddha", "Catweasel", "X-Surf"
while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { };
static const char *board_name[]
= { "Buddha", "Catweasel", "X-Surf" };
struct ata_host *host; struct ata_host *host;
void __iomem *buddha_board; void __iomem *buddha_board;
unsigned long 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; 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]); dev_info(&z->dev, "%s IDE controller\n", board_name[type]);
board = z->resource.start; board = z->resource.start;
...@@ -176,22 +169,28 @@ static int __init pata_buddha_init_one(void) ...@@ -176,22 +169,28 @@ static int __init pata_buddha_init_one(void)
if (!devm_request_mem_region(&z->dev, if (!devm_request_mem_region(&z->dev,
board + BUDDHA_BASE1, board + BUDDHA_BASE1,
0x800, DRV_NAME)) 0x800, DRV_NAME))
continue; return -ENXIO;
} else { } else {
if (!devm_request_mem_region(&z->dev, if (!devm_request_mem_region(&z->dev,
board + XSURF_BASE1, board + XSURF_BASE1,
0x1000, DRV_NAME)) 0x1000, DRV_NAME))
continue; return -ENXIO;
if (!devm_request_mem_region(&z->dev, if (!devm_request_mem_region(&z->dev,
board + XSURF_BASE2, board + XSURF_BASE2,
0x1000, DRV_NAME)) 0x1000, DRV_NAME)) {
continue;
} }
}
/* 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 */ /* allocate host */
host = ata_host_alloc(&z->dev, nr_ports); host = ata_host_alloc(&z->dev, nr_ports);
if (type == BOARD_XSURF)
dev_set_drvdata(&z->dev, old_drvdata);
if (!host) if (!host)
continue; return -ENXIO;
buddha_board = ZTWO_VADDR(board); buddha_board = ZTWO_VADDR(board);
...@@ -244,12 +243,55 @@ static int __init pata_buddha_init_one(void) ...@@ -244,12 +243,55 @@ static int __init pata_buddha_init_one(void)
ata_host_activate(host, IRQ_AMIGA_PORTS, ata_sff_interrupt, ata_host_activate(host, IRQ_AMIGA_PORTS, ata_sff_interrupt,
IRQF_SHARED, &pata_buddha_sht); IRQF_SHARED, &pata_buddha_sht);
return 0;
}
static void pata_buddha_remove(struct zorro_dev *z)
{
struct ata_host *host = dev_get_drvdata(&z->dev);
ata_host_detach(host);
}
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; return 0;
} }
late_initcall(pata_buddha_late_init);
module_init(pata_buddha_init_one);
MODULE_AUTHOR("Bartlomiej Zolnierkiewicz"); MODULE_AUTHOR("Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("low-level driver for Buddha/Catweasel/X-Surf PATA"); MODULE_DESCRIPTION("low-level driver for Buddha/Catweasel/X-Surf PATA");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment