[PATCH] Add {css,ccw}_bus_type probe, remove, shutdown methods.
The following patch converts css_bus_type and ccw_bus_type to use the new bus_type methods. Signed-off-by: Cornelia Huck <huckc@de.ibm.com> CC: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Родитель
348290a4ae
Коммит
8bbace7e68
|
@ -542,9 +542,41 @@ css_bus_match (struct device *dev, struct device_driver *drv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
css_probe (struct device *dev)
|
||||||
|
{
|
||||||
|
struct subchannel *sch;
|
||||||
|
|
||||||
|
sch = to_subchannel(dev);
|
||||||
|
sch->driver = container_of (dev->driver, struct css_driver, drv);
|
||||||
|
return (sch->driver->probe ? sch->driver->probe(sch) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
css_remove (struct device *dev)
|
||||||
|
{
|
||||||
|
struct subchannel *sch;
|
||||||
|
|
||||||
|
sch = to_subchannel(dev);
|
||||||
|
return (sch->driver->remove ? sch->driver->remove(sch) : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
css_shutdown (struct device *dev)
|
||||||
|
{
|
||||||
|
struct subchannel *sch;
|
||||||
|
|
||||||
|
sch = to_subchannel(dev);
|
||||||
|
if (sch->driver->shutdown)
|
||||||
|
sch->driver->shutdown(sch);
|
||||||
|
}
|
||||||
|
|
||||||
struct bus_type css_bus_type = {
|
struct bus_type css_bus_type = {
|
||||||
.name = "css",
|
.name = "css",
|
||||||
.match = &css_bus_match,
|
.match = css_bus_match,
|
||||||
|
.probe = css_probe,
|
||||||
|
.remove = css_remove,
|
||||||
|
.shutdown = css_shutdown,
|
||||||
};
|
};
|
||||||
|
|
||||||
subsys_initcall(init_channel_subsystem);
|
subsys_initcall(init_channel_subsystem);
|
||||||
|
|
|
@ -115,6 +115,7 @@ struct ccw_device_private {
|
||||||
* Currently, we only care about I/O subchannels (type 0), these
|
* Currently, we only care about I/O subchannels (type 0), these
|
||||||
* have a ccw_device connected to them.
|
* have a ccw_device connected to them.
|
||||||
*/
|
*/
|
||||||
|
struct subchannel;
|
||||||
struct css_driver {
|
struct css_driver {
|
||||||
unsigned int subchannel_type;
|
unsigned int subchannel_type;
|
||||||
struct device_driver drv;
|
struct device_driver drv;
|
||||||
|
@ -122,6 +123,9 @@ struct css_driver {
|
||||||
int (*notify)(struct device *, int);
|
int (*notify)(struct device *, int);
|
||||||
void (*verify)(struct device *);
|
void (*verify)(struct device *);
|
||||||
void (*termination)(struct device *);
|
void (*termination)(struct device *);
|
||||||
|
int (*probe)(struct subchannel *);
|
||||||
|
int (*remove)(struct subchannel *);
|
||||||
|
void (*shutdown)(struct subchannel *);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -107,33 +107,29 @@ ccw_uevent (struct device *dev, char **envp, int num_envp,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct bus_type ccw_bus_type = {
|
struct bus_type ccw_bus_type;
|
||||||
.name = "ccw",
|
|
||||||
.match = &ccw_bus_match,
|
|
||||||
.uevent = &ccw_uevent,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int io_subchannel_probe (struct device *);
|
static int io_subchannel_probe (struct subchannel *);
|
||||||
static int io_subchannel_remove (struct device *);
|
static int io_subchannel_remove (struct subchannel *);
|
||||||
void io_subchannel_irq (struct device *);
|
void io_subchannel_irq (struct device *);
|
||||||
static int io_subchannel_notify(struct device *, int);
|
static int io_subchannel_notify(struct device *, int);
|
||||||
static void io_subchannel_verify(struct device *);
|
static void io_subchannel_verify(struct device *);
|
||||||
static void io_subchannel_ioterm(struct device *);
|
static void io_subchannel_ioterm(struct device *);
|
||||||
static void io_subchannel_shutdown(struct device *);
|
static void io_subchannel_shutdown(struct subchannel *);
|
||||||
|
|
||||||
struct css_driver io_subchannel_driver = {
|
struct css_driver io_subchannel_driver = {
|
||||||
.subchannel_type = SUBCHANNEL_TYPE_IO,
|
.subchannel_type = SUBCHANNEL_TYPE_IO,
|
||||||
.drv = {
|
.drv = {
|
||||||
.name = "io_subchannel",
|
.name = "io_subchannel",
|
||||||
.bus = &css_bus_type,
|
.bus = &css_bus_type,
|
||||||
.probe = &io_subchannel_probe,
|
|
||||||
.remove = &io_subchannel_remove,
|
|
||||||
.shutdown = &io_subchannel_shutdown,
|
|
||||||
},
|
},
|
||||||
.irq = io_subchannel_irq,
|
.irq = io_subchannel_irq,
|
||||||
.notify = io_subchannel_notify,
|
.notify = io_subchannel_notify,
|
||||||
.verify = io_subchannel_verify,
|
.verify = io_subchannel_verify,
|
||||||
.termination = io_subchannel_ioterm,
|
.termination = io_subchannel_ioterm,
|
||||||
|
.probe = io_subchannel_probe,
|
||||||
|
.remove = io_subchannel_remove,
|
||||||
|
.shutdown = io_subchannel_shutdown,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct workqueue_struct *ccw_device_work;
|
struct workqueue_struct *ccw_device_work;
|
||||||
|
@ -803,14 +799,12 @@ io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
io_subchannel_probe (struct device *pdev)
|
io_subchannel_probe (struct subchannel *sch)
|
||||||
{
|
{
|
||||||
struct subchannel *sch;
|
|
||||||
struct ccw_device *cdev;
|
struct ccw_device *cdev;
|
||||||
int rc;
|
int rc;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
sch = to_subchannel(pdev);
|
|
||||||
if (sch->dev.driver_data) {
|
if (sch->dev.driver_data) {
|
||||||
/*
|
/*
|
||||||
* This subchannel already has an associated ccw_device.
|
* This subchannel already has an associated ccw_device.
|
||||||
|
@ -846,7 +840,7 @@ io_subchannel_probe (struct device *pdev)
|
||||||
memset(cdev->private, 0, sizeof(struct ccw_device_private));
|
memset(cdev->private, 0, sizeof(struct ccw_device_private));
|
||||||
atomic_set(&cdev->private->onoff, 0);
|
atomic_set(&cdev->private->onoff, 0);
|
||||||
cdev->dev = (struct device) {
|
cdev->dev = (struct device) {
|
||||||
.parent = pdev,
|
.parent = &sch->dev,
|
||||||
.release = ccw_device_release,
|
.release = ccw_device_release,
|
||||||
};
|
};
|
||||||
INIT_LIST_HEAD(&cdev->private->kick_work.entry);
|
INIT_LIST_HEAD(&cdev->private->kick_work.entry);
|
||||||
|
@ -859,7 +853,7 @@ io_subchannel_probe (struct device *pdev)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = io_subchannel_recog(cdev, to_subchannel(pdev));
|
rc = io_subchannel_recog(cdev, sch);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
spin_lock_irqsave(&sch->lock, flags);
|
spin_lock_irqsave(&sch->lock, flags);
|
||||||
sch->dev.driver_data = NULL;
|
sch->dev.driver_data = NULL;
|
||||||
|
@ -883,17 +877,17 @@ ccw_device_unregister(void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
io_subchannel_remove (struct device *dev)
|
io_subchannel_remove (struct subchannel *sch)
|
||||||
{
|
{
|
||||||
struct ccw_device *cdev;
|
struct ccw_device *cdev;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (!dev->driver_data)
|
if (!sch->dev.driver_data)
|
||||||
return 0;
|
return 0;
|
||||||
cdev = dev->driver_data;
|
cdev = sch->dev.driver_data;
|
||||||
/* Set ccw device to not operational and drop reference. */
|
/* Set ccw device to not operational and drop reference. */
|
||||||
spin_lock_irqsave(cdev->ccwlock, flags);
|
spin_lock_irqsave(cdev->ccwlock, flags);
|
||||||
dev->driver_data = NULL;
|
sch->dev.driver_data = NULL;
|
||||||
cdev->private->state = DEV_STATE_NOT_OPER;
|
cdev->private->state = DEV_STATE_NOT_OPER;
|
||||||
spin_unlock_irqrestore(cdev->ccwlock, flags);
|
spin_unlock_irqrestore(cdev->ccwlock, flags);
|
||||||
/*
|
/*
|
||||||
|
@ -948,14 +942,12 @@ io_subchannel_ioterm(struct device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
io_subchannel_shutdown(struct device *dev)
|
io_subchannel_shutdown(struct subchannel *sch)
|
||||||
{
|
{
|
||||||
struct subchannel *sch;
|
|
||||||
struct ccw_device *cdev;
|
struct ccw_device *cdev;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
sch = to_subchannel(dev);
|
cdev = sch->dev.driver_data;
|
||||||
cdev = dev->driver_data;
|
|
||||||
|
|
||||||
if (cio_is_console(sch->schid))
|
if (cio_is_console(sch->schid))
|
||||||
return;
|
return;
|
||||||
|
@ -1129,6 +1121,14 @@ ccw_device_remove (struct device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct bus_type ccw_bus_type = {
|
||||||
|
.name = "ccw",
|
||||||
|
.match = ccw_bus_match,
|
||||||
|
.uevent = ccw_uevent,
|
||||||
|
.probe = ccw_device_probe,
|
||||||
|
.remove = ccw_device_remove,
|
||||||
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
ccw_driver_register (struct ccw_driver *cdriver)
|
ccw_driver_register (struct ccw_driver *cdriver)
|
||||||
{
|
{
|
||||||
|
@ -1136,8 +1136,6 @@ ccw_driver_register (struct ccw_driver *cdriver)
|
||||||
|
|
||||||
drv->bus = &ccw_bus_type;
|
drv->bus = &ccw_bus_type;
|
||||||
drv->name = cdriver->name;
|
drv->name = cdriver->name;
|
||||||
drv->probe = ccw_device_probe;
|
|
||||||
drv->remove = ccw_device_remove;
|
|
||||||
|
|
||||||
return driver_register(drv);
|
return driver_register(drv);
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче