aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/cio/ccwgroup.c16
-rw-r--r--drivers/s390/cio/css.c36
-rw-r--r--drivers/s390/cio/css.h4
-rw-r--r--drivers/s390/cio/device.c50
4 files changed, 71 insertions, 35 deletions
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index e849289d4f3c..503a568e47c3 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -52,11 +52,7 @@ ccwgroup_uevent (struct device *dev, char **envp, int num_envp, char *buffer,
52 return 0; 52 return 0;
53} 53}
54 54
55static struct bus_type ccwgroup_bus_type = { 55static struct bus_type ccwgroup_bus_type;
56 .name = "ccwgroup",
57 .match = ccwgroup_bus_match,
58 .uevent = ccwgroup_uevent,
59};
60 56
61static inline void 57static inline void
62__ccwgroup_remove_symlinks(struct ccwgroup_device *gdev) 58__ccwgroup_remove_symlinks(struct ccwgroup_device *gdev)
@@ -389,6 +385,14 @@ ccwgroup_remove (struct device *dev)
389 return 0; 385 return 0;
390} 386}
391 387
388static struct bus_type ccwgroup_bus_type = {
389 .name = "ccwgroup",
390 .match = ccwgroup_bus_match,
391 .uevent = ccwgroup_uevent,
392 .probe = ccwgroup_probe,
393 .remove = ccwgroup_remove,
394};
395
392int 396int
393ccwgroup_driver_register (struct ccwgroup_driver *cdriver) 397ccwgroup_driver_register (struct ccwgroup_driver *cdriver)
394{ 398{
@@ -396,8 +400,6 @@ ccwgroup_driver_register (struct ccwgroup_driver *cdriver)
396 cdriver->driver = (struct device_driver) { 400 cdriver->driver = (struct device_driver) {
397 .bus = &ccwgroup_bus_type, 401 .bus = &ccwgroup_bus_type,
398 .name = cdriver->name, 402 .name = cdriver->name,
399 .probe = ccwgroup_probe,
400 .remove = ccwgroup_remove,
401 }; 403 };
402 404
403 return driver_register(&cdriver->driver); 405 return driver_register(&cdriver->driver);
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index e565193650c7..2d319fb812ca 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -542,9 +542,41 @@ css_bus_match (struct device *dev, struct device_driver *drv)
542 return 0; 542 return 0;
543} 543}
544 544
545static int
546css_probe (struct device *dev)
547{
548 struct subchannel *sch;
549
550 sch = to_subchannel(dev);
551 sch->driver = container_of (dev->driver, struct css_driver, drv);
552 return (sch->driver->probe ? sch->driver->probe(sch) : 0);
553}
554
555static int
556css_remove (struct device *dev)
557{
558 struct subchannel *sch;
559
560 sch = to_subchannel(dev);
561 return (sch->driver->remove ? sch->driver->remove(sch) : 0);
562}
563
564static void
565css_shutdown (struct device *dev)
566{
567 struct subchannel *sch;
568
569 sch = to_subchannel(dev);
570 if (sch->driver->shutdown)
571 sch->driver->shutdown(sch);
572}
573
545struct bus_type css_bus_type = { 574struct bus_type css_bus_type = {
546 .name = "css", 575 .name = "css",
547 .match = &css_bus_match, 576 .match = css_bus_match,
577 .probe = css_probe,
578 .remove = css_remove,
579 .shutdown = css_shutdown,
548}; 580};
549 581
550subsys_initcall(init_channel_subsystem); 582subsys_initcall(init_channel_subsystem);
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 251ebd7a7d3a..aa5ab5d4547c 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -115,6 +115,7 @@ struct ccw_device_private {
115 * Currently, we only care about I/O subchannels (type 0), these 115 * Currently, we only care about I/O subchannels (type 0), these
116 * have a ccw_device connected to them. 116 * have a ccw_device connected to them.
117 */ 117 */
118struct subchannel;
118struct css_driver { 119struct css_driver {
119 unsigned int subchannel_type; 120 unsigned int subchannel_type;
120 struct device_driver drv; 121 struct device_driver drv;
@@ -122,6 +123,9 @@ struct css_driver {
122 int (*notify)(struct device *, int); 123 int (*notify)(struct device *, int);
123 void (*verify)(struct device *); 124 void (*verify)(struct device *);
124 void (*termination)(struct device *); 125 void (*termination)(struct device *);
126 int (*probe)(struct subchannel *);
127 int (*remove)(struct subchannel *);
128 void (*shutdown)(struct subchannel *);
125}; 129};
126 130
127/* 131/*
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index fa3e4c0a2536..eb73605a0527 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -107,33 +107,29 @@ ccw_uevent (struct device *dev, char **envp, int num_envp,
107 return 0; 107 return 0;
108} 108}
109 109
110struct bus_type ccw_bus_type = { 110struct bus_type ccw_bus_type;
111 .name = "ccw",
112 .match = &ccw_bus_match,
113 .uevent = &ccw_uevent,
114};
115 111
116static int io_subchannel_probe (struct device *); 112static int io_subchannel_probe (struct subchannel *);
117static int io_subchannel_remove (struct device *); 113static int io_subchannel_remove (struct subchannel *);
118void io_subchannel_irq (struct device *); 114void io_subchannel_irq (struct device *);
119static int io_subchannel_notify(struct device *, int); 115static int io_subchannel_notify(struct device *, int);
120static void io_subchannel_verify(struct device *); 116static void io_subchannel_verify(struct device *);
121static void io_subchannel_ioterm(struct device *); 117static void io_subchannel_ioterm(struct device *);
122static void io_subchannel_shutdown(struct device *); 118static void io_subchannel_shutdown(struct subchannel *);
123 119
124struct css_driver io_subchannel_driver = { 120struct css_driver io_subchannel_driver = {
125 .subchannel_type = SUBCHANNEL_TYPE_IO, 121 .subchannel_type = SUBCHANNEL_TYPE_IO,
126 .drv = { 122 .drv = {
127 .name = "io_subchannel", 123 .name = "io_subchannel",
128 .bus = &css_bus_type, 124 .bus = &css_bus_type,
129 .probe = &io_subchannel_probe,
130 .remove = &io_subchannel_remove,
131 .shutdown = &io_subchannel_shutdown,
132 }, 125 },
133 .irq = io_subchannel_irq, 126 .irq = io_subchannel_irq,
134 .notify = io_subchannel_notify, 127 .notify = io_subchannel_notify,
135 .verify = io_subchannel_verify, 128 .verify = io_subchannel_verify,
136 .termination = io_subchannel_ioterm, 129 .termination = io_subchannel_ioterm,
130 .probe = io_subchannel_probe,
131 .remove = io_subchannel_remove,
132 .shutdown = io_subchannel_shutdown,
137}; 133};
138 134
139struct workqueue_struct *ccw_device_work; 135struct workqueue_struct *ccw_device_work;
@@ -803,14 +799,12 @@ io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch)
803} 799}
804 800
805static int 801static int
806io_subchannel_probe (struct device *pdev) 802io_subchannel_probe (struct subchannel *sch)
807{ 803{
808 struct subchannel *sch;
809 struct ccw_device *cdev; 804 struct ccw_device *cdev;
810 int rc; 805 int rc;
811 unsigned long flags; 806 unsigned long flags;
812 807
813 sch = to_subchannel(pdev);
814 if (sch->dev.driver_data) { 808 if (sch->dev.driver_data) {
815 /* 809 /*
816 * This subchannel already has an associated ccw_device. 810 * This subchannel already has an associated ccw_device.
@@ -846,7 +840,7 @@ io_subchannel_probe (struct device *pdev)
846 memset(cdev->private, 0, sizeof(struct ccw_device_private)); 840 memset(cdev->private, 0, sizeof(struct ccw_device_private));
847 atomic_set(&cdev->private->onoff, 0); 841 atomic_set(&cdev->private->onoff, 0);
848 cdev->dev = (struct device) { 842 cdev->dev = (struct device) {
849 .parent = pdev, 843 .parent = &sch->dev,
850 .release = ccw_device_release, 844 .release = ccw_device_release,
851 }; 845 };
852 INIT_LIST_HEAD(&cdev->private->kick_work.entry); 846 INIT_LIST_HEAD(&cdev->private->kick_work.entry);
@@ -859,7 +853,7 @@ io_subchannel_probe (struct device *pdev)
859 return -ENODEV; 853 return -ENODEV;
860 } 854 }
861 855
862 rc = io_subchannel_recog(cdev, to_subchannel(pdev)); 856 rc = io_subchannel_recog(cdev, sch);
863 if (rc) { 857 if (rc) {
864 spin_lock_irqsave(&sch->lock, flags); 858 spin_lock_irqsave(&sch->lock, flags);
865 sch->dev.driver_data = NULL; 859 sch->dev.driver_data = NULL;
@@ -883,17 +877,17 @@ ccw_device_unregister(void *data)
883} 877}
884 878
885static int 879static int
886io_subchannel_remove (struct device *dev) 880io_subchannel_remove (struct subchannel *sch)
887{ 881{
888 struct ccw_device *cdev; 882 struct ccw_device *cdev;
889 unsigned long flags; 883 unsigned long flags;
890 884
891 if (!dev->driver_data) 885 if (!sch->dev.driver_data)
892 return 0; 886 return 0;
893 cdev = dev->driver_data; 887 cdev = sch->dev.driver_data;
894 /* Set ccw device to not operational and drop reference. */ 888 /* Set ccw device to not operational and drop reference. */
895 spin_lock_irqsave(cdev->ccwlock, flags); 889 spin_lock_irqsave(cdev->ccwlock, flags);
896 dev->driver_data = NULL; 890 sch->dev.driver_data = NULL;
897 cdev->private->state = DEV_STATE_NOT_OPER; 891 cdev->private->state = DEV_STATE_NOT_OPER;
898 spin_unlock_irqrestore(cdev->ccwlock, flags); 892 spin_unlock_irqrestore(cdev->ccwlock, flags);
899 /* 893 /*
@@ -948,14 +942,12 @@ io_subchannel_ioterm(struct device *dev)
948} 942}
949 943
950static void 944static void
951io_subchannel_shutdown(struct device *dev) 945io_subchannel_shutdown(struct subchannel *sch)
952{ 946{
953 struct subchannel *sch;
954 struct ccw_device *cdev; 947 struct ccw_device *cdev;
955 int ret; 948 int ret;
956 949
957 sch = to_subchannel(dev); 950 cdev = sch->dev.driver_data;
958 cdev = dev->driver_data;
959 951
960 if (cio_is_console(sch->schid)) 952 if (cio_is_console(sch->schid))
961 return; 953 return;
@@ -1129,6 +1121,14 @@ ccw_device_remove (struct device *dev)
1129 return 0; 1121 return 0;
1130} 1122}
1131 1123
1124struct bus_type ccw_bus_type = {
1125 .name = "ccw",
1126 .match = ccw_bus_match,
1127 .uevent = ccw_uevent,
1128 .probe = ccw_device_probe,
1129 .remove = ccw_device_remove,
1130};
1131
1132int 1132int
1133ccw_driver_register (struct ccw_driver *cdriver) 1133ccw_driver_register (struct ccw_driver *cdriver)
1134{ 1134{
@@ -1136,8 +1136,6 @@ ccw_driver_register (struct ccw_driver *cdriver)
1136 1136
1137 drv->bus = &ccw_bus_type; 1137 drv->bus = &ccw_bus_type;
1138 drv->name = cdriver->name; 1138 drv->name = cdriver->name;
1139 drv->probe = ccw_device_probe;
1140 drv->remove = ccw_device_remove;
1141 1139
1142 return driver_register(drv); 1140 return driver_register(drv);
1143} 1141}