aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-03 13:46:26 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-03 13:46:26 -0400
commit1ccfd5eaf8f0135a0ce030728d1739e0eea4e3ce (patch)
tree95ae125e755f694ad80866f1540e03576702319a /drivers/s390
parentea98af133f8dac1aa4ec093f69e1165a5db2d1ad (diff)
parent224593215525a79fe1acfffaafa528af9dc6f738 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull first batch of s390 updates from Martin Schwidefsky: "The most interesting change is that Martin converted s390 to generic hardirqs. Which means that all current architectures have been converted and that CONFIG_GENERIC_HARDIRQS can be removed. Martin prepared a patch for that already (see genirq branch), but the best time to merge that is probably at the end of the merge window / begin of -rc1. Another patch converts s390 to software referenced bits instead of relying on the reference bit in the storage key. Therefore s390 doesn't use storage keys anymore, except for kvm. Besides that we have improvements, cleanups and fixes in PCI, DASD and all over the place." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (32 commits) s390/pci: use virtual memory for iommu bitmap s390/cio: fix unlocked access of global bitmap s390/pci: update function handle after resume from hibernate s390/pci: try harder to modify a function s390/pci: split lpf s390/hibernate: add early resume function s390/pci: add recover sysfs knob s390/pci: use claim_resource s390/pci/hotplug: convert to be builtin only s390/mm: implement software referenced bits s390/dasd: fix statistics for recovered requests s390/tx: allow program interruption filtering in user space s390/pgtable: fix mprotect for single-threaded KVM guests s390/time: return with irqs disabled from psw_idle s390/kprobes: add support for compare and branch instructions s390/switch_to: fix save_access_regs() / restore_access_regs() s390/bitops: fix inline assembly constraints s390/dasd: enable raw_track_access reads without direct I/O s390/mm: introduce ptep_flush_lazy helper s390/time: clock comparator revalidation ...
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/block/dasd_devmap.c8
-rw-r--r--drivers/s390/block/dasd_eckd.c54
-rw-r--r--drivers/s390/block/dasd_erp.c14
-rw-r--r--drivers/s390/char/sclp_config.c2
-rw-r--r--drivers/s390/cio/airq.c174
-rw-r--r--drivers/s390/cio/ccwgroup.c2
-rw-r--r--drivers/s390/cio/cio.c46
-rw-r--r--drivers/s390/cio/cio.h3
-rw-r--r--drivers/s390/cio/cmf.c2
-rw-r--r--drivers/s390/cio/css.c4
-rw-r--r--drivers/s390/cio/css.h2
-rw-r--r--drivers/s390/cio/device.c2
-rw-r--r--drivers/s390/net/qeth_l3_sys.c2
13 files changed, 262 insertions, 53 deletions
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 58bc6eb49de1..2ead7e78c456 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -930,7 +930,7 @@ dasd_use_raw_store(struct device *dev, struct device_attribute *attr,
930 if (IS_ERR(devmap)) 930 if (IS_ERR(devmap))
931 return PTR_ERR(devmap); 931 return PTR_ERR(devmap);
932 932
933 if ((strict_strtoul(buf, 10, &val) != 0) || val > 1) 933 if ((kstrtoul(buf, 10, &val) != 0) || val > 1)
934 return -EINVAL; 934 return -EINVAL;
935 935
936 spin_lock(&dasd_devmap_lock); 936 spin_lock(&dasd_devmap_lock);
@@ -1225,7 +1225,7 @@ dasd_expires_store(struct device *dev, struct device_attribute *attr,
1225 if (IS_ERR(device)) 1225 if (IS_ERR(device))
1226 return -ENODEV; 1226 return -ENODEV;
1227 1227
1228 if ((strict_strtoul(buf, 10, &val) != 0) || 1228 if ((kstrtoul(buf, 10, &val) != 0) ||
1229 (val > DASD_EXPIRES_MAX) || val == 0) { 1229 (val > DASD_EXPIRES_MAX) || val == 0) {
1230 dasd_put_device(device); 1230 dasd_put_device(device);
1231 return -EINVAL; 1231 return -EINVAL;
@@ -1265,7 +1265,7 @@ dasd_retries_store(struct device *dev, struct device_attribute *attr,
1265 if (IS_ERR(device)) 1265 if (IS_ERR(device))
1266 return -ENODEV; 1266 return -ENODEV;
1267 1267
1268 if ((strict_strtoul(buf, 10, &val) != 0) || 1268 if ((kstrtoul(buf, 10, &val) != 0) ||
1269 (val > DASD_RETRIES_MAX)) { 1269 (val > DASD_RETRIES_MAX)) {
1270 dasd_put_device(device); 1270 dasd_put_device(device);
1271 return -EINVAL; 1271 return -EINVAL;
@@ -1307,7 +1307,7 @@ dasd_timeout_store(struct device *dev, struct device_attribute *attr,
1307 if (IS_ERR(device) || !device->block) 1307 if (IS_ERR(device) || !device->block)
1308 return -ENODEV; 1308 return -ENODEV;
1309 1309
1310 if ((strict_strtoul(buf, 10, &val) != 0) || 1310 if ((kstrtoul(buf, 10, &val) != 0) ||
1311 val > UINT_MAX / HZ) { 1311 val > UINT_MAX / HZ) {
1312 dasd_put_device(device); 1312 dasd_put_device(device);
1313 return -EINVAL; 1313 return -EINVAL;
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index e61a6deea3c0..5adb2042e824 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -85,6 +85,8 @@ MODULE_DEVICE_TABLE(ccw, dasd_eckd_ids);
85 85
86static struct ccw_driver dasd_eckd_driver; /* see below */ 86static struct ccw_driver dasd_eckd_driver; /* see below */
87 87
88static void *rawpadpage;
89
88#define INIT_CQR_OK 0 90#define INIT_CQR_OK 0
89#define INIT_CQR_UNFORMATTED 1 91#define INIT_CQR_UNFORMATTED 1
90#define INIT_CQR_ERROR 2 92#define INIT_CQR_ERROR 2
@@ -3237,18 +3239,26 @@ static struct dasd_ccw_req *dasd_raw_build_cp(struct dasd_device *startdev,
3237 unsigned int seg_len, len_to_track_end; 3239 unsigned int seg_len, len_to_track_end;
3238 unsigned int first_offs; 3240 unsigned int first_offs;
3239 unsigned int cidaw, cplength, datasize; 3241 unsigned int cidaw, cplength, datasize;
3240 sector_t first_trk, last_trk; 3242 sector_t first_trk, last_trk, sectors;
3243 sector_t start_padding_sectors, end_sector_offset, end_padding_sectors;
3241 unsigned int pfx_datasize; 3244 unsigned int pfx_datasize;
3242 3245
3243 /* 3246 /*
3244 * raw track access needs to be mutiple of 64k and on 64k boundary 3247 * raw track access needs to be mutiple of 64k and on 64k boundary
3248 * For read requests we can fix an incorrect alignment by padding
3249 * the request with dummy pages.
3245 */ 3250 */
3246 if ((blk_rq_pos(req) % DASD_RAW_SECTORS_PER_TRACK) != 0) { 3251 start_padding_sectors = blk_rq_pos(req) % DASD_RAW_SECTORS_PER_TRACK;
3247 cqr = ERR_PTR(-EINVAL); 3252 end_sector_offset = (blk_rq_pos(req) + blk_rq_sectors(req)) %
3248 goto out; 3253 DASD_RAW_SECTORS_PER_TRACK;
3249 } 3254 end_padding_sectors = (DASD_RAW_SECTORS_PER_TRACK - end_sector_offset) %
3250 if (((blk_rq_pos(req) + blk_rq_sectors(req)) % 3255 DASD_RAW_SECTORS_PER_TRACK;
3251 DASD_RAW_SECTORS_PER_TRACK) != 0) { 3256 basedev = block->base;
3257 if ((start_padding_sectors || end_padding_sectors) &&
3258 (rq_data_dir(req) == WRITE)) {
3259 DBF_DEV_EVENT(DBF_ERR, basedev,
3260 "raw write not track aligned (%lu,%lu) req %p",
3261 start_padding_sectors, end_padding_sectors, req);
3252 cqr = ERR_PTR(-EINVAL); 3262 cqr = ERR_PTR(-EINVAL);
3253 goto out; 3263 goto out;
3254 } 3264 }
@@ -3258,7 +3268,6 @@ static struct dasd_ccw_req *dasd_raw_build_cp(struct dasd_device *startdev,
3258 DASD_RAW_SECTORS_PER_TRACK; 3268 DASD_RAW_SECTORS_PER_TRACK;
3259 trkcount = last_trk - first_trk + 1; 3269 trkcount = last_trk - first_trk + 1;
3260 first_offs = 0; 3270 first_offs = 0;
3261 basedev = block->base;
3262 3271
3263 if (rq_data_dir(req) == READ) 3272 if (rq_data_dir(req) == READ)
3264 cmd = DASD_ECKD_CCW_READ_TRACK; 3273 cmd = DASD_ECKD_CCW_READ_TRACK;
@@ -3307,12 +3316,26 @@ static struct dasd_ccw_req *dasd_raw_build_cp(struct dasd_device *startdev,
3307 } 3316 }
3308 3317
3309 idaws = (unsigned long *)(cqr->data + pfx_datasize); 3318 idaws = (unsigned long *)(cqr->data + pfx_datasize);
3310
3311 len_to_track_end = 0; 3319 len_to_track_end = 0;
3312 3320 if (start_padding_sectors) {
3321 ccw[-1].flags |= CCW_FLAG_CC;
3322 ccw->cmd_code = cmd;
3323 /* maximum 3390 track size */
3324 ccw->count = 57326;
3325 /* 64k map to one track */
3326 len_to_track_end = 65536 - start_padding_sectors * 512;
3327 ccw->cda = (__u32)(addr_t)idaws;
3328 ccw->flags |= CCW_FLAG_IDA;
3329 ccw->flags |= CCW_FLAG_SLI;
3330 ccw++;
3331 for (sectors = 0; sectors < start_padding_sectors; sectors += 8)
3332 idaws = idal_create_words(idaws, rawpadpage, PAGE_SIZE);
3333 }
3313 rq_for_each_segment(bv, req, iter) { 3334 rq_for_each_segment(bv, req, iter) {
3314 dst = page_address(bv->bv_page) + bv->bv_offset; 3335 dst = page_address(bv->bv_page) + bv->bv_offset;
3315 seg_len = bv->bv_len; 3336 seg_len = bv->bv_len;
3337 if (cmd == DASD_ECKD_CCW_READ_TRACK)
3338 memset(dst, 0, seg_len);
3316 if (!len_to_track_end) { 3339 if (!len_to_track_end) {
3317 ccw[-1].flags |= CCW_FLAG_CC; 3340 ccw[-1].flags |= CCW_FLAG_CC;
3318 ccw->cmd_code = cmd; 3341 ccw->cmd_code = cmd;
@@ -3328,7 +3351,8 @@ static struct dasd_ccw_req *dasd_raw_build_cp(struct dasd_device *startdev,
3328 len_to_track_end -= seg_len; 3351 len_to_track_end -= seg_len;
3329 idaws = idal_create_words(idaws, dst, seg_len); 3352 idaws = idal_create_words(idaws, dst, seg_len);
3330 } 3353 }
3331 3354 for (sectors = 0; sectors < end_padding_sectors; sectors += 8)
3355 idaws = idal_create_words(idaws, rawpadpage, PAGE_SIZE);
3332 if (blk_noretry_request(req) || 3356 if (blk_noretry_request(req) ||
3333 block->base->features & DASD_FEATURE_FAILFAST) 3357 block->base->features & DASD_FEATURE_FAILFAST)
3334 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); 3358 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
@@ -4479,12 +4503,19 @@ dasd_eckd_init(void)
4479 kfree(dasd_reserve_req); 4503 kfree(dasd_reserve_req);
4480 return -ENOMEM; 4504 return -ENOMEM;
4481 } 4505 }
4506 rawpadpage = (void *)__get_free_page(GFP_KERNEL);
4507 if (!rawpadpage) {
4508 kfree(path_verification_worker);
4509 kfree(dasd_reserve_req);
4510 return -ENOMEM;
4511 }
4482 ret = ccw_driver_register(&dasd_eckd_driver); 4512 ret = ccw_driver_register(&dasd_eckd_driver);
4483 if (!ret) 4513 if (!ret)
4484 wait_for_device_probe(); 4514 wait_for_device_probe();
4485 else { 4515 else {
4486 kfree(path_verification_worker); 4516 kfree(path_verification_worker);
4487 kfree(dasd_reserve_req); 4517 kfree(dasd_reserve_req);
4518 free_page((unsigned long)rawpadpage);
4488 } 4519 }
4489 return ret; 4520 return ret;
4490} 4521}
@@ -4495,6 +4526,7 @@ dasd_eckd_cleanup(void)
4495 ccw_driver_unregister(&dasd_eckd_driver); 4526 ccw_driver_unregister(&dasd_eckd_driver);
4496 kfree(path_verification_worker); 4527 kfree(path_verification_worker);
4497 kfree(dasd_reserve_req); 4528 kfree(dasd_reserve_req);
4529 free_page((unsigned long)rawpadpage);
4498} 4530}
4499 4531
4500module_init(dasd_eckd_init); 4532module_init(dasd_eckd_init);
diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c
index 8d11f773a752..e1e88486b2b4 100644
--- a/drivers/s390/block/dasd_erp.c
+++ b/drivers/s390/block/dasd_erp.c
@@ -124,10 +124,15 @@ dasd_default_erp_action(struct dasd_ccw_req *cqr)
124struct dasd_ccw_req *dasd_default_erp_postaction(struct dasd_ccw_req *cqr) 124struct dasd_ccw_req *dasd_default_erp_postaction(struct dasd_ccw_req *cqr)
125{ 125{
126 int success; 126 int success;
127 unsigned long long startclk, stopclk;
128 struct dasd_device *startdev;
127 129
128 BUG_ON(cqr->refers == NULL || cqr->function == NULL); 130 BUG_ON(cqr->refers == NULL || cqr->function == NULL);
129 131
130 success = cqr->status == DASD_CQR_DONE; 132 success = cqr->status == DASD_CQR_DONE;
133 startclk = cqr->startclk;
134 stopclk = cqr->stopclk;
135 startdev = cqr->startdev;
131 136
132 /* free all ERPs - but NOT the original cqr */ 137 /* free all ERPs - but NOT the original cqr */
133 while (cqr->refers != NULL) { 138 while (cqr->refers != NULL) {
@@ -142,6 +147,9 @@ struct dasd_ccw_req *dasd_default_erp_postaction(struct dasd_ccw_req *cqr)
142 } 147 }
143 148
144 /* set corresponding status to original cqr */ 149 /* set corresponding status to original cqr */
150 cqr->startclk = startclk;
151 cqr->stopclk = stopclk;
152 cqr->startdev = startdev;
145 if (success) 153 if (success)
146 cqr->status = DASD_CQR_DONE; 154 cqr->status = DASD_CQR_DONE;
147 else { 155 else {
@@ -160,11 +168,13 @@ dasd_log_sense(struct dasd_ccw_req *cqr, struct irb *irb)
160 168
161 device = cqr->startdev; 169 device = cqr->startdev;
162 if (cqr->intrc == -ETIMEDOUT) { 170 if (cqr->intrc == -ETIMEDOUT) {
163 dev_err(&device->cdev->dev, "cqr %p timeout error", cqr); 171 dev_err(&device->cdev->dev,
172 "A timeout error occurred for cqr %p", cqr);
164 return; 173 return;
165 } 174 }
166 if (cqr->intrc == -ENOLINK) { 175 if (cqr->intrc == -ENOLINK) {
167 dev_err(&device->cdev->dev, "cqr %p transport error", cqr); 176 dev_err(&device->cdev->dev,
177 "A transport error occurred for cqr %p", cqr);
168 return; 178 return;
169 } 179 }
170 /* dump sense data */ 180 /* dump sense data */
diff --git a/drivers/s390/char/sclp_config.c b/drivers/s390/char/sclp_config.c
index 444d36183a25..944156207477 100644
--- a/drivers/s390/char/sclp_config.c
+++ b/drivers/s390/char/sclp_config.c
@@ -32,7 +32,7 @@ static void sclp_cpu_capability_notify(struct work_struct *work)
32 struct device *dev; 32 struct device *dev;
33 33
34 s390_adjust_jiffies(); 34 s390_adjust_jiffies();
35 pr_warning("cpu capability changed.\n"); 35 pr_info("CPU capability may have changed\n");
36 get_online_cpus(); 36 get_online_cpus();
37 for_each_online_cpu(cpu) { 37 for_each_online_cpu(cpu) {
38 dev = get_cpu_device(cpu); 38 dev = get_cpu_device(cpu);
diff --git a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c
index 91edbd7ee806..d028fd800c9c 100644
--- a/drivers/s390/cio/airq.c
+++ b/drivers/s390/cio/airq.c
@@ -81,15 +81,185 @@ void unregister_adapter_interrupt(struct airq_struct *airq)
81} 81}
82EXPORT_SYMBOL(unregister_adapter_interrupt); 82EXPORT_SYMBOL(unregister_adapter_interrupt);
83 83
84void do_adapter_IO(u8 isc) 84static irqreturn_t do_airq_interrupt(int irq, void *dummy)
85{ 85{
86 struct tpi_info *tpi_info;
86 struct airq_struct *airq; 87 struct airq_struct *airq;
87 struct hlist_head *head; 88 struct hlist_head *head;
88 89
89 head = &airq_lists[isc]; 90 __this_cpu_write(s390_idle.nohz_delay, 1);
91 tpi_info = (struct tpi_info *) &get_irq_regs()->int_code;
92 head = &airq_lists[tpi_info->isc];
90 rcu_read_lock(); 93 rcu_read_lock();
91 hlist_for_each_entry_rcu(airq, head, list) 94 hlist_for_each_entry_rcu(airq, head, list)
92 if ((*airq->lsi_ptr & airq->lsi_mask) != 0) 95 if ((*airq->lsi_ptr & airq->lsi_mask) != 0)
93 airq->handler(airq); 96 airq->handler(airq);
94 rcu_read_unlock(); 97 rcu_read_unlock();
98
99 return IRQ_HANDLED;
100}
101
102static struct irqaction airq_interrupt = {
103 .name = "AIO",
104 .handler = do_airq_interrupt,
105};
106
107void __init init_airq_interrupts(void)
108{
109 irq_set_chip_and_handler(THIN_INTERRUPT,
110 &dummy_irq_chip, handle_percpu_irq);
111 setup_irq(THIN_INTERRUPT, &airq_interrupt);
112}
113
114/**
115 * airq_iv_create - create an interrupt vector
116 * @bits: number of bits in the interrupt vector
117 * @flags: allocation flags
118 *
119 * Returns a pointer to an interrupt vector structure
120 */
121struct airq_iv *airq_iv_create(unsigned long bits, unsigned long flags)
122{
123 struct airq_iv *iv;
124 unsigned long size;
125
126 iv = kzalloc(sizeof(*iv), GFP_KERNEL);
127 if (!iv)
128 goto out;
129 iv->bits = bits;
130 size = BITS_TO_LONGS(bits) * sizeof(unsigned long);
131 iv->vector = kzalloc(size, GFP_KERNEL);
132 if (!iv->vector)
133 goto out_free;
134 if (flags & AIRQ_IV_ALLOC) {
135 iv->avail = kmalloc(size, GFP_KERNEL);
136 if (!iv->avail)
137 goto out_free;
138 memset(iv->avail, 0xff, size);
139 iv->end = 0;
140 } else
141 iv->end = bits;
142 if (flags & AIRQ_IV_BITLOCK) {
143 iv->bitlock = kzalloc(size, GFP_KERNEL);
144 if (!iv->bitlock)
145 goto out_free;
146 }
147 if (flags & AIRQ_IV_PTR) {
148 size = bits * sizeof(unsigned long);
149 iv->ptr = kzalloc(size, GFP_KERNEL);
150 if (!iv->ptr)
151 goto out_free;
152 }
153 if (flags & AIRQ_IV_DATA) {
154 size = bits * sizeof(unsigned int);
155 iv->data = kzalloc(size, GFP_KERNEL);
156 if (!iv->data)
157 goto out_free;
158 }
159 spin_lock_init(&iv->lock);
160 return iv;
161
162out_free:
163 kfree(iv->ptr);
164 kfree(iv->bitlock);
165 kfree(iv->avail);
166 kfree(iv->vector);
167 kfree(iv);
168out:
169 return NULL;
170}
171EXPORT_SYMBOL(airq_iv_create);
172
173/**
174 * airq_iv_release - release an interrupt vector
175 * @iv: pointer to interrupt vector structure
176 */
177void airq_iv_release(struct airq_iv *iv)
178{
179 kfree(iv->data);
180 kfree(iv->ptr);
181 kfree(iv->bitlock);
182 kfree(iv->vector);
183 kfree(iv->avail);
184 kfree(iv);
185}
186EXPORT_SYMBOL(airq_iv_release);
187
188/**
189 * airq_iv_alloc_bit - allocate an irq bit from an interrupt vector
190 * @iv: pointer to an interrupt vector structure
191 *
192 * Returns the bit number of the allocated irq, or -1UL if no bit
193 * is available or the AIRQ_IV_ALLOC flag has not been specified
194 */
195unsigned long airq_iv_alloc_bit(struct airq_iv *iv)
196{
197 const unsigned long be_to_le = BITS_PER_LONG - 1;
198 unsigned long bit;
199
200 if (!iv->avail)
201 return -1UL;
202 spin_lock(&iv->lock);
203 bit = find_first_bit_left(iv->avail, iv->bits);
204 if (bit < iv->bits) {
205 clear_bit(bit ^ be_to_le, iv->avail);
206 if (bit >= iv->end)
207 iv->end = bit + 1;
208 } else
209 bit = -1UL;
210 spin_unlock(&iv->lock);
211 return bit;
212
213}
214EXPORT_SYMBOL(airq_iv_alloc_bit);
215
216/**
217 * airq_iv_free_bit - free an irq bit of an interrupt vector
218 * @iv: pointer to interrupt vector structure
219 * @bit: number of the irq bit to free
220 */
221void airq_iv_free_bit(struct airq_iv *iv, unsigned long bit)
222{
223 const unsigned long be_to_le = BITS_PER_LONG - 1;
224
225 if (!iv->avail)
226 return;
227 spin_lock(&iv->lock);
228 /* Clear (possibly left over) interrupt bit */
229 clear_bit(bit ^ be_to_le, iv->vector);
230 /* Make the bit position available again */
231 set_bit(bit ^ be_to_le, iv->avail);
232 if (bit == iv->end - 1) {
233 /* Find new end of bit-field */
234 while (--iv->end > 0)
235 if (!test_bit((iv->end - 1) ^ be_to_le, iv->avail))
236 break;
237 }
238 spin_unlock(&iv->lock);
239}
240EXPORT_SYMBOL(airq_iv_free_bit);
241
242/**
243 * airq_iv_scan - scan interrupt vector for non-zero bits
244 * @iv: pointer to interrupt vector structure
245 * @start: bit number to start the search
246 * @end: bit number to end the search
247 *
248 * Returns the bit number of the next non-zero interrupt bit, or
249 * -1UL if the scan completed without finding any more any non-zero bits.
250 */
251unsigned long airq_iv_scan(struct airq_iv *iv, unsigned long start,
252 unsigned long end)
253{
254 const unsigned long be_to_le = BITS_PER_LONG - 1;
255 unsigned long bit;
256
257 /* Find non-zero bit starting from 'ivs->next'. */
258 bit = find_next_bit_left(iv->vector, end, start);
259 if (bit >= end)
260 return -1UL;
261 /* Clear interrupt bit (find left uses big-endian bit numbers) */
262 clear_bit(bit ^ be_to_le, iv->vector);
263 return bit;
95} 264}
265EXPORT_SYMBOL(airq_iv_scan);
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 84846c2b96d3..959135a01847 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -137,7 +137,7 @@ static ssize_t ccwgroup_online_store(struct device *dev,
137 if (!try_module_get(gdrv->driver.owner)) 137 if (!try_module_get(gdrv->driver.owner))
138 return -EINVAL; 138 return -EINVAL;
139 139
140 ret = strict_strtoul(buf, 0, &value); 140 ret = kstrtoul(buf, 0, &value);
141 if (ret) 141 if (ret)
142 goto out; 142 goto out;
143 143
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 4eeb4a6bf207..d7da67a31c77 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -561,37 +561,23 @@ out:
561} 561}
562 562
563/* 563/*
564 * do_IRQ() handles all normal I/O device IRQ's (the special 564 * do_cio_interrupt() handles all normal I/O device IRQ's
565 * SMP cross-CPU interrupts have their own specific
566 * handlers).
567 *
568 */ 565 */
569void __irq_entry do_IRQ(struct pt_regs *regs) 566static irqreturn_t do_cio_interrupt(int irq, void *dummy)
570{ 567{
571 struct tpi_info *tpi_info = (struct tpi_info *) &regs->int_code; 568 struct tpi_info *tpi_info;
572 struct subchannel *sch; 569 struct subchannel *sch;
573 struct irb *irb; 570 struct irb *irb;
574 struct pt_regs *old_regs;
575 571
576 old_regs = set_irq_regs(regs);
577 irq_enter();
578 __this_cpu_write(s390_idle.nohz_delay, 1); 572 __this_cpu_write(s390_idle.nohz_delay, 1);
579 if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) 573 tpi_info = (struct tpi_info *) &get_irq_regs()->int_code;
580 /* Serve timer interrupts first. */
581 clock_comparator_work();
582
583 kstat_incr_irqs_this_cpu(IO_INTERRUPT, NULL);
584 irb = (struct irb *) &S390_lowcore.irb; 574 irb = (struct irb *) &S390_lowcore.irb;
585 if (tpi_info->adapter_IO) {
586 do_adapter_IO(tpi_info->isc);
587 goto out;
588 }
589 sch = (struct subchannel *)(unsigned long) tpi_info->intparm; 575 sch = (struct subchannel *)(unsigned long) tpi_info->intparm;
590 if (!sch) { 576 if (!sch) {
591 /* Clear pending interrupt condition. */ 577 /* Clear pending interrupt condition. */
592 inc_irq_stat(IRQIO_CIO); 578 inc_irq_stat(IRQIO_CIO);
593 tsch(tpi_info->schid, irb); 579 tsch(tpi_info->schid, irb);
594 goto out; 580 return IRQ_HANDLED;
595 } 581 }
596 spin_lock(sch->lock); 582 spin_lock(sch->lock);
597 /* Store interrupt response block to lowcore. */ 583 /* Store interrupt response block to lowcore. */
@@ -606,9 +592,23 @@ void __irq_entry do_IRQ(struct pt_regs *regs)
606 } else 592 } else
607 inc_irq_stat(IRQIO_CIO); 593 inc_irq_stat(IRQIO_CIO);
608 spin_unlock(sch->lock); 594 spin_unlock(sch->lock);
609out: 595
610 irq_exit(); 596 return IRQ_HANDLED;
611 set_irq_regs(old_regs); 597}
598
599static struct irq_desc *irq_desc_io;
600
601static struct irqaction io_interrupt = {
602 .name = "IO",
603 .handler = do_cio_interrupt,
604};
605
606void __init init_cio_interrupts(void)
607{
608 irq_set_chip_and_handler(IO_INTERRUPT,
609 &dummy_irq_chip, handle_percpu_irq);
610 setup_irq(IO_INTERRUPT, &io_interrupt);
611 irq_desc_io = irq_to_desc(IO_INTERRUPT);
612} 612}
613 613
614#ifdef CONFIG_CCW_CONSOLE 614#ifdef CONFIG_CCW_CONSOLE
@@ -635,7 +635,7 @@ void cio_tsch(struct subchannel *sch)
635 local_bh_disable(); 635 local_bh_disable();
636 irq_enter(); 636 irq_enter();
637 } 637 }
638 kstat_incr_irqs_this_cpu(IO_INTERRUPT, NULL); 638 kstat_incr_irqs_this_cpu(IO_INTERRUPT, irq_desc_io);
639 if (sch->driver && sch->driver->irq) 639 if (sch->driver && sch->driver->irq)
640 sch->driver->irq(sch); 640 sch->driver->irq(sch);
641 else 641 else
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h
index d62f5e7f3cf1..d42f67412bd8 100644
--- a/drivers/s390/cio/cio.h
+++ b/drivers/s390/cio/cio.h
@@ -121,9 +121,6 @@ extern int cio_commit_config(struct subchannel *sch);
121int cio_tm_start_key(struct subchannel *sch, struct tcw *tcw, u8 lpm, u8 key); 121int cio_tm_start_key(struct subchannel *sch, struct tcw *tcw, u8 lpm, u8 key);
122int cio_tm_intrg(struct subchannel *sch); 122int cio_tm_intrg(struct subchannel *sch);
123 123
124void do_adapter_IO(u8 isc);
125void do_IRQ(struct pt_regs *);
126
127/* Use with care. */ 124/* Use with care. */
128#ifdef CONFIG_CCW_CONSOLE 125#ifdef CONFIG_CCW_CONSOLE
129extern struct subchannel *cio_probe_console(void); 126extern struct subchannel *cio_probe_console(void);
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index 4495e0627a40..23054f8fa9fc 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -1182,7 +1182,7 @@ static ssize_t cmb_enable_store(struct device *dev,
1182 int ret; 1182 int ret;
1183 unsigned long val; 1183 unsigned long val;
1184 1184
1185 ret = strict_strtoul(buf, 16, &val); 1185 ret = kstrtoul(buf, 16, &val);
1186 if (ret) 1186 if (ret)
1187 return ret; 1187 return ret;
1188 1188
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 1ebe5d3ddebb..8c2cb87bccc5 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -546,7 +546,9 @@ static int slow_eval_unknown_fn(struct subchannel_id schid, void *data)
546 case -ENOMEM: 546 case -ENOMEM:
547 case -EIO: 547 case -EIO:
548 /* These should abort looping */ 548 /* These should abort looping */
549 spin_lock_irq(&slow_subchannel_lock);
549 idset_sch_del_subseq(slow_subchannel_set, schid); 550 idset_sch_del_subseq(slow_subchannel_set, schid);
551 spin_unlock_irq(&slow_subchannel_lock);
550 break; 552 break;
551 default: 553 default:
552 rc = 0; 554 rc = 0;
@@ -740,7 +742,7 @@ css_cm_enable_store(struct device *dev, struct device_attribute *attr,
740 int ret; 742 int ret;
741 unsigned long val; 743 unsigned long val;
742 744
743 ret = strict_strtoul(buf, 16, &val); 745 ret = kstrtoul(buf, 16, &val);
744 if (ret) 746 if (ret)
745 return ret; 747 return ret;
746 mutex_lock(&css->mutex); 748 mutex_lock(&css->mutex);
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index b1de60335238..29351321bad6 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -130,8 +130,6 @@ struct channel_subsystem {
130 130
131extern struct channel_subsystem *channel_subsystems[]; 131extern struct channel_subsystem *channel_subsystems[];
132 132
133void channel_subsystem_reinit(void);
134
135/* Helper functions to build lists for the slow path. */ 133/* Helper functions to build lists for the slow path. */
136void css_schedule_eval(struct subchannel_id schid); 134void css_schedule_eval(struct subchannel_id schid);
137void css_schedule_eval_all(void); 135void css_schedule_eval_all(void);
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 1ab5f6c36d9b..e4a7ab2bb629 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -564,7 +564,7 @@ static ssize_t online_store (struct device *dev, struct device_attribute *attr,
564 ret = 0; 564 ret = 0;
565 } else { 565 } else {
566 force = 0; 566 force = 0;
567 ret = strict_strtoul(buf, 16, &i); 567 ret = kstrtoul(buf, 16, &i);
568 } 568 }
569 if (ret) 569 if (ret)
570 goto out; 570 goto out;
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c
index d1c8025b0b03..adef5f5de118 100644
--- a/drivers/s390/net/qeth_l3_sys.c
+++ b/drivers/s390/net/qeth_l3_sys.c
@@ -208,7 +208,7 @@ static ssize_t qeth_l3_dev_sniffer_store(struct device *dev,
208 goto out; 208 goto out;
209 } 209 }
210 210
211 rc = strict_strtoul(buf, 16, &i); 211 rc = kstrtoul(buf, 16, &i);
212 if (rc) { 212 if (rc) {
213 rc = -EINVAL; 213 rc = -EINVAL;
214 goto out; 214 goto out;