From 03efed8a2a1b8e00164eb4720a82a7dd5e368a8e Mon Sep 17 00:00:00 2001 From: Tiger Yang Date: Sat, 28 May 2011 00:34:19 +0800 Subject: ocfs2: Bugfix for hard readonly mount ocfs2 cannot currently mount a device that is readonly at the media ("hard readonly"). Fix the broken places. see detail: http://oss.oracle.com/bugzilla/show_bug.cgi?id=1322 [ Description edited -- Joel ] Signed-off-by: Tiger Yang Reviewed-by: Sunil Mushran Signed-off-by: Joel Becker --- fs/ocfs2/dlmglue.c | 21 +++++++++++++++------ fs/ocfs2/super.c | 3 ++- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 7642d7c..da103f5 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c @@ -1692,7 +1692,7 @@ int ocfs2_open_lock(struct inode *inode) mlog(0, "inode %llu take PRMODE open lock\n", (unsigned long long)OCFS2_I(inode)->ip_blkno); - if (ocfs2_mount_local(osb)) + if (ocfs2_is_hard_readonly(osb) || ocfs2_mount_local(osb)) goto out; lockres = &OCFS2_I(inode)->ip_open_lockres; @@ -1718,6 +1718,12 @@ int ocfs2_try_open_lock(struct inode *inode, int write) (unsigned long long)OCFS2_I(inode)->ip_blkno, write ? "EXMODE" : "PRMODE"); + if (ocfs2_is_hard_readonly(osb)) { + if (write) + status = -EROFS; + goto out; + } + if (ocfs2_mount_local(osb)) goto out; @@ -2298,7 +2304,7 @@ int ocfs2_inode_lock_full_nested(struct inode *inode, if (ocfs2_is_hard_readonly(osb)) { if (ex) status = -EROFS; - goto bail; + goto getbh; } if (ocfs2_mount_local(osb)) @@ -2356,7 +2362,7 @@ local: mlog_errno(status); goto bail; } - +getbh: if (ret_bh) { status = ocfs2_assign_bh(inode, ret_bh, local_bh); if (status < 0) { @@ -2628,8 +2634,11 @@ int ocfs2_dentry_lock(struct dentry *dentry, int ex) BUG_ON(!dl); - if (ocfs2_is_hard_readonly(osb)) - return -EROFS; + if (ocfs2_is_hard_readonly(osb)) { + if (ex) + return -EROFS; + return 0; + } if (ocfs2_mount_local(osb)) return 0; @@ -2647,7 +2656,7 @@ void ocfs2_dentry_unlock(struct dentry *dentry, int ex) struct ocfs2_dentry_lock *dl = dentry->d_fsdata; struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb); - if (!ocfs2_mount_local(osb)) + if (!ocfs2_is_hard_readonly(osb) && !ocfs2_mount_local(osb)) ocfs2_cluster_unlock(osb, &dl->dl_lockres, level); } diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index cdbaf5e..029c4cd 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -1974,7 +1974,8 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err) * If we failed before we got a uuid_str yet, we can't stop * heartbeat. Otherwise, do it. */ - if (!mnt_err && !ocfs2_mount_local(osb) && osb->uuid_str) + if (!mnt_err && !ocfs2_mount_local(osb) && osb->uuid_str && + !ocfs2_is_hard_readonly(osb)) hangup_needed = 1; if (osb->cconn) -- cgit v1.1 From 3d75be7c4771c7e4d5b5fa586a599af8473de32c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 29 May 2011 22:56:31 +0300 Subject: ocfs2: checking the wrong variable in ocfs2_move_extent() "new_phys_cpos" is always a valid pointer here. ocfs2_probe_alloc_group() allocates "*new_phys_cpos". Signed-off-by: Dan Carpenter Signed-off-by: Joel Becker --- fs/ocfs2/move_extents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c index cd94270..d3433d6 100644 --- a/fs/ocfs2/move_extents.c +++ b/fs/ocfs2/move_extents.c @@ -746,7 +746,7 @@ static int ocfs2_move_extent(struct ocfs2_move_extents_context *context, */ ocfs2_probe_alloc_group(inode, gd_bh, &goal_bit, len, move_max_hop, new_phys_cpos); - if (!new_phys_cpos) { + if (!*new_phys_cpos) { ret = -ENOSPC; goto out_commit; } -- cgit v1.1 From 87f0d5c8db7aad85b9120c26723fdc63cd84a460 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 29 May 2011 22:57:16 +0300 Subject: ocfs2: null deref on allocation error The original code had a null derefence in the error handling. Signed-off-by: Dan Carpenter Signed-off-by: Joel Becker --- fs/ocfs2/ioctl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c index bc91072..d9a6ce7 100644 --- a/fs/ocfs2/ioctl.c +++ b/fs/ocfs2/ioctl.c @@ -381,7 +381,7 @@ int ocfs2_info_handle_freeinode(struct inode *inode, if (!oifi) { status = -ENOMEM; mlog_errno(status); - goto bail; + goto out_err; } if (o2info_from_user(*oifi, req)) @@ -431,7 +431,7 @@ bail: o2info_set_request_error(&oifi->ifi_req, req); kfree(oifi); - +out_err: return status; } @@ -666,7 +666,7 @@ int ocfs2_info_handle_freefrag(struct inode *inode, if (!oiff) { status = -ENOMEM; mlog_errno(status); - goto bail; + goto out_err; } if (o2info_from_user(*oiff, req)) @@ -716,7 +716,7 @@ bail: o2info_set_request_error(&oiff->iff_req, req); kfree(oiff); - +out_err: return status; } -- cgit v1.1 From 730e663bd82c1a10a85ff00728d34152a5a67ec8 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Mon, 30 May 2011 21:58:05 +0900 Subject: ocfs2: use proper little-endian bitops Using __test_and_{set,clear}_bit_le() with ignoring its return value can be replaced with __{set,clear}_bit_le(). Signed-off-by: Akinobu Mita Cc: Joel Becker Cc: Mark Fasheh Cc: ocfs2-devel@oss.oracle.com Signed-off-by: Joel Becker --- fs/ocfs2/ocfs2.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index 4092858..bcde467 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h @@ -836,13 +836,13 @@ static inline unsigned int ocfs2_clusters_to_megabytes(struct super_block *sb, static inline void _ocfs2_set_bit(unsigned int bit, unsigned long *bitmap) { - __test_and_set_bit_le(bit, bitmap); + __set_bit_le(bit, bitmap); } #define ocfs2_set_bit(bit, addr) _ocfs2_set_bit((bit), (unsigned long *)(addr)) static inline void _ocfs2_clear_bit(unsigned int bit, unsigned long *bitmap) { - __test_and_clear_bit_le(bit, bitmap); + __clear_bit_le(bit, bitmap); } #define ocfs2_clear_bit(bit, addr) _ocfs2_clear_bit((bit), (unsigned long *)(addr)) -- cgit v1.1 From d2eece376648d2f7ba0a7d78f3c4d0421e608ac2 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Sun, 24 Jul 2011 10:21:54 -0700 Subject: ocfs2/cluster: Abort heartbeat start on hard-ro devices Currently if the heartbeat device is hard-ro, the o2hb thread keeps chugging along and dumping errors along the way. The user needs to manually stop the heartbeat. The patch addresses this shortcoming by adding a limit to the number of times the hb thread will iterate in an unsteady state. If the hb thread does not ready steady state in that many interation, the start is aborted. Signed-off-by: Sunil Mushran --- fs/ocfs2/cluster/heartbeat.c | 185 +++++++++++++++++++++++++++---------------- 1 file changed, 116 insertions(+), 69 deletions(-) diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 9a3e6bb..4728a74 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c @@ -216,6 +216,7 @@ struct o2hb_region { struct list_head hr_all_item; unsigned hr_unclean_stop:1, + hr_aborted_start:1, hr_item_pinned:1, hr_item_dropped:1; @@ -254,6 +255,10 @@ struct o2hb_region { * a more complete api that doesn't lead to this sort of fragility. */ atomic_t hr_steady_iterations; + /* terminate o2hb thread if it does not reach steady state + * (hr_steady_iterations == 0) within hr_unsteady_iterations */ + atomic_t hr_unsteady_iterations; + char hr_dev_name[BDEVNAME_SIZE]; unsigned int hr_timeout_ms; @@ -324,6 +329,10 @@ static void o2hb_write_timeout(struct work_struct *work) static void o2hb_arm_write_timeout(struct o2hb_region *reg) { + /* Arm writeout only after thread reaches steady state */ + if (atomic_read(®->hr_steady_iterations) != 0) + return; + mlog(ML_HEARTBEAT, "Queue write timeout for %u ms\n", O2HB_MAX_WRITE_TIMEOUT_MS); @@ -537,9 +546,14 @@ static int o2hb_verify_crc(struct o2hb_region *reg, return read == computed; } -/* We want to make sure that nobody is heartbeating on top of us -- - * this will help detect an invalid configuration. */ -static void o2hb_check_last_timestamp(struct o2hb_region *reg) +/* + * Compare the slot data with what we wrote in the last iteration. + * If the match fails, print an appropriate error message. This is to + * detect errors like... another node hearting on the same slot, + * flaky device that is losing writes, etc. + * Returns 1 if check succeeds, 0 otherwise. + */ +static int o2hb_check_own_slot(struct o2hb_region *reg) { struct o2hb_disk_slot *slot; struct o2hb_disk_heartbeat_block *hb_block; @@ -548,13 +562,13 @@ static void o2hb_check_last_timestamp(struct o2hb_region *reg) slot = ®->hr_slots[o2nm_this_node()]; /* Don't check on our 1st timestamp */ if (!slot->ds_last_time) - return; + return 0; hb_block = slot->ds_raw_block; if (le64_to_cpu(hb_block->hb_seq) == slot->ds_last_time && le64_to_cpu(hb_block->hb_generation) == slot->ds_last_generation && hb_block->hb_node == slot->ds_node_num) - return; + return 1; #define ERRSTR1 "Another node is heartbeating on device" #define ERRSTR2 "Heartbeat generation mismatch on device" @@ -574,6 +588,8 @@ static void o2hb_check_last_timestamp(struct o2hb_region *reg) (unsigned long long)slot->ds_last_time, hb_block->hb_node, (unsigned long long)le64_to_cpu(hb_block->hb_generation), (unsigned long long)le64_to_cpu(hb_block->hb_seq)); + + return 0; } static inline void o2hb_prepare_block(struct o2hb_region *reg, @@ -719,17 +735,24 @@ static void o2hb_shutdown_slot(struct o2hb_disk_slot *slot) o2nm_node_put(node); } -static void o2hb_set_quorum_device(struct o2hb_region *reg, - struct o2hb_disk_slot *slot) +static void o2hb_set_quorum_device(struct o2hb_region *reg) { - assert_spin_locked(&o2hb_live_lock); - if (!o2hb_global_heartbeat_active()) return; - if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap)) + /* Prevent race with o2hb_heartbeat_group_drop_item() */ + if (kthread_should_stop()) + return; + + /* Tag region as quorum only after thread reaches steady state */ + if (atomic_read(®->hr_steady_iterations) != 0) return; + spin_lock(&o2hb_live_lock); + + if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap)) + goto unlock; + /* * A region can be added to the quorum only when it sees all * live nodes heartbeat on it. In other words, the region has been @@ -737,13 +760,10 @@ static void o2hb_set_quorum_device(struct o2hb_region *reg, */ if (memcmp(reg->hr_live_node_bitmap, o2hb_live_node_bitmap, sizeof(o2hb_live_node_bitmap))) - return; - - if (slot->ds_changed_samples < O2HB_LIVE_THRESHOLD) - return; + goto unlock; - printk(KERN_NOTICE "o2hb: Region %s is now a quorum device\n", - config_item_name(®->hr_item)); + printk(KERN_NOTICE "o2hb: Region %s (%s) is now a quorum device\n", + config_item_name(®->hr_item), reg->hr_dev_name); set_bit(reg->hr_region_num, o2hb_quorum_region_bitmap); @@ -754,6 +774,8 @@ static void o2hb_set_quorum_device(struct o2hb_region *reg, if (o2hb_pop_count(&o2hb_quorum_region_bitmap, O2NM_MAX_REGIONS) > O2HB_PIN_CUT_OFF) o2hb_region_unpin(NULL); +unlock: + spin_unlock(&o2hb_live_lock); } static int o2hb_check_slot(struct o2hb_region *reg, @@ -925,8 +947,6 @@ fire_callbacks: slot->ds_equal_samples = 0; } out: - o2hb_set_quorum_device(reg, slot); - spin_unlock(&o2hb_live_lock); o2hb_run_event_list(&event); @@ -957,7 +977,8 @@ static int o2hb_highest_node(unsigned long *nodes, static int o2hb_do_disk_heartbeat(struct o2hb_region *reg) { - int i, ret, highest_node, change = 0; + int i, ret, highest_node; + int membership_change = 0, own_slot_ok = 0; unsigned long configured_nodes[BITS_TO_LONGS(O2NM_MAX_NODES)]; unsigned long live_node_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)]; struct o2hb_bio_wait_ctxt write_wc; @@ -966,7 +987,7 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg) sizeof(configured_nodes)); if (ret) { mlog_errno(ret); - return ret; + goto bail; } /* @@ -982,8 +1003,9 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg) highest_node = o2hb_highest_node(configured_nodes, O2NM_MAX_NODES); if (highest_node >= O2NM_MAX_NODES) { - mlog(ML_NOTICE, "ocfs2_heartbeat: no configured nodes found!\n"); - return -EINVAL; + mlog(ML_NOTICE, "o2hb: No configured nodes found!\n"); + ret = -EINVAL; + goto bail; } /* No sense in reading the slots of nodes that don't exist @@ -993,29 +1015,27 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg) ret = o2hb_read_slots(reg, highest_node + 1); if (ret < 0) { mlog_errno(ret); - return ret; + goto bail; } /* With an up to date view of the slots, we can check that no * other node has been improperly configured to heartbeat in * our slot. */ - o2hb_check_last_timestamp(reg); + own_slot_ok = o2hb_check_own_slot(reg); /* fill in the proper info for our next heartbeat */ o2hb_prepare_block(reg, reg->hr_generation); - /* And fire off the write. Note that we don't wait on this I/O - * until later. */ ret = o2hb_issue_node_write(reg, &write_wc); if (ret < 0) { mlog_errno(ret); - return ret; + goto bail; } i = -1; while((i = find_next_bit(configured_nodes, O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) { - change |= o2hb_check_slot(reg, ®->hr_slots[i]); + membership_change |= o2hb_check_slot(reg, ®->hr_slots[i]); } /* @@ -1030,18 +1050,39 @@ static int o2hb_do_disk_heartbeat(struct o2hb_region *reg) * disk */ mlog(ML_ERROR, "Write error %d on device \"%s\"\n", write_wc.wc_error, reg->hr_dev_name); - return write_wc.wc_error; + ret = write_wc.wc_error; + goto bail; } - o2hb_arm_write_timeout(reg); + /* Skip disarming the timeout if own slot has stale/bad data */ + if (own_slot_ok) { + o2hb_set_quorum_device(reg); + o2hb_arm_write_timeout(reg); + } +bail: /* let the person who launched us know when things are steady */ - if (!change && (atomic_read(®->hr_steady_iterations) != 0)) { - if (atomic_dec_and_test(®->hr_steady_iterations)) + if (atomic_read(®->hr_steady_iterations) != 0) { + if (!ret && own_slot_ok && !membership_change) { + if (atomic_dec_and_test(®->hr_steady_iterations)) + wake_up(&o2hb_steady_queue); + } + } + + if (atomic_read(®->hr_steady_iterations) != 0) { + if (atomic_dec_and_test(®->hr_unsteady_iterations)) { + printk(KERN_NOTICE "o2hb: Unable to stabilize " + "heartbeart on region %s (%s)\n", + config_item_name(®->hr_item), + reg->hr_dev_name); + atomic_set(®->hr_steady_iterations, 0); + reg->hr_aborted_start = 1; wake_up(&o2hb_steady_queue); + ret = -EIO; + } } - return 0; + return ret; } /* Subtract b from a, storing the result in a. a *must* have a larger @@ -1095,7 +1136,8 @@ static int o2hb_thread(void *data) /* Pin node */ o2nm_depend_this_node(); - while (!kthread_should_stop() && !reg->hr_unclean_stop) { + while (!kthread_should_stop() && + !reg->hr_unclean_stop && !reg->hr_aborted_start) { /* We track the time spent inside * o2hb_do_disk_heartbeat so that we avoid more than * hr_timeout_ms between disk writes. On busy systems @@ -1103,10 +1145,7 @@ static int o2hb_thread(void *data) * likely to time itself out. */ do_gettimeofday(&before_hb); - i = 0; - do { - ret = o2hb_do_disk_heartbeat(reg); - } while (ret && ++i < 2); + ret = o2hb_do_disk_heartbeat(reg); do_gettimeofday(&after_hb); elapsed_msec = o2hb_elapsed_msecs(&before_hb, &after_hb); @@ -1117,7 +1156,8 @@ static int o2hb_thread(void *data) after_hb.tv_sec, (unsigned long) after_hb.tv_usec, elapsed_msec); - if (elapsed_msec < reg->hr_timeout_ms) { + if (!kthread_should_stop() && + elapsed_msec < reg->hr_timeout_ms) { /* the kthread api has blocked signals for us so no * need to record the return value. */ msleep_interruptible(reg->hr_timeout_ms - elapsed_msec); @@ -1134,20 +1174,20 @@ static int o2hb_thread(void *data) * to timeout on this region when we could just as easily * write a clear generation - thus indicating to them that * this node has left this region. - * - * XXX: Should we skip this on unclean_stop? */ - o2hb_prepare_block(reg, 0); - ret = o2hb_issue_node_write(reg, &write_wc); - if (ret == 0) { - o2hb_wait_on_io(reg, &write_wc); - } else { - mlog_errno(ret); + */ + if (!reg->hr_unclean_stop && !reg->hr_aborted_start) { + o2hb_prepare_block(reg, 0); + ret = o2hb_issue_node_write(reg, &write_wc); + if (ret == 0) + o2hb_wait_on_io(reg, &write_wc); + else + mlog_errno(ret); } /* Unpin node */ o2nm_undepend_this_node(); - mlog(ML_HEARTBEAT|ML_KTHREAD, "hb thread exiting\n"); + mlog(ML_HEARTBEAT|ML_KTHREAD, "o2hb thread exiting\n"); return 0; } @@ -1426,6 +1466,8 @@ static void o2hb_region_release(struct config_item *item) struct page *page; struct o2hb_region *reg = to_o2hb_region(item); + mlog(ML_HEARTBEAT, "hb region release (%s)\n", reg->hr_dev_name); + if (reg->hr_tmp_block) kfree(reg->hr_tmp_block); @@ -1792,7 +1834,10 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, live_threshold <<= 1; spin_unlock(&o2hb_live_lock); } - atomic_set(®->hr_steady_iterations, live_threshold + 1); + ++live_threshold; + atomic_set(®->hr_steady_iterations, live_threshold); + /* unsteady_iterations is double the steady_iterations */ + atomic_set(®->hr_unsteady_iterations, (live_threshold << 1)); hb_task = kthread_run(o2hb_thread, reg, "o2hb-%s", reg->hr_item.ci_name); @@ -1809,14 +1854,12 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, ret = wait_event_interruptible(o2hb_steady_queue, atomic_read(®->hr_steady_iterations) == 0); if (ret) { - /* We got interrupted (hello ptrace!). Clean up */ - spin_lock(&o2hb_live_lock); - hb_task = reg->hr_task; - reg->hr_task = NULL; - spin_unlock(&o2hb_live_lock); + atomic_set(®->hr_steady_iterations, 0); + reg->hr_aborted_start = 1; + } - if (hb_task) - kthread_stop(hb_task); + if (reg->hr_aborted_start) { + ret = -EIO; goto out; } @@ -1833,8 +1876,8 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, ret = -EIO; if (hb_task && o2hb_global_heartbeat_active()) - printk(KERN_NOTICE "o2hb: Heartbeat started on region %s\n", - config_item_name(®->hr_item)); + printk(KERN_NOTICE "o2hb: Heartbeat started on region %s (%s)\n", + config_item_name(®->hr_item), reg->hr_dev_name); out: if (filp) @@ -2092,13 +2135,6 @@ static void o2hb_heartbeat_group_drop_item(struct config_group *group, /* stop the thread when the user removes the region dir */ spin_lock(&o2hb_live_lock); - if (o2hb_global_heartbeat_active()) { - clear_bit(reg->hr_region_num, o2hb_region_bitmap); - clear_bit(reg->hr_region_num, o2hb_live_region_bitmap); - if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap)) - quorum_region = 1; - clear_bit(reg->hr_region_num, o2hb_quorum_region_bitmap); - } hb_task = reg->hr_task; reg->hr_task = NULL; reg->hr_item_dropped = 1; @@ -2107,19 +2143,30 @@ static void o2hb_heartbeat_group_drop_item(struct config_group *group, if (hb_task) kthread_stop(hb_task); + if (o2hb_global_heartbeat_active()) { + spin_lock(&o2hb_live_lock); + clear_bit(reg->hr_region_num, o2hb_region_bitmap); + clear_bit(reg->hr_region_num, o2hb_live_region_bitmap); + if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap)) + quorum_region = 1; + clear_bit(reg->hr_region_num, o2hb_quorum_region_bitmap); + spin_unlock(&o2hb_live_lock); + printk(KERN_NOTICE "o2hb: Heartbeat %s on region %s (%s)\n", + ((atomic_read(®->hr_steady_iterations) == 0) ? + "stopped" : "start aborted"), config_item_name(item), + reg->hr_dev_name); + } + /* * If we're racing a dev_write(), we need to wake them. They will * check reg->hr_task */ if (atomic_read(®->hr_steady_iterations) != 0) { + reg->hr_aborted_start = 1; atomic_set(®->hr_steady_iterations, 0); wake_up(&o2hb_steady_queue); } - if (o2hb_global_heartbeat_active()) - printk(KERN_NOTICE "o2hb: Heartbeat stopped on region %s\n", - config_item_name(®->hr_item)); - config_item_put(item); if (!o2hb_global_heartbeat_active() || !quorum_region) -- cgit v1.1 From 1dfecf810e0eacb35987905082f23e5c2cd26e91 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Sun, 24 Jul 2011 10:22:54 -0700 Subject: ocfs2/cluster: Clean up messages in o2net o2net messages needed a facelift. Signed-off-by: Sunil Mushran --- fs/ocfs2/cluster/tcp.c | 119 ++++++++++++++++++++++--------------------------- 1 file changed, 53 insertions(+), 66 deletions(-) diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index db5ee4b..6e97895 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c @@ -545,7 +545,7 @@ static void o2net_set_nn_state(struct o2net_node *nn, } if (was_valid && !valid) { - printk(KERN_NOTICE "o2net: no longer connected to " + printk(KERN_NOTICE "o2net: No longer connected to " SC_NODEF_FMT "\n", SC_NODEF_ARGS(old_sc)); o2net_complete_nodes_nsw(nn); } @@ -555,7 +555,7 @@ static void o2net_set_nn_state(struct o2net_node *nn, cancel_delayed_work(&nn->nn_connect_expired); printk(KERN_NOTICE "o2net: %s " SC_NODEF_FMT "\n", o2nm_this_node() > sc->sc_node->nd_num ? - "connected to" : "accepted connection from", + "Connected to" : "Accepted connection from", SC_NODEF_ARGS(sc)); } @@ -643,7 +643,7 @@ static void o2net_state_change(struct sock *sk) o2net_sc_queue_work(sc, &sc->sc_connect_work); break; default: - printk(KERN_INFO "o2net: connection to " SC_NODEF_FMT + printk(KERN_INFO "o2net: Connection to " SC_NODEF_FMT " shutdown, state %d\n", SC_NODEF_ARGS(sc), sk->sk_state); o2net_sc_queue_work(sc, &sc->sc_shutdown_work); @@ -1284,11 +1284,11 @@ static int o2net_check_handshake(struct o2net_sock_container *sc) struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); if (hand->protocol_version != cpu_to_be64(O2NET_PROTOCOL_VERSION)) { - mlog(ML_NOTICE, SC_NODEF_FMT " advertised net protocol " - "version %llu but %llu is required, disconnecting\n", - SC_NODEF_ARGS(sc), - (unsigned long long)be64_to_cpu(hand->protocol_version), - O2NET_PROTOCOL_VERSION); + printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " Advertised net " + "protocol version %llu but %llu is required. " + "Disconnecting.\n", SC_NODEF_ARGS(sc), + (unsigned long long)be64_to_cpu(hand->protocol_version), + O2NET_PROTOCOL_VERSION); /* don't bother reconnecting if its the wrong version. */ o2net_ensure_shutdown(nn, sc, -ENOTCONN); @@ -1302,33 +1302,33 @@ static int o2net_check_handshake(struct o2net_sock_container *sc) */ if (be32_to_cpu(hand->o2net_idle_timeout_ms) != o2net_idle_timeout()) { - mlog(ML_NOTICE, SC_NODEF_FMT " uses a network idle timeout of " - "%u ms, but we use %u ms locally. disconnecting\n", - SC_NODEF_ARGS(sc), - be32_to_cpu(hand->o2net_idle_timeout_ms), - o2net_idle_timeout()); + printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " uses a network " + "idle timeout of %u ms, but we use %u ms locally. " + "Disconnecting.\n", SC_NODEF_ARGS(sc), + be32_to_cpu(hand->o2net_idle_timeout_ms), + o2net_idle_timeout()); o2net_ensure_shutdown(nn, sc, -ENOTCONN); return -1; } if (be32_to_cpu(hand->o2net_keepalive_delay_ms) != o2net_keepalive_delay()) { - mlog(ML_NOTICE, SC_NODEF_FMT " uses a keepalive delay of " - "%u ms, but we use %u ms locally. disconnecting\n", - SC_NODEF_ARGS(sc), - be32_to_cpu(hand->o2net_keepalive_delay_ms), - o2net_keepalive_delay()); + printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " uses a keepalive " + "delay of %u ms, but we use %u ms locally. " + "Disconnecting.\n", SC_NODEF_ARGS(sc), + be32_to_cpu(hand->o2net_keepalive_delay_ms), + o2net_keepalive_delay()); o2net_ensure_shutdown(nn, sc, -ENOTCONN); return -1; } if (be32_to_cpu(hand->o2hb_heartbeat_timeout_ms) != O2HB_MAX_WRITE_TIMEOUT_MS) { - mlog(ML_NOTICE, SC_NODEF_FMT " uses a heartbeat timeout of " - "%u ms, but we use %u ms locally. disconnecting\n", - SC_NODEF_ARGS(sc), - be32_to_cpu(hand->o2hb_heartbeat_timeout_ms), - O2HB_MAX_WRITE_TIMEOUT_MS); + printk(KERN_NOTICE "o2net: " SC_NODEF_FMT " uses a heartbeat " + "timeout of %u ms, but we use %u ms locally. " + "Disconnecting.\n", SC_NODEF_ARGS(sc), + be32_to_cpu(hand->o2hb_heartbeat_timeout_ms), + O2HB_MAX_WRITE_TIMEOUT_MS); o2net_ensure_shutdown(nn, sc, -ENOTCONN); return -1; } @@ -1539,28 +1539,16 @@ static void o2net_idle_timer(unsigned long data) { struct o2net_sock_container *sc = (struct o2net_sock_container *)data; struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); - #ifdef CONFIG_DEBUG_FS - ktime_t now = ktime_get(); + unsigned long msecs = ktime_to_ms(ktime_get()) - + ktime_to_ms(sc->sc_tv_timer); +#else + unsigned long msecs = o2net_idle_timeout(); #endif - printk(KERN_NOTICE "o2net: connection to " SC_NODEF_FMT " has been idle for %u.%u " - "seconds, shutting it down.\n", SC_NODEF_ARGS(sc), - o2net_idle_timeout() / 1000, - o2net_idle_timeout() % 1000); - -#ifdef CONFIG_DEBUG_FS - mlog(ML_NOTICE, "Here are some times that might help debug the " - "situation: (Timer: %lld, Now %lld, DataReady %lld, Advance %lld-%lld, " - "Key 0x%08x, Func %u, FuncTime %lld-%lld)\n", - (long long)ktime_to_us(sc->sc_tv_timer), (long long)ktime_to_us(now), - (long long)ktime_to_us(sc->sc_tv_data_ready), - (long long)ktime_to_us(sc->sc_tv_advance_start), - (long long)ktime_to_us(sc->sc_tv_advance_stop), - sc->sc_msg_key, sc->sc_msg_type, - (long long)ktime_to_us(sc->sc_tv_func_start), - (long long)ktime_to_us(sc->sc_tv_func_stop)); -#endif + printk(KERN_NOTICE "o2net: Connection to " SC_NODEF_FMT " has been " + "idle for %lu.%lu secs, shutting it down.\n", SC_NODEF_ARGS(sc), + msecs / 1000, msecs % 1000); /* * Initialize the nn_timeout so that the next connection attempt @@ -1693,8 +1681,8 @@ static void o2net_start_connect(struct work_struct *work) out: if (ret) { - mlog(ML_NOTICE, "connect attempt to " SC_NODEF_FMT " failed " - "with errno %d\n", SC_NODEF_ARGS(sc), ret); + printk(KERN_NOTICE "o2net: Connect attempt to " SC_NODEF_FMT + " failed with errno %d\n", SC_NODEF_ARGS(sc), ret); /* 0 err so that another will be queued and attempted * from set_nn_state */ if (sc) @@ -1717,8 +1705,8 @@ static void o2net_connect_expired(struct work_struct *work) spin_lock(&nn->nn_lock); if (!nn->nn_sc_valid) { - mlog(ML_ERROR, "no connection established with node %u after " - "%u.%u seconds, giving up and returning errors.\n", + printk(KERN_NOTICE "o2net: No connection established with " + "node %u after %u.%u seconds, giving up.\n", o2net_num_from_nn(nn), o2net_idle_timeout() / 1000, o2net_idle_timeout() % 1000); @@ -1861,21 +1849,21 @@ static int o2net_accept_one(struct socket *sock) node = o2nm_get_node_by_ip(sin.sin_addr.s_addr); if (node == NULL) { - mlog(ML_NOTICE, "attempt to connect from unknown node at %pI4:%d\n", - &sin.sin_addr.s_addr, ntohs(sin.sin_port)); + printk(KERN_NOTICE "o2net: Attempt to connect from unknown " + "node at %pI4:%d\n", &sin.sin_addr.s_addr, + ntohs(sin.sin_port)); ret = -EINVAL; goto out; } if (o2nm_this_node() >= node->nd_num) { local_node = o2nm_get_node_by_num(o2nm_this_node()); - mlog(ML_NOTICE, "unexpected connect attempt seen at node '%s' (" - "%u, %pI4:%d) from node '%s' (%u, %pI4:%d)\n", - local_node->nd_name, local_node->nd_num, - &(local_node->nd_ipv4_address), - ntohs(local_node->nd_ipv4_port), - node->nd_name, node->nd_num, &sin.sin_addr.s_addr, - ntohs(sin.sin_port)); + printk(KERN_NOTICE "o2net: Unexpected connect attempt seen " + "at node '%s' (%u, %pI4:%d) from node '%s' (%u, " + "%pI4:%d)\n", local_node->nd_name, local_node->nd_num, + &(local_node->nd_ipv4_address), + ntohs(local_node->nd_ipv4_port), node->nd_name, + node->nd_num, &sin.sin_addr.s_addr, ntohs(sin.sin_port)); ret = -EINVAL; goto out; } @@ -1900,10 +1888,10 @@ static int o2net_accept_one(struct socket *sock) ret = 0; spin_unlock(&nn->nn_lock); if (ret) { - mlog(ML_NOTICE, "attempt to connect from node '%s' at " - "%pI4:%d but it already has an open connection\n", - node->nd_name, &sin.sin_addr.s_addr, - ntohs(sin.sin_port)); + printk(KERN_NOTICE "o2net: Attempt to connect from node '%s' " + "at %pI4:%d but it already has an open connection\n", + node->nd_name, &sin.sin_addr.s_addr, + ntohs(sin.sin_port)); goto out; } @@ -1983,7 +1971,7 @@ static int o2net_open_listening_sock(__be32 addr, __be16 port) ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); if (ret < 0) { - mlog(ML_ERROR, "unable to create socket, ret=%d\n", ret); + printk(KERN_ERR "o2net: Error %d while creating socket\n", ret); goto out; } @@ -2000,16 +1988,15 @@ static int o2net_open_listening_sock(__be32 addr, __be16 port) sock->sk->sk_reuse = 1; ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin)); if (ret < 0) { - mlog(ML_ERROR, "unable to bind socket at %pI4:%u, " - "ret=%d\n", &addr, ntohs(port), ret); + printk(KERN_ERR "o2net: Error %d while binding socket at " + "%pI4:%u\n", ret, &addr, ntohs(port)); goto out; } ret = sock->ops->listen(sock, 64); - if (ret < 0) { - mlog(ML_ERROR, "unable to listen on %pI4:%u, ret=%d\n", - &addr, ntohs(port), ret); - } + if (ret < 0) + printk(KERN_ERR "o2net: Error %d while listening on %pI4:%u\n", + ret, &addr, ntohs(port)); out: if (ret) { -- cgit v1.1 From 8decab3c8dadcdf4f54ffb30df6e6f67b398b6e0 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Sun, 24 Jul 2011 10:23:54 -0700 Subject: ocfs2/dlm: Clean up messages in o2dlm o2dlm messages needed a facelift. Signed-off-by: Sunil Mushran --- fs/ocfs2/dlm/dlmdomain.c | 18 +++++++++------- fs/ocfs2/dlm/dlmlock.c | 22 ++++++++----------- fs/ocfs2/dlm/dlmmaster.c | 46 ++++++++++++++++++---------------------- fs/ocfs2/dlm/dlmrecovery.c | 53 +++++++++++++++++++++++++++------------------- fs/ocfs2/dlm/dlmthread.c | 2 -- 5 files changed, 71 insertions(+), 70 deletions(-) diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 6ed6b95..ce225fb 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c @@ -539,17 +539,17 @@ again: static void __dlm_print_nodes(struct dlm_ctxt *dlm) { - int node = -1; + int node = -1, num = 0; assert_spin_locked(&dlm->spinlock); - printk(KERN_NOTICE "o2dlm: Nodes in domain %s: ", dlm->name); - + printk("( "); while ((node = find_next_bit(dlm->domain_map, O2NM_MAX_NODES, node + 1)) < O2NM_MAX_NODES) { printk("%d ", node); + ++num; } - printk("\n"); + printk(") %u nodes\n", num); } static int dlm_exit_domain_handler(struct o2net_msg *msg, u32 len, void *data, @@ -566,11 +566,10 @@ static int dlm_exit_domain_handler(struct o2net_msg *msg, u32 len, void *data, node = exit_msg->node_idx; - printk(KERN_NOTICE "o2dlm: Node %u leaves domain %s\n", node, dlm->name); - spin_lock(&dlm->spinlock); clear_bit(node, dlm->domain_map); clear_bit(node, dlm->exit_domain_map); + printk(KERN_NOTICE "o2dlm: Node %u leaves domain %s ", node, dlm->name); __dlm_print_nodes(dlm); /* notify anything attached to the heartbeat events */ @@ -755,6 +754,7 @@ void dlm_unregister_domain(struct dlm_ctxt *dlm) dlm_mark_domain_leaving(dlm); dlm_leave_domain(dlm); + printk(KERN_NOTICE "o2dlm: Leaving domain %s\n", dlm->name); dlm_force_free_mles(dlm); dlm_complete_dlm_shutdown(dlm); } @@ -970,7 +970,7 @@ static int dlm_assert_joined_handler(struct o2net_msg *msg, u32 len, void *data, clear_bit(assert->node_idx, dlm->exit_domain_map); __dlm_set_joining_node(dlm, DLM_LOCK_RES_OWNER_UNKNOWN); - printk(KERN_NOTICE "o2dlm: Node %u joins domain %s\n", + printk(KERN_NOTICE "o2dlm: Node %u joins domain %s ", assert->node_idx, dlm->name); __dlm_print_nodes(dlm); @@ -1701,8 +1701,10 @@ static int dlm_try_to_join_domain(struct dlm_ctxt *dlm) bail: spin_lock(&dlm->spinlock); __dlm_set_joining_node(dlm, DLM_LOCK_RES_OWNER_UNKNOWN); - if (!status) + if (!status) { + printk(KERN_NOTICE "o2dlm: Joining domain %s ", dlm->name); __dlm_print_nodes(dlm); + } spin_unlock(&dlm->spinlock); if (ctxt) { diff --git a/fs/ocfs2/dlm/dlmlock.c b/fs/ocfs2/dlm/dlmlock.c index 8d39e0fd6..c7f3e22 100644 --- a/fs/ocfs2/dlm/dlmlock.c +++ b/fs/ocfs2/dlm/dlmlock.c @@ -319,27 +319,23 @@ static enum dlm_status dlm_send_remote_lock_request(struct dlm_ctxt *dlm, tmpret = o2net_send_message(DLM_CREATE_LOCK_MSG, dlm->key, &create, sizeof(create), res->owner, &status); if (tmpret >= 0) { - // successfully sent and received - ret = status; // this is already a dlm_status + ret = status; if (ret == DLM_REJECTED) { - mlog(ML_ERROR, "%s:%.*s: BUG. this is a stale lockres " - "no longer owned by %u. that node is coming back " - "up currently.\n", dlm->name, create.namelen, + mlog(ML_ERROR, "%s: res %.*s, Stale lockres no longer " + "owned by node %u. That node is coming back up " + "currently.\n", dlm->name, create.namelen, create.name, res->owner); dlm_print_one_lock_resource(res); BUG(); } } else { - mlog(ML_ERROR, "Error %d when sending message %u (key 0x%x) to " - "node %u\n", tmpret, DLM_CREATE_LOCK_MSG, dlm->key, - res->owner); - if (dlm_is_host_down(tmpret)) { + mlog(ML_ERROR, "%s: res %.*s, Error %d send CREATE LOCK to " + "node %u\n", dlm->name, create.namelen, create.name, + tmpret, res->owner); + if (dlm_is_host_down(tmpret)) ret = DLM_RECOVERING; - mlog(0, "node %u died so returning DLM_RECOVERING " - "from lock message!\n", res->owner); - } else { + else ret = dlm_err_to_dlm_status(tmpret); - } } return ret; diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 11eefb8..9f3b093 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -829,8 +829,8 @@ lookup: * but they might own this lockres. wait on them. */ bit = find_next_bit(dlm->recovery_map, O2NM_MAX_NODES, 0); if (bit < O2NM_MAX_NODES) { - mlog(ML_NOTICE, "%s:%.*s: at least one node (%d) to " - "recover before lock mastery can begin\n", + mlog(0, "%s: res %.*s, At least one node (%d) " + "to recover before lock mastery can begin\n", dlm->name, namelen, (char *)lockid, bit); wait_on_recovery = 1; } @@ -864,8 +864,8 @@ redo_request: * dlm spinlock would be detectable be a change on the mle, * so we only need to clear out the recovery map once. */ if (dlm_is_recovery_lock(lockid, namelen)) { - mlog(ML_NOTICE, "%s: recovery map is not empty, but " - "must master $RECOVERY lock now\n", dlm->name); + mlog(0, "%s: Recovery map is not empty, but must " + "master $RECOVERY lock now\n", dlm->name); if (!dlm_pre_master_reco_lockres(dlm, res)) wait_on_recovery = 0; else { @@ -883,8 +883,8 @@ redo_request: spin_lock(&dlm->spinlock); bit = find_next_bit(dlm->recovery_map, O2NM_MAX_NODES, 0); if (bit < O2NM_MAX_NODES) { - mlog(ML_NOTICE, "%s:%.*s: at least one node (%d) to " - "recover before lock mastery can begin\n", + mlog(0, "%s: res %.*s, At least one node (%d) " + "to recover before lock mastery can begin\n", dlm->name, namelen, (char *)lockid, bit); wait_on_recovery = 1; } else @@ -913,8 +913,8 @@ redo_request: * yet, keep going until it does. this is how the * master will know that asserts are needed back to * the lower nodes. */ - mlog(0, "%s:%.*s: requests only up to %u but master " - "is %u, keep going\n", dlm->name, namelen, + mlog(0, "%s: res %.*s, Requests only up to %u but " + "master is %u, keep going\n", dlm->name, namelen, lockid, nodenum, mle->master); } } @@ -924,13 +924,12 @@ wait: ret = dlm_wait_for_lock_mastery(dlm, res, mle, &blocked); if (ret < 0) { wait_on_recovery = 1; - mlog(0, "%s:%.*s: node map changed, redo the " - "master request now, blocked=%d\n", - dlm->name, res->lockname.len, + mlog(0, "%s: res %.*s, Node map changed, redo the master " + "request now, blocked=%d\n", dlm->name, res->lockname.len, res->lockname.name, blocked); if (++tries > 20) { - mlog(ML_ERROR, "%s:%.*s: spinning on " - "dlm_wait_for_lock_mastery, blocked=%d\n", + mlog(ML_ERROR, "%s: res %.*s, Spinning on " + "dlm_wait_for_lock_mastery, blocked = %d\n", dlm->name, res->lockname.len, res->lockname.name, blocked); dlm_print_one_lock_resource(res); @@ -940,7 +939,8 @@ wait: goto redo_request; } - mlog(0, "lockres mastered by %u\n", res->owner); + mlog(0, "%s: res %.*s, Mastered by %u\n", dlm->name, res->lockname.len, + res->lockname.name, res->owner); /* make sure we never continue without this */ BUG_ON(res->owner == O2NM_MAX_NODES); @@ -2187,8 +2187,6 @@ int dlm_drop_lockres_ref(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) namelen = res->lockname.len; BUG_ON(namelen > O2NM_MAX_NAME_LEN); - mlog(0, "%s:%.*s: sending deref to %d\n", - dlm->name, namelen, lockname, res->owner); memset(&deref, 0, sizeof(deref)); deref.node_idx = dlm->node_num; deref.namelen = namelen; @@ -2197,14 +2195,12 @@ int dlm_drop_lockres_ref(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) ret = o2net_send_message(DLM_DEREF_LOCKRES_MSG, dlm->key, &deref, sizeof(deref), res->owner, &r); if (ret < 0) - mlog(ML_ERROR, "Error %d when sending message %u (key 0x%x) to " - "node %u\n", ret, DLM_DEREF_LOCKRES_MSG, dlm->key, - res->owner); + mlog(ML_ERROR, "%s: res %.*s, error %d send DEREF to node %u\n", + dlm->name, namelen, lockname, ret, res->owner); else if (r < 0) { /* BAD. other node says I did not have a ref. */ - mlog(ML_ERROR,"while dropping ref on %s:%.*s " - "(master=%u) got %d.\n", dlm->name, namelen, - lockname, res->owner, r); + mlog(ML_ERROR, "%s: res %.*s, DEREF to node %u got %d\n", + dlm->name, namelen, lockname, res->owner, r); dlm_print_one_lock_resource(res); BUG(); } @@ -2916,9 +2912,9 @@ static int dlm_do_migrate_request(struct dlm_ctxt *dlm, &migrate, sizeof(migrate), nodenum, &status); if (ret < 0) { - mlog(ML_ERROR, "Error %d when sending message %u (key " - "0x%x) to node %u\n", ret, DLM_MIGRATE_REQUEST_MSG, - dlm->key, nodenum); + mlog(ML_ERROR, "%s: res %.*s, Error %d send " + "MIGRATE_REQUEST to node %u\n", dlm->name, + migrate.namelen, migrate.name, ret, nodenum); if (!dlm_is_host_down(ret)) { mlog(ML_ERROR, "unhandled error=%d!\n", ret); BUG(); diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index 7efab6d..a3c312c 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c @@ -430,6 +430,8 @@ static void dlm_begin_recovery(struct dlm_ctxt *dlm) { spin_lock(&dlm->spinlock); BUG_ON(dlm->reco.state & DLM_RECO_STATE_ACTIVE); + printk(KERN_NOTICE "o2dlm: Begin recovery on domain %s for node %u\n", + dlm->name, dlm->reco.dead_node); dlm->reco.state |= DLM_RECO_STATE_ACTIVE; spin_unlock(&dlm->spinlock); } @@ -440,9 +442,18 @@ static void dlm_end_recovery(struct dlm_ctxt *dlm) BUG_ON(!(dlm->reco.state & DLM_RECO_STATE_ACTIVE)); dlm->reco.state &= ~DLM_RECO_STATE_ACTIVE; spin_unlock(&dlm->spinlock); + printk(KERN_NOTICE "o2dlm: End recovery on domain %s\n", dlm->name); wake_up(&dlm->reco.event); } +static void dlm_print_recovery_master(struct dlm_ctxt *dlm) +{ + printk(KERN_NOTICE "o2dlm: Node %u (%s) is the Recovery Master for the " + "dead node %u in domain %s\n", dlm->reco.new_master, + (dlm->node_num == dlm->reco.new_master ? "me" : "he"), + dlm->reco.dead_node, dlm->name); +} + static int dlm_do_recovery(struct dlm_ctxt *dlm) { int status = 0; @@ -505,9 +516,8 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm) } mlog(0, "another node will master this recovery session.\n"); } - mlog(0, "dlm=%s (%d), new_master=%u, this node=%u, dead_node=%u\n", - dlm->name, task_pid_nr(dlm->dlm_reco_thread_task), dlm->reco.new_master, - dlm->node_num, dlm->reco.dead_node); + + dlm_print_recovery_master(dlm); /* it is safe to start everything back up here * because all of the dead node's lock resources @@ -518,15 +528,13 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm) return 0; master_here: - mlog(ML_NOTICE, "(%d) Node %u is the Recovery Master for the Dead Node " - "%u for Domain %s\n", task_pid_nr(dlm->dlm_reco_thread_task), - dlm->node_num, dlm->reco.dead_node, dlm->name); + dlm_print_recovery_master(dlm); status = dlm_remaster_locks(dlm, dlm->reco.dead_node); if (status < 0) { /* we should never hit this anymore */ - mlog(ML_ERROR, "error %d remastering locks for node %u, " - "retrying.\n", status, dlm->reco.dead_node); + mlog(ML_ERROR, "%s: Error %d remastering locks for node %u, " + "retrying.\n", dlm->name, status, dlm->reco.dead_node); /* yield a bit to allow any final network messages * to get handled on remaining nodes */ msleep(100); @@ -567,7 +575,7 @@ static int dlm_remaster_locks(struct dlm_ctxt *dlm, u8 dead_node) BUG_ON(ndata->state != DLM_RECO_NODE_DATA_INIT); ndata->state = DLM_RECO_NODE_DATA_REQUESTING; - mlog(0, "requesting lock info from node %u\n", + mlog(0, "%s: Requesting lock info from node %u\n", dlm->name, ndata->node_num); if (ndata->node_num == dlm->node_num) { @@ -640,7 +648,7 @@ static int dlm_remaster_locks(struct dlm_ctxt *dlm, u8 dead_node) spin_unlock(&dlm_reco_state_lock); } - mlog(0, "done requesting all lock info\n"); + mlog(0, "%s: Done requesting all lock info\n", dlm->name); /* nodes should be sending reco data now * just need to wait */ @@ -802,10 +810,9 @@ static int dlm_request_all_locks(struct dlm_ctxt *dlm, u8 request_from, /* negative status is handled by caller */ if (ret < 0) - mlog(ML_ERROR, "Error %d when sending message %u (key " - "0x%x) to node %u\n", ret, DLM_LOCK_REQUEST_MSG, - dlm->key, request_from); - + mlog(ML_ERROR, "%s: Error %d send LOCK_REQUEST to node %u " + "to recover dead node %u\n", dlm->name, ret, + request_from, dead_node); // return from here, then // sleep until all received or error return ret; @@ -956,9 +963,9 @@ static int dlm_send_all_done_msg(struct dlm_ctxt *dlm, u8 dead_node, u8 send_to) ret = o2net_send_message(DLM_RECO_DATA_DONE_MSG, dlm->key, &done_msg, sizeof(done_msg), send_to, &tmpret); if (ret < 0) { - mlog(ML_ERROR, "Error %d when sending message %u (key " - "0x%x) to node %u\n", ret, DLM_RECO_DATA_DONE_MSG, - dlm->key, send_to); + mlog(ML_ERROR, "%s: Error %d send RECO_DATA_DONE to node %u " + "to recover dead node %u\n", dlm->name, ret, send_to, + dead_node); if (!dlm_is_host_down(ret)) { BUG(); } @@ -1127,9 +1134,11 @@ static int dlm_send_mig_lockres_msg(struct dlm_ctxt *dlm, if (ret < 0) { /* XXX: negative status is not handled. * this will end up killing this node. */ - mlog(ML_ERROR, "Error %d when sending message %u (key " - "0x%x) to node %u\n", ret, DLM_MIG_LOCKRES_MSG, - dlm->key, send_to); + mlog(ML_ERROR, "%s: res %.*s, Error %d send MIG_LOCKRES to " + "node %u (%s)\n", dlm->name, mres->lockname_len, + mres->lockname, ret, send_to, + (orig_flags & DLM_MRES_MIGRATION ? + "migration" : "recovery")); } else { /* might get an -ENOMEM back here */ ret = status; @@ -2324,9 +2333,9 @@ static void dlm_do_local_recovery_cleanup(struct dlm_ctxt *dlm, u8 dead_node) dlm_revalidate_lvb(dlm, res, dead_node); if (res->owner == dead_node) { if (res->state & DLM_LOCK_RES_DROPPING_REF) { - mlog(ML_NOTICE, "Ignore %.*s for " + mlog(ML_NOTICE, "%s: res %.*s, Skip " "recovery as it is being freed\n", - res->lockname.len, + dlm->name, res->lockname.len, res->lockname.name); } else dlm_move_lockres_to_recovery_list(dlm, diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c index 1d6d1d2..46faac2 100644 --- a/fs/ocfs2/dlm/dlmthread.c +++ b/fs/ocfs2/dlm/dlmthread.c @@ -185,8 +185,6 @@ static void dlm_purge_lockres(struct dlm_ctxt *dlm, /* clear our bit from the master's refmap, ignore errors */ ret = dlm_drop_lockres_ref(dlm, res); if (ret < 0) { - mlog(ML_ERROR, "%s: deref %.*s failed %d\n", dlm->name, - res->lockname.len, res->lockname.name, ret); if (!dlm_is_host_down(ret)) BUG(); } -- cgit v1.1 From 394eb3d38a3ecc549cc34a3040103a9164be516b Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Sun, 24 Jul 2011 10:24:54 -0700 Subject: ocfs2: Clean up messages in stack_o2cb.c o2cb messages needed a facelift. Signed-off-by: Sunil Mushran --- fs/ocfs2/stack_o2cb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/stack_o2cb.c b/fs/ocfs2/stack_o2cb.c index 19965b0..be935d8 100644 --- a/fs/ocfs2/stack_o2cb.c +++ b/fs/ocfs2/stack_o2cb.c @@ -263,8 +263,8 @@ static void o2dlm_eviction_cb(int node_num, void *data) { struct ocfs2_cluster_connection *conn = data; - mlog(ML_NOTICE, "o2dlm has evicted node %d from group %.*s\n", - node_num, conn->cc_namelen, conn->cc_name); + printk(KERN_NOTICE "o2cb: o2dlm has evicted node %d from domain %.*s\n", + node_num, conn->cc_namelen, conn->cc_name); conn->cc_recovery_handler(node_num, conn->cc_recovery_data); } -- cgit v1.1 From 0afbba13226fcdbd4327f6b13a42f6efbb8c9caf Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Sun, 24 Jul 2011 10:25:54 -0700 Subject: ocfs2/dlm: Cleanup up dlm_finish_local_lockres_recovery() dlm_finish_local_lockres_recovery() needed a facelift. Signed-off-by: Sunil Mushran --- fs/ocfs2/dlm/dlmrecovery.c | 57 ++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index a3c312c..41e74f0 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c @@ -2093,6 +2093,9 @@ static void dlm_finish_local_lockres_recovery(struct dlm_ctxt *dlm, list_for_each_entry_safe(res, next, &dlm->reco.resources, recovering) { if (res->owner == dead_node) { + mlog(0, "%s: res %.*s, Changing owner from %u to %u\n", + dlm->name, res->lockname.len, res->lockname.name, + res->owner, new_master); list_del_init(&res->recovering); spin_lock(&res->spinlock); /* new_master has our reference from @@ -2114,40 +2117,30 @@ static void dlm_finish_local_lockres_recovery(struct dlm_ctxt *dlm, for (i = 0; i < DLM_HASH_BUCKETS; i++) { bucket = dlm_lockres_hash(dlm, i); hlist_for_each_entry(res, hash_iter, bucket, hash_node) { - if (res->state & DLM_LOCK_RES_RECOVERING) { - if (res->owner == dead_node) { - mlog(0, "(this=%u) res %.*s owner=%u " - "was not on recovering list, but " - "clearing state anyway\n", - dlm->node_num, res->lockname.len, - res->lockname.name, new_master); - } else if (res->owner == dlm->node_num) { - mlog(0, "(this=%u) res %.*s owner=%u " - "was not on recovering list, " - "owner is THIS node, clearing\n", - dlm->node_num, res->lockname.len, - res->lockname.name, new_master); - } else - continue; + if (!(res->state & DLM_LOCK_RES_RECOVERING)) + continue; - if (!list_empty(&res->recovering)) { - mlog(0, "%s:%.*s: lockres was " - "marked RECOVERING, owner=%u\n", - dlm->name, res->lockname.len, - res->lockname.name, res->owner); - list_del_init(&res->recovering); - dlm_lockres_put(res); - } - spin_lock(&res->spinlock); - /* new_master has our reference from - * the lock state sent during recovery */ - dlm_change_lockres_owner(dlm, res, new_master); - res->state &= ~DLM_LOCK_RES_RECOVERING; - if (__dlm_lockres_has_locks(res)) - __dlm_dirty_lockres(dlm, res); - spin_unlock(&res->spinlock); - wake_up(&res->wq); + if (res->owner != dead_node && + res->owner != dlm->node_num) + continue; + + if (!list_empty(&res->recovering)) { + list_del_init(&res->recovering); + dlm_lockres_put(res); } + + /* new_master has our reference from + * the lock state sent during recovery */ + mlog(0, "%s: res %.*s, Changing owner from %u to %u\n", + dlm->name, res->lockname.len, res->lockname.name, + res->owner, new_master); + spin_lock(&res->spinlock); + dlm_change_lockres_owner(dlm, res, new_master); + res->state &= ~DLM_LOCK_RES_RECOVERING; + if (__dlm_lockres_has_locks(res)) + __dlm_dirty_lockres(dlm, res); + spin_unlock(&res->spinlock); + wake_up(&res->wq); } } } -- cgit v1.1 From 8d400b81cc83b171ff872587723a37eb7fae9abe Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Sun, 24 Jul 2011 10:26:54 -0700 Subject: ocfs2/dlm: Clean up refmap helpers Patch cleans up helpers that set/clear refmap bits and grab/drop inflight lock ref counts. Signed-off-by: Sunil Mushran --- fs/ocfs2/dlm/dlmcommon.h | 49 +++++--------------------- fs/ocfs2/dlm/dlmmaster.c | 88 ++++++++++++++++++++++++++++------------------ fs/ocfs2/dlm/dlmrecovery.c | 8 ++--- 3 files changed, 66 insertions(+), 79 deletions(-) diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index d602abb..4a5d580 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h @@ -902,46 +902,15 @@ struct dlm_lock_resource *dlm_new_lockres(struct dlm_ctxt *dlm, const char *name, unsigned int namelen); -#define dlm_lockres_set_refmap_bit(bit,res) \ - __dlm_lockres_set_refmap_bit(bit,res,__FILE__,__LINE__) -#define dlm_lockres_clear_refmap_bit(bit,res) \ - __dlm_lockres_clear_refmap_bit(bit,res,__FILE__,__LINE__) - -static inline void __dlm_lockres_set_refmap_bit(int bit, - struct dlm_lock_resource *res, - const char *file, - int line) -{ - //printk("%s:%d:%.*s: setting bit %d\n", file, line, - // res->lockname.len, res->lockname.name, bit); - set_bit(bit, res->refmap); -} - -static inline void __dlm_lockres_clear_refmap_bit(int bit, - struct dlm_lock_resource *res, - const char *file, - int line) -{ - //printk("%s:%d:%.*s: clearing bit %d\n", file, line, - // res->lockname.len, res->lockname.name, bit); - clear_bit(bit, res->refmap); -} - -void __dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm, - struct dlm_lock_resource *res, - const char *file, - int line); -void __dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm, - struct dlm_lock_resource *res, - int new_lockres, - const char *file, - int line); -#define dlm_lockres_drop_inflight_ref(d,r) \ - __dlm_lockres_drop_inflight_ref(d,r,__FILE__,__LINE__) -#define dlm_lockres_grab_inflight_ref(d,r) \ - __dlm_lockres_grab_inflight_ref(d,r,0,__FILE__,__LINE__) -#define dlm_lockres_grab_inflight_ref_new(d,r) \ - __dlm_lockres_grab_inflight_ref(d,r,1,__FILE__,__LINE__) +void dlm_lockres_set_refmap_bit(struct dlm_ctxt *dlm, + struct dlm_lock_resource *res, int bit); +void dlm_lockres_clear_refmap_bit(struct dlm_ctxt *dlm, + struct dlm_lock_resource *res, int bit); + +void dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm, + struct dlm_lock_resource *res); +void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm, + struct dlm_lock_resource *res); void dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock); void dlm_queue_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock); diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 9f3b093..11e446ff 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -631,39 +631,58 @@ error: return NULL; } -void __dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm, - struct dlm_lock_resource *res, - int new_lockres, - const char *file, - int line) +void dlm_lockres_set_refmap_bit(struct dlm_ctxt *dlm, + struct dlm_lock_resource *res, int bit) { - if (!new_lockres) - assert_spin_locked(&res->spinlock); + assert_spin_locked(&res->spinlock); + + mlog(0, "res %.*s, set node %u, %ps()\n", res->lockname.len, + res->lockname.name, bit, __builtin_return_address(0)); + + set_bit(bit, res->refmap); +} + +void dlm_lockres_clear_refmap_bit(struct dlm_ctxt *dlm, + struct dlm_lock_resource *res, int bit) +{ + assert_spin_locked(&res->spinlock); + + mlog(0, "res %.*s, clr node %u, %ps()\n", res->lockname.len, + res->lockname.name, bit, __builtin_return_address(0)); + + clear_bit(bit, res->refmap); +} + + +void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm, + struct dlm_lock_resource *res) +{ + assert_spin_locked(&res->spinlock); if (!test_bit(dlm->node_num, res->refmap)) { BUG_ON(res->inflight_locks != 0); - dlm_lockres_set_refmap_bit(dlm->node_num, res); + dlm_lockres_set_refmap_bit(dlm, res, dlm->node_num); } res->inflight_locks++; - mlog(0, "%s:%.*s: inflight++: now %u\n", - dlm->name, res->lockname.len, res->lockname.name, - res->inflight_locks); + mlog(0, "%s: res %.*s, inflight++: now %u, %ps()\n", dlm->name, + res->lockname.len, res->lockname.name, res->inflight_locks, + __builtin_return_address(0)); } -void __dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm, - struct dlm_lock_resource *res, - const char *file, - int line) +void dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm, + struct dlm_lock_resource *res) { assert_spin_locked(&res->spinlock); BUG_ON(res->inflight_locks == 0); + res->inflight_locks--; - mlog(0, "%s:%.*s: inflight--: now %u\n", - dlm->name, res->lockname.len, res->lockname.name, - res->inflight_locks); + mlog(0, "%s: res %.*s, inflight--: now %u, %ps()\n", dlm->name, + res->lockname.len, res->lockname.name, res->inflight_locks, + __builtin_return_address(0)); + if (res->inflight_locks == 0) - dlm_lockres_clear_refmap_bit(dlm->node_num, res); + dlm_lockres_clear_refmap_bit(dlm, res, dlm->node_num); wake_up(&res->wq); } @@ -843,8 +862,10 @@ lookup: /* finally add the lockres to its hash bucket */ __dlm_insert_lockres(dlm, res); - /* since this lockres is new it doesn't not require the spinlock */ - dlm_lockres_grab_inflight_ref_new(dlm, res); + + spin_lock(&res->spinlock); + dlm_lockres_grab_inflight_ref(dlm, res); + spin_unlock(&res->spinlock); /* if this node does not become the master make sure to drop * this inflight reference below */ @@ -1426,9 +1447,7 @@ way_up_top: } if (res->owner == dlm->node_num) { - mlog(0, "%s:%.*s: setting bit %u in refmap\n", - dlm->name, namelen, name, request->node_idx); - dlm_lockres_set_refmap_bit(request->node_idx, res); + dlm_lockres_set_refmap_bit(dlm, res, request->node_idx); spin_unlock(&res->spinlock); response = DLM_MASTER_RESP_YES; if (mle) @@ -1493,10 +1512,8 @@ way_up_top: * go back and clean the mles on any * other nodes */ dispatch_assert = 1; - dlm_lockres_set_refmap_bit(request->node_idx, res); - mlog(0, "%s:%.*s: setting bit %u in refmap\n", - dlm->name, namelen, name, - request->node_idx); + dlm_lockres_set_refmap_bit(dlm, res, + request->node_idx); } else response = DLM_MASTER_RESP_NO; } else { @@ -1702,7 +1719,7 @@ again: "lockres, set the bit in the refmap\n", namelen, lockname, to); spin_lock(&res->spinlock); - dlm_lockres_set_refmap_bit(to, res); + dlm_lockres_set_refmap_bit(dlm, res, to); spin_unlock(&res->spinlock); } } @@ -2256,7 +2273,7 @@ int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data, else { BUG_ON(res->state & DLM_LOCK_RES_DROPPING_REF); if (test_bit(node, res->refmap)) { - dlm_lockres_clear_refmap_bit(node, res); + dlm_lockres_clear_refmap_bit(dlm, res, node); cleared = 1; } } @@ -2316,7 +2333,7 @@ static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data) BUG_ON(res->state & DLM_LOCK_RES_DROPPING_REF); if (test_bit(node, res->refmap)) { __dlm_wait_on_lockres_flags(res, DLM_LOCK_RES_SETREF_INPROG); - dlm_lockres_clear_refmap_bit(node, res); + dlm_lockres_clear_refmap_bit(dlm, res, node); cleared = 1; } spin_unlock(&res->spinlock); @@ -2798,7 +2815,8 @@ static void dlm_remove_nonlocal_locks(struct dlm_ctxt *dlm, BUG_ON(!list_empty(&lock->bast_list)); BUG_ON(lock->ast_pending); BUG_ON(lock->bast_pending); - dlm_lockres_clear_refmap_bit(lock->ml.node, res); + dlm_lockres_clear_refmap_bit(dlm, res, + lock->ml.node); list_del_init(&lock->list); dlm_lock_put(lock); /* In a normal unlock, we would have added a @@ -2819,7 +2837,7 @@ static void dlm_remove_nonlocal_locks(struct dlm_ctxt *dlm, mlog(0, "%s:%.*s: node %u had a ref to this " "migrating lockres, clearing\n", dlm->name, res->lockname.len, res->lockname.name, bit); - dlm_lockres_clear_refmap_bit(bit, res); + dlm_lockres_clear_refmap_bit(dlm, res, bit); } bit++; } @@ -2933,7 +2951,7 @@ static int dlm_do_migrate_request(struct dlm_ctxt *dlm, dlm->name, res->lockname.len, res->lockname.name, nodenum); spin_lock(&res->spinlock); - dlm_lockres_set_refmap_bit(nodenum, res); + dlm_lockres_set_refmap_bit(dlm, res, nodenum); spin_unlock(&res->spinlock); } } @@ -3267,7 +3285,7 @@ int dlm_finish_migration(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, * mastery reference here since old_master will briefly have * a reference after the migration completes */ spin_lock(&res->spinlock); - dlm_lockres_set_refmap_bit(old_master, res); + dlm_lockres_set_refmap_bit(dlm, res, old_master); spin_unlock(&res->spinlock); mlog(0, "now time to do a migrate request to other nodes\n"); diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index 41e74f0..f1a3aa8 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c @@ -1776,7 +1776,7 @@ static int dlm_process_recovery_data(struct dlm_ctxt *dlm, dlm->name, mres->lockname_len, mres->lockname, from); spin_lock(&res->spinlock); - dlm_lockres_set_refmap_bit(from, res); + dlm_lockres_set_refmap_bit(dlm, res, from); spin_unlock(&res->spinlock); added++; break; @@ -1974,7 +1974,7 @@ skip_lvb: mlog(0, "%s:%.*s: added lock for node %u, " "setting refmap bit\n", dlm->name, res->lockname.len, res->lockname.name, ml->node); - dlm_lockres_set_refmap_bit(ml->node, res); + dlm_lockres_set_refmap_bit(dlm, res, ml->node); added++; } spin_unlock(&res->spinlock); @@ -2254,12 +2254,12 @@ static void dlm_free_dead_locks(struct dlm_ctxt *dlm, res->lockname.len, res->lockname.name, freed, dead_node); __dlm_print_one_lock_resource(res); } - dlm_lockres_clear_refmap_bit(dead_node, res); + dlm_lockres_clear_refmap_bit(dlm, res, dead_node); } else if (test_bit(dead_node, res->refmap)) { mlog(0, "%s:%.*s: dead node %u had a ref, but had " "no locks and had not purged before dying\n", dlm->name, res->lockname.len, res->lockname.name, dead_node); - dlm_lockres_clear_refmap_bit(dead_node, res); + dlm_lockres_clear_refmap_bit(dlm, res, dead_node); } /* do not kick thread yet */ -- cgit v1.1 From e9f0b6a6233105c188064328c3f15e21942d0241 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Sun, 24 Jul 2011 10:27:54 -0700 Subject: ocfs2/dlm: Trace insert/remove of resource to/from hash Add mlog to trace adding and removing the resource from/to the hash table. Signed-off-by: Sunil Mushran --- fs/ocfs2/dlm/dlmcommon.h | 5 ++--- fs/ocfs2/dlm/dlmdomain.c | 19 ++++++++++++------- fs/ocfs2/dlm/dlmthread.c | 2 +- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index 4a5d580..b1748ac 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h @@ -877,9 +877,8 @@ static inline void dlm_lockres_get(struct dlm_lock_resource *res) kref_get(&res->refs); } void dlm_lockres_put(struct dlm_lock_resource *res); -void __dlm_unhash_lockres(struct dlm_lock_resource *res); -void __dlm_insert_lockres(struct dlm_ctxt *dlm, - struct dlm_lock_resource *res); +void __dlm_unhash_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res); +void __dlm_insert_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res); struct dlm_lock_resource * __dlm_lookup_lockres_full(struct dlm_ctxt *dlm, const char *name, unsigned int len, diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index ce225fb..200d988 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c @@ -157,16 +157,18 @@ static int dlm_protocol_compare(struct dlm_protocol_version *existing, static void dlm_unregister_domain_handlers(struct dlm_ctxt *dlm); -void __dlm_unhash_lockres(struct dlm_lock_resource *lockres) +void __dlm_unhash_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) { - if (!hlist_unhashed(&lockres->hash_node)) { - hlist_del_init(&lockres->hash_node); - dlm_lockres_put(lockres); - } + if (hlist_unhashed(&res->hash_node)) + return; + + mlog(0, "%s: Unhash res %.*s\n", dlm->name, res->lockname.len, + res->lockname.name); + hlist_del_init(&res->hash_node); + dlm_lockres_put(res); } -void __dlm_insert_lockres(struct dlm_ctxt *dlm, - struct dlm_lock_resource *res) +void __dlm_insert_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) { struct hlist_head *bucket; struct qstr *q; @@ -180,6 +182,9 @@ void __dlm_insert_lockres(struct dlm_ctxt *dlm, dlm_lockres_get(res); hlist_add_head(&res->hash_node, bucket); + + mlog(0, "%s: Hash res %.*s\n", dlm->name, res->lockname.len, + res->lockname.name); } struct dlm_lock_resource * __dlm_lookup_lockres_full(struct dlm_ctxt *dlm, diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c index 46faac2..4eff65e 100644 --- a/fs/ocfs2/dlm/dlmthread.c +++ b/fs/ocfs2/dlm/dlmthread.c @@ -207,7 +207,7 @@ static void dlm_purge_lockres(struct dlm_ctxt *dlm, BUG(); } - __dlm_unhash_lockres(res); + __dlm_unhash_lockres(dlm, res); /* lockres is not in the hash now. drop the flag and wake up * any processes waiting in dlm_get_lock_resource. */ -- cgit v1.1 From ed8625c6fb93d750ed022db571a8a7b7a6724b3b Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Sun, 24 Jul 2011 10:28:54 -0700 Subject: ocfs2/dlm: Cleanup dlm_wait_for_node_death() and dlm_wait_for_node_recovery() dlm_wait_for_node_death() and dlm_wait_for_node_recovery() needed a facelift. Signed-off-by: Sunil Mushran --- fs/ocfs2/dlm/dlmcommon.h | 4 ++-- fs/ocfs2/dlm/dlmrecovery.c | 46 ++++++++++++++++++++++------------------------ 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index b1748ac..a5952ce 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h @@ -859,8 +859,8 @@ void dlm_complete_recovery_thread(struct dlm_ctxt *dlm); void dlm_wait_for_recovery(struct dlm_ctxt *dlm); void dlm_kick_recovery_thread(struct dlm_ctxt *dlm); int dlm_is_node_dead(struct dlm_ctxt *dlm, u8 node); -int dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout); -int dlm_wait_for_node_recovery(struct dlm_ctxt *dlm, u8 node, int timeout); +void dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout); +void dlm_wait_for_node_recovery(struct dlm_ctxt *dlm, u8 node, int timeout); void dlm_put(struct dlm_ctxt *dlm); struct dlm_ctxt *dlm_grab(struct dlm_ctxt *dlm); diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index f1a3aa8..01ebfd0 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c @@ -362,40 +362,38 @@ static int dlm_is_node_recovered(struct dlm_ctxt *dlm, u8 node) } -int dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout) +void dlm_wait_for_node_death(struct dlm_ctxt *dlm, u8 node, int timeout) { - if (timeout) { - mlog(ML_NOTICE, "%s: waiting %dms for notification of " - "death of node %u\n", dlm->name, timeout, node); + if (dlm_is_node_dead(dlm, node)) + return; + + printk(KERN_NOTICE "o2dlm: Waiting on the death of node %u in " + "domain %s\n", node, dlm->name); + + if (timeout) wait_event_timeout(dlm->dlm_reco_thread_wq, - dlm_is_node_dead(dlm, node), - msecs_to_jiffies(timeout)); - } else { - mlog(ML_NOTICE, "%s: waiting indefinitely for notification " - "of death of node %u\n", dlm->name, node); + dlm_is_node_dead(dlm, node), + msecs_to_jiffies(timeout)); + else wait_event(dlm->dlm_reco_thread_wq, dlm_is_node_dead(dlm, node)); - } - /* for now, return 0 */ - return 0; } -int dlm_wait_for_node_recovery(struct dlm_ctxt *dlm, u8 node, int timeout) +void dlm_wait_for_node_recovery(struct dlm_ctxt *dlm, u8 node, int timeout) { - if (timeout) { - mlog(0, "%s: waiting %dms for notification of " - "recovery of node %u\n", dlm->name, timeout, node); + if (dlm_is_node_recovered(dlm, node)) + return; + + printk(KERN_NOTICE "o2dlm: Waiting on the recovery of node %u in " + "domain %s\n", node, dlm->name); + + if (timeout) wait_event_timeout(dlm->dlm_reco_thread_wq, - dlm_is_node_recovered(dlm, node), - msecs_to_jiffies(timeout)); - } else { - mlog(0, "%s: waiting indefinitely for notification " - "of recovery of node %u\n", dlm->name, node); + dlm_is_node_recovered(dlm, node), + msecs_to_jiffies(timeout)); + else wait_event(dlm->dlm_reco_thread_wq, dlm_is_node_recovered(dlm, node)); - } - /* for now, return 0 */ - return 0; } /* callers of the top-level api calls (dlmlock/dlmunlock) should -- cgit v1.1 From ff0a522e7db79625aa27a433467eb94c5e255718 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Sun, 24 Jul 2011 10:29:54 -0700 Subject: ocfs2/dlm: Take inflight reference count for remotely mastered resources too The inflight reference count, in the lock resource, is taken to pin the resource in memory. We take it when a new resource is created and release it after a lock is attached to it. We do this to prevent the resource from getting purged prematurely. Earlier this reference count was being taken for locally mastered resources only. This patch extends the same functionality for remotely mastered ones. We are doing this because the same premature purging could occur for remotely mastered resources if the remote node were to die before completion of the create lock. Fix for Oracle bug#12405575. Signed-off-by: Sunil Mushran --- fs/ocfs2/dlm/dlmlock.c | 12 ++++++++---- fs/ocfs2/dlm/dlmmaster.c | 47 +++++++++++++++++------------------------------ fs/ocfs2/dlm/dlmthread.c | 12 +++++++----- 3 files changed, 32 insertions(+), 39 deletions(-) diff --git a/fs/ocfs2/dlm/dlmlock.c b/fs/ocfs2/dlm/dlmlock.c index c7f3e22..3ef2c1a 100644 --- a/fs/ocfs2/dlm/dlmlock.c +++ b/fs/ocfs2/dlm/dlmlock.c @@ -183,10 +183,6 @@ static enum dlm_status dlmlock_master(struct dlm_ctxt *dlm, kick_thread = 1; } } - /* reduce the inflight count, this may result in the lockres - * being purged below during calc_usage */ - if (lock->ml.node == dlm->node_num) - dlm_lockres_drop_inflight_ref(dlm, res); spin_unlock(&res->spinlock); wake_up(&res->wq); @@ -737,6 +733,14 @@ retry_lock: } } + /* Inflight taken in dlm_get_lock_resource() is dropped here */ + spin_lock(&res->spinlock); + dlm_lockres_drop_inflight_ref(dlm, res); + spin_unlock(&res->spinlock); + + dlm_lockres_calc_usage(dlm, res); + dlm_kick_thread(dlm, res); + if (status != DLM_NORMAL) { lock->lksb->flags &= ~DLM_LKSB_GET_LVB; if (status != DLM_NOTQUEUED) diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 11e446ff..005261c 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -659,11 +659,8 @@ void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm, { assert_spin_locked(&res->spinlock); - if (!test_bit(dlm->node_num, res->refmap)) { - BUG_ON(res->inflight_locks != 0); - dlm_lockres_set_refmap_bit(dlm, res, dlm->node_num); - } res->inflight_locks++; + mlog(0, "%s: res %.*s, inflight++: now %u, %ps()\n", dlm->name, res->lockname.len, res->lockname.name, res->inflight_locks, __builtin_return_address(0)); @@ -677,12 +674,11 @@ void dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm, BUG_ON(res->inflight_locks == 0); res->inflight_locks--; + mlog(0, "%s: res %.*s, inflight--: now %u, %ps()\n", dlm->name, res->lockname.len, res->lockname.name, res->inflight_locks, __builtin_return_address(0)); - if (res->inflight_locks == 0) - dlm_lockres_clear_refmap_bit(dlm, res, dlm->node_num); wake_up(&res->wq); } @@ -716,7 +712,6 @@ struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm, unsigned int hash; int tries = 0; int bit, wait_on_recovery = 0; - int drop_inflight_if_nonlocal = 0; BUG_ON(!lockid); @@ -728,36 +723,33 @@ lookup: spin_lock(&dlm->spinlock); tmpres = __dlm_lookup_lockres_full(dlm, lockid, namelen, hash); if (tmpres) { - int dropping_ref = 0; - spin_unlock(&dlm->spinlock); - spin_lock(&tmpres->spinlock); - /* We wait for the other thread that is mastering the resource */ + /* Wait on the thread that is mastering the resource */ if (tmpres->owner == DLM_LOCK_RES_OWNER_UNKNOWN) { __dlm_wait_on_lockres(tmpres); BUG_ON(tmpres->owner == DLM_LOCK_RES_OWNER_UNKNOWN); + spin_unlock(&tmpres->spinlock); + dlm_lockres_put(tmpres); + tmpres = NULL; + goto lookup; } - if (tmpres->owner == dlm->node_num) { - BUG_ON(tmpres->state & DLM_LOCK_RES_DROPPING_REF); - dlm_lockres_grab_inflight_ref(dlm, tmpres); - } else if (tmpres->state & DLM_LOCK_RES_DROPPING_REF) - dropping_ref = 1; - spin_unlock(&tmpres->spinlock); - - /* wait until done messaging the master, drop our ref to allow - * the lockres to be purged, start over. */ - if (dropping_ref) { - spin_lock(&tmpres->spinlock); - __dlm_wait_on_lockres_flags(tmpres, DLM_LOCK_RES_DROPPING_REF); + /* Wait on the resource purge to complete before continuing */ + if (tmpres->state & DLM_LOCK_RES_DROPPING_REF) { + BUG_ON(tmpres->owner == dlm->node_num); + __dlm_wait_on_lockres_flags(tmpres, + DLM_LOCK_RES_DROPPING_REF); spin_unlock(&tmpres->spinlock); dlm_lockres_put(tmpres); tmpres = NULL; goto lookup; } - mlog(0, "found in hash!\n"); + /* Grab inflight ref to pin the resource */ + dlm_lockres_grab_inflight_ref(dlm, tmpres); + + spin_unlock(&tmpres->spinlock); if (res) dlm_lockres_put(res); res = tmpres; @@ -863,14 +855,11 @@ lookup: /* finally add the lockres to its hash bucket */ __dlm_insert_lockres(dlm, res); + /* Grab inflight ref to pin the resource */ spin_lock(&res->spinlock); dlm_lockres_grab_inflight_ref(dlm, res); spin_unlock(&res->spinlock); - /* if this node does not become the master make sure to drop - * this inflight reference below */ - drop_inflight_if_nonlocal = 1; - /* get an extra ref on the mle in case this is a BLOCK * if so, the creator of the BLOCK may try to put the last * ref at this time in the assert master handler, so we @@ -973,8 +962,6 @@ wait: wake_waiters: spin_lock(&res->spinlock); - if (res->owner != dlm->node_num && drop_inflight_if_nonlocal) - dlm_lockres_drop_inflight_ref(dlm, res); res->state &= ~DLM_LOCK_RES_IN_PROGRESS; spin_unlock(&res->spinlock); wake_up(&res->wq); diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c index 4eff65e..e73c833 100644 --- a/fs/ocfs2/dlm/dlmthread.c +++ b/fs/ocfs2/dlm/dlmthread.c @@ -94,24 +94,26 @@ int __dlm_lockres_unused(struct dlm_lock_resource *res) { int bit; + assert_spin_locked(&res->spinlock); + if (__dlm_lockres_has_locks(res)) return 0; + /* Locks are in the process of being created */ + if (res->inflight_locks) + return 0; + if (!list_empty(&res->dirty) || res->state & DLM_LOCK_RES_DIRTY) return 0; if (res->state & DLM_LOCK_RES_RECOVERING) return 0; + /* Another node has this resource with this node as the master */ bit = find_next_bit(res->refmap, O2NM_MAX_NODES, 0); if (bit < O2NM_MAX_NODES) return 0; - /* - * since the bit for dlm->node_num is not set, inflight_locks better - * be zero - */ - BUG_ON(res->inflight_locks != 0); return 1; } -- cgit v1.1 From a2c0cc1579176bd0808ef7deea456767dfa80217 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Sun, 24 Jul 2011 10:30:54 -0700 Subject: ocfs2/dlm: dlmlock_remote() needs to account for remastery In dlmlock_remote(), we wait for the resource to stop being active before setting the inprogress flag. Active includes recovery, migration, etc. The problem here is that if the resource was being recovered or migrated, the new owner could very well be that node itself (and thus not a remote node). This problem was observed in Oracle bug#12583620. The error messages observed were as follows: dlm_send_remote_lock_request:337 ERROR: Error -40 (ELOOP) when sending message 503 (key 0xd6d8c7) to node 2 dlmlock_remote:271 ERROR: dlm status = DLM_BADARGS dlmlock:751 ERROR: dlm status = DLM_BADARGS Signed-off-by: Sunil Mushran --- fs/ocfs2/dlm/dlmlock.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/fs/ocfs2/dlm/dlmlock.c b/fs/ocfs2/dlm/dlmlock.c index 3ef2c1a..f32fcba 100644 --- a/fs/ocfs2/dlm/dlmlock.c +++ b/fs/ocfs2/dlm/dlmlock.c @@ -227,10 +227,16 @@ static enum dlm_status dlmlock_remote(struct dlm_ctxt *dlm, lock->ml.type, res->lockname.len, res->lockname.name, flags); + /* + * Wait if resource is getting recovered, remastered, etc. + * If the resource was remastered and new owner is self, then exit. + */ spin_lock(&res->spinlock); - - /* will exit this call with spinlock held */ __dlm_wait_on_lockres(res); + if (res->owner == dlm->node_num) { + spin_unlock(&res->spinlock); + return DLM_RECOVERING; + } res->state |= DLM_LOCK_RES_IN_PROGRESS; /* add lock to local (secondary) queue */ @@ -710,18 +716,10 @@ retry_lock: if (status == DLM_RECOVERING || status == DLM_MIGRATING || status == DLM_FORWARD) { - mlog(0, "retrying lock with migration/" - "recovery/in progress\n"); msleep(100); - /* no waiting for dlm_reco_thread */ if (recovery) { if (status != DLM_RECOVERING) goto retry_lock; - - mlog(0, "%s: got RECOVERING " - "for $RECOVERY lock, master " - "was %u\n", dlm->name, - res->owner); /* wait to see the node go down, then * drop down and allow the lockres to * get cleaned up. need to remaster. */ -- cgit v1.1 From bb570a5d9e74f71d32751823052db4a97d6a5e7c Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Sun, 24 Jul 2011 10:31:54 -0700 Subject: ocfs2/cluster: Fix output in file elapsed_time_in_ms The o2hb debugfs file, elapsed_time_in_ms, should return values only after the timer is armed atleast once. Signed-off-by: Sunil Mushran --- fs/ocfs2/cluster/heartbeat.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 4728a74..a4e855e 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c @@ -1198,6 +1198,7 @@ static int o2hb_debug_open(struct inode *inode, struct file *file) struct o2hb_debug_buf *db = inode->i_private; struct o2hb_region *reg; unsigned long map[BITS_TO_LONGS(O2NM_MAX_NODES)]; + unsigned long lts; char *buf = NULL; int i = -1; int out = 0; @@ -1234,9 +1235,11 @@ static int o2hb_debug_open(struct inode *inode, struct file *file) case O2HB_DB_TYPE_REGION_ELAPSED_TIME: reg = (struct o2hb_region *)db->db_data; - out += snprintf(buf + out, PAGE_SIZE - out, "%u\n", - jiffies_to_msecs(jiffies - - reg->hr_last_timeout_start)); + lts = reg->hr_last_timeout_start; + /* If 0, it has never been set before */ + if (lts) + lts = jiffies_to_msecs(jiffies - lts); + out += snprintf(buf + out, PAGE_SIZE - out, "%lu\n", lts); goto done; case O2HB_DB_TYPE_REGION_PINNED: -- cgit v1.1 From 3ba169ccec1c5ad0f678e04fd29b990197fdfe79 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Sun, 24 Jul 2011 10:32:54 -0700 Subject: ocfs2/cluster: Add new function o2net_fill_node_map() Patch adds function o2net_fill_node_map() to return the bitmap of nodes that it is connected to. This bitmap is also accessible by the user via the debugfs file, /sys/kernel/debug/o2net/connected_nodes. Signed-off-by: Sunil Mushran --- fs/ocfs2/cluster/netdebug.c | 102 ++++++++++++++++++++++++++++++-------------- fs/ocfs2/cluster/tcp.c | 19 +++++++++ fs/ocfs2/cluster/tcp.h | 2 + 3 files changed, 90 insertions(+), 33 deletions(-) diff --git a/fs/ocfs2/cluster/netdebug.c b/fs/ocfs2/cluster/netdebug.c index 3a583590..dc45deb 100644 --- a/fs/ocfs2/cluster/netdebug.c +++ b/fs/ocfs2/cluster/netdebug.c @@ -47,6 +47,7 @@ #define SC_DEBUG_NAME "sock_containers" #define NST_DEBUG_NAME "send_tracking" #define STATS_DEBUG_NAME "stats" +#define NODES_DEBUG_NAME "connected_nodes" #define SHOW_SOCK_CONTAINERS 0 #define SHOW_SOCK_STATS 1 @@ -55,6 +56,7 @@ static struct dentry *o2net_dentry; static struct dentry *sc_dentry; static struct dentry *nst_dentry; static struct dentry *stats_dentry; +static struct dentry *nodes_dentry; static DEFINE_SPINLOCK(o2net_debug_lock); @@ -491,53 +493,87 @@ static const struct file_operations sc_seq_fops = { .release = sc_fop_release, }; -int o2net_debugfs_init(void) +static int o2net_fill_bitmap(char *buf, int len) { - o2net_dentry = debugfs_create_dir(O2NET_DEBUG_DIR, NULL); - if (!o2net_dentry) { - mlog_errno(-ENOMEM); - goto bail; - } + unsigned long map[BITS_TO_LONGS(O2NM_MAX_NODES)]; + int i = -1, out = 0; - nst_dentry = debugfs_create_file(NST_DEBUG_NAME, S_IFREG|S_IRUSR, - o2net_dentry, NULL, - &nst_seq_fops); - if (!nst_dentry) { - mlog_errno(-ENOMEM); - goto bail; - } + o2net_fill_node_map(map, sizeof(map)); - sc_dentry = debugfs_create_file(SC_DEBUG_NAME, S_IFREG|S_IRUSR, - o2net_dentry, NULL, - &sc_seq_fops); - if (!sc_dentry) { - mlog_errno(-ENOMEM); - goto bail; - } + while ((i = find_next_bit(map, O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) + out += snprintf(buf + out, PAGE_SIZE - out, "%d ", i); + out += snprintf(buf + out, PAGE_SIZE - out, "\n"); - stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, S_IFREG|S_IRUSR, - o2net_dentry, NULL, - &stats_seq_fops); - if (!stats_dentry) { - mlog_errno(-ENOMEM); - goto bail; - } + return out; +} + +static int nodes_fop_open(struct inode *inode, struct file *file) +{ + char *buf; + + buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + i_size_write(inode, o2net_fill_bitmap(buf, PAGE_SIZE)); + + file->private_data = buf; return 0; -bail: - debugfs_remove(stats_dentry); - debugfs_remove(sc_dentry); - debugfs_remove(nst_dentry); - debugfs_remove(o2net_dentry); - return -ENOMEM; } +static int o2net_debug_release(struct inode *inode, struct file *file) +{ + kfree(file->private_data); + return 0; +} + +static ssize_t o2net_debug_read(struct file *file, char __user *buf, + size_t nbytes, loff_t *ppos) +{ + return simple_read_from_buffer(buf, nbytes, ppos, file->private_data, + i_size_read(file->f_mapping->host)); +} + +static const struct file_operations nodes_fops = { + .open = nodes_fop_open, + .release = o2net_debug_release, + .read = o2net_debug_read, + .llseek = generic_file_llseek, +}; + void o2net_debugfs_exit(void) { + debugfs_remove(nodes_dentry); debugfs_remove(stats_dentry); debugfs_remove(sc_dentry); debugfs_remove(nst_dentry); debugfs_remove(o2net_dentry); } +int o2net_debugfs_init(void) +{ + mode_t mode = S_IFREG|S_IRUSR; + + o2net_dentry = debugfs_create_dir(O2NET_DEBUG_DIR, NULL); + if (o2net_dentry) + nst_dentry = debugfs_create_file(NST_DEBUG_NAME, mode, + o2net_dentry, NULL, &nst_seq_fops); + if (nst_dentry) + sc_dentry = debugfs_create_file(SC_DEBUG_NAME, mode, + o2net_dentry, NULL, &sc_seq_fops); + if (sc_dentry) + stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, mode, + o2net_dentry, NULL, &stats_seq_fops); + if (stats_dentry) + nodes_dentry = debugfs_create_file(NODES_DEBUG_NAME, mode, + o2net_dentry, NULL, &nodes_fops); + if (nodes_dentry) + return 0; + + o2net_debugfs_exit(); + mlog_errno(-ENOMEM); + return -ENOMEM; +} + #endif /* CONFIG_DEBUG_FS */ diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index 6e97895..ae13d5c 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c @@ -1034,6 +1034,25 @@ static int o2net_tx_can_proceed(struct o2net_node *nn, return ret; } +/* Get a map of all nodes to which this node is currently connected to */ +void o2net_fill_node_map(unsigned long *map, unsigned bytes) +{ + struct o2net_sock_container *sc; + int node, ret; + + BUG_ON(bytes < (BITS_TO_LONGS(O2NM_MAX_NODES) * sizeof(unsigned long))); + + memset(map, 0, bytes); + for (node = 0; node < O2NM_MAX_NODES; ++node) { + o2net_tx_can_proceed(o2net_nn_from_num(node), &sc, &ret); + if (!ret) { + set_bit(node, map); + sc_put(sc); + } + } +} +EXPORT_SYMBOL_GPL(o2net_fill_node_map); + int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec, size_t caller_veclen, u8 target_node, int *status) { diff --git a/fs/ocfs2/cluster/tcp.h b/fs/ocfs2/cluster/tcp.h index fd6179e..5bada2a 100644 --- a/fs/ocfs2/cluster/tcp.h +++ b/fs/ocfs2/cluster/tcp.h @@ -106,6 +106,8 @@ int o2net_register_handler(u32 msg_type, u32 key, u32 max_len, struct list_head *unreg_list); void o2net_unregister_handler_list(struct list_head *list); +void o2net_fill_node_map(unsigned long *map, unsigned bytes); + struct o2nm_node; int o2net_register_hb_callbacks(void); void o2net_unregister_hb_callbacks(void); -- cgit v1.1 From 6b27f62fc750d85bc6fc3718b3b38ec60edc2d74 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Sun, 24 Jul 2011 10:33:54 -0700 Subject: ocfs2/cluster: Cluster up now includes network connections too The cluster up check only checks to see if the node is heartbeating or not. If yes it continues assuming that the node is connected to all the nodes. But if that is not the case, the cluster join aborts with a stack of errors that are not easy to comprehend. This patch adds the network connect check upfront and prints the nodes that the node is not yet connected to, before aborting. Signed-off-by: Sunil Mushran --- fs/ocfs2/dlm/dlmdomain.c | 7 ----- fs/ocfs2/stack_o2cb.c | 67 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 61 insertions(+), 13 deletions(-) diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 200d988..92f2ead 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c @@ -2138,13 +2138,6 @@ struct dlm_ctxt * dlm_register_domain(const char *domain, goto leave; } - if (!o2hb_check_local_node_heartbeating()) { - mlog(ML_ERROR, "the local node has not been configured, or is " - "not heartbeating\n"); - ret = -EPROTO; - goto leave; - } - mlog(0, "register called for domain \"%s\"\n", domain); retry: diff --git a/fs/ocfs2/stack_o2cb.c b/fs/ocfs2/stack_o2cb.c index be935d8..9436801 100644 --- a/fs/ocfs2/stack_o2cb.c +++ b/fs/ocfs2/stack_o2cb.c @@ -28,6 +28,7 @@ #include "cluster/masklog.h" #include "cluster/nodemanager.h" #include "cluster/heartbeat.h" +#include "cluster/tcp.h" #include "stackglue.h" @@ -256,6 +257,61 @@ static void o2cb_dump_lksb(struct ocfs2_dlm_lksb *lksb) } /* + * Check if this node is heartbeating and is connected to all other + * heartbeating nodes. + */ +static int o2cb_cluster_check(void) +{ + u8 node_num; + int i; + unsigned long hbmap[BITS_TO_LONGS(O2NM_MAX_NODES)]; + unsigned long netmap[BITS_TO_LONGS(O2NM_MAX_NODES)]; + + node_num = o2nm_this_node(); + if (node_num == O2NM_MAX_NODES) { + printk(KERN_ERR "o2cb: This node has not been configured.\n"); + return -EINVAL; + } + + /* + * o2dlm expects o2net sockets to be created. If not, then + * dlm_join_domain() fails with a stack of errors which are both cryptic + * and incomplete. The idea here is to detect upfront whether we have + * managed to connect to all nodes or not. If not, then list the nodes + * to allow the user to check the configuration (incorrect IP, firewall, + * etc.) Yes, this is racy. But its not the end of the world. + */ +#define O2CB_MAP_STABILIZE_COUNT 60 + for (i = 0; i < O2CB_MAP_STABILIZE_COUNT; ++i) { + o2hb_fill_node_map(hbmap, sizeof(hbmap)); + if (!test_bit(node_num, hbmap)) { + printk(KERN_ERR "o2cb: %s heartbeat has not been " + "started.\n", (o2hb_global_heartbeat_active() ? + "Global" : "Local")); + return -EINVAL; + } + o2net_fill_node_map(netmap, sizeof(netmap)); + /* Force set the current node to allow easy compare */ + set_bit(node_num, netmap); + if (!memcmp(hbmap, netmap, sizeof(hbmap))) + return 0; + if (i < O2CB_MAP_STABILIZE_COUNT) + msleep(1000); + } + + printk(KERN_ERR "o2cb: This node could not connect to nodes:"); + i = -1; + while ((i = find_next_bit(hbmap, O2NM_MAX_NODES, + i + 1)) < O2NM_MAX_NODES) { + if (!test_bit(i, netmap)) + printk(" %u", i); + } + printk(".\n"); + + return -ENOTCONN; +} + +/* * Called from the dlm when it's about to evict a node. This is how the * classic stack signals node death. */ @@ -280,12 +336,11 @@ static int o2cb_cluster_connect(struct ocfs2_cluster_connection *conn) BUG_ON(conn == NULL); BUG_ON(conn->cc_proto == NULL); - /* for now we only have one cluster/node, make sure we see it - * in the heartbeat universe */ - if (!o2hb_check_local_node_heartbeating()) { - if (o2hb_global_heartbeat_active()) - mlog(ML_ERROR, "Global heartbeat not started\n"); - rc = -EINVAL; + /* Ensure cluster stack is up and all nodes are connected */ + rc = o2cb_cluster_check(); + if (rc) { + printk(KERN_ERR "o2cb: Cluster check failed. Fix errors " + "before retrying.\n"); goto out; } -- cgit v1.1 From 619c200de144b44f5e405305241bcd7edbb8c6cf Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Sun, 24 Jul 2011 10:34:54 -0700 Subject: ocfs2: Clean up messages in the fs Convert useful messages from ML_NOTICE to KERN_NOTICE to improve readability. Signed-off-by: Sunil Mushran --- fs/ocfs2/journal.c | 9 ++++++--- fs/ocfs2/quota_local.c | 13 +++++++++---- fs/ocfs2/slot_map.c | 4 ++-- fs/ocfs2/super.c | 10 +++++----- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index 295d564..8eaaa78 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c @@ -1544,9 +1544,9 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb, /* we need to run complete recovery for offline orphan slots */ ocfs2_replay_map_set_state(osb, REPLAY_NEEDED); - mlog(ML_NOTICE, "Recovering node %d from slot %d on device (%u,%u)\n", - node_num, slot_num, - MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev)); + printk(KERN_NOTICE "ocfs2: Begin replay journal (node %d, slot %d) on "\ + "device (%u,%u)\n", node_num, slot_num, MAJOR(osb->sb->s_dev), + MINOR(osb->sb->s_dev)); OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters); @@ -1601,6 +1601,9 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb, jbd2_journal_destroy(journal); + printk(KERN_NOTICE "ocfs2: End replay journal (node %d, slot %d) on "\ + "device (%u,%u)\n", node_num, slot_num, MAJOR(osb->sb->s_dev), + MINOR(osb->sb->s_dev)); done: /* drop the lock on this nodes journal */ if (got_lock) diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c index dc8007f..942fd65 100644 --- a/fs/ocfs2/quota_local.c +++ b/fs/ocfs2/quota_local.c @@ -404,7 +404,9 @@ struct ocfs2_quota_recovery *ocfs2_begin_quota_recovery( int status = 0; struct ocfs2_quota_recovery *rec; - mlog(ML_NOTICE, "Beginning quota recovery in slot %u\n", slot_num); + printk(KERN_NOTICE "ocfs2: Beginning quota recovery on device (%s) for " + "slot %u\n", osb->dev_str, slot_num); + rec = ocfs2_alloc_quota_recovery(); if (!rec) return ERR_PTR(-ENOMEM); @@ -596,7 +598,9 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb, struct inode *lqinode; unsigned int flags; - mlog(ML_NOTICE, "Finishing quota recovery in slot %u\n", slot_num); + printk(KERN_NOTICE "ocfs2: Finishing quota recovery on device (%s) for " + "slot %u\n", osb->dev_str, slot_num); + mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); for (type = 0; type < MAXQUOTAS; type++) { if (list_empty(&(rec->r_list[type]))) @@ -612,8 +616,9 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb, /* Someone else is holding the lock? Then he must be * doing the recovery. Just skip the file... */ if (status == -EAGAIN) { - mlog(ML_NOTICE, "skipping quota recovery for slot %d " - "because quota file is locked.\n", slot_num); + printk(KERN_NOTICE "ocfs2: Skipping quota recovery on " + "device (%s) for slot %d because quota file is " + "locked.\n", osb->dev_str, slot_num); status = 0; goto out_put; } else if (status < 0) { diff --git a/fs/ocfs2/slot_map.c b/fs/ocfs2/slot_map.c index 26fc001..1424c15 100644 --- a/fs/ocfs2/slot_map.c +++ b/fs/ocfs2/slot_map.c @@ -493,8 +493,8 @@ int ocfs2_find_slot(struct ocfs2_super *osb) goto bail; } } else - mlog(ML_NOTICE, "slot %d is already allocated to this node!\n", - slot); + printk(KERN_INFO "ocfs2: Slot %d on device (%s) was already " + "allocated to this node!\n", slot, osb->dev_str); ocfs2_set_slot(si, slot, osb->node_num); osb->slot_num = slot; diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 56f6102..3e78503 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -1107,9 +1107,9 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) ocfs2_set_ro_flag(osb, 1); - printk(KERN_NOTICE "Readonly device detected. No cluster " - "services will be utilized for this mount. Recovery " - "will be skipped.\n"); + printk(KERN_NOTICE "ocfs2: Readonly device (%s) detected. " + "Cluster services will not be used for this mount. " + "Recovery will be skipped.\n", osb->dev_str); } if (!ocfs2_is_hard_readonly(osb)) { @@ -2462,8 +2462,8 @@ static int ocfs2_check_volume(struct ocfs2_super *osb) goto finally; } } else { - mlog(ML_NOTICE, "File system was not unmounted cleanly, " - "recovering volume.\n"); + printk(KERN_NOTICE "ocfs2: File system on device (%s) was not " + "unmounted cleanly, recovering it.\n", osb->dev_str); } local = ocfs2_mount_local(osb); -- cgit v1.1 From a035bff6b82aca89c1223e2c614adc2d17ec8aa2 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Sun, 24 Jul 2011 10:35:54 -0700 Subject: ocfs2: Add comment about orphan scanning Add a comment that explains the reason as to why orphan scan scans all the slots. Signed-off-by: Sunil Mushran --- fs/ocfs2/journal.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index 8eaaa78..0a42ae9 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c @@ -1811,6 +1811,20 @@ static inline unsigned long ocfs2_orphan_scan_timeout(void) * every slot, queuing a recovery of the slot on the ocfs2_wq thread. This * is done to catch any orphans that are left over in orphan directories. * + * It scans all slots, even ones that are in use. It does so to handle the + * case described below: + * + * Node 1 has an inode it was using. The dentry went away due to memory + * pressure. Node 1 closes the inode, but it's on the free list. The node + * has the open lock. + * Node 2 unlinks the inode. It grabs the dentry lock to notify others, + * but node 1 has no dentry and doesn't get the message. It trylocks the + * open lock, sees that another node has a PR, and does nothing. + * Later node 2 runs its orphan dir. It igets the inode, trylocks the + * open lock, sees the PR still, and does nothing. + * Basically, we have to trigger an orphan iput on node 1. The only way + * for this to happen is if node 1 runs node 2's orphan dir. + * * ocfs2_queue_orphan_scan gets called every ORPHAN_SCAN_SCHEDULE_TIMEOUT * seconds. It gets an EX lock on os_lockres and checks sequence number * stored in LVB. If the sequence number has changed, it means some other -- cgit v1.1 From 5cffff9e29866a3de98c2c25135b3199491f93b0 Mon Sep 17 00:00:00 2001 From: Wengang Wang Date: Sun, 24 Jul 2011 10:36:54 -0700 Subject: ocfs2: Fix ocfs2_page_mkwrite() This patch address two shortcomings in ocfs2_page_mkwrite(): 1. Makes the function return better VM_FAULT_* errors. 2. It handles a error that is triggered when a page is dropped from the mapping due to memory pressure. This patch locks the page to prevent that. [Patch was cleaned up by Sunil Mushran.] Signed-off-by: Wengang Wang Signed-off-by: Sunil Mushran --- fs/ocfs2/aops.c | 51 +++++++++++++++++++++++++++++++++++++++++++-------- fs/ocfs2/mmap.c | 53 ++++++++++++++++++++++++----------------------------- 2 files changed, 67 insertions(+), 37 deletions(-) diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index c1efe93..ff98c16 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c @@ -863,6 +863,12 @@ struct ocfs2_write_ctxt { struct page *w_target_page; /* + * w_target_locked is used for page_mkwrite path indicating no unlocking + * against w_target_page in ocfs2_write_end_nolock. + */ + unsigned int w_target_locked:1; + + /* * ocfs2_write_end() uses this to know what the real range to * write in the target should be. */ @@ -895,6 +901,24 @@ void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages) static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc) { + int i; + + /* + * w_target_locked is only set to true in the page_mkwrite() case. + * The intent is to allow us to lock the target page from write_begin() + * to write_end(). The caller must hold a ref on w_target_page. + */ + if (wc->w_target_locked) { + BUG_ON(!wc->w_target_page); + for (i = 0; i < wc->w_num_pages; i++) { + if (wc->w_target_page == wc->w_pages[i]) { + wc->w_pages[i] = NULL; + break; + } + } + mark_page_accessed(wc->w_target_page); + page_cache_release(wc->w_target_page); + } ocfs2_unlock_and_free_pages(wc->w_pages, wc->w_num_pages); brelse(wc->w_di_bh); @@ -1132,20 +1156,17 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping, */ lock_page(mmap_page); + /* Exit and let the caller retry */ if (mmap_page->mapping != mapping) { + WARN_ON(mmap_page->mapping); unlock_page(mmap_page); - /* - * Sanity check - the locking in - * ocfs2_pagemkwrite() should ensure - * that this code doesn't trigger. - */ - ret = -EINVAL; - mlog_errno(ret); + ret = -EAGAIN; goto out; } page_cache_get(mmap_page); wc->w_pages[i] = mmap_page; + wc->w_target_locked = true; } else { wc->w_pages[i] = find_or_create_page(mapping, index, GFP_NOFS); @@ -1160,6 +1181,8 @@ static int ocfs2_grab_pages_for_write(struct address_space *mapping, wc->w_target_page = wc->w_pages[i]; } out: + if (ret) + wc->w_target_locked = false; return ret; } @@ -1817,11 +1840,23 @@ try_again: */ ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos, len, cluster_of_pages, mmap_page); - if (ret) { + if (ret && ret != -EAGAIN) { mlog_errno(ret); goto out_quota; } + /* + * ocfs2_grab_pages_for_write() returns -EAGAIN if it could not lock + * the target page. In this case, we exit with no error and no target + * page. This will trigger the caller, page_mkwrite(), to re-try + * the operation. + */ + if (ret == -EAGAIN) { + BUG_ON(wc->w_target_page); + ret = 0; + goto out_quota; + } + ret = ocfs2_write_cluster_by_desc(mapping, data_ac, meta_ac, wc, pos, len); if (ret) { diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c index 3e9393c..9cd4108 100644 --- a/fs/ocfs2/mmap.c +++ b/fs/ocfs2/mmap.c @@ -61,7 +61,7 @@ static int ocfs2_fault(struct vm_area_struct *area, struct vm_fault *vmf) static int __ocfs2_page_mkwrite(struct file *file, struct buffer_head *di_bh, struct page *page) { - int ret; + int ret = VM_FAULT_NOPAGE; struct inode *inode = file->f_path.dentry->d_inode; struct address_space *mapping = inode->i_mapping; loff_t pos = page_offset(page); @@ -71,32 +71,25 @@ static int __ocfs2_page_mkwrite(struct file *file, struct buffer_head *di_bh, void *fsdata; loff_t size = i_size_read(inode); - /* - * Another node might have truncated while we were waiting on - * cluster locks. - * We don't check size == 0 before the shift. This is borrowed - * from do_generic_file_read. - */ last_index = (size - 1) >> PAGE_CACHE_SHIFT; - if (unlikely(!size || page->index > last_index)) { - ret = -EINVAL; - goto out; - } /* - * The i_size check above doesn't catch the case where nodes - * truncated and then re-extended the file. We'll re-check the - * page mapping after taking the page lock inside of - * ocfs2_write_begin_nolock(). + * There are cases that lead to the page no longer bebongs to the + * mapping. + * 1) pagecache truncates locally due to memory pressure. + * 2) pagecache truncates when another is taking EX lock against + * inode lock. see ocfs2_data_convert_worker. + * + * The i_size check doesn't catch the case where nodes truncated and + * then re-extended the file. We'll re-check the page mapping after + * taking the page lock inside of ocfs2_write_begin_nolock(). + * + * Let VM retry with these cases. */ - if (!PageUptodate(page) || page->mapping != inode->i_mapping) { - /* - * the page has been umapped in ocfs2_data_downconvert_worker. - * So return 0 here and let VFS retry. - */ - ret = 0; + if ((page->mapping != inode->i_mapping) || + (!PageUptodate(page)) || + (page_offset(page) >= size)) goto out; - } /* * Call ocfs2_write_begin() and ocfs2_write_end() to take @@ -116,17 +109,21 @@ static int __ocfs2_page_mkwrite(struct file *file, struct buffer_head *di_bh, if (ret) { if (ret != -ENOSPC) mlog_errno(ret); + if (ret == -ENOMEM) + ret = VM_FAULT_OOM; + else + ret = VM_FAULT_SIGBUS; goto out; } - ret = ocfs2_write_end_nolock(mapping, pos, len, len, locked_page, - fsdata); - if (ret < 0) { - mlog_errno(ret); + if (!locked_page) { + ret = VM_FAULT_NOPAGE; goto out; } + ret = ocfs2_write_end_nolock(mapping, pos, len, len, locked_page, + fsdata); BUG_ON(ret != len); - ret = 0; + ret = VM_FAULT_LOCKED; out: return ret; } @@ -168,8 +165,6 @@ static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) out: ocfs2_unblock_signals(&oldset); - if (ret) - ret = VM_FAULT_SIGBUS; return ret; } -- cgit v1.1 From 93862d5e1ab875664c6cc95254fc365028a48bb1 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Mon, 25 Jul 2011 14:58:15 -0700 Subject: ocfs2: Implement llseek() ocfs2 implements its own llseek() to provide the SEEK_HOLE/SEEK_DATA functionality. SEEK_HOLE sets the file pointer to the start of either a hole or an unwritten (preallocated) extent, that is greater than or equal to the supplied offset. SEEK_DATA sets the file pointer to the start of an allocated extent (not unwritten) that is greater than or equal to the supplied offset. If the supplied offset is on a desired region, then the file pointer is set to it. Offsets greater than or equal to the file size return -ENXIO. Unwritten (preallocated) extents are considered holes because the file system treats reads to such regions in the same way as it does to holes. Signed-off-by: Sunil Mushran --- fs/ocfs2/extent_map.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++ fs/ocfs2/extent_map.h | 2 ++ fs/ocfs2/file.c | 55 +++++++++++++++++++++++++++-- 3 files changed, 151 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c index 23457b4..2f5b92e 100644 --- a/fs/ocfs2/extent_map.c +++ b/fs/ocfs2/extent_map.c @@ -832,6 +832,102 @@ out: return ret; } +int ocfs2_seek_data_hole_offset(struct file *file, loff_t *offset, int origin) +{ + struct inode *inode = file->f_mapping->host; + int ret; + unsigned int is_last = 0, is_data = 0; + u16 cs_bits = OCFS2_SB(inode->i_sb)->s_clustersize_bits; + u32 cpos, cend, clen, hole_size; + u64 extoff, extlen; + struct buffer_head *di_bh = NULL; + struct ocfs2_extent_rec rec; + + BUG_ON(origin != SEEK_DATA && origin != SEEK_HOLE); + + ret = ocfs2_inode_lock(inode, &di_bh, 0); + if (ret) { + mlog_errno(ret); + goto out; + } + + down_read(&OCFS2_I(inode)->ip_alloc_sem); + + if (*offset >= inode->i_size) { + ret = -ENXIO; + goto out_unlock; + } + + if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) { + if (origin == SEEK_HOLE) + *offset = inode->i_size; + goto out_unlock; + } + + clen = 0; + cpos = *offset >> cs_bits; + cend = ocfs2_clusters_for_bytes(inode->i_sb, inode->i_size); + + while (cpos < cend && !is_last) { + ret = ocfs2_get_clusters_nocache(inode, di_bh, cpos, &hole_size, + &rec, &is_last); + if (ret) { + mlog_errno(ret); + goto out_unlock; + } + + extoff = cpos; + extoff <<= cs_bits; + + if (rec.e_blkno == 0ULL) { + clen = hole_size; + is_data = 0; + } else { + clen = le16_to_cpu(rec.e_leaf_clusters) - + (cpos - le32_to_cpu(rec.e_cpos)); + is_data = (rec.e_flags & OCFS2_EXT_UNWRITTEN) ? 0 : 1; + } + + if ((!is_data && origin == SEEK_HOLE) || + (is_data && origin == SEEK_DATA)) { + if (extoff > *offset) + *offset = extoff; + goto out_unlock; + } + + if (!is_last) + cpos += clen; + } + + if (origin == SEEK_HOLE) { + extoff = cpos; + extoff <<= cs_bits; + extlen = clen; + extlen <<= cs_bits; + + if ((extoff + extlen) > inode->i_size) + extlen = inode->i_size - extoff; + extoff += extlen; + if (extoff > *offset) + *offset = extoff; + goto out_unlock; + } + + ret = -ENXIO; + +out_unlock: + + brelse(di_bh); + + up_read(&OCFS2_I(inode)->ip_alloc_sem); + + ocfs2_inode_unlock(inode, 0); +out: + if (ret && ret != -ENXIO) + ret = -ENXIO; + return ret; +} + int ocfs2_read_virt_blocks(struct inode *inode, u64 v_block, int nr, struct buffer_head *bhs[], int flags, int (*validate)(struct super_block *sb, diff --git a/fs/ocfs2/extent_map.h b/fs/ocfs2/extent_map.h index e79d41c..67ea57d 100644 --- a/fs/ocfs2/extent_map.h +++ b/fs/ocfs2/extent_map.h @@ -53,6 +53,8 @@ int ocfs2_extent_map_get_blocks(struct inode *inode, u64 v_blkno, u64 *p_blkno, int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, u64 map_start, u64 map_len); +int ocfs2_seek_data_hole_offset(struct file *file, loff_t *offset, int origin); + int ocfs2_xattr_get_clusters(struct inode *inode, u32 v_cluster, u32 *p_cluster, u32 *num_clusters, struct ocfs2_extent_list *el, diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 0fc2bd3..c0f015e 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -2591,6 +2591,57 @@ bail: return ret; } +/* Refer generic_file_llseek_unlocked() */ +static loff_t ocfs2_file_llseek(struct file *file, loff_t offset, int origin) +{ + struct inode *inode = file->f_mapping->host; + int ret = 0; + + mutex_lock(&inode->i_mutex); + + switch (origin) { + case SEEK_SET: + break; + case SEEK_END: + offset += inode->i_size; + break; + case SEEK_CUR: + if (offset == 0) { + offset = file->f_pos; + goto out; + } + offset += file->f_pos; + break; + case SEEK_DATA: + case SEEK_HOLE: + ret = ocfs2_seek_data_hole_offset(file, &offset, origin); + if (ret) + goto out; + break; + default: + ret = -EINVAL; + goto out; + } + + if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) + ret = -EINVAL; + if (!ret && offset > inode->i_sb->s_maxbytes) + ret = -EINVAL; + if (ret) + goto out; + + if (offset != file->f_pos) { + file->f_pos = offset; + file->f_version = 0; + } + +out: + mutex_unlock(&inode->i_mutex); + if (ret) + return ret; + return offset; +} + const struct inode_operations ocfs2_file_iops = { .setattr = ocfs2_setattr, .getattr = ocfs2_getattr, @@ -2615,7 +2666,7 @@ const struct inode_operations ocfs2_special_file_iops = { * ocfs2_fops_no_plocks and ocfs2_dops_no_plocks! */ const struct file_operations ocfs2_fops = { - .llseek = generic_file_llseek, + .llseek = ocfs2_file_llseek, .read = do_sync_read, .write = do_sync_write, .mmap = ocfs2_mmap, @@ -2663,7 +2714,7 @@ const struct file_operations ocfs2_dops = { * the cluster. */ const struct file_operations ocfs2_fops_no_plocks = { - .llseek = generic_file_llseek, + .llseek = ocfs2_file_llseek, .read = do_sync_read, .write = do_sync_write, .mmap = ocfs2_mmap, -- cgit v1.1 From a11f7e63c59810a81494d4c4b028af707d4c7ca4 Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Wed, 22 Jun 2011 14:23:38 -0700 Subject: ocfs2: serialize unaligned aio Fix a corruption that can happen when we have (two or more) outstanding aio's to an overlapping unaligned region. Ext4 (e9e3bcecf44c04b9e6b505fd8e2eb9cea58fb94d) and xfs recently had to fix similar issues. In our case what happens is that we can have an outstanding aio on a region and if a write comes in with some bytes overlapping the original aio we may decide to read that region into a page before continuing (typically because of buffered-io fallback). Since we have no ordering guarantees with the aio, we can read stale or bad data into the page and then write it back out. If the i/o is page and block aligned, then we avoid this issue as there won't be any need to read data from disk. I took the same approach as Eric in the ext4 patch and introduced some serialization of unaligned async direct i/o. I don't expect this to have an effect on the most common cases of AIO. Unaligned aio will be slower though, but that's far more acceptable than data corruption. Signed-off-by: Mark Fasheh Signed-off-by: Joel Becker --- fs/ocfs2/aops.c | 10 ++++++++++ fs/ocfs2/aops.h | 14 ++++++++++++++ fs/ocfs2/file.c | 38 ++++++++++++++++++++++++++++++++++++++ fs/ocfs2/inode.h | 3 +++ fs/ocfs2/super.c | 10 ++++++++-- 5 files changed, 73 insertions(+), 2 deletions(-) diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index ac97bca..4c1ec8f 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c @@ -564,6 +564,7 @@ static void ocfs2_dio_end_io(struct kiocb *iocb, { struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode; int level; + wait_queue_head_t *wq = ocfs2_ioend_wq(inode); /* this io's submitter should not have unlocked this before we could */ BUG_ON(!ocfs2_iocb_is_rw_locked(iocb)); @@ -573,6 +574,15 @@ static void ocfs2_dio_end_io(struct kiocb *iocb, ocfs2_iocb_clear_sem_locked(iocb); } + if (ocfs2_iocb_is_unaligned_aio(iocb)) { + ocfs2_iocb_clear_unaligned_aio(iocb); + + if (atomic_dec_and_test(&OCFS2_I(inode)->ip_unaligned_aio) && + waitqueue_active(wq)) { + wake_up_all(wq); + } + } + ocfs2_iocb_clear_rw_locked(iocb); level = ocfs2_iocb_rw_locked_level(iocb); diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h index 75cf3ad..ffb2da3 100644 --- a/fs/ocfs2/aops.h +++ b/fs/ocfs2/aops.h @@ -78,6 +78,7 @@ enum ocfs2_iocb_lock_bits { OCFS2_IOCB_RW_LOCK = 0, OCFS2_IOCB_RW_LOCK_LEVEL, OCFS2_IOCB_SEM, + OCFS2_IOCB_UNALIGNED_IO, OCFS2_IOCB_NUM_LOCKS }; @@ -91,4 +92,17 @@ enum ocfs2_iocb_lock_bits { clear_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private) #define ocfs2_iocb_is_sem_locked(iocb) \ test_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private) + +#define ocfs2_iocb_set_unaligned_aio(iocb) \ + set_bit(OCFS2_IOCB_UNALIGNED_IO, (unsigned long *)&iocb->private) +#define ocfs2_iocb_clear_unaligned_aio(iocb) \ + clear_bit(OCFS2_IOCB_UNALIGNED_IO, (unsigned long *)&iocb->private) +#define ocfs2_iocb_is_unaligned_aio(iocb) \ + test_bit(OCFS2_IOCB_UNALIGNED_IO, (unsigned long *)&iocb->private) + +#define OCFS2_IOEND_WQ_HASH_SZ 37 +#define ocfs2_ioend_wq(v) (&ocfs2__ioend_wq[((unsigned long)(v)) %\ + OCFS2_IOEND_WQ_HASH_SZ]) +extern wait_queue_head_t ocfs2__ioend_wq[OCFS2_IOEND_WQ_HASH_SZ]; + #endif /* OCFS2_FILE_H */ diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index b1e35a3..145f453 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -2038,6 +2038,23 @@ out: return ret; } +static void ocfs2_aiodio_wait(struct inode *inode) +{ + wait_queue_head_t *wq = ocfs2_ioend_wq(inode); + + wait_event(*wq, (atomic_read(&OCFS2_I(inode)->ip_unaligned_aio) == 0)); +} + +static int ocfs2_is_io_unaligned(struct inode *inode, size_t count, loff_t pos) +{ + int blockmask = inode->i_sb->s_blocksize - 1; + loff_t final_size = pos + count; + + if ((pos & blockmask) || (final_size & blockmask)) + return 1; + return 0; +} + static int ocfs2_prepare_inode_for_refcount(struct inode *inode, struct file *file, loff_t pos, size_t count, @@ -2216,6 +2233,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); int full_coherency = !(osb->s_mount_opt & OCFS2_MOUNT_COHERENCY_BUFFERED); + int unaligned_dio = 0; trace_ocfs2_file_aio_write(inode, file, file->f_path.dentry, (unsigned long long)OCFS2_I(inode)->ip_blkno, @@ -2284,6 +2302,10 @@ relock: goto out; } + if (direct_io && !is_sync_kiocb(iocb)) + unaligned_dio = ocfs2_is_io_unaligned(inode, iocb->ki_left, + *ppos); + /* * We can't complete the direct I/O as requested, fall back to * buffered I/O. @@ -2299,6 +2321,18 @@ relock: goto relock; } + if (unaligned_dio) { + /* + * Wait on previous unaligned aio to complete before + * proceeding. + */ + ocfs2_aiodio_wait(inode); + + /* Mark the iocb as needing a decrement in ocfs2_dio_end_io */ + atomic_inc(&OCFS2_I(inode)->ip_unaligned_aio); + ocfs2_iocb_set_unaligned_aio(iocb); + } + /* * To later detect whether a journal commit for sync writes is * necessary, we sample i_size, and cluster count here. @@ -2371,8 +2405,12 @@ out_dio: if ((ret == -EIOCBQUEUED) || (!ocfs2_iocb_is_rw_locked(iocb))) { rw_level = -1; have_alloc_sem = 0; + unaligned_dio = 0; } + if (unaligned_dio) + atomic_dec(&OCFS2_I(inode)->ip_unaligned_aio); + out: if (rw_level != -1) ocfs2_rw_unlock(inode, rw_level); diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h index 1c508b1..88924a3 100644 --- a/fs/ocfs2/inode.h +++ b/fs/ocfs2/inode.h @@ -43,6 +43,9 @@ struct ocfs2_inode_info /* protects extended attribute changes on this inode */ struct rw_semaphore ip_xattr_sem; + /* Number of outstanding AIO's which are not page aligned */ + atomic_t ip_unaligned_aio; + /* These fields are protected by ip_lock */ spinlock_t ip_lock; u32 ip_open_count; diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 029c4cd..603f5fe 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -54,6 +54,7 @@ #include "ocfs1_fs_compat.h" #include "alloc.h" +#include "aops.h" #include "blockcheck.h" #include "dlmglue.h" #include "export.h" @@ -1616,12 +1617,17 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt) return 0; } +wait_queue_head_t ocfs2__ioend_wq[OCFS2_IOEND_WQ_HASH_SZ]; + static int __init ocfs2_init(void) { - int status; + int status, i; ocfs2_print_version(); + for (i = 0; i < OCFS2_IOEND_WQ_HASH_SZ; i++) + init_waitqueue_head(&ocfs2__ioend_wq[i]); + status = init_ocfs2_uptodate_cache(); if (status < 0) { mlog_errno(status); @@ -1760,7 +1766,7 @@ static void ocfs2_inode_init_once(void *data) ocfs2_extent_map_init(&oi->vfs_inode); INIT_LIST_HEAD(&oi->ip_io_markers); oi->ip_dir_start_lookup = 0; - + atomic_set(&oi->ip_unaligned_aio, 0); init_rwsem(&oi->ip_alloc_sem); init_rwsem(&oi->ip_xattr_sem); mutex_init(&oi->ip_io_mutex); -- cgit v1.1 From c7e25e6e0b0486492c5faaf6312b37413642c48e Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 23 Jun 2011 22:51:47 +0200 Subject: ocfs2: Avoid livelock in ocfs2_readpage() When someone writes to an inode, readers accessing the same inode via ocfs2_readpage() just busyloop trying to get ip_alloc_sem because do_generic_file_read() looks up the page again and retries ->readpage() when previous attempt failed with AOP_TRUNCATED_PAGE. When there are enough readers, they can occupy all CPUs and in non-preempt kernel the system is deadlocked because writer holding ip_alloc_sem is never run to release the semaphore. Fix the problem by making reader block on ip_alloc_sem to break the busy loop. Signed-off-by: Jan Kara Signed-off-by: Joel Becker --- fs/ocfs2/aops.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 4c1ec8f..ba3ca1e 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c @@ -290,7 +290,15 @@ static int ocfs2_readpage(struct file *file, struct page *page) } if (down_read_trylock(&oi->ip_alloc_sem) == 0) { + /* + * Unlock the page and cycle ip_alloc_sem so that we don't + * busyloop waiting for ip_alloc_sem to unlock + */ ret = AOP_TRUNCATED_PAGE; + unlock_page(page); + unlock = 0; + down_read(&oi->ip_alloc_sem); + up_read(&oi->ip_alloc_sem); goto out_inode_unlock; } -- cgit v1.1 From ece9528e5f88cee11303fceefe39382f1030cd4e Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Tue, 12 Jul 2011 08:18:15 -0700 Subject: gpio/omap: replace MOD_REG_BIT macro with static inline This macro is ugly and confusing, especially since it passes in most arguments, but uses an implied 'base' from the caller. Replace it with an equivalent static inline. Signed-off-by: Kevin Hilman --- drivers/gpio/gpio-omap.c | 54 ++++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 0599854..34a7110 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -148,13 +148,17 @@ static int _get_gpio_dataout(struct gpio_bank *bank, int gpio) return (__raw_readl(reg) & GPIO_BIT(bank, gpio)) != 0; } -#define MOD_REG_BIT(reg, bit_mask, set) \ -do { \ - int l = __raw_readl(base + reg); \ - if (set) l |= bit_mask; \ - else l &= ~bit_mask; \ - __raw_writel(l, base + reg); \ -} while(0) +static inline void _gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set) +{ + int l = __raw_readl(base + reg); + + if (set) + l |= mask; + else + l &= ~mask; + + __raw_writel(l, base + reg); +} /** * _set_gpio_debounce - low level gpio debounce time @@ -210,28 +214,28 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, u32 gpio_bit = 1 << gpio; if (cpu_is_omap44xx()) { - MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT0, gpio_bit, - trigger & IRQ_TYPE_LEVEL_LOW); - MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT1, gpio_bit, - trigger & IRQ_TYPE_LEVEL_HIGH); - MOD_REG_BIT(OMAP4_GPIO_RISINGDETECT, gpio_bit, - trigger & IRQ_TYPE_EDGE_RISING); - MOD_REG_BIT(OMAP4_GPIO_FALLINGDETECT, gpio_bit, - trigger & IRQ_TYPE_EDGE_FALLING); + _gpio_rmw(base, OMAP4_GPIO_LEVELDETECT0, gpio_bit, + trigger & IRQ_TYPE_LEVEL_LOW); + _gpio_rmw(base, OMAP4_GPIO_LEVELDETECT1, gpio_bit, + trigger & IRQ_TYPE_LEVEL_HIGH); + _gpio_rmw(base, OMAP4_GPIO_RISINGDETECT, gpio_bit, + trigger & IRQ_TYPE_EDGE_RISING); + _gpio_rmw(base, OMAP4_GPIO_FALLINGDETECT, gpio_bit, + trigger & IRQ_TYPE_EDGE_FALLING); } else { - MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, - trigger & IRQ_TYPE_LEVEL_LOW); - MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, - trigger & IRQ_TYPE_LEVEL_HIGH); - MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit, - trigger & IRQ_TYPE_EDGE_RISING); - MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, - trigger & IRQ_TYPE_EDGE_FALLING); + _gpio_rmw(base, OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, + trigger & IRQ_TYPE_LEVEL_LOW); + _gpio_rmw(base, OMAP24XX_GPIO_LEVELDETECT1, gpio_bit, + trigger & IRQ_TYPE_LEVEL_HIGH); + _gpio_rmw(base, OMAP24XX_GPIO_RISINGDETECT, gpio_bit, + trigger & IRQ_TYPE_EDGE_RISING); + _gpio_rmw(base, OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, + trigger & IRQ_TYPE_EDGE_FALLING); } if (likely(!(bank->non_wakeup_gpios & gpio_bit))) { if (cpu_is_omap44xx()) { - MOD_REG_BIT(OMAP4_GPIO_IRQWAKEN0, gpio_bit, - trigger != 0); + _gpio_rmw(base, OMAP4_GPIO_IRQWAKEN0, gpio_bit, + trigger != 0); } else { /* * GPIO wakeup request can only be generated on edge -- cgit v1.1 From 832337490f22987a1b739ba840e105c0c9af01bc Mon Sep 17 00:00:00 2001 From: Todd Poynor Date: Mon, 18 Jul 2011 07:43:14 -0700 Subject: gpio/omap: check return value from irq_alloc_generic_chip Ensure return value of irq_alloc_generic_chip() is checked before continuing on to use it. Signed-off-by: Todd Poynor Signed-off-by: Kevin Hilman --- drivers/gpio/gpio-omap.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 34a7110..f0208a9 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1090,6 +1090,11 @@ omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start, gc = irq_alloc_generic_chip("MPUIO", 1, irq_start, bank->base, handle_simple_irq); + if (!gc) { + dev_err(bank->dev, "Memory alloc failed for gc\n"); + return; + } + ct = gc->chip_types; /* NOTE: No ack required, reading IRQ status clears it. */ -- cgit v1.1 From a78f6787a3dd7223bf185895fdcea661b408dc0a Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 17:18:08 +0000 Subject: DocBook/drm: Eradicate inappropriate uses of the future tense Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 50 +++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index c279158..0527ff2 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -57,10 +57,10 @@ existing drivers. - First, we'll go over some typical driver initialization + First, we go over some typical driver initialization requirements, like setting up command buffers, creating an initial output configuration, and initializing core services. - Subsequent sections will cover core internals in more detail, + Subsequent sections cover core internals in more detail, providing implementation notes and examples. @@ -74,7 +74,7 @@ The core of every DRM driver is struct drm_driver. Drivers - will typically statically initialize a drm_driver structure, + typically statically initialize a drm_driver structure, then pass it to drm_init() at load time. @@ -155,7 +155,7 @@ In the example above, taken from the i915 DRM driver, the driver sets several flags indicating what core features it supports. - We'll go over the individual callbacks in later sections. Since + We go over the individual callbacks in later sections. Since flags indicate which features your driver supports to the DRM core, you need to set most of them prior to calling drm_init(). Some, like DRIVER_MODESET can be set later based on user supplied parameters, @@ -238,7 +238,7 @@ In this specific case, the driver requires AGP and supports - IRQs. DMA, as we'll see, is handled by device specific ioctls + IRQs. DMA, as discussed later, is handled by device specific ioctls in this case. It also supports the kernel mode setting APIs, though unlike in the actual i915 driver source, this example unconditionally exports KMS capability. @@ -315,7 +315,7 @@ Configuring the device - Obviously, device configuration will be device specific. + Obviously, device configuration is device specific. However, there are several common operations: finding a device's PCI resources, mapping them, and potentially setting up an IRQ handler. @@ -326,7 +326,7 @@ drm_get_resource_len() can be used to find BARs on the given drm_device struct. Once those values have been retrieved, the driver load function can call drm_addmap() to create a new - mapping for the BAR in question. Note you'll probably want a + mapping for the BAR in question. Note you probably want a drm_local_map_t in your driver private structure to track any mappings you create. @@ -357,7 +357,7 @@ - Once your interrupt handler is registered (it'll use your + Once your interrupt handler is registered (it uses your drm_driver.irq_handler as the actual interrupt handling function), you can safely enable interrupts on your device, assuming any other state your interrupt handler uses is also @@ -389,7 +389,7 @@ should support a memory manager. - If your driver supports memory management (it should!), you'll + If your driver supports memory management (it should!), you need to set that up at load time as well. How you initialize it depends on which memory manager you're using, TTM or GEM. @@ -430,13 +430,13 @@ have a type of TTM_GLOBAL_TTM_MEM. The size field for the global object should be sizeof(struct ttm_mem_global), and the init and release hooks should point at your driver specific init and - release routines, which will probably eventually call + release routines, which probably eventually call ttm_mem_global_init and ttm_mem_global_release respectively. Once your global TTM accounting structure is set up and initialized (done by calling ttm_global_item_ref on the global object you - just created), you'll need to create a buffer object TTM to + just created), you need to create a buffer object TTM to provide a pool for buffer object allocation by clients and the kernel itself. The type of this object should be TTM_GLOBAL_TTM_BO, and its size should be sizeof(struct ttm_bo_global). Again, @@ -455,8 +455,8 @@ than TTM, but has no VRAM management capability. Core GEM initialization is comprised of a basic drm_mm_init call to create a GTT DRM MM object, which provides an address space pool for - object allocation. In a KMS configuration, the driver will - need to allocate and initialize a command ring buffer following + object allocation. In a KMS configuration, the driver + needs to allocate and initialize a command ring buffer following basic GEM initialization. Most UMA devices have a so-called "stolen" memory region, which provides space for the initial framebuffer and large, contiguous memory regions required by the @@ -464,16 +464,16 @@ be initialized separately into its own DRM MM object. - Initialization will be driver specific, and will depend on + Initialization is driver specific, and depends on the architecture of the device. In the case of Intel integrated graphics chips like 965GM, GEM initialization can be done by calling the internal GEM init function, i915_gem_do_init(). Since the 965GM is a UMA device - (i.e. it doesn't have dedicated VRAM), GEM will manage + (i.e. it doesn't have dedicated VRAM), GEM manages making regular RAM available for GPU operations. Memory set aside by the BIOS (called "stolen" memory by the i915 - driver) will be managed by the DRM memrange allocator; the - rest of the aperture will be managed by GEM. + driver) is managed by the DRM memrange allocator; the + rest of the aperture is managed by GEM. /* Basic memrange allocator for stolen space (aka vram) */ drm_memrange_init(&dev_priv->vram, 0, prealloc_size); @@ -616,7 +616,7 @@ void intel_crt_init(struct drm_device *dev) DRM_IOCTL_MODESET_CTL should be called by application level drivers before and after mode setting, since on many devices the - vertical blank counter will be reset at that time. Internally, + vertical blank counter is reset at that time. Internally, the DRM snapshots the last vblank count when the ioctl is called with the _DRM_PRE_MODESET command so that the counter won't go backwards (which is dealt with when _DRM_POST_MODESET is used). @@ -632,8 +632,8 @@ void intel_crt_init(struct drm_device *dev) register. The enable and disable vblank callbacks should enable and disable vertical blank interrupts, respectively. In the absence of DRM clients waiting on vblank events, the core DRM - code will use the disable_vblank() function to disable - interrupts, which saves power. They'll be re-enabled again when + code uses the disable_vblank() function to disable + interrupts, which saves power. They are re-enabled again when a client calls the vblank wait ioctl above. @@ -699,14 +699,14 @@ void intel_crt_init(struct drm_device *dev) performs any necessary flushing or synchronization to put the object into the desired coherency domain (note that the object may be busy, i.e. an active render target; in that case the set domain function - will block the client and wait for rendering to complete before + blocks the client and waits for rendering to complete before performing any necessary flushing operations). Perhaps the most important GEM function is providing a command execution interface to clients. Client programs construct command buffers containing references to previously allocated memory objects - and submit them to GEM. At that point, GEM will take care to bind + and submit them to GEM. At that point, GEM takes care to bind all the objects into the GTT, execute the buffer, and provide necessary synchronization between clients accessing the same buffers. This often involves evicting some objects from the GTT and re-binding @@ -767,7 +767,7 @@ void intel_crt_init(struct drm_device *dev) In order to set a mode on a given CRTC, encoder and connector configuration, clients need to provide a framebuffer object which - will provide a source of pixels for the CRTC to deliver to the encoder(s) + provides a source of pixels for the CRTC to deliver to the encoder(s) and ultimately the connector(s) in the configuration. A framebuffer is fundamentally a driver specific memory object, made into an opaque handle by the DRM addfb function. Once an fb has been created this @@ -789,7 +789,7 @@ void intel_crt_init(struct drm_device *dev) The DRM core provides some suspend/resume code, but drivers wanting full suspend/resume support should provide save() and - restore() functions. These will be called at suspend, + restore() functions. These are called at suspend, hibernate, or resume time, and should perform any state save or restore required by your device across suspend or hibernate states. @@ -823,7 +823,7 @@ void intel_crt_init(struct drm_device *dev) Cover generic ioctls and sysfs layout here. Only need high - level info, since man pages will cover the rest. + level info, since man pages should cover the rest. -- cgit v1.1 From f11aca045c165b9d4c9c4fce29f51ec24bcf64d3 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 17:21:31 +0000 Subject: DocBook/drm: can -> may Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 0527ff2..b907938 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -32,7 +32,7 @@ The Linux DRM layer contains code intended to support the needs of complex graphics devices, usually containing programmable pipelines well suited to 3D graphics acceleration. Graphics - drivers in the kernel can make use of DRM functions to make + drivers in the kernel may make use of DRM functions to make tasks like memory management, interrupt handling and DMA easier, and provide a uniform interface to applications. @@ -293,12 +293,12 @@ can be used for tracking various device specific bits of information, like register offsets, command buffer status, register state for suspend/resume, etc. At load time, a - driver can simply allocate one and set drm_device.dev_priv + driver may simply allocate one and set drm_device.dev_priv appropriately; at unload the driver can free it and set drm_device.dev_priv to NULL. - The DRM supports several counters which can be used for rough + The DRM supports several counters which may be used for rough performance characterization. Note that the DRM stat counter system is not often used by applications, and supporting additional counters is completely optional. @@ -323,7 +323,7 @@ Finding & mapping resources is fairly straightforward. The DRM wrapper functions, drm_get_resource_start() and - drm_get_resource_len() can be used to find BARs on the given + drm_get_resource_len() may be used to find BARs on the given drm_device struct. Once those values have been retrieved, the driver load function can call drm_addmap() to create a new mapping for the BAR in question. Note you probably want a @@ -335,12 +335,12 @@ if compatibility with other operating systems isn't a concern (DRM drivers can run under various BSD variants and OpenSolaris), - native Linux calls can be used for the above, e.g. pci_resource_* + native Linux calls may be used for the above, e.g. pci_resource_* and iomap*/iounmap. See the Linux device driver book for more info. - Once you have a register map, you can use the DRM_READn() and + Once you have a register map, you may use the DRM_READn() and DRM_WRITEn() macros to access the registers on your device, or use driver specific versions to offset into your MMIO space relative to a driver specific base pointer (see I915_READ for @@ -440,7 +440,7 @@ provide a pool for buffer object allocation by clients and the kernel itself. The type of this object should be TTM_GLOBAL_TTM_BO, and its size should be sizeof(struct ttm_bo_global). Again, - driver specific init and release functions can be provided, + driver specific init and release functions may be provided, likely eventually calling ttm_bo_global_init and ttm_bo_global_release, respectively. Also like the previous object, ttm_global_item_ref is used to create an initial reference @@ -483,7 +483,7 @@ - Once the memory manager has been set up, we can allocate the + Once the memory manager has been set up, we may allocate the command buffer. In the i915 case, this is also done with a GEM function, i915_gem_init_ringbuffer(). @@ -572,7 +572,7 @@ void intel_crt_init(struct drm_device *dev) devices with PC-style architectures (i.e. a set of display planes for feeding pixels to encoders which are in turn routed to connectors). Devices with more complex requirements needing - finer grained management can opt to use the core callbacks + finer grained management may opt to use the core callbacks directly. @@ -637,7 +637,7 @@ void intel_crt_init(struct drm_device *dev) a client calls the vblank wait ioctl above. - Devices that don't provide a count register can simply use an + Devices that don't provide a count register may simply use an internal atomic counter incremented on every vertical blank interrupt, and can make their enable and disable vblank functions into no-ops. -- cgit v1.1 From 0c54781bc5aaec1e23bc50a4ef757b8e8bfc693b Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 17:55:54 +0000 Subject: DocBook/drm: Clean up code comment Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 4 ++-- drivers/gpu/drm/i915/i915_drv.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index b907938..4ddc999 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -88,8 +88,8 @@ static struct drm_driver driver = { - /* don't use mtrr's here, the Xserver or user space app should - * deal with them for intel hardware. + /* Don't use MTRRs here; the Xserver or userspace app should + * deal with them for Intel hardware. */ .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ce045a8..acf4ea8 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -785,8 +785,8 @@ static struct vm_operations_struct i915_gem_vm_ops = { }; static struct drm_driver driver = { - /* don't use mtrr's here, the Xserver or user space app should - * deal with them for intel hardware. + /* Don't use MTRRs here; the Xserver or userspace app should + * deal with them for Intel hardware. */ .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/ -- cgit v1.1 From 2c267e9e016da3e19a95261875a5f3b19dd6e9f6 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 18:10:12 +0000 Subject: DocBook/drm: Use a semicolon Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 4ddc999..aa13e08 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -154,8 +154,8 @@ In the example above, taken from the i915 DRM driver, the driver - sets several flags indicating what core features it supports. - We go over the individual callbacks in later sections. Since + sets several flags indicating what core features it supports; + we go over the individual callbacks in later sections. Since flags indicate which features your driver supports to the DRM core, you need to set most of them prior to calling drm_init(). Some, like DRIVER_MODESET can be set later based on user supplied parameters, @@ -647,8 +647,8 @@ void intel_crt_init(struct drm_device *dev) Memory management - The memory manager lies at the heart of many DRM operations, and - is also required to support advanced client features like OpenGL + The memory manager lies at the heart of many DRM operations; it + is required to support advanced client features like OpenGL pbuffers. The DRM currently contains two memory managers, TTM and GEM. -- cgit v1.1 From 02391f1fe7b4e5434e4c558dcae99b9368c84bf3 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 18:20:54 +0000 Subject: DocBook/drm: a -> an Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index aa13e08..5b815b8 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -203,7 +203,7 @@ DRIVER_HAVE_IRQDRIVER_IRQ_SHARED - DRIVER_HAVE_IRQ indicates whether the driver has a IRQ + DRIVER_HAVE_IRQ indicates whether the driver has an IRQ handler, DRIVER_IRQ_SHARED indicates whether the device & handler support shared IRQs (note that this is required of PCI drivers). -- cgit v1.1 From b1f95bdc1eb10e3d3c8a85b2f0bc08fa6c08ae5d Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 18:21:29 +0000 Subject: DocBook/drm: , -> . Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 5b815b8..a0f0f98 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -204,7 +204,7 @@ DRIVER_HAVE_IRQ indicates whether the driver has an IRQ - handler, DRIVER_IRQ_SHARED indicates whether the device & + handler. DRIVER_IRQ_SHARED indicates whether the device & handler support shared IRQs (note that this is required of PCI drivers). -- cgit v1.1 From 80c84e6f3c2c707ccb5d7b500e25bda69f0e1895 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 18:23:21 +0000 Subject: DocBook/drm: Move `should be set' to the beginning of the sentence Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index a0f0f98..42368f4 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -214,8 +214,8 @@ DRIVER_DMA_QUEUE - If the driver queues DMA requests and completes them - asynchronously, this flag should be set. Deprecated. + Should be set if the driver queues DMA requests and completes them + asynchronously. Deprecated. -- cgit v1.1 From 58f1d652def02db0bdcdf03d01f3483fc18ec392 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 18:31:42 +0000 Subject: DocBook/drm: Clean up `pre-memory management aware' Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 42368f4..e9242c0 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -273,7 +273,7 @@ conflict with DRM client requirements. For instance, if user level mode setting drivers are in use, it would be problematic to perform output discovery & configuration at load time. - Likewise, if pre-memory management aware user level drivers are + Likewise, if user-level drivers unaware of memory management are in use, memory management and command buffer setup may need to be omitted. These requirements are driver specific, and care needs to be taken to keep both old and new applications and -- cgit v1.1 From 75aa9df5a2bf2ae90a1f0f6f283278f634ca4233 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 18:34:49 +0000 Subject: DocBook/drm: Rearrange wording to make more sense Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index e9242c0..eb28cc0 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -281,9 +281,9 @@ module parameter to control whether advanced features are enabled at load time or in legacy fashion. If compatibility is a concern (e.g. with drivers converted over to the new interfaces - from the old ones), care must be taken to prevent incompatible - device initialization and control with the currently active - userspace drivers. + from the old ones), care must be taken to prevent device + initialization and control that is incompatible with + currently active userspace drivers. -- cgit v1.1 From 6e375f44b6073dd320895753ff05cbfd3f410f66 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 18:37:05 +0000 Subject: DocBook/drm: Replace the paragraph's first sentence with its last sentence Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index eb28cc0..9eda9b6 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -269,8 +269,10 @@ initial output configuration. - Note that the tasks performed at driver load time must not - conflict with DRM client requirements. For instance, if user + If compatibility is a concern (e.g. with drivers converted over + to the new interfaces from the old ones), care must be taken to + prevent device initialization and control that is incompatible with + currently active userspace drivers. For instance, if user level mode setting drivers are in use, it would be problematic to perform output discovery & configuration at load time. Likewise, if user-level drivers unaware of memory management are @@ -279,11 +281,7 @@ needs to be taken to keep both old and new applications and libraries working. The i915 driver supports the "modeset" module parameter to control whether advanced features are - enabled at load time or in legacy fashion. If compatibility is - a concern (e.g. with drivers converted over to the new interfaces - from the old ones), care must be taken to prevent device - initialization and control that is incompatible with - currently active userspace drivers. + enabled at load time or in legacy fashion. -- cgit v1.1 From 06fa7b8066d4dc3f6c9d4c4bf34f385d5a823f13 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 18:40:55 +0000 Subject: DocBook/drm: Better wording Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 9eda9b6..b4196c1 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -292,8 +292,8 @@ information, like register offsets, command buffer status, register state for suspend/resume, etc. At load time, a driver may simply allocate one and set drm_device.dev_priv - appropriately; at unload the driver can free it and set - drm_device.dev_priv to NULL. + appropriately; it should be freed and drm_device.dev_priv set + to NULL when the driver is unloaded. The DRM supports several counters which may be used for rough -- cgit v1.1 From 57a15fd663d6680dc100a537f0ed328993c33af2 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 18:42:36 +0000 Subject: DocBook/drm: Clearer wording with `for consumption by' Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index b4196c1..33290e3 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -305,8 +305,8 @@ These interfaces are deprecated and should not be used. If performance monitoring is desired, the developer should investigate and potentially enhance the kernel perf and tracing infrastructure to export - GPU related performance information to performance monitoring - tools and applications. + GPU related performance information for consumption by performance + monitoring tools and applications. -- cgit v1.1 From 8814630f0b59421e558f4403b79f5dc3a025a386 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 18:46:10 +0000 Subject: DocBook/drm: Insert missing `that' Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 33290e3..25e0f46 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -321,10 +321,10 @@ Finding & mapping resources is fairly straightforward. The DRM wrapper functions, drm_get_resource_start() and - drm_get_resource_len() may be used to find BARs on the given + drm_get_resource_len(), may be used to find BARs on the given drm_device struct. Once those values have been retrieved, the driver load function can call drm_addmap() to create a new - mapping for the BAR in question. Note you probably want a + mapping for the BAR in question. Note that you probably want a drm_local_map_t in your driver private structure to track any mappings you create. -- cgit v1.1 From f07faf693c59b449b6637ea056e5826c85dcd265 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 18:48:15 +0000 Subject: DocBook/drm: Insert missing `an' Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 25e0f46..1b2e3c3 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -342,7 +342,7 @@ DRM_WRITEn() macros to access the registers on your device, or use driver specific versions to offset into your MMIO space relative to a driver specific base pointer (see I915_READ for - example). + an example). If your device supports interrupt generation, you may want to -- cgit v1.1 From 5b658bf2bf9e47f9a67cd26b1c69e4441eaf04fc Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 18:49:11 +0000 Subject: DocBook/drm: `setup' is the noun; `to set up' is the verb Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 1b2e3c3..d2f1dda 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -346,7 +346,7 @@ If your device supports interrupt generation, you may want to - setup an interrupt handler at driver load time as well. This + set up an interrupt handler at driver load time as well. This is done using the drm_irq_install() function. If your device supports vertical blank interrupts, it should call drm_vblank_init() to initialize the core vblank handling code before -- cgit v1.1 From bb49a6a1f3303f9cf23a19f403c9b90cdff0e7da Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 18:50:14 +0000 Subject: DocBook/drm: `at driver load time' -> `when the driver is loaded' Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index d2f1dda..7001937 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -346,7 +346,7 @@ If your device supports interrupt generation, you may want to - set up an interrupt handler at driver load time as well. This + set up an interrupt handler when the driver is loaded. This is done using the drm_irq_install() function. If your device supports vertical blank interrupts, it should call drm_vblank_init() to initialize the core vblank handling code before -- cgit v1.1 From 9c2416adac986d7d90814d7985a0ea80ebea416f Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 18:56:12 +0000 Subject: DocBook/drm: Use the passive voice Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 7001937..03321eb 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -369,9 +369,9 @@ using the pci_map_rom() call, a convenience function that takes care of mapping the actual ROM, whether it has been shadowed into memory (typically at address 0xc0000) or exists - on the PCI device in the ROM BAR. Note that once you've - mapped the ROM and extracted any necessary information, be - sure to unmap it; on many devices the ROM address decoder is + on the PCI device in the ROM BAR. Note that after the ROM + has been mapped and any necessary information has been extracted, + it should be unmapped; on many devices the ROM address decoder is shared with other BARs, so leaving it mapped can cause undesired behavior like hangs or memory corruption. -- cgit v1.1 From 118bdd70bdd73b08dcc3920fa30a21be5bbbffae Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 18:57:04 +0000 Subject: DocBook/drm: Offset modifiers with commas Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 03321eb..ce145ba 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -371,7 +371,7 @@ shadowed into memory (typically at address 0xc0000) or exists on the PCI device in the ROM BAR. Note that after the ROM has been mapped and any necessary information has been extracted, - it should be unmapped; on many devices the ROM address decoder is + it should be unmapped; on many devices, the ROM address decoder is shared with other BARs, so leaving it mapped can cause undesired behavior like hangs or memory corruption. @@ -440,7 +440,7 @@ and its size should be sizeof(struct ttm_bo_global). Again, driver specific init and release functions may be provided, likely eventually calling ttm_bo_global_init and - ttm_bo_global_release, respectively. Also like the previous + ttm_bo_global_release, respectively. Also, like the previous object, ttm_global_item_ref is used to create an initial reference count for the TTM, which will call your initialization function. @@ -613,7 +613,7 @@ void intel_crt_init(struct drm_device *dev) DRM_IOCTL_MODESET_CTL should be called by application level - drivers before and after mode setting, since on many devices the + drivers before and after mode setting, since on many devices, the vertical blank counter is reset at that time. Internally, the DRM snapshots the last vblank count when the ioctl is called with the _DRM_PRE_MODESET command so that the counter won't go @@ -696,7 +696,7 @@ void intel_crt_init(struct drm_device *dev) set domain function, which evaluates an object's current domain and performs any necessary flushing or synchronization to put the object into the desired coherency domain (note that the object may be busy, - i.e. an active render target; in that case the set domain function + i.e. an active render target; in that case, the set domain function blocks the client and waits for rendering to complete before performing any necessary flushing operations). -- cgit v1.1 From 8d36ffae67d89a86e37e7745503743fec1ac695c Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 18:57:37 +0000 Subject: DocBook/drm: can -> could Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index ce145ba..60ddf4b 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -372,7 +372,7 @@ on the PCI device in the ROM BAR. Note that after the ROM has been mapped and any necessary information has been extracted, it should be unmapped; on many devices, the ROM address decoder is - shared with other BARs, so leaving it mapped can cause + shared with other BARs, so leaving it mapped could cause undesired behavior like hangs or memory corruption. -- cgit v1.1 From eb2b8d4273fb8b73821ca8dbc9c0de10e9879833 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 18:58:42 +0000 Subject: DocBook/drm: , -> : Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 60ddf4b..953c4cb 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -389,7 +389,7 @@ If your driver supports memory management (it should!), you need to set that up at load time as well. How you initialize - it depends on which memory manager you're using, TTM or GEM. + it depends on which memory manager you're using: TTM or GEM. TTM initialization @@ -647,7 +647,7 @@ void intel_crt_init(struct drm_device *dev) The memory manager lies at the heart of many DRM operations; it is required to support advanced client features like OpenGL - pbuffers. The DRM currently contains two memory managers, TTM + pbuffers. The DRM currently contains two memory managers: TTM and GEM. -- cgit v1.1 From 005d7f4a01d3c755c3abab38b7e380f0bbff475d Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 19:02:52 +0000 Subject: DocBook/drm: Insert missing comma Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 953c4cb..230c738 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -429,7 +429,7 @@ object should be sizeof(struct ttm_mem_global), and the init and release hooks should point at your driver specific init and release routines, which probably eventually call - ttm_mem_global_init and ttm_mem_global_release respectively. + ttm_mem_global_init and ttm_mem_global_release, respectively. Once your global TTM accounting structure is set up and initialized @@ -499,8 +499,8 @@ Output discovery and initialization - Several core functions exist to create CRTCs, encoders and - connectors, namely drm_crtc_init(), drm_connector_init() and + Several core functions exist to create CRTCs, encoders, and + connectors, namely drm_crtc_init(), drm_connector_init(), and drm_encoder_init(), along with several "helper" functions to perform common tasks. @@ -578,7 +578,7 @@ void intel_crt_init(struct drm_device *dev) - For each encoder, CRTC and connector, several functions must + For each encoder, CRTC, and connector, several functions must be provided, depending on the object type. Encoder objects need to provide a DPMS (basically on/off) function, mode fixup (for converting requested modes into native hardware timings), @@ -727,7 +727,7 @@ void intel_crt_init(struct drm_device *dev) Output management At the core of the DRM output management code is a set of - structures representing CRTCs, encoders and connectors. + structures representing CRTCs, encoders, and connectors. A CRTC is an abstraction representing a part of the chip that -- cgit v1.1 From 1c86de2216f678bfb6e2472af6e5c25b0df8d91f Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 19:14:26 +0000 Subject: DocBook/drm: Remove parentheses and unnecessary repetition Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 230c738..6b2a803 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -433,8 +433,8 @@ Once your global TTM accounting structure is set up and initialized - (done by calling ttm_global_item_ref on the global object you - just created), you need to create a buffer object TTM to + by calling ttm_global_item_ref on it, + you need to create a buffer object TTM to provide a pool for buffer object allocation by clients and the kernel itself. The type of this object should be TTM_GLOBAL_TTM_BO, and its size should be sizeof(struct ttm_bo_global). Again, -- cgit v1.1 From ae63d793a43888eeb1c16422252d987aa37ab96c Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 19:19:18 +0000 Subject: DocBook/drm: Insert `()' after function name Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 6b2a803..6977cd9 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -433,15 +433,15 @@ Once your global TTM accounting structure is set up and initialized - by calling ttm_global_item_ref on it, + by calling ttm_global_item_ref() on it, you need to create a buffer object TTM to provide a pool for buffer object allocation by clients and the kernel itself. The type of this object should be TTM_GLOBAL_TTM_BO, and its size should be sizeof(struct ttm_bo_global). Again, driver specific init and release functions may be provided, - likely eventually calling ttm_bo_global_init and - ttm_bo_global_release, respectively. Also, like the previous - object, ttm_global_item_ref is used to create an initial reference + likely eventually calling ttm_bo_global_init() and + ttm_bo_global_release(), respectively. Also, like the previous + object, ttm_global_item_ref() is used to create an initial reference count for the TTM, which will call your initialization function. -- cgit v1.1 From 049cc903e714a27805eae0c34a4c34902a385032 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 19:21:17 +0000 Subject: DocBook/drm: Streamline wording of GEM initialization Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 6977cd9..7c11d79 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -451,7 +451,7 @@ GEM is an alternative to TTM, designed specifically for UMA devices. It has simpler initialization and execution requirements than TTM, but has no VRAM management capability. Core GEM - initialization is comprised of a basic drm_mm_init call to create + is initialized by calling drm_mm_init() to create a GTT DRM MM object, which provides an address space pool for object allocation. In a KMS configuration, the driver needs to allocate and initialize a command ring buffer following -- cgit v1.1 From 482b2ad8e488e609bb3bb408a8e9ca17b73b17c6 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 19:37:24 +0000 Subject: DocBook/drm: basic -> core Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 7c11d79..d385e90 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -455,7 +455,7 @@ a GTT DRM MM object, which provides an address space pool for object allocation. In a KMS configuration, the driver needs to allocate and initialize a command ring buffer following - basic GEM initialization. Most UMA devices have a so-called + core GEM initialization. Most UMA devices have a so-called "stolen" memory region, which provides space for the initial framebuffer and large, contiguous memory regions required by the device. This space is not typically managed by GEM, and must -- cgit v1.1 From 54f2cb8fc930e08fd6156519b28c45d576615f82 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 19:41:37 +0000 Subject: DocBook/drm: Use a singular subject for grammatical cleanliness Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index d385e90..3470c6b 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -455,7 +455,7 @@ a GTT DRM MM object, which provides an address space pool for object allocation. In a KMS configuration, the driver needs to allocate and initialize a command ring buffer following - core GEM initialization. Most UMA devices have a so-called + core GEM initialization. A UMA device usually has a so-called "stolen" memory region, which provides space for the initial framebuffer and large, contiguous memory regions required by the device. This space is not typically managed by GEM, and must @@ -635,10 +635,10 @@ void intel_crt_init(struct drm_device *dev) a client calls the vblank wait ioctl above. - Devices that don't provide a count register may simply use an + A device that doesn't provide a count register may simply use an internal atomic counter incremented on every vertical blank - interrupt, and can make their enable and disable vblank - functions into no-ops. + interrupt (and then treat the enable_vblank() and disable_vblank() + callbacks as no-ops). -- cgit v1.1 From 9029bd7a42e3c32783866630ee3eb6b82e273544 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 19:42:20 +0000 Subject: DocBook/drm: The word `so-called'; I do not think it connotes what you think it connotes From Webster's Revised Unabridged Dictionary (1913) [web1913]: So-called \So"-called`\, a. So named; called by such a name (but perhaps called thus with doubtful propriety). From WordNet (r) 2.0 [wn]: so-called adj : doubtful or suspect; "these so-called experts are no help" [syn: {alleged(a)}, {supposed}] My strong conviction is that widespread use of 'so gennant' or 'sogennant' in German has led to the creeping misuse of 'so-called' in English (especially through technical writings). In English, it would be better to use: what is called or a better translation of 'so gennant': so named Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 3470c6b..66a114a 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -455,7 +455,7 @@ a GTT DRM MM object, which provides an address space pool for object allocation. In a KMS configuration, the driver needs to allocate and initialize a command ring buffer following - core GEM initialization. A UMA device usually has a so-called + core GEM initialization. A UMA device usually has what is called a "stolen" memory region, which provides space for the initial framebuffer and large, contiguous memory regions required by the device. This space is not typically managed by GEM, and must -- cgit v1.1 From 1dbd39c3ea3967c41a09e81c826499f7ae9c8180 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 19:48:32 +0000 Subject: DocBook/drm: Insert `it' for smooth reading Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 66a114a..15541b1 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -458,7 +458,7 @@ core GEM initialization. A UMA device usually has what is called a "stolen" memory region, which provides space for the initial framebuffer and large, contiguous memory regions required by the - device. This space is not typically managed by GEM, and must + device. This space is not typically managed by GEM, and it must be initialized separately into its own DRM MM object. -- cgit v1.1 From 3bf7df615612671271512aada7d83285f3fa731b Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 19:49:10 +0000 Subject: DocBook/drm: Remove redundancy Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 15541b1..c24f50c 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -462,8 +462,7 @@ be initialized separately into its own DRM MM object. - Initialization is driver specific, and depends on - the architecture of the device. In the case of Intel + Initialization is driver specific. In the case of Intel integrated graphics chips like 965GM, GEM initialization can be done by calling the internal GEM init function, i915_gem_do_init(). Since the 965GM is a UMA device -- cgit v1.1 From 327d6fb962f227a31d4b03869774287efca49c50 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 20:18:14 +0000 Subject: DocBook/drm: Clarify `final initialization' via better formatting Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index c24f50c..1bbeea7 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -490,10 +490,19 @@ Output configuration - The final initialization task is output configuration. This involves - finding and initializing the CRTCs, encoders and connectors - for your device, creating an initial configuration and - registering a framebuffer console driver. + The final initialization task is output configuration. This involves: + + + Finding and initializing the CRTCs, encoders, and connectors + for the device. + + + Creating an initial configuration. + + + Registering a framebuffer console driver. + + Output discovery and initialization -- cgit v1.1 From 8a9ba910ac3962e5adb4ce1f086adf1e21fa04d1 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 20:21:22 +0000 Subject: DocBook/drm: Use a colon Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 1bbeea7..790e634 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -508,7 +508,7 @@ Output discovery and initialization Several core functions exist to create CRTCs, encoders, and - connectors, namely drm_crtc_init(), drm_connector_init(), and + connectors, namely: drm_crtc_init(), drm_connector_init(), and drm_encoder_init(), along with several "helper" functions to perform common tasks. -- cgit v1.1 From 896ee65fb646f9a98243a9f69e5904dff394c78a Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 20:26:17 +0000 Subject: DocBook/drm: Remove extraneous commas Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 790e634..d2aee84 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -562,9 +562,9 @@ void intel_crt_init(struct drm_device *dev) In the example above (again, taken from the i915 driver), a CRT connector and encoder combination is created. A device - specific i2c bus is also created, for fetching EDID data and + specific i2c bus is also created for fetching EDID data and performing monitor detection. Once the process is complete, - the new connector is registered with sysfs, to make its + the new connector is registered with sysfs to make its properties available to applications. -- cgit v1.1 From 4dc0152d5780f04573046b06a3fb7c7ad9b81afa Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 20:29:32 +0000 Subject: DocBook/drm: Insert `the' for readability, and change `set' to `setting' Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index d2aee84..09e02f7 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -573,8 +573,8 @@ void intel_crt_init(struct drm_device *dev) Since many PC-class graphics devices have similar display output designs, the DRM provides a set of helper functions to make output management easier. The core helper routines handle - encoder re-routing and disabling of unused functions following - mode set. Using the helpers is optional, but recommended for + encoder re-routing and the disabling of unused functions following + mode setting. Using the helpers is optional, but recommended for devices with PC-style architectures (i.e. a set of display planes for feeding pixels to encoders which are in turn routed to connectors). Devices with more complex requirements needing -- cgit v1.1 From 65ffef508f23d5e67940cadc8eca2ae34738018a Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 20:55:58 +0000 Subject: DocBook/drm: Use an itemizedlist for what an encoder needs to provide Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 09e02f7..da011f2 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -586,17 +586,25 @@ void intel_crt_init(struct drm_device *dev) - For each encoder, CRTC, and connector, several functions must - be provided, depending on the object type. Encoder objects - need to provide a DPMS (basically on/off) function, mode fixup - (for converting requested modes into native hardware timings), - and prepare, set and commit functions for use by the core DRM - helper functions. Connector helpers need to provide mode fetch and - validity functions as well as an encoder matching function for - returning an ideal encoder for a given connector. The core - connector functions include a DPMS callback, (deprecated) - save/restore routines, detection, mode probing, property handling, - and cleanup functions. + Each encoder object needs to provide: + + + A DPMS (basically on/off) function. + + + A mode-fixup function (for converting requested modes into + native hardware timings). + + + Functions (prepare, set, and commit) for use by the core DRM + helper functions. + + + Connector helpers need to provide functions (mode-fetch, validity, + and encoder-matching) for returning an ideal encoder for a given + connector. The core connector functions include a DPMS callback, + save/restore routines (deprecated), detection, mode probing, + property handling, and cleanup functions. -- cgit v1.1 From 51b9500de28a1e5e7a2090de5d345d6d98581617 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 21:11:30 +0000 Subject: DocBook/drm: Use a for vblank ioctls Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index da011f2..457d56a 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -619,23 +619,34 @@ void intel_crt_init(struct drm_device *dev) VBlank event handling The DRM core exposes two vertical blank related ioctls: - DRM_IOCTL_WAIT_VBLANK and DRM_IOCTL_MODESET_CTL. + + + DRM_IOCTL_WAIT_VBLANK + + + This takes a struct drm_wait_vblank structure as its argument, + and it is used to block or request a signal when a specified + vblank event occurs. + + + + + DRM_IOCTL_MODESET_CTL + + + This should be called by application level drivers before and + after mode setting, since on many devices the vertical blank + counter is reset at that time. Internally, the DRM snapshots + the last vblank count when the ioctl is called with the + _DRM_PRE_MODESET command so that the counter won't go backwards + (which is dealt with when _DRM_POST_MODESET is used). + + + + - DRM_IOCTL_WAIT_VBLANK takes a struct drm_wait_vblank structure - as its argument, and is used to block or request a signal when a - specified vblank event occurs. - - - DRM_IOCTL_MODESET_CTL should be called by application level - drivers before and after mode setting, since on many devices, the - vertical blank counter is reset at that time. Internally, - the DRM snapshots the last vblank count when the ioctl is called - with the _DRM_PRE_MODESET command so that the counter won't go - backwards (which is dealt with when _DRM_POST_MODESET is used). - - To support the functions above, the DRM core provides several helper functions for tracking vertical blank counters, and requires drivers to provide several callbacks: -- cgit v1.1 From f877bd4ad5508e2f0653c31d05ffe0ad4e2bfe11 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Thu, 25 Aug 2011 21:16:15 +0000 Subject: DocBook/drm: Insert a comma Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 457d56a..0387970 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -638,7 +638,7 @@ void intel_crt_init(struct drm_device *dev) after mode setting, since on many devices the vertical blank counter is reset at that time. Internally, the DRM snapshots the last vblank count when the ioctl is called with the - _DRM_PRE_MODESET command so that the counter won't go backwards + _DRM_PRE_MODESET command, so that the counter won't go backwards (which is dealt with when _DRM_POST_MODESET is used). -- cgit v1.1 From 0c2d91a80a156208d2f9f3dfb01871ebcf4a9338 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Mon, 29 Aug 2011 15:59:56 +0000 Subject: DocBook/drm: Use an for fundamental GEM operations Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 0387970..c358367 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -709,9 +709,13 @@ void intel_crt_init(struct drm_device *dev) read & write, mapping, and domain ownership transfers. - On a fundamental level, GEM involves several operations: memory - allocation and freeing, command execution, and aperture management - at command execution time. Buffer object allocation is relatively + On a fundamental level, GEM involves several operations: + + Memory allocation and freeing + Command execution + Aperture management at command execution time + + Buffer object allocation is relatively straightforward and largely provided by Linux's shmem layer, which provides memory to back each object. When mapped into the GTT or used in a command buffer, the backing pages for an object are -- cgit v1.1 From 2d43f5d667273ba4975cb79782a46aa374dd8607 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Mon, 29 Aug 2011 16:00:55 +0000 Subject: DocBook/drm: Improve flow of GPU/CPU coherence sentence Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index c358367..ba20f9f 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -720,8 +720,9 @@ void intel_crt_init(struct drm_device *dev) provides memory to back each object. When mapped into the GTT or used in a command buffer, the backing pages for an object are flushed to memory and marked write combined so as to be coherent - with the GPU. Likewise, when the GPU finishes rendering to an object, - if the CPU accesses it, it must be made coherent with the CPU's view + with the GPU. Likewise, if the CPU accesses an object after the GPU + has finished rendering to the object, then the object must be made + coherent with the CPU's view of memory, usually involving GPU cache flushing of various kinds. This core CPU<->GPU coherency management is provided by the GEM set domain function, which evaluates an object's current domain and -- cgit v1.1 From b8c6e0fe46fcd60f58089365dd96dcf04f95263b Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Mon, 29 Aug 2011 17:34:00 +0000 Subject: DocBook/drm: Refer to the domain-setting function as a device-specific ioctl Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index ba20f9f..9ae328a 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -724,11 +724,11 @@ void intel_crt_init(struct drm_device *dev) has finished rendering to the object, then the object must be made coherent with the CPU's view of memory, usually involving GPU cache flushing of various kinds. - This core CPU<->GPU coherency management is provided by the GEM - set domain function, which evaluates an object's current domain and + This core CPU<->GPU coherency management is provided by a + device-specific ioctl, which evaluates an object's current domain and performs any necessary flushing or synchronization to put the object into the desired coherency domain (note that the object may be busy, - i.e. an active render target; in that case, the set domain function + i.e. an active render target; in that case, setting the domain blocks the client and waits for rendering to complete before performing any necessary flushing operations). -- cgit v1.1 From e355b2014da06458385902c47edf193a997895fc Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Mon, 29 Aug 2011 17:38:48 +0000 Subject: DocBook/drm: Better flow with `, and then' Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 9ae328a..0b6c59d 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -735,8 +735,8 @@ void intel_crt_init(struct drm_device *dev) Perhaps the most important GEM function is providing a command execution interface to clients. Client programs construct command - buffers containing references to previously allocated memory objects - and submit them to GEM. At that point, GEM takes care to bind + buffers containing references to previously allocated memory objects, + and then submit them to GEM. At that point, GEM takes care to bind all the objects into the GTT, execute the buffer, and provide necessary synchronization between clients accessing the same buffers. This often involves evicting some objects from the GTT and re-binding -- cgit v1.1 From 964d32dcbefcfda015bc33dc76414b05c6f512de Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Mon, 29 Aug 2011 17:41:31 +0000 Subject: DocBook/drm: Use `; otherwise,' Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 0b6c59d..606a989 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -743,7 +743,7 @@ void intel_crt_init(struct drm_device *dev) others (a fairly expensive operation), and providing relocation support which hides fixed GTT offsets from clients. Clients must take care not to submit command buffers that reference more objects - than can fit in the GTT or GEM will reject them and no rendering + than can fit in the GTT; otherwise, GEM will reject them and no rendering will occur. Similarly, if several objects in the buffer require fence registers to be allocated for correct rendering (e.g. 2D blits on pre-965 chips), care must be taken not to require more fence -- cgit v1.1 From 5a462d58c84a2f5ed161daced2c7df34357c6d3d Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Mon, 29 Aug 2011 17:58:46 +0000 Subject: DocBook/drm: Clean up the paragraph on framebuffer objects Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 606a989..a39e76b 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -795,14 +795,12 @@ void intel_crt_init(struct drm_device *dev) Framebuffer management - In order to set a mode on a given CRTC, encoder and connector - configuration, clients need to provide a framebuffer object which - provides a source of pixels for the CRTC to deliver to the encoder(s) - and ultimately the connector(s) in the configuration. A framebuffer - is fundamentally a driver specific memory object, made into an opaque - handle by the DRM addfb function. Once an fb has been created this - way it can be passed to the KMS mode setting routines for use in - a configuration. + Clients need to provide a framebuffer object which provides a source + of pixels for a CRTC to deliver to the encoder(s) and ultimately the + connector(s). A framebuffer is fundamentally a driver specific memory + object, made into an opaque handle by the DRM's addfb() function. + Once a framebuffer has been created this way, it may be passed to the + KMS mode setting routines for use in a completed configuration. -- cgit v1.1 From a5294e01f2777649834d218583e7a32b2dacb699 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Mon, 29 Aug 2011 18:05:52 +0000 Subject: DocBook/drm: `(device|driver) specific' -> `(device|driver)-specific' Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index a39e76b..65e14f9 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -238,7 +238,7 @@ In this specific case, the driver requires AGP and supports - IRQs. DMA, as discussed later, is handled by device specific ioctls + IRQs. DMA, as discussed later, is handled by device-specific ioctls in this case. It also supports the kernel mode setting APIs, though unlike in the actual i915 driver source, this example unconditionally exports KMS capability. @@ -277,7 +277,7 @@ to perform output discovery & configuration at load time. Likewise, if user-level drivers unaware of memory management are in use, memory management and command buffer setup may need to - be omitted. These requirements are driver specific, and care + be omitted. These requirements are driver-specific, and care needs to be taken to keep both old and new applications and libraries working. The i915 driver supports the "modeset" module parameter to control whether advanced features are @@ -288,7 +288,7 @@ Driver private & performance counters The driver private hangs off the main drm_device structure and - can be used for tracking various device specific bits of + can be used for tracking various device-specific bits of information, like register offsets, command buffer status, register state for suspend/resume, etc. At load time, a driver may simply allocate one and set drm_device.dev_priv @@ -313,7 +313,7 @@ Configuring the device - Obviously, device configuration is device specific. + Obviously, device configuration is device-specific. However, there are several common operations: finding a device's PCI resources, mapping them, and potentially setting up an IRQ handler. @@ -340,8 +340,8 @@ Once you have a register map, you may use the DRM_READn() and DRM_WRITEn() macros to access the registers on your device, or - use driver specific versions to offset into your MMIO space - relative to a driver specific base pointer (see I915_READ for + use driver-specific versions to offset into your MMIO space + relative to a driver-specific base pointer (see I915_READ for an example). @@ -399,7 +399,7 @@ and devices with dedicated video RAM (VRAM), i.e. most discrete graphics devices. If your device has dedicated RAM, supporting TTM is desirable. TTM also integrates tightly with your - driver specific buffer execution function. See the radeon + driver-specific buffer execution function. See the radeon driver for examples. @@ -427,7 +427,7 @@ created by the memory manager at runtime. Your global TTM should have a type of TTM_GLOBAL_TTM_MEM. The size field for the global object should be sizeof(struct ttm_mem_global), and the init and - release hooks should point at your driver specific init and + release hooks should point at your driver-specific init and release routines, which probably eventually call ttm_mem_global_init and ttm_mem_global_release, respectively. @@ -438,7 +438,7 @@ provide a pool for buffer object allocation by clients and the kernel itself. The type of this object should be TTM_GLOBAL_TTM_BO, and its size should be sizeof(struct ttm_bo_global). Again, - driver specific init and release functions may be provided, + driver-specific init and release functions may be provided, likely eventually calling ttm_bo_global_init() and ttm_bo_global_release(), respectively. Also, like the previous object, ttm_global_item_ref() is used to create an initial reference @@ -462,7 +462,7 @@ be initialized separately into its own DRM MM object. - Initialization is driver specific. In the case of Intel + Initialization is driver-specific. In the case of Intel integrated graphics chips like 965GM, GEM initialization can be done by calling the internal GEM init function, i915_gem_do_init(). Since the 965GM is a UMA device @@ -561,8 +561,8 @@ void intel_crt_init(struct drm_device *dev) In the example above (again, taken from the i915 driver), a - CRT connector and encoder combination is created. A device - specific i2c bus is also created for fetching EDID data and + CRT connector and encoder combination is created. A device-specific + i2c bus is also created for fetching EDID data and performing monitor detection. Once the process is complete, the new connector is registered with sysfs to make its properties available to applications. @@ -704,8 +704,8 @@ void intel_crt_init(struct drm_device *dev) GEM-enabled drivers must provide gem_init_object() and gem_free_object() callbacks to support the core memory - allocation routines. They should also provide several driver - specific ioctls to support command execution, pinning, buffer + allocation routines. They should also provide several driver-specific + ioctls to support command execution, pinning, buffer read & write, mapping, and domain ownership transfers. @@ -797,7 +797,7 @@ void intel_crt_init(struct drm_device *dev) Clients need to provide a framebuffer object which provides a source of pixels for a CRTC to deliver to the encoder(s) and ultimately the - connector(s). A framebuffer is fundamentally a driver specific memory + connector(s). A framebuffer is fundamentally a driver-specific memory object, made into an opaque handle by the DRM's addfb() function. Once a framebuffer has been created this way, it may be passed to the KMS mode setting routines for use in a completed configuration. @@ -807,7 +807,7 @@ void intel_crt_init(struct drm_device *dev) Command submission & fencing - This should cover a few device specific command submission + This should cover a few device-specific command submission implementations. @@ -840,7 +840,7 @@ void intel_crt_init(struct drm_device *dev) The DRM core exports several interfaces to applications, generally intended to be used through corresponding libdrm - wrapper functions. In addition, drivers export device specific + wrapper functions. In addition, drivers export device-specific interfaces for use by userspace drivers & device aware applications through ioctls and sysfs files. -- cgit v1.1 From 7f0925aca586b4a0cce81b06af7383d6aec59cc1 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Mon, 29 Aug 2011 18:07:13 +0000 Subject: DocBook/drm: `device aware' -> `device-aware' Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 65e14f9..9da9b28 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -841,7 +841,7 @@ void intel_crt_init(struct drm_device *dev) The DRM core exports several interfaces to applications, generally intended to be used through corresponding libdrm wrapper functions. In addition, drivers export device-specific - interfaces for use by userspace drivers & device aware + interfaces for use by userspace drivers & device-aware applications through ioctls and sysfs files. -- cgit v1.1 From bcd3cfc1213894ff955771508d46fa18d66e9328 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Mon, 29 Aug 2011 19:29:16 +0000 Subject: DocBook/drm: Clean up a todo-note Signed-off-by: Michael Witten --- Documentation/DocBook/drm.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 9da9b28..196b8b9 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -850,8 +850,8 @@ void intel_crt_init(struct drm_device *dev) management, memory management, and output management. - Cover generic ioctls and sysfs layout here. Only need high - level info, since man pages should cover the rest. + Cover generic ioctls and sysfs layout here. We only need high-level + info, since man pages should cover the rest. -- cgit v1.1 From 2cafbb37a135945ecc07d17f3484ed0dea1aa8b1 Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Mon, 2 May 2011 16:30:52 -0600 Subject: powerpc/5200: add support for charon board Signed-off-by: Heiko Schocher Acked-by: Benjamin Herrenschmidt Acked-by: Wolfram Sang [squashed with patch to add sm501 node] Signed-off-by: Grant Likely Signed-off-by: Anatolij Gustschin --- arch/powerpc/boot/dts/charon.dts | 236 +++++++++++++++++++++++++++ arch/powerpc/platforms/52xx/mpc5200_simple.c | 1 + 2 files changed, 237 insertions(+) create mode 100644 arch/powerpc/boot/dts/charon.dts diff --git a/arch/powerpc/boot/dts/charon.dts b/arch/powerpc/boot/dts/charon.dts new file mode 100644 index 0000000..0e00e50 --- /dev/null +++ b/arch/powerpc/boot/dts/charon.dts @@ -0,0 +1,236 @@ +/* + * charon board Device Tree Source + * + * Copyright (C) 2007 Semihalf + * Marian Balakowicz + * + * Copyright (C) 2010 DENX Software Engineering GmbH + * Heiko Schocher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/dts-v1/; + +/ { + model = "anon,charon"; + compatible = "anon,charon"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&mpc5200_pic>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,5200@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <32>; + i-cache-line-size = <32>; + d-cache-size = <0x4000>; // L1, 16K + i-cache-size = <0x4000>; // L1, 16K + timebase-frequency = <0>; // from bootloader + bus-frequency = <0>; // from bootloader + clock-frequency = <0>; // from bootloader + }; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x08000000>; // 128MB + }; + + soc5200@f0000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "fsl,mpc5200-immr"; + ranges = <0 0xf0000000 0x0000c000>; + reg = <0xf0000000 0x00000100>; + bus-frequency = <0>; // from bootloader + system-frequency = <0>; // from bootloader + + cdm@200 { + compatible = "fsl,mpc5200-cdm"; + reg = <0x200 0x38>; + }; + + mpc5200_pic: interrupt-controller@500 { + // 5200 interrupts are encoded into two levels; + interrupt-controller; + #interrupt-cells = <3>; + compatible = "fsl,mpc5200-pic"; + reg = <0x500 0x80>; + }; + + timer@600 { // General Purpose Timer + compatible = "fsl,mpc5200-gpt"; + reg = <0x600 0x10>; + interrupts = <1 9 0>; + fsl,has-wdt; + }; + + can@900 { + compatible = "fsl,mpc5200-mscan"; + interrupts = <2 17 0>; + reg = <0x900 0x80>; + }; + + can@980 { + compatible = "fsl,mpc5200-mscan"; + interrupts = <2 18 0>; + reg = <0x980 0x80>; + }; + + gpio_simple: gpio@b00 { + compatible = "fsl,mpc5200-gpio"; + reg = <0xb00 0x40>; + interrupts = <1 7 0>; + gpio-controller; + #gpio-cells = <2>; + }; + + usb@1000 { + compatible = "fsl,mpc5200-ohci","ohci-be"; + reg = <0x1000 0xff>; + interrupts = <2 6 0>; + }; + + dma-controller@1200 { + device_type = "dma-controller"; + compatible = "fsl,mpc5200-bestcomm"; + reg = <0x1200 0x80>; + interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 + 3 4 0 3 5 0 3 6 0 3 7 0 + 3 8 0 3 9 0 3 10 0 3 11 0 + 3 12 0 3 13 0 3 14 0 3 15 0>; + }; + + xlb@1f00 { + compatible = "fsl,mpc5200-xlb"; + reg = <0x1f00 0x100>; + }; + + serial@2000 { // PSC1 + compatible = "fsl,mpc5200-psc-uart"; + reg = <0x2000 0x100>; + interrupts = <2 1 0>; + }; + + serial@2400 { // PSC3 + compatible = "fsl,mpc5200-psc-uart"; + reg = <0x2400 0x100>; + interrupts = <2 3 0>; + }; + + ethernet@3000 { + compatible = "fsl,mpc5200-fec"; + reg = <0x3000 0x400>; + local-mac-address = [ 00 00 00 00 00 00 ]; + interrupts = <2 5 0>; + fixed-link = <1 1 100 0 0>; + }; + + mdio@3000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200-mdio"; + reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts + interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. + }; + + ata@3a00 { + compatible = "fsl,mpc5200-ata"; + reg = <0x3a00 0x100>; + interrupts = <2 7 0>; + }; + + i2c@3d00 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200-i2c","fsl-i2c"; + reg = <0x3d00 0x40>; + interrupts = <2 15 0>; + }; + + + i2c@3d40 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200-i2c","fsl-i2c"; + reg = <0x3d40 0x40>; + interrupts = <2 16 0>; + + dtt@28 { + compatible = "national,lm80"; + reg = <0x28>; + }; + + rtc@68 { + compatible = "dallas,ds1374"; + reg = <0x68>; + }; + }; + + sram@8000 { + compatible = "fsl,mpc5200-sram"; + reg = <0x8000 0x4000>; + }; + }; + + localbus { + compatible = "fsl,mpc5200-lpb","simple-bus"; + #address-cells = <2>; + #size-cells = <1>; + ranges = < 0 0 0xfc000000 0x02000000 + 1 0 0xe0000000 0x04000000 // CS1 range, SM501 + 3 0 0xe8000000 0x00080000>; + + flash@0,0 { + compatible = "cfi-flash"; + reg = <0 0 0x02000000>; + bank-width = <4>; + device-width = <2>; + #size-cells = <1>; + #address-cells = <1>; + }; + + display@1,0 { + compatible = "smi,sm501"; + reg = <1 0x00000000 0x00800000 + 1 0x03e00000 0x00200000>; + mode = "640x480-32@60"; + interrupts = <1 1 3>; + little-endian; + }; + + mram0@3,0 { + compatible = "mtd-ram"; + reg = <3 0x00000 0x80000>; + bank-width = <1>; + }; + }; + + pci@f0000d00 { + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + device_type = "pci"; + compatible = "fsl,mpc5200-pci"; + reg = <0xf0000d00 0x100>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = <0xc000 0 0 1 &mpc5200_pic 0 0 3 + 0xc000 0 0 2 &mpc5200_pic 0 0 3 + 0xc000 0 0 3 &mpc5200_pic 0 0 3 + 0xc000 0 0 4 &mpc5200_pic 0 0 3>; + clock-frequency = <0>; // From boot loader + interrupts = <2 8 0 2 9 0 2 10 0>; + bus-range = <0 0>; + ranges = <0x42000000 0 0x80000000 0x80000000 0 0x10000000 + 0x02000000 0 0x90000000 0x90000000 0 0x10000000 + 0x01000000 0 0x00000000 0xa0000000 0 0x01000000>; + }; +}; diff --git a/arch/powerpc/platforms/52xx/mpc5200_simple.c b/arch/powerpc/platforms/52xx/mpc5200_simple.c index e36d6e2..846b789 100644 --- a/arch/powerpc/platforms/52xx/mpc5200_simple.c +++ b/arch/powerpc/platforms/52xx/mpc5200_simple.c @@ -50,6 +50,7 @@ static void __init mpc5200_simple_setup_arch(void) /* list of the supported boards */ static const char *board[] __initdata = { + "anon,charon", "intercontrol,digsy-mtc", "manroland,mucmc52", "manroland,uc101", -- cgit v1.1 From 6ecc07b966977bb0855db1fa52d233c39fb3cafb Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Tue, 22 Mar 2011 09:27:32 +0100 Subject: powerpc, tqm5200: update tqm5200_defconfig to fit for charon board. added: CONFIG_MTD_OF_PARTS CONFIG_MTD_PLATRAM CONFIG_FIXED_PHY CONFIG_SENSORS_LM80 CONFIG_MFD_SM501 CONFIG_FB CONFIG_FB_FOREIGN_ENDIAN CONFIG_FB_SM501 CONFIG_FRAMEBUFFER_CONSOLE CONFIG_RTC_DRV_DS1374 Signed-off-by: Heiko Schocher Signed-off-by: Grant Likely Signed-off-by: Anatolij Gustschin --- arch/powerpc/configs/52xx/tqm5200_defconfig | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/configs/52xx/tqm5200_defconfig b/arch/powerpc/configs/52xx/tqm5200_defconfig index 959cd2c..716a37b 100644 --- a/arch/powerpc/configs/52xx/tqm5200_defconfig +++ b/arch/powerpc/configs/52xx/tqm5200_defconfig @@ -1,9 +1,10 @@ CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y +CONFIG_SPARSE_IRQ=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_BLK_DEV_INITRD=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_EXPERT=y +CONFIG_EMBEDDED=y # CONFIG_SYSCTL_SYSCALL is not set # CONFIG_KALLSYMS is not set # CONFIG_EPOLL is not set @@ -17,7 +18,6 @@ CONFIG_PPC_MPC5200_SIMPLE=y CONFIG_PPC_MPC5200_BUGFIX=y # CONFIG_PPC_PMAC is not set CONFIG_PPC_BESTCOMM=y -CONFIG_SPARSE_IRQ=y CONFIG_PM=y # CONFIG_PCI is not set CONFIG_NET=y @@ -38,17 +38,18 @@ CONFIG_MTD=y CONFIG_MTD_CONCAT=y CONFIG_MTD_PARTITIONS=y CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_OF_PARTS=y CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_ROM=y CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_PLATRAM=y CONFIG_PROC_DEVICETREE=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=32768 -# CONFIG_MISC_DEVICES is not set CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_SG=y CONFIG_ATA=y @@ -56,13 +57,11 @@ CONFIG_PATA_MPC52xx=y CONFIG_PATA_PLATFORM=y CONFIG_NETDEVICES=y CONFIG_LXT_PHY=y +CONFIG_FIXED_PHY=y CONFIG_NET_ETHERNET=y CONFIG_FEC_MPC52xx=y # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set -# CONFIG_INPUT is not set -# CONFIG_SERIO is not set -# CONFIG_VT is not set CONFIG_SERIAL_MPC52xx=y CONFIG_SERIAL_MPC52xx_CONSOLE=y CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 @@ -70,7 +69,13 @@ CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MPC=y +CONFIG_SENSORS_LM80=y CONFIG_WATCHDOG=y +CONFIG_MFD_SM501=y +CONFIG_FB=y +CONFIG_FB_FOREIGN_ENDIAN=y +CONFIG_FB_SM501=y +CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_USB=y CONFIG_USB_DEVICEFS=y # CONFIG_USB_DEVICE_CLASS is not set @@ -80,10 +85,10 @@ CONFIG_USB_OHCI_HCD_PPC_OF_BE=y CONFIG_USB_STORAGE=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=y +CONFIG_RTC_DRV_DS1374=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_INOTIFY=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_PROC_KCORE=y @@ -102,7 +107,6 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_PCBC=y # CONFIG_CRYPTO_ANSI_CPRNG is not set -- cgit v1.1 From dc9c0beecfeb4866fdbc245c295cf30d340b702c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 11 Oct 2011 15:19:43 -0400 Subject: piix: ICH7 MWDMA1 errata Based on libata commit c611bed7. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: David S. Miller --- drivers/ide/piix.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c index b59d04c..1892e81 100644 --- a/drivers/ide/piix.c +++ b/drivers/ide/piix.c @@ -331,7 +331,7 @@ static const struct ide_port_ops ich_port_ops = { .udma_mask = udma, \ } -#define DECLARE_ICH_DEV(udma) \ +#define DECLARE_ICH_DEV(mwdma, udma) \ { \ .name = DRV_NAME, \ .init_chipset = init_chipset_ich, \ @@ -340,7 +340,7 @@ static const struct ide_port_ops ich_port_ops = { .port_ops = &ich_port_ops, \ .pio_mask = ATA_PIO4, \ .swdma_mask = ATA_SWDMA2_ONLY, \ - .mwdma_mask = ATA_MWDMA12_ONLY, \ + .mwdma_mask = mwdma, \ .udma_mask = udma, \ } @@ -362,13 +362,15 @@ static const struct ide_port_info piix_pci_info[] __devinitdata = { /* 2: PIIX4 */ DECLARE_PIIX_DEV(ATA_UDMA2), /* 3: ICH0 */ - DECLARE_ICH_DEV(ATA_UDMA2), + DECLARE_ICH_DEV(ATA_MWDMA12_ONLY, ATA_UDMA2), /* 4: ICH */ - DECLARE_ICH_DEV(ATA_UDMA4), + DECLARE_ICH_DEV(ATA_MWDMA12_ONLY, ATA_UDMA4), /* 5: PIIX4 */ DECLARE_PIIX_DEV(ATA_UDMA4), - /* 6: ICH[2-7]/ICH[2-3]M/C-ICH/ICH5-SATA/ESB2/ICH8M */ - DECLARE_ICH_DEV(ATA_UDMA5), + /* 6: ICH[2-6]/ICH[2-3]M/C-ICH/ICH5-SATA/ESB2/ICH8M */ + DECLARE_ICH_DEV(ATA_MWDMA12_ONLY, ATA_UDMA5), + /* 7: ICH7/7-R, no MWDMA1 */ + DECLARE_ICH_DEV(ATA_MWDMA2_ONLY, ATA_UDMA5), }; /** @@ -438,9 +440,9 @@ static const struct pci_device_id piix_pci_tbl[] = { #endif { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ESB_2), 6 }, { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH6_19), 6 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH7_21), 6 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH7_21), 7 }, { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801DB_1), 6 }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ESB2_18), 6 }, + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ESB2_18), 7 }, { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH8_6), 6 }, { 0, }, }; -- cgit v1.1 From 839e7306e5d1ebd57cf12e83d9910b8b2dbe79ba Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Wed, 12 Oct 2011 04:31:51 +0000 Subject: IDE: Don't powerdown Compaq Triflex IDE device on suspend Don't powerdown Compaq Triflex IDE device on suspend This fixes APM suspend on Compaq Armada 7400. APM BIOS doesn't suspend if IDE is powered down when suspending. The Triflex controller is found only on old Compaq boards, so this patch will hopefully have no side effects. This patch fixes a suspend regression introduced in feb22b7f8e62b1b987a3a1dbad95af767a1df832 ("ide: add proper PCI PM support (v2)"). Signed-off-by: Mikulas Patocka [bart: add commit's summary in parens] Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: David S. Miller --- drivers/ide/triflex.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/ide/triflex.c b/drivers/ide/triflex.c index e53a1b7..281c914 100644 --- a/drivers/ide/triflex.c +++ b/drivers/ide/triflex.c @@ -113,12 +113,26 @@ static const struct pci_device_id triflex_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, triflex_pci_tbl); +#ifdef CONFIG_PM +static int triflex_ide_pci_suspend(struct pci_dev *dev, pm_message_t state) +{ + /* + * We must not disable or powerdown the device. + * APM bios refuses to suspend if IDE is not accessible. + */ + pci_save_state(dev); + return 0; +} +#else +#define triflex_ide_pci_suspend NULL +#endif + static struct pci_driver triflex_pci_driver = { .name = "TRIFLEX_IDE", .id_table = triflex_pci_tbl, .probe = triflex_init_one, .remove = ide_pci_remove, - .suspend = ide_pci_suspend, + .suspend = triflex_ide_pci_suspend, .resume = ide_pci_resume, }; -- cgit v1.1 From acc8dbe7f44f1bab6fcf21f2d5efb32ea92e19fd Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 12 Oct 2011 04:45:34 +0000 Subject: icside: DMA support fix Fix problem introduced by commit 5e37bdc ("ide: add struct ide_dma_ops (take 3)"): d.dma_ops shouldn't be cleared if we are going to use DMA. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: David S. Miller --- drivers/ide/icside.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c index 4a697a2..8716066 100644 --- a/drivers/ide/icside.c +++ b/drivers/ide/icside.c @@ -521,8 +521,8 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec) if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) { d.init_dma = icside_dma_init; d.port_ops = &icside_v6_port_ops; + } else d.dma_ops = NULL; - } ret = ide_host_register(host, &d, hws); if (ret) -- cgit v1.1 From 0ab3d8b3213c8bb55370b11fcc5321ee4f2c5e92 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 13 Oct 2011 00:28:54 +0000 Subject: cy82c693: fix PCI device selection Wrong PCI device may be selected by cy82c693_set_pio_mode() if modular IDE host drivers are used and there are additional IDE PCI devices installed in the system. Fix it. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: David S. Miller --- drivers/ide/cy82c693.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/ide/cy82c693.c b/drivers/ide/cy82c693.c index 67cbcfa..847553f 100644 --- a/drivers/ide/cy82c693.c +++ b/drivers/ide/cy82c693.c @@ -1,7 +1,7 @@ /* * Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer * Copyright (C) 1998-2002 Andre Hedrick , Integrator - * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz + * Copyright (C) 2007-2011 Bartlomiej Zolnierkiewicz * * CYPRESS CY82C693 chipset IDE controller * @@ -90,7 +90,7 @@ static void cy82c693_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) u8 time_16, time_8; /* select primary or secondary channel */ - if (hwif->index > 0) { /* drive is on the secondary channel */ + if (drive->dn > 1) { /* drive is on the secondary channel */ dev = pci_get_slot(dev->bus, dev->devfn+1); if (!dev) { printk(KERN_ERR "%s: tune_drive: " @@ -141,7 +141,7 @@ static void cy82c693_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) pci_write_config_byte(dev, CY82_IDE_SLAVE_IOW, time_16); pci_write_config_byte(dev, CY82_IDE_SLAVE_8BIT, time_8); } - if (hwif->index > 0) + if (drive->dn > 1) pci_dev_put(dev); } -- cgit v1.1 From cd8e368f475251c0e3c42203f21e68fa25afbb3d Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 18 Aug 2011 16:35:44 -0400 Subject: ktest: Add TEST_TYPE install option In testing one of my boxes, I found that I only wanted to build and install the kernel. I wanted to manually reboot the box and test it. Adding a TEST_TYPE option "install" allows this to happen. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 7 +++++++ tools/testing/ktest/sample.conf | 7 ++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 8d02ccb..e087cb4 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -2929,6 +2929,13 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { build $build_type or next; } + if ($test_type eq "install") { + get_version; + install; + success $i; + next; + } + if ($test_type ne "build") { my $failed = 0; start_monitor_and_boot or $failed = 1; diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf index b8bcd14..eadca3e 100644 --- a/tools/testing/ktest/sample.conf +++ b/tools/testing/ktest/sample.conf @@ -253,9 +253,10 @@ # The default test type (default test) # The test types may be: -# build - only build the kernel, do nothing else -# boot - build and boot the kernel -# test - build, boot and if TEST is set, run the test script +# build - only build the kernel, do nothing else +# install - build and install, but do nothing else (does not reboot) +# boot - build, install, and boot the kernel +# test - build, boot and if TEST is set, run the test script # (If TEST is not set, it defaults back to boot) # bisect - Perform a bisect on the kernel (see BISECT_TYPE below) # patchcheck - Do a test on a series of commits in git (see PATCHCHECK below) -- cgit v1.1 From a908a6659ba3e7eb52ea74a78e2f342978aa5f5b Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 12 Aug 2011 15:32:03 +0200 Subject: ktest: Create outputdir if it does not exist Signed-off-by: Andrew Jones Link: http://lkml.kernel.org/r/1313155932-20092-2-git-send-email-drjones@redhat.com Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index e087cb4..253e9a2 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -2850,9 +2850,11 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { chdir $builddir || die "can't change directory to $builddir"; - if (!-d $tmpdir) { - mkpath($tmpdir) or - die "can't create $tmpdir"; + foreach my $dir ($tmpdir, $outputdir) { + if (!-d $dir) { + mkpath($dir) or + die "can't create $dir"; + } } $ENV{"SSH_USER"} = $ssh_user; -- cgit v1.1 From 134882311cb9c2dca2ffadeabc5f8f9faa0fca81 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 12 Aug 2011 15:32:04 +0200 Subject: ktest: Only need to save .config when doing mrproper Only save the .config file if we're doing mrproper Signed-off-by: Andrew Jones Link: http://lkml.kernel.org/r/1313155932-20092-3-git-send-email-drjones@redhat.com Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 253e9a2..20b0e73 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -1272,15 +1272,15 @@ sub build { # allow for empty configs run_command "touch $output_config"; - run_command "mv $output_config $outputdir/config_temp" or - dodie "moving .config"; + if (!$noclean) { + run_command "mv $output_config $outputdir/config_temp" or + dodie "moving .config"; - if (!$noclean && !run_command "$make mrproper") { - dodie "make mrproper"; - } + run_command "$make mrproper" or dodie "make mrproper"; - run_command "mv $outputdir/config_temp $output_config" or - dodie "moving config_temp"; + run_command "mv $outputdir/config_temp $output_config" or + dodie "moving config_temp"; + } } elsif (!$noclean) { unlink "$output_config"; -- cgit v1.1 From 2728be418db65aa873ee354168b56f028845e956 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 12 Aug 2011 15:32:05 +0200 Subject: ktest: Include monitor in reboot code Several places that call reboot do the same thing with respect to the monitor. By adding this code into the reboot code, redundant code is removed and it paves the way for the the reset time patch. Signed-off-by: Andrew Jones Link: http://lkml.kernel.org/r/1313155932-20092-4-git-send-email-drjones@redhat.com Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 20b0e73..debc689 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -603,8 +603,13 @@ sub doprint { } sub run_command; +sub start_monitor; +sub end_monitor; +sub wait_for_monitor; sub reboot { + my ($time) = @_; + # try to reboot normally if (run_command $reboot) { if (defined($powercycle_after_reboot)) { @@ -615,6 +620,12 @@ sub reboot { # nope? power cycle it. run_command "$power_cycle"; } + + if (defined($time)) { + start_monitor; + wait_for_monitor $time; + end_monitor; + } } sub do_not_reboot { @@ -719,10 +730,7 @@ sub fail { # no need to reboot for just building. if (!do_not_reboot) { doprint "REBOOTING\n"; - reboot; - start_monitor; - wait_for_monitor $sleep_time; - end_monitor; + reboot $sleep_time; } my $name = ""; @@ -1356,10 +1364,7 @@ sub success { if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) { doprint "Reboot and wait $sleep_time seconds\n"; - reboot; - start_monitor; - wait_for_monitor $sleep_time; - end_monitor; + reboot $sleep_time; } } @@ -1500,10 +1505,7 @@ sub run_git_bisect { sub bisect_reboot { doprint "Reboot and sleep $bisect_sleep_time seconds\n"; - reboot; - start_monitor; - wait_for_monitor $bisect_sleep_time; - end_monitor; + reboot $bisect_sleep_time; } # returns 1 on success, 0 on failure, -1 on skip @@ -2066,10 +2068,7 @@ sub config_bisect { sub patchcheck_reboot { doprint "Reboot and sleep $patchcheck_sleep_time seconds\n"; - reboot; - start_monitor; - wait_for_monitor $patchcheck_sleep_time; - end_monitor; + reboot $patchcheck_sleep_time; } sub patchcheck { @@ -2659,10 +2658,7 @@ sub make_min_config { } doprint "Reboot and wait $sleep_time seconds\n"; - reboot; - start_monitor; - wait_for_monitor $sleep_time; - end_monitor; + reboot $sleep_time; } success $i; -- cgit v1.1 From eaa1fe25ea79e94c6727a67baaca3da0791da5de Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 14 Sep 2011 17:20:39 -0400 Subject: ktest: Fail when grub menu not found Currently if the grub menu that is supplied is not found, it will just boot into the last grub menu in menu.lst. Fail instead of confusing the user why their kernel is not booting. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index debc689..ca6ff99 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -862,9 +862,12 @@ sub get_grub_index { open(IN, "$ssh_grub |") or die "unable to get menu.lst"; + my $found = 0; + while () { if (/^\s*title\s+$grub_menu\s*$/) { $grub_number++; + $found = 1; last; } elsif (/^\s*title\s/) { $grub_number++; @@ -873,7 +876,7 @@ sub get_grub_index { close(IN); die "Could not find '$grub_menu' in /boot/grub/menu on $machine" - if ($grub_number < 0); + if (!$found); doprint "$grub_number\n"; } -- cgit v1.1 From e0a8742e3d4b7649be2ca6f22e7d45153505fc81 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 30 Sep 2011 17:50:48 -0400 Subject: ktest: Add NO_INSTALL option to not install for a test There's cases where running the same kernel over and over again is useful, and being able to not install the same kernel can save time between tests. Add a NO_INSTALL option that tells ktest.pl to not install the new kernel. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 10 +++++++++- tools/testing/ktest/sample.conf | 7 +++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index ca6ff99..74fb2ac 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -42,6 +42,7 @@ $default{"BISECT_MANUAL"} = 0; $default{"BISECT_SKIP"} = 1; $default{"SUCCESS_LINE"} = "login:"; $default{"DETECT_TRIPLE_FAULT"} = 1; +$default{"NO_INSTALL"} = 0; $default{"BOOTED_TIMEOUT"} = 1; $default{"DIE_ON_FAILURE"} = 1; $default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND"; @@ -84,6 +85,7 @@ my $grub_number; my $target; my $make; my $post_install; +my $no_install; my $noclean; my $minconfig; my $start_minconfig; @@ -1094,6 +1096,8 @@ sub do_post_install { sub install { + return if ($no_install); + run_scp "$outputdir/$build_target", "$target_image" or dodie "failed to copy image"; @@ -2810,6 +2814,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { $reboot_type = set_test_option("REBOOT_TYPE", $i); $grub_menu = set_test_option("GRUB_MENU", $i); $post_install = set_test_option("POST_INSTALL", $i); + $no_install = set_test_option("NO_INSTALL", $i); $reboot_script = set_test_option("REBOOT_SCRIPT", $i); $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i); $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i); @@ -2890,8 +2895,11 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { $run_type = "ERROR"; } + my $installme = ""; + $installme = " no_install" if ($no_install); + doprint "\n\n"; - doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n"; + doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n"; unlink $dmesg; unlink $buildlog; diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf index eadca3e..b3e0dc1 100644 --- a/tools/testing/ktest/sample.conf +++ b/tools/testing/ktest/sample.conf @@ -294,6 +294,13 @@ # or on some systems: #POST_INSTALL = ssh user@target /sbin/dracut -f /boot/initramfs-test.img $KERNEL_VERSION +# If for some reason you just want to boot the kernel and you do not +# want the test to install anything new. For example, you may just want +# to boot test the same kernel over and over and do not want to go through +# the hassle of installing anything, you can set this option to 1 +# (default 0) +#NO_INSTALL = 1 + # If there is a script that you require to run before the build is done # you can specify it with PRE_BUILD. # -- cgit v1.1 From 2b803365a6fa177ea7e1f64f645be1cb5dd39d55 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 30 Sep 2011 18:00:23 -0400 Subject: ktest: Add option REBOOT_SUCCESS_LINE to stop waiting after a reboot When ktest.pl reboots, it will usuall wait SLEEP_TIME seconds of idle console before starting the next test. By setting the REBOOT_SUCCESS_LINE, ktest will not wait SLEEP_TIME when it detects the line while rebooting to a new kernel. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 33 +++++++++++++++++++++++++++------ tools/testing/ktest/sample.conf | 10 ++++++++++ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 74fb2ac..51ddaa5 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -117,6 +117,7 @@ my $timeout; my $booted_timeout; my $detect_triplefault; my $console; +my $reboot_success_line; my $success_line; my $stop_after_success; my $stop_after_failure; @@ -612,6 +613,13 @@ sub wait_for_monitor; sub reboot { my ($time) = @_; + if (defined($time)) { + start_monitor; + # flush out current monitor + # May contain the reboot success line + wait_for_monitor 1; + } + # try to reboot normally if (run_command $reboot) { if (defined($powercycle_after_reboot)) { @@ -624,8 +632,7 @@ sub reboot { } if (defined($time)) { - start_monitor; - wait_for_monitor $time; + wait_for_monitor($time, $reboot_success_line); end_monitor; } } @@ -706,16 +713,29 @@ sub end_monitor { } sub wait_for_monitor { - my ($time) = @_; + my ($time, $stop) = @_; + my $full_line = ""; my $line; + my $booted = 0; doprint "** Wait for monitor to settle down **\n"; # read the monitor and wait for the system to calm down - do { + while (!$booted) { $line = wait_for_input($monitor_fp, $time); - print "$line" if (defined($line)); - } while (defined($line)); + last if (!defined($line)); + print "$line"; + $full_line .= $line; + + if (defined($stop) && $full_line =~ /$stop/) { + doprint "wait for monitor detected $stop\n"; + $booted = 1; + } + + if ($line =~ /\n/) { + $full_line = ""; + } + } print "** Monitor flushed **\n"; } @@ -2836,6 +2856,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { $console = set_test_option("CONSOLE", $i); $detect_triplefault = set_test_option("DETECT_TRIPLE_FAULT", $i); $success_line = set_test_option("SUCCESS_LINE", $i); + $reboot_success_line = set_test_option("REBOOT_SUCCESS_LINE", $i); $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i); $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i); $stop_test_after = set_test_option("STOP_TEST_AFTER", $i); diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf index b3e0dc1..67bc4e0 100644 --- a/tools/testing/ktest/sample.conf +++ b/tools/testing/ktest/sample.conf @@ -423,6 +423,14 @@ # (default "login:") #SUCCESS_LINE = login: +# To speed up between reboots, defining a line that the +# default kernel produces that represents that the default +# kernel has successfully booted and can be used to pass +# a new test kernel to it. Otherwise ktest.pl will wait till +# SLEEP_TIME to continue. +# (default undefined) +#REBOOT_SUCCESS_LINE = login: + # In case the console constantly fills the screen, having # a specified time to stop the test after success is recommended. # (in seconds) @@ -488,6 +496,8 @@ # another test. If a reboot to the reliable kernel happens, # we wait SLEEP_TIME for the console to stop producing output # before starting the next test. +# +# You can speed up reboot times even more by setting REBOOT_SUCCESS_LINE. # (default 60) #SLEEP_TIME = 60 -- cgit v1.1 From 4ab1cce5bdd87948b75ed4fe4a8629c0f76267ae Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 30 Sep 2011 18:12:20 -0400 Subject: ktest: Do not reboot on config or build issues Even if REBOOT_ON_ERROR is set, it becomes annoying that the target machine is rebooted when a config option is incorrect or a build fails. There's no reason to reboot the target for host only issues. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 51ddaa5..057676a 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -133,6 +133,9 @@ my %config_help; my %variable; my %force_config; +# do not force reboots on config problems +my $no_reboot = 1; + $config_help{"MACHINE"} = << "EOF" The machine hostname that you will test. EOF @@ -640,7 +643,7 @@ sub reboot { sub do_not_reboot { my $i = $iteration; - return $test_type eq "build" || + return $test_type eq "build" || $no_reboot || ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") || ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build"); } @@ -1285,6 +1288,10 @@ sub build { unlink $buildlog; + # Failed builds should not reboot the target + my $save_no_reboot = $no_reboot; + $no_reboot = 1; + if (defined($pre_build)) { my $ret = run_command $pre_build; if (!$ret && defined($pre_build_die) && @@ -1353,10 +1360,15 @@ sub build { if (!$build_ret) { # bisect may need this to pass - return 0 if ($in_bisect); + if ($in_bisect) { + $no_reboot = $save_no_reboot; + return 0; + } fail "failed build" and return 0; } + $no_reboot = $save_no_reboot; + return 1; } @@ -2806,6 +2818,9 @@ sub set_test_option { # First we need to do is the builds for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { + # Do not reboot on failing test options + $no_reboot = 1; + $iteration = $i; my $makecmd = set_test_option("MAKE_CMD", $i); @@ -2941,6 +2956,9 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { die "failed to checkout $checkout"; } + $no_reboot = 0; + + if ($test_type eq "bisect") { bisect $i; next; -- cgit v1.1 From 45d73a5d8a98dbabcdf37e2da5ef5b0412244643 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 30 Sep 2011 19:44:53 -0400 Subject: ktest: Add IF and ELSE to config sections Add IF keyword to sections within the config. Also added an ELSE keyword that allows different config options to be set for a given section. For example: TYPE := 1 STATUS := 0 DEFAULTS IF ${TYPE} [...] ELSE IF ${STATUS} [...] ELSE [...] The above will process the first section as $TYPE is true. If it was false, it would process the last section as $STATUS is false. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 64 ++++++++++++++++++++++++++++++++++++++--- tools/testing/ktest/sample.conf | 38 ++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 4 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 057676a..c76e18f 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -361,6 +361,21 @@ sub set_variable { } } +sub process_if { + my ($name, $value) = @_; + + my $val = process_variables($value); + + if ($val =~ /^\s*0\s*$/) { + return 0; + } elsif ($val =~ /^\s*\d+\s*$/) { + return 1; + } + + die ("$name: $.: Undefined variable $val in if statement\n"); + return 1; +} + sub read_config { my ($config) = @_; @@ -376,6 +391,8 @@ sub read_config { my $skip = 0; my $rest; my $test_case = 0; + my $if = 0; + my $if_set = 0; while () { @@ -397,7 +414,7 @@ sub read_config { $default = 0; $repeat = 1; - if ($rest =~ /\s+SKIP(.*)/) { + if ($rest =~ /\s+SKIP\b(.*)/) { $rest = $1; $skip = 1; } else { @@ -411,9 +428,16 @@ sub read_config { $repeat_tests{"$test_num"} = $repeat; } - if ($rest =~ /\s+SKIP(.*)/) { - $rest = $1; - $skip = 1; + if ($rest =~ /\sIF\s+(\S*)(.*)/) { + $rest = $2; + if (process_if($name, $1)) { + $if_set = 1; + } else { + $skip = 1; + } + $if = 1; + } else { + $if = 0; } if ($rest !~ /^\s*$/) { @@ -437,10 +461,42 @@ sub read_config { $skip = 0; } + if ($rest =~ /\sIF\s+(\S*)(.*)/) { + $if = 1; + $rest = $2; + if (process_if($name, $1)) { + $if_set = 1; + } else { + $skip = 1; + } + } else { + $if = 0; + } + if ($rest !~ /^\s*$/) { die "$name: $.: Gargbage found after DEFAULTS\n$_"; } + } elsif (/^\s*ELSE(.*)$/) { + if (!$if) { + die "$name: $.: ELSE found with out matching IF section\n$_"; + } + $rest = $1; + if ($if_set) { + $skip = 1; + } else { + $skip = 0; + + if ($rest =~ /\sIF\s+(\S*)(.*)/) { + # May be a ELSE IF section. + if (!process_if($name, $1)) { + $skip = 1; + } + } else { + $if = 0; + } + } + } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) { next if ($skip); diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf index 67bc4e0..6a0a0ba 100644 --- a/tools/testing/ktest/sample.conf +++ b/tools/testing/ktest/sample.conf @@ -72,6 +72,44 @@ # the same option name under the same test or as default # ktest will fail to execute, and no tests will run. # +# Both TEST_START and DEFAULTS sections can also have the IF keyword +# The value after the IF must evaluate into a 0 or non 0 positive +# integer, and can use the config variables (explained below). +# +# DEFAULTS IF ${IS_X86_32} +# +# The above will process the DEFAULTS section if the config +# variable IS_X86_32 evaluates to a non zero positive integer +# otherwise if it evaluates to zero, it will act the same +# as if the SKIP keyword was used. +# +# The ELSE keyword can be used directly after a section with +# a IF statement. +# +# TEST_START IF ${RUN_NET_TESTS} +# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-network +# +# ELSE +# +# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-normal +# +# +# The ELSE keyword can also contain an IF statement to allow multiple +# if then else sections. But all the sections must be either +# DEFAULT or TEST_START, they can not be a mixture. +# +# TEST_START IF ${RUN_NET_TESTS} +# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-network +# +# ELSE IF ${RUN_DISK_TESTS} +# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-tests +# +# ELSE IF ${RUN_CPU_TESTS} +# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-cpu +# +# ELSE +# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-network +# #### Config variables #### # -- cgit v1.1 From ab7a3f52cef5ff1c784de7adfbda3421b10754a4 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 30 Sep 2011 20:24:07 -0400 Subject: ktest: Let IF keyword take comparisons Allow ==, !=, <=, >=, <, and > to be used in IF statements to compare if a section should be processed or not. For example: BITS := 32 DEFAULTS IF ${BITS} == 32 MIN_CONFIG = ${CONFIG_DIR}/config-32 ELSE MIN_CONFIG = ${CONFIG_DIR}/config-64 Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 54 ++++++++++++++++++++++++++++++++++++----- tools/testing/ktest/sample.conf | 14 +++++++++++ 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index c76e18f..ed20d68 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -361,11 +361,47 @@ sub set_variable { } } +sub process_compare { + my ($lval, $cmp, $rval) = @_; + + # remove whitespace + + $lval =~ s/^\s*//; + $lval =~ s/\s*$//; + + $rval =~ s/^\s*//; + $rval =~ s/\s*$//; + + if ($cmp eq "==") { + return $lval eq $rval; + } elsif ($cmp eq "!=") { + return $lval ne $rval; + } + + my $statement = "$lval $cmp $rval"; + my $ret = eval $statement; + + # $@ stores error of eval + if ($@) { + return -1; + } + + return $ret; +} + sub process_if { my ($name, $value) = @_; my $val = process_variables($value); + if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) { + my $ret = process_compare($1, $2, $3); + if ($ret < 0) { + die "$name: $.: Unable to process comparison\n"; + } + return $ret; + } + if ($val =~ /^\s*0\s*$/) { return 0; } elsif ($val =~ /^\s*\d+\s*$/) { @@ -428,8 +464,8 @@ sub read_config { $repeat_tests{"$test_num"} = $repeat; } - if ($rest =~ /\sIF\s+(\S*)(.*)/) { - $rest = $2; + if ($rest =~ /\sIF\s+(.*)/) { + $rest = ""; if (process_if($name, $1)) { $if_set = 1; } else { @@ -461,14 +497,14 @@ sub read_config { $skip = 0; } - if ($rest =~ /\sIF\s+(\S*)(.*)/) { + if ($rest =~ /\sIF\s+(.*)/) { $if = 1; - $rest = $2; if (process_if($name, $1)) { $if_set = 1; } else { $skip = 1; } + $rest = ""; } else { $if = 0; } @@ -477,26 +513,32 @@ sub read_config { die "$name: $.: Gargbage found after DEFAULTS\n$_"; } - } elsif (/^\s*ELSE(.*)$/) { + } elsif (/^\s*ELSE\b(.*)$/) { if (!$if) { die "$name: $.: ELSE found with out matching IF section\n$_"; } $rest = $1; if ($if_set) { $skip = 1; + $rest = ""; } else { $skip = 0; - if ($rest =~ /\sIF\s+(\S*)(.*)/) { + if ($rest =~ /\sIF\s+(.*)/) { # May be a ELSE IF section. if (!process_if($name, $1)) { $skip = 1; } + $rest = ""; } else { $if = 0; } } + if ($rest !~ /^\s*$/) { + die "$name: $.: Gargbage found after DEFAULTS\n$_"; + } + } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) { next if ($skip); diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf index 6a0a0ba..4e8fb91 100644 --- a/tools/testing/ktest/sample.conf +++ b/tools/testing/ktest/sample.conf @@ -72,6 +72,8 @@ # the same option name under the same test or as default # ktest will fail to execute, and no tests will run. # +# +# # Both TEST_START and DEFAULTS sections can also have the IF keyword # The value after the IF must evaluate into a 0 or non 0 positive # integer, and can use the config variables (explained below). @@ -110,6 +112,18 @@ # ELSE # BUILD_TYPE = useconfig:${CONFIG_DIR}/config-network # +# The if statement may also have comparisons that will and for +# == and !=, strings may be used for both sides. +# +# BOX_TYPE := x86_32 +# +# DEFAULTS IF ${BOX_TYPE} == x86_32 +# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-32 +# ELSE +# BUILD_TYPE = useconfig:${CONFIG_DIR}/config-64 +# + + #### Config variables #### # -- cgit v1.1 From 2ed3b16128e93309758e62937e7f137ac9844227 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 30 Sep 2011 21:00:00 -0400 Subject: ktest: Add INCLUDE keyword to include other config files Have the reading of the config file allow reading of other config files using the INCLUDE keyword. This allows multiple config files to share config options. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 55 +++++++++++++++++++++++++++++++++++------ tools/testing/ktest/sample.conf | 32 ++++++++++++++++++++++-- 2 files changed, 78 insertions(+), 9 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index ed20d68..62de47d 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -412,15 +412,16 @@ sub process_if { return 1; } -sub read_config { - my ($config) = @_; +sub __read_config { + my ($config, $current_test_num) = @_; - open(IN, $config) || die "can't read file $config"; + my $in; + open($in, $config) || die "can't read file $config"; my $name = $config; $name =~ s,.*/(.*),$1,; - my $test_num = 0; + my $test_num = $$current_test_num; my $default = 1; my $repeat = 1; my $num_tests_set = 0; @@ -430,7 +431,7 @@ sub read_config { my $if = 0; my $if_set = 0; - while () { + while (<$in>) { # ignore blank lines and comments next if (/^\s*$/ || /\s*\#/); @@ -539,6 +540,33 @@ sub read_config { die "$name: $.: Gargbage found after DEFAULTS\n$_"; } + } elsif (/^\s*INCLUDE\s+(\S+)/) { + + next if ($skip); + + if (!$default) { + die "$name: $.: INCLUDE can only be done in default sections\n$_"; + } + + my $file = process_variables($1); + + if ($file !~ m,^/,) { + # check the path of the config file first + if ($config =~ m,(.*)/,) { + if (-f "$1/$file") { + $file = "$1/$file"; + } + } + } + + if ( ! -r $file ) { + die "$name: $.: Can't read file $file\n$_"; + } + + if (__read_config($file, \$test_num)) { + $test_case = 1; + } + } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) { next if ($skip); @@ -594,13 +622,26 @@ sub read_config { } } - close(IN); - if ($test_num) { $test_num += $repeat - 1; $opt{"NUM_TESTS"} = $test_num; } + close($in); + + $$current_test_num = $test_num; + + return $test_case; +} + +sub read_config { + my ($config) = @_; + + my $test_case; + my $test_num = 0; + + $test_case = __read_config $config, \$test_num; + # make sure we have all mandatory configs get_ktest_configs; diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf index 4e8fb91..ae2a93c 100644 --- a/tools/testing/ktest/sample.conf +++ b/tools/testing/ktest/sample.conf @@ -122,8 +122,36 @@ # ELSE # BUILD_TYPE = useconfig:${CONFIG_DIR}/config-64 # - - +# +# INCLUDE file +# +# The INCLUDE keyword may be used in DEFAULT sections. This will +# read another config file and process that file as well. The included +# file can include other files, add new test cases or default +# statements. Config variables will be passed to these files and changes +# to config variables will be seen by top level config files. Including +# a file is processed just like the contents of the file was cut and pasted +# into the top level file, except, that include files that end with +# TEST_START sections will have that section ended at the end of +# the include file. That is, an included file is included followed +# by another DEFAULT keyword. +# +# Unlike other files referenced in this config, the file path does not need +# to be absolute. If the file does not start with '/', then the directory +# that the current config file was located in is used. If no config by the +# given name is found there, then the current directory is searched. +# +# INCLUDE myfile +# DEFAULT +# +# is the same as: +# +# INCLUDE myfile +# +# Note, if the include file does not contain a full path, the file is +# searched first by the location of the original include file, and then +# by the location that ktest.pl was executed in. +# #### Config variables #### # -- cgit v1.1 From 0050b6bbef01d871a34a77685047190aa428b210 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 30 Sep 2011 21:10:30 -0400 Subject: ktest: Consolidate TEST_TYPE and DEFAULT code The code that handles parsing the TEST_TYPE and DEFAULT code share a lot of common functionality. Combine the two and add a if statement that does what is different between them. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 61 +++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 40 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 62de47d..b4f32e7 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -436,20 +436,29 @@ sub __read_config { # ignore blank lines and comments next if (/^\s*$/ || /\s*\#/); - if (/^\s*TEST_START(.*)/) { + if (/^\s*(TEST_START|DEFAULTS)\b(.*)/) { - $rest = $1; + my $type = $1; + $rest = $2; - if ($num_tests_set) { - die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; - } + my $old_test_num; + my $old_repeat; + + if ($type eq "TEST_START") { - my $old_test_num = $test_num; - my $old_repeat = $repeat; + if ($num_tests_set) { + die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; + } - $test_num += $repeat; - $default = 0; - $repeat = 1; + $old_test_num = $test_num; + $old_repeat = $repeat; + + $test_num += $repeat; + $default = 0; + $repeat = 1; + } else { + $default = 1; + } if ($rest =~ /\s+SKIP\b(.*)/) { $rest = $1; @@ -478,42 +487,14 @@ sub __read_config { } if ($rest !~ /^\s*$/) { - die "$name: $.: Gargbage found after TEST_START\n$_"; + die "$name: $.: Gargbage found after $type\n$_"; } - if ($skip) { + if ($skip && $type eq "TEST_START") { $test_num = $old_test_num; $repeat = $old_repeat; } - } elsif (/^\s*DEFAULTS(.*)$/) { - $default = 1; - - $rest = $1; - - if ($rest =~ /\s+SKIP(.*)/) { - $rest = $1; - $skip = 1; - } else { - $skip = 0; - } - - if ($rest =~ /\sIF\s+(.*)/) { - $if = 1; - if (process_if($name, $1)) { - $if_set = 1; - } else { - $skip = 1; - } - $rest = ""; - } else { - $if = 0; - } - - if ($rest !~ /^\s*$/) { - die "$name: $.: Gargbage found after DEFAULTS\n$_"; - } - } elsif (/^\s*ELSE\b(.*)$/) { if (!$if) { die "$name: $.: ELSE found with out matching IF section\n$_"; -- cgit v1.1 From 3d1cc41432b0491a39a3185b52bfa1d0411bba10 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 30 Sep 2011 22:14:21 -0400 Subject: ktest: Add OVERRIDE keyword to DEFAULTS section The OVERRIDE keyword will allow options defined in the given DEFAULTS section to override options defined in previous DEFAULT sections. Normally, options will error if they were previous defined. The OVERRIDE keyword allows options that have been previously defined to be changed in the given section. Note, the same option can not be defined in the same DEFAULT section even if that section is marked as OVERRIDE. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 37 +++++++++++++++++++++++++++++-------- tools/testing/ktest/sample.conf | 15 +++++++++++++++ 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index b4f32e7..7bce412 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -337,10 +337,17 @@ sub process_variables { } sub set_value { - my ($lvalue, $rvalue) = @_; + my ($lvalue, $rvalue, $override, $overrides, $name) = @_; if (defined($opt{$lvalue})) { - die "Error: Option $lvalue defined more than once!\n"; + if (!$override || defined(${$overrides}{$lvalue})) { + my $extra = ""; + if ($override) { + $extra = "In the same override section!\n"; + } + die "$name: $.: Option $lvalue defined more than once!\n$extra"; + } + ${$overrides}{$lvalue} = $rvalue; } if ($rvalue =~ /^\s*$/) { delete $opt{$lvalue}; @@ -430,6 +437,9 @@ sub __read_config { my $test_case = 0; my $if = 0; my $if_set = 0; + my $override = 0; + + my %overrides; while (<$in>) { @@ -443,6 +453,7 @@ sub __read_config { my $old_test_num; my $old_repeat; + $override = 0; if ($type eq "TEST_START") { @@ -468,10 +479,20 @@ sub __read_config { $skip = 0; } - if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) { - $repeat = $1; - $rest = $2; - $repeat_tests{"$test_num"} = $repeat; + if (!$skip) { + if ($type eq "TEST_START") { + if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) { + $repeat = $1; + $rest = $2; + $repeat_tests{"$test_num"} = $repeat; + } + } elsif ($rest =~ /\sOVERRIDE\b(.*)/) { + # DEFAULT only + $rest = $1; + $override = 1; + # Clear previous overrides + %overrides = (); + } } if ($rest =~ /\sIF\s+(.*)/) { @@ -573,10 +594,10 @@ sub __read_config { } if ($default || $lvalue =~ /\[\d+\]$/) { - set_value($lvalue, $rvalue); + set_value($lvalue, $rvalue, $override, \%overrides, $name); } else { my $val = "$lvalue\[$test_num\]"; - set_value($val, $rvalue); + set_value($val, $rvalue, $override, \%overrides, $name); if ($repeat > 1) { $repeats{$val} = $repeat; diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf index ae2a93c..0fd3ca3 100644 --- a/tools/testing/ktest/sample.conf +++ b/tools/testing/ktest/sample.conf @@ -72,6 +72,21 @@ # the same option name under the same test or as default # ktest will fail to execute, and no tests will run. # +# DEFAULTS OVERRIDE +# +# Options defined in the DEFAULTS section can not be duplicated +# even if they are defined in two different DEFAULT sections. +# This is done to catch mistakes where an option is added but +# the previous option was forgotten about and not commented. +# +# The OVERRIDE keyword can be added to a section to allow this +# section to override other DEFAULT sections values that have +# been defined previously. It will only override options that +# have been defined before its use. Options defined later +# in a non override section will still error. The same option +# can not be defined in the same section even if that section +# is marked OVERRIDE. +# # # # Both TEST_START and DEFAULTS sections can also have the IF keyword -- cgit v1.1 From 9900b5dc067551fcdcaec63d013b1d95b36835ae Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 30 Sep 2011 22:41:14 -0400 Subject: ktest: Add DEFINED keyword for IF statements Have IF statements process if a config variable or option has been defined or not. Can use NOT DEFINED in the case for telling if a variable or option has not been defined. DEFAULTS IF NOT DEFINED SSH_USER SSH_USER = root Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 17 ++++++++++++++++- tools/testing/ktest/sample.conf | 17 +++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 7bce412..76a5964 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -396,6 +396,13 @@ sub process_compare { return $ret; } +sub value_defined { + my ($val) = @_; + + return defined($variable{$2}) || + defined($opt{$2}); +} + sub process_if { my ($name, $value) = @_; @@ -409,13 +416,21 @@ sub process_if { return $ret; } + if ($val =~ /^\s*(NOT\s*)?DEFINED\s+(\S+)\s*$/) { + if (defined $1) { + return !value_defined($2); + } else { + return value_defined($2); + } + } + if ($val =~ /^\s*0\s*$/) { return 0; } elsif ($val =~ /^\s*\d+\s*$/) { return 1; } - die ("$name: $.: Undefined variable $val in if statement\n"); + die ("$name: $.: Undefined content $val in if statement\n"); return 1; } diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf index 0fd3ca3..7b49f07 100644 --- a/tools/testing/ktest/sample.conf +++ b/tools/testing/ktest/sample.conf @@ -137,6 +137,23 @@ # ELSE # BUILD_TYPE = useconfig:${CONFIG_DIR}/config-64 # +# The DEFINED keyword can be used by the IF statements too. +# It returns true if the given config variable or option has been defined +# or false otherwise. +# +# +# DEFAULTS IF DEFINED USE_CC +# CC := ${USE_CC} +# ELSE +# CC := gcc +# +# +# As well as NOT DEFINED. +# +# DEFAULTS IF NOT DEFINED MAKE_CMD +# MAKE_CMD := make ARCH=x86 +# +# # # INCLUDE file # -- cgit v1.1 From ac6974c76e66c2f9b8b8a23b974c5f3d94302e81 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 4 Oct 2011 09:40:17 -0400 Subject: ktest: Sort make_min_config configs by dependecies The make_min_config test will turn off one config at a time and check if the config boots or not, and if it does, it will remove that config plus any config that depended on that config. ktest already looks if a config has a dependency and will try the dependency config first. But by sorting the configs and trying the config with the most configs dependent on it, we can shrink the minconfig faster. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 71 ++++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 22 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 76a5964..2a9d042 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -2372,12 +2372,31 @@ sub patchcheck { } my %depends; +my %depcount; my $iflevel = 0; my @ifdeps; # prevent recursion my %read_kconfigs; +sub add_dep { + # $config depends on $dep + my ($config, $dep) = @_; + + if (defined($depends{$config})) { + $depends{$config} .= " " . $dep; + } else { + $depends{$config} = $dep; + } + + # record the number of configs depending on $dep + if (defined $depcount{$dep}) { + $depcount{$dep}++; + } else { + $depcount{$dep} = 1; + } +} + # taken from streamline_config.pl sub read_kconfig { my ($kconfig) = @_; @@ -2424,30 +2443,19 @@ sub read_kconfig { $config = $2; for (my $i = 0; $i < $iflevel; $i++) { - if ($i) { - $depends{$config} .= " " . $ifdeps[$i]; - } else { - $depends{$config} = $ifdeps[$i]; - } - $state = "DEP"; + add_dep $config, $ifdeps[$i]; } # collect the depends for the config } elsif ($state eq "NEW" && /^\s*depends\s+on\s+(.*)$/) { - if (defined($depends{$1})) { - $depends{$config} .= " " . $1; - } else { - $depends{$config} = $1; - } + add_dep $config, $1; # Get the configs that select this config - } elsif ($state ne "NONE" && /^\s*select\s+(\S+)/) { - if (defined($depends{$1})) { - $depends{$1} .= " " . $config; - } else { - $depends{$1} = $config; - } + } elsif ($state eq "NEW" && /^\s*select\s+(\S+)/) { + + # selected by depends on config + add_dep $1, $config; # Check for if statements } elsif (/^if\s+(.*\S)\s*$/) { @@ -2559,11 +2567,18 @@ sub make_new_config { close OUT; } +sub chomp_config { + my ($config) = @_; + + $config =~ s/CONFIG_//; + + return $config; +} + sub get_depends { my ($dep) = @_; - my $kconfig = $dep; - $kconfig =~ s/CONFIG_//; + my $kconfig = chomp_config $dep; $dep = $depends{"$kconfig"}; @@ -2613,8 +2628,7 @@ sub test_this_config { return undef; } - my $kconfig = $config; - $kconfig =~ s/CONFIG_//; + my $kconfig = chomp_config $config; # Test dependencies first if (defined($depends{"$kconfig"})) { @@ -2704,6 +2718,14 @@ sub make_min_config { my @config_keys = keys %min_configs; + # All configs need a depcount + foreach my $config (@config_keys) { + my $kconfig = chomp_config $config; + if (!defined $depcount{$kconfig}) { + $depcount{$kconfig} = 0; + } + } + # Remove anything that was set by the make allnoconfig # we shouldn't need them as they get set for us anyway. foreach my $config (@config_keys) { @@ -2742,8 +2764,13 @@ sub make_min_config { # Now disable each config one by one and do a make oldconfig # till we find a config that changes our list. - # Put configs that did not modify the config at the end. my @test_configs = keys %min_configs; + + # Sort keys by who is most dependent on + @test_configs = sort { $depcount{chomp_config($b)} <=> $depcount{chomp_config($a)} } + @test_configs ; + + # Put configs that did not modify the config at the end. my $reset = 1; for (my $i = 0; $i < $#test_configs; $i++) { if (!defined($nochange_config{$test_configs[0]})) { -- cgit v1.1 From a9f84424be8d12e8a84b9eac112cd1152587d437 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 17 Oct 2011 11:06:29 -0400 Subject: ktest: Fix parsing of config section lines The order for some of the keywords on a section line (TEST_START or DEFAULTS) does not really matter. Simply need to remove the keyword from the line as we process it and evaluate the next keyword in the line. By removing the keywords as we find them, we do not need to keep track of where on the line they were found. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 49 ++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 2a9d042..d292c2d 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -449,6 +449,7 @@ sub __read_config { my $num_tests_set = 0; my $skip = 0; my $rest; + my $line; my $test_case = 0; my $if = 0; my $if_set = 0; @@ -465,6 +466,7 @@ sub __read_config { my $type = $1; $rest = $2; + $line = $2; my $old_test_num; my $old_repeat; @@ -486,32 +488,28 @@ sub __read_config { $default = 1; } - if ($rest =~ /\s+SKIP\b(.*)/) { - $rest = $1; + # If SKIP is anywhere in the line, the command will be skipped + if ($rest =~ s/\s+SKIP\b//) { $skip = 1; } else { $test_case = 1; $skip = 0; } - if (!$skip) { - if ($type eq "TEST_START") { - if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) { - $repeat = $1; - $rest = $2; - $repeat_tests{"$test_num"} = $repeat; - } - } elsif ($rest =~ /\sOVERRIDE\b(.*)/) { - # DEFAULT only - $rest = $1; - $override = 1; - # Clear previous overrides - %overrides = (); + if ($rest =~ s/\sELSE\b//) { + if (!$if) { + die "$name: $.: ELSE found with out matching IF section\n$_"; + } + $if = 0; + + if ($if_set) { + $skip = 1; + } else { + $skip = 0; } } - if ($rest =~ /\sIF\s+(.*)/) { - $rest = ""; + if ($rest =~ s/\sIF\s+(.*)//) { if (process_if($name, $1)) { $if_set = 1; } else { @@ -520,9 +518,24 @@ sub __read_config { $if = 1; } else { $if = 0; + $if_set = 0; } - if ($rest !~ /^\s*$/) { + if (!$skip) { + if ($type eq "TEST_START") { + if ($rest =~ s/\s+ITERATE\s+(\d+)//) { + $repeat = $1; + $repeat_tests{"$test_num"} = $repeat; + } + } elsif ($rest =~ s/\sOVERRIDE\b//) { + # DEFAULT only + $override = 1; + # Clear previous overrides + %overrides = (); + } + } + + if (!$skip && $rest !~ /^\s*$/) { die "$name: $.: Gargbage found after $type\n$_"; } -- cgit v1.1 From 8d735212e441af855afd28ccc402fcaf12999f8d Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 17 Oct 2011 11:36:44 -0400 Subject: ktest: Add processing of complex conditionals The IF statements for DEFAULTS and TEST_START sections now handle complex statements (&&,||) Example: TEST_START IF (DEFINED ALL_TESTS || ${MYTEST} == boottest) && ${MACHINE} == gandalf Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 53 +++++++++++++++++++++++++++++++++++++---- tools/testing/ktest/sample.conf | 10 ++++++++ 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index d292c2d..1bda07f 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -304,7 +304,7 @@ sub get_ktest_configs { } sub process_variables { - my ($value) = @_; + my ($value, $remove_undef) = @_; my $retval = ""; # We want to check for '\', and it is just easier @@ -322,6 +322,10 @@ sub process_variables { $retval = "$retval$begin"; if (defined($variable{$var})) { $retval = "$retval$variable{$var}"; + } elsif (defined($remove_undef) && $remove_undef) { + # for if statements, any variable that is not defined, + # we simple convert to 0 + $retval = "${retval}0"; } else { # put back the origin piece. $retval = "$retval\$\{$var\}"; @@ -403,10 +407,40 @@ sub value_defined { defined($opt{$2}); } -sub process_if { - my ($name, $value) = @_; +my $d = 0; +sub process_expression { + my ($name, $val) = @_; + + my $c = $d++; + + while ($val =~ s/\(([^\(]*?)\)/\&\&\&\&VAL\&\&\&\&/) { + my $express = $1; + + if (process_expression($name, $express)) { + $val =~ s/\&\&\&\&VAL\&\&\&\&/ 1 /; + } else { + $val =~ s/\&\&\&\&VAL\&\&\&\&/ 0 /; + } + } + + $d--; + my $OR = "\\|\\|"; + my $AND = "\\&\\&"; - my $val = process_variables($value); + while ($val =~ s/^(.*?)($OR|$AND)//) { + my $express = $1; + my $op = $2; + + if (process_expression($name, $express)) { + if ($op eq "||") { + return 1; + } + } else { + if ($op eq "&&") { + return 0; + } + } + } if ($val =~ /(.*)(==|\!=|>=|<=|>|<)(.*)/) { my $ret = process_compare($1, $2, $3); @@ -431,7 +465,16 @@ sub process_if { } die ("$name: $.: Undefined content $val in if statement\n"); - return 1; +} + +sub process_if { + my ($name, $value) = @_; + + # Convert variables and replace undefined ones with 0 + my $val = process_variables($value, 1); + my $ret = process_expression $name, $val; + + return $ret; } sub __read_config { diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf index 7b49f07..dbedfa1 100644 --- a/tools/testing/ktest/sample.conf +++ b/tools/testing/ktest/sample.conf @@ -154,6 +154,16 @@ # MAKE_CMD := make ARCH=x86 # # +# And/or ops (&&,||) may also be used to make complex conditionals. +# +# TEST_START IF (DEFINED ALL_TESTS || ${MYTEST} == boottest) && ${MACHINE} == gandalf +# +# Notice the use of paranthesis. Without any paranthesis the above would be +# processed the same as: +# +# TEST_START IF DEFINED ALL_TESTS || (${MYTEST} == boottest && ${MACHINE} == gandalf) +# +# # # INCLUDE file # -- cgit v1.1 From c54367f9d6be8e19c6e98ae7038438f0377ee138 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 20 Oct 2011 09:56:41 -0400 Subject: ktest: Do not opencode reboot in grub setting When setting the next kernel to boot to with grub, do not opencode the reboot operation. The normal reboot operation can be modified by config options (namely POWERCYCLE_AFTER_REBOOT). This needs to affect all reboots. Remove the opencoded reboot to make sure that any changes to the reboot code also affect all reboots. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 1bda07f..d60c496 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -1150,7 +1150,8 @@ sub wait_for_input sub reboot_to { if ($reboot_type eq "grub") { - run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch && reboot)'"; + run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch)'"; + reboot; return; } -- cgit v1.1 From 9f7424cc86adf55c3fccaa1160b6cf5c6cfc4c02 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Sat, 22 Oct 2011 08:58:19 -0400 Subject: ktest: Add another monitor flush before installing kernel On some tests that do multiple boots (patchcheck, bisect, etc), the build of the next kernel to run may finish before the stable kernel has finished booting. Then the install of the new kernel will fail when it tries to connect as the machine has not finished the boot process. Do one more monitor flush to make sure the machine is up and running before trying to connect to it again. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index d60c496..652446d 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -1391,6 +1391,11 @@ sub get_version { } sub start_monitor_and_boot { + # Make sure the stable kernel has finished booting + start_monitor; + wait_for_monitor 5; + end_monitor; + get_grub_index; get_version; install; -- cgit v1.1 From 7bf5107347d94bb056c5a0cf78f09e499c3d8f48 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Sat, 22 Oct 2011 09:07:03 -0400 Subject: ktest: Add variable ${PWD} Adding the variable ${PWD} that equals `pwd` makes the config files much simpler. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 652446d..9d9ee32 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -136,6 +136,9 @@ my %force_config; # do not force reboots on config problems my $no_reboot = 1; +# default variables that can be used +chomp ($variable{"PWD"} = `pwd`); + $config_help{"MACHINE"} = << "EOF" The machine hostname that you will test. EOF -- cgit v1.1 From c2bc11113c50449f23c40b724fe410fc2380a8e9 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 27 Oct 2011 18:12:42 -0700 Subject: time: Improve documentation of timekeeeping_adjust() After getting a number of questions in private emails about the math around admittedly very complex timekeeping_adjust() and timekeeping_big_adjust(), I figure the code needs some better comments. Hopefully the explanations are clear enough and don't muddy the water any worse. Still needs documentation for ntp_error, but I couldn't recall exactly the full explanation behind the code that's there (although I do recall once working it out when Roman first proposed it). Given a bit more time I can probably work it out, but I don't want to hold back this documentation until then. Signed-off-by: John Stultz Cc: Chen Jie Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1319764362-32367-1-git-send-email-john.stultz@linaro.org Signed-off-by: Ingo Molnar --- kernel/time/timekeeping.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 2b021b0e..025e136 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -802,14 +802,44 @@ static void timekeeping_adjust(s64 offset) s64 error, interval = timekeeper.cycle_interval; int adj; + /* + * The point of this is to check if the error is greater then half + * an interval. + * + * First we shift it down from NTP_SHIFT to clocksource->shifted nsecs. + * + * Note we subtract one in the shift, so that error is really error*2. + * This "saves" dividing(shifting) intererval twice, but keeps the + * (error > interval) comparision as still measuring if error is + * larger then half an interval. + * + * Note: It does not "save" on aggrivation when reading the code. + */ error = timekeeper.ntp_error >> (timekeeper.ntp_error_shift - 1); if (error > interval) { + /* + * We now divide error by 4(via shift), which checks if + * the error is greater then twice the interval. + * If it is greater, we need a bigadjust, if its smaller, + * we can adjust by 1. + */ error >>= 2; + /* + * XXX - In update_wall_time, we round up to the next + * nanosecond, and store the amount rounded up into + * the error. This causes the likely below to be unlikely. + * + * The properfix is to avoid rounding up by using + * the high precision timekeeper.xtime_nsec instead of + * xtime.tv_nsec everywhere. Fixing this will take some + * time. + */ if (likely(error <= interval)) adj = 1; else adj = timekeeping_bigadjust(error, &interval, &offset); } else if (error < -interval) { + /* See comment above, this is just switched for the negative */ error >>= 2; if (likely(error >= -interval)) { adj = -1; @@ -817,9 +847,58 @@ static void timekeeping_adjust(s64 offset) offset = -offset; } else adj = timekeeping_bigadjust(error, &interval, &offset); - } else + } else /* No adjustment needed */ return; + /* + * So the following can be confusing. + * + * To keep things simple, lets assume adj == 1 for now. + * + * When adj != 1, remember that the interval and offset values + * have been appropriately scaled so the math is the same. + * + * The basic idea here is that we're increasing the multiplier + * by one, this causes the xtime_interval to be incremented by + * one cycle_interval. This is because: + * xtime_interval = cycle_interval * mult + * So if mult is being incremented by one: + * xtime_interval = cycle_interval * (mult + 1) + * Its the same as: + * xtime_interval = (cycle_interval * mult) + cycle_interval + * Which can be shortened to: + * xtime_interval += cycle_interval + * + * So offset stores the non-accumulated cycles. Thus the current + * time (in shifted nanoseconds) is: + * now = (offset * adj) + xtime_nsec + * Now, even though we're adjusting the clock frequency, we have + * to keep time consistent. In other words, we can't jump back + * in time, and we also want to avoid jumping forward in time. + * + * So given the same offset value, we need the time to be the same + * both before and after the freq adjustment. + * now = (offset * adj_1) + xtime_nsec_1 + * now = (offset * adj_2) + xtime_nsec_2 + * So: + * (offset * adj_1) + xtime_nsec_1 = + * (offset * adj_2) + xtime_nsec_2 + * And we know: + * adj_2 = adj_1 + 1 + * So: + * (offset * adj_1) + xtime_nsec_1 = + * (offset * (adj_1+1)) + xtime_nsec_2 + * (offset * adj_1) + xtime_nsec_1 = + * (offset * adj_1) + offset + xtime_nsec_2 + * Canceling the sides: + * xtime_nsec_1 = offset + xtime_nsec_2 + * Which gives us: + * xtime_nsec_2 = xtime_nsec_1 - offset + * Which simplfies to: + * xtime_nsec -= offset + * + * XXX - TODO: Doc ntp_error calculation. + */ timekeeper.mult += adj; timekeeper.xtime_interval += interval; timekeeper.xtime_nsec -= offset; -- cgit v1.1 From 815e2bd7d609da9c7615ea28a3990064a394312f Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 28 Oct 2011 07:01:40 -0400 Subject: ktest: Evaluate variables entered on the command line When ktest.pl is called without any arguments, or if the config file does not exist, ktest.pl will ask the user for some information. Some of these questions are code paths. Allowing the user to type ${PWD} for the current directory greatly simplifies these entries. Add variable processing to the entered values. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 9d9ee32..30e2bef 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -250,6 +250,7 @@ sub read_yn { sub get_ktest_config { my ($config) = @_; + my $ans; return if (defined($opt{$config})); @@ -263,16 +264,17 @@ sub get_ktest_config { if (defined($default{$config})) { print "\[$default{$config}\] "; } - $entered_configs{$config} = ; - $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/; - if ($entered_configs{$config} =~ /^\s*$/) { + $ans = ; + $ans =~ s/^\s*(.*\S)\s*$/$1/; + if ($ans =~ /^\s*$/) { if ($default{$config}) { - $entered_configs{$config} = $default{$config}; + $ans = $default{$config}; } else { print "Your answer can not be blank\n"; next; } } + $entered_configs{$config} = process_variables($ans); last; } } -- cgit v1.1 From f74974c763c872d65da4062a14f4e73c77a0b577 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 11 Oct 2011 17:27:51 +0200 Subject: drm/i915: disable temporal dithering on the internal panel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit i'm getting tempted to just disable temporal Approved. apparently it makes the screen look pulse-y which is worse than the disease. References: http://lists.freedesktop.org/archives/intel-gfx/2011-October/012545.html Tested-by: Олег Герман Reviewed-by: Adam Jackson Signed-off-by: Daniel Vetter Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 981b1f1..b75bd93 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5671,7 +5671,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, pipeconf &= ~PIPECONF_DITHER_TYPE_MASK; if ((is_lvds && dev_priv->lvds_dither) || dither) { pipeconf |= PIPECONF_DITHER_EN; - pipeconf |= PIPECONF_DITHER_TYPE_ST1; + pipeconf |= PIPECONF_DITHER_TYPE_SP; } if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) { intel_dp_set_m_n(crtc, mode, adjusted_mode); -- cgit v1.1 From 80a2901d2a59946d098c4479d650d0c3c82c3d85 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 11 Oct 2011 10:59:05 +0200 Subject: drm/i915: only match on PCI_BASE_CLASS_DISPLAY ... not DISPLAY_VGA, because we ignore the VGA subclass with our class_mask. It confused me until Chris Wilson clued me up. Signed-off-by: Daniel Vetter Reviewed-by: Adam Jackson Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/i915_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 4c8d681..548e04b 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -106,7 +106,7 @@ static struct drm_driver driver; extern int intel_agp_enabled; #define INTEL_VGA_DEVICE(id, info) { \ - .class = PCI_CLASS_DISPLAY_VGA << 8, \ + .class = PCI_BASE_CLASS_DISPLAY << 16, \ .class_mask = 0xff0000, \ .vendor = 0x8086, \ .device = id, \ -- cgit v1.1 From 828204903945002be837d938401e242978b7b505 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 10 Oct 2011 16:33:34 -0400 Subject: drm/i915: intel_choose_pipe_bpp_dither messages should be DRM_DEBUG_KMS Shouldn't hide these behind _DRIVER, they're all KMS-related. Signed-off-by: Adam Jackson Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/intel_display.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b75bd93..9fa342e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4711,7 +4711,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, lvds_bpc = 6; if (lvds_bpc < display_bpc) { - DRM_DEBUG_DRIVER("clamping display bpc (was %d) to LVDS (%d)\n", display_bpc, lvds_bpc); + DRM_DEBUG_KMS("clamping display bpc (was %d) to LVDS (%d)\n", display_bpc, lvds_bpc); display_bpc = lvds_bpc; } continue; @@ -4722,7 +4722,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, unsigned int edp_bpc = dev_priv->edp.bpp / 3; if (edp_bpc < display_bpc) { - DRM_DEBUG_DRIVER("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); + DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); display_bpc = edp_bpc; } continue; @@ -4737,7 +4737,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, /* Don't use an invalid EDID bpc value */ if (connector->display_info.bpc && connector->display_info.bpc < display_bpc) { - DRM_DEBUG_DRIVER("clamping display bpc (was %d) to EDID reported max of %d\n", display_bpc, connector->display_info.bpc); + DRM_DEBUG_KMS("clamping display bpc (was %d) to EDID reported max of %d\n", display_bpc, connector->display_info.bpc); display_bpc = connector->display_info.bpc; } } @@ -4748,10 +4748,10 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, */ if (intel_encoder->type == INTEL_OUTPUT_HDMI) { if (display_bpc > 8 && display_bpc < 12) { - DRM_DEBUG_DRIVER("forcing bpc to 12 for HDMI\n"); + DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n"); display_bpc = 12; } else { - DRM_DEBUG_DRIVER("forcing bpc to 8 for HDMI\n"); + DRM_DEBUG_KMS("forcing bpc to 8 for HDMI\n"); display_bpc = 8; } } @@ -4789,8 +4789,8 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, display_bpc = min(display_bpc, bpc); - DRM_DEBUG_DRIVER("setting pipe bpc to %d (max display bpc %d)\n", - bpc, display_bpc); + DRM_DEBUG_KMS("setting pipe bpc to %d (max display bpc %d)\n", + bpc, display_bpc); *pipe_bpp = display_bpc * 3; -- cgit v1.1 From 3fca806cf343155d0bb0dfbdbc2e51ef47b65750 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 28 Oct 2011 14:42:41 +0300 Subject: drm/i915: fix if statement (bogus semi-colon) The semi-colon is a typo here and it makes the if statement unconditional. Signed-off-by: Dan Carpenter Signed-off-by: Keith Packard --- drivers/char/agp/intel-gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 66cd0b8..3a8d448 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -1236,7 +1236,7 @@ static int i9xx_setup(void) intel_private.gtt_bus_addr = reg_addr + gtt_offset; } - if (needs_idle_maps()); + if (needs_idle_maps()) intel_private.base.do_idle_maps = 1; intel_i9xx_setup_flush(); -- cgit v1.1 From c5e62bdd73da80e1017058c923336a5a150af9f2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 28 Oct 2011 10:28:00 -0700 Subject: agp: iommu_gfx_mapped only available if CONFIG_INTEL_IOMMU is set Kernels with no iommu support cannot ever need the Ironlake work-around, so never enable it in that case. Might be better to completely remove the work-around from the kernel in this case? Signed-off-by: Keith Packard Reviewed-by: Ben Widawsky --- drivers/char/agp/intel-gtt.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 3a8d448..c92424c 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -1186,10 +1186,11 @@ static void gen6_cleanup(void) /* Certain Gen5 chipsets require require idling the GPU before * unmapping anything from the GTT when VT-d is enabled. */ -extern int intel_iommu_gfx_mapped; static inline int needs_idle_maps(void) { +#ifdef CONFIG_INTEL_IOMMU const unsigned short gpu_devid = intel_private.pcidev->device; + extern int intel_iommu_gfx_mapped; /* Query intel_iommu to see if we need the workaround. Presumably that * was loaded first. @@ -1198,7 +1199,7 @@ static inline int needs_idle_maps(void) gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) && intel_iommu_gfx_mapped) return 1; - +#endif return 0; } -- cgit v1.1 From f0eb824beee3f596b9799e667a6fdac3116e9f7d Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 14 Oct 2011 15:31:59 +0200 Subject: gpio: pca953x: remove unneeded check for chip type We can assume our own device_id table is correct, so remove checking if the chip type is valid. (The check was bogus anyway: If it found an invalid entry, it returned with 0!) This is in preparation for further cleanups. Signed-off-by: Wolfram Sang Cc: Grant Likely Signed-off-by: Grant Likely --- drivers/gpio/gpio-pca953x.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index c43b8ff..45de6a4 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -673,10 +673,8 @@ static int __devinit pca953x_probe(struct i2c_client *client, if (chip->chip_type == PCA953X_TYPE) device_pca953x_init(chip, invert); - else if (chip->chip_type == PCA957X_TYPE) - device_pca957x_init(chip, invert); else - goto out_failed; + device_pca957x_init(chip, invert); ret = pca953x_irq_setup(chip, id, irq_base); if (ret) -- cgit v1.1 From 7ea2aa2046a15af1c048115e7c05f1ba1566899d Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 14 Oct 2011 15:32:00 +0200 Subject: gpio: pca953x: propagate the errno from the chip_init functions Initializing the chips may return with an error, but this error gets dropped in probe(). Propagate this further to the driver core. Also, simplify returning the error in one of the init functions. Signed-off-by: Wolfram Sang Cc: Grant Likely Signed-off-by: Grant Likely --- drivers/gpio/gpio-pca953x.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 45de6a4..a3fef0c 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -595,9 +595,6 @@ static int __devinit device_pca953x_init(struct pca953x_chip *chip, int invert) /* set platform specific polarity inversion */ ret = pca953x_write_reg(chip, PCA953X_INVERT, invert); - if (ret) - goto out; - return 0; out: return ret; } @@ -639,7 +636,7 @@ static int __devinit pca953x_probe(struct i2c_client *client, struct pca953x_platform_data *pdata; struct pca953x_chip *chip; int irq_base=0, invert=0; - int ret = 0; + int ret; chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); if (chip == NULL) @@ -672,9 +669,11 @@ static int __devinit pca953x_probe(struct i2c_client *client, pca953x_setup_gpio(chip, id->driver_data & PCA_GPIO_MASK); if (chip->chip_type == PCA953X_TYPE) - device_pca953x_init(chip, invert); + ret = device_pca953x_init(chip, invert); else - device_pca957x_init(chip, invert); + ret = device_pca957x_init(chip, invert); + if (ret) + goto out_failed; ret = pca953x_irq_setup(chip, id, irq_base); if (ret) -- cgit v1.1 From 0d52f54e2ef64c189dedc332e680b2eb4a34590a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 22 Oct 2011 00:43:38 +0200 Subject: PCI / ACPI: Make acpiphp ignore root bridges using PCIe native hotplug If the kernel has requested control of the PCIe native hotplug feature for a given root complex, the acpiphp driver should not try to handle that root complex and it should leave it to pciehp. Failing to do so causes problems to happen if acpiphp is loaded before pciehp on such systems. To address this issue make find_root_bridges() ignore PCIe root complexes with PCIe native hotplug enabled and make add_bridge() return error code if PCIe native hotplug is enabled for the given root port. This causes acpiphp to refuse to load if PCIe native hotplug is enabled for all complexes and to refuse binding to the root complexes with PCIe native hotplug is enabled. Acked-by: Kenji Kaneshige Signed-off-by: Rafael J. Wysocki Signed-off-by: Jesse Barnes --- drivers/pci/hotplug/acpiphp_glue.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 596172b..fce1c54 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -459,8 +459,17 @@ static int add_bridge(acpi_handle handle) { acpi_status status; unsigned long long tmp; + struct acpi_pci_root *root; acpi_handle dummy_handle; + /* + * We shouldn't use this bridge if PCIe native hotplug control has been + * granted by the BIOS for it. + */ + root = acpi_pci_find_root(handle); + if (root && (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)) + return -ENODEV; + /* if the bridge doesn't have _STA, we assume it is always there */ status = acpi_get_handle(handle, "_STA", &dummy_handle); if (ACPI_SUCCESS(status)) { @@ -1376,13 +1385,23 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, static acpi_status find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) { + struct acpi_pci_root *root; int *count = (int *)context; - if (acpi_is_root_bridge(handle)) { - acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, - handle_hotplug_event_bridge, NULL); - (*count)++; - } + if (!acpi_is_root_bridge(handle)) + return AE_OK; + + root = acpi_pci_find_root(handle); + if (!root) + return AE_OK; + + if (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL) + return AE_OK; + + (*count)++; + acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, + handle_hotplug_event_bridge, NULL); + return AE_OK ; } -- cgit v1.1 From 466b3ddfbcf4f5ce402a77397630a0fa9ea9ce6b Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Sun, 30 Oct 2011 16:35:08 +0100 Subject: PCI: Fix compile errors with PCI_ATS and !PCI_IOV The ats and sroiv members of 'struct pci_dev' are required for the ATS code already, even without IOV support compiled in. So depend on ATS here. This is fine with PCI_IOV too because it selects PCI_ATS. Also the prototypes for ATS need to be available for PCI_ATS. Reported-by: Randy Dunlap Signed-off-by: Joerg Roedel Signed-off-by: Jesse Barnes --- include/linux/pci-ats.h | 6 +++--- include/linux/pci.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/linux/pci-ats.h b/include/linux/pci-ats.h index e3d0b38..7ef6872 100644 --- a/include/linux/pci-ats.h +++ b/include/linux/pci-ats.h @@ -12,7 +12,7 @@ struct pci_ats { unsigned int is_enabled:1; /* Enable bit is set */ }; -#ifdef CONFIG_PCI_IOV +#ifdef CONFIG_PCI_ATS extern int pci_enable_ats(struct pci_dev *dev, int ps); extern void pci_disable_ats(struct pci_dev *dev); @@ -29,7 +29,7 @@ static inline int pci_ats_enabled(struct pci_dev *dev) return dev->ats && dev->ats->is_enabled; } -#else /* CONFIG_PCI_IOV */ +#else /* CONFIG_PCI_ATS */ static inline int pci_enable_ats(struct pci_dev *dev, int ps) { @@ -50,7 +50,7 @@ static inline int pci_ats_enabled(struct pci_dev *dev) return 0; } -#endif /* CONFIG_PCI_IOV */ +#endif /* CONFIG_PCI_ATS */ #ifdef CONFIG_PCI_PRI diff --git a/include/linux/pci.h b/include/linux/pci.h index 337df0d5..7cda65b 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -338,7 +338,7 @@ struct pci_dev { struct list_head msi_list; #endif struct pci_vpd *vpd; -#ifdef CONFIG_PCI_IOV +#ifdef CONFIG_PCI_ATS union { struct pci_sriov *sriov; /* SR-IOV capability related */ struct pci_dev *physfn; /* the PF this VF is associated with */ -- cgit v1.1 From c54420d3302d30999060e2669d0800b85e5b5a20 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Sun, 30 Oct 2011 16:35:07 +0100 Subject: PCI: Let PCI_PRI depend on PCI This avoids the PCI_PRI question in 'make config' when PCI is not selected. Reported-by: Geert Uytterhoeven Signed-off-by: Joerg Roedel Signed-off-by: Jesse Barnes --- drivers/pci/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index cec6606..8252fc3 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -87,6 +87,7 @@ config PCI_IOV config PCI_PRI bool "PCI PRI support" + depends on PCI select PCI_ATS help PRI is the PCI Page Request Interface. It allows PCI devices that are -- cgit v1.1 From 51ce185af0f71b65c23ed719f72d0241895a61da Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 1 Nov 2011 00:51:30 -0700 Subject: sparc: Hook up process_vm_{readv,writev} syscalls. Signed-off-by: David S. Miller --- arch/sparc/include/asm/unistd.h | 4 +++- arch/sparc/kernel/systbls_32.S | 2 +- arch/sparc/kernel/systbls_64.S | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h index 6260d5d..c7cb0af 100644 --- a/arch/sparc/include/asm/unistd.h +++ b/arch/sparc/include/asm/unistd.h @@ -406,8 +406,10 @@ #define __NR_syncfs 335 #define __NR_sendmmsg 336 #define __NR_setns 337 +#define __NR_process_vm_readv 338 +#define __NR_process_vm_writev 339 -#define NR_syscalls 338 +#define NR_syscalls 340 #ifdef __32bit_syscall_numbers__ /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 09d8ec4..63402f9 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S @@ -84,4 +84,4 @@ sys_call_table: /*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime -/*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns +/*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index edbec45..db86b1a 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -85,7 +85,7 @@ sys_call_table32: /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init /*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime - .word sys_syncfs, compat_sys_sendmmsg, sys_setns + .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev #endif /* CONFIG_COMPAT */ @@ -162,4 +162,4 @@ sys_call_table: /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime - .word sys_syncfs, sys_sendmmsg, sys_setns + .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev -- cgit v1.1 From 627f7675f0f530ea555d76543dc4e469d70a1532 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 31 Oct 2011 11:30:10 -0700 Subject: drm/i915: Use mode_config.mutex in ironlake_panel_vdd_work Use of the struct_mutex is not correct for locking in mode setting paths. Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/intel_dp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index fc1a0832..7259034 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -971,9 +971,9 @@ static void ironlake_panel_vdd_work(struct work_struct *__work) struct intel_dp, panel_vdd_work); struct drm_device *dev = intel_dp->base.base.dev; - mutex_lock(&dev->struct_mutex); + mutex_lock(&dev->mode_config.mutex); ironlake_panel_vdd_off_sync(intel_dp); - mutex_unlock(&dev->struct_mutex); + mutex_unlock(&dev->mode_config.mutex); } static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) -- cgit v1.1 From ff56b0bc84c01fb2c5d2ec6438becfe0f5f2f78f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 31 Oct 2011 23:16:21 -0700 Subject: drm/i915: Fix object refcount leak on mmappable size limit error path. I've been seeing memory leaks on my system in the form of large (300-400MB) GEM objects created by now-dead processes laying around clogging up memory. I usually notice when it gets to about 1.2GB of them. Hopefully this clears up the issue, but I just found this bug by inspection. Signed-off-by: Eric Anholt Cc: stable@kernel.org Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/i915_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6651c36..d18b07a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1396,7 +1396,7 @@ i915_gem_mmap_gtt(struct drm_file *file, if (obj->base.size > dev_priv->mm.gtt_mappable_end) { ret = -E2BIG; - goto unlock; + goto out; } if (obj->madv != I915_MADV_WILLNEED) { -- cgit v1.1 From fb223c32b4d3ee593c8dce07e983680d06abe387 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Wed, 2 Nov 2011 09:15:16 +1100 Subject: crypto: user - Fix rwsem leak in crypto_user The list_empty case in crypto_alg_match() will return without calling up_read() on crypto_alg_sem. We could do the "goto out" routine, but the function will clearly do the right thing with that test simply removed. Signed-off-by: Jonathan Corbet Signed-off-by: Herbert Xu --- crypto/crypto_user.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c index 2abca78..0605a2b 100644 --- a/crypto/crypto_user.c +++ b/crypto/crypto_user.c @@ -44,9 +44,6 @@ static struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p, int exact) down_read(&crypto_alg_sem); - if (list_empty(&crypto_alg_list)) - return NULL; - list_for_each_entry(q, &crypto_alg_list, cra_list) { int match = 0; -- cgit v1.1 From 47a6770ac6cd0d28f14dd9e1b17705abe6f05e41 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 25 Oct 2011 09:35:19 -0700 Subject: msm: boards: Fix fallout from removal of machine_desc in fixup After 0744a3ee (ARM: platform fixups: remove mdesc argument to fixup function, 2010-12-20) the fixup functions introduced in 9e775ad (ARM: 7012/1: Set proper TEXT_OFFSET for newer MSMs, 2011-08-12) cause warnings like: arch/arm/mach-msm/board-msm8x60.c:85: warning: initialization from incompatible pointer type Fix them by removing the machine_desc argument from the fixup functions. Signed-off-by: Stephen Boyd Signed-off-by: David Brown --- arch/arm/mach-msm/board-msm7x30.c | 4 ++-- arch/arm/mach-msm/board-msm8960.c | 4 ++-- arch/arm/mach-msm/board-msm8x60.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c index 71de506..db81ed53 100644 --- a/arch/arm/mach-msm/board-msm7x30.c +++ b/arch/arm/mach-msm/board-msm7x30.c @@ -42,8 +42,8 @@ extern struct sys_timer msm_timer; -static void __init msm7x30_fixup(struct machine_desc *desc, struct tag *tag, - char **cmdline, struct meminfo *mi) +static void __init msm7x30_fixup(struct tag *tag, char **cmdline, + struct meminfo *mi) { for (; tag->hdr.size; tag = tag_next(tag)) if (tag->hdr.tag == ATAG_MEM && tag->u.mem.start == 0x200000) { diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c index b04468e..6dc1cbd 100644 --- a/arch/arm/mach-msm/board-msm8960.c +++ b/arch/arm/mach-msm/board-msm8960.c @@ -32,8 +32,8 @@ #include "devices.h" -static void __init msm8960_fixup(struct machine_desc *desc, struct tag *tag, - char **cmdline, struct meminfo *mi) +static void __init msm8960_fixup(struct tag *tag, char **cmdline, + struct meminfo *mi) { for (; tag->hdr.size; tag = tag_next(tag)) if (tag->hdr.tag == ATAG_MEM && diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c index 106170f..eed73e2 100644 --- a/arch/arm/mach-msm/board-msm8x60.c +++ b/arch/arm/mach-msm/board-msm8x60.c @@ -30,8 +30,8 @@ #include #include -static void __init msm8x60_fixup(struct machine_desc *desc, struct tag *tag, - char **cmdline, struct meminfo *mi) +static void __init msm8x60_fixup(struct tag *tag, char **cmdline, + struct meminfo *mi) { for (; tag->hdr.size; tag = tag_next(tag)) if (tag->hdr.tag == ATAG_MEM && -- cgit v1.1 From f43d623164022dcbf6750ef220b7a1133a1183eb Mon Sep 17 00:00:00 2001 From: Don Zickus Date: Thu, 20 Oct 2011 23:52:14 -0400 Subject: usb, xhci: fix lockdep warning on endpoint timeout While debugging a usb3 problem, I stumbled upon this lockdep warning. Oct 18 21:41:17 dhcp47-74 kernel: ================================= Oct 18 21:41:17 dhcp47-74 kernel: [ INFO: inconsistent lock state ] Oct 18 21:41:17 dhcp47-74 kernel: 3.1.0-rc4nmi+ #456 Oct 18 21:41:17 dhcp47-74 kernel: --------------------------------- Oct 18 21:41:17 dhcp47-74 kernel: inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage. Oct 18 21:41:17 dhcp47-74 kernel: swapper/0 [HC0[0]:SC1[1]:HE1:SE0] takes: Oct 18 21:41:17 dhcp47-74 kernel: (&(&xhci->lock)->rlock){?.-...}, at: [] xhci_stop_endpoint_command_watchdog+0x30/0x340 [xhci_hcd] Oct 18 21:41:17 dhcp47-74 kernel: {IN-HARDIRQ-W} state was registered at: Oct 18 21:41:17 dhcp47-74 kernel: [] __lock_acquire+0x781/0x1660 Oct 18 21:41:17 dhcp47-74 kernel: [] lock_acquire+0x97/0x170 Oct 18 21:41:17 dhcp47-74 kernel: [] _raw_spin_lock+0x46/0x80 Oct 18 21:41:17 dhcp47-74 kernel: [] xhci_irq+0x3a/0x1960 [xhci_hcd] Oct 18 21:41:17 dhcp47-74 kernel: [] xhci_msi_irq+0x31/0x40 [xhci_hcd] Oct 18 21:41:17 dhcp47-74 kernel: [] handle_irq_event_percpu+0x85/0x320 Oct 18 21:41:17 dhcp47-74 kernel: [] handle_irq_event+0x48/0x70 Oct 18 21:41:17 dhcp47-74 kernel: [] handle_edge_irq+0x6d/0x130 Oct 18 21:41:17 dhcp47-74 kernel: [] handle_irq+0x49/0xa0 Oct 18 21:41:17 dhcp47-74 kernel: [] do_IRQ+0x5d/0xe0 Oct 18 21:41:17 dhcp47-74 kernel: [] ret_from_intr+0x0/0x13 Oct 18 21:41:17 dhcp47-74 kernel: [] usb_set_device_state+0x8a/0x180 Oct 18 21:41:17 dhcp47-74 kernel: [] usb_add_hcd+0x2b8/0x730 Oct 18 21:41:17 dhcp47-74 kernel: [] xhci_pci_probe+0x9e/0xd4 [xhci_hcd] Oct 18 21:41:17 dhcp47-74 kernel: [] local_pci_probe+0x5f/0xd0 Oct 18 21:41:17 dhcp47-74 kernel: [] pci_device_probe+0x119/0x120 Oct 18 21:41:17 dhcp47-74 kernel: [] driver_probe_device+0xa3/0x2c0 Oct 18 21:41:17 dhcp47-74 kernel: [] __driver_attach+0xab/0xb0 Oct 18 21:41:17 dhcp47-74 kernel: [] bus_for_each_dev+0x6c/0xa0 Oct 18 21:41:17 dhcp47-74 kernel: [] driver_attach+0x1e/0x20 Oct 18 21:41:17 dhcp47-74 kernel: [] bus_add_driver+0x1f8/0x2b0 Oct 18 21:41:17 dhcp47-74 kernel: [] driver_register+0x76/0x140 Oct 18 21:41:17 dhcp47-74 kernel: [] __pci_register_driver+0x66/0xe0 Oct 18 21:41:17 dhcp47-74 kernel: [] snd_timer_find+0x4a/0x70 [snd_timer] Oct 18 21:41:17 dhcp47-74 kernel: [] snd_timer_find+0xe/0x70 [snd_timer] Oct 18 21:41:17 dhcp47-74 kernel: [] do_one_initcall+0x43/0x180 Oct 18 21:41:17 dhcp47-74 kernel: [] sys_init_module+0x92/0x1f0 Oct 18 21:41:17 dhcp47-74 kernel: [] system_call_fastpath+0x16/0x1b Oct 18 21:41:17 dhcp47-74 kernel: irq event stamp: 631984 Oct 18 21:41:17 dhcp47-74 kernel: hardirqs last enabled at (631984): [] _raw_spin_unlock_irq+0x30/0x50 Oct 18 21:41:17 dhcp47-74 kernel: hardirqs last disabled at (631983): [] _raw_spin_lock_irq+0x19/0x90 Oct 18 21:41:17 dhcp47-74 kernel: softirqs last enabled at (631980): [] _local_bh_enable+0x13/0x20 Oct 18 21:41:17 dhcp47-74 kernel: softirqs last disabled at (631981): [] call_softirq+0x1c/0x30 Oct 18 21:41:17 dhcp47-74 kernel: Oct 18 21:41:17 dhcp47-74 kernel: other info that might help us debug this: Oct 18 21:41:17 dhcp47-74 kernel: Possible unsafe locking scenario: Oct 18 21:41:17 dhcp47-74 kernel: Oct 18 21:41:17 dhcp47-74 kernel: CPU0 Oct 18 21:41:17 dhcp47-74 kernel: ---- Oct 18 21:41:17 dhcp47-74 kernel: lock(&(&xhci->lock)->rlock); Oct 18 21:41:17 dhcp47-74 kernel: Oct 18 21:41:17 dhcp47-74 kernel: lock(&(&xhci->lock)->rlock); Oct 18 21:41:17 dhcp47-74 kernel: Oct 18 21:41:17 dhcp47-74 kernel: *** DEADLOCK *** Oct 18 21:41:17 dhcp47-74 kernel: Oct 18 21:41:17 dhcp47-74 kernel: 1 lock held by swapper/0: Oct 18 21:41:17 dhcp47-74 kernel: #0: (&ep->stop_cmd_timer){+.-...}, at: [] run_timer_softirq+0x162/0x570 Oct 18 21:41:17 dhcp47-74 kernel: Oct 18 21:41:17 dhcp47-74 kernel: stack backtrace: Oct 18 21:41:17 dhcp47-74 kernel: Pid: 0, comm: swapper Tainted: G W 3.1.0-rc4nmi+ #456 Oct 18 21:41:17 dhcp47-74 kernel: Call Trace: Oct 18 21:41:17 dhcp47-74 kernel: [] print_usage_bug+0x227/0x270 Oct 18 21:41:17 dhcp47-74 kernel: [] mark_lock+0x346/0x410 Oct 18 21:41:17 dhcp47-74 kernel: [] __lock_acquire+0x61e/0x1660 Oct 18 21:41:17 dhcp47-74 kernel: [] ? mark_lock+0x213/0x410 Oct 18 21:41:17 dhcp47-74 kernel: [] lock_acquire+0x97/0x170 Oct 18 21:41:17 dhcp47-74 kernel: [] ? xhci_stop_endpoint_command_watchdog+0x30/0x340 [xhci_hcd] Oct 18 21:41:17 dhcp47-74 kernel: [] _raw_spin_lock+0x46/0x80 Oct 18 21:41:17 dhcp47-74 kernel: [] ? xhci_stop_endpoint_command_watchdog+0x30/0x340 [xhci_hcd] Oct 18 21:41:17 dhcp47-74 kernel: [] xhci_stop_endpoint_command_watchdog+0x30/0x340 [xhci_hcd] Oct 18 21:41:17 dhcp47-74 kernel: [] ? run_timer_softirq+0x162/0x570 Oct 18 21:41:17 dhcp47-74 kernel: [] run_timer_softirq+0x20d/0x570 Oct 18 21:41:17 dhcp47-74 kernel: [] ? run_timer_softirq+0x162/0x570 Oct 18 21:41:17 dhcp47-74 kernel: [] ? xhci_queue_isoc_tx_prepare+0x8e0/0x8e0 [xhci_hcd] Oct 18 21:41:17 dhcp47-74 kernel: [] __do_softirq+0xf2/0x3f0 Oct 18 21:41:17 dhcp47-74 kernel: [] ? lapic_next_event+0x1d/0x30 Oct 18 21:41:17 dhcp47-74 kernel: [] ? clockevents_program_event+0x5e/0x90 Oct 18 21:41:17 dhcp47-74 kernel: [] call_softirq+0x1c/0x30 Oct 18 21:41:17 dhcp47-74 kernel: [] do_softirq+0x8d/0xc0 Oct 18 21:41:17 dhcp47-74 kernel: [] irq_exit+0xe5/0x100 Oct 18 21:41:17 dhcp47-74 kernel: [] smp_apic_timer_interrupt+0x6e/0x99 Oct 18 21:41:17 dhcp47-74 kernel: [] apic_timer_interrupt+0x70/0x80 Oct 18 21:41:17 dhcp47-74 kernel: [] ? trace_hardirqs_off+0xd/0x10 Oct 18 21:41:17 dhcp47-74 kernel: [] ? acpi_idle_enter_bm+0x227/0x25b Oct 18 21:41:17 dhcp47-74 kernel: [] ? acpi_idle_enter_bm+0x222/0x25b Oct 18 21:41:17 dhcp47-74 kernel: [] cpuidle_idle_call+0x103/0x290 Oct 18 21:41:17 dhcp47-74 kernel: [] cpu_idle+0xe5/0x160 Oct 18 21:41:17 dhcp47-74 kernel: [] rest_init+0xe0/0xf0 Oct 18 21:41:17 dhcp47-74 kernel: [] ? csum_partial_copy_generic+0x170/0x170 Oct 18 21:41:17 dhcp47-74 kernel: [] start_kernel+0x3fc/0x407 Oct 18 21:41:17 dhcp47-74 kernel: [] x86_64_start_reservations+0x131/0x135 Oct 18 21:41:17 dhcp47-74 kernel: [] x86_64_start_kernel+0xed/0xf4 Oct 18 21:41:17 dhcp47-74 kernel: xhci_hcd 0000:00:14.0: xHCI host not responding to stop endpoint command. Oct 18 21:41:17 dhcp47-74 kernel: xhci_hcd 0000:00:14.0: Assuming host is dying, halting host. Oct 18 21:41:17 dhcp47-74 kernel: xhci_hcd 0000:00:14.0: HC died; cleaning up Oct 18 21:41:17 dhcp47-74 kernel: usb 3-4: device descriptor read/8, error -110 Oct 18 21:41:17 dhcp47-74 kernel: usb 3-4: device descriptor read/8, error -22 Oct 18 21:41:17 dhcp47-74 kernel: hub 3-0:1.0: cannot disable port 4 (err = -19) Basically what is happening is in xhci_stop_endpoint_command_watchdog() the xhci->lock is grabbed with just spin_lock. What lockdep deduces is that if an interrupt occurred while in this function it would deadlock with xhci_irq because that function also grabs the xhci->lock. Fixing it is trivial by using spin_lock_irqsave instead. This should be queued to stable kernels as far back as 2.6.33. Signed-off-by: Don Zickus Signed-off-by: Sarah Sharp Cc: stable@kernel.org --- drivers/usb/host/xhci-ring.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 940321b..9f1d4b1 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -816,23 +816,24 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) struct xhci_ring *ring; struct xhci_td *cur_td; int ret, i, j; + unsigned long flags; ep = (struct xhci_virt_ep *) arg; xhci = ep->xhci; - spin_lock(&xhci->lock); + spin_lock_irqsave(&xhci->lock, flags); ep->stop_cmds_pending--; if (xhci->xhc_state & XHCI_STATE_DYING) { xhci_dbg(xhci, "Stop EP timer ran, but another timer marked " "xHCI as DYING, exiting.\n"); - spin_unlock(&xhci->lock); + spin_unlock_irqrestore(&xhci->lock, flags); return; } if (!(ep->stop_cmds_pending == 0 && (ep->ep_state & EP_HALT_PENDING))) { xhci_dbg(xhci, "Stop EP timer ran, but no command pending, " "exiting.\n"); - spin_unlock(&xhci->lock); + spin_unlock_irqrestore(&xhci->lock, flags); return; } @@ -844,11 +845,11 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) xhci->xhc_state |= XHCI_STATE_DYING; /* Disable interrupts from the host controller and start halting it */ xhci_quiesce(xhci); - spin_unlock(&xhci->lock); + spin_unlock_irqrestore(&xhci->lock, flags); ret = xhci_halt(xhci); - spin_lock(&xhci->lock); + spin_lock_irqsave(&xhci->lock, flags); if (ret < 0) { /* This is bad; the host is not responding to commands and it's * not allowing itself to be halted. At least interrupts are @@ -896,7 +897,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) } } } - spin_unlock(&xhci->lock); + spin_unlock_irqrestore(&xhci->lock, flags); xhci_dbg(xhci, "Calling usb_hc_died()\n"); usb_hc_died(xhci_to_hcd(xhci)->primary_hcd); xhci_dbg(xhci, "xHCI host controller is dead.\n"); -- cgit v1.1 From 86f14df8ed1ecec5cefe7d002b4d297e298238c2 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 2 Nov 2011 21:36:32 +0000 Subject: ASoC: Update git repository URL Remove the -2.6 from the name. Signed-off-by: Mark Brown --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index bbf42cd..63b58dd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6001,7 +6001,7 @@ F: sound/ SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC) M: Liam Girdwood M: Mark Brown -T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git L: alsa-devel@alsa-project.org (moderated for non-subscribers) W: http://alsa-project.org/main/index.php/ASoC S: Supported -- cgit v1.1 From c75d720fca8a91ce99196d33adea383621027bf2 Mon Sep 17 00:00:00 2001 From: Edward Donovan Date: Tue, 1 Nov 2011 15:29:44 -0400 Subject: genirq: Fix irqfixup, irqpoll regression commit d05c65fff0 ("genirq: spurious: Run only one poller at a time") introduced a regression, leaving the boot options 'irqfixup' and 'irqpoll' non-functional. The patch placed tests in each function, to exit if the function is already running. The test in 'misrouted_irq' exited when it should have proceeded, effectively disabling 'misrouted_irq' and 'poll_spurious_irqs'. The check for an already running poller needs to be "!= 1" not "== 1" as "1" is the value when the first poller starts running. Signed-off-by: Edward Donovan Cc: maciej.rutecki@gmail.com Link: http://lkml.kernel.org/r/1320175784-6745-1-git-send-email-edward.donovan@numble.net Cc: stable@vger.kernel.org # >= 2.6.39 Signed-off-by: Thomas Gleixner --- kernel/irq/spurious.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c index aa57d5d..b5f4742 100644 --- a/kernel/irq/spurious.c +++ b/kernel/irq/spurious.c @@ -115,7 +115,7 @@ static int misrouted_irq(int irq) struct irq_desc *desc; int i, ok = 0; - if (atomic_inc_return(&irq_poll_active) == 1) + if (atomic_inc_return(&irq_poll_active) != 1) goto out; irq_poll_cpu = smp_processor_id(); -- cgit v1.1 From 616fdb5afb12b4d5bb9e36df40d039e86aaaefc2 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Wed, 5 Oct 2011 11:44:54 -0700 Subject: drm/i915: forcewake warning fixes in debugfs Some more unsafe debugfs access are fixed with this patch. I tested all reads, but didn't thoroughly test the writes. Cc: "Nicolas Kalkhof" Signed-off-by: Ben Widawsky Reviewed-by: Daniel Vetter Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/i915_debugfs.c | 57 +++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 8e95d66..f2e0207 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -635,11 +635,16 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; struct intel_ring_buffer *ring; + int ret; ring = &dev_priv->ring[(uintptr_t)node->info_ent->data]; if (ring->size == 0) return 0; + ret = mutex_lock_interruptible(&dev->struct_mutex); + if (ret) + return ret; + seq_printf(m, "Ring %s:\n", ring->name); seq_printf(m, " Head : %08x\n", I915_READ_HEAD(ring) & HEAD_ADDR); seq_printf(m, " Tail : %08x\n", I915_READ_TAIL(ring) & TAIL_ADDR); @@ -653,6 +658,8 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) seq_printf(m, " Control : %08x\n", I915_READ_CTL(ring)); seq_printf(m, " Start : %08x\n", I915_READ_START(ring)); + mutex_unlock(&dev->struct_mutex); + return 0; } @@ -841,7 +848,16 @@ static int i915_rstdby_delays(struct seq_file *m, void *unused) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; - u16 crstanddelay = I915_READ16(CRSTANDVID); + u16 crstanddelay; + int ret; + + ret = mutex_lock_interruptible(&dev->struct_mutex); + if (ret) + return ret; + + crstanddelay = I915_READ16(CRSTANDVID); + + mutex_unlock(&dev->struct_mutex); seq_printf(m, "w/ctx: %d, w/o ctx: %d\n", (crstanddelay >> 8) & 0x3f, (crstanddelay & 0x3f)); @@ -939,7 +955,11 @@ static int i915_delayfreq_table(struct seq_file *m, void *unused) struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; u32 delayfreq; - int i; + int ret, i; + + ret = mutex_lock_interruptible(&dev->struct_mutex); + if (ret) + return ret; for (i = 0; i < 16; i++) { delayfreq = I915_READ(PXVFREQ_BASE + i * 4); @@ -947,6 +967,8 @@ static int i915_delayfreq_table(struct seq_file *m, void *unused) (delayfreq & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT); } + mutex_unlock(&dev->struct_mutex); + return 0; } @@ -961,13 +983,19 @@ static int i915_inttoext_table(struct seq_file *m, void *unused) struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; u32 inttoext; - int i; + int ret, i; + + ret = mutex_lock_interruptible(&dev->struct_mutex); + if (ret) + return ret; for (i = 1; i <= 32; i++) { inttoext = I915_READ(INTTOEXT_BASE_ILK + i * 4); seq_printf(m, "INTTOEXT%02d: 0x%08x\n", i, inttoext); } + mutex_unlock(&dev->struct_mutex); + return 0; } @@ -976,9 +1004,19 @@ static int i915_drpc_info(struct seq_file *m, void *unused) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; - u32 rgvmodectl = I915_READ(MEMMODECTL); - u32 rstdbyctl = I915_READ(RSTDBYCTL); - u16 crstandvid = I915_READ16(CRSTANDVID); + u32 rgvmodectl, rstdbyctl; + u16 crstandvid; + int ret; + + ret = mutex_lock_interruptible(&dev->struct_mutex); + if (ret) + return ret; + + rgvmodectl = I915_READ(MEMMODECTL); + rstdbyctl = I915_READ(RSTDBYCTL); + crstandvid = I915_READ16(CRSTANDVID); + + mutex_unlock(&dev->struct_mutex); seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ? "yes" : "no"); @@ -1166,9 +1204,16 @@ static int i915_gfxec(struct seq_file *m, void *unused) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; + int ret; + + ret = mutex_lock_interruptible(&dev->struct_mutex); + if (ret) + return ret; seq_printf(m, "GFXEC: %ld\n", (unsigned long)I915_READ(0x112f4)); + mutex_unlock(&dev->struct_mutex); + return 0; } -- cgit v1.1 From 775d17b6ca4357048f36c22151335addfe15db4b Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sun, 9 Oct 2011 21:52:01 +0200 Subject: drm/i915: Ivybridge still has fences! So don't forget to restore them on resume and dump them into the error state. Cc: stable@kernel.org Signed-off-by: Daniel Vetter Reviewed-by: Chris Wilson Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/i915_irq.c | 1 + drivers/gpu/drm/i915/i915_suspend.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 9ee2729..b40004b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -824,6 +824,7 @@ static void i915_gem_record_fences(struct drm_device *dev, /* Fences */ switch (INTEL_INFO(dev)->gen) { + case 7: case 6: for (i = 0; i < 16; i++) error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index f8f602d..7886e4f 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -370,6 +370,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) /* Fences */ switch (INTEL_INFO(dev)->gen) { + case 7: case 6: for (i = 0; i < 16; i++) dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); @@ -404,6 +405,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) /* Fences */ switch (INTEL_INFO(dev)->gen) { + case 7: case 6: for (i = 0; i < 16; i++) I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]); -- cgit v1.1 From 4b9de737fad5bd8993e6070530802de22f32744d Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sun, 9 Oct 2011 21:52:02 +0200 Subject: drm/i915: add constants to size fence arrays and fields In preparation of to support 32 fences on Ivybdrigde. Signed-Off-by: Daniel Vetter Reviewed-by: Chris Wilson Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/i915_drv.h | 15 ++++++++------- drivers/gpu/drm/i915/i915_gem.c | 4 ++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 06a37f4..d2da91f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -126,6 +126,9 @@ struct drm_i915_master_private { struct _drm_i915_sarea *sarea_priv; }; #define I915_FENCE_REG_NONE -1 +#define I915_MAX_NUM_FENCES 16 +/* 16 fences + sign bit for FENCE_REG_NONE */ +#define I915_MAX_NUM_FENCE_BITS 5 struct drm_i915_fence_reg { struct list_head lru_list; @@ -168,7 +171,7 @@ struct drm_i915_error_state { u32 instdone1; u32 seqno; u64 bbaddr; - u64 fence[16]; + u64 fence[I915_MAX_NUM_FENCES]; struct timeval time; struct drm_i915_error_object { int page_count; @@ -182,7 +185,7 @@ struct drm_i915_error_state { u32 gtt_offset; u32 read_domains; u32 write_domain; - s32 fence_reg:5; + s32 fence_reg:I915_MAX_NUM_FENCE_BITS; s32 pinned:2; u32 tiling:2; u32 dirty:1; @@ -375,7 +378,7 @@ typedef struct drm_i915_private { struct notifier_block lid_notifier; int crt_ddc_pin; - struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ + struct drm_i915_fence_reg fence_regs[I915_MAX_NUM_FENCES]; /* assume 965 */ int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ int num_fence_regs; /* 8 on pre-965, 16 otherwise */ @@ -506,7 +509,7 @@ typedef struct drm_i915_private { u8 saveAR[21]; u8 saveDACMASK; u8 saveCR[37]; - uint64_t saveFENCE[16]; + uint64_t saveFENCE[I915_MAX_NUM_FENCES]; u32 saveCURACNTR; u32 saveCURAPOS; u32 saveCURABASE; @@ -777,10 +780,8 @@ struct drm_i915_gem_object { * Fence register bits (if any) for this object. Will be set * as needed when mapped into the GTT. * Protected by dev->struct_mutex. - * - * Size: 4 bits for 16 fences + sign (for FENCE_REG_NONE) */ - signed int fence_reg:5; + signed int fence_reg:I915_MAX_NUM_FENCE_BITS; /** * Advice: are the backing pages purgeable? diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d18b07a..a838597 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1745,7 +1745,7 @@ static void i915_gem_reset_fences(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; int i; - for (i = 0; i < 16; i++) { + for (i = 0; i < dev_priv->num_fence_regs; i++) { struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; struct drm_i915_gem_object *obj = reg->obj; @@ -3877,7 +3877,7 @@ i915_gem_load(struct drm_device *dev) INIT_LIST_HEAD(&dev_priv->mm.gtt_list); for (i = 0; i < I915_NUM_RINGS; i++) init_ring_lists(&dev_priv->ring[i]); - for (i = 0; i < 16; i++) + for (i = 0; i < I915_MAX_NUM_FENCES; i++) INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); INIT_DELAYED_WORK(&dev_priv->mm.retire_work, i915_gem_retire_work_handler); -- cgit v1.1 From a918feef334090692ea65e77a8b0cca5e682e666 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Wed, 2 Nov 2011 17:30:49 +0000 Subject: ARM: mxc: fix local timer interrupt handling As local timer interrupts are now handled as normal interrupts, remove the special case in the GIC handler. Cc: Shawn Guo Cc: Sascha Hauer Signed-off-by: Marc Zyngier Tested-and-Acked-by: Shawn Guo --- arch/arm/plat-mxc/gic.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/arch/arm/plat-mxc/gic.c b/arch/arm/plat-mxc/gic.c index b3b8eed..12f8f81 100644 --- a/arch/arm/plat-mxc/gic.c +++ b/arch/arm/plat-mxc/gic.c @@ -28,21 +28,14 @@ asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) if (irqnr == 1023) break; - if (irqnr > 29 && irqnr < 1021) + if (irqnr > 15 && irqnr < 1021) handle_IRQ(irqnr, regs); #ifdef CONFIG_SMP - else if (irqnr < 16) { + else { writel_relaxed(irqstat, gic_cpu_base_addr + GIC_CPU_EOI); handle_IPI(irqnr, regs); } #endif -#ifdef CONFIG_LOCAL_TIMERS - else if (irqnr == 29) { - writel_relaxed(irqstat, gic_cpu_base_addr + - GIC_CPU_EOI); - handle_local_timer(regs); - } -#endif } while (1); } -- cgit v1.1 From 98de0cbbe2e7157fd87d04386621be3eadd4d6ab Mon Sep 17 00:00:00 2001 From: Jason Liu Date: Thu, 3 Nov 2011 17:31:26 +0800 Subject: ARM:i.MX: fix build error in tzic/avic.c arch/arm/plat-mxc/tzic.c:105: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'tzic_handle_irq' Signed-off-by: Jason Liu --- arch/arm/plat-mxc/avic.c | 1 + arch/arm/plat-mxc/tzic.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/plat-mxc/avic.c b/arch/arm/plat-mxc/avic.c index 8875fb4..55f1569 100644 --- a/arch/arm/plat-mxc/avic.c +++ b/arch/arm/plat-mxc/avic.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "irq-common.h" diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c index e993a184..a3c164c 100644 --- a/arch/arm/plat-mxc/tzic.c +++ b/arch/arm/plat-mxc/tzic.c @@ -17,6 +17,7 @@ #include #include +#include #include #include -- cgit v1.1 From 188d7c6b0cfee134cc7fbc61d36223b1d7dfffab Mon Sep 17 00:00:00 2001 From: Jason Liu Date: Thu, 3 Nov 2011 17:31:27 +0800 Subject: ARM:i.MX: fix build error in clock-mx51-mx53.c arch/arm/mach-mx5/clock-mx51-mx53.c: In function 'clk_get_freq_dt': arch/arm/mach-mx5/clock-mx51-mx53.c:1643: error: implicit declaration of function 'for_each_compatible_node' arch/arm/mach-mx5/clock-mx51-mx53.c:1643: error: expected ';' before '{' token Signed-off-by: Jason Liu --- arch/arm/mach-mx5/clock-mx51-mx53.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c index 2aacf41..6312425 100644 --- a/arch/arm/mach-mx5/clock-mx51-mx53.c +++ b/arch/arm/mach-mx5/clock-mx51-mx53.c @@ -1634,6 +1634,7 @@ int __init mx53_clocks_init(unsigned long ckil, unsigned long osc, return 0; } +#ifdef CONFIG_OF static void __init clk_get_freq_dt(unsigned long *ckil, unsigned long *osc, unsigned long *ckih1, unsigned long *ckih2) { @@ -1671,3 +1672,4 @@ int __init mx53_clocks_init_dt(void) clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2); return mx53_clocks_init(ckil, osc, ckih1, ckih2); } +#endif -- cgit v1.1 From a9866a0975881ba5e819b0a02324ba683b5cdb81 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 21 Oct 2011 11:53:34 +0800 Subject: MAINTAINERS: add ARM/FREESCALE MXS entry As suggested by Pengutronix, they want to get Sascha relieved from the burden of maintaining MXS sub-architecture. Since I brought the most of MXS core code to mainline (with the great help from Pengutronix people, thanks!), I would like to step up for maintaining MXS. Signed-off-by: Shawn Guo Acked-by: Sascha Hauer --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index ab77670..8fe3f01 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -804,6 +804,13 @@ S: Maintained T: git git://git.linaro.org/people/shawnguo/linux-2.6.git F: arch/arm/mach-imx/*imx6* +ARM/FREESCALE MXS ARM ARCHITECTURE +M: Shawn Guo +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +T: git git://git.linaro.org/people/shawnguo/linux-2.6.git +F: arch/arm/mach-mxs/ + ARM/GLOMATION GESBC9312SX MACHINE SUPPORT M: Lennert Buytenhek L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -- cgit v1.1 From 680da876f44a644aee891e1d0df5a560cfa4720e Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 3 Nov 2011 14:15:13 -0700 Subject: drm/i915: enable cacheable objects on Ivybridge IVB supports these bits as well. Signed-off-by: Jesse Barnes Reviewed-by: Daniel Vetter Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/i915_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index a838597..ed0b68f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3613,7 +3613,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, obj->base.write_domain = I915_GEM_DOMAIN_CPU; obj->base.read_domains = I915_GEM_DOMAIN_CPU; - if (IS_GEN6(dev)) { + if (IS_GEN6(dev) || IS_GEN7(dev)) { /* On Gen6, we can have the GPU use the LLC (the CPU * cache) for about a 10% performance improvement * compared to uncached. Graphics requests other than -- cgit v1.1 From 15394cad2747ea2d98fc88ccb464973e173cd2f8 Mon Sep 17 00:00:00 2001 From: Dirk Behme Date: Fri, 4 Nov 2011 20:30:18 +0800 Subject: ARM: mxc: Remove test_for_ltirq The patch "ARM: gic: consolidate PPI handling" removes the usage of test_for_ltirq. After the merge of imx6q remove this there, too. Cc: Sascha Hauer Signed-off-by: Dirk Behme Acked-by: Shawn Guo Acked-by: Marc Zyngier --- arch/arm/plat-mxc/include/mach/entry-macro.S | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S index 9fe0dfc..ca5cf26 100644 --- a/arch/arm/plat-mxc/include/mach/entry-macro.S +++ b/arch/arm/plat-mxc/include/mach/entry-macro.S @@ -25,6 +25,3 @@ .macro test_for_ipi, irqnr, irqstat, base, tmp .endm - - .macro test_for_ltirq, irqnr, irqstat, base, tmp - .endm -- cgit v1.1 From dfd3b596fbbfa48b8e7966ef996d587157554b69 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Fri, 4 Nov 2011 22:13:50 +0900 Subject: sh: Fix cached/uncaced address calculation in 29bit mode In the case of 29bit mode, CAC/UNCAC_ADDR does not return a right address. This revises this problem by using P1SEGADDR and P2SEGADDR in 29bit mode. Reported-by: Yutaro Ebihara Signed-off-by: Nobuhiro Iwamatsu Tested-by: Kuninori Morimoto Tested-by: Simon Horman Cc: stable@kernel.org Signed-off-by: Paul Mundt --- arch/sh/include/asm/page.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h index 0dca9a5..15d9703 100644 --- a/arch/sh/include/asm/page.h +++ b/arch/sh/include/asm/page.h @@ -151,8 +151,13 @@ typedef struct page *pgtable_t; #endif /* !__ASSEMBLY__ */ #ifdef CONFIG_UNCACHED_MAPPING +#if defined(CONFIG_29BIT) +#define UNCAC_ADDR(addr) P2SEGADDR(addr) +#define CAC_ADDR(addr) P1SEGADDR(addr) +#else #define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + uncached_start) #define CAC_ADDR(addr) ((addr) - uncached_start + PAGE_OFFSET) +#endif #else #define UNCAC_ADDR(addr) ((addr)) #define CAC_ADDR(addr) ((addr)) -- cgit v1.1 From 3af1f8a41feab47b232b0c3d3b2322426672480d Mon Sep 17 00:00:00 2001 From: Phil Edworthy Date: Mon, 3 Oct 2011 15:16:47 +0100 Subject: serial: sh-sci: Fix up SH-2A SCIF support. This fixes up support for SH-2(A) SCIFs by introducing a new regtype. As expected, it's close to the SH-4A SCIF with fifodata, but still different enough to warrant its own type. Fixes up a number of FIFO overflows and similar for both SH7203/SH7264. Signed-off-by: Phil Edworthy Tested-by: Federico Fuga Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh2a/setup-sh7203.c | 16 ++++++++++++---- drivers/tty/serial/sh-sci.c | 19 +++++++++++++++++++ include/linux/serial_sci.h | 1 + 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c index a43124e..0bd744f 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c @@ -176,10 +176,12 @@ static DECLARE_INTC_DESC(intc_desc, "sh7203", vectors, groups, static struct plat_sci_port scif0_platform_data = { .mapbase = 0xfffe8000, .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | + SCSCR_REIE, .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 192, 192, 192, 192 }, + .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif0_device = { @@ -193,10 +195,12 @@ static struct platform_device scif0_device = { static struct plat_sci_port scif1_platform_data = { .mapbase = 0xfffe8800, .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | + SCSCR_REIE, .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 196, 196, 196, 196 }, + .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif1_device = { @@ -210,10 +214,12 @@ static struct platform_device scif1_device = { static struct plat_sci_port scif2_platform_data = { .mapbase = 0xfffe9000, .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | + SCSCR_REIE, .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 200, 200, 200, 200 }, + .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif2_device = { @@ -227,10 +233,12 @@ static struct platform_device scif2_device = { static struct plat_sci_port scif3_platform_data = { .mapbase = 0xfffe9800, .flags = UPF_BOOT_AUTOCONF, - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | + SCSCR_REIE, .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 204, 204, 204, 204 }, + .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, }; static struct platform_device scif3_device = { diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 9871c57..1b6ec56 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -207,6 +207,25 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { }, /* + * Common SH-2(A) SCIF definitions for ports with FIFO data + * count registers. + */ + [SCIx_SH2_SCIF_FIFODATA_REGTYPE] = { + [SCSMR] = { 0x00, 16 }, + [SCBRR] = { 0x04, 8 }, + [SCSCR] = { 0x08, 16 }, + [SCxTDR] = { 0x0c, 8 }, + [SCxSR] = { 0x10, 16 }, + [SCxRDR] = { 0x14, 8 }, + [SCFCR] = { 0x18, 16 }, + [SCFDR] = { 0x1c, 16 }, + [SCTFDR] = sci_reg_invalid, + [SCRFDR] = sci_reg_invalid, + [SCSPTR] = { 0x20, 16 }, + [SCLSR] = { 0x24, 16 }, + }, + + /* * Common SH-3 SCIF definitions. */ [SCIx_SH3_SCIF_REGTYPE] = { diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index 8bffe9a..5f3939c 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -67,6 +67,7 @@ enum { SCIx_IRDA_REGTYPE, SCIx_SCIFA_REGTYPE, SCIx_SCIFB_REGTYPE, + SCIx_SH2_SCIF_FIFODATA_REGTYPE, SCIx_SH3_SCIF_REGTYPE, SCIx_SH4_SCIF_REGTYPE, SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, -- cgit v1.1 From 87121ca504fd1d963a66b3fb0c72054b0fd9a177 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Fri, 7 Oct 2011 16:31:46 +0200 Subject: oprofile: Fix crash when unloading module (hr timer mode) Oprofile may crash in a KVM guest while unlaoding modules. This happens if oprofile_arch_init() fails and oprofile switches to the hr timer mode as a fallback. In this case oprofile_arch_exit() is called, but it never was initialized properly which causes the crash. This patch fixes this. oprofile: using timer interrupt. BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 IP: [] unregister_syscore_ops+0x41/0x58 PGD 41da3f067 PUD 41d80e067 PMD 0 Oops: 0002 [#1] PREEMPT SMP CPU 5 Modules linked in: oprofile(-) Pid: 2382, comm: modprobe Not tainted 3.1.0-rc7-00018-g709a39d #18 Advanced Micro Device Anaheim/Anaheim RIP: 0010:[] [] unregister_syscore_ops+0x41/0x58 RSP: 0018:ffff88041de1de98 EFLAGS: 00010296 RAX: 0000000000000000 RBX: ffffffffa00060e0 RCX: dead000000200200 RDX: 0000000000000000 RSI: dead000000100100 RDI: ffffffff8178c620 RBP: ffff88041de1dea8 R08: 0000000000000001 R09: 0000000000000082 R10: 0000000000000000 R11: ffff88041de1dde8 R12: 0000000000000080 R13: fffffffffffffff5 R14: 0000000000000001 R15: 0000000000610210 FS: 00007f9ae5bef700(0000) GS:ffff88042fd40000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000008 CR3: 000000041ca44000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process modprobe (pid: 2382, threadinfo ffff88041de1c000, task ffff88042db6d040) Stack: ffff88041de1deb8 ffffffffa0006770 ffff88041de1deb8 ffffffffa000251e ffff88041de1dec8 ffffffffa00022c2 ffff88041de1ded8 ffffffffa0004993 ffff88041de1df78 ffffffff81073115 656c69666f72706f 0000000000610200 Call Trace: [] op_nmi_exit+0x15/0x17 [oprofile] [] oprofile_arch_exit+0xe/0x10 [oprofile] [] oprofile_exit+0x13/0x15 [oprofile] [] sys_delete_module+0x1c3/0x22f [] ? trace_hardirqs_on_thunk+0x3a/0x3f [] system_call_fastpath+0x16/0x1b Code: 20 c6 78 81 e8 c5 cc 23 00 48 8b 13 48 8b 43 08 48 be 00 01 10 00 00 00 ad de 48 b9 00 02 20 00 00 00 ad de 48 c7 c7 20 c6 78 81 89 42 08 48 89 10 48 89 33 48 89 4b 08 e8 a6 c0 23 00 5a 5b RIP [] unregister_syscore_ops+0x41/0x58 RSP CR2: 0000000000000008 ---[ end trace 06d4e95b6aa3b437 ]--- CC: stable@kernel.org # 2.6.37+ Signed-off-by: Robert Richter --- drivers/oprofile/oprof.c | 29 ++++++++++++++++++++++++----- drivers/oprofile/timer_int.c | 1 + 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c index dccd863..f8c752e 100644 --- a/drivers/oprofile/oprof.c +++ b/drivers/oprofile/oprof.c @@ -239,26 +239,45 @@ int oprofile_set_ulong(unsigned long *addr, unsigned long val) return err; } +static int timer_mode; + static int __init oprofile_init(void) { int err; + /* always init architecture to setup backtrace support */ err = oprofile_arch_init(&oprofile_ops); - if (err < 0 || timer) { - printk(KERN_INFO "oprofile: using timer interrupt.\n"); + + timer_mode = err || timer; /* fall back to timer mode on errors */ + if (timer_mode) { + if (!err) + oprofile_arch_exit(); err = oprofile_timer_init(&oprofile_ops); if (err) return err; } - return oprofilefs_register(); + + err = oprofilefs_register(); + if (!err) + return 0; + + /* failed */ + if (timer_mode) + oprofile_timer_exit(); + else + oprofile_arch_exit(); + + return err; } static void __exit oprofile_exit(void) { - oprofile_timer_exit(); oprofilefs_unregister(); - oprofile_arch_exit(); + if (timer_mode) + oprofile_timer_exit(); + else + oprofile_arch_exit(); } diff --git a/drivers/oprofile/timer_int.c b/drivers/oprofile/timer_int.c index 3ef4462..878fba1 100644 --- a/drivers/oprofile/timer_int.c +++ b/drivers/oprofile/timer_int.c @@ -110,6 +110,7 @@ int oprofile_timer_init(struct oprofile_operations *ops) ops->start = oprofile_hrtimer_start; ops->stop = oprofile_hrtimer_stop; ops->cpu_type = "timer"; + printk(KERN_INFO "oprofile: using timer interrupt.\n"); return 0; } -- cgit v1.1 From 97f7f8189fe54e3cfe324ef9ad35064f3d2d3bff Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Mon, 10 Oct 2011 16:21:10 +0200 Subject: oprofile, x86: Fix crash when unloading module (nmi timer mode) If oprofile uses the nmi timer interrupt there is a crash while unloading the module. The bug can be triggered with oprofile build as module and kernel parameter nolapic set. This patch fixes this. oprofile: using NMI timer interrupt. BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 IP: [] unregister_syscore_ops+0x41/0x58 PGD 42dbca067 PUD 41da6a067 PMD 0 Oops: 0002 [#1] PREEMPT SMP CPU 5 Modules linked in: oprofile(-) [last unloaded: oprofile] Pid: 2518, comm: modprobe Not tainted 3.1.0-rc7-00019-gb2fb49d #19 Advanced Micro Device Anaheim/Anaheim RIP: 0010:[] [] unregister_syscore_ops+0x41/0x58 RSP: 0018:ffff88041ef71e98 EFLAGS: 00010296 RAX: 0000000000000000 RBX: ffffffffa0017100 RCX: dead000000200200 RDX: 0000000000000000 RSI: dead000000100100 RDI: ffffffff8178c620 RBP: ffff88041ef71ea8 R08: 0000000000000001 R09: 0000000000000082 R10: 0000000000000000 R11: ffff88041ef71de8 R12: 0000000000000080 R13: fffffffffffffff5 R14: 0000000000000001 R15: 0000000000610210 FS: 00007fc902f20700(0000) GS:ffff88042fd40000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000008 CR3: 000000041cdb6000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process modprobe (pid: 2518, threadinfo ffff88041ef70000, task ffff88041d348040) Stack: ffff88041ef71eb8 ffffffffa0017790 ffff88041ef71eb8 ffffffffa0013532 ffff88041ef71ec8 ffffffffa00132d6 ffff88041ef71ed8 ffffffffa00159b2 ffff88041ef71f78 ffffffff81073115 656c69666f72706f 0000000000610200 Call Trace: [] op_nmi_exit+0x15/0x17 [oprofile] [] oprofile_arch_exit+0xe/0x10 [oprofile] [] oprofile_exit+0x1e/0x20 [oprofile] [] sys_delete_module+0x1c3/0x22f [] ? trace_hardirqs_on_thunk+0x3a/0x3f [] system_call_fastpath+0x16/0x1b Code: 20 c6 78 81 e8 c5 cc 23 00 48 8b 13 48 8b 43 08 48 be 00 01 10 00 00 00 ad de 48 b9 00 02 20 00 00 00 ad de 48 c7 c7 20 c6 78 81 89 42 08 48 89 10 48 89 33 48 89 4b 08 e8 a6 c0 23 00 5a 5b RIP [] unregister_syscore_ops+0x41/0x58 RSP CR2: 0000000000000008 ---[ end trace 43a541a52956b7b0 ]--- CC: stable@kernel.org # 2.6.37+ Signed-off-by: Robert Richter --- arch/x86/oprofile/init.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/x86/oprofile/init.c b/arch/x86/oprofile/init.c index cdfe4c5..f148cf6 100644 --- a/arch/x86/oprofile/init.c +++ b/arch/x86/oprofile/init.c @@ -21,6 +21,7 @@ extern int op_nmi_timer_init(struct oprofile_operations *ops); extern void op_nmi_exit(void); extern void x86_backtrace(struct pt_regs * const regs, unsigned int depth); +static int nmi_timer; int __init oprofile_arch_init(struct oprofile_operations *ops) { @@ -31,8 +32,9 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) #ifdef CONFIG_X86_LOCAL_APIC ret = op_nmi_init(ops); #endif + nmi_timer = (ret != 0); #ifdef CONFIG_X86_IO_APIC - if (ret < 0) + if (nmi_timer) ret = op_nmi_timer_init(ops); #endif ops->backtrace = x86_backtrace; @@ -44,6 +46,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) void oprofile_arch_exit(void) { #ifdef CONFIG_X86_LOCAL_APIC - op_nmi_exit(); + if (!nmi_timer) + op_nmi_exit(); #endif } -- cgit v1.1 From dd2c0ca1b153b555c09fd8e08f6842e12cf8e87b Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 19 Sep 2011 18:51:13 -0700 Subject: sh: clkfwk: add clk_rate_mult_range_round() This provides a clk_rate_mult_range_round() helper for use by some of the CPG PLL ranged multipliers, following the same approach as used by the div ranges. Signed-off-by: Kuninori Morimoto Signed-off-by: Paul Mundt --- drivers/sh/clk/core.c | 20 ++++++++++++++++++++ include/linux/sh_clk.h | 3 +++ 2 files changed, 23 insertions(+) diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c index dc8d022..352036b 100644 --- a/drivers/sh/clk/core.c +++ b/drivers/sh/clk/core.c @@ -173,6 +173,26 @@ long clk_rate_div_range_round(struct clk *clk, unsigned int div_min, return clk_rate_round_helper(&div_range_round); } +static long clk_rate_mult_range_iter(unsigned int pos, + struct clk_rate_round_data *rounder) +{ + return clk_get_rate(rounder->arg) * pos; +} + +long clk_rate_mult_range_round(struct clk *clk, unsigned int mult_min, + unsigned int mult_max, unsigned long rate) +{ + struct clk_rate_round_data mult_range_round = { + .min = mult_min, + .max = mult_max, + .func = clk_rate_mult_range_iter, + .arg = clk_get_parent(clk), + .rate = rate, + }; + + return clk_rate_round_helper(&mult_range_round); +} + int clk_rate_table_find(struct clk *clk, struct cpufreq_frequency_table *freq_table, unsigned long rate) diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h index 3ccf186..9237c29 100644 --- a/include/linux/sh_clk.h +++ b/include/linux/sh_clk.h @@ -94,6 +94,9 @@ int clk_rate_table_find(struct clk *clk, long clk_rate_div_range_round(struct clk *clk, unsigned int div_min, unsigned int div_max, unsigned long rate); +long clk_rate_mult_range_round(struct clk *clk, unsigned int mult_min, + unsigned int mult_max, unsigned long rate); + long clk_round_parent(struct clk *clk, unsigned long target, unsigned long *best_freq, unsigned long *parent_freq, unsigned int div_min, unsigned int div_max); -- cgit v1.1 From d31c285b3a71cf9056e6a060de41f37780b0af86 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 3 Nov 2011 13:06:08 -0700 Subject: xhci: Set slot and ep0 flags for address command. Matt's AsMedia xHCI host controller was responding with a Context Error to an address device command after a configured device reset. Some sequence of events leads both the slot and endpoint zero add flags cleared to zero, which the AsMedia host doesn't like: [ 223.701839] xhci_hcd 0000:03:00.0: Slot ID 1 Input Context: [ 223.701841] xhci_hcd 0000:03:00.0: @ffff880137b25000 (virt) @ffffc000 (dma) 0x000000 - drop flags [ 223.701843] xhci_hcd 0000:03:00.0: @ffff880137b25004 (virt) @ffffc004 (dma) 0x000000 - add flags [ 223.701846] xhci_hcd 0000:03:00.0: @ffff880137b25008 (virt) @ffffc008 (dma) 0x000000 - rsvd2[0] [ 223.701848] xhci_hcd 0000:03:00.0: @ffff880137b2500c (virt) @ffffc00c (dma) 0x000000 - rsvd2[1] [ 223.701850] xhci_hcd 0000:03:00.0: @ffff880137b25010 (virt) @ffffc010 (dma) 0x000000 - rsvd2[2] [ 223.701852] xhci_hcd 0000:03:00.0: @ffff880137b25014 (virt) @ffffc014 (dma) 0x000000 - rsvd2[3] [ 223.701854] xhci_hcd 0000:03:00.0: @ffff880137b25018 (virt) @ffffc018 (dma) 0x000000 - rsvd2[4] [ 223.701857] xhci_hcd 0000:03:00.0: @ffff880137b2501c (virt) @ffffc01c (dma) 0x000000 - rsvd2[5] [ 223.701858] xhci_hcd 0000:03:00.0: Slot Context: [ 223.701860] xhci_hcd 0000:03:00.0: @ffff880137b25020 (virt) @ffffc020 (dma) 0x8400000 - dev_info [ 223.701862] xhci_hcd 0000:03:00.0: @ffff880137b25024 (virt) @ffffc024 (dma) 0x010000 - dev_info2 [ 223.701864] xhci_hcd 0000:03:00.0: @ffff880137b25028 (virt) @ffffc028 (dma) 0x000000 - tt_info [ 223.701866] xhci_hcd 0000:03:00.0: @ffff880137b2502c (virt) @ffffc02c (dma) 0x000000 - dev_state [ 223.701869] xhci_hcd 0000:03:00.0: @ffff880137b25030 (virt) @ffffc030 (dma) 0x000000 - rsvd[0] [ 223.701871] xhci_hcd 0000:03:00.0: @ffff880137b25034 (virt) @ffffc034 (dma) 0x000000 - rsvd[1] [ 223.701873] xhci_hcd 0000:03:00.0: @ffff880137b25038 (virt) @ffffc038 (dma) 0x000000 - rsvd[2] [ 223.701875] xhci_hcd 0000:03:00.0: @ffff880137b2503c (virt) @ffffc03c (dma) 0x000000 - rsvd[3] [ 223.701877] xhci_hcd 0000:03:00.0: Endpoint 00 Context: [ 223.701879] xhci_hcd 0000:03:00.0: @ffff880137b25040 (virt) @ffffc040 (dma) 0x000000 - ep_info [ 223.701881] xhci_hcd 0000:03:00.0: @ffff880137b25044 (virt) @ffffc044 (dma) 0x2000026 - ep_info2 [ 223.701883] xhci_hcd 0000:03:00.0: @ffff880137b25048 (virt) @ffffc048 (dma) 0xffffe8e0 - deq [ 223.701885] xhci_hcd 0000:03:00.0: @ffff880137b25050 (virt) @ffffc050 (dma) 0x000000 - tx_info [ 223.701887] xhci_hcd 0000:03:00.0: @ffff880137b25054 (virt) @ffffc054 (dma) 0x000000 - rsvd[0] [ 223.701889] xhci_hcd 0000:03:00.0: @ffff880137b25058 (virt) @ffffc058 (dma) 0x000000 - rsvd[1] [ 223.701892] xhci_hcd 0000:03:00.0: @ffff880137b2505c (virt) @ffffc05c (dma) 0x000000 - rsvd[2] ... [ 223.701927] xhci_hcd 0000:03:00.0: // Ding dong! [ 223.701992] xhci_hcd 0000:03:00.0: Setup ERROR: address device command for slot 1. The xHCI spec says that both flags must be set to one for the Address Device command. When the device is first enumerated, xhci_setup_addressable_virt_dev() does set those flags. However, when the device is addressed after it has been reset in the configured state, xhci_setup_addressable_virt_dev() is not called, and xhci_copy_ep0_dequeue_into_input_ctx() is called instead. That function relies on the flags being set up by previous commands, which apparently isn't a good assumption. Move the setting of the flags into the common parent function. This should be queued for stable kernels as old as 2.6.35, since that was the first introduction of xhci_copy_ep0_dequeue_into_input_ctx. Signed-off-by: Sarah Sharp Tested-by: Matt Cc: stable@vger.kernel.org --- drivers/usb/host/xhci-mem.c | 5 ----- drivers/usb/host/xhci.c | 5 ++++- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 42a22b8..0e4b25f 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -982,7 +982,6 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud struct xhci_virt_device *dev; struct xhci_ep_ctx *ep0_ctx; struct xhci_slot_ctx *slot_ctx; - struct xhci_input_control_ctx *ctrl_ctx; u32 port_num; struct usb_device *top_dev; @@ -994,12 +993,8 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud return -EINVAL; } ep0_ctx = xhci_get_ep_ctx(xhci, dev->in_ctx, 0); - ctrl_ctx = xhci_get_input_control_ctx(xhci, dev->in_ctx); slot_ctx = xhci_get_slot_ctx(xhci, dev->in_ctx); - /* 2) New slot context and endpoint 0 context are valid*/ - ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG); - /* 3) Only the control endpoint is valid - one endpoint context */ slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | udev->route); switch (udev->speed) { diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 1ff95a0..747c5ea 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -3504,6 +3504,10 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) /* Otherwise, update the control endpoint ring enqueue pointer. */ else xhci_copy_ep0_dequeue_into_input_ctx(xhci, udev); + ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); + ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG); + ctrl_ctx->drop_flags = 0; + xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); @@ -3585,7 +3589,6 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) virt_dev->address = (le32_to_cpu(slot_ctx->dev_state) & DEV_ADDR_MASK) + 1; /* Zero the input context control for later use */ - ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); ctrl_ctx->add_flags = 0; ctrl_ctx->drop_flags = 0; -- cgit v1.1 From 79c3dd8150fd5236d95766a9e662e3e932b462c9 Mon Sep 17 00:00:00 2001 From: Don Zickus Date: Thu, 3 Nov 2011 09:07:18 -0400 Subject: usb, xhci: Clear warm reset change event during init I noticed on my Panther Point system that I wasn't getting hotplug events for my usb3.0 disk on a usb3 port. I tracked it down to the fact that the system had the warm reset change bit still set. This seemed to block future events from being received, including a hotplug event. Clearing this bit during initialization allowed the hotplug event to be received and the disk to be recognized correctly. This patch should be backported to kernels as old as 2.6.39. Signed-off-by: Don Zickus Signed-off-by: Sarah Sharp Cc: stable@vger.kernel.org --- drivers/usb/core/hub.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 96f05b2..7978146 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -813,6 +813,12 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) USB_PORT_FEAT_C_PORT_LINK_STATE); } + if ((portchange & USB_PORT_STAT_C_BH_RESET) && + hub_is_superspeed(hub->hdev)) { + need_debounce_delay = true; + clear_port_feature(hub->hdev, port1, + USB_PORT_FEAT_C_BH_PORT_RESET); + } /* We can forget about a "removed" device when there's a * physical disconnect or the connect status changes. */ -- cgit v1.1 From 1788ea6e3b2a58cf4fb00206e362d9caff8d86a7 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Fri, 4 Nov 2011 13:31:21 -0400 Subject: nfs: when attempting to open a directory, fall back on normal lookup (try #5) commit d953126 changed how nfs_atomic_lookup handles an -EISDIR return from an OPEN call. Prior to that patch, that caused the client to fall back to doing a normal lookup. When that patch went in, the code began returning that error to userspace. The d_revalidate codepath however never had the corresponding change, so it was still possible to end up with a NULL ctx->state pointer after that. That patch caused a regression. When we attempt to open a directory that does not have a cached dentry, that open now errors out with EISDIR. If you attempt the same open with a cached dentry, it will succeed. Fix this by reverting the change in nfs_atomic_lookup and allowing attempts to open directories to fall back to a normal lookup Also, add a NFSv4-specific f_ops->open routine that just returns -ENOTDIR. This should never be called if things are working properly, but if it ever is, then the dprintk may help in debugging. To facilitate this, a new file_operations field is also added to the nfs_rpc_ops struct. Cc: stable@kernel.org Signed-off-by: Jeff Layton Signed-off-by: Trond Myklebust --- fs/nfs/dir.c | 2 +- fs/nfs/file.c | 32 ++++++++++++++++++++++++++++++++ fs/nfs/inode.c | 2 +- fs/nfs/nfs3proc.c | 1 + fs/nfs/nfs4proc.c | 1 + fs/nfs/proc.c | 1 + include/linux/nfs_fs.h | 3 +++ include/linux/nfs_xdr.h | 1 + 8 files changed, 41 insertions(+), 2 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index b238d95..ac28990 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1468,12 +1468,12 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry res = NULL; goto out; /* This turned out not to be a regular file */ + case -EISDIR: case -ENOTDIR: goto no_open; case -ELOOP: if (!(nd->intent.open.flags & O_NOFOLLOW)) goto no_open; - /* case -EISDIR: */ /* case -EINVAL: */ default: res = ERR_CAST(inode); diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 0a1f831..6d93e07 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -886,3 +886,35 @@ static int nfs_setlease(struct file *file, long arg, struct file_lock **fl) file->f_path.dentry->d_name.name, arg); return -EINVAL; } + +#ifdef CONFIG_NFS_V4 +static int +nfs4_file_open(struct inode *inode, struct file *filp) +{ + /* + * NFSv4 opens are handled in d_lookup and d_revalidate. If we get to + * this point, then something is very wrong + */ + dprintk("NFS: %s called! inode=%p filp=%p\n", __func__, inode, filp); + return -ENOTDIR; +} + +const struct file_operations nfs4_file_operations = { + .llseek = nfs_file_llseek, + .read = do_sync_read, + .write = do_sync_write, + .aio_read = nfs_file_read, + .aio_write = nfs_file_write, + .mmap = nfs_file_mmap, + .open = nfs4_file_open, + .flush = nfs_file_flush, + .release = nfs_file_release, + .fsync = nfs_file_fsync, + .lock = nfs_lock, + .flock = nfs_flock, + .splice_read = nfs_file_splice_read, + .splice_write = nfs_file_splice_write, + .check_flags = nfs_check_flags, + .setlease = nfs_setlease, +}; +#endif /* CONFIG_NFS_V4 */ diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index c07a55a..50a15fa 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -291,7 +291,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) */ inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->file_inode_ops; if (S_ISREG(inode->i_mode)) { - inode->i_fop = &nfs_file_operations; + inode->i_fop = NFS_SB(sb)->nfs_client->rpc_ops->file_ops; inode->i_data.a_ops = &nfs_file_aops; inode->i_data.backing_dev_info = &NFS_SB(sb)->backing_dev_info; } else if (S_ISDIR(inode->i_mode)) { diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 85f1690..d4bc9ed9 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -853,6 +853,7 @@ const struct nfs_rpc_ops nfs_v3_clientops = { .dentry_ops = &nfs_dentry_operations, .dir_inode_ops = &nfs3_dir_inode_operations, .file_inode_ops = &nfs3_file_inode_operations, + .file_ops = &nfs_file_operations, .getroot = nfs3_proc_get_root, .getattr = nfs3_proc_getattr, .setattr = nfs3_proc_setattr, diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index b60fddf..069cb80 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -6253,6 +6253,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = { .dentry_ops = &nfs4_dentry_operations, .dir_inode_ops = &nfs4_dir_inode_operations, .file_inode_ops = &nfs4_file_inode_operations, + .file_ops = &nfs4_file_operations, .getroot = nfs4_proc_get_root, .getattr = nfs4_proc_getattr, .setattr = nfs4_proc_setattr, diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index ac40b85..f48125d 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c @@ -710,6 +710,7 @@ const struct nfs_rpc_ops nfs_v2_clientops = { .dentry_ops = &nfs_dentry_operations, .dir_inode_ops = &nfs_dir_inode_operations, .file_inode_ops = &nfs_file_inode_operations, + .file_ops = &nfs_file_operations, .getroot = nfs_proc_get_root, .getattr = nfs_proc_getattr, .setattr = nfs_proc_setattr, diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index ab2c634..92ecf55 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -410,6 +410,9 @@ extern const struct inode_operations nfs_file_inode_operations; extern const struct inode_operations nfs3_file_inode_operations; #endif /* CONFIG_NFS_V3 */ extern const struct file_operations nfs_file_operations; +#ifdef CONFIG_NFS_V4 +extern const struct file_operations nfs4_file_operations; +#endif /* CONFIG_NFS_V4 */ extern const struct address_space_operations nfs_file_aops; extern const struct address_space_operations nfs_dir_aops; diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index c74595b..2a7c533 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1192,6 +1192,7 @@ struct nfs_rpc_ops { const struct dentry_operations *dentry_ops; const struct inode_operations *dir_inode_ops; const struct inode_operations *file_inode_ops; + const struct file_operations *file_ops; int (*getroot) (struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); -- cgit v1.1 From 0486958f57a496212e3c1e3d9194deebba3dc3d4 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Fri, 4 Nov 2011 13:31:22 -0400 Subject: nfs: move nfs_file_operations declaration to bottom of file.c (try #2) ...a remove a set of forward declarations. Signed-off-by: Jeff Layton Signed-off-by: Trond Myklebust --- fs/nfs/file.c | 59 +++++++++++++++++++---------------------------------------- 1 file changed, 19 insertions(+), 40 deletions(-) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 6d93e07..eca56d4 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -40,48 +40,8 @@ #define NFSDBG_FACILITY NFSDBG_FILE -static int nfs_file_open(struct inode *, struct file *); -static int nfs_file_release(struct inode *, struct file *); -static loff_t nfs_file_llseek(struct file *file, loff_t offset, int origin); -static int nfs_file_mmap(struct file *, struct vm_area_struct *); -static ssize_t nfs_file_splice_read(struct file *filp, loff_t *ppos, - struct pipe_inode_info *pipe, - size_t count, unsigned int flags); -static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov, - unsigned long nr_segs, loff_t pos); -static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe, - struct file *filp, loff_t *ppos, - size_t count, unsigned int flags); -static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov, - unsigned long nr_segs, loff_t pos); -static int nfs_file_flush(struct file *, fl_owner_t id); -static int nfs_file_fsync(struct file *, loff_t, loff_t, int datasync); -static int nfs_check_flags(int flags); -static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); -static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); -static int nfs_setlease(struct file *file, long arg, struct file_lock **fl); - static const struct vm_operations_struct nfs_file_vm_ops; -const struct file_operations nfs_file_operations = { - .llseek = nfs_file_llseek, - .read = do_sync_read, - .write = do_sync_write, - .aio_read = nfs_file_read, - .aio_write = nfs_file_write, - .mmap = nfs_file_mmap, - .open = nfs_file_open, - .flush = nfs_file_flush, - .release = nfs_file_release, - .fsync = nfs_file_fsync, - .lock = nfs_lock, - .flock = nfs_flock, - .splice_read = nfs_file_splice_read, - .splice_write = nfs_file_splice_write, - .check_flags = nfs_check_flags, - .setlease = nfs_setlease, -}; - const struct inode_operations nfs_file_inode_operations = { .permission = nfs_permission, .getattr = nfs_getattr, @@ -887,6 +847,25 @@ static int nfs_setlease(struct file *file, long arg, struct file_lock **fl) return -EINVAL; } +const struct file_operations nfs_file_operations = { + .llseek = nfs_file_llseek, + .read = do_sync_read, + .write = do_sync_write, + .aio_read = nfs_file_read, + .aio_write = nfs_file_write, + .mmap = nfs_file_mmap, + .open = nfs_file_open, + .flush = nfs_file_flush, + .release = nfs_file_release, + .fsync = nfs_file_fsync, + .lock = nfs_lock, + .flock = nfs_flock, + .splice_read = nfs_file_splice_read, + .splice_write = nfs_file_splice_write, + .check_flags = nfs_check_flags, + .setlease = nfs_setlease, +}; + #ifdef CONFIG_NFS_V4 static int nfs4_file_open(struct inode *inode, struct file *filp) -- cgit v1.1 From 8eeea521d9d0fa6afd62df8c6e6566ee946117fa Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 4 Nov 2011 15:52:31 +0000 Subject: ASoC: Don't use wm8994->control_data in wm8994_readable_register() The field is no longer initialised so this will crash if running on wm8958. Reported-by: Thomas Abraham Signed-off-by: Mark Brown Cc: stable@kernel.org --- sound/soc/codecs/wm8994.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 6b73efd..3d2c3d4 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -56,7 +56,7 @@ static int wm8994_retune_mobile_base[] = { static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994 *control = wm8994->control_data; + struct wm8994 *control = codec->control_data; switch (reg) { case WM8994_GPIO_1: -- cgit v1.1 From 5a3ad6bd6ae0687cb0ecb424d74221920fbc7f38 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 4 Nov 2011 15:53:48 +0000 Subject: ASoC: Don't use wm8994->control_data when requesting IRQs The field is no longer initialised so this will crash if running on wm8958. Reported-by: Thomas Abraham Signed-off-by: Mark Brown --- sound/soc/codecs/wm8994.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 3d2c3d4..9cb16cc 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3180,9 +3180,9 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, wm8994_fifo_error, "FIFO error", codec); - wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_WARN, + wm8994_request_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, wm8994_temp_warn, "Thermal warning", codec); - wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_SHUT, + wm8994_request_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, wm8994_temp_shut, "Thermal shutdown", codec); ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE, -- cgit v1.1 From 19940b3d55c87d8089a8cb0fa8e5a9918a3846bd Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 19 Aug 2011 18:05:05 +0900 Subject: ASoC: Ensure we get an impedence reported for WM8958 jack detect Occasionally we may see an accessory reported before we have a stable impedance for the accessory. If this happens then reread the status in order to ensure that the handler can take the appropriate action for the status change. Signed-off-by: Mark Brown --- include/linux/mfd/wm8994/registers.h | 15 +++++++++++++++ sound/soc/codecs/wm8994.c | 37 +++++++++++++++++++++++++----------- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/include/linux/mfd/wm8994/registers.h b/include/linux/mfd/wm8994/registers.h index fae2950..83a9cae 100644 --- a/include/linux/mfd/wm8994/registers.h +++ b/include/linux/mfd/wm8994/registers.h @@ -1963,6 +1963,21 @@ #define WM8958_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */ /* + * R210 (0xD2) - Mic Detect 3 + */ +#define WM8958_MICD_LVL_MASK 0x07FC /* MICD_LVL - [10:2] */ +#define WM8958_MICD_LVL_SHIFT 2 /* MICD_LVL - [10:2] */ +#define WM8958_MICD_LVL_WIDTH 9 /* MICD_LVL - [10:2] */ +#define WM8958_MICD_VALID 0x0002 /* MICD_VALID */ +#define WM8958_MICD_VALID_MASK 0x0002 /* MICD_VALID */ +#define WM8958_MICD_VALID_SHIFT 1 /* MICD_VALID */ +#define WM8958_MICD_VALID_WIDTH 1 /* MICD_VALID */ +#define WM8958_MICD_STS 0x0001 /* MICD_STS */ +#define WM8958_MICD_STS_MASK 0x0001 /* MICD_STS */ +#define WM8958_MICD_STS_SHIFT 0 /* MICD_STS */ +#define WM8958_MICD_STS_WIDTH 1 /* MICD_STS */ + +/* * R76 (0x4C) - Charge Pump (1) */ #define WM8994_CP_ENA 0x8000 /* CP_ENA */ diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 9cb16cc..9c982e4 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3030,19 +3030,34 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) { struct wm8994_priv *wm8994 = data; struct snd_soc_codec *codec = wm8994->codec; - int reg; + int reg, count; - reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); - if (reg < 0) { - dev_err(codec->dev, "Failed to read mic detect status: %d\n", - reg); - return IRQ_NONE; - } + /* We may occasionally read a detection without an impedence + * range being provided - if that happens loop again. + */ + count = 10; + do { + reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); + if (reg < 0) { + dev_err(codec->dev, + "Failed to read mic detect status: %d\n", + reg); + return IRQ_NONE; + } - if (!(reg & WM8958_MICD_VALID)) { - dev_dbg(codec->dev, "Mic detect data not valid\n"); - goto out; - } + if (!(reg & WM8958_MICD_VALID)) { + dev_dbg(codec->dev, "Mic detect data not valid\n"); + goto out; + } + + if (!(reg & WM8958_MICD_STS) || (reg & WM8958_MICD_LVL_MASK)) + break; + + msleep(1); + } while (count--); + + if (count == 0) + dev_warn(codec->dev, "No impedence range reported for jack\n"); #ifndef CONFIG_SND_SOC_WM8994_MODULE trace_snd_soc_jack_irq(dev_name(codec->dev)); -- cgit v1.1 From b42c909743595208f7987e331f0921b73af2ce25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20Miljenovi=C4=87?= Date: Fri, 4 Nov 2011 23:59:49 -0700 Subject: Input: i8042 - add HP Pavilion dv4s to 'notimeout' and 'nomux' blacklists Touchpad input doesn't work with newer HP Pavilion dv4 laptops due to bad i8042 timeout data. Booting with i8042.notimeout and i8042.nomux successfully works around the problem. This patch adds the devices to the i8042 notimeout and nomux blacklists. Signed-off-by: Tomas Miljenovic Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042-x86ia64io.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index bb9f5d3..b4cfc6c 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -431,6 +431,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), }, }, + { + /* Newer HP Pavilion dv4 models */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"), + }, + }, { } }; @@ -560,6 +567,13 @@ static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), }, }, + { + /* Newer HP Pavilion dv4 models */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"), + }, + }, { } }; -- cgit v1.1 From 15a2015fbc692e1c97d7ce12d96e077f5ae7ea6d Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Sat, 5 Nov 2011 22:06:31 -0700 Subject: ceph: fix iput race when queueing inode work If we queue a work item that calls iput(), make sure we ihold() before attempting to queue work. Otherwise our queued work might miraculously run before we notice the queue_work() succeeded and call ihold(), allowing the inode to be destroyed. That is, instead of if (queue_work(...)) ihold(); we need to do ihold(); if (!queue_work(...)) iput(); Reported-by: Amon Ott Signed-off-by: Sage Weil --- fs/ceph/inode.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index e392bfc..116f365 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -1328,12 +1328,13 @@ int ceph_inode_set_size(struct inode *inode, loff_t size) */ void ceph_queue_writeback(struct inode *inode) { + ihold(inode); if (queue_work(ceph_inode_to_client(inode)->wb_wq, &ceph_inode(inode)->i_wb_work)) { dout("ceph_queue_writeback %p\n", inode); - ihold(inode); } else { dout("ceph_queue_writeback %p failed\n", inode); + iput(inode); } } @@ -1353,12 +1354,13 @@ static void ceph_writeback_work(struct work_struct *work) */ void ceph_queue_invalidate(struct inode *inode) { + ihold(inode); if (queue_work(ceph_inode_to_client(inode)->pg_inv_wq, &ceph_inode(inode)->i_pg_inv_work)) { dout("ceph_queue_invalidate %p\n", inode); - ihold(inode); } else { dout("ceph_queue_invalidate %p failed\n", inode); + iput(inode); } } @@ -1434,13 +1436,14 @@ void ceph_queue_vmtruncate(struct inode *inode) { struct ceph_inode_info *ci = ceph_inode(inode); + ihold(inode); if (queue_work(ceph_sb_to_client(inode->i_sb)->trunc_wq, &ci->i_vmtruncate_work)) { dout("ceph_queue_vmtruncate %p\n", inode); - ihold(inode); } else { dout("ceph_queue_vmtruncate %p failed, pending=%d\n", inode, ci->i_truncate_pending); + iput(inode); } } -- cgit v1.1 From 241fa6e42f5462a82f00ddf5169628a8c3976548 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 11 Oct 2011 11:54:26 -0300 Subject: [media] uvcvideo: GET_RES should only be checked for BITMAP type menu controls Currently it is also being checked for non BITMAP type menu controls, breaking the logitech LED control menu added by uvcdynctrl, as well as potentially breaking the powerline frequency menu. Signed-off-by: Hans de Goede Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_ctrl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index 10c2364..254d326 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c @@ -1016,7 +1016,8 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain, menu_info = &mapping->menu_info[query_menu->index]; - if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) { + if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK && + (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)) { s32 bitmap; if (!ctrl->cached) { @@ -1225,7 +1226,8 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, /* Valid menu indices are reported by the GET_RES request for * UVC controls that support it. */ - if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) { + if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK && + (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)) { if (!ctrl->cached) { ret = uvc_ctrl_populate_cache(chain, ctrl); if (ret < 0) -- cgit v1.1 From a9380ba11fc384a52bcee0884ca6dd069deb6b1b Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 31 Oct 2011 23:20:41 -0300 Subject: [media] mxl111sf: fix return value of mxl111sf_idac_config mxl111sf_idac_config was incorrectly returning val instead of ret Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/mxl111sf-phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-phy.c b/drivers/media/dvb/dvb-usb/mxl111sf-phy.c index 91dc1fc..ae8c2f8 100644 --- a/drivers/media/dvb/dvb-usb/mxl111sf-phy.c +++ b/drivers/media/dvb/dvb-usb/mxl111sf-phy.c @@ -332,7 +332,7 @@ int mxl111sf_idac_config(struct mxl111sf_state *state, ret = mxl111sf_write_reg(state, V6_IDAC_SETTINGS_REG, val); - return val; + return ret; } /* -- cgit v1.1 From 2f4133de28edafcaac3ce6b57faf8f40ed2ff1b9 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 31 Oct 2011 23:29:17 -0300 Subject: [media] mxl111sf: check for errors after mxl111sf_write_reg in mxl111sf_idac_config Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/mxl111sf-phy.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-phy.c b/drivers/media/dvb/dvb-usb/mxl111sf-phy.c index ae8c2f8..09787be 100644 --- a/drivers/media/dvb/dvb-usb/mxl111sf-phy.c +++ b/drivers/media/dvb/dvb-usb/mxl111sf-phy.c @@ -328,9 +328,11 @@ int mxl111sf_idac_config(struct mxl111sf_state *state, /* set hysteresis value reg: 0x0B<5:0> */ ret = mxl111sf_write_reg(state, V6_IDAC_HYSTERESIS_REG, (hysteresis_value & 0x3F)); + mxl_fail(ret); } ret = mxl111sf_write_reg(state, V6_IDAC_SETTINGS_REG, val); + mxl_fail(ret); return ret; } -- cgit v1.1 From cd834fa693160914029fee128f52e87a79d3e480 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 31 Oct 2011 23:31:04 -0300 Subject: [media] mxl111sf: remove pointless if condition in mxl111sf_config_spi Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/mxl111sf-phy.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-phy.c b/drivers/media/dvb/dvb-usb/mxl111sf-phy.c index 09787be..b741b3a 100644 --- a/drivers/media/dvb/dvb-usb/mxl111sf-phy.c +++ b/drivers/media/dvb/dvb-usb/mxl111sf-phy.c @@ -296,8 +296,7 @@ int mxl111sf_config_spi(struct mxl111sf_state *state, int onoff) goto fail; ret = mxl111sf_write_reg(state, 0x00, 0x00); - if (mxl_fail(ret)) - goto fail; + mxl_fail(ret); fail: return ret; } -- cgit v1.1 From e836a1c078e230dd5a94bb086b186c2be3ec6a84 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 31 Oct 2011 23:46:46 -0300 Subject: [media] mxl111sf: fix build warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix build warning: variable ‘ret’ set but not used in function ‘mxl111sf_i2c_readagain’ Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/mxl111sf-i2c.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-i2c.c b/drivers/media/dvb/dvb-usb/mxl111sf-i2c.c index 2e8c288..3443455 100644 --- a/drivers/media/dvb/dvb-usb/mxl111sf-i2c.c +++ b/drivers/media/dvb/dvb-usb/mxl111sf-i2c.c @@ -398,7 +398,6 @@ static int mxl111sf_i2c_readagain(struct mxl111sf_state *state, u8 i2c_r_data[24]; u8 i = 0; u8 fifo_status = 0; - int ret; int status = 0; mxl_i2c("read %d bytes", count); @@ -418,7 +417,7 @@ static int mxl111sf_i2c_readagain(struct mxl111sf_state *state, i2c_w_data[4+(i*3)] = 0x00; } - ret = mxl111sf_i2c_get_data(state, 0, i2c_w_data, i2c_r_data); + mxl111sf_i2c_get_data(state, 0, i2c_w_data, i2c_r_data); /* Check for I2C NACK status */ if (mxl111sf_i2c_check_status(state) == 1) { -- cgit v1.1 From eb513689c97e3e73bb9b4459d490a8e894b4a546 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 7 Nov 2011 10:47:42 -0500 Subject: ext4: ignore journalled data options on remount if fs has no journal This avoids a confusing failure in the init scripts when the /etc/fstab has data=writeback or data=journal but the file system does not have a journal. So check for this case explicitly, and warn the user that we are ignoring the (pointless, since they have no journal) data=* mount option. Signed-off-by: "Theodore Ts'o" --- fs/ext4/super.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 9953d80..0435013 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1683,7 +1683,9 @@ static int parse_options(char *options, struct super_block *sb, data_opt = EXT4_MOUNT_WRITEBACK_DATA; datacheck: if (is_remount) { - if (test_opt(sb, DATA_FLAGS) != data_opt) { + if (!sbi->s_journal) + ext4_msg(sb, KERN_WARNING, "Remounting file system with no journal so ignoring journalled data option"); + else if (test_opt(sb, DATA_FLAGS) != data_opt) { ext4_msg(sb, KERN_ERR, "Cannot change data mode on remount"); return 0; -- cgit v1.1 From 2397256d6218e7bf5147a3b01dcc6aec20fd3916 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 7 Nov 2011 10:50:09 -0500 Subject: ext4: Remove kernel_lock annotations The BKL is gone, these annotations are useless. Signed-off-by: Richard Weinberger Signed-off-by: "Theodore Ts'o" --- fs/ext4/super.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 0435013..3858767 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3101,8 +3101,6 @@ static void ext4_destroy_lazyinit_thread(void) } static int ext4_fill_super(struct super_block *sb, void *data, int silent) - __releases(kernel_lock) - __acquires(kernel_lock) { char *orig_data = kstrdup(data, GFP_KERNEL); struct buffer_head *bh; -- cgit v1.1 From 3c1fcb2c24519febd7ca9cf292fa5bdf513b601f Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Mon, 7 Nov 2011 11:01:13 -0500 Subject: ext4: add blk_finish_plug in error case of writepages. blk_finish_plug is needed in error case of writepages. Signed-off-by: Namjae Jeon Signed-off-by: "Theodore Ts'o" --- fs/ext4/inode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index cc5a6da..18b262b 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2270,6 +2270,7 @@ retry: ext4_msg(inode->i_sb, KERN_CRIT, "%s: jbd2_start: " "%ld pages, ino %lu; err %d", __func__, wbc->nr_to_write, inode->i_ino, ret); + blk_finish_plug(&plug); goto out_writepages; } -- cgit v1.1 From fdbd3ce9efb3a045266f2f6b2f1b6047882ff092 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 7 Nov 2011 07:53:23 -0800 Subject: PCI: pciehp: Retrieve link speed after link is trained During hot plug, board_added will call pciehp_power_on_slot(). But link speed is updated in pciehp_power_on_slot(). We should not update link speed there, because that is too early. So move the link speed update to pciehp_check_link_status() after making sure the link has been trained. -v2: fix compile warning that Kenji found. Signed-off-by: Yinghai Lu Reviewed-by: Kenji Kaneshige Tested-by: Kenji Kaneshige Signed-off-by: Jesse Barnes --- drivers/pci/hotplug/pciehp_hpc.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 96dc473..6692832 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -294,6 +294,8 @@ int pciehp_check_link_status(struct controller *ctrl) return retval; } + pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status); + return retval; } @@ -484,7 +486,6 @@ int pciehp_power_on_slot(struct slot * slot) u16 slot_cmd; u16 cmd_mask; u16 slot_status; - u16 lnk_status; int retval = 0; /* Clear sticky power-fault bit from previous power failures */ @@ -516,14 +517,6 @@ int pciehp_power_on_slot(struct slot * slot) ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); - retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); - if (retval) { - ctrl_err(ctrl, "%s: Cannot read LNKSTA register\n", - __func__); - return retval; - } - pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status); - return retval; } -- cgit v1.1 From 694718d8ad2f0b11d7376f8aa32b1befff6e5966 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 17 Oct 2011 16:59:25 +0200 Subject: b43: fill ctl1 word on all newer PHYs, fix PHY errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes PHY transmission errors reported on some LP-PHY and HT-PHY cards. For LP-PHY they were quite rare and not really noticable. On HT-PHY they were critical, OFDM rates were not available at all. Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/xmit.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index 58ea0e5..b62d4a1 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c @@ -175,6 +175,7 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp, } } +/* TODO: verify if needed for SSLPN or LCN */ static u16 b43_generate_tx_phy_ctl1(struct b43_wldev *dev, u8 bitrate) { const struct b43_phy *phy = &dev->phy; @@ -256,6 +257,9 @@ int b43_generate_txhdr(struct b43_wldev *dev, unsigned int plcp_fragment_len; u32 mac_ctl = 0; u16 phy_ctl = 0; + bool fill_phy_ctl1 = (phy->type == B43_PHYTYPE_LP || + phy->type == B43_PHYTYPE_N || + phy->type == B43_PHYTYPE_HT); u8 extra_ft = 0; struct ieee80211_rate *txrate; struct ieee80211_tx_rate *rates; @@ -531,7 +535,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, extra_ft |= B43_TXH_EFT_RTSFB_CCK; if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS && - phy->type == B43_PHYTYPE_N) { + fill_phy_ctl1) { txhdr->phy_ctl1_rts = cpu_to_le16( b43_generate_tx_phy_ctl1(dev, rts_rate)); txhdr->phy_ctl1_rts_fb = cpu_to_le16( @@ -552,7 +556,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, break; } - if (phy->type == B43_PHYTYPE_N) { + if (fill_phy_ctl1) { txhdr->phy_ctl1 = cpu_to_le16(b43_generate_tx_phy_ctl1(dev, rate)); txhdr->phy_ctl1_fb = -- cgit v1.1 From 73d51f38c736ae286372e90056a7f31519f555ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 17 Oct 2011 17:15:44 +0200 Subject: b43: HT-PHY: report signal to mac80211 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/xmit.c | 7 +++++++ drivers/net/wireless/b43/xmit.h | 16 +++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index b62d4a1..5f77cbe 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c @@ -740,7 +740,14 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) /* Link quality statistics */ switch (chanstat & B43_RX_CHAN_PHYTYPE) { + case B43_PHYTYPE_HT: + /* TODO: is max the right choice? */ + status.signal = max_t(__s8, + max(rxhdr->phy_ht_power0, rxhdr->phy_ht_power1), + rxhdr->phy_ht_power2); + break; case B43_PHYTYPE_N: + /* Broadcom has code for min and avg, but always uses max */ if (rxhdr->power0 == 16 || rxhdr->power0 == 32) status.signal = max(rxhdr->power1, rxhdr->power2); else diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h index 16c514d..98d9074 100644 --- a/drivers/net/wireless/b43/xmit.h +++ b/drivers/net/wireless/b43/xmit.h @@ -249,6 +249,12 @@ struct b43_rxhdr_fw4 { } __packed; } __packed; union { + /* HT-PHY */ + struct { + PAD_BYTES(1); + __s8 phy_ht_power0; + } __packed; + /* RSSI for N-PHYs */ struct { __s8 power2; @@ -257,7 +263,15 @@ struct b43_rxhdr_fw4 { __le16 phy_status2; /* PHY RX Status 2 */ } __packed; - __le16 phy_status3; /* PHY RX Status 3 */ + union { + /* HT-PHY */ + struct { + __s8 phy_ht_power1; + __s8 phy_ht_power2; + } __packed; + + __le16 phy_status3; /* PHY RX Status 3 */ + } __packed; union { /* Tested with 598.314, 644.1001 and 666.2 */ struct { -- cgit v1.1 From ae8e46723f803057daff392bdc93332be2f0ec98 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sat, 29 Oct 2011 11:30:15 +0200 Subject: brcm80211: smac: eliminate a null pointer dereference in dma.c Though it's unlikely, di may be null, so we can't dereference di->dma.dmactrlflags until we've checked it. Move this de-reference after the check, and adjust the error message to not require de-referencing di. This is based upon Julia's original patch: <1319846297-2985-2-git-send-email-julia@diku.dk> Reported-by: Julia Lawall Acked-by: Arend van Spriel Signed-off-by: Julian Calaby Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmsmac/dma.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c index b56a302..6ebec8f 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c @@ -358,13 +358,14 @@ static uint nrxdactive(struct dma_info *di, uint h, uint t) static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags) { - uint dmactrlflags = di->dma.dmactrlflags; + uint dmactrlflags; if (di == NULL) { - DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name)); + DMA_ERROR(("_dma_ctrlflags: NULL dma handle\n")); return 0; } + dmactrlflags = di->dma.dmactrlflags; dmactrlflags &= ~mask; dmactrlflags |= flags; -- cgit v1.1 From 3432f9233704a66e6067944339a311744243707d Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 30 Oct 2011 15:41:59 +0200 Subject: mac80211: use min rate as basic rate for buggy APs Some buggy APs (and even P2P_GO) don't advertise their basic rates in the association response. In such case, use the min supported rate as the basic rate. Reported-by: Pontus Fuchs Signed-off-by: Eliad Peller Signed-off-by: John W. Linville --- net/mac80211/mlme.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 17258fe..d3b408c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1485,6 +1485,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, int i, j, err; bool have_higher_than_11mbit = false; u16 ap_ht_cap_flags; + int min_rate = INT_MAX, min_rate_index = -1; /* AssocResp and ReassocResp have identical structure */ @@ -1551,6 +1552,10 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, rates |= BIT(j); if (is_basic) basic_rates |= BIT(j); + if (rate < min_rate) { + min_rate = rate; + min_rate_index = j; + } break; } } @@ -1568,11 +1573,25 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, rates |= BIT(j); if (is_basic) basic_rates |= BIT(j); + if (rate < min_rate) { + min_rate = rate; + min_rate_index = j; + } break; } } } + /* + * some buggy APs don't advertise basic_rates. use the lowest + * supported rate instead. + */ + if (unlikely(!basic_rates) && min_rate_index >= 0) { + printk(KERN_DEBUG "%s: No basic rates in AssocResp. " + "Using min supported rate instead.\n", sdata->name); + basic_rates = BIT(min_rate_index); + } + sta->sta.supp_rates[wk->chan->band] = rates; sdata->vif.bss_conf.basic_rates = basic_rates; -- cgit v1.1 From 6c7394197af90f6a332180e33f5d025d3037d883 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 3 Nov 2011 09:27:01 +0100 Subject: nl80211: fix HT capability attribute validation Since the NL80211_ATTR_HT_CAPABILITY attribute is used as a struct, it needs a minimum, not maximum length. Enforce that properly. Not doing so could potentially lead to reading after the buffer. Cc: stable@vger.kernel.org Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 48260c2..b587857 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -132,8 +132,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED }, [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG }, - [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY, - .len = NL80211_HT_CAPABILITY_LEN }, + [NL80211_ATTR_HT_CAPABILITY] = { .len = NL80211_HT_CAPABILITY_LEN }, [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 }, [NL80211_ATTR_IE] = { .type = NLA_BINARY, -- cgit v1.1 From 133a3ff2c934223a8143bfa52401bba962a97165 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 3 Nov 2011 14:50:13 +0100 Subject: cfg80211: allow setting TXQ parameters only in AP mode In other modes the parameters should not be set. Right now, mac80211 will set them, even if the user asked for setting them on VLANs which the driver doesn't know about, causing all kinds of trouble. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index b587857..b3a476f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1252,6 +1252,12 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) goto bad_res; } + if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && + netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { + result = -EINVAL; + goto bad_res; + } + nla_for_each_nested(nl_txq_params, info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], rem_txq_params) { -- cgit v1.1 From 3b6ef6334febb05d3050a96546e635f038dbcb15 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 4 Nov 2011 11:01:46 +0100 Subject: cfg80211: fix cmp_ies When comparing two items by IE, the sort order wasn't stable, which could lead to issues in the rbtree. Make it stable by making a missing IE sort before a present IE. Also sort by length first if it differs and then by contents. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/wireless/scan.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 0fb1424..dc23b31 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -259,17 +259,20 @@ static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2) { const u8 *ie1 = cfg80211_find_ie(num, ies1, len1); const u8 *ie2 = cfg80211_find_ie(num, ies2, len2); - int r; + /* equal if both missing */ if (!ie1 && !ie2) return 0; - if (!ie1 || !ie2) + /* sort missing IE before (left of) present IE */ + if (!ie1) return -1; + if (!ie2) + return 1; - r = memcmp(ie1 + 2, ie2 + 2, min(ie1[1], ie2[1])); - if (r == 0 && ie1[1] != ie2[1]) + /* sort by length first, then by contents */ + if (ie1[1] != ie2[1]) return ie2[1] - ie1[1]; - return r; + return memcmp(ie1 + 2, ie2 + 2, ie1[1]); } static bool is_bss(struct cfg80211_bss *a, -- cgit v1.1 From db652e4b36e5f1e5f49a4a49caf3aa365fe851c4 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 6 Nov 2011 22:58:31 +0100 Subject: net, wireless, mwifiex: Fix mem leak in mwifiex_update_curr_bss_params() If kmemdup() fails we leak the memory allocated to bss_desc. This patch fixes the leak. I also removed the pointless default assignment of 'NULL' to 'bss_desc' while I was there anyway. Signed-off-by: Jesper Juhl Reviewed-by: Srivatsa S. Bhat Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/scan.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index dae8dbb..8a3f959 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -1469,7 +1469,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid, s32 rssi, const u8 *ie_buf, size_t ie_len, u16 beacon_period, u16 cap_info_bitmap, u8 band) { - struct mwifiex_bssdescriptor *bss_desc = NULL; + struct mwifiex_bssdescriptor *bss_desc; int ret; unsigned long flags; u8 *beacon_ie; @@ -1484,6 +1484,7 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv, u8 *bssid, beacon_ie = kmemdup(ie_buf, ie_len, GFP_KERNEL); if (!beacon_ie) { + kfree(bss_desc); dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n"); return -ENOMEM; } -- cgit v1.1 From 24b9c373ab787ccacfa2c46736153708796f5cd6 Mon Sep 17 00:00:00 2001 From: "Janusz.Dziedzic@tieto.com" Date: Mon, 7 Nov 2011 09:47:47 +0200 Subject: mac80211: uAPSD - fix IEEE80211_FCTL_MOREDATA bit setting Set IEEE80211_FCTL_MOREDATA bit also in case we have buffered frames (more than one) only for one AC. Signed-off-by: Janusz Dziedzic Reviewed-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/sta_info.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index ce962d2..8eaa746 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -1354,12 +1354,12 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, * Use MoreData flag to indicate whether there are * more buffered frames for this STA */ - if (!more_data) - hdr->frame_control &= - cpu_to_le16(~IEEE80211_FCTL_MOREDATA); - else + if (more_data || !skb_queue_empty(&frames)) hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); + else + hdr->frame_control &= + cpu_to_le16(~IEEE80211_FCTL_MOREDATA); if (ieee80211_is_data_qos(hdr->frame_control) || ieee80211_is_qos_nullfunc(hdr->frame_control)) -- cgit v1.1 From 4dff523a913197e3314c7b0d08734ab037709093 Mon Sep 17 00:00:00 2001 From: Arek Lichwa Date: Wed, 26 Oct 2011 11:23:22 +0200 Subject: Bluetooth: Revert: Fix L2CAP connection establishment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 330605423ca6eafafb8dcc27502bce1c585d1b06. The commit introduces regression when two 2.1 devices attempt establish rfcomm channel. Such connection is refused since there's a security block issue on l2cap. It means the link is unencrypted. 2011-09-16 18:08:46.567616 < ACL data: handle 1 flags 0x00 dlen 24 0000: 14 00 40 00 06 00 02 00 0f 35 03 19 12 00 ff ff ..@......5....˙˙ 0010: 35 05 0a 00 00 ff ff 00 5....˙˙. 2011-09-16 18:08:46.572377 > HCI Event: Number of Completed Packets (0x13) plen 5 handle 1 packets 1 2011-09-16 18:08:46.577931 > ACL data: handle 1 flags 0x02 dlen 88 L2CAP(d): cid 0x0040 len 84 [psm 0] 0000: 07 00 02 00 4f 00 4c 35 4a 35 48 09 00 00 0a 00 ....O.L5J5H..... 0010: 01 00 00 09 00 01 35 03 19 12 00 09 00 05 35 03 ......5.......5. 0020: 19 10 02 09 00 09 35 08 35 06 19 12 00 09 01 02 ......5.5....... 0030: 09 02 00 09 01 02 09 02 01 09 00 0a 09 02 02 09 ................ 0040: 00 00 09 02 03 09 00 00 09 02 04 28 01 09 02 05 ...........(.... 0050: 09 00 02 00 .... 2011-09-16 18:08:46.626057 < HCI Command: Authentication Requested (0x01|0x0011) plen 2 handle 1 2011-09-16 18:08:46.627614 > HCI Event: Command Status (0x0f) plen 4 Authentication Requested (0x01|0x0011) status 0x00 ncmd 1 2011-09-16 18:08:46.627675 > HCI Event: Link Key Request (0x17) plen 6 bdaddr 00:00:F2:6A:29:69 2011-09-16 18:08:46.634999 < HCI Command: Link Key Request Reply (0x01|0x000b) plen 22 bdaddr 00:00:F2:6A:29:69 key 58CD393179FC902E5E8F512A855EE532 2011-09-16 18:08:46.683278 > HCI Event: Command Complete (0x0e) plen 10 Link Key Request Reply (0x01|0x000b) ncmd 1 status 0x00 bdaddr 00:00:F2:6A:29:69 2011-09-16 18:08:46.764729 > HCI Event: Auth Complete (0x06) plen 3 status 0x00 handle 1 2011-09-16 18:08:46.764821 < ACL data: handle 1 flags 0x00 dlen 12 0000: 08 00 01 00 02 05 04 00 03 00 41 00 ..........A. 2011-09-16 18:08:46.764851 > HCI Event: Command Status (0x0f) plen 4 Unknown (0x00|0x0000) status 0x00 ncmd 2 2011-09-16 18:08:46.768117 > HCI Event: Number of Completed Packets (0x13) plen 5 handle 1 packets 1 2011-09-16 18:08:46.770894 > ACL data: handle 1 flags 0x02 dlen 16 L2CAP(s): Connect rsp: dcid 0x0000 scid 0x0041 result 3 status 0 Connection refused - security block 2011-09-16 18:08:49.000691 < ACL data: handle 1 flags 0x00 dlen 12 0000: 08 00 01 00 06 06 04 00 40 00 40 00 ........@.@. 2011-09-16 18:08:49.015675 > HCI Event: Number of Completed Packets (0x13) plen 5 handle 1 packets 1 2011-09-16 18:08:49.016927 > ACL data: handle 1 flags 0x02 dlen 12 L2CAP(s): Disconn rsp: dcid 0x0040 scid 0x0040 2011-09-16 18:08:51.009480 < HCI Command: Disconnect (0x01|0x0006) plen 3 handle 1 reason 0x13 Reason: Remote User Terminated Connection 2011-09-16 18:08:51.011525 > HCI Event: Command Status (0x0f) plen 4 Disconnect (0x01|0x0006) status 0x00 ncmd 1 2011-09-16 18:08:51.123494 > HCI Event: Disconn Complete (0x05) plen 4 status 0x00 handle 1 reason 0x16 Reason: Connection Terminated by Local Host Signed-off-by: Arek Lichwa Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_conn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index c1c597e..e0af723 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -673,7 +673,7 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) goto encrypt; auth: - if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) + if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) return 0; if (!hci_conn_auth(conn, sec_level, auth_type)) -- cgit v1.1 From abf015f04614a3a7da43d35b55edc90189af4e6a Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 7 Nov 2011 19:04:36 +0000 Subject: Revert "ARM: 7098/1: kdump: copy kernel relocation code at the kexec prepare stage" This reverts commit 2b034922af2caa19df86f0c502e76cb6f6e910f9. Will Deacon reports: This is causing kexec to fail. The symptoms are that the .init.text section is not loaded as part of the new kernel image, so when we try to do the SMP/UP fixups we hit a whole sea of poison left there by the previous kernel. So my guess is that machine_kexec_prepare *is* too early for preparing the reboot_code_buffer and, unless anybody has a good reason not to, I'd like to revert the patch causing these problems. Reported-by: Will Deacon --- arch/arm/kernel/machine_kexec.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index c1b4463..e59bbd4 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c @@ -32,24 +32,6 @@ static atomic_t waiting_for_crash_ipi; int machine_kexec_prepare(struct kimage *image) { - unsigned long page_list; - void *reboot_code_buffer; - page_list = image->head & PAGE_MASK; - - reboot_code_buffer = page_address(image->control_code_page); - - /* Prepare parameters for reboot_code_buffer*/ - kexec_start_address = image->start; - kexec_indirection_page = page_list; - kexec_mach_type = machine_arch_type; - kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET; - - /* copy our kernel relocation code to the control code page */ - memcpy(reboot_code_buffer, - relocate_new_kernel, relocate_new_kernel_size); - - flush_icache_range((unsigned long) reboot_code_buffer, - (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE); return 0; } @@ -100,14 +82,31 @@ void (*kexec_reinit)(void); void machine_kexec(struct kimage *image) { + unsigned long page_list; unsigned long reboot_code_buffer_phys; void *reboot_code_buffer; + + page_list = image->head & PAGE_MASK; + /* we need both effective and real address here */ reboot_code_buffer_phys = page_to_pfn(image->control_code_page) << PAGE_SHIFT; reboot_code_buffer = page_address(image->control_code_page); + /* Prepare parameters for reboot_code_buffer*/ + kexec_start_address = image->start; + kexec_indirection_page = page_list; + kexec_mach_type = machine_arch_type; + kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET; + + /* copy our kernel relocation code to the control code page */ + memcpy(reboot_code_buffer, + relocate_new_kernel, relocate_new_kernel_size); + + + flush_icache_range((unsigned long) reboot_code_buffer, + (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE); printk(KERN_INFO "Bye!\n"); if (kexec_reinit) -- cgit v1.1 From f3f668b0ef4399b67e60e4c10a30099d630a6206 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 7 Nov 2011 17:19:04 -0200 Subject: Bluetooth: Use miliseconds for L2CAP channel timeouts Timers set by __set_chan_timer() should use miliseconds instead of jiffies. Commit 942ecc9c4643db5ce071562e0a23f99464d6b461 updated l2cap_set_timer() so it expects timeout to be specified in msecs instead of jiffies. This makes timeouts unreliable when CONFIG_HZ is not set to 1000. Signed-off-by: Andrzej Kaczmarek Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/l2cap.h | 7 +++++-- net/bluetooth/l2cap_core.c | 16 ++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index ab90ae0..6cc18f3 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -39,8 +39,11 @@ #define L2CAP_DEFAULT_ACK_TO 200 #define L2CAP_LE_DEFAULT_MTU 23 -#define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */ -#define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */ +#define L2CAP_DISC_TIMEOUT (100) +#define L2CAP_DISC_REJ_TIMEOUT (5000) /* 5 seconds */ +#define L2CAP_ENC_TIMEOUT (5000) /* 5 seconds */ +#define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */ +#define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */ /* L2CAP socket address */ struct sockaddr_l2 { diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 8cd1291..5ea94a1 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -251,7 +251,7 @@ static void l2cap_chan_timeout(unsigned long arg) if (sock_owned_by_user(sk)) { /* sk is owned by user. Try again later */ - __set_chan_timer(chan, HZ / 5); + __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); bh_unlock_sock(sk); chan_put(chan); return; @@ -2488,7 +2488,7 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd if (sock_owned_by_user(sk)) { l2cap_state_change(chan, BT_DISCONN); __clear_chan_timer(chan); - __set_chan_timer(chan, HZ / 5); + __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); break; } @@ -2661,7 +2661,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr default: sk->sk_err = ECONNRESET; - __set_chan_timer(chan, HZ * 5); + __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT); l2cap_send_disconn_req(conn, chan, ECONNRESET); goto done; } @@ -2718,7 +2718,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd if (sock_owned_by_user(sk)) { l2cap_state_change(chan, BT_DISCONN); __clear_chan_timer(chan); - __set_chan_timer(chan, HZ / 5); + __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); bh_unlock_sock(sk); return 0; } @@ -2752,7 +2752,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd if (sock_owned_by_user(sk)) { l2cap_state_change(chan,BT_DISCONN); __clear_chan_timer(chan); - __set_chan_timer(chan, HZ / 5); + __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); bh_unlock_sock(sk); return 0; } @@ -3998,7 +3998,7 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt) if (encrypt == 0x00) { if (chan->sec_level == BT_SECURITY_MEDIUM) { __clear_chan_timer(chan); - __set_chan_timer(chan, HZ * 5); + __set_chan_timer(chan, L2CAP_ENC_TIMEOUT); } else if (chan->sec_level == BT_SECURITY_HIGH) l2cap_chan_close(chan, ECONNREFUSED); } else { @@ -4066,7 +4066,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) L2CAP_CONN_REQ, sizeof(req), &req); } else { __clear_chan_timer(chan); - __set_chan_timer(chan, HZ / 10); + __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); } } else if (chan->state == BT_CONNECT2) { struct l2cap_conn_rsp rsp; @@ -4086,7 +4086,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) } } else { l2cap_state_change(chan, BT_DISCONN); - __set_chan_timer(chan, HZ / 10); + __set_chan_timer(chan, L2CAP_DISC_TIMEOUT); res = L2CAP_CR_SEC_BLOCK; stat = L2CAP_CS_NO_INFO; } -- cgit v1.1 From 45ea6095c8f0d6caad5658306416a5d254f1205e Mon Sep 17 00:00:00 2001 From: "slyich@gmail.com" Date: Mon, 7 Nov 2011 16:08:01 -0500 Subject: btrfs: fix double-free 'tree_root' in 'btrfs_mount()' On error path 'tree_root' is treed in 'free_fs_info()'. No need to free it explicitely. Noticed by SLUB in debug mode: Complete reproducer under usermode linux (discovered on real machine): bdev=/dev/ubda btr_root=/btr /mkfs.btrfs $bdev mount $bdev $btr_root mkdir $btr_root/subvols/ cd $btr_root/subvols/ /btrfs su cr foo /btrfs su cr bar mount $bdev -osubvol=subvols/foo $btr_root/subvols/bar umount $btr_root/subvols/bar which gives device fsid 4d55aa28-45b1-474b-b4ec-da912322195e devid 1 transid 7 /dev/ubda ============================================================================= BUG kmalloc-2048: Object already free ----------------------------------------------------------------------------- INFO: Allocated in btrfs_mount+0x389/0x7f0 age=0 cpu=0 pid=277 INFO: Freed in btrfs_mount+0x51c/0x7f0 age=0 cpu=0 pid=277 INFO: Slab 0x0000000062886200 objects=15 used=9 fp=0x0000000070b4d2d0 flags=0x4081 INFO: Object 0x0000000070b4d2d0 @offset=21200 fp=0x0000000070b4a968 ... Call Trace: 70b31948: [<6008c522>] print_trailer+0xe2/0x130 70b31978: [<6008c5aa>] object_err+0x3a/0x50 70b319a8: [<6008e242>] free_debug_processing+0x142/0x2a0 70b319e0: [<600ebf6f>] btrfs_mount+0x55f/0x7f0 70b319f8: [<6008e5c1>] __slab_free+0x221/0x2d0 Signed-off-by: Sergei Trofimovich Cc: Arne Jansen Cc: Chris Mason Cc: David Sterba Signed-off-by: Chris Mason --- fs/btrfs/super.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 57080df..dcd5aef 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -933,8 +933,12 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, * then open_ctree will properly initialize everything later. */ fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS); + if (!fs_info) { + error = -ENOMEM; + goto error_close_devices; + } tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS); - if (!fs_info || !tree_root) { + if (!tree_root) { error = -ENOMEM; goto error_close_devices; } @@ -964,7 +968,6 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, btrfs_close_devices(fs_devices); free_fs_info(fs_info); - kfree(tree_root); } else { char b[BDEVNAME_SIZE]; @@ -992,7 +995,6 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, error_close_devices: btrfs_close_devices(fs_devices); free_fs_info(fs_info); - kfree(tree_root); return ERR_PTR(error); } -- cgit v1.1 From a6f498a891c730327645a7afa10c5ae977de6fd8 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 7 Nov 2011 15:50:32 -0500 Subject: NFS: Fix a regression in the referral code Fix a regression that was introduced by commit 0c2e53f11a6dae9e3af5f50f5ad0382e7c3e0cfa (NFS: Remove the unused "lookupfh()" version of nfs4_proc_lookup()). In the case where the lookup gets an NFS4ERR_MOVED, we want to return the result of nfs4_get_referral(). Instead, that value is getting clobbered by the call to nfs4_handle_exception()... Reported-by: Tigran Mkrtchyan Tested-by: Tigran Mkrtchyan Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 069cb80..be2bbac 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2464,8 +2464,7 @@ static int nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, struct qst case -NFS4ERR_BADNAME: return -ENOENT; case -NFS4ERR_MOVED: - err = nfs4_get_referral(dir, name, fattr, fhandle); - break; + return nfs4_get_referral(dir, name, fattr, fhandle); case -NFS4ERR_WRONGSEC: nfs_fixup_secinfo_attributes(fattr, fhandle); } -- cgit v1.1 From a6f05b97d1ba87326bd96f3da9fef994830d6994 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 6 Nov 2011 21:54:12 +0100 Subject: PM / QoS: Set cpu_dma_pm_qos->name Since commit 4a31a334, the name of this misc device is not initialized, which leads to a funny device named /dev/(null) being created and /proc/misc containing an entry with just a number but no name. The latter leads to complaints by cryptsetup, which caused me to investigate this matter. Signed-off-by: Dominik Brodowski Signed-off-by: Rafael J. Wysocki --- kernel/power/qos.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/power/qos.c b/kernel/power/qos.c index 56db751..995e3bd 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c @@ -70,6 +70,7 @@ static struct pm_qos_constraints cpu_dma_constraints = { }; static struct pm_qos_object cpu_dma_pm_qos = { .constraints = &cpu_dma_constraints, + .name = "cpu_dma_latency", }; static BLOCKING_NOTIFIER_HEAD(network_lat_notifier); -- cgit v1.1 From 5f11161675be1351cadb96c83850e20bf5bcdc48 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 6 Nov 2011 22:00:20 +0100 Subject: Documentation: Fix typo in freezer-subsystem.txt Fix a typo in Documentation/cgroups/freezer-subsystem.txt. Signed-off-by: Rafael J. Wysocki Reviewed-by: Srivatsa S. Bhat Acked-by: Randy Dunlap --- Documentation/cgroups/freezer-subsystem.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/cgroups/freezer-subsystem.txt b/Documentation/cgroups/freezer-subsystem.txt index c21d777..7e62de1 100644 --- a/Documentation/cgroups/freezer-subsystem.txt +++ b/Documentation/cgroups/freezer-subsystem.txt @@ -33,9 +33,9 @@ demonstrate this problem using nested bash shells: From a second, unrelated bash shell: $ kill -SIGSTOP 16690 - $ kill -SIGCONT 16990 + $ kill -SIGCONT 16690 - + This happens because bash can observe both signals and choose how it responds to them. -- cgit v1.1 From 1a51cfdc4516a6e1f2c1f8a579630a027c30331a Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Mon, 7 Nov 2011 23:54:53 +0100 Subject: PM / devfreq: fix private_data The "private_date" field in struct devfreq_dev_status almost certainly wants to be "private_data"; since there are no in-tree users of this functionality, now seems like an easy time to make the fix. Signed-off-by: Jonathan Corbet Signed-off-by: Rafael J. Wysocki --- include/linux/devfreq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index afb9458..98ce812 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -41,7 +41,7 @@ struct devfreq_dev_status { unsigned long total_time; unsigned long busy_time; unsigned long current_frequency; - void *private_date; + void *private_data; }; /** -- cgit v1.1 From 5698eb4eda657fd4a74612a65cd5d583f35a5bdb Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 7 Nov 2011 15:58:40 -0800 Subject: ARM: OMAP3: CPUidle: include The CPUidle use THIS_MODULE, so needs Signed-off-by: Kevin Hilman Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/cpuidle34xx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index 4bf6e6e..2e0fa5a 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -24,6 +24,7 @@ #include #include +#include #include #include -- cgit v1.1 From 4e549d6d4a32d1a610ad081841d575f64087744a Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Sun, 6 Nov 2011 12:57:31 +0100 Subject: MTD: MAPS: bcm963xx-flash.c: explicitly include module.h module.h was previously implicitly included through mtd/mtd.h. Fixes the following build failure after the module.h cleanup: CC drivers/mtd/maps/bcm963xx-flash.o drivers/mtd/maps/bcm963xx-flash.c: In function 'bcm963xx_probe': drivers/mtd/maps/bcm963xx-flash.c:208:29: error: 'THIS_MODULE' undeclared (first use in this function) [...] drivers/mtd/maps/bcm963xx-flash.c:276:1: warning: type defaults to 'int' in declaration of 'MODULE_AUTHOR' drivers/mtd/maps/bcm963xx-flash.c:276:15: warning: function declaration isn't a prototype make[7]: *** [drivers/mtd/maps/bcm963xx-flash.o] Error 1 Signed-off-by: Jonas Gorski Signed-off-by: Paul Gortmaker --- drivers/mtd/maps/bcm963xx-flash.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/maps/bcm963xx-flash.c b/drivers/mtd/maps/bcm963xx-flash.c index 608967f..736ca10 100644 --- a/drivers/mtd/maps/bcm963xx-flash.c +++ b/drivers/mtd/maps/bcm963xx-flash.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include -- cgit v1.1 From 8f7346bdea64f2e3d02b0bcaf456e391c4cba134 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 6 Nov 2011 21:16:51 +0800 Subject: hwspinlock/u8500: include linux/module.h Include module.h to fix below build error: CC drivers/hwspinlock/u8500_hsem.o drivers/hwspinlock/u8500_hsem.c:177: error: 'THIS_MODULE' undeclared here (not in a function) [...] drivers/hwspinlock/u8500_hsem.c:196: warning: type defaults to 'int' in declaration of 'MODULE_AUTHOR' drivers/hwspinlock/u8500_hsem.c:196: warning: function declaration isn't a prototype make[2]: *** [drivers/hwspinlock/u8500_hsem.o] Error 1 make[1]: *** [drivers/hwspinlock] Error 2 make: *** [drivers] Error 2 Signed-off-by: Axel Lin Signed-off-by: Paul Gortmaker --- drivers/hwspinlock/u8500_hsem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hwspinlock/u8500_hsem.c b/drivers/hwspinlock/u8500_hsem.c index 143461a..0156af5 100644 --- a/drivers/hwspinlock/u8500_hsem.c +++ b/drivers/hwspinlock/u8500_hsem.c @@ -21,6 +21,7 @@ * General Public License for more details. */ +#include #include #include #include -- cgit v1.1 From 3b8ce3aed986090d9249629f97c53b4dfb8c9783 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Mon, 7 Nov 2011 11:17:04 -0500 Subject: mfd: fix build failures in recently added ab5500 code These files had implicit dependencies on modular support which now show up as build failures with the module cleanup work merged to mainline. Reported-by: Axel Lin Signed-off-by: Paul Gortmaker --- drivers/mfd/ab5500-core.c | 1 + drivers/mfd/ab5500-debugfs.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/mfd/ab5500-core.c b/drivers/mfd/ab5500-core.c index 4175544..ec10629 100644 --- a/drivers/mfd/ab5500-core.c +++ b/drivers/mfd/ab5500-core.c @@ -13,6 +13,7 @@ * TODO: Event handling with irq_chip. Waiting for PRCMU fw support. */ +#include #include #include #include diff --git a/drivers/mfd/ab5500-debugfs.c b/drivers/mfd/ab5500-debugfs.c index 6be1fe6..43c0ebb 100644 --- a/drivers/mfd/ab5500-debugfs.c +++ b/drivers/mfd/ab5500-debugfs.c @@ -4,6 +4,7 @@ * Debugfs support for the AB5500 MFD driver */ +#include #include #include #include -- cgit v1.1 From 406478dc911e16677fbd9c84d1d50cdffbc031ab Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 7 Nov 2011 16:07:04 -0800 Subject: drm/i915: Turn on a required 3D clock gating bit on Sandybridge. Fixes rendering failures in Unigine Tropics and Sanctuary and the mesa "fire" demo. Signed-off-by: Eric Anholt Cc: stable@kernel.org Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/i915_reg.h | 3 +++ drivers/gpu/drm/i915/intel_display.c | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5a09416..b807275 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3444,6 +3444,9 @@ #define GT_FIFO_FREE_ENTRIES 0x120008 #define GT_FIFO_NUM_RESERVED_ENTRIES 20 +#define GEN6_UCGCTL2 0x9404 +# define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12) + #define GEN6_RPNSWREQ 0xA008 #define GEN6_TURBO_DISABLE (1<<31) #define GEN6_FREQUENCY(x) ((x)<<25) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9fa342e..2b2a764 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8148,6 +8148,15 @@ static void gen6_init_clock_gating(struct drm_device *dev) I915_WRITE(WM2_LP_ILK, 0); I915_WRITE(WM1_LP_ILK, 0); + /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock + * gating disable must be set. Failure to set it results in + * flickering pixels due to Z write ordering failures after + * some amount of runtime in the Mesa "fire" demo, and Unigine + * Sanctuary and Tropics, and apparently anything else with + * alpha test or pixel discard. + */ + I915_WRITE(GEN6_UCGCTL2, GEN6_RCPBUNIT_CLOCK_GATE_DISABLE); + /* * According to the spec the following bits should be * set in order to enable memory self-refresh and fbc: -- cgit v1.1 From 9ca1d10d748e56964de95e3ed80211b192f56cf4 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 7 Nov 2011 16:07:05 -0800 Subject: drm/i915: Turn on another required clock gating bit on gen6. Unlike the previous one, I don't have known testcases it fixes. I'd rather not go through the same debug cycle on whatever testcases those might be. Signed-off-by: Eric Anholt Cc: stable@kernel.org Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_display.c | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b807275..a34e866 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3446,6 +3446,7 @@ #define GEN6_UCGCTL2 0x9404 # define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12) +# define GEN6_RCCUNIT_CLOCK_GATE_DISABLE (1 << 11) #define GEN6_RPNSWREQ 0xA008 #define GEN6_TURBO_DISABLE (1<<31) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2b2a764..591eb0ed 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8154,8 +8154,13 @@ static void gen6_init_clock_gating(struct drm_device *dev) * some amount of runtime in the Mesa "fire" demo, and Unigine * Sanctuary and Tropics, and apparently anything else with * alpha test or pixel discard. + * + * According to the spec, bit 11 (RCCUNIT) must also be set, + * but we didn't debug actual testcases to find it out. */ - I915_WRITE(GEN6_UCGCTL2, GEN6_RCPBUNIT_CLOCK_GATE_DISABLE); + I915_WRITE(GEN6_UCGCTL2, + GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | + GEN6_RCCUNIT_CLOCK_GATE_DISABLE); /* * According to the spec the following bits should be -- cgit v1.1 From ad61d64e263228a418fe25809a23d5107cf778a0 Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Mon, 7 Nov 2011 13:36:56 +0000 Subject: powerpc/kvm: Fix build with older toolchains Fix KVM build for older toolchains (found with .powerpc64-unknown-linux-gnu-gcc (crosstool-NG-1.8.1) 4.3.2): AS arch/powerpc/kvm/book3s_hv_rmhandlers.o arch/powerpc/kvm/book3s_hv_rmhandlers.S: Assembler messages: arch/powerpc/kvm/book3s_hv_rmhandlers.S:1388: Error: Unrecognized opcode: `popcntw' make[1]: *** [arch/powerpc/kvm/book3s_hv_rmhandlers.o] Error 1 make: *** [_module_arch/powerpc/kvm] Error 2 Signed-off-by: Nishanth Aravamudan Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kvm/book3s_hv_rmhandlers.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index f422231..44d8829 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -1263,7 +1263,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206) addi r6,r5,VCORE_NAPPING_THREADS 31: lwarx r4,0,r6 or r4,r4,r0 - popcntw r7,r4 + PPC_POPCNTW(r7,r4) cmpw r7,r8 bge 2f stwcx. r4,0,r6 -- cgit v1.1 From 88cf11b4cca8ee0044d0a10ce100d8c0012b2c5e Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Mon, 7 Nov 2011 14:49:13 +0000 Subject: powerpc: Add KVM as module to defconfigs Add HV mode KVM to Book3 server 64bit defconfigs as a module. Doesn't add much to the size: text data bss dec hex filename 8244109 4686767 994000 13924876 d47a0c vmlinux.vanilla 8256092 4691607 994128 13941827 d4bc43 vmlinux.kvm This should enable more testing of this configuration. Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/configs/ppc64_defconfig | 4 ++++ arch/powerpc/configs/pseries_defconfig | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index 84a685a5..535711f 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -485,3 +485,7 @@ CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set +CONFIG_VIRTUALIZATION=y +CONFIG_KVM_BOOK3S_64=m +CONFIG_KVM_BOOK3S_64_HV=y +CONFIG_VHOST_NET=m diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index 96a58b7..a72f241 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig @@ -362,3 +362,7 @@ CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_LZO=m # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set +CONFIG_VIRTUALIZATION=y +CONFIG_KVM_BOOK3S_64=m +CONFIG_KVM_BOOK3S_64_HV=y +CONFIG_VHOST_NET=m -- cgit v1.1 From c40dd2f76644016ca7677545fc846ec2470d70a1 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 2 Nov 2011 14:56:12 +0000 Subject: powerpc: Add System RAM to /proc/iomem We've resisted adding System RAM to /proc/iomem because it is the wrong place for it. Unfortunately we continue to find tools that rely on this behaviour so give up and add it in. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/mem.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 16da595..2dd6bdd 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -555,3 +556,32 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, book3e_hugetlb_preload(vma->vm_mm, address, *ptep); #endif } + +/* + * System memory should not be in /proc/iomem but various tools expect it + * (eg kdump). + */ +static int add_system_ram_resources(void) +{ + struct memblock_region *reg; + + for_each_memblock(memory, reg) { + struct resource *res; + unsigned long base = reg->base; + unsigned long size = reg->size; + + res = kzalloc(sizeof(struct resource), GFP_KERNEL); + WARN_ON(!res); + + if (res) { + res->name = "System RAM"; + res->start = base; + res->end = base + size - 1; + res->flags = IORESOURCE_MEM; + WARN_ON(request_resource(&iomem_resource, res) < 0); + } + } + + return 0; +} +subsys_initcall(add_system_ram_resources); -- cgit v1.1 From 1c8ee73395af762726e9eb628636d3b763618c60 Mon Sep 17 00:00:00 2001 From: Dipankar Sarma Date: Fri, 28 Oct 2011 04:25:32 +0000 Subject: powerpc/numa: NUMA topology support for PowerNV This patch adds support for numa topology on powernv platforms running OPAL formware. It checks for the type of platform at run time and sets the affinity form correctly so that NUMA topology can be discovered correctly. Signed-off-by: Dipankar Sarma Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/numa.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index c7dd4de..b22a83a 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -315,7 +315,10 @@ static int __init find_min_common_depth(void) struct device_node *root; const char *vec5; - root = of_find_node_by_path("/rtas"); + if (firmware_has_feature(FW_FEATURE_OPAL)) + root = of_find_node_by_path("/ibm,opal"); + else + root = of_find_node_by_path("/rtas"); if (!root) root = of_find_node_by_path("/"); @@ -344,12 +347,19 @@ static int __init find_min_common_depth(void) #define VEC5_AFFINITY_BYTE 5 #define VEC5_AFFINITY 0x80 - chosen = of_find_node_by_path("/chosen"); - if (chosen) { - vec5 = of_get_property(chosen, "ibm,architecture-vec-5", NULL); - if (vec5 && (vec5[VEC5_AFFINITY_BYTE] & VEC5_AFFINITY)) { - dbg("Using form 1 affinity\n"); - form1_affinity = 1; + + if (firmware_has_feature(FW_FEATURE_OPAL)) + form1_affinity = 1; + else { + chosen = of_find_node_by_path("/chosen"); + if (chosen) { + vec5 = of_get_property(chosen, + "ibm,architecture-vec-5", NULL); + if (vec5 && (vec5[VEC5_AFFINITY_BYTE] & + VEC5_AFFINITY)) { + dbg("Using form 1 affinity\n"); + form1_affinity = 1; + } } } -- cgit v1.1 From a3a9f3b47d12b5f6dfc9c7ed9d7b193d77812195 Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Fri, 21 Oct 2011 23:56:27 +0000 Subject: powerpc/irq: Remove IRQF_DISABLED Since commit [e58aa3d2: genirq: Run irq handlers with interrupts disabled], We run all interrupt handlers with interrupts disabled and we even check and yell when an interrupt handler returns with interrupts enabled (see commit [b738a50a: genirq: Warn when handler enables interrupts]). So now this flag is a NOOP and can be removed. Signed-off-by: Yong Zhang Acked-by: Arnd Bergmann Acked-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/floppy.h | 4 ++-- arch/powerpc/include/asm/xics.h | 4 ++-- arch/powerpc/kernel/smp.c | 2 +- arch/powerpc/platforms/cell/beat.c | 2 +- arch/powerpc/platforms/cell/celleb_scc_pciex.c | 2 +- arch/powerpc/platforms/cell/iommu.c | 3 +-- arch/powerpc/platforms/cell/pmu.c | 2 +- arch/powerpc/platforms/cell/spu_base.c | 9 +++------ arch/powerpc/platforms/powermac/pic.c | 1 - arch/powerpc/platforms/powermac/smp.c | 4 ++-- arch/powerpc/platforms/ps3/device-init.c | 2 +- arch/powerpc/sysdev/mpic.c | 2 -- arch/powerpc/sysdev/ppc4xx_soc.c | 2 +- arch/powerpc/sysdev/xics/xics-common.c | 5 ++--- 14 files changed, 18 insertions(+), 26 deletions(-) diff --git a/arch/powerpc/include/asm/floppy.h b/arch/powerpc/include/asm/floppy.h index 24bd34c..936a904 100644 --- a/arch/powerpc/include/asm/floppy.h +++ b/arch/powerpc/include/asm/floppy.h @@ -108,10 +108,10 @@ static int fd_request_irq(void) { if (can_use_virtual_dma) return request_irq(FLOPPY_IRQ, floppy_hardint, - IRQF_DISABLED, "floppy", NULL); + 0, "floppy", NULL); else return request_irq(FLOPPY_IRQ, floppy_interrupt, - IRQF_DISABLED, "floppy", NULL); + 0, "floppy", NULL); } static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io) diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h index bd6c401..c48de98 100644 --- a/arch/powerpc/include/asm/xics.h +++ b/arch/powerpc/include/asm/xics.h @@ -15,8 +15,8 @@ #define DEFAULT_PRIORITY 5 /* - * Mark IPIs as higher priority so we can take them inside interrupts that - * arent marked IRQF_DISABLED + * Mark IPIs as higher priority so we can take them inside interrupts + * FIXME: still true now? */ #define IPI_PRIORITY 4 diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 25ddbfc..6df7090 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -187,7 +187,7 @@ int smp_request_message_ipi(int virq, int msg) return 1; } #endif - err = request_irq(virq, smp_ipi_action[msg], IRQF_DISABLED|IRQF_PERCPU, + err = request_irq(virq, smp_ipi_action[msg], IRQF_PERCPU, smp_ipi_name[msg], 0); WARN(err < 0, "unable to request_irq %d for %s (rc %d)\n", virq, smp_ipi_name[msg], err); diff --git a/arch/powerpc/platforms/cell/beat.c b/arch/powerpc/platforms/cell/beat.c index 232fc38..852592b 100644 --- a/arch/powerpc/platforms/cell/beat.c +++ b/arch/powerpc/platforms/cell/beat.c @@ -230,7 +230,7 @@ static int __init beat_register_event(void) } ev->virq = virq; - rc = request_irq(virq, ev->handler, IRQF_DISABLED, + rc = request_irq(virq, ev->handler, 0, ev->typecode, NULL); if (rc != 0) { printk(KERN_ERR "Beat: failed to request virtual IRQ" diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c index ae790ac..14be2bd 100644 --- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c +++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c @@ -514,7 +514,7 @@ static __init int celleb_setup_pciex(struct device_node *node, virq = irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size); if (request_irq(virq, pciex_handle_internal_irq, - IRQF_DISABLED, "pciex", (void *)phb)) { + 0, "pciex", (void *)phb)) { pr_err("PCIEXC:Failed to request irq\n"); goto error; } diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index fc46fca..592c3d5 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -412,8 +412,7 @@ static void cell_iommu_enable_hardware(struct cbe_iommu *iommu) IIC_IRQ_IOEX_ATI | (iommu->nid << IIC_IRQ_NODE_SHIFT)); BUG_ON(virq == NO_IRQ); - ret = request_irq(virq, ioc_interrupt, IRQF_DISABLED, - iommu->name, iommu); + ret = request_irq(virq, ioc_interrupt, 0, iommu->name, iommu); BUG_ON(ret); /* set the IOC segment table origin register (and turn on the iommu) */ diff --git a/arch/powerpc/platforms/cell/pmu.c b/arch/powerpc/platforms/cell/pmu.c index 1acf360..59c1a16 100644 --- a/arch/powerpc/platforms/cell/pmu.c +++ b/arch/powerpc/platforms/cell/pmu.c @@ -392,7 +392,7 @@ static int __init cbe_init_pm_irq(void) } rc = request_irq(irq, cbe_pm_irq, - IRQF_DISABLED, "cbe-pmu-0", NULL); + 0, "cbe-pmu-0", NULL); if (rc) { printk("ERROR: Request for irq on node %d failed\n", node); diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 3675da7..e94d3ec 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -442,8 +442,7 @@ static int spu_request_irqs(struct spu *spu) snprintf(spu->irq_c0, sizeof (spu->irq_c0), "spe%02d.0", spu->number); ret = request_irq(spu->irqs[0], spu_irq_class_0, - IRQF_DISABLED, - spu->irq_c0, spu); + 0, spu->irq_c0, spu); if (ret) goto bail0; } @@ -451,8 +450,7 @@ static int spu_request_irqs(struct spu *spu) snprintf(spu->irq_c1, sizeof (spu->irq_c1), "spe%02d.1", spu->number); ret = request_irq(spu->irqs[1], spu_irq_class_1, - IRQF_DISABLED, - spu->irq_c1, spu); + 0, spu->irq_c1, spu); if (ret) goto bail1; } @@ -460,8 +458,7 @@ static int spu_request_irqs(struct spu *spu) snprintf(spu->irq_c2, sizeof (spu->irq_c2), "spe%02d.2", spu->number); ret = request_irq(spu->irqs[2], spu_irq_class_2, - IRQF_DISABLED, - spu->irq_c2, spu); + 0, spu->irq_c2, spu); if (ret) goto bail2; } diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index cb40e92..901bfbd 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -272,7 +272,6 @@ static struct irqaction xmon_action = { static struct irqaction gatwick_cascade_action = { .handler = gatwick_action, - .flags = IRQF_DISABLED, .name = "cascade", }; diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index 9a521dc..9b6a820 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c @@ -200,7 +200,7 @@ static int psurge_secondary_ipi_init(void) if (psurge_secondary_virq) rc = request_irq(psurge_secondary_virq, psurge_ipi_intr, - IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL); + IRQF_PERCPU, "IPI", NULL); if (rc) pr_err("Failed to setup secondary cpu IPI\n"); @@ -408,7 +408,7 @@ static int __init smp_psurge_kick_cpu(int nr) static struct irqaction psurge_irqaction = { .handler = psurge_ipi_intr, - .flags = IRQF_DISABLED|IRQF_PERCPU, + .flags = IRQF_PERCPU, .name = "primary IPI", }; diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c index 6c4b583..3f175e8 100644 --- a/arch/powerpc/platforms/ps3/device-init.c +++ b/arch/powerpc/platforms/ps3/device-init.c @@ -825,7 +825,7 @@ static int ps3_probe_thread(void *data) spin_lock_init(&dev.lock); - res = request_irq(irq, ps3_notification_interrupt, IRQF_DISABLED, + res = request_irq(irq, ps3_notification_interrupt, 0, "ps3_notification", &dev); if (res) { pr_err("%s:%u: request_irq failed %d\n", __func__, __LINE__, diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 0842c6f..8c7e852 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -800,8 +800,6 @@ static void mpic_end_ipi(struct irq_data *d) * IPIs are marked IRQ_PER_CPU. This has the side effect of * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from * applying to them. We EOI them late to avoid re-entering. - * We mark IPI's with IRQF_DISABLED as they must run with - * irqs disabled. */ mpic_eoi(mpic); } diff --git a/arch/powerpc/sysdev/ppc4xx_soc.c b/arch/powerpc/sysdev/ppc4xx_soc.c index d3d6ce3..0debcc3 100644 --- a/arch/powerpc/sysdev/ppc4xx_soc.c +++ b/arch/powerpc/sysdev/ppc4xx_soc.c @@ -115,7 +115,7 @@ static int __init ppc4xx_l2c_probe(void) } /* Install error handler */ - if (request_irq(irq, l2c_error_handler, IRQF_DISABLED, "L2C", 0) < 0) { + if (request_irq(irq, l2c_error_handler, 0, "L2C", 0) < 0) { printk(KERN_ERR "Cannot install L2C error handler" ", cache is not enabled\n"); of_node_put(np); diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c index 3d93a8d..63762c6 100644 --- a/arch/powerpc/sysdev/xics/xics-common.c +++ b/arch/powerpc/sysdev/xics/xics-common.c @@ -134,11 +134,10 @@ static void xics_request_ipi(void) BUG_ON(ipi == NO_IRQ); /* - * IPIs are marked IRQF_DISABLED as they must run with irqs - * disabled, and PERCPU. The handler was set in map. + * IPIs are marked IRQF_PERCPU. The handler was set in map. */ BUG_ON(request_irq(ipi, icp_ops->ipi_action, - IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL)); + IRQF_PERCPU, "IPI", NULL)); } int __init xics_smp_probe(void) -- cgit v1.1 From 6ea741a13690da9dbbac76175db8e313b0c4b817 Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Fri, 21 Oct 2011 23:56:53 +0000 Subject: powerpc/ps3: irq: Remove IRQF_DISABLED Since commit [e58aa3d2: genirq: Run irq handlers with interrupts disabled], We run all interrupt handlers with interrupts disabled and we even check and yell when an interrupt handler returns with interrupts enabled (see commit [b738a50a: genirq: Warn when handler enables interrupts]). So now this flag is a NOOP and can be removed. Signed-off-by: Yong Zhang Acked-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt --- drivers/ps3/ps3-vuart.c | 2 +- drivers/ps3/ps3stor_lib.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ps3/ps3-vuart.c b/drivers/ps3/ps3-vuart.c index d9fb729..fb73008 100644 --- a/drivers/ps3/ps3-vuart.c +++ b/drivers/ps3/ps3-vuart.c @@ -952,7 +952,7 @@ static int ps3_vuart_bus_interrupt_get(void) } result = request_irq(vuart_bus_priv.virq, ps3_vuart_irq_handler, - IRQF_DISABLED, "vuart", &vuart_bus_priv); + 0, "vuart", &vuart_bus_priv); if (result) { pr_debug("%s:%d: request_irq failed (%d)\n", diff --git a/drivers/ps3/ps3stor_lib.c b/drivers/ps3/ps3stor_lib.c index cc328dec..8c3f5ad 100644 --- a/drivers/ps3/ps3stor_lib.c +++ b/drivers/ps3/ps3stor_lib.c @@ -167,7 +167,7 @@ int ps3stor_setup(struct ps3_storage_device *dev, irq_handler_t handler) goto fail_close_device; } - error = request_irq(dev->irq, handler, IRQF_DISABLED, + error = request_irq(dev->irq, handler, 0, dev->sbd.core.driver->name, dev); if (error) { dev_err(&dev->sbd.core, "%s:%u: request_irq failed %d\n", -- cgit v1.1 From 5233e26ebb90242e3691c185ddda02dc83649e7d Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Wed, 12 Oct 2011 08:39:15 +0000 Subject: powerpc/ps3: Fix PS3 repository build warnings Fix uninitialized variable warnings in build of repository.c Signed-off-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/ps3/repository.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c index 5e304c2..ca40f6a 100644 --- a/arch/powerpc/platforms/ps3/repository.c +++ b/arch/powerpc/platforms/ps3/repository.c @@ -184,7 +184,7 @@ int ps3_repository_read_bus_type(unsigned int bus_index, enum ps3_bus_type *bus_type) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index), @@ -199,7 +199,7 @@ int ps3_repository_read_bus_num_dev(unsigned int bus_index, unsigned int *num_dev) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index), @@ -239,7 +239,7 @@ int ps3_repository_read_dev_type(unsigned int bus_index, unsigned int dev_index, enum ps3_dev_type *dev_type) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index), @@ -256,8 +256,8 @@ int ps3_repository_read_dev_intr(unsigned int bus_index, enum ps3_interrupt_type *intr_type, unsigned int *interrupt_id) { int result; - u64 v1; - u64 v2; + u64 v1 = 0; + u64 v2 = 0; result = read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index), @@ -275,7 +275,7 @@ int ps3_repository_read_dev_reg_type(unsigned int bus_index, enum ps3_reg_type *reg_type) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index), @@ -615,7 +615,7 @@ int ps3_repository_read_stor_dev_num_regions(unsigned int bus_index, unsigned int dev_index, unsigned int *num_regions) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index), @@ -631,7 +631,7 @@ int ps3_repository_read_stor_dev_region_id(unsigned int bus_index, unsigned int *region_id) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index), @@ -786,7 +786,7 @@ int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size, u64 *region_total) int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_CURRENT, make_first_field("bi", 0), @@ -805,7 +805,7 @@ int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved) int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_CURRENT, make_first_field("bi", 0), @@ -827,8 +827,8 @@ int ps3_repository_read_spu_resource_id(unsigned int res_index, enum ps3_spu_resource_type *resource_type, unsigned int *resource_id) { int result; - u64 v1; - u64 v2; + u64 v1 = 0; + u64 v2 = 0; result = read_node(PS3_LPAR_ID_CURRENT, make_first_field("bi", 0), @@ -854,7 +854,7 @@ static int ps3_repository_read_boot_dat_address(u64 *address) int ps3_repository_read_boot_dat_size(unsigned int *size) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_CURRENT, make_first_field("bi", 0), @@ -869,7 +869,7 @@ int ps3_repository_read_boot_dat_size(unsigned int *size) int ps3_repository_read_vuart_av_port(unsigned int *port) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_CURRENT, make_first_field("bi", 0), @@ -884,7 +884,7 @@ int ps3_repository_read_vuart_av_port(unsigned int *port) int ps3_repository_read_vuart_sysmgr_port(unsigned int *port) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_CURRENT, make_first_field("bi", 0), @@ -919,7 +919,7 @@ int ps3_repository_read_boot_dat_info(u64 *lpar_addr, unsigned int *size) int ps3_repository_read_num_be(unsigned int *num_be) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_PME, make_first_field("ben", 0), -- cgit v1.1 From 9fce85f7ff94f1a877c15ad3d6ffbaed4b5cd1a6 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Wed, 12 Oct 2011 08:42:13 +0000 Subject: powerpc/ps3: Fix lv1_gpu_attribute hcall The lv1_gpu_attribute hcall takes three, not five input arguments. Adjust the lv1 hcall table and all calls. Signed-off-by: Geoff Levand CC: Takashi Iwai Acked-by: Takashi Iwai Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/lv1call.h | 2 +- sound/ppc/snd_ps3.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/lv1call.h b/arch/powerpc/include/asm/lv1call.h index 9cd5fc8..f77c708 100644 --- a/arch/powerpc/include/asm/lv1call.h +++ b/arch/powerpc/include/asm/lv1call.h @@ -316,7 +316,7 @@ LV1_CALL(gpu_context_free, 1, 0, 218 ) LV1_CALL(gpu_context_iomap, 5, 0, 221 ) LV1_CALL(gpu_context_attribute, 6, 0, 225 ) LV1_CALL(gpu_context_intr, 1, 1, 227 ) -LV1_CALL(gpu_attribute, 5, 0, 228 ) +LV1_CALL(gpu_attribute, 3, 0, 228 ) LV1_CALL(get_rtc, 0, 2, 232 ) LV1_CALL(set_ppe_periodic_tracer_frequency, 1, 0, 240 ) LV1_CALL(start_ppe_periodic_tracer, 5, 0, 241 ) diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c index a3ce1b2..1aa52ef 100644 --- a/sound/ppc/snd_ps3.c +++ b/sound/ppc/snd_ps3.c @@ -876,7 +876,7 @@ static void __devinit snd_ps3_audio_set_base_addr(uint64_t ioaddr_start) (0x0fUL << 12) | (PS3_AUDIO_IOID); - ret = lv1_gpu_attribute(0x100, 0x007, val, 0, 0); + ret = lv1_gpu_attribute(0x100, 0x007, val); if (ret) pr_info("%s: gpu_attribute failed %d\n", __func__, ret); -- cgit v1.1 From 5ccf55dd8177295813b68780f0a3c85e47306be1 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Tue, 13 Sep 2011 04:15:31 +0000 Subject: powerpc/kvm: Fix build failure with HV KVM and CBE When running with HV KVM and CBE config options enabled, I get build failures like the following: arch/powerpc/kernel/head_64.o: In function `cbe_system_error_hv': (.text+0x1228): undefined reference to `do_kvm_0x1202' arch/powerpc/kernel/head_64.o: In function `cbe_maintenance_hv': (.text+0x1628): undefined reference to `do_kvm_0x1602' arch/powerpc/kernel/head_64.o: In function `cbe_thermal_hv': (.text+0x1828): undefined reference to `do_kvm_0x1802' This is because we jump to a KVM handler when HV is enabled, but we only generate the handler with PR KVM mode. Signed-off-by: Alexander Graf Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/exceptions-64s.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index a54d92f..cf9c69b 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -267,7 +267,7 @@ vsx_unavailable_pSeries_1: #ifdef CONFIG_CBE_RAS STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error) - KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_HV, 0x1202) + KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1202) #endif /* CONFIG_CBE_RAS */ STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint) @@ -275,7 +275,7 @@ vsx_unavailable_pSeries_1: #ifdef CONFIG_CBE_RAS STD_EXCEPTION_HV(0x1600, 0x1602, cbe_maintenance) - KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_HV, 0x1602) + KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1602) #endif /* CONFIG_CBE_RAS */ STD_EXCEPTION_PSERIES(0x1700, 0x1700, altivec_assist) @@ -283,7 +283,7 @@ vsx_unavailable_pSeries_1: #ifdef CONFIG_CBE_RAS STD_EXCEPTION_HV(0x1800, 0x1802, cbe_thermal) - KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_HV, 0x1802) + KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1802) #endif /* CONFIG_CBE_RAS */ . = 0x3000 -- cgit v1.1 From 9a3f530f39f4490eaa18b02719fb74ce5f4d2d86 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 8 Nov 2011 16:22:01 +1100 Subject: md/raid5: abort any pending parity operations when array fails. When the number of failed devices exceeds the allowed number we must abort any active parity operations (checks or updates) as they are no longer meaningful, and can lead to a BUG_ON in handle_parity_checks6. This bug was introduce by commit 6c0069c0ae9659e3a91b68eaed06a5c6c37f45c8 in 2.6.29. Reported-by: Manish Katiyar Tested-by: Manish Katiyar Acked-by: Dan Williams Signed-off-by: NeilBrown Cc: stable@kernel.org --- drivers/md/raid5.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 472aedf..318bdae 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3159,10 +3159,14 @@ static void handle_stripe(struct stripe_head *sh) /* check if the array has lost more than max_degraded devices and, * if so, some requests might need to be failed. */ - if (s.failed > conf->max_degraded && s.to_read+s.to_write+s.written) - handle_failed_stripe(conf, sh, &s, disks, &s.return_bi); - if (s.failed > conf->max_degraded && s.syncing) - handle_failed_sync(conf, sh, &s); + if (s.failed > conf->max_degraded) { + sh->check_state = 0; + sh->reconstruct_state = 0; + if (s.to_read+s.to_write+s.written) + handle_failed_stripe(conf, sh, &s, disks, &s.return_bi); + if (s.syncing) + handle_failed_sync(conf, sh, &s); + } /* * might be able to return some write requests if the parity blocks -- cgit v1.1 From 257a4b42af7586fab4eaec7f04e6896b86551843 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 8 Nov 2011 16:22:06 +1100 Subject: md/raid5: STRIPE_ACTIVE has lock semantics, add barriers All updates that occur under STRIPE_ACTIVE should be globally visible when STRIPE_ACTIVE clears. test_and_set_bit() implies a barrier, but clear_bit() does not. This is suitable for 3.1-stable. Signed-off-by: Dan Williams Signed-off-by: NeilBrown Cc: stable@kernel.org --- drivers/md/raid5.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 318bdae..297e260 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3110,7 +3110,7 @@ static void handle_stripe(struct stripe_head *sh) struct r5dev *pdev, *qdev; clear_bit(STRIPE_HANDLE, &sh->state); - if (test_and_set_bit(STRIPE_ACTIVE, &sh->state)) { + if (test_and_set_bit_lock(STRIPE_ACTIVE, &sh->state)) { /* already being handled, ensure it gets handled * again when current action finishes */ set_bit(STRIPE_HANDLE, &sh->state); @@ -3375,7 +3375,7 @@ finish: return_io(s.return_bi); - clear_bit(STRIPE_ACTIVE, &sh->state); + clear_bit_unlock(STRIPE_ACTIVE, &sh->state); } static void raid5_activate_delayed(struct r5conf *conf) -- cgit v1.1 From 5a9a51799b23142d2fc3ef94894d3b5ac00d05a5 Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Mon, 7 Nov 2011 20:33:25 +0400 Subject: ALSA: intel8x0: Improve comments for VM optimization The recently merged 228cf79376f1 looks a bit hackish while it is not. The change was quite simple. In a virtualized environment the patch unhacks old kludge introduced for old broken AC97 hardware. This patch adds proper comment to "unkludge" code. Signed-off-by: Denis V. Lunev Signed-off-by: Konstantin Ozerkov Signed-off-by: Takashi Iwai --- sound/pci/intel8x0.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 29e3125..c3b9bd0 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -1077,6 +1077,13 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs } if (civ != igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV)) continue; + + /* IO read operation is very expensive inside virtual machine + * as it is emulated. The probability that subsequent PICB read + * will return different result is high enough to loop till + * timeout here. + * Same CIV is strict enough condition to be sure that PICB + * is valid inside VM on emulated card. */ if (chip->inside_vm) break; if (ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) -- cgit v1.1 From dccc1810f41b42773a2e359907f05a7fd10910bd Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 8 Nov 2011 07:52:19 +0100 Subject: ALSA: hda - Mute unused capture sources for Realtek codecs When a Realtek codec has a matrix-style capture-source selection, we need to scan all connections instead of only imux items. Otherwise some input might be kept unmuted. Although the corresponding input must be dead so there should be no input from it, it's still safer to mute the route completely. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a24e068..308bb57 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -284,7 +284,7 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, struct alc_spec *spec = codec->spec; const struct hda_input_mux *imux; unsigned int mux_idx; - int i, type; + int i, type, num_conns; hda_nid_t nid; mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; @@ -307,16 +307,17 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; /* no selection? */ - if (snd_hda_get_conn_list(codec, nid, NULL) <= 1) + num_conns = snd_hda_get_conn_list(codec, nid, NULL); + if (num_conns <= 1) return 1; type = get_wcaps_type(get_wcaps(codec, nid)); if (type == AC_WID_AUD_MIX) { /* Matrix-mixer style (e.g. ALC882) */ - for (i = 0; i < imux->num_items; i++) { - unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; - snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, - imux->items[i].index, + int active = imux->items[idx].index; + for (i = 0; i < num_conns; i++) { + unsigned int v = (i == active) ? 0 : HDA_AMP_MUTE; + snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, i, HDA_AMP_MUTE, v); } } else { -- cgit v1.1 From 816af3bb5022c1468b3d826c645ddc2cac45bc97 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 3 Nov 2011 14:45:48 +0800 Subject: hwspinlock: Don't return a value in __hwspin_unlock Fix below build warning: CC arch/arm/mach-omap2/hwspinlock.o In file included from arch/arm/mach-omap2/hwspinlock.c:22: include/linux/hwspinlock.h: In function '__hwspin_unlock': include/linux/hwspinlock.h:121: warning: 'return' with a value, in function returning void Signed-off-by: Axel Lin Signed-off-by: Ohad Ben-Cohen --- include/linux/hwspinlock.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h index 08a2fee..aad6bd4 100644 --- a/include/linux/hwspinlock.h +++ b/include/linux/hwspinlock.h @@ -118,7 +118,6 @@ int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags) static inline void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags) { - return 0; } static inline int hwspin_lock_get_id(struct hwspinlock *hwlock) -- cgit v1.1 From fdcb23634c9b6649bb02c681033d4973491b0e35 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 6 Nov 2011 21:14:16 +0800 Subject: hwspinlock/u8500: fix build error due to undefined label Fix below build error: CC drivers/hwspinlock/u8500_hsem.o drivers/hwspinlock/u8500_hsem.c: In function 'u8500_hsem_probe': drivers/hwspinlock/u8500_hsem.c:113: error: label 'free_state' used but not defined Signed-off-by: Axel Lin Signed-off-by: Ohad Ben-Cohen --- drivers/hwspinlock/u8500_hsem.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/hwspinlock/u8500_hsem.c b/drivers/hwspinlock/u8500_hsem.c index 143461a..a120f14 100644 --- a/drivers/hwspinlock/u8500_hsem.c +++ b/drivers/hwspinlock/u8500_hsem.c @@ -108,10 +108,8 @@ static int __devinit u8500_hsem_probe(struct platform_device *pdev) return -ENODEV; io_base = ioremap(res->start, resource_size(res)); - if (!io_base) { - ret = -ENOMEM; - goto free_state; - } + if (!io_base) + return -ENOMEM; /* make sure protocol 1 is selected */ val = readl(io_base + HSEM_CTRL_REG); -- cgit v1.1 From 1258ea596fe0422272525d9ec8a25b703de4623f Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 8 Nov 2011 03:16:09 -0700 Subject: ARM: OMAP2xxx: HWMOD: Fix DSS reset DSS needs all DSS clocks to be enabled to be able to finish reset properly. Before v3.1-rc1 the omapdss driver was managing clocks and resets correctly. However, when omapdss started using runtime PM at v3.1-rc1, the responsibility for the reset moved to HWMOD framework. HWMOD framework does not currently enable all the DSS clocks when resetting the DSS hardware. This hasn't caused any problems so far, but we may just have been lucky. This patch sets HWMOD_CONTROL_OPT_CLKS_IN_RESET for dss_core in OMAP2xxx HWMOD data, fixing the issue. Signed-off-by: Tomi Valkeinen [paul@pwsan.com: merged duplicate .flags fields] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod_2420_data.c | 6 +++++- arch/arm/mach-omap2/omap_hwmod_2430_data.c | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index 6d72062..5160e35 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -875,6 +875,10 @@ static struct omap_hwmod_ocp_if *omap2420_dss_slaves[] = { }; static struct omap_hwmod_opt_clk dss_opt_clks[] = { + /* + * The DSS HW needs all DSS clocks enabled during reset. The dss_core + * driver does not use these clocks. + */ { .role = "tv_clk", .clk = "dss_54m_fck" }, { .role = "sys_clk", .clk = "dss2_fck" }, }; @@ -899,7 +903,7 @@ static struct omap_hwmod omap2420_dss_core_hwmod = { .slaves_cnt = ARRAY_SIZE(omap2420_dss_slaves), .masters = omap2420_dss_masters, .masters_cnt = ARRAY_SIZE(omap2420_dss_masters), - .flags = HWMOD_NO_IDLEST, + .flags = HWMOD_NO_IDLEST | HWMOD_CONTROL_OPT_CLKS_IN_RESET, }; /* l4_core -> dss_dispc */ diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index a2580d0..d02a44e 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -942,6 +942,10 @@ static struct omap_hwmod_ocp_if *omap2430_dss_slaves[] = { }; static struct omap_hwmod_opt_clk dss_opt_clks[] = { + /* + * The DSS HW needs all DSS clocks enabled during reset. The dss_core + * driver does not use these clocks. + */ { .role = "tv_clk", .clk = "dss_54m_fck" }, { .role = "sys_clk", .clk = "dss2_fck" }, }; @@ -966,7 +970,7 @@ static struct omap_hwmod omap2430_dss_core_hwmod = { .slaves_cnt = ARRAY_SIZE(omap2430_dss_slaves), .masters = omap2430_dss_masters, .masters_cnt = ARRAY_SIZE(omap2430_dss_masters), - .flags = HWMOD_NO_IDLEST, + .flags = HWMOD_NO_IDLEST | HWMOD_CONTROL_OPT_CLKS_IN_RESET, }; /* l4_core -> dss_dispc */ -- cgit v1.1 From b8ac10d8b75843c9ddd6aadf70a0cdf8aa783659 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 8 Nov 2011 03:16:09 -0700 Subject: ARM: OMAP2xxx: HWMOD: fix DSS clock data The OMAP2xxx HWMOD data currently contains two errors with DSS clocks: - dss_rfbi is missing ick opt-clock, which is needed for RFBI to calculate timings - dss_venc's interface and main clocks are wrong, causing VENC to fail to start These problems were temporarily fixed with a DSS patch 9ede365aa6f74428a1f69c21ca1cf21213167576 ("HACK: OMAP: DSS2: clk hack for OMAP2/3"), which can be reverted after this patch (and the similar patches for other OMAPs). Signed-off-by: Tomi Valkeinen Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod_2420_data.c | 10 ++++++++-- arch/arm/mach-omap2/omap_hwmod_2430_data.c | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index 5160e35..74037a5 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -965,6 +965,10 @@ static struct omap_hwmod_ocp_if *omap2420_dss_rfbi_slaves[] = { &omap2420_l4_core__dss_rfbi, }; +static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = { + { .role = "ick", .clk = "dss_ick" }, +}; + static struct omap_hwmod omap2420_dss_rfbi_hwmod = { .name = "dss_rfbi", .class = &omap2_rfbi_hwmod_class, @@ -976,6 +980,8 @@ static struct omap_hwmod omap2420_dss_rfbi_hwmod = { .module_offs = CORE_MOD, }, }, + .opt_clks = dss_rfbi_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks), .slaves = omap2420_dss_rfbi_slaves, .slaves_cnt = ARRAY_SIZE(omap2420_dss_rfbi_slaves), .flags = HWMOD_NO_IDLEST, @@ -985,7 +991,7 @@ static struct omap_hwmod omap2420_dss_rfbi_hwmod = { static struct omap_hwmod_ocp_if omap2420_l4_core__dss_venc = { .master = &omap2420_l4_core_hwmod, .slave = &omap2420_dss_venc_hwmod, - .clk = "dss_54m_fck", + .clk = "dss_ick", .addr = omap2_dss_venc_addrs, .fw = { .omap2 = { @@ -1005,7 +1011,7 @@ static struct omap_hwmod_ocp_if *omap2420_dss_venc_slaves[] = { static struct omap_hwmod omap2420_dss_venc_hwmod = { .name = "dss_venc", .class = &omap2_venc_hwmod_class, - .main_clk = "dss1_fck", + .main_clk = "dss_54m_fck", .prcm = { .omap2 = { .prcm_reg_id = 1, diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index d02a44e..6f03653 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -1020,6 +1020,10 @@ static struct omap_hwmod_ocp_if *omap2430_dss_rfbi_slaves[] = { &omap2430_l4_core__dss_rfbi, }; +static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = { + { .role = "ick", .clk = "dss_ick" }, +}; + static struct omap_hwmod omap2430_dss_rfbi_hwmod = { .name = "dss_rfbi", .class = &omap2_rfbi_hwmod_class, @@ -1031,6 +1035,8 @@ static struct omap_hwmod omap2430_dss_rfbi_hwmod = { .module_offs = CORE_MOD, }, }, + .opt_clks = dss_rfbi_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks), .slaves = omap2430_dss_rfbi_slaves, .slaves_cnt = ARRAY_SIZE(omap2430_dss_rfbi_slaves), .flags = HWMOD_NO_IDLEST, @@ -1040,7 +1046,7 @@ static struct omap_hwmod omap2430_dss_rfbi_hwmod = { static struct omap_hwmod_ocp_if omap2430_l4_core__dss_venc = { .master = &omap2430_l4_core_hwmod, .slave = &omap2430_dss_venc_hwmod, - .clk = "dss_54m_fck", + .clk = "dss_ick", .addr = omap2_dss_venc_addrs, .flags = OCPIF_SWSUP_IDLE, .user = OCP_USER_MPU | OCP_USER_SDMA, @@ -1054,7 +1060,7 @@ static struct omap_hwmod_ocp_if *omap2430_dss_venc_slaves[] = { static struct omap_hwmod omap2430_dss_venc_hwmod = { .name = "dss_venc", .class = &omap2_venc_hwmod_class, - .main_clk = "dss1_fck", + .main_clk = "dss_54m_fck", .prcm = { .omap2 = { .prcm_reg_id = 1, -- cgit v1.1 From 8c3105ca1a42783b13930fbd375484ec8c72e608 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 8 Nov 2011 03:16:10 -0700 Subject: ARM: OMAP3: HWMOD: Fix DSS reset DSS needs all DSS clocks to be enabled to be able to finish reset properly. Before v3.1-rc1 the omapdss driver was managing clocks and resets correctly. However, when omapdss started using runtime PM at v3.1-rc1, the responsibility for the reset moved to HWMOD framework. HWMOD framework does not currently enable all the DSS clocks when resetting the DSS hardware. This hasn't caused any problems so far, but we may just have been lucky. dss_core's opt-clocks is also missing dss_96m_fck, which is a DSS clock present only on OMAP3430, and thus required on OMAP3430 to finish the reset. This patch sets HWMOD_CONTROL_OPT_CLKS_IN_RESET and adds the dss_96m_fck opt-clock for dss_core in OMAP3 HWMOD data, fixing the issue. Signed-off-by: Tomi Valkeinen [paul@pwsan.com: merged duplicate .flags fields] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index bc9035e..45ccd4f 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1369,9 +1369,14 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_slaves[] = { }; static struct omap_hwmod_opt_clk dss_opt_clks[] = { - { .role = "tv_clk", .clk = "dss_tv_fck" }, - { .role = "video_clk", .clk = "dss_96m_fck" }, + /* + * The DSS HW needs all DSS clocks enabled during reset. The dss_core + * driver does not use these clocks. + */ { .role = "sys_clk", .clk = "dss2_alwon_fck" }, + { .role = "tv_clk", .clk = "dss_tv_fck" }, + /* required only on OMAP3430 */ + { .role = "tv_dac_clk", .clk = "dss_96m_fck" }, }; static struct omap_hwmod omap3430es1_dss_core_hwmod = { @@ -1394,11 +1399,12 @@ static struct omap_hwmod omap3430es1_dss_core_hwmod = { .slaves_cnt = ARRAY_SIZE(omap3430es1_dss_slaves), .masters = omap3xxx_dss_masters, .masters_cnt = ARRAY_SIZE(omap3xxx_dss_masters), - .flags = HWMOD_NO_IDLEST, + .flags = HWMOD_NO_IDLEST | HWMOD_CONTROL_OPT_CLKS_IN_RESET, }; static struct omap_hwmod omap3xxx_dss_core_hwmod = { .name = "dss_core", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .class = &omap2_dss_hwmod_class, .main_clk = "dss1_alwon_fck", /* instead of dss_fck */ .sdma_reqs = omap3xxx_dss_sdma_chs, -- cgit v1.1 From 6c3d7e34d68ffae888d33bf364f447e0b415591f Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 8 Nov 2011 03:16:10 -0700 Subject: ARM: OMAP3: HWMOD: fix DSS clock data The OMAP3 HWMOD data currently contains these errors with DSS clocks: - dss_rfbi is missing ick opt-clock, which is needed for RFBI to calculate timings - dss_dsi is missing ick and sys_clk - dss_venc is missing dss_96m_fck opt-clock, which is required on OMAP3430 - dss_venc's interface and main clocks are wrong, causing VENC to fail to start These problems were temporarily fixed with a DSS patch 9ede365aa6f74428a1f69c21ca1cf21213167576 ("HACK: OMAP: DSS2: clk hack for OMAP2/3"), which can be reverted after this patch (and the similar patches for other OMAPs). Signed-off-by: Tomi Valkeinen Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 45ccd4f..4aaf0ca 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1492,6 +1492,7 @@ static struct omap_hwmod_addr_space omap3xxx_dss_dsi1_addrs[] = { static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dsi1 = { .master = &omap3xxx_l4_core_hwmod, .slave = &omap3xxx_dss_dsi1_hwmod, + .clk = "dss_ick", .addr = omap3xxx_dss_dsi1_addrs, .fw = { .omap2 = { @@ -1508,6 +1509,10 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_dsi1_slaves[] = { &omap3xxx_l4_core__dss_dsi1, }; +static struct omap_hwmod_opt_clk dss_dsi1_opt_clks[] = { + { .role = "sys_clk", .clk = "dss2_alwon_fck" }, +}; + static struct omap_hwmod omap3xxx_dss_dsi1_hwmod = { .name = "dss_dsi1", .class = &omap3xxx_dsi_hwmod_class, @@ -1520,6 +1525,8 @@ static struct omap_hwmod omap3xxx_dss_dsi1_hwmod = { .module_offs = OMAP3430_DSS_MOD, }, }, + .opt_clks = dss_dsi1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_dsi1_opt_clks), .slaves = omap3xxx_dss_dsi1_slaves, .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_dsi1_slaves), .flags = HWMOD_NO_IDLEST, @@ -1546,6 +1553,10 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_rfbi_slaves[] = { &omap3xxx_l4_core__dss_rfbi, }; +static struct omap_hwmod_opt_clk dss_rfbi_opt_clks[] = { + { .role = "ick", .clk = "dss_ick" }, +}; + static struct omap_hwmod omap3xxx_dss_rfbi_hwmod = { .name = "dss_rfbi", .class = &omap2_rfbi_hwmod_class, @@ -1557,6 +1568,8 @@ static struct omap_hwmod omap3xxx_dss_rfbi_hwmod = { .module_offs = OMAP3430_DSS_MOD, }, }, + .opt_clks = dss_rfbi_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks), .slaves = omap3xxx_dss_rfbi_slaves, .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_rfbi_slaves), .flags = HWMOD_NO_IDLEST, @@ -1566,7 +1579,7 @@ static struct omap_hwmod omap3xxx_dss_rfbi_hwmod = { static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_venc = { .master = &omap3xxx_l4_core_hwmod, .slave = &omap3xxx_dss_venc_hwmod, - .clk = "dss_tv_fck", + .clk = "dss_ick", .addr = omap2_dss_venc_addrs, .fw = { .omap2 = { @@ -1584,10 +1597,15 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_venc_slaves[] = { &omap3xxx_l4_core__dss_venc, }; +static struct omap_hwmod_opt_clk dss_venc_opt_clks[] = { + /* required only on OMAP3430 */ + { .role = "tv_dac_clk", .clk = "dss_96m_fck" }, +}; + static struct omap_hwmod omap3xxx_dss_venc_hwmod = { .name = "dss_venc", .class = &omap2_venc_hwmod_class, - .main_clk = "dss1_alwon_fck", + .main_clk = "dss_tv_fck", .prcm = { .omap2 = { .prcm_reg_id = 1, @@ -1595,6 +1613,8 @@ static struct omap_hwmod omap3xxx_dss_venc_hwmod = { .module_offs = OMAP3430_DSS_MOD, }, }, + .opt_clks = dss_venc_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_venc_opt_clks), .slaves = omap3xxx_dss_venc_slaves, .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_venc_slaves), .flags = HWMOD_NO_IDLEST, -- cgit v1.1 From 4247878efca76143aa015ed1142652056052abb8 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 8 Nov 2011 03:16:11 -0700 Subject: ARM: OMAP4: HWMOD: remove extra clocks Remove the dss_dss_clk from dss_core's opt-clocks. dss_dss_clk already defined as the dss main_clk, and thus is not needed as an opt-clock. Remove opt-clocks for dss_dispc, as dispc only uses the main_clk. Signed-off-by: Tomi Valkeinen Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 7695e5d..3b9f2d9 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -1240,7 +1240,6 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_slaves[] = { static struct omap_hwmod_opt_clk dss_opt_clks[] = { { .role = "sys_clk", .clk = "dss_sys_clk" }, { .role = "tv_clk", .clk = "dss_tv_clk" }, - { .role = "dss_clk", .clk = "dss_dss_clk" }, { .role = "video_clk", .clk = "dss_48mhz_clk" }, }; @@ -1340,12 +1339,6 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_dispc_slaves[] = { &omap44xx_l4_per__dss_dispc, }; -static struct omap_hwmod_opt_clk dss_dispc_opt_clks[] = { - { .role = "sys_clk", .clk = "dss_sys_clk" }, - { .role = "tv_clk", .clk = "dss_tv_clk" }, - { .role = "hdmi_clk", .clk = "dss_48mhz_clk" }, -}; - static struct omap_hwmod omap44xx_dss_dispc_hwmod = { .name = "dss_dispc", .class = &omap44xx_dispc_hwmod_class, @@ -1359,8 +1352,6 @@ static struct omap_hwmod omap44xx_dss_dispc_hwmod = { .context_offs = OMAP4_RM_DSS_DSS_CONTEXT_OFFSET, }, }, - .opt_clks = dss_dispc_opt_clks, - .opt_clks_cnt = ARRAY_SIZE(dss_dispc_opt_clks), .slaves = omap44xx_dss_dispc_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_dss_dispc_slaves), }; -- cgit v1.1 From 37ad085527860397438f27c81a2cb13272378458 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 8 Nov 2011 03:16:11 -0700 Subject: ARM: OMAP4: HWMOD: Add HWMOD_CONTROL_OPT_CLKS_IN_RESET for dss_core DSS needs all DSS clocks to be enabled to be able to finish reset properly. Before v3.1-rc1 the omapdss driver was managing clocks and resets correctly. However, when omapdss started using runtime PM at v3.1-rc1, the responsibility for the reset moved to HWMOD framework. HWMOD framework does not currently enable all the DSS clocks when resetting the DSS hardware. This causes the HWMOD frameworks boot-time reset to fail, possibly leaving the DSS hardware in undefined state. This patch sets HWMOD_CONTROL_OPT_CLKS_IN_RESET for dss_core. The flag is actually not used on OMAP4, because dss_core hardware does not have soft-reset functionality and thus the HWMOD framework never resets nor waits for the reset to finish. However, while the flag is not strictly needed currently, I think it represents the HW correctly: all the DSS clocks should be enabled after power-on to allow DSS hardware to finish its reset. A custom reset function will be added in the following patches which manages this correctly for OMAP4. Signed-off-by: Tomi Valkeinen Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 3b9f2d9..b82720a 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -1245,6 +1245,7 @@ static struct omap_hwmod_opt_clk dss_opt_clks[] = { static struct omap_hwmod omap44xx_dss_hwmod = { .name = "dss_core", + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, .class = &omap44xx_dss_hwmod_class, .clkdm_name = "l3_dss_clkdm", .main_clk = "dss_dss_clk", -- cgit v1.1 From 4d0698d98f501b86d3bef38c46a54a702e0469a0 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 8 Nov 2011 03:16:12 -0700 Subject: ARM: OMAP4: HWMOD: fix DSS clock data The OMAP4 HWMOD data currently contains errors with DSS clocks: dss_hdmi and dss_venc have their main_clks wrong. The clocks should be dss_48mhz_clk and dss_tv_clk, respectively. These problems were temporarily fixed with the DSS patches 9ede365aa6f74428a1f69c21ca1cf21213167576 ("HACK: OMAP: DSS2: clk hack for OMAP2/3"), and df5d3ed23cf73ee0763a8963003bda9b69d9620f ("OMAP: DSS2: HDMI: fix hdmi clock name"), which can be reverted after this patch. Signed-off-by: Tomi Valkeinen Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index b82720a..cadf0bb 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -1240,7 +1240,7 @@ static struct omap_hwmod_ocp_if *omap44xx_dss_slaves[] = { static struct omap_hwmod_opt_clk dss_opt_clks[] = { { .role = "sys_clk", .clk = "dss_sys_clk" }, { .role = "tv_clk", .clk = "dss_tv_clk" }, - { .role = "video_clk", .clk = "dss_48mhz_clk" }, + { .role = "hdmi_clk", .clk = "dss_48mhz_clk" }, }; static struct omap_hwmod omap44xx_dss_hwmod = { @@ -1616,7 +1616,7 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { .clkdm_name = "l3_dss_clkdm", .mpu_irqs = omap44xx_dss_hdmi_irqs, .sdma_reqs = omap44xx_dss_hdmi_sdma_reqs, - .main_clk = "dss_dss_clk", + .main_clk = "dss_48mhz_clk", .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, @@ -1777,7 +1777,7 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = { .name = "dss_venc", .class = &omap44xx_venc_hwmod_class, .clkdm_name = "l3_dss_clkdm", - .main_clk = "dss_dss_clk", + .main_clk = "dss_tv_clk", .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, -- cgit v1.1 From 3ce32676bb355420ceeda57b73dd84df0ff5ad6f Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 8 Nov 2011 03:16:12 -0700 Subject: ARM: OMAP2/3: HWMOD: Add SYSS_HAS_RESET_STATUS for dss OMAP2/3 dss_core has a reset status flag in sysstatus register. Add SYSS_HAS_RESET_STATUS flag to HWMOD data so it can be used. Signed-off-by: Tomi Valkeinen Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c index c451729..d78c132 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c @@ -43,7 +43,8 @@ static struct omap_hwmod_class_sysconfig omap2_dss_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, .syss_offs = 0x0014, - .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), + .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | + SYSS_HAS_RESET_STATUS), .sysc_fields = &omap_hwmod_sysc_type1, }; -- cgit v1.1 From 13662dc5b177d68885695ef513dd4ae0e4d2a099 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 8 Nov 2011 03:16:13 -0700 Subject: ARM: OMAP: HWMOD: Unify DSS resets for OMAPs This patch adds a custom DSS reset function used on OMAPs from OMAP2 forward. The function doesn't actually do a reset, it only waits for the reset to complete. The reason for this is that on OMAP4 there is no possibility to do a SW reset, and on OMAP2/3 doing a SW reset for dss_core resets all the other DSS modules also, thus breaking the HWMOD model where every DSS module is handled independently. This fixes the problem with DSS reset on OMAP4, caused by the fact that because there's no SW reset for dss_core on OMAP4, the HWMOD framework doesn't try to reset dss_core and thus the DSS clocks were never enabled at the same time. This causes causes the HWMOD reset to fail for dss_dispc and dss_rfbi. The common reset function will also allow us to fix another problem in the future: before doing a reset we need to disable DSS outputs, which are in some cases enabled by the bootloader, as otherwise DSS HW seems to get more or less stuck, requiring a power reset to recover. Signed-off-by: Tomi Valkeinen [paul@pwsan.com: modified to build arch/arm/mach-omap2/display.o unconditionally to avoid an error when !CONFIG_OMAP2_DSS] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/Makefile | 5 +--- arch/arm/mach-omap2/display.c | 35 ++++++++++++++++++++++ .../mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c | 2 ++ arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 2 ++ arch/arm/plat-omap/include/plat/common.h | 3 ++ include/video/omapdss.h | 7 ----- 6 files changed, 43 insertions(+), 11 deletions(-) diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 69ab1c0..b009f17 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -4,7 +4,7 @@ # Common support obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer.o pm.o \ - common.o gpio.o dma.o wd_timer.o + common.o gpio.o dma.o wd_timer.o display.o omap-2-3-common = irq.o sdrc.o hwmod-common = omap_hwmod.o \ @@ -264,7 +264,4 @@ smsc911x-$(CONFIG_SMSC911X) := gpmc-smsc911x.o obj-y += $(smsc911x-m) $(smsc911x-y) obj-$(CONFIG_ARCH_OMAP4) += hwspinlock.o -disp-$(CONFIG_OMAP2_DSS) := display.o -obj-y += $(disp-m) $(disp-y) - obj-y += common-board-devices.o twl-common.o diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index adb2756..941b545 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "control.h" @@ -172,3 +173,37 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) return r; } + +#define MAX_MODULE_SOFTRESET_WAIT 10000 +int omap_dss_reset(struct omap_hwmod *oh) +{ + struct omap_hwmod_opt_clk *oc; + int c = 0; + int i, r; + + if (!(oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS)) { + pr_err("dss_core: hwmod data doesn't contain reset data\n"); + return -EINVAL; + } + + for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) + if (oc->_clk) + clk_enable(oc->_clk); + + omap_test_timeout((omap_hwmod_read(oh, oh->class->sysc->syss_offs) + & SYSS_RESETDONE_MASK), + MAX_MODULE_SOFTRESET_WAIT, c); + + if (c == MAX_MODULE_SOFTRESET_WAIT) + pr_warning("dss_core: waiting for reset to finish failed\n"); + else + pr_debug("dss_core: softreset done\n"); + + for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) + if (oc->_clk) + clk_disable(oc->_clk); + + r = (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : 0; + + return r; +} diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c index d78c132..c11273d 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -51,6 +52,7 @@ static struct omap_hwmod_class_sysconfig omap2_dss_sysc = { struct omap_hwmod_class omap2_dss_hwmod_class = { .name = "dss", .sysc = &omap2_dss_sysc, + .reset = omap_dss_reset, }; /* diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index cadf0bb..3b04d63 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "omap_hwmod_common_data.h" @@ -1187,6 +1188,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_dss_sysc = { static struct omap_hwmod_class omap44xx_dss_hwmod_class = { .name = "dss", .sysc = &omap44xx_dss_sysc, + .reset = omap_dss_reset, }; /* dss */ diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h index c50df48..3ff3e36 100644 --- a/arch/arm/plat-omap/include/plat/common.h +++ b/arch/arm/plat-omap/include/plat/common.h @@ -30,6 +30,7 @@ #include #include +#include struct sys_timer; @@ -55,6 +56,8 @@ void am35xx_init_early(void); void ti816x_init_early(void); void omap4430_init_early(void); +extern int omap_dss_reset(struct omap_hwmod *); + void omap_sram_init(void); /* diff --git a/include/video/omapdss.h b/include/video/omapdss.h index b66ebb2..378c7ed 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -307,15 +307,8 @@ struct omap_dss_board_info { void (*dsi_disable_pads)(int dsi_id, unsigned lane_mask); }; -#if defined(CONFIG_OMAP2_DSS_MODULE) || defined(CONFIG_OMAP2_DSS) /* Init with the board info */ extern int omap_display_init(struct omap_dss_board_info *board_data); -#else -static inline int omap_display_init(struct omap_dss_board_info *board_data) -{ - return 0; -} -#endif struct omap_display_platform_data { struct omap_dss_board_info *board_data; -- cgit v1.1 From b923d40dd4211c4ef7d4efa2bd81b7ca1d8744c1 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Thu, 6 Oct 2011 18:04:08 -0600 Subject: ARM: OMAP2PLUS: DSS: Ensure DSS works correctly if display is enabled in bootloader Resetting DISPC when a DISPC output is enabled causes the DSS to go into an inconsistent state. Thus if the bootloader has enabled a display, the hwmod code cannot reset the DISPC module just like that, but the outputs need to be disabled first. Add function dispc_disable_outputs() which disables all active overlay manager and ensure all frame transfers are completed. Modify omap_dss_reset() to call this function and clear DSS_CONTROL, DSS_SDI_CONTROL and DSS_PLL_CONTROL so that DSS is in a clean state when the DSS2 driver starts. This resolves the hang issue(caused by a L3 error during boot) seen on the beagle board C3, which has a factory bootloader that enables display. The issue is resolved with this patch. Thanks to Tomi and Sricharan for some additional testing. Acked-by: Tomi Valkeinen Tested-by: R, Sricharan Signed-off-by: Archit Taneja [paul@pwsan.com: restructured code, removed omap_{read,write}l(), removed cpu_is_omap*() calls and converted to dev_attr] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/display.c | 124 +++++++++++++++++++++++++++ arch/arm/mach-omap2/display.h | 29 +++++++ arch/arm/mach-omap2/omap_hwmod_2420_data.c | 1 + arch/arm/mach-omap2/omap_hwmod_2430_data.c | 1 + arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 1 + arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 6 ++ arch/arm/mach-omap2/omap_hwmod_common_data.c | 4 + arch/arm/mach-omap2/omap_hwmod_common_data.h | 4 + 8 files changed, 170 insertions(+) create mode 100644 arch/arm/mach-omap2/display.h diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 941b545..dce9905 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -30,6 +30,32 @@ #include #include "control.h" +#include "display.h" + +#define DISPC_CONTROL 0x0040 +#define DISPC_CONTROL2 0x0238 +#define DISPC_IRQSTATUS 0x0018 + +#define DSS_SYSCONFIG 0x10 +#define DSS_SYSSTATUS 0x14 +#define DSS_CONTROL 0x40 +#define DSS_SDI_CONTROL 0x44 +#define DSS_PLL_CONTROL 0x48 + +#define LCD_EN_MASK (0x1 << 0) +#define DIGIT_EN_MASK (0x1 << 1) + +#define FRAMEDONE_IRQ_SHIFT 0 +#define EVSYNC_EVEN_IRQ_SHIFT 2 +#define EVSYNC_ODD_IRQ_SHIFT 3 +#define FRAMEDONE2_IRQ_SHIFT 22 +#define FRAMEDONETV_IRQ_SHIFT 24 + +/* + * FRAMEDONE_IRQ_TIMEOUT: how long (in milliseconds) to wait during DISPC + * reset before deciding that something has gone wrong + */ +#define FRAMEDONE_IRQ_TIMEOUT 100 static struct platform_device omap_display_device = { .name = "omapdss", @@ -174,6 +200,90 @@ int __init omap_display_init(struct omap_dss_board_info *board_data) return r; } +static void dispc_disable_outputs(void) +{ + u32 v, irq_mask = 0; + bool lcd_en, digit_en, lcd2_en = false; + int i; + struct omap_dss_dispc_dev_attr *da; + struct omap_hwmod *oh; + + oh = omap_hwmod_lookup("dss_dispc"); + if (!oh) { + WARN(1, "display: could not disable outputs during reset - could not find dss_dispc hwmod\n"); + return; + } + + if (!oh->dev_attr) { + pr_err("display: could not disable outputs during reset due to missing dev_attr\n"); + return; + } + + da = (struct omap_dss_dispc_dev_attr *)oh->dev_attr; + + /* store value of LCDENABLE and DIGITENABLE bits */ + v = omap_hwmod_read(oh, DISPC_CONTROL); + lcd_en = v & LCD_EN_MASK; + digit_en = v & DIGIT_EN_MASK; + + /* store value of LCDENABLE for LCD2 */ + if (da->manager_count > 2) { + v = omap_hwmod_read(oh, DISPC_CONTROL2); + lcd2_en = v & LCD_EN_MASK; + } + + if (!(lcd_en | digit_en | lcd2_en)) + return; /* no managers currently enabled */ + + /* + * If any manager was enabled, we need to disable it before + * DSS clocks are disabled or DISPC module is reset + */ + if (lcd_en) + irq_mask |= 1 << FRAMEDONE_IRQ_SHIFT; + + if (digit_en) { + if (da->has_framedonetv_irq) { + irq_mask |= 1 << FRAMEDONETV_IRQ_SHIFT; + } else { + irq_mask |= 1 << EVSYNC_EVEN_IRQ_SHIFT | + 1 << EVSYNC_ODD_IRQ_SHIFT; + } + } + + if (lcd2_en) + irq_mask |= 1 << FRAMEDONE2_IRQ_SHIFT; + + /* + * clear any previous FRAMEDONE, FRAMEDONETV, + * EVSYNC_EVEN/ODD or FRAMEDONE2 interrupts + */ + omap_hwmod_write(irq_mask, oh, DISPC_IRQSTATUS); + + /* disable LCD and TV managers */ + v = omap_hwmod_read(oh, DISPC_CONTROL); + v &= ~(LCD_EN_MASK | DIGIT_EN_MASK); + omap_hwmod_write(v, oh, DISPC_CONTROL); + + /* disable LCD2 manager */ + if (da->manager_count > 2) { + v = omap_hwmod_read(oh, DISPC_CONTROL2); + v &= ~LCD_EN_MASK; + omap_hwmod_write(v, oh, DISPC_CONTROL2); + } + + i = 0; + while ((omap_hwmod_read(oh, DISPC_IRQSTATUS) & irq_mask) != + irq_mask) { + i++; + if (i > FRAMEDONE_IRQ_TIMEOUT) { + pr_err("didn't get FRAMEDONE1/2 or TV interrupt\n"); + break; + } + mdelay(1); + } +} + #define MAX_MODULE_SOFTRESET_WAIT 10000 int omap_dss_reset(struct omap_hwmod *oh) { @@ -190,6 +300,20 @@ int omap_dss_reset(struct omap_hwmod *oh) if (oc->_clk) clk_enable(oc->_clk); + dispc_disable_outputs(); + + /* clear SDI registers */ + if (cpu_is_omap3430()) { + omap_hwmod_write(0x0, oh, DSS_SDI_CONTROL); + omap_hwmod_write(0x0, oh, DSS_PLL_CONTROL); + } + + /* + * clear DSS_CONTROL register to switch DSS clock sources to + * PRCM clock, if any + */ + omap_hwmod_write(0x0, oh, DSS_CONTROL); + omap_test_timeout((omap_hwmod_read(oh, oh->class->sysc->syss_offs) & SYSS_RESETDONE_MASK), MAX_MODULE_SOFTRESET_WAIT, c); diff --git a/arch/arm/mach-omap2/display.h b/arch/arm/mach-omap2/display.h new file mode 100644 index 0000000..b871b017 --- /dev/null +++ b/arch/arm/mach-omap2/display.h @@ -0,0 +1,29 @@ +/* + * display.h - OMAP2+ integration-specific DSS header + * + * Copyright (C) 2011 Texas Instruments, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#ifndef __ARCH_ARM_MACH_OMAP2_DISPLAY_H +#define __ARCH_ARM_MACH_OMAP2_DISPLAY_H + +#include + +struct omap_dss_dispc_dev_attr { + u8 manager_count; + bool has_framedonetv_irq; +}; + +#endif diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index 74037a5..a5409ce 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -943,6 +943,7 @@ static struct omap_hwmod omap2420_dss_dispc_hwmod = { .slaves = omap2420_dss_dispc_slaves, .slaves_cnt = ARRAY_SIZE(omap2420_dss_dispc_slaves), .flags = HWMOD_NO_IDLEST, + .dev_attr = &omap2_3_dss_dispc_dev_attr }; /* l4_core -> dss_rfbi */ diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index 6f03653..c4f56cb 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -1004,6 +1004,7 @@ static struct omap_hwmod omap2430_dss_dispc_hwmod = { .slaves = omap2430_dss_dispc_slaves, .slaves_cnt = ARRAY_SIZE(omap2430_dss_dispc_slaves), .flags = HWMOD_NO_IDLEST, + .dev_attr = &omap2_3_dss_dispc_dev_attr }; /* l4_core -> dss_rfbi */ diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 4aaf0ca..7f8915a 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1462,6 +1462,7 @@ static struct omap_hwmod omap3xxx_dss_dispc_hwmod = { .slaves = omap3xxx_dss_dispc_slaves, .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_dispc_slaves), .flags = HWMOD_NO_IDLEST, + .dev_attr = &omap2_3_dss_dispc_dev_attr }; /* diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 3b04d63..daaf165 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -1327,6 +1327,11 @@ static struct omap_hwmod_addr_space omap44xx_dss_dispc_addrs[] = { { } }; +static struct omap_dss_dispc_dev_attr omap44xx_dss_dispc_dev_attr = { + .manager_count = 3, + .has_framedonetv_irq = 1 +}; + /* l4_per -> dss_dispc */ static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_dispc = { .master = &omap44xx_l4_per_hwmod, @@ -1357,6 +1362,7 @@ static struct omap_hwmod omap44xx_dss_dispc_hwmod = { }, .slaves = omap44xx_dss_dispc_slaves, .slaves_cnt = ARRAY_SIZE(omap44xx_dss_dispc_slaves), + .dev_attr = &omap44xx_dss_dispc_dev_attr }; /* diff --git a/arch/arm/mach-omap2/omap_hwmod_common_data.c b/arch/arm/mach-omap2/omap_hwmod_common_data.c index de832eb..51e5418 100644 --- a/arch/arm/mach-omap2/omap_hwmod_common_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_common_data.c @@ -49,3 +49,7 @@ struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2 = { .srst_shift = SYSC_TYPE2_SOFTRESET_SHIFT, }; +struct omap_dss_dispc_dev_attr omap2_3_dss_dispc_dev_attr = { + .manager_count = 2, + .has_framedonetv_irq = 0 +}; diff --git a/arch/arm/mach-omap2/omap_hwmod_common_data.h b/arch/arm/mach-omap2/omap_hwmod_common_data.h index 39a7c37..ad5d8f0 100644 --- a/arch/arm/mach-omap2/omap_hwmod_common_data.h +++ b/arch/arm/mach-omap2/omap_hwmod_common_data.h @@ -16,6 +16,8 @@ #include +#include "display.h" + /* Common address space across OMAP2xxx */ extern struct omap_hwmod_addr_space omap2xxx_uart1_addr_space[]; extern struct omap_hwmod_addr_space omap2xxx_uart2_addr_space[]; @@ -111,4 +113,6 @@ extern struct omap_hwmod_class omap2xxx_dma_hwmod_class; extern struct omap_hwmod_class omap2xxx_mailbox_hwmod_class; extern struct omap_hwmod_class omap2xxx_mcspi_class; +extern struct omap_dss_dispc_dev_attr omap2_3_dss_dispc_dev_attr; + #endif -- cgit v1.1 From 35b09c9bf619c4fc6040c52dcea6bd5bd6af7679 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 28 Oct 2011 14:42:41 +0300 Subject: drm/i915: fix if statement (bogus semi-colon) The semi-colon is a typo here and it makes the if statement unconditional. Signed-off-by: Dan Carpenter Signed-off-by: Keith Packard --- drivers/char/agp/intel-gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 66cd0b8..3a8d448 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -1236,7 +1236,7 @@ static int i9xx_setup(void) intel_private.gtt_bus_addr = reg_addr + gtt_offset; } - if (needs_idle_maps()); + if (needs_idle_maps()) intel_private.base.do_idle_maps = 1; intel_i9xx_setup_flush(); -- cgit v1.1 From a08185a3eb658854b29c05bcbfac0f85038ffe9f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 28 Oct 2011 10:28:00 -0700 Subject: agp: iommu_gfx_mapped only available if CONFIG_INTEL_IOMMU is set Kernels with no iommu support cannot ever need the Ironlake work-around, so never enable it in that case. Might be better to completely remove the work-around from the kernel in this case? Signed-off-by: Keith Packard Reviewed-by: Ben Widawsky --- drivers/char/agp/intel-gtt.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 3a8d448..c92424c 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -1186,10 +1186,11 @@ static void gen6_cleanup(void) /* Certain Gen5 chipsets require require idling the GPU before * unmapping anything from the GTT when VT-d is enabled. */ -extern int intel_iommu_gfx_mapped; static inline int needs_idle_maps(void) { +#ifdef CONFIG_INTEL_IOMMU const unsigned short gpu_devid = intel_private.pcidev->device; + extern int intel_iommu_gfx_mapped; /* Query intel_iommu to see if we need the workaround. Presumably that * was loaded first. @@ -1198,7 +1199,7 @@ static inline int needs_idle_maps(void) gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) && intel_iommu_gfx_mapped) return 1; - +#endif return 0; } -- cgit v1.1 From 14660ccd599dc7bd6ecef17408bd76dc853f9b77 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 31 Oct 2011 23:16:21 -0700 Subject: drm/i915: Fix object refcount leak on mmappable size limit error path. I've been seeing memory leaks on my system in the form of large (300-400MB) GEM objects created by now-dead processes laying around clogging up memory. I usually notice when it gets to about 1.2GB of them. Hopefully this clears up the issue, but I just found this bug by inspection. Signed-off-by: Eric Anholt Cc: stable@kernel.org Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/i915_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6651c36..d18b07a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1396,7 +1396,7 @@ i915_gem_mmap_gtt(struct drm_file *file, if (obj->base.size > dev_priv->mm.gtt_mappable_end) { ret = -E2BIG; - goto unlock; + goto out; } if (obj->madv != I915_MADV_WILLNEED) { -- cgit v1.1 From 2c2dd6ac738d8a22def46e073fb7383cac8fa180 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 12 Oct 2011 13:09:53 -0300 Subject: [media] media: vb2: add a check for uninitialized buffer __buffer_in_use() might be called for empty/uninitialized buffer in the following scenario: REQBUF(n, USER_PTR), QUERYBUF(). This patch fixes kernel ops in such case. Signed-off-by: Marek Szyprowski Signed-off-by: Kyungmin Park CC: Pawel Osciak Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videobuf2-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c index 979e544..9bb9214 100644 --- a/drivers/media/video/videobuf2-core.c +++ b/drivers/media/video/videobuf2-core.c @@ -296,14 +296,14 @@ static bool __buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb) { unsigned int plane; for (plane = 0; plane < vb->num_planes; ++plane) { + void *mem_priv = vb->planes[plane].mem_priv; /* * If num_users() has not been provided, call_memop * will return 0, apparently nobody cares about this * case anyway. If num_users() returns more than 1, * we are not the only user of the plane's memory. */ - if (call_memop(q, plane, num_users, - vb->planes[plane].mem_priv) > 1) + if (mem_priv && call_memop(q, plane, num_users, mem_priv) > 1) return true; } return false; -- cgit v1.1 From 4907602f85d454c127d20ac943ead13e2919898d Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 13 Oct 2011 07:07:24 -0300 Subject: [media] media: vb2: set buffer length correctly for all buffer types v4l2_planes[plane].length field was not initialized for userptr buffers. This patch fixes this issue. Signed-off-by: Marek Szyprowski Signed-off-by: Kyungmin Park CC: Pawel Osciak Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videobuf2-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c index 9bb9214..e7c52ff 100644 --- a/drivers/media/video/videobuf2-core.c +++ b/drivers/media/video/videobuf2-core.c @@ -131,6 +131,7 @@ static void __setup_offsets(struct vb2_queue *q, unsigned int n) continue; for (plane = 0; plane < vb->num_planes; ++plane) { + vb->v4l2_planes[plane].length = q->plane_sizes[plane]; vb->v4l2_planes[plane].m.mem_offset = off; dprintk(3, "Buffer %d, plane %d offset 0x%08lx\n", -- cgit v1.1 From bd50d999d4d4f311fda9b777d1e567433cc0f142 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 25 Oct 2011 03:07:59 -0300 Subject: [media] media: vb2: reset queued list on REQBUFS(0) call Queued list was not reset on REQBUFS(0) call. This caused to enqueue a freed buffer to the driver. Reported-by: Angela Wan Signed-off-by: Marek Szyprowski Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videobuf2-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c index e7c52ff..95a3f5e 100644 --- a/drivers/media/video/videobuf2-core.c +++ b/drivers/media/video/videobuf2-core.c @@ -265,6 +265,7 @@ static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers) q->num_buffers -= buffers; if (!q->num_buffers) q->memory = 0; + INIT_LIST_HEAD(&q->queued_list); } /** -- cgit v1.1 From 43defb118247b9c72d53328aa366bdb154d5ee98 Mon Sep 17 00:00:00 2001 From: Kamil Debski Date: Thu, 6 Oct 2011 11:34:05 -0300 Subject: [media] v4l: s5p-mfc: fix reported capabilities MFC uses the multi-plane API, but it reported single-plane when querying capabilities. Signed-off-by: Kamil Debski Signed-off-by: Kyungmin Park Signed-off-by: Marek Szyprowski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s5p-mfc/s5p_mfc_dec.c | 4 ++-- drivers/media/video/s5p-mfc/s5p_mfc_enc.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c index 725634d..844a4d7 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c @@ -220,8 +220,8 @@ static int vidioc_querycap(struct file *file, void *priv, strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1); cap->bus_info[0] = 0; cap->version = KERNEL_VERSION(1, 0, 0); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT - | V4L2_CAP_STREAMING; + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE_MPLANE | + V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_STREAMING; return 0; } diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c index ecef127..1e8cdb7 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c @@ -785,8 +785,8 @@ static int vidioc_querycap(struct file *file, void *priv, strncpy(cap->card, dev->plat_dev->name, sizeof(cap->card) - 1); cap->bus_info[0] = 0; cap->version = KERNEL_VERSION(1, 0, 0); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE - | V4L2_CAP_VIDEO_OUTPUT + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE_MPLANE + | V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_STREAMING; return 0; } -- cgit v1.1 From 60659dd49509f255ad9748411cd4eb3c74a8d8a9 Mon Sep 17 00:00:00 2001 From: Jeongtae Park Date: Fri, 14 Oct 2011 00:03:23 -0300 Subject: [media] MAINTAINERS: add a maintainer for s5p-mfc driver Add a maintainer for s5p-mfc driver. Signed-off-by: Jeongtae Park Acked-by: Marek Szyprowski Acked-by: Kamil Debski Signed-off-by: Mauro Carvalho Chehab --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 5e587fc..e839b95 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1088,6 +1088,7 @@ F: drivers/media/video/s5p-fimc/ ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT M: Kyungmin Park M: Kamil Debski +M: Jeongtae Park L: linux-arm-kernel@lists.infradead.org L: linux-media@vger.kernel.org S: Maintained -- cgit v1.1 From b36b505965e374b284166c2e6b9c1d369d663ea9 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 24 Oct 2011 05:03:27 -0300 Subject: [media] v4l2-event: Deny subscribing with a type of V4L2_EVENT_ALL Signed-off-by: Hans de Goede Acked-by: Laurent Pinchart Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-event.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/media/video/v4l2-event.c b/drivers/media/video/v4l2-event.c index 53b190c..9f56f18 100644 --- a/drivers/media/video/v4l2-event.c +++ b/drivers/media/video/v4l2-event.c @@ -215,6 +215,9 @@ int v4l2_event_subscribe(struct v4l2_fh *fh, unsigned long flags; unsigned i; + if (sub->type == V4L2_EVENT_ALL) + return -EINVAL; + if (elems < 1) elems = 1; if (sub->type == V4L2_EVENT_CTRL) { -- cgit v1.1 From 78c87e863bb3350426fecd14912fd0a546c58ec0 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 26 Oct 2011 05:40:27 -0300 Subject: [media] v4l2-event: Remove pending events from fh event queue when unsubscribing The kev pointers inside the pending events queue (the available queue) of the fh point to data inside the sev, unsubscribing frees the sev, thus making these pointers point to freed memory! This patch fixes these dangling pointers in the available queue by removing all matching pending events on unsubscription. Signed-off-by: Hans de Goede Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-event.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/media/video/v4l2-event.c b/drivers/media/video/v4l2-event.c index 9f56f18..4d01f17 100644 --- a/drivers/media/video/v4l2-event.c +++ b/drivers/media/video/v4l2-event.c @@ -285,6 +285,7 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh, { struct v4l2_subscribed_event *sev; unsigned long flags; + int i; if (sub->type == V4L2_EVENT_ALL) { v4l2_event_unsubscribe_all(fh); @@ -295,6 +296,11 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh, sev = v4l2_event_subscribed(fh, sub->type, sub->id); if (sev != NULL) { + /* Remove any pending events for this subscription */ + for (i = 0; i < sev->in_use; i++) { + list_del(&sev->events[sev_pos(sev, i)].list); + fh->navailable--; + } list_del(&sev->list); sev->fh = NULL; } -- cgit v1.1 From e3e72f39b68ec2563d8ef22f9704a66b7f71b638 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 26 Oct 2011 05:52:47 -0300 Subject: [media] v4l2-event: Don't set sev->fh to NULL on unsubscribe Setting sev->fh to NULL causes problems for the del op added in the next patch of this series, since this op needs a way to get to its own data structures, and typically this will be done by using container_of on an embedded v4l2_fh struct. The reason the original code is setting sev->fh to NULL is to signal to users of the event framework that the unsubscription has happened, but since their is no shared lock between the event framework and users of it, this is inherently racy, and it also turns out to be unnecessary as long as both the event framework and the user of the framework do their own locking properly and the user guarantees that it holds no references to the subcribed_event structure after its del operation has been called. This is best explained by looking at the only code currently checking for sev->fh being set to NULL on unsubscribe, which is the v4l2-ctrls.c send_event function. Here is the relevant code from v4l2-ctrls: send_event(): if (sev->fh && (sev->fh != fh || (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK))) v4l2_event_queue_fh(sev->fh, &ev); Now lets say that v4l2_event_unsubscribe and v4l2-ctrls: send_event() race on the same sev, then the following could happens: 1) send_event checks sev->fh, finds it is not NULL 2) v4l2_event_unsubscribe sets sev->fh NULL 3) v4l2_event_unsubscribe calls v4l2_ctrls del_event function, this blocks as the thread calling send_event holds the ctrl_lock 4) send_event calls v4l2_event_queue_fh(sev->fh, &ev) which not is equivalent to calling: v4l2_event_queue_fh(NULL, &ev) 5) oops, NULL pointer deref. Now again without setting sev->fh to NULL in v4l2_event_unsubscribe and without the (now senseless since always true) sev->fh != NULL check in 1) send_event is about to call v4l2_event_queue_fh(sev->fh, &ev) 2) v4l2_event_unsubscribe removes sev->list from the fh->subscribed list 3) send_event calls v4l2_event_queue_fh(sev->fh, &ev) 4) v4l2_event_queue_fh blocks on the fh_lock spinlock 5) v4l2_event_unsubscribe unlocks the fh_lock spinlock 6) v4l2_event_unsubscribe calls v4l2_ctrls del_event function, this blocks as the thread calling send_event holds the ctrl_lock 8) v4l2_event_queue_fh takes the fh_lock 7) v4l2_event_queue_fh calls v4l2_event_subscribed, does not find it since sev->list has been removed from fh->subscribed already -> does nothing 9) v4l2_event_queue_fh releases the fh_lock 10) the caller of send_event releases the ctrl lock (mutex) 11) v4l2_ctrls del_event takes the ctrl lock 12) v4l2_ctrls del_event removes sev->node from the ev_subs list 13) v4l2_ctrls del_event releases the ctrl lock 14) v4l2_event_unsubscribe frees the sev, to which no references are being held anymore Signed-off-by: Hans de Goede Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-ctrls.c | 4 ++-- drivers/media/video/v4l2-event.c | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c index 5552f81..c58c91b 100644 --- a/drivers/media/video/v4l2-ctrls.c +++ b/drivers/media/video/v4l2-ctrls.c @@ -820,8 +820,8 @@ static void send_event(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 changes) fill_event(&ev, ctrl, changes); list_for_each_entry(sev, &ctrl->ev_subs, node) - if (sev->fh && (sev->fh != fh || - (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK))) + if (sev->fh != fh || + (sev->flags & V4L2_EVENT_SUB_FL_ALLOW_FEEDBACK)) v4l2_event_queue_fh(sev->fh, &ev); } diff --git a/drivers/media/video/v4l2-event.c b/drivers/media/video/v4l2-event.c index 4d01f17..3d93251 100644 --- a/drivers/media/video/v4l2-event.c +++ b/drivers/media/video/v4l2-event.c @@ -302,7 +302,6 @@ int v4l2_event_unsubscribe(struct v4l2_fh *fh, fh->navailable--; } list_del(&sev->list); - sev->fh = NULL; } spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); -- cgit v1.1 From 1249a3a82d08d73ece65ae79e0553cd0f3407a15 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 31 Oct 2011 11:16:44 -0300 Subject: [media] v4l2-ctrl: Send change events to all fh for auto cluster slave controls Otherwise the fh changing the master control won't get the inactive state change event for the slave controls. Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-ctrls.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c index c58c91b..2ece709 100644 --- a/drivers/media/video/v4l2-ctrls.c +++ b/drivers/media/video/v4l2-ctrls.c @@ -946,6 +946,7 @@ static void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, if (ctrl->cluster[0]->has_volatiles) ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; } + fh = NULL; } if (changed || update_inactive) { /* If a control was changed that was not one of the controls -- cgit v1.1 From 617d1017545c27a56229483cc1d689eff6c38561 Mon Sep 17 00:00:00 2001 From: Thomas Jarosch Date: Sat, 29 Oct 2011 15:45:56 +0200 Subject: MIPS: Yosemite, Emma: Fix off-by-two in arcs_cmdline buffer size check Cause is a misplaced bracket. The code strlen(buf+1) will be two bytes less than strlen(buf)+1 The +1 is in this code to reserve space for an additional space character. [ralf@linux-mips.org: Thomas' original patch fixed the issue only for Yosemite but the same bug exists also in Emma.] Signed-off-by: Thomas Jarosch Patchwork: https://patchwork.linux-mips.org/patch/2861/ Signed-off-by: Ralf Baechle --- arch/mips/emma/common/prom.c | 2 +- arch/mips/pmc-sierra/yosemite/prom.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/emma/common/prom.c b/arch/mips/emma/common/prom.c index 708f087..cae4225 100644 --- a/arch/mips/emma/common/prom.c +++ b/arch/mips/emma/common/prom.c @@ -50,7 +50,7 @@ void __init prom_init(void) /* arg[0] is "g", the rest is boot parameters */ for (i = 1; i < argc; i++) { - if (strlen(arcs_cmdline) + strlen(arg[i] + 1) + if (strlen(arcs_cmdline) + strlen(arg[i]) + 1 >= sizeof(arcs_cmdline)) break; strcat(arcs_cmdline, arg[i]); diff --git a/arch/mips/pmc-sierra/yosemite/prom.c b/arch/mips/pmc-sierra/yosemite/prom.c index cf4c868..dcc926e 100644 --- a/arch/mips/pmc-sierra/yosemite/prom.c +++ b/arch/mips/pmc-sierra/yosemite/prom.c @@ -102,7 +102,7 @@ void __init prom_init(void) /* Get the boot parameters */ for (i = 1; i < argc; i++) { - if (strlen(arcs_cmdline) + strlen(arg[i] + 1) >= + if (strlen(arcs_cmdline) + strlen(arg[i]) + 1 >= sizeof(arcs_cmdline)) break; -- cgit v1.1 From 798580815126c899616146f286d5cc259abb5e16 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 4 Nov 2011 10:45:57 +0000 Subject: MIPS: NXP: Remove unused source files. The NXP code was moved for 2.6.36 but two files survived unused in the old location. Signed-off-by: Ralf Baechle --- arch/mips/nxp/pnx8550/common/pci.c | 134 -------------------------------- arch/mips/nxp/pnx8550/common/setup.c | 143 ----------------------------------- 2 files changed, 277 deletions(-) delete mode 100644 arch/mips/nxp/pnx8550/common/pci.c delete mode 100644 arch/mips/nxp/pnx8550/common/setup.c diff --git a/arch/mips/nxp/pnx8550/common/pci.c b/arch/mips/nxp/pnx8550/common/pci.c deleted file mode 100644 index 98e86dd..0000000 --- a/arch/mips/nxp/pnx8550/common/pci.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * - * BRIEF MODULE DESCRIPTION - * - * Author: source@mvista.com - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - */ -#include -#include -#include -#include - -#include -#include -#include - -static struct resource pci_io_resource = { - .start = PNX8550_PCIIO + 0x1000, /* reserve regacy I/O space */ - .end = PNX8550_PCIIO + PNX8550_PCIIO_SIZE, - .name = "pci IO space", - .flags = IORESOURCE_IO -}; - -static struct resource pci_mem_resource = { - .start = PNX8550_PCIMEM, - .end = PNX8550_PCIMEM + PNX8550_PCIMEM_SIZE - 1, - .name = "pci memory space", - .flags = IORESOURCE_MEM -}; - -extern struct pci_ops pnx8550_pci_ops; - -static struct pci_controller pnx8550_controller = { - .pci_ops = &pnx8550_pci_ops, - .io_map_base = PNX8550_PORT_BASE, - .io_resource = &pci_io_resource, - .mem_resource = &pci_mem_resource, -}; - -/* Return the total size of DRAM-memory, (RANK0 + RANK1) */ -static inline unsigned long get_system_mem_size(void) -{ - /* Read IP2031_RANK0_ADDR_LO */ - unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010); - /* Read IP2031_RANK1_ADDR_HI */ - unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018); - - return dram_r1_hi - dram_r0_lo + 1; -} - -static int __init pnx8550_pci_setup(void) -{ - int pci_mem_code; - int mem_size = get_system_mem_size() >> 20; - - /* Clear the Global 2 Register, PCI Inta Output Enable Registers - Bit 1:Enable DAC Powerdown - -> 0:DACs are enabled and are working normally - 1:DACs are powerdown - Bit 0:Enable of PCI inta output - -> 0 = Disable PCI inta output - 1 = Enable PCI inta output - */ - PNX8550_GLB2_ENAB_INTA_O = 0; - - /* Calc the PCI mem size code */ - if (mem_size >= 128) - pci_mem_code = SIZE_128M; - else if (mem_size >= 64) - pci_mem_code = SIZE_64M; - else if (mem_size >= 32) - pci_mem_code = SIZE_32M; - else - pci_mem_code = SIZE_16M; - - /* Set PCI_XIO registers */ - outl(pci_mem_resource.start, PCI_BASE | PCI_BASE1_LO); - outl(pci_mem_resource.end + 1, PCI_BASE | PCI_BASE1_HI); - outl(pci_io_resource.start, PCI_BASE | PCI_BASE2_LO); - outl(pci_io_resource.end, PCI_BASE | PCI_BASE2_HI); - - /* Send memory transaction via PCI_BASE2 */ - outl(0x00000001, PCI_BASE | PCI_IO); - - /* Unlock the setup register */ - outl(0xca, PCI_BASE | PCI_UNLOCKREG); - - /* - * BAR0 of PNX8550 (pci base 10) must be zero in order for ide - * to work, and in order for bus_to_baddr to work without any - * hacks. - */ - outl(0x00000000, PCI_BASE | PCI_BASE10); - - /* - *These two bars are set by default or the boot code. - * However, it's safer to set them here so we're not boot - * code dependent. - */ - outl(0x1be00000, PCI_BASE | PCI_BASE14); /* PNX MMIO */ - outl(PNX8550_NAND_BASE_ADDR, PCI_BASE | PCI_BASE18); /* XIO */ - - outl(PCI_EN_TA | - PCI_EN_PCI2MMI | - PCI_EN_XIO | - PCI_SETUP_BASE18_SIZE(SIZE_32M) | - PCI_SETUP_BASE18_EN | - PCI_SETUP_BASE14_EN | - PCI_SETUP_BASE10_PREF | - PCI_SETUP_BASE10_SIZE(pci_mem_code) | - PCI_SETUP_CFGMANAGE_EN | - PCI_SETUP_PCIARB_EN, - PCI_BASE | - PCI_SETUP); /* PCI_SETUP */ - outl(0x00000000, PCI_BASE | PCI_CTRL); /* PCI_CONTROL */ - - register_pci_controller(&pnx8550_controller); - - return 0; -} - -arch_initcall(pnx8550_pci_setup); diff --git a/arch/mips/nxp/pnx8550/common/setup.c b/arch/mips/nxp/pnx8550/common/setup.c deleted file mode 100644 index 71adac3..0000000 --- a/arch/mips/nxp/pnx8550/common/setup.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * - * 2.6 port, Embedded Alley Solutions, Inc - * - * Based on Per Hallsmark, per.hallsmark@mvista.com - * - * This program is free software; you can distribute it and/or modify it - * under the terms of the GNU General Public License (Version 2) as - * published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -extern void __init board_setup(void); -extern void pnx8550_machine_restart(char *); -extern void pnx8550_machine_halt(void); -extern void pnx8550_machine_power_off(void); -extern struct resource ioport_resource; -extern struct resource iomem_resource; -extern char *prom_getcmdline(void); - -struct resource standard_io_resources[] = { - { - .start = 0x00, - .end = 0x1f, - .name = "dma1", - .flags = IORESOURCE_BUSY - }, { - .start = 0x40, - .end = 0x5f, - .name = "timer", - .flags = IORESOURCE_BUSY - }, { - .start = 0x80, - .end = 0x8f, - .name = "dma page reg", - .flags = IORESOURCE_BUSY - }, { - .start = 0xc0, - .end = 0xdf, - .name = "dma2", - .flags = IORESOURCE_BUSY - }, -}; - -#define STANDARD_IO_RESOURCES ARRAY_SIZE(standard_io_resources) - -extern struct resource pci_io_resource; -extern struct resource pci_mem_resource; - -/* Return the total size of DRAM-memory, (RANK0 + RANK1) */ -unsigned long get_system_mem_size(void) -{ - /* Read IP2031_RANK0_ADDR_LO */ - unsigned long dram_r0_lo = inl(PCI_BASE | 0x65010); - /* Read IP2031_RANK1_ADDR_HI */ - unsigned long dram_r1_hi = inl(PCI_BASE | 0x65018); - - return dram_r1_hi - dram_r0_lo + 1; -} - -int pnx8550_console_port = -1; - -void __init plat_mem_setup(void) -{ - int i; - char* argptr; - - board_setup(); /* board specific setup */ - - _machine_restart = pnx8550_machine_restart; - _machine_halt = pnx8550_machine_halt; - pm_power_off = pnx8550_machine_power_off; - - /* Clear the Global 2 Register, PCI Inta Output Enable Registers - Bit 1:Enable DAC Powerdown - -> 0:DACs are enabled and are working normally - 1:DACs are powerdown - Bit 0:Enable of PCI inta output - -> 0 = Disable PCI inta output - 1 = Enable PCI inta output - */ - PNX8550_GLB2_ENAB_INTA_O = 0; - - /* IO/MEM resources. */ - set_io_port_base(PNX8550_PORT_BASE); - ioport_resource.start = 0; - ioport_resource.end = ~0; - iomem_resource.start = 0; - iomem_resource.end = ~0; - - /* Request I/O space for devices on this board */ - for (i = 0; i < STANDARD_IO_RESOURCES; i++) - request_resource(&ioport_resource, standard_io_resources + i); - - /* Place the Mode Control bit for GPIO pin 16 in primary function */ - /* Pin 16 is used by UART1, UA1_TX */ - outl((PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_16_BIT) | - (PNX8550_GPIO_MODE_PRIMOP << PNX8550_GPIO_MC_17_BIT), - PNX8550_GPIO_MC1); - - argptr = prom_getcmdline(); - if ((argptr = strstr(argptr, "console=ttyS")) != NULL) { - argptr += strlen("console=ttyS"); - pnx8550_console_port = *argptr == '0' ? 0 : 1; - - /* We must initialize the UART (console) before early printk */ - /* Set LCR to 8-bit and BAUD to 38400 (no 5) */ - ip3106_lcr(UART_BASE, pnx8550_console_port) = - PNX8XXX_UART_LCR_8BIT; - ip3106_baud(UART_BASE, pnx8550_console_port) = 5; - } -} -- cgit v1.1 From df55a66addf87bc21ef5678bea238f2c1b2db48a Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 4 Nov 2011 11:17:46 +0100 Subject: MIPS: BCM47xx: fix build with GENERIC_GPIO configuration Since eb9ae7f2 (gpio: fix build error in include/asm-generic/gpio.h) the generic version of gpio.h calls __gpio_{set,get}_value which we do not define. Get rid of asm-generic/gpio.h and define the missing stubs directly for BCM47xx to build. Reported-by: Ralf Baechle To: linux-mips@linux-mips.org CC: Hauke Mehrtens Signed-off-by: Florian Fainelli Patchwork: https://patchwork.linux-mips.org/patch/2885/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-bcm47xx/gpio.h | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/arch/mips/include/asm/mach-bcm47xx/gpio.h b/arch/mips/include/asm/mach-bcm47xx/gpio.h index 76961ca..2ef17e8 100644 --- a/arch/mips/include/asm/mach-bcm47xx/gpio.h +++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h @@ -36,6 +36,8 @@ static inline int gpio_get_value(unsigned gpio) return -EINVAL; } +#define gpio_get_value_cansleep gpio_get_value + static inline void gpio_set_value(unsigned gpio, int value) { switch (bcm47xx_bus_type) { @@ -54,6 +56,19 @@ static inline void gpio_set_value(unsigned gpio, int value) } } +#define gpio_set_value_cansleep gpio_set_value + +static inline int gpio_cansleep(unsigned gpio) +{ + return 0; +} + +static inline int gpio_is_valid(unsigned gpio) +{ + return gpio < (BCM47XX_EXTIF_GPIO_LINES + BCM47XX_CHIPCO_GPIO_LINES); +} + + static inline int gpio_direction_input(unsigned gpio) { switch (bcm47xx_bus_type) { @@ -137,7 +152,4 @@ static inline int gpio_polarity(unsigned gpio, int value) } -/* cansleep wrappers */ -#include - #endif /* __BCM47XX_GPIO_H */ -- cgit v1.1 From e63fb7a9dae820b3ff6754f794fd713f83e32fff Mon Sep 17 00:00:00 2001 From: Venkat Subbiah Date: Mon, 3 Oct 2011 13:31:10 -0700 Subject: MIPS: Octeon: Mark SMP-IPI interrupt as IRQF_NO_THREAD This is to exclude it from force threading to allow RT patch set to work. And while on this line * Remove IRQF_DISABLED as as this flag is NOOP * Add IRQF_PERCPU as this is a per cpu interrupt. Signed-off-by: Venkat Subbiah Acked-by: David Daney To: linux-mips@linux-mips.org To: linux-rt-users@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/2817/ Acked-by: Thomas Gleixner Signed-off-by: Ralf Baechle --- arch/mips/cavium-octeon/smp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index 8b60642..efcfff4 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c @@ -207,8 +207,9 @@ void octeon_prepare_cpus(unsigned int max_cpus) * the other bits alone. */ cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()), 0xffff); - if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt, IRQF_DISABLED, - "SMP-IPI", mailbox_interrupt)) { + if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt, + IRQF_PERCPU | IRQF_NO_THREAD, "SMP-IPI", + mailbox_interrupt)) { panic("Cannot request_irq(OCTEON_IRQ_MBOX0)\n"); } } -- cgit v1.1 From e94e05eae9a56e4fad93f18a63ae90e7ff02b576 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Tue, 8 Nov 2011 21:57:59 +0800 Subject: arm/mxs: fix mmc device adding for mach-mx28evk The merge commit "526b264 Merge branch 'imx/cleanup' into imx/devel" left a duplicated mx28_add_mxs_mmc() call, which causes the problem below during boot. kobject_add_internal failed for mxs-mmc.1 with -EEXIST, don't try to register things with the same name in the same directory. The patch removes this leftover and also change mmc0 adding to align with mmc1. Signed-off-by: Shawn Guo --- arch/arm/mach-mxs/mach-mx28evk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c index ac2316d..064ec5a 100644 --- a/arch/arm/mach-mxs/mach-mx28evk.c +++ b/arch/arm/mach-mxs/mach-mx28evk.c @@ -471,7 +471,8 @@ static void __init mx28evk_init(void) "mmc0-slot-power"); if (ret) pr_warn("failed to request gpio mmc0-slot-power: %d\n", ret); - mx28_add_mxs_mmc(0, &mx28evk_mmc_pdata[0]); + else + mx28_add_mxs_mmc(0, &mx28evk_mmc_pdata[0]); ret = gpio_request_one(MX28EVK_MMC1_SLOT_POWER, GPIOF_OUT_INIT_LOW, "mmc1-slot-power"); @@ -480,7 +481,6 @@ static void __init mx28evk_init(void) else mx28_add_mxs_mmc(1, &mx28evk_mmc_pdata[1]); - mx28_add_mxs_mmc(1, &mx28evk_mmc_pdata[1]); mx28_add_rtc_stmp3xxx(); gpio_led_register_device(0, &mx28evk_led_data); -- cgit v1.1 From d13431ca3eb2a2c14314f04813cdc11cd869f150 Mon Sep 17 00:00:00 2001 From: Wen-chien Jesse Sung Date: Tue, 8 Nov 2011 14:30:22 +0800 Subject: Bluetooth: Add support for Broadcom BCM20702A0 Since this device declares itself as vendor specific, must add a new entry to device ID table to support it. usb-device output of this device: T: Bus=01 Lev=02 Prnt=02 Port=03 Cnt=01 Dev#= 3 Spd=12 MxCh= 0 D: Ver= 2.00 Cls=ff(vend.) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=413c ProdID=8197 Rev=01.12 S: Manufacturer=Broadcom Corp S: Product=BCM20702A0 S: SerialNumber=D0DF9AA9C9F1 C: #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=0mA I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none) I: If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none) I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) I: If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none) Signed-off-by: Wen-chien Jesse Sung Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/btusb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index f9b7260..fe4ebc3 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -100,6 +100,9 @@ static struct usb_device_id btusb_table[] = { /* Canyon CN-BTU1 with HID interfaces */ { USB_DEVICE(0x0c10, 0x0000) }, + /* Broadcom BCM20702A0 */ + { USB_DEVICE(0x413c, 0x8197) }, + { } /* Terminating entry */ }; -- cgit v1.1 From 66f5ddf30a59f811818656cb2833c80da0340cfa Mon Sep 17 00:00:00 2001 From: "Luck, Tony" Date: Thu, 3 Nov 2011 11:46:47 -0700 Subject: x86/mce: Make mce_chrdev_ops 'static const' Arjan would like to make struct file_operations const, but mce-inject directly writes to the mce_chrdev_ops to install its write handler. In an ideal world mce-inject would have its own character device, but we have a sizable legacy of test scripts that hardwire "/dev/mcelog", so it would be painful to switch to a separate device now. Instead, this patch switches to a stub function in the mce code, with a registration helper that mce-inject can call when it is loaded. Note that this would also allow for a sane process to allow mce-inject to be unloaded again (with an unregister function, and appropriate module_{get,put}() calls), but that is left for potential future patches. Reported-by: Arjan van de Ven Signed-off-by: Tony Luck Link: http://lkml.kernel.org/r/4eb2e1971326651a3b@agluck-desktop.sc.intel.com Signed-off-by: Ingo Molnar --- arch/x86/include/asm/mce.h | 5 ++++- arch/x86/kernel/cpu/mcheck/mce-inject.c | 2 +- arch/x86/kernel/cpu/mcheck/mce.c | 25 ++++++++++++++++++++++--- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index c9321f3..0e8ae57 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h @@ -201,7 +201,10 @@ int mce_notify_irq(void); void mce_notify_process(void); DECLARE_PER_CPU(struct mce, injectm); -extern struct file_operations mce_chrdev_ops; + +extern void register_mce_write_callback(ssize_t (*)(struct file *filp, + const char __user *ubuf, + size_t usize, loff_t *off)); /* * Exception handler diff --git a/arch/x86/kernel/cpu/mcheck/mce-inject.c b/arch/x86/kernel/cpu/mcheck/mce-inject.c index 6199232..319882e 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-inject.c +++ b/arch/x86/kernel/cpu/mcheck/mce-inject.c @@ -208,7 +208,7 @@ static int inject_init(void) if (!alloc_cpumask_var(&mce_inject_cpumask, GFP_KERNEL)) return -ENOMEM; printk(KERN_INFO "Machine check injector initialized\n"); - mce_chrdev_ops.write = mce_write; + register_mce_write_callback(mce_write); register_nmi_handler(NMI_LOCAL, mce_raise_notify, 0, "mce_notify"); return 0; diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 362056a..2af127d 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -1634,16 +1634,35 @@ static long mce_chrdev_ioctl(struct file *f, unsigned int cmd, } } -/* Modified in mce-inject.c, so not static or const */ -struct file_operations mce_chrdev_ops = { +static ssize_t (*mce_write)(struct file *filp, const char __user *ubuf, + size_t usize, loff_t *off); + +void register_mce_write_callback(ssize_t (*fn)(struct file *filp, + const char __user *ubuf, + size_t usize, loff_t *off)) +{ + mce_write = fn; +} +EXPORT_SYMBOL_GPL(register_mce_write_callback); + +ssize_t mce_chrdev_write(struct file *filp, const char __user *ubuf, + size_t usize, loff_t *off) +{ + if (mce_write) + return mce_write(filp, ubuf, usize, off); + else + return -EINVAL; +} + +static const struct file_operations mce_chrdev_ops = { .open = mce_chrdev_open, .release = mce_chrdev_release, .read = mce_chrdev_read, + .write = mce_chrdev_write, .poll = mce_chrdev_poll, .unlocked_ioctl = mce_chrdev_ioctl, .llseek = no_llseek, }; -EXPORT_SYMBOL_GPL(mce_chrdev_ops); static struct miscdevice mce_chrdev_device = { MISC_MCELOG_MINOR, -- cgit v1.1 From f1e10354fc2a12773e5e8efcf841380aa57d4aa5 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 5 Nov 2011 14:47:19 +0800 Subject: ASoC: wm9081: Fix reading wrong register for setting VMID 2*240k VMID Divider Enable and Select is controlled by BIT[2:1] of WM9081_VMID_CONTROL register (04h). Current code reads wrong register (WM9081_BIAS_CONTROL_1) for setting VMID 2*240k. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- sound/soc/codecs/wm9081.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index 3cd35a0..fe65618 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -818,7 +818,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec, } /* VMID 2*240k */ - reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); + reg = snd_soc_read(codec, WM9081_VMID_CONTROL); reg &= ~WM9081_VMID_SEL_MASK; reg |= 0x04; snd_soc_write(codec, WM9081_VMID_CONTROL, reg); -- cgit v1.1 From adf463626ad8e0a2cdbe17d8bb64c1d9d0ac160d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 5 Nov 2011 14:49:21 +0800 Subject: ASoC: wm9081: Don't write WM9081_BIAS_ENA bit to WM9081_VMID_CONTROL register WM9081_BIAS_ENA is the bit[1] of WM9081_BIAS_CONTROL_1 register (05h). Current code incorrectly write it to WM9081_VMID_CONTROL(04h) register. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- sound/soc/codecs/wm9081.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index fe65618..4a398c3 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -807,7 +807,6 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec, mdelay(100); /* Normal bias enable & soft start off */ - reg |= WM9081_BIAS_ENA; reg &= ~WM9081_VMID_RAMP; snd_soc_write(codec, WM9081_VMID_CONTROL, reg); @@ -830,14 +829,15 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_OFF: - /* Startup bias source */ + /* Startup bias source and disable bias */ reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); reg |= WM9081_BIAS_SRC; + reg &= ~WM9081_BIAS_ENA; snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg); - /* Disable VMID and biases with soft ramping */ + /* Disable VMID with soft ramping */ reg = snd_soc_read(codec, WM9081_VMID_CONTROL); - reg &= ~(WM9081_VMID_SEL_MASK | WM9081_BIAS_ENA); + reg &= ~WM9081_VMID_SEL_MASK; reg |= WM9081_VMID_RAMP; snd_soc_write(codec, WM9081_VMID_CONTROL, reg); -- cgit v1.1 From 08f2e6312c67fed80df9342e06ad36daf11eb80b Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Tue, 8 Nov 2011 18:29:15 +0800 Subject: iommu: omap: Fix compile failure Fix compile failure in drivers/iommu/omap-iommu-debug.c because of missing module.h include. Signed-off-by: Ming Lei Signed-off-by: Joerg Roedel --- drivers/iommu/omap-iommu-debug.c | 1 + drivers/iommu/omap-iovmm.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c index 9c192e7..288da5c 100644 --- a/drivers/iommu/omap-iommu-debug.c +++ b/drivers/iommu/omap-iommu-debug.c @@ -10,6 +10,7 @@ * published by the Free Software Foundation. */ +#include #include #include #include diff --git a/drivers/iommu/omap-iovmm.c b/drivers/iommu/omap-iovmm.c index e8fdb88..46be456 100644 --- a/drivers/iommu/omap-iovmm.c +++ b/drivers/iommu/omap-iovmm.c @@ -10,6 +10,7 @@ * published by the Free Software Foundation. */ +#include #include #include #include -- cgit v1.1 From b52a360b2aa1c59ba9970fb0f52bbb093fcc7a24 Mon Sep 17 00:00:00 2001 From: Carlos Maiolino Date: Mon, 7 Nov 2011 16:10:24 +0000 Subject: xfs: Fix possible memory corruption in xfs_readlink Fixes a possible memory corruption when the link is larger than MAXPATHLEN and XFS_DEBUG is not enabled. This also remove the S_ISLNK assert, since the inode mode is checked previously in xfs_readlink_by_handle() and via VFS. Updated to address concerns raised by Ben Hutchings about the loose attention paid to 32- vs 64-bit values, and the lack of handling a potentially negative pathlen value: - Changed type of "pathlen" to be xfs_fsize_t, to match that of ip->i_d.di_size - Added checking for a negative pathlen to the too-long pathlen test, and generalized the message that gets reported in that case to reflect the change As a result, if a negative pathlen were encountered, this function would return EFSCORRUPTED (and would fail an assertion for a debug build)--just as would a too-long pathlen. Signed-off-by: Alex Elder Signed-off-by: Carlos Maiolino Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_vnodeops.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 4ecf2a5..ce9268a 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -112,7 +112,7 @@ xfs_readlink( char *link) { xfs_mount_t *mp = ip->i_mount; - int pathlen; + xfs_fsize_t pathlen; int error = 0; trace_xfs_readlink(ip); @@ -122,13 +122,19 @@ xfs_readlink( xfs_ilock(ip, XFS_ILOCK_SHARED); - ASSERT(S_ISLNK(ip->i_d.di_mode)); - ASSERT(ip->i_d.di_size <= MAXPATHLEN); - pathlen = ip->i_d.di_size; if (!pathlen) goto out; + if (pathlen < 0 || pathlen > MAXPATHLEN) { + xfs_alert(mp, "%s: inode (%llu) bad symlink length (%lld)", + __func__, (unsigned long long) ip->i_ino, + (long long) pathlen); + ASSERT(0); + return XFS_ERROR(EFSCORRUPTED); + } + + if (ip->i_df.if_flags & XFS_IFINLINE) { memcpy(link, ip->i_df.if_u1.if_data, pathlen); link[pathlen] = '\0'; -- cgit v1.1 From 272e42b215c52d32e06bf035c1f6b70baa6716bd Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 28 Oct 2011 09:54:24 +0000 Subject: xfs: constify xfs_item_ops The log item ops aren't nessecarily the biggest exploit vector, but marking them const is easy enough. Also remove the unused xfs_item_ops_t typedef while we're at it. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Reviewed-by: Alex Elder --- fs/xfs/xfs_buf_item.c | 2 +- fs/xfs/xfs_dquot_item.c | 6 +++--- fs/xfs/xfs_extfree_item.c | 4 ++-- fs/xfs/xfs_inode_item.c | 2 +- fs/xfs/xfs_log.c | 2 +- fs/xfs/xfs_log.h | 2 +- fs/xfs/xfs_trans.h | 6 +++--- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 1a35138..eac97ef 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -656,7 +656,7 @@ xfs_buf_item_committing( /* * This is the ops vector shared by all buf log items. */ -static struct xfs_item_ops xfs_buf_item_ops = { +static const struct xfs_item_ops xfs_buf_item_ops = { .iop_size = xfs_buf_item_size, .iop_format = xfs_buf_item_format, .iop_pin = xfs_buf_item_pin, diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c index bb3f71d..0dee0b7 100644 --- a/fs/xfs/xfs_dquot_item.c +++ b/fs/xfs/xfs_dquot_item.c @@ -295,7 +295,7 @@ xfs_qm_dquot_logitem_committing( /* * This is the ops vector for dquots */ -static struct xfs_item_ops xfs_dquot_item_ops = { +static const struct xfs_item_ops xfs_dquot_item_ops = { .iop_size = xfs_qm_dquot_logitem_size, .iop_format = xfs_qm_dquot_logitem_format, .iop_pin = xfs_qm_dquot_logitem_pin, @@ -483,7 +483,7 @@ xfs_qm_qoff_logitem_committing( { } -static struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { +static const struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { .iop_size = xfs_qm_qoff_logitem_size, .iop_format = xfs_qm_qoff_logitem_format, .iop_pin = xfs_qm_qoff_logitem_pin, @@ -498,7 +498,7 @@ static struct xfs_item_ops xfs_qm_qoffend_logitem_ops = { /* * This is the ops vector shared by all quotaoff-start log items. */ -static struct xfs_item_ops xfs_qm_qoff_logitem_ops = { +static const struct xfs_item_ops xfs_qm_qoff_logitem_ops = { .iop_size = xfs_qm_qoff_logitem_size, .iop_format = xfs_qm_qoff_logitem_format, .iop_pin = xfs_qm_qoff_logitem_pin, diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index d22e626..35c2aff 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c @@ -217,7 +217,7 @@ xfs_efi_item_committing( /* * This is the ops vector shared by all efi log items. */ -static struct xfs_item_ops xfs_efi_item_ops = { +static const struct xfs_item_ops xfs_efi_item_ops = { .iop_size = xfs_efi_item_size, .iop_format = xfs_efi_item_format, .iop_pin = xfs_efi_item_pin, @@ -477,7 +477,7 @@ xfs_efd_item_committing( /* * This is the ops vector shared by all efd log items. */ -static struct xfs_item_ops xfs_efd_item_ops = { +static const struct xfs_item_ops xfs_efd_item_ops = { .iop_size = xfs_efd_item_size, .iop_format = xfs_efd_item_format, .iop_pin = xfs_efd_item_pin, diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index b7cf21b..abaafdb 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -795,7 +795,7 @@ xfs_inode_item_committing( /* * This is the ops vector shared by all buf log items. */ -static struct xfs_item_ops xfs_inode_item_ops = { +static const struct xfs_item_ops xfs_inode_item_ops = { .iop_size = xfs_inode_item_size, .iop_format = xfs_inode_item_format, .iop_pin = xfs_inode_item_pin, diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 2758a62..a14cd89 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -626,7 +626,7 @@ xfs_log_item_init( struct xfs_mount *mp, struct xfs_log_item *item, int type, - struct xfs_item_ops *ops) + const struct xfs_item_ops *ops) { item->li_mountp = mp; item->li_ailp = mp->m_ail; diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h index 78c9039..3f7bf45 100644 --- a/fs/xfs/xfs_log.h +++ b/fs/xfs/xfs_log.h @@ -137,7 +137,7 @@ struct xfs_trans; void xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item, int type, - struct xfs_item_ops *ops); + const struct xfs_item_ops *ops); xfs_lsn_t xfs_log_done(struct xfs_mount *mp, struct xlog_ticket *ticket, diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 603f3eb..3ae713c 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -326,7 +326,7 @@ typedef struct xfs_log_item { struct xfs_log_item *); /* buffer item iodone */ /* callback func */ - struct xfs_item_ops *li_ops; /* function list */ + const struct xfs_item_ops *li_ops; /* function list */ /* delayed logging */ struct list_head li_cil; /* CIL pointers */ @@ -341,7 +341,7 @@ typedef struct xfs_log_item { { XFS_LI_IN_AIL, "IN_AIL" }, \ { XFS_LI_ABORTED, "ABORTED" } -typedef struct xfs_item_ops { +struct xfs_item_ops { uint (*iop_size)(xfs_log_item_t *); void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *); void (*iop_pin)(xfs_log_item_t *); @@ -352,7 +352,7 @@ typedef struct xfs_item_ops { void (*iop_push)(xfs_log_item_t *); bool (*iop_pushbuf)(xfs_log_item_t *); void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t); -} xfs_item_ops_t; +}; #define IOP_SIZE(ip) (*(ip)->li_ops->iop_size)(ip) #define IOP_FORMAT(ip,vp) (*(ip)->li_ops->iop_format)(ip, vp) -- cgit v1.1 From 810627d9a6d0e8820c798001875bc4e1b7754ebf Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 8 Nov 2011 08:56:15 +0000 Subject: xfs: fix force shutdown handling in xfs_end_io Ensure ioend->io_error gets propagated back to e.g. AIO completions. Signed-off-by: Christoph Hellwig Reviewed-by: Alex Elder --- fs/xfs/xfs_aops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 33b1331..574d4ee 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -189,7 +189,7 @@ xfs_end_io( int error = 0; if (XFS_FORCED_SHUTDOWN(ip->i_mount)) { - error = -EIO; + ioend->io_error = -EIO; goto done; } if (ioend->io_error) -- cgit v1.1 From dcaaf9f2c16b56f8bb316881fcd3f15c18fc71e7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 8 Nov 2011 17:50:27 +0100 Subject: ALSA: usb-audio - Fix the missing volume quirks at delayed init In the recent usb-audio driver, the initialization of volume ranges may be delayed when the device doesn't respond well at the probing time. But the volume quirks for certain devices are applied only in mixer_ctl_feature_info() thus only at the very first probe and will be missing when the volume range is initialized later. This patch moves the volume quirk code to be always called from the volume-range extraction (get_min_max()), so that the quirks are properly applied in the later init time. Reported-and-tested-by: Alexey Fisher Cc: Signed-off-by: Takashi Iwai --- sound/usb/mixer.c | 109 +++++++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 50 deletions(-) diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 60f65ac..c5444e0 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -765,10 +765,60 @@ static void usb_mixer_elem_free(struct snd_kcontrol *kctl) * interface to ALSA control for feature/mixer units */ +/* volume control quirks */ +static void volume_control_quirks(struct usb_mixer_elem_info *cval, + struct snd_kcontrol *kctl) +{ + switch (cval->mixer->chip->usb_id) { + case USB_ID(0x0471, 0x0101): + case USB_ID(0x0471, 0x0104): + case USB_ID(0x0471, 0x0105): + case USB_ID(0x0672, 0x1041): + /* quirk for UDA1321/N101. + * note that detection between firmware 2.1.1.7 (N101) + * and later 2.1.1.21 is not very clear from datasheets. + * I hope that the min value is -15360 for newer firmware --jk + */ + if (!strcmp(kctl->id.name, "PCM Playback Volume") && + cval->min == -15616) { + snd_printk(KERN_INFO + "set volume quirk for UDA1321/N101 chip\n"); + cval->max = -256; + } + break; + + case USB_ID(0x046d, 0x09a4): + if (!strcmp(kctl->id.name, "Mic Capture Volume")) { + snd_printk(KERN_INFO + "set volume quirk for QuickCam E3500\n"); + cval->min = 6080; + cval->max = 8768; + cval->res = 192; + } + break; + + case USB_ID(0x046d, 0x0808): + case USB_ID(0x046d, 0x0809): + case USB_ID(0x046d, 0x0991): + /* Most audio usb devices lie about volume resolution. + * Most Logitech webcams have res = 384. + * Proboly there is some logitech magic behind this number --fishor + */ + if (!strcmp(kctl->id.name, "Mic Capture Volume")) { + snd_printk(KERN_INFO + "set resolution quirk: cval->res = 384\n"); + cval->res = 384; + } + break; + + } +} + /* * retrieve the minimum and maximum values for the specified control */ -static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) +static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval, + int default_min, struct snd_kcontrol *kctl) { /* for failsafe */ cval->min = default_min; @@ -844,6 +894,9 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) cval->initialized = 1; } + if (kctl) + volume_control_quirks(cval, kctl); + /* USB descriptions contain the dB scale in 1/256 dB unit * while ALSA TLV contains in 1/100 dB unit */ @@ -864,6 +917,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) return 0; } +#define get_min_max(cval, def) get_min_max_with_quirks(cval, def, NULL) /* get a feature/mixer unit info */ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) @@ -882,7 +936,7 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ uinfo->value.integer.max = 1; } else { if (!cval->initialized) { - get_min_max(cval, 0); + get_min_max_with_quirks(cval, 0, kcontrol); if (cval->initialized && cval->dBmin >= cval->dBmax) { kcontrol->vd[0].access &= ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ | @@ -1045,9 +1099,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, cval->ch_readonly = readonly_mask; } - /* get min/max values */ - get_min_max(cval, 0); - /* if all channels in the mask are marked read-only, make the control * read-only. set_cur_mix_value() will check the mask again and won't * issue write commands to read-only channels. */ @@ -1069,6 +1120,9 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name)); + /* get min/max values */ + get_min_max_with_quirks(cval, 0, kctl); + switch (control) { case UAC_FU_MUTE: case UAC_FU_VOLUME: @@ -1118,51 +1172,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, break; } - /* volume control quirks */ - switch (state->chip->usb_id) { - case USB_ID(0x0471, 0x0101): - case USB_ID(0x0471, 0x0104): - case USB_ID(0x0471, 0x0105): - case USB_ID(0x0672, 0x1041): - /* quirk for UDA1321/N101. - * note that detection between firmware 2.1.1.7 (N101) - * and later 2.1.1.21 is not very clear from datasheets. - * I hope that the min value is -15360 for newer firmware --jk - */ - if (!strcmp(kctl->id.name, "PCM Playback Volume") && - cval->min == -15616) { - snd_printk(KERN_INFO - "set volume quirk for UDA1321/N101 chip\n"); - cval->max = -256; - } - break; - - case USB_ID(0x046d, 0x09a4): - if (!strcmp(kctl->id.name, "Mic Capture Volume")) { - snd_printk(KERN_INFO - "set volume quirk for QuickCam E3500\n"); - cval->min = 6080; - cval->max = 8768; - cval->res = 192; - } - break; - - case USB_ID(0x046d, 0x0808): - case USB_ID(0x046d, 0x0809): - case USB_ID(0x046d, 0x0991): - /* Most audio usb devices lie about volume resolution. - * Most Logitech webcams have res = 384. - * Proboly there is some logitech magic behind this number --fishor - */ - if (!strcmp(kctl->id.name, "Mic Capture Volume")) { - snd_printk(KERN_INFO - "set resolution quirk: cval->res = 384\n"); - cval->res = 384; - } - break; - - } - range = (cval->max - cval->min) / cval->res; /* Are there devices with volume range more than 255? I use a bit more * to be sure. 384 is a resolution magic number found on Logitech -- cgit v1.1 From eca55f4d9c1d918c2aa95fb8a73a34e2ba8a1b11 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 8 Nov 2011 13:07:36 +0000 Subject: ARM: msm: fix compilation flags for MSM_SCM CONFIG_MSM_SCM uses the smc instruction, which with some toolchains requires a ".arch_extension" directive. Cc: David Brown Signed-off-by: Marc Zyngier Signed-off-by: David Brown --- arch/arm/mach-msm/Makefile | 2 ++ arch/arm/mach-msm/scm.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 4285dfd..4ad3969 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -15,6 +15,8 @@ obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o obj-$(CONFIG_MSM_SMD) += last_radio_log.o obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o +CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1) + obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o obj-$(CONFIG_SMP) += headsmp.o platsmp.o diff --git a/arch/arm/mach-msm/scm.c b/arch/arm/mach-msm/scm.c index 232f97a..bafabb5 100644 --- a/arch/arm/mach-msm/scm.c +++ b/arch/arm/mach-msm/scm.c @@ -180,6 +180,9 @@ static u32 smc(u32 cmd_addr) __asmeq("%1", "r0") __asmeq("%2", "r1") __asmeq("%3", "r2") +#ifdef REQUIRES_SEC + ".arch_extension sec\n" +#endif "smc #0 @ switch to secure world\n" : "=r" (r0) : "r" (r0), "r" (r1), "r" (r2) -- cgit v1.1 From 10953db8e1a278742ef7e64a3d1491802bcfa98b Mon Sep 17 00:00:00 2001 From: hayeswang Date: Mon, 7 Nov 2011 20:44:37 +0000 Subject: r8169: increase the delay parameter of pm_schedule_suspend The link down would occur when reseting PHY. And it would take about 2 ~ 5 seconds from link down to link up. If the delay of pm_schedule_suspend is not long enough, the device would enter runtime_suspend before link up. After link up, the device would wake up and reset PHY again. Then, you would find the driver keep in a loop of runtime_suspend and rumtime_resume. Signed-off-by: Hayes Wang Acked-by: Francois Romieu Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/r8169.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 92b45f0..6f06aa1 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -1292,7 +1292,7 @@ static void __rtl8169_check_link_status(struct net_device *dev, netif_carrier_off(dev); netif_info(tp, ifdown, dev, "link down\n"); if (pm) - pm_schedule_suspend(&tp->pci_dev->dev, 100); + pm_schedule_suspend(&tp->pci_dev->dev, 5000); } spin_unlock_irqrestore(&tp->lock, flags); } -- cgit v1.1 From c457338d7acd3823e765b684a62294cfda9d2f55 Mon Sep 17 00:00:00 2001 From: Brian Haley Date: Tue, 8 Nov 2011 04:41:42 +0000 Subject: ipv6: drop packets when source address is multicast RFC 4291 Section 2.7 says Multicast addresses must not be used as source addresses in IPv6 packets - drop them on input so we don't process the packet further. Signed-off-by: Brian Haley Reported-and-Tested-by: Kumar Sanghvi Signed-off-by: David S. Miller --- net/ipv6/ip6_input.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 027c7ff..a46c64e 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -111,6 +111,14 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt ipv6_addr_loopback(&hdr->daddr)) goto err; + /* + * RFC4291 2.7 + * Multicast addresses must not be used as source addresses in IPv6 + * packets or appear in any Routing header. + */ + if (ipv6_addr_is_multicast(&hdr->saddr)) + goto err; + skb->transport_header = skb->network_header + sizeof(*hdr); IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); -- cgit v1.1 From ea1649dea95fb270af94f75e842402c4cfbfc15f Mon Sep 17 00:00:00 2001 From: Nico Erfurth Date: Tue, 8 Nov 2011 07:30:40 +0000 Subject: Fix incorrect usage of NET_IP_ALIGN The driver used NET_IP_ALIGN to remove some additional padding inside of the rx_fixup function. On many architectures NET_IP_ALIGN defaults to 2 which removed the correct amount of bytes. On MCORE2-machines commit ea812ca1b06113597adcd8e70c0f84a413d97544 introduces a change which sets NET_IP_ALIGN to 0 by default. Which triggered the bug on these machines. This fix introduces a new RXW_PADDING define and uses this instead of NET_IP_ALIGN. The name was taken from the original SMSC7500 driver which is provided by SMSC. Signed-off-by: Nico Erfurth Tested-by: Phil Sutter Signed-off-by: David S. Miller --- drivers/net/usb/smsc75xx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 22a7cf9..a5b9b12 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -51,6 +51,7 @@ #define USB_VENDOR_ID_SMSC (0x0424) #define USB_PRODUCT_ID_LAN7500 (0x7500) #define USB_PRODUCT_ID_LAN7505 (0x7505) +#define RXW_PADDING 2 #define check_warn(ret, fmt, args...) \ ({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); }) @@ -1088,13 +1089,13 @@ static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) memcpy(&rx_cmd_b, skb->data, sizeof(rx_cmd_b)); le32_to_cpus(&rx_cmd_b); - skb_pull(skb, 4 + NET_IP_ALIGN); + skb_pull(skb, 4 + RXW_PADDING); packet = skb->data; /* get the packet length */ - size = (rx_cmd_a & RX_CMD_A_LEN) - NET_IP_ALIGN; - align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4; + size = (rx_cmd_a & RX_CMD_A_LEN) - RXW_PADDING; + align_count = (4 - ((size + RXW_PADDING) % 4)) % 4; if (unlikely(rx_cmd_a & RX_CMD_A_RED)) { netif_dbg(dev, rx_err, dev->net, -- cgit v1.1 From 4f1a1eb530071c39fb239fd26c912a64284b1408 Mon Sep 17 00:00:00 2001 From: Al Cooper Date: Tue, 8 Nov 2011 09:59:01 -0500 Subject: MIPS: Kernel hangs occasionally during boot. The Kernel hangs occasionally during boot after "Calibrating delay loop..". This is caused by the c0_compare_int_usable() routine in cevt-r4k.c returning false which causes the system to disable the timer and hang later. The false return happens because the routine is using a series of four calls to irq_disable_hazard() as a delay while it waits for the timer changes to propagate to the cp0 cause register. On newer MIPS cores, like the 74K, the series of irq_disable_hazard() calls turn into ehb instructions and can take as little as a few clock ticks for all 4 instructions. This is not enough of a delay, so the routine thinks the timer is not working. This fix uses up to a max number of cycle counter ticks for the delay and uses back_to_back_c0_hazard() instead of irq_disable_hazard() to handle the hazard condition between cp0 writes and cp0 reads. Signed-off-by: Al Cooper Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/2911/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/cevt-r4k.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index 98c5a97..e2d8e19 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c @@ -103,19 +103,10 @@ static int c0_compare_int_pending(void) /* * Compare interrupt can be routed and latched outside the core, - * so a single execution hazard barrier may not be enough to give - * it time to clear as seen in the Cause register. 4 time the - * pipeline depth seems reasonably conservative, and empirically - * works better in configurations with high CPU/bus clock ratios. + * so wait up to worst case number of cycle counter ticks for timer interrupt + * changes to propagate to the cause register. */ - -#define compare_change_hazard() \ - do { \ - irq_disable_hazard(); \ - irq_disable_hazard(); \ - irq_disable_hazard(); \ - irq_disable_hazard(); \ - } while (0) +#define COMPARE_INT_SEEN_TICKS 50 int c0_compare_int_usable(void) { @@ -126,8 +117,12 @@ int c0_compare_int_usable(void) * IP7 already pending? Try to clear it by acking the timer. */ if (c0_compare_int_pending()) { - write_c0_compare(read_c0_count()); - compare_change_hazard(); + cnt = read_c0_count(); + write_c0_compare(cnt); + back_to_back_c0_hazard(); + while (read_c0_count() < (cnt + COMPARE_INT_SEEN_TICKS)) + if (!c0_compare_int_pending()) + break; if (c0_compare_int_pending()) return 0; } @@ -136,7 +131,7 @@ int c0_compare_int_usable(void) cnt = read_c0_count(); cnt += delta; write_c0_compare(cnt); - compare_change_hazard(); + back_to_back_c0_hazard(); if ((int)(read_c0_count() - cnt) < 0) break; /* increase delta if the timer was already expired */ @@ -145,12 +140,17 @@ int c0_compare_int_usable(void) while ((int)(read_c0_count() - cnt) <= 0) ; /* Wait for expiry */ - compare_change_hazard(); + while (read_c0_count() < (cnt + COMPARE_INT_SEEN_TICKS)) + if (c0_compare_int_pending()) + break; if (!c0_compare_int_pending()) return 0; - - write_c0_compare(read_c0_count()); - compare_change_hazard(); + cnt = read_c0_count(); + write_c0_compare(cnt); + back_to_back_c0_hazard(); + while (read_c0_count() < (cnt + COMPARE_INT_SEEN_TICKS)) + if (!c0_compare_int_pending()) + break; if (c0_compare_int_pending()) return 0; -- cgit v1.1 From a8d12007c795f3d69ee0b2d29f0abfefd55c6120 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 8 Nov 2011 18:02:10 +0000 Subject: n_gsm: Fix timings Alek Du reported that the code erroneously applies time to jiffies conversions twice to the t1 and t2 values. In normal use on a modem link this cases no visible problem but on a slower link it will break as with HZ=1000 as is typical we are running t1/t2 ten times too fast. Alek's original patch removed the conversion from the timer setting but we in fact have to be more careful as the contents of t1/t2 are visible via the device API and we thus need to correct the constants. Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/tty/n_gsm.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 4cb0d0a..fc7bbba 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -66,14 +66,16 @@ static int debug; module_param(debug, int, 0600); -#define T1 (HZ/10) -#define T2 (HZ/3) -#define N2 3 +/* Defaults: these are from the specification */ + +#define T1 10 /* 100mS */ +#define T2 34 /* 333mS */ +#define N2 3 /* Retry 3 times */ /* Use long timers for testing at low speed with debug on */ #ifdef DEBUG_TIMING -#define T1 HZ -#define T2 (2 * HZ) +#define T1 100 +#define T2 200 #endif /* -- cgit v1.1 From 71e63e748ee6f4bad482b8021386eeb74f6e47f1 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Fri, 4 Nov 2011 08:10:09 +0100 Subject: ARM: 7149/1: spi/pl022: Enable clock in probe Make sure we enable the clock before leaving probe. Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Signed-off-by: Russell King --- drivers/spi/spi-pl022.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index f103e47..5559b22 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -2184,6 +2184,12 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) goto err_clk_prep; } + status = clk_enable(pl022->clk); + if (status) { + dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n"); + goto err_no_clk_en; + } + /* Disable SSP */ writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase)); @@ -2237,6 +2243,8 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) free_irq(adev->irq[0], pl022); err_no_irq: + clk_disable(pl022->clk); + err_no_clk_en: clk_unprepare(pl022->clk); err_clk_prep: clk_put(pl022->clk); -- cgit v1.1 From 8428e84d42179c2a00f5f6450866e70d802d1d05 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Mon, 7 Nov 2011 18:05:53 +0100 Subject: ARM: 7150/1: Allow kernel unaligned accesses on ARMv6+ processors Recent gcc versions generate unaligned accesses by default on ARMv6 and later processors. This patch ensures that the SCTLR.A bit is always cleared on such processors to avoid kernel traping before alignment_init() is called. Signed-off-by: Catalin Marinas Tested-by: John Linn Acked-by: Nicolas Pitre Cc: stable@vger.kernel.org Signed-off-by: Russell King --- arch/arm/kernel/head.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 566c54c..08c82fd 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -360,7 +360,7 @@ __secondary_data: * r13 = *virtual* address to jump to upon completion */ __enable_mmu: -#ifdef CONFIG_ALIGNMENT_TRAP +#if defined(CONFIG_ALIGNMENT_TRAP) && __LINUX_ARM_ARCH__ < 6 orr r0, r0, #CR_A #else bic r0, r0, #CR_A -- cgit v1.1 From 5f300acd8ae9f3d4585154370012ffc5c665330f Mon Sep 17 00:00:00 2001 From: Dirk B Date: Tue, 8 Nov 2011 18:16:39 +0100 Subject: ARM: 7152/1: distclean: Remove generated .dtb files The patch 'arm/dt: Add dtb make rule' adds support to create a .dtb file. But this is never removed afterwards. Remove the generated .dtb file if 'distclean' is called. Signed-off-by: Dirk Behme Acked-by: Rob Herring Acked-by: Grant Likely Cc: Shawn Guo Cc: Jason Liu Signed-off-by: Russell King --- arch/arm/boot/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index 176062a..5df26a9 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -65,6 +65,8 @@ $(obj)/%.dtb: $(src)/dts/%.dts $(obj)/dtbs: $(addprefix $(obj)/, $(dtb-y)) +clean-files := *.dtb + quiet_cmd_uimage = UIMAGE $@ cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \ -C none -a $(LOADADDR) -e $(STARTADDR) \ -- cgit v1.1 From 042f36e1560cedfe524607791fa44607a3121f63 Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Tue, 8 Nov 2011 13:27:31 -0500 Subject: IB/qib: Don't use schedule_work() It was mistakenly introduced by dde05cbdf8b1 ("IB/qib: Hold links until tuning data is available"). Signed-off-by: Mike Marciniszyn Signed-off-by: Roland Dreier --- drivers/infiniband/hw/qib/qib_iba7322.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index 5bd2162..8b46b60 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c @@ -5241,7 +5241,7 @@ static int qib_7322_ib_updown(struct qib_pportdata *ppd, int ibup, u64 ibcs) off */ if (ppd->dd->flags & QIB_HAS_QSFP) { qd->t_insert = get_jiffies_64(); - schedule_work(&qd->work); + queue_work(ib_wq, &qd->work); } spin_lock_irqsave(&ppd->sdma_lock, flags); if (__qib_sdma_running(ppd)) -- cgit v1.1 From e50e705ca71db82a78a3e13fb7abf6b2171ac9c7 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 8 Nov 2011 13:59:44 -0500 Subject: l2tp: fix l2tp_udp_recv_core() pskb_may_pull() can change skb->data, so we have to load ptr/optr at the right place. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/l2tp/l2tp_core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index bf8d50c..cf0f308 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -756,9 +756,6 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb, goto error; } - /* Point to L2TP header */ - optr = ptr = skb->data; - /* Trace packet contents, if enabled */ if (tunnel->debug & L2TP_MSG_DATA) { length = min(32u, skb->len); @@ -769,12 +766,15 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb, offset = 0; do { - printk(" %02X", ptr[offset]); + printk(" %02X", skb->data[offset]); } while (++offset < length); printk("\n"); } + /* Point to L2TP header */ + optr = ptr = skb->data; + /* Get L2TP header flags */ hdrflags = ntohs(*(__be16 *) ptr); -- cgit v1.1 From 59caa5612ce916c4902c753aa61429eb76ac2b21 Mon Sep 17 00:00:00 2001 From: oftedal Date: Mon, 7 Nov 2011 11:47:53 +0000 Subject: sunhme: Allow usage on SBI based SBus systems To prevent the SBus driver for Sun Happy Meal cards from being loaded for PCI cards utilizing the same chipset, a filter was added to the probe function in commit 0b492fce3d72d982a7981905f85484a1e1ba7fde. The filter was implemented by checking the name of the parent node in the OF tree. This patch extends this filter, so that the driver will load on SBus systems that are based upon SBI SBus Bridges. Signed-off-by: Kjetil Oftedal Signed-off-by: David S. Miller --- drivers/net/ethernet/sun/sunhme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c index c517dac..cf14ab9 100644 --- a/drivers/net/ethernet/sun/sunhme.c +++ b/drivers/net/ethernet/sun/sunhme.c @@ -2637,7 +2637,7 @@ static int __devinit happy_meal_sbus_probe_one(struct platform_device *op, int i sbus_dp = op->dev.parent->of_node; /* We can match PCI devices too, do not accept those here. */ - if (strcmp(sbus_dp->name, "sbus")) + if (strcmp(sbus_dp->name, "sbus") && strcmp(sbus_dp->name, "sbi")) return err; if (is_qfe) { -- cgit v1.1 From 6d67e9beb68bc6712b042c9723cecc87dc8e3f4c Mon Sep 17 00:00:00 2001 From: Feng King Date: Sat, 5 Nov 2011 04:23:23 +0000 Subject: tcp: Fix comments for Nagle algorithm TCP_NODELAY is weaker than TCP_CORK, when TCP_CORK was set, small segments will always pass Nagle test regardless of TCP_NODELAY option. Signed-off-by: Feng King Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 980b98f..63170e29 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1382,7 +1382,7 @@ static inline int tcp_minshall_check(const struct tcp_sock *tp) /* Return 0, if packet can be sent now without violation Nagle's rules: * 1. It is full sized. * 2. Or it contains FIN. (already checked by caller) - * 3. Or TCP_NODELAY was set. + * 3. Or TCP_CORK is not set, and TCP_NODELAY is set. * 4. Or TCP_CORK is not set, and all sent packets are ACKed. * With Minshall's modification: all sent small packets are ACKed. */ -- cgit v1.1 From 20db93c34095553a01a9c31136658917bf1fa5d5 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 8 Nov 2011 14:21:44 -0500 Subject: net: min_pmtu default is 552 Small fix in Documentation, since min_pmtu is 512 + 20 + 20 = 552 Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- Documentation/networking/ip-sysctl.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index cb7f314..f049a1c 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -20,7 +20,7 @@ ip_no_pmtu_disc - BOOLEAN default FALSE min_pmtu - INTEGER - default 562 - minimum discovered Path MTU + default 552 - minimum discovered Path MTU route/max_size - INTEGER Maximum number of routes allowed in the kernel. Increase -- cgit v1.1 From 2bc8ca40f951163b3bb75949479e2755c12c1b96 Mon Sep 17 00:00:00 2001 From: Steffen Klassert Date: Tue, 11 Oct 2011 01:12:02 +0000 Subject: ipv4: Fix inetpeer expire time information As we update the learned pmtu informations on demand, we might report a nagative expiration time value to userspace if the pmtu informations are already expired and we have not send a packet to that inetpeer after expiration. With this patch we send a expire time of null to userspace after expiration until the next packet is send to that inetpeer. Signed-off-by: Steffen Klassert Signed-off-by: David S. Miller --- net/ipv4/route.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 155138d..511f4a7 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2845,7 +2845,7 @@ static int rt_fill_info(struct net *net, struct rtable *rt = skb_rtable(skb); struct rtmsg *r; struct nlmsghdr *nlh; - long expires = 0; + unsigned long expires = 0; const struct inet_peer *peer = rt->peer; u32 id = 0, ts = 0, tsage = 0, error; @@ -2902,8 +2902,12 @@ static int rt_fill_info(struct net *net, tsage = get_seconds() - peer->tcp_ts_stamp; } expires = ACCESS_ONCE(peer->pmtu_expires); - if (expires) - expires -= jiffies; + if (expires) { + if (time_before(jiffies, expires)) + expires -= jiffies; + else + expires = 0; + } } if (rt_is_input_route(rt)) { -- cgit v1.1 From 917c16b2b69fc2eeb432eabca73258f08c58361e Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Tue, 8 Nov 2011 14:49:59 -0500 Subject: Btrfs: fix oops on NULL trans handle in btrfs_truncate If we fail to reserve space in the transaction during truncate, we can error out with a NULL trans handle. The cleanup code needs an extra check to make sure we aren't trying to use the bad handle. Signed-off-by: Chris Mason --- fs/btrfs/inode.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 9d0eaa5..f60e249 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6529,14 +6529,16 @@ end_trans: ret = btrfs_orphan_del(NULL, inode); } - trans->block_rsv = &root->fs_info->trans_block_rsv; - ret = btrfs_update_inode(trans, root, inode); - if (ret && !err) - err = ret; + if (trans) { + trans->block_rsv = &root->fs_info->trans_block_rsv; + ret = btrfs_update_inode(trans, root, inode); + if (ret && !err) + err = ret; - nr = trans->blocks_used; - ret = btrfs_end_transaction_throttle(trans, root); - btrfs_btree_balance_dirty(root, nr); + nr = trans->blocks_used; + ret = btrfs_end_transaction_throttle(trans, root); + btrfs_btree_balance_dirty(root, nr); + } out: btrfs_free_block_rsv(root, rsv); -- cgit v1.1 From 6aec187a90aeb883533c9180e2acac1e54c87f7d Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Tue, 8 Nov 2011 14:56:50 -0500 Subject: drivers/media: video/a5k6aa is a module and so needs module.h This file uses core functions like module_init() and module_exit() and so it explicitly needs to include the module.h header. Signed-off-by: Paul Gortmaker --- drivers/media/video/s5k6aa.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/video/s5k6aa.c b/drivers/media/video/s5k6aa.c index 2446736..0df7f2a 100644 --- a/drivers/media/video/s5k6aa.c +++ b/drivers/media/video/s5k6aa.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include -- cgit v1.1 From c26887d2a48600bfa87a27ce41ff78828bd7243c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 8 Nov 2011 09:20:07 +0100 Subject: cfg80211: fix missing kernel-doc Two new struct members were not documented, fix that. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/net/cfg80211.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 92cf1c2..95852e3 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -456,6 +456,9 @@ enum station_parameters_apply_mask { * as the AC bitmap in the QoS info field * @max_sp: max Service Period. same format as the MAX_SP in the * QoS info field (but already shifted down) + * @sta_modify_mask: bitmap indicating which parameters changed + * (for those that don't have a natural "no change" value), + * see &enum station_parameters_apply_mask */ struct station_parameters { u8 *supported_rates; @@ -615,6 +618,7 @@ struct sta_bss_parameters { * user space MLME/SME implementation. The information is provided for * the cfg80211_new_sta() calls to notify user space of the IEs. * @assoc_req_ies_len: Length of assoc_req_ies buffer in octets. + * @sta_flags: station flags mask & values */ struct station_info { u32 filled; -- cgit v1.1 From a59be0811c322f80aaa886b144239393efece42d Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Tue, 8 Nov 2011 14:01:13 +0100 Subject: ath: Fix NULL ptr dereference in ath_reg_apply_world_flags This happens with devices using a regulatory domain 0x68 that are only 5Ghz capable because ath_reg_apply_active_scan_flags assumes that we always have a 2,4Ghz band. CPU 0 Unable to handle kernel paging request at virtual address 00000000, epc == 82cd838c, ra == 82cd8384 Oops[#1]: Cpu 0 $ 0 : 00000000 00000061 00000003 00000024 $ 4 : 00000003 000016c1 82f900ac 00000024 $ 8 : 00000000 82cda304 0058bad8 00000005 $12 : 005908f8 001e8481 00000003 1dcd6500 $16 : 00000002 00000000 82c700c0 82c700c0 $20 : 82d415e4 82c70d64 82c70200 82c715bc $24 : 00000000 11e1a300 $28 : 82ce2000 82ce3c70 82c715a8 82cd8384 Hi : 00000000 Lo : 0000001e epc : 82cd838c ath_reg_apply_world_flags+0x78/0x17c [ath] Not tainted ra : 82cd8384 ath_reg_apply_world_flags+0x70/0x17c [ath] Status: 1000d403 KERNEL EXL IE Cause : 80800008 BadVA : 00000000 PrId : 00019374 (MIPS 24Kc) Modules linked in: ath9k(+) ath9k_common ath9k_hw ath mac80211 cfg80211 compat_firmware_class compat arc4 aes_generic deflate ecb cbc leds_gpio button_hotplug gpio_buttons input_polldev ie Process insmod (pid: 464, threadinfo=82ce2000, task=838b31d8, tls=00000000) Stack : 00000000 00000002 82f900ac 82c700c0 82d415e4 82c70d64 00000000 00000068 82f900ac 82cd88f4 82c700c0 82cda304 00000001 000020f0 82f90000 82c70d40 00000002 82f90000 82f900ac 82d4207c 82d518a0 00000002 7fee6118 8017c0d8 00000008 8397ba00 82c70d40 00000000 82c70200 83813000 83813058 b0010000 82d518a0 00000002 7fee6118 82d4b8c8 83445cc0 80120dc0 83804000 800eeda0 ... Call Trace: [<82cd838c>] ath_reg_apply_world_flags+0x78/0x17c [ath] [<82cd88f4>] ath_regd_init+0x464/0x488 [ath] [<82d4207c>] ath9k_init_device+0x6a4/0x6b4 [ath9k] [<82d4b8c8>] ath_pci_probe+0x27c/0x358 [ath9k] [<80181de0>] pci_device_probe+0x64/0xa4 [<8019e874>] driver_probe_device+0xb8/0x190 [<8019e9b8>] __driver_attach+0x6c/0xa4 [<8019dfc0>] bus_for_each_dev+0x60/0xb0 [<8019d744>] bus_add_driver+0xc4/0x25c [<8019ed6c>] driver_register+0xe0/0x198 [<8018206c>] __pci_register_driver+0x50/0xe0 [<82dd0010>] ath9k_init+0x10/0x54 [ath9k] [<8006b4a0>] do_one_initcall+0x68/0x1ec [<800a901c>] sys_init_module+0xec/0x23c [<80062544>] stack_done+0x20/0x3c Signed-off-by: Helmut Schaa Signed-off-by: John W. Linville --- drivers/net/wireless/ath/regd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 028310f..f1be57f 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -253,6 +253,8 @@ ath_reg_apply_active_scan_flags(struct wiphy *wiphy, int r; sband = wiphy->bands[IEEE80211_BAND_2GHZ]; + if (!sband) + return; /* * If no country IE has been received always enable active scan -- cgit v1.1 From cc438fccd5783c9f7b4c4858358ac897dcf8a58d Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Tue, 8 Nov 2011 15:54:46 +0200 Subject: wl12xx: fix wl12xx_scan_sched_scan_ssid_list() check that all given ssids are in filters A minor fix for the check that verifies that all given SSIDs (in req) exist in the filters (the match sets) Signed-off-by: Eyal Shapira Acked-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index 128ccb7..fc29c67 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c @@ -559,7 +559,7 @@ wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl, break; } /* Fail if SSID isn't present in the filters */ - if (j == req->n_ssids) { + if (j == cmd->n_ssids) { ret = -EINVAL; goto out_free; } -- cgit v1.1 From b9c913f327ccc5cf422b6dc9b5acfbc9b86e7b62 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 8 Nov 2011 12:17:25 -0800 Subject: x86 platform drivers: make Dell laptop driver select needed LED support Otherwise we get compile errors like this: ERROR: "led_classdev_unregister" [drivers/platform/x86/dell-laptop.ko] undefined! ERROR: "led_classdev_register" [drivers/platform/x86/dell-laptop.ko] undefined! make[1]: *** [__modpost] Error 1 make: *** [modules] Error 2 when the dell-laptop support is enabled without the necessary LED support being enabled. Reported-by: Alessandro Suardi Acked-by: Matthew Garrett Signed-off-by: Linus Torvalds --- drivers/platform/x86/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index f4e3d82..598d5b8 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -85,6 +85,8 @@ config DELL_LAPTOP depends on RFKILL || RFKILL = n depends on POWER_SUPPLY depends on SERIO_I8042 + select LEDS_CLASS + select NEW_LEDS default n ---help--- This driver adds support for rfkill and backlight control to Dell -- cgit v1.1 From 7fd2ae21a42d178982679b86086661292b4afe4a Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Tue, 8 Nov 2011 15:47:34 -0500 Subject: Btrfs: fix our reservations for updating an inode when completing io People have been reporting ENOSPC crashes in finish_ordered_io. This is because we try to steal from the delalloc block rsv to satisfy a reservation to update the inode. The problem with this is we don't explicitly save space for updating the inode when doing delalloc. This is kind of a problem and we've gotten away with this because way back when we just stole from the delalloc reserve without any questions, and this worked out fine because generally speaking the leaf had been modified either by the mtime update when we did the original write or because we just updated the leaf when we inserted the file extent item, only on rare occasions had the leaf not actually been modified, and that was still ok because we'd just use a block or two out of the over-reservation that is delalloc. Then came the delayed inode stuff. This is amazing, except it wants a full reservation for updating the inode since it may do it at some point down the road after we've written the blocks and we have to recow everything again. This worked out because the delayed inode stuff just stole from the global reserve, that is until recently when I changed that because it caused other problems. So here we are, we're doing everything right and being screwed for it. So take an extra reservation for the inode at delalloc reservation time and carry it through the life of the delalloc reservation. If we need it we can steal it in the delayed inode stuff. If we have already stolen it try and do a normal metadata reservation. If that fails try to steal from the delalloc reservation. If _that_ fails we'll get a WARN_ON() so I can start thinking of a better way to solve this and in the meantime we'll steal from the global reserve. With this patch I ran xfstests 13 in a loop for a couple of hours and didn't see any problems. Signed-off-by: Josef Bacik Signed-off-by: Chris Mason --- fs/btrfs/btrfs_inode.h | 4 +-- fs/btrfs/delayed-inode.c | 65 +++++++++++++++++++++++++++++++++++++++++++++--- fs/btrfs/extent-tree.c | 22 +++++++++++++--- fs/btrfs/inode.c | 1 + 4 files changed, 83 insertions(+), 9 deletions(-) diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index 5a5d325..634608d2 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h @@ -147,14 +147,12 @@ struct btrfs_inode { * the btrfs file release call will add this inode to the * ordered operations list so that we make sure to flush out any * new data the application may have written before commit. - * - * yes, its silly to have a single bitflag, but we might grow more - * of these. */ unsigned ordered_data_close:1; unsigned orphan_meta_reserved:1; unsigned dummy_inode:1; unsigned in_defrag:1; + unsigned delalloc_meta_reserved:1; /* * always compress this one file diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index bbe8496..313ee14 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c @@ -617,12 +617,14 @@ static void btrfs_delayed_item_release_metadata(struct btrfs_root *root, static int btrfs_delayed_inode_reserve_metadata( struct btrfs_trans_handle *trans, struct btrfs_root *root, + struct inode *inode, struct btrfs_delayed_node *node) { struct btrfs_block_rsv *src_rsv; struct btrfs_block_rsv *dst_rsv; u64 num_bytes; int ret; + int release = false; src_rsv = trans->block_rsv; dst_rsv = &root->fs_info->delayed_block_rsv; @@ -652,11 +654,67 @@ static int btrfs_delayed_inode_reserve_metadata( if (!ret) node->bytes_reserved = num_bytes; return ret; + } else if (src_rsv == &root->fs_info->delalloc_block_rsv) { + spin_lock(&BTRFS_I(inode)->lock); + if (BTRFS_I(inode)->delalloc_meta_reserved) { + BTRFS_I(inode)->delalloc_meta_reserved = 0; + spin_unlock(&BTRFS_I(inode)->lock); + release = true; + goto migrate; + } + spin_unlock(&BTRFS_I(inode)->lock); + + /* Ok we didn't have space pre-reserved. This shouldn't happen + * too often but it can happen if we do delalloc to an existing + * inode which gets dirtied because of the time update, and then + * isn't touched again until after the transaction commits and + * then we try to write out the data. First try to be nice and + * reserve something strictly for us. If not be a pain and try + * to steal from the delalloc block rsv. + */ + ret = btrfs_block_rsv_add_noflush(root, dst_rsv, num_bytes); + if (!ret) + goto out; + + ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); + if (!ret) + goto out; + + /* + * Ok this is a problem, let's just steal from the global rsv + * since this really shouldn't happen that often. + */ + WARN_ON(1); + ret = btrfs_block_rsv_migrate(&root->fs_info->global_block_rsv, + dst_rsv, num_bytes); + goto out; } +migrate: ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); - if (!ret) - node->bytes_reserved = num_bytes; + if (unlikely(ret)) { + /* This shouldn't happen */ + BUG_ON(release); + return ret; + } + +out: + /* + * Migrate only takes a reservation, it doesn't touch the size of the + * block_rsv. This is to simplify people who don't normally have things + * migrated from their block rsv. If they go to release their + * reservation, that will decrease the size as well, so if migrate + * reduced size we'd end up with a negative size. But for the + * delalloc_meta_reserved stuff we will only know to drop 1 reservation, + * but we could in fact do this reserve/migrate dance several times + * between the time we did the original reservation and we'd clean it + * up. So to take care of this, release the space for the meta + * reservation here. I think it may be time for a documentation page on + * how block rsvs. work. + */ + if (release) + btrfs_block_rsv_release(root, src_rsv, num_bytes); + node->bytes_reserved = num_bytes; return ret; } @@ -1708,7 +1766,8 @@ int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans, goto release_node; } - ret = btrfs_delayed_inode_reserve_metadata(trans, root, delayed_node); + ret = btrfs_delayed_inode_reserve_metadata(trans, root, inode, + delayed_node); if (ret) goto release_node; diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 18ea90c..0b044e5 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -4063,23 +4063,30 @@ int btrfs_snap_reserve_metadata(struct btrfs_trans_handle *trans, */ static unsigned drop_outstanding_extent(struct inode *inode) { + unsigned drop_inode_space = 0; unsigned dropped_extents = 0; BUG_ON(!BTRFS_I(inode)->outstanding_extents); BTRFS_I(inode)->outstanding_extents--; + if (BTRFS_I(inode)->outstanding_extents == 0 && + BTRFS_I(inode)->delalloc_meta_reserved) { + drop_inode_space = 1; + BTRFS_I(inode)->delalloc_meta_reserved = 0; + } + /* * If we have more or the same amount of outsanding extents than we have * reserved then we need to leave the reserved extents count alone. */ if (BTRFS_I(inode)->outstanding_extents >= BTRFS_I(inode)->reserved_extents) - return 0; + return drop_inode_space; dropped_extents = BTRFS_I(inode)->reserved_extents - BTRFS_I(inode)->outstanding_extents; BTRFS_I(inode)->reserved_extents -= dropped_extents; - return dropped_extents; + return dropped_extents + drop_inode_space; } /** @@ -4165,9 +4172,18 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) nr_extents = BTRFS_I(inode)->outstanding_extents - BTRFS_I(inode)->reserved_extents; BTRFS_I(inode)->reserved_extents += nr_extents; + } - to_reserve = btrfs_calc_trans_metadata_size(root, nr_extents); + /* + * Add an item to reserve for updating the inode when we complete the + * delalloc io. + */ + if (!BTRFS_I(inode)->delalloc_meta_reserved) { + nr_extents++; + BTRFS_I(inode)->delalloc_meta_reserved = 1; } + + to_reserve = btrfs_calc_trans_metadata_size(root, nr_extents); to_reserve += calc_csum_metadata_size(inode, num_bytes, 1); spin_unlock(&BTRFS_I(inode)->lock); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index f60e249..2b92059 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6607,6 +6607,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb) ei->orphan_meta_reserved = 0; ei->dummy_inode = 0; ei->in_defrag = 0; + ei->delalloc_meta_reserved = 0; ei->force_compress = BTRFS_COMPRESS_NONE; ei->delayed_node = NULL; -- cgit v1.1 From dccefb3729c8c2b17e45c68cdc0d575f2473a5f0 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 8 Nov 2011 12:49:29 -0800 Subject: x86 platform drivers: add POWER_SUPPLY to selected drivers for Dell The Kconfig loop detection goes crazy without this. Signed-off-by: Linus Torvalds --- drivers/platform/x86/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 598d5b8..7f43cf8 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -83,8 +83,8 @@ config DELL_LAPTOP depends on EXPERIMENTAL depends on BACKLIGHT_CLASS_DEVICE depends on RFKILL || RFKILL = n - depends on POWER_SUPPLY depends on SERIO_I8042 + select POWER_SUPPLY select LEDS_CLASS select NEW_LEDS default n -- cgit v1.1 From 156acb166ea9a43d7fcdf9b8051694ce4e91dbfc Mon Sep 17 00:00:00 2001 From: Thomas Meyer Date: Tue, 8 Nov 2011 22:34:00 +0100 Subject: PM / OPP: Use ERR_CAST instead of ERR_PTR(PTR_ERR()) Use ERR_CAST inlined function instead of ERR_PTR(PTR_ERR(...)) [The semantic patch that makes this change is available in scripts/coccinelle/api/err_cast.cocci. More information about semantic patching is available at http://coccinelle.lip6.fr/] Signed-off-by: Thomas Meyer Signed-off-by: Rafael J. Wysocki --- drivers/base/power/opp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index 434a6c0..95706fa 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c @@ -669,7 +669,7 @@ struct srcu_notifier_head *opp_get_notifier(struct device *dev) struct device_opp *dev_opp = find_device_opp(dev); if (IS_ERR(dev_opp)) - return ERR_PTR(PTR_ERR(dev_opp)); /* matching type */ + return ERR_CAST(dev_opp); /* matching type */ return &dev_opp->head; } -- cgit v1.1 From 24ed6ddd9cbf084f1a2dfa3ef66287e5277002e1 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 25 Oct 2011 21:14:10 +0200 Subject: m68k: Revive lost ARAnyM config options commit 0e152d80507b75c00aac60f2ffc586360687cd52 ("m68k: reorganize Kconfig options to improve mmu/non-mmu selections") accidentally dropped the ARAnyM config options. Re-add them to the "Platform devices" section. Signed-off-by: Geert Uytterhoeven Acked-by: Greg Ungerer --- arch/m68k/Kconfig.devices | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/arch/m68k/Kconfig.devices b/arch/m68k/Kconfig.devices index d214034..6033f5d 100644 --- a/arch/m68k/Kconfig.devices +++ b/arch/m68k/Kconfig.devices @@ -24,6 +24,37 @@ config PROC_HARDWARE including the model, CPU, MMU, clock speed, BogoMIPS rating, and memory size. +config NATFEAT + bool "ARAnyM emulator support" + depends on ATARI + help + This option enables support for ARAnyM native features, such as + access to a disk image as /dev/hda. + +config NFBLOCK + tristate "NatFeat block device support" + depends on BLOCK && NATFEAT + help + Say Y to include support for the ARAnyM NatFeat block device + which allows direct access to the hard drives without using + the hardware emulation. + +config NFCON + tristate "NatFeat console driver" + depends on NATFEAT + help + Say Y to include support for the ARAnyM NatFeat console driver + which allows the console output to be redirected to the stderr + output of ARAnyM. + +config NFETH + tristate "NatFeat Ethernet support" + depends on ETHERNET && NATFEAT + help + Say Y to include support for the ARAnyM NatFeat network device + which will emulate a regular ethernet device while presenting an + ethertap device to the host system. + endmenu menu "Character devices" -- cgit v1.1 From 59433a59b073b88cb32efd03af8ac9b13d56f4cf Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 28 Oct 2011 22:37:21 +0200 Subject: m68k: Revive lost DIO bus config option commit 0e152d80507b75c00aac60f2ffc586360687cd52 ("m68k: reorganize Kconfig options to improve mmu/non-mmu selections") accidentally dropped the DIO bus config option. Re-add it to the "Bus support" section. Signed-off-by: Geert Uytterhoeven --- arch/m68k/Kconfig.bus | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/m68k/Kconfig.bus b/arch/m68k/Kconfig.bus index 8294f0c..3adb499 100644 --- a/arch/m68k/Kconfig.bus +++ b/arch/m68k/Kconfig.bus @@ -2,6 +2,15 @@ if MMU comment "Bus Support" +config DIO + bool "DIO bus support" + depends on HP300 + default y + help + Say Y here to enable support for the "DIO" expansion bus used in + HP300 machines. If you are using such a system you almost certainly + want this. + config NUBUS bool depends on MAC -- cgit v1.1 From 3ec7215e5d1a714ef65069a1d0999a31e4930bb7 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 25 May 2011 21:40:59 +0200 Subject: ide-{cd,floppy,tape}: Do not include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The top of has this comment: * Please do not include this file in generic code. There is currently * no requirement for any architecture to implement anything held * within this file. * * Thanks. --rmk Remove inclusion of , to prevent the following compile error from happening soon: | include/linux/irq.h:132: error: redefinition of ‘struct irq_data’ | include/linux/irq.h:286: error: redefinition of ‘struct irq_chip’ Signed-off-by: Geert Uytterhoeven Acked-by: Thomas Gleixner Acked-by: Borislav Petkov Cc: linux-ide@vger.kernel.org --- drivers/ide/ide-cd.c | 1 - drivers/ide/ide-floppy.c | 1 - drivers/ide/ide-tape.c | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 04b0956..8126824 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -43,7 +43,6 @@ /* For SCSI -> ATAPI command conversion */ #include -#include #include #include #include diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 61fdf544..3d42043 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -35,7 +35,6 @@ #include #include -#include #include #include #include diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 7ecb1ad..ce8237d 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -41,7 +41,6 @@ #include #include -#include #include #include #include -- cgit v1.1 From c288bf2533e57174b90b07860c4391bcd1ea269c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 13 Apr 2011 22:31:28 +0200 Subject: m68k/irq: Rename irq_controller to irq_chip Make it more similar to the genirq version: - Remove lock (unused as we don't do SMP anyway), - Prepend methods with irq_, - Make irq_startup() return unsigned int. Signed-off-by: Geert Uytterhoeven Acked-by: Thomas Gleixner --- arch/m68k/amiga/amiints.c | 9 +++-- arch/m68k/amiga/cia.c | 18 +++++----- arch/m68k/apollo/dn_ints.c | 11 +++--- arch/m68k/atari/ataints.c | 15 ++++---- arch/m68k/include/asm/irq.h | 15 ++++---- arch/m68k/kernel/ints.c | 86 ++++++++++++++++++++++----------------------- arch/m68k/mac/macints.c | 9 +++-- arch/m68k/q40/q40ints.c | 17 +++++---- arch/m68k/sun3/sun3ints.c | 13 ++++--- 9 files changed, 91 insertions(+), 102 deletions(-) diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c index c5b5212..320c5d0 100644 --- a/arch/m68k/amiga/amiints.c +++ b/arch/m68k/amiga/amiints.c @@ -52,11 +52,10 @@ static irqreturn_t ami_int3(int irq, void *dev_id); static irqreturn_t ami_int4(int irq, void *dev_id); static irqreturn_t ami_int5(int irq, void *dev_id); -static struct irq_controller amiga_irq_controller = { +static struct irq_chip amiga_irq_chip = { .name = "amiga", - .lock = __SPIN_LOCK_UNLOCKED(amiga_irq_controller.lock), - .enable = amiga_enable_irq, - .disable = amiga_disable_irq, + .irq_enable = amiga_enable_irq, + .irq_disable = amiga_disable_irq, }; /* @@ -81,7 +80,7 @@ void __init amiga_init_IRQ(void) if (request_irq(IRQ_AUTO_5, ami_int5, 0, "int5", NULL)) pr_err("Couldn't register int%d\n", 5); - m68k_setup_irq_controller(&amiga_irq_controller, IRQ_USER, AMI_STD_IRQS); + m68k_setup_irq_chip(&amiga_irq_chip, IRQ_USER, AMI_STD_IRQS); /* turn off PCMCIA interrupts */ if (AMIGAHW_PRESENT(PCMCIA)) diff --git a/arch/m68k/amiga/cia.c b/arch/m68k/amiga/cia.c index ecd0f7c..637ef53 100644 --- a/arch/m68k/amiga/cia.c +++ b/arch/m68k/amiga/cia.c @@ -121,11 +121,10 @@ static void cia_disable_irq(unsigned int irq) cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA)); } -static struct irq_controller cia_irq_controller = { +static struct irq_chip cia_irq_chip = { .name = "cia", - .lock = __SPIN_LOCK_UNLOCKED(cia_irq_controller.lock), - .enable = cia_enable_irq, - .disable = cia_disable_irq, + .irq_enable = cia_enable_irq, + .irq_disable = cia_disable_irq, }; /* @@ -158,23 +157,22 @@ static void auto_disable_irq(unsigned int irq) } } -static struct irq_controller auto_irq_controller = { +static struct irq_chip auto_irq_chip = { .name = "auto", - .lock = __SPIN_LOCK_UNLOCKED(auto_irq_controller.lock), - .enable = auto_enable_irq, - .disable = auto_disable_irq, + .irq_enable = auto_enable_irq, + .irq_disable = auto_disable_irq, }; void __init cia_init_IRQ(struct ciabase *base) { - m68k_setup_irq_controller(&cia_irq_controller, base->cia_irq, CIA_IRQS); + m68k_setup_irq_chip(&cia_irq_chip, base->cia_irq, CIA_IRQS); /* clear any pending interrupt and turn off all interrupts */ cia_set_irq(base, CIA_ICR_ALL); cia_able_irq(base, CIA_ICR_ALL); /* override auto int and install CIA handler */ - m68k_setup_irq_controller(&auto_irq_controller, base->handler_irq, 1); + m68k_setup_irq_chip(&auto_irq_chip, base->handler_irq, 1); m68k_irq_startup(base->handler_irq); if (request_irq(base->handler_irq, cia_handler, IRQF_SHARED, base->name, base)) diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c index 5d47f3a..d6e8f334 100644 --- a/arch/m68k/apollo/dn_ints.c +++ b/arch/m68k/apollo/dn_ints.c @@ -12,7 +12,7 @@ void dn_process_int(unsigned int irq, struct pt_regs *fp) *(volatile unsigned char *)(picb)=0x20; } -int apollo_irq_startup(unsigned int irq) +unsigned int apollo_irq_startup(unsigned int irq) { if (irq < 8) *(volatile unsigned char *)(pica+1) &= ~(1 << irq); @@ -29,16 +29,15 @@ void apollo_irq_shutdown(unsigned int irq) *(volatile unsigned char *)(picb+1) |= (1 << (irq - 8)); } -static struct irq_controller apollo_irq_controller = { +static struct irq_chip apollo_irq_chip = { .name = "apollo", - .lock = __SPIN_LOCK_UNLOCKED(apollo_irq_controller.lock), - .startup = apollo_irq_startup, - .shutdown = apollo_irq_shutdown, + .irq_startup = apollo_irq_startup, + .irq_shutdown = apollo_irq_shutdown, }; void __init dn_init_IRQ(void) { m68k_setup_user_interrupt(VEC_USER + 96, 16, dn_process_int); - m68k_setup_irq_controller(&apollo_irq_controller, IRQ_APOLLO, 16); + m68k_setup_irq_chip(&apollo_irq_chip, IRQ_APOLLO, 16); } diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c index 26a804e..ac0ebdf 100644 --- a/arch/m68k/atari/ataints.c +++ b/arch/m68k/atari/ataints.c @@ -320,7 +320,7 @@ extern void atari_microwire_cmd(int cmd); extern int atari_SCC_reset_done; -static int atari_startup_irq(unsigned int irq) +static unsigned int atari_startup_irq(unsigned int irq) { m68k_irq_startup(irq); atari_turnon_irq(irq); @@ -338,13 +338,12 @@ static void atari_shutdown_irq(unsigned int irq) vectors[VEC_INT4] = falcon_hblhandler; } -static struct irq_controller atari_irq_controller = { +static struct irq_chip atari_irq_chip = { .name = "atari", - .lock = __SPIN_LOCK_UNLOCKED(atari_irq_controller.lock), - .startup = atari_startup_irq, - .shutdown = atari_shutdown_irq, - .enable = atari_enable_irq, - .disable = atari_disable_irq, + .irq_startup = atari_startup_irq, + .irq_shutdown = atari_shutdown_irq, + .irq_enable = atari_enable_irq, + .irq_disable = atari_disable_irq, }; /* @@ -361,7 +360,7 @@ static struct irq_controller atari_irq_controller = { void __init atari_init_IRQ(void) { m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER, NULL); - m68k_setup_irq_controller(&atari_irq_controller, 1, NUM_ATARI_SOURCES - 1); + m68k_setup_irq_chip(&atari_irq_chip, 1, NUM_ATARI_SOURCES - 1); /* Initialize the MFP(s) */ diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h index 69ed0d74..d8c6f68 100644 --- a/arch/m68k/include/asm/irq.h +++ b/arch/m68k/include/asm/irq.h @@ -93,16 +93,15 @@ struct irq_handler { const char *devname; }; -struct irq_controller { +struct irq_chip { const char *name; - spinlock_t lock; - int (*startup)(unsigned int irq); - void (*shutdown)(unsigned int irq); - void (*enable)(unsigned int irq); - void (*disable)(unsigned int irq); + unsigned int (*irq_startup)(unsigned int irq); + void (*irq_shutdown)(unsigned int irq); + void (*irq_enable)(unsigned int irq); + void (*irq_disable)(unsigned int irq); }; -extern int m68k_irq_startup(unsigned int); +extern unsigned int m68k_irq_startup(unsigned int); extern void m68k_irq_shutdown(unsigned int); /* @@ -113,7 +112,7 @@ extern irq_node_t *new_irq_node(void); extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)); extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, void (*handler)(unsigned int, struct pt_regs *)); -extern void m68k_setup_irq_controller(struct irq_controller *, unsigned int, unsigned int); +extern void m68k_setup_irq_chip(struct irq_chip *, unsigned int, unsigned int); asmlinkage void m68k_handle_int(unsigned int); asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *); diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c index 761ee04..f43ad7b 100644 --- a/arch/m68k/kernel/ints.c +++ b/arch/m68k/kernel/ints.c @@ -52,23 +52,21 @@ extern u16 user_irqvec_fixup[]; /* table for system interrupt handlers */ static struct irq_node *irq_list[NR_IRQS]; -static struct irq_controller *irq_controller[NR_IRQS]; +static struct irq_chip *irq_chip[NR_IRQS]; static int irq_depth[NR_IRQS]; static int m68k_first_user_vec; -static struct irq_controller auto_irq_controller = { +static struct irq_chip auto_irq_chip = { .name = "auto", - .lock = __SPIN_LOCK_UNLOCKED(auto_irq_controller.lock), - .startup = m68k_irq_startup, - .shutdown = m68k_irq_shutdown, + .irq_startup = m68k_irq_startup, + .irq_shutdown = m68k_irq_shutdown, }; -static struct irq_controller user_irq_controller = { +static struct irq_chip user_irq_chip = { .name = "user", - .lock = __SPIN_LOCK_UNLOCKED(user_irq_controller.lock), - .startup = m68k_irq_startup, - .shutdown = m68k_irq_shutdown, + .irq_startup = m68k_irq_startup, + .irq_shutdown = m68k_irq_shutdown, }; #define NUM_IRQ_NODES 100 @@ -96,7 +94,7 @@ void __init init_IRQ(void) } for (i = IRQ_AUTO_1; i <= IRQ_AUTO_7; i++) - irq_controller[i] = &auto_irq_controller; + irq_chip[i] = &auto_irq_chip; mach_init_IRQ(); } @@ -136,7 +134,7 @@ void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, BUG_ON(IRQ_USER + cnt > NR_IRQS); m68k_first_user_vec = vec; for (i = 0; i < cnt; i++) - irq_controller[IRQ_USER + i] = &user_irq_controller; + irq_chip[IRQ_USER + i] = &user_irq_chip; *user_irqvec_fixup = vec - IRQ_USER; if (handler) *user_irqhandler_fixup = (u32)handler; @@ -144,7 +142,7 @@ void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, } /** - * m68k_setup_irq_controller + * m68k_setup_irq_chip * @contr: irq controller which controls specified irq * @irq: first irq to be managed by the controller * @@ -153,13 +151,13 @@ void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, * be changed as well, but the controller probably should use m68k_irq_startup/ * m68k_irq_shutdown. */ -void m68k_setup_irq_controller(struct irq_controller *contr, unsigned int irq, +void m68k_setup_irq_chip(struct irq_chip *contr, unsigned int irq, unsigned int cnt) { int i; for (i = 0; i < cnt; i++) - irq_controller[irq + i] = contr; + irq_chip[irq + i] = contr; } irq_node_t *new_irq_node(void) @@ -180,23 +178,23 @@ irq_node_t *new_irq_node(void) int setup_irq(unsigned int irq, struct irq_node *node) { - struct irq_controller *contr; + struct irq_chip *contr; struct irq_node **prev; unsigned long flags; - if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { + if (irq >= NR_IRQS || !(contr = irq_chip[irq])) { printk("%s: Incorrect IRQ %d from %s\n", __func__, irq, node->devname); return -ENXIO; } - spin_lock_irqsave(&contr->lock, flags); + local_irq_save(flags); prev = irq_list + irq; if (*prev) { /* Can't share interrupts unless both agree to */ if (!((*prev)->flags & node->flags & IRQF_SHARED)) { - spin_unlock_irqrestore(&contr->lock, flags); + local_irq_restore(flags); return -EBUSY; } while (*prev) @@ -204,15 +202,15 @@ int setup_irq(unsigned int irq, struct irq_node *node) } if (!irq_list[irq]) { - if (contr->startup) - contr->startup(irq); + if (contr->irq_startup) + contr->irq_startup(irq); else - contr->enable(irq); + contr->irq_enable(irq); } node->next = NULL; *prev = node; - spin_unlock_irqrestore(&contr->lock, flags); + local_irq_restore(flags); return 0; } @@ -244,16 +242,16 @@ EXPORT_SYMBOL(request_irq); void free_irq(unsigned int irq, void *dev_id) { - struct irq_controller *contr; + struct irq_chip *contr; struct irq_node **p, *node; unsigned long flags; - if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { + if (irq >= NR_IRQS || !(contr = irq_chip[irq])) { printk("%s: Incorrect IRQ %d\n", __func__, irq); return; } - spin_lock_irqsave(&contr->lock, flags); + local_irq_save(flags); p = irq_list + irq; while ((node = *p)) { @@ -270,58 +268,58 @@ void free_irq(unsigned int irq, void *dev_id) __func__, irq); if (!irq_list[irq]) { - if (contr->shutdown) - contr->shutdown(irq); + if (contr->irq_shutdown) + contr->irq_shutdown(irq); else - contr->disable(irq); + contr->irq_disable(irq); } - spin_unlock_irqrestore(&contr->lock, flags); + local_irq_restore(flags); } EXPORT_SYMBOL(free_irq); void enable_irq(unsigned int irq) { - struct irq_controller *contr; + struct irq_chip *contr; unsigned long flags; - if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { + if (irq >= NR_IRQS || !(contr = irq_chip[irq])) { printk("%s: Incorrect IRQ %d\n", __func__, irq); return; } - spin_lock_irqsave(&contr->lock, flags); + local_irq_save(flags); if (irq_depth[irq]) { if (!--irq_depth[irq]) { - if (contr->enable) - contr->enable(irq); + if (contr->irq_enable) + contr->irq_enable(irq); } } else WARN_ON(1); - spin_unlock_irqrestore(&contr->lock, flags); + local_irq_restore(flags); } EXPORT_SYMBOL(enable_irq); void disable_irq(unsigned int irq) { - struct irq_controller *contr; + struct irq_chip *contr; unsigned long flags; - if (irq >= NR_IRQS || !(contr = irq_controller[irq])) { + if (irq >= NR_IRQS || !(contr = irq_chip[irq])) { printk("%s: Incorrect IRQ %d\n", __func__, irq); return; } - spin_lock_irqsave(&contr->lock, flags); + local_irq_save(flags); if (!irq_depth[irq]++) { - if (contr->disable) - contr->disable(irq); + if (contr->irq_disable) + contr->irq_disable(irq); } - spin_unlock_irqrestore(&contr->lock, flags); + local_irq_restore(flags); } EXPORT_SYMBOL(disable_irq); @@ -330,7 +328,7 @@ void disable_irq_nosync(unsigned int irq) __attribute__((alias("disable_irq"))); EXPORT_SYMBOL(disable_irq_nosync); -int m68k_irq_startup(unsigned int irq) +unsigned int m68k_irq_startup(unsigned int irq) { if (irq <= IRQ_AUTO_7) vectors[VEC_SPUR + irq] = auto_inthandler; @@ -413,13 +411,13 @@ asmlinkage void handle_badint(struct pt_regs *regs) int show_interrupts(struct seq_file *p, void *v) { - struct irq_controller *contr; + struct irq_chip *contr; struct irq_node *node; int i = *(loff_t *) v; /* autovector interrupts */ if (irq_list[i]) { - contr = irq_controller[i]; + contr = irq_chip[i]; node = irq_list[i]; seq_printf(p, "%-8s %3u: %10u %s", contr->name, i, kstat_cpu(0).irqs[i], node->devname); while ((node = node->next)) diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c index f92190c..ffa1b3f 100644 --- a/arch/m68k/mac/macints.c +++ b/arch/m68k/mac/macints.c @@ -193,11 +193,10 @@ irqreturn_t mac_debug_handler(int, void *); void mac_enable_irq(unsigned int irq); void mac_disable_irq(unsigned int irq); -static struct irq_controller mac_irq_controller = { +static struct irq_chip mac_irq_chip = { .name = "mac", - .lock = __SPIN_LOCK_UNLOCKED(mac_irq_controller.lock), - .enable = mac_enable_irq, - .disable = mac_disable_irq, + .irq_enable = mac_enable_irq, + .irq_disable = mac_disable_irq, }; void __init mac_init_IRQ(void) @@ -205,7 +204,7 @@ void __init mac_init_IRQ(void) #ifdef DEBUG_MACINTS printk("mac_init_IRQ(): Setting things up...\n"); #endif - m68k_setup_irq_controller(&mac_irq_controller, IRQ_USER, + m68k_setup_irq_chip(&mac_irq_chip, IRQ_USER, NUM_MAC_SOURCES - IRQ_USER); /* Make sure the SONIC interrupt is cleared or things get ugly */ #ifdef SHUTUP_SONIC diff --git a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c index 9f0e3d5..fa05a03 100644 --- a/arch/m68k/q40/q40ints.c +++ b/arch/m68k/q40/q40ints.c @@ -41,14 +41,14 @@ static void q40_disable_irq(unsigned int); unsigned short q40_ablecount[35]; unsigned short q40_state[35]; -static int q40_irq_startup(unsigned int irq) +static unsigned int q40_irq_startup(unsigned int irq) { /* test for ISA ints not implemented by HW */ switch (irq) { case 1: case 2: case 8: case 9: case 11: case 12: case 13: printk("%s: ISA IRQ %d not implemented by HW\n", __func__, irq); - return -ENXIO; + /* FIXME return -ENXIO; */ } return 0; } @@ -57,13 +57,12 @@ static void q40_irq_shutdown(unsigned int irq) { } -static struct irq_controller q40_irq_controller = { +static struct irq_chip q40_irq_chip = { .name = "q40", - .lock = __SPIN_LOCK_UNLOCKED(q40_irq_controller.lock), - .startup = q40_irq_startup, - .shutdown = q40_irq_shutdown, - .enable = q40_enable_irq, - .disable = q40_disable_irq, + .irq_startup = q40_irq_startup, + .irq_shutdown = q40_irq_shutdown, + .irq_enable = q40_enable_irq, + .irq_disable = q40_disable_irq, }; /* @@ -81,7 +80,7 @@ static int disabled; void __init q40_init_IRQ(void) { - m68k_setup_irq_controller(&q40_irq_controller, 1, Q40_IRQ_MAX); + m68k_setup_irq_chip(&q40_irq_chip, 1, Q40_IRQ_MAX); /* setup handler for ISA ints */ m68k_setup_auto_interrupt(q40_irq_handler); diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c index 6464ad3..97fa9ed 100644 --- a/arch/m68k/sun3/sun3ints.c +++ b/arch/m68k/sun3/sun3ints.c @@ -86,13 +86,12 @@ static void sun3_inthandle(unsigned int irq, struct pt_regs *fp) __m68k_handle_int(irq, fp); } -static struct irq_controller sun3_irq_controller = { +static struct irq_chip sun3_irq_chip = { .name = "sun3", - .lock = __SPIN_LOCK_UNLOCKED(sun3_irq_controller.lock), - .startup = m68k_irq_startup, - .shutdown = m68k_irq_shutdown, - .enable = sun3_enable_irq, - .disable = sun3_disable_irq, + .irq_startup = m68k_irq_startup, + .irq_shutdown = m68k_irq_shutdown, + .irq_enable = sun3_enable_irq, + .irq_disable = sun3_disable_irq, }; void __init sun3_init_IRQ(void) @@ -100,7 +99,7 @@ void __init sun3_init_IRQ(void) *sun3_intreg = 1; m68k_setup_auto_interrupt(sun3_inthandle); - m68k_setup_irq_controller(&sun3_irq_controller, IRQ_AUTO_1, 7); + m68k_setup_irq_chip(&sun3_irq_chip, IRQ_AUTO_1, 7); m68k_setup_user_interrupt(VEC_USER, 128, NULL); if (request_irq(IRQ_AUTO_5, sun3_int5, 0, "int5", NULL)) -- cgit v1.1 From 0dde595be678c06e7de27c98f45403088f1b126a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 17 Apr 2011 21:39:08 +0200 Subject: m68k/irq: Kill irq_node_t typedef, always use struct irq_node Signed-off-by: Geert Uytterhoeven Acked-by: Thomas Gleixner --- arch/m68k/include/asm/irq.h | 8 ++++---- arch/m68k/kernel/ints.c | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h index d8c6f68..bfc521f 100644 --- a/arch/m68k/include/asm/irq.h +++ b/arch/m68k/include/asm/irq.h @@ -75,13 +75,13 @@ struct pt_regs; * This structure is used to chain together the ISRs for a particular * interrupt source (if it supports chaining). */ -typedef struct irq_node { +struct irq_node { irqreturn_t (*handler)(int, void *); void *dev_id; struct irq_node *next; unsigned long flags; const char *devname; -} irq_node_t; +}; /* * This structure has only 4 elements for speed reasons @@ -105,9 +105,9 @@ extern unsigned int m68k_irq_startup(unsigned int); extern void m68k_irq_shutdown(unsigned int); /* - * This function returns a new irq_node_t + * This function returns a new struct irq_node */ -extern irq_node_t *new_irq_node(void); +extern struct irq_node *new_irq_node(void); extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)); extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c index f43ad7b..9de8eb4 100644 --- a/arch/m68k/kernel/ints.c +++ b/arch/m68k/kernel/ints.c @@ -70,7 +70,7 @@ static struct irq_chip user_irq_chip = { }; #define NUM_IRQ_NODES 100 -static irq_node_t nodes[NUM_IRQ_NODES]; +static struct irq_node nodes[NUM_IRQ_NODES]; /* * void init_IRQ(void) @@ -160,9 +160,9 @@ void m68k_setup_irq_chip(struct irq_chip *contr, unsigned int irq, irq_chip[irq + i] = contr; } -irq_node_t *new_irq_node(void) +struct irq_node *new_irq_node(void) { - irq_node_t *node; + struct irq_node *node; short i; for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--) { -- cgit v1.1 From 6549d537922da6a6893e9bc1be9c2b89db663719 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 17 Apr 2011 21:59:23 +0200 Subject: m68k/irq: Rename irq_node to irq_data Make it more similar to the genirq version: - Add an irq field Signed-off-by: Geert Uytterhoeven Acked-by: Thomas Gleixner --- arch/m68k/include/asm/irq.h | 9 +++++---- arch/m68k/kernel/ints.c | 21 +++++++++++---------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h index bfc521f..3cb037c 100644 --- a/arch/m68k/include/asm/irq.h +++ b/arch/m68k/include/asm/irq.h @@ -75,10 +75,11 @@ struct pt_regs; * This structure is used to chain together the ISRs for a particular * interrupt source (if it supports chaining). */ -struct irq_node { +struct irq_data { + unsigned int irq; irqreturn_t (*handler)(int, void *); void *dev_id; - struct irq_node *next; + struct irq_data *next; unsigned long flags; const char *devname; }; @@ -105,9 +106,9 @@ extern unsigned int m68k_irq_startup(unsigned int); extern void m68k_irq_shutdown(unsigned int); /* - * This function returns a new struct irq_node + * This function returns a new struct irq_data */ -extern struct irq_node *new_irq_node(void); +extern struct irq_data *new_irq_node(void); extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)); extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c index 9de8eb4..8877932 100644 --- a/arch/m68k/kernel/ints.c +++ b/arch/m68k/kernel/ints.c @@ -51,7 +51,7 @@ extern u32 user_irqhandler_fixup[]; extern u16 user_irqvec_fixup[]; /* table for system interrupt handlers */ -static struct irq_node *irq_list[NR_IRQS]; +static struct irq_data *irq_list[NR_IRQS]; static struct irq_chip *irq_chip[NR_IRQS]; static int irq_depth[NR_IRQS]; @@ -70,7 +70,7 @@ static struct irq_chip user_irq_chip = { }; #define NUM_IRQ_NODES 100 -static struct irq_node nodes[NUM_IRQ_NODES]; +static struct irq_data nodes[NUM_IRQ_NODES]; /* * void init_IRQ(void) @@ -160,9 +160,9 @@ void m68k_setup_irq_chip(struct irq_chip *contr, unsigned int irq, irq_chip[irq + i] = contr; } -struct irq_node *new_irq_node(void) +struct irq_data *new_irq_node(void) { - struct irq_node *node; + struct irq_data *node; short i; for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--) { @@ -176,10 +176,10 @@ struct irq_node *new_irq_node(void) return NULL; } -int setup_irq(unsigned int irq, struct irq_node *node) +int setup_irq(unsigned int irq, struct irq_data *node) { struct irq_chip *contr; - struct irq_node **prev; + struct irq_data **prev; unsigned long flags; if (irq >= NR_IRQS || !(contr = irq_chip[irq])) { @@ -219,13 +219,14 @@ int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *devname, void *dev_id) { - struct irq_node *node; + struct irq_data *node; int res; node = new_irq_node(); if (!node) return -ENOMEM; + node->irq = irq; node->handler = handler; node->flags = flags; node->dev_id = dev_id; @@ -243,7 +244,7 @@ EXPORT_SYMBOL(request_irq); void free_irq(unsigned int irq, void *dev_id) { struct irq_chip *contr; - struct irq_node **p, *node; + struct irq_data **p, *node; unsigned long flags; if (irq >= NR_IRQS || !(contr = irq_chip[irq])) { @@ -386,7 +387,7 @@ EXPORT_SYMBOL(irq_canonicalize); asmlinkage void m68k_handle_int(unsigned int irq) { - struct irq_node *node; + struct irq_data *node; kstat_cpu(0).irqs[irq]++; node = irq_list[irq]; do { @@ -412,7 +413,7 @@ asmlinkage void handle_badint(struct pt_regs *regs) int show_interrupts(struct seq_file *p, void *v) { struct irq_chip *contr; - struct irq_node *node; + struct irq_data *node; int i = *(loff_t *) v; /* autovector interrupts */ -- cgit v1.1 From e8abf5e73cdb6c034d35ccba1f63a4801cd3dec5 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 17 Apr 2011 22:53:04 +0200 Subject: m68k/irq: Switch irq_chip methods to "struct irq_data *data" Signed-off-by: Geert Uytterhoeven Acked-by: Thomas Gleixner --- arch/m68k/amiga/amiints.c | 16 ++++++++-------- arch/m68k/amiga/cia.c | 25 ++++++++++++++----------- arch/m68k/apollo/dn_ints.c | 8 ++++++-- arch/m68k/atari/ataints.c | 30 ++++++++++++++++++++++-------- arch/m68k/include/asm/irq.h | 13 +++++++------ arch/m68k/kernel/ints.c | 23 +++++++++++++++-------- arch/m68k/mac/macints.c | 14 ++++++++++++-- arch/m68k/q40/q40ints.c | 28 +++++++++++++++++----------- arch/m68k/sun3/sun3ints.c | 14 ++++++++++++-- 9 files changed, 113 insertions(+), 58 deletions(-) diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c index 320c5d0..09a695b 100644 --- a/arch/m68k/amiga/amiints.c +++ b/arch/m68k/amiga/amiints.c @@ -45,8 +45,8 @@ #include #include -static void amiga_enable_irq(unsigned int irq); -static void amiga_disable_irq(unsigned int irq); +static void amiga_irq_enable(struct irq_data *data); +static void amiga_irq_disable(struct irq_data *data); static irqreturn_t ami_int1(int irq, void *dev_id); static irqreturn_t ami_int3(int irq, void *dev_id); static irqreturn_t ami_int4(int irq, void *dev_id); @@ -54,8 +54,8 @@ static irqreturn_t ami_int5(int irq, void *dev_id); static struct irq_chip amiga_irq_chip = { .name = "amiga", - .irq_enable = amiga_enable_irq, - .irq_disable = amiga_disable_irq, + .irq_enable = amiga_irq_enable, + .irq_disable = amiga_irq_disable, }; /* @@ -102,14 +102,14 @@ void __init amiga_init_IRQ(void) * internal data, that may not be changed by the interrupt at the same time. */ -static void amiga_enable_irq(unsigned int irq) +static void amiga_irq_enable(struct irq_data *data) { - amiga_custom.intena = IF_SETCLR | (1 << (irq - IRQ_USER)); + amiga_custom.intena = IF_SETCLR | (1 << (data->irq - IRQ_USER)); } -static void amiga_disable_irq(unsigned int irq) +static void amiga_irq_disable(struct irq_data *data) { - amiga_custom.intena = 1 << (irq - IRQ_USER); + amiga_custom.intena = 1 << (data->irq - IRQ_USER); } /* diff --git a/arch/m68k/amiga/cia.c b/arch/m68k/amiga/cia.c index 637ef53..b04b453 100644 --- a/arch/m68k/amiga/cia.c +++ b/arch/m68k/amiga/cia.c @@ -98,8 +98,9 @@ static irqreturn_t cia_handler(int irq, void *dev_id) return IRQ_HANDLED; } -static void cia_enable_irq(unsigned int irq) +static void cia_irq_enable(struct irq_data *data) { + unsigned int irq = data->irq; unsigned char mask; if (irq >= IRQ_AMIGA_CIAB) { @@ -113,8 +114,10 @@ static void cia_enable_irq(unsigned int irq) } } -static void cia_disable_irq(unsigned int irq) +static void cia_irq_disable(struct irq_data *data) { + unsigned int irq = data->irq; + if (irq >= IRQ_AMIGA_CIAB) cia_able_irq(&ciab_base, 1 << (irq - IRQ_AMIGA_CIAB)); else @@ -123,8 +126,8 @@ static void cia_disable_irq(unsigned int irq) static struct irq_chip cia_irq_chip = { .name = "cia", - .irq_enable = cia_enable_irq, - .irq_disable = cia_disable_irq, + .irq_enable = cia_irq_enable, + .irq_disable = cia_irq_disable, }; /* @@ -133,9 +136,9 @@ static struct irq_chip cia_irq_chip = { * into this chain. */ -static void auto_enable_irq(unsigned int irq) +static void auto_irq_enable(struct irq_data *data) { - switch (irq) { + switch (data->irq) { case IRQ_AUTO_2: amiga_custom.intena = IF_SETCLR | IF_PORTS; break; @@ -145,9 +148,9 @@ static void auto_enable_irq(unsigned int irq) } } -static void auto_disable_irq(unsigned int irq) +static void auto_irq_disable(struct irq_data *data) { - switch (irq) { + switch (data->irq) { case IRQ_AUTO_2: amiga_custom.intena = IF_PORTS; break; @@ -159,8 +162,8 @@ static void auto_disable_irq(unsigned int irq) static struct irq_chip auto_irq_chip = { .name = "auto", - .irq_enable = auto_enable_irq, - .irq_disable = auto_disable_irq, + .irq_enable = auto_irq_enable, + .irq_disable = auto_irq_disable, }; void __init cia_init_IRQ(struct ciabase *base) @@ -173,7 +176,7 @@ void __init cia_init_IRQ(struct ciabase *base) /* override auto int and install CIA handler */ m68k_setup_irq_chip(&auto_irq_chip, base->handler_irq, 1); - m68k_irq_startup(base->handler_irq); + m68k_irq_startup_irq(base->handler_irq); if (request_irq(base->handler_irq, cia_handler, IRQF_SHARED, base->name, base)) pr_err("Couldn't register %s interrupt\n", base->name); diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c index d6e8f334..2bdab49 100644 --- a/arch/m68k/apollo/dn_ints.c +++ b/arch/m68k/apollo/dn_ints.c @@ -12,8 +12,10 @@ void dn_process_int(unsigned int irq, struct pt_regs *fp) *(volatile unsigned char *)(picb)=0x20; } -unsigned int apollo_irq_startup(unsigned int irq) +unsigned int apollo_irq_startup(struct irq_data *data) { + unsigned int irq = data->irq; + if (irq < 8) *(volatile unsigned char *)(pica+1) &= ~(1 << irq); else @@ -21,8 +23,10 @@ unsigned int apollo_irq_startup(unsigned int irq) return 0; } -void apollo_irq_shutdown(unsigned int irq) +void apollo_irq_shutdown(struct irq_data *data) { + unsigned int irq = data->irq; + if (irq < 8) *(volatile unsigned char *)(pica+1) |= (1 << irq); else diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c index ac0ebdf..7f4e5a9 100644 --- a/arch/m68k/atari/ataints.c +++ b/arch/m68k/atari/ataints.c @@ -320,30 +320,44 @@ extern void atari_microwire_cmd(int cmd); extern int atari_SCC_reset_done; -static unsigned int atari_startup_irq(unsigned int irq) +static unsigned int atari_irq_startup(struct irq_data *data) { - m68k_irq_startup(irq); + unsigned int irq = data->irq; + + m68k_irq_startup(data); atari_turnon_irq(irq); atari_enable_irq(irq); return 0; } -static void atari_shutdown_irq(unsigned int irq) +static void atari_irq_shutdown(struct irq_data *data) { + unsigned int irq = data->irq; + atari_disable_irq(irq); atari_turnoff_irq(irq); - m68k_irq_shutdown(irq); + m68k_irq_shutdown(data); if (irq == IRQ_AUTO_4) vectors[VEC_INT4] = falcon_hblhandler; } +static void atari_irq_enable(struct irq_data *data) +{ + atari_enable_irq(data->irq); +} + +static void atari_irq_disable(struct irq_data *data) +{ + atari_disable_irq(data->irq); +} + static struct irq_chip atari_irq_chip = { .name = "atari", - .irq_startup = atari_startup_irq, - .irq_shutdown = atari_shutdown_irq, - .irq_enable = atari_enable_irq, - .irq_disable = atari_disable_irq, + .irq_startup = atari_irq_startup, + .irq_shutdown = atari_irq_shutdown, + .irq_enable = atari_irq_enable, + .irq_disable = atari_irq_disable, }; /* diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h index 3cb037c..423f064 100644 --- a/arch/m68k/include/asm/irq.h +++ b/arch/m68k/include/asm/irq.h @@ -96,14 +96,15 @@ struct irq_handler { struct irq_chip { const char *name; - unsigned int (*irq_startup)(unsigned int irq); - void (*irq_shutdown)(unsigned int irq); - void (*irq_enable)(unsigned int irq); - void (*irq_disable)(unsigned int irq); + unsigned int (*irq_startup)(struct irq_data *data); + void (*irq_shutdown)(struct irq_data *data); + void (*irq_enable)(struct irq_data *data); + void (*irq_disable)(struct irq_data *data); }; -extern unsigned int m68k_irq_startup(unsigned int); -extern void m68k_irq_shutdown(unsigned int); +extern unsigned int m68k_irq_startup(struct irq_data *data); +extern unsigned int m68k_irq_startup_irq(unsigned int irq); +extern void m68k_irq_shutdown(struct irq_data *data); /* * This function returns a new struct irq_data diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c index 8877932..404d832 100644 --- a/arch/m68k/kernel/ints.c +++ b/arch/m68k/kernel/ints.c @@ -203,9 +203,9 @@ int setup_irq(unsigned int irq, struct irq_data *node) if (!irq_list[irq]) { if (contr->irq_startup) - contr->irq_startup(irq); + contr->irq_startup(node); else - contr->irq_enable(irq); + contr->irq_enable(node); } node->next = NULL; *prev = node; @@ -270,9 +270,9 @@ void free_irq(unsigned int irq, void *dev_id) if (!irq_list[irq]) { if (contr->irq_shutdown) - contr->irq_shutdown(irq); + contr->irq_shutdown(node); else - contr->irq_disable(irq); + contr->irq_disable(node); } local_irq_restore(flags); @@ -295,7 +295,7 @@ void enable_irq(unsigned int irq) if (irq_depth[irq]) { if (!--irq_depth[irq]) { if (contr->irq_enable) - contr->irq_enable(irq); + contr->irq_enable(irq_list[irq]); } } else WARN_ON(1); @@ -318,7 +318,7 @@ void disable_irq(unsigned int irq) local_irq_save(flags); if (!irq_depth[irq]++) { if (contr->irq_disable) - contr->irq_disable(irq); + contr->irq_disable(irq_list[irq]); } local_irq_restore(flags); } @@ -329,7 +329,7 @@ void disable_irq_nosync(unsigned int irq) __attribute__((alias("disable_irq"))); EXPORT_SYMBOL(disable_irq_nosync); -unsigned int m68k_irq_startup(unsigned int irq) +unsigned int m68k_irq_startup_irq(unsigned int irq) { if (irq <= IRQ_AUTO_7) vectors[VEC_SPUR + irq] = auto_inthandler; @@ -338,8 +338,15 @@ unsigned int m68k_irq_startup(unsigned int irq) return 0; } -void m68k_irq_shutdown(unsigned int irq) +unsigned int m68k_irq_startup(struct irq_data *data) { + return m68k_irq_startup_irq(data->irq); +} + +void m68k_irq_shutdown(struct irq_data *data) +{ + unsigned int irq = data->irq; + if (irq <= IRQ_AUTO_7) vectors[VEC_SPUR + irq] = bad_inthandler; else diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c index ffa1b3f..3cee6d2 100644 --- a/arch/m68k/mac/macints.c +++ b/arch/m68k/mac/macints.c @@ -193,10 +193,20 @@ irqreturn_t mac_debug_handler(int, void *); void mac_enable_irq(unsigned int irq); void mac_disable_irq(unsigned int irq); +static void mac_irq_enable(struct irq_data *data) +{ + mac_enable_irq(data->irq); +} + +static void mac_irq_disable(struct irq_data *data) +{ + mac_disable_irq(data->irq); +} + static struct irq_chip mac_irq_chip = { .name = "mac", - .irq_enable = mac_enable_irq, - .irq_disable = mac_disable_irq, + .irq_enable = mac_irq_enable, + .irq_disable = mac_irq_disable, }; void __init mac_init_IRQ(void) diff --git a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c index fa05a03..cb245f9 100644 --- a/arch/m68k/q40/q40ints.c +++ b/arch/m68k/q40/q40ints.c @@ -35,14 +35,16 @@ */ static void q40_irq_handler(unsigned int, struct pt_regs *fp); -static void q40_enable_irq(unsigned int); -static void q40_disable_irq(unsigned int); +static void q40_irq_enable(struct irq_data *data); +static void q40_irq_disable(struct irq_data *data); unsigned short q40_ablecount[35]; unsigned short q40_state[35]; -static unsigned int q40_irq_startup(unsigned int irq) +static unsigned int q40_irq_startup(struct irq_data *data) { + unsigned int irq = data->irq; + /* test for ISA ints not implemented by HW */ switch (irq) { case 1: case 2: case 8: case 9: @@ -53,7 +55,7 @@ static unsigned int q40_irq_startup(unsigned int irq) return 0; } -static void q40_irq_shutdown(unsigned int irq) +static void q40_irq_shutdown(struct irq_data *data) { } @@ -61,8 +63,8 @@ static struct irq_chip q40_irq_chip = { .name = "q40", .irq_startup = q40_irq_startup, .irq_shutdown = q40_irq_shutdown, - .irq_enable = q40_enable_irq, - .irq_disable = q40_disable_irq, + .irq_enable = q40_irq_enable, + .irq_disable = q40_irq_disable, }; /* @@ -85,8 +87,8 @@ void __init q40_init_IRQ(void) /* setup handler for ISA ints */ m68k_setup_auto_interrupt(q40_irq_handler); - m68k_irq_startup(IRQ_AUTO_2); - m68k_irq_startup(IRQ_AUTO_4); + m68k_irq_startup_irq(IRQ_AUTO_2); + m68k_irq_startup_irq(IRQ_AUTO_4); /* now enable some ints.. */ master_outb(1, EXT_ENABLE_REG); /* ISA IRQ 5-15 */ @@ -292,20 +294,24 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp) return; } -void q40_enable_irq(unsigned int irq) +void q40_irq_enable(struct irq_data *data) { + unsigned int irq = data->irq; + if (irq >= 5 && irq <= 15) { mext_disabled--; if (mext_disabled > 0) - printk("q40_enable_irq : nested disable/enable\n"); + printk("q40_irq_enable : nested disable/enable\n"); if (mext_disabled == 0) master_outb(1, EXT_ENABLE_REG); } } -void q40_disable_irq(unsigned int irq) +void q40_irq_disable(struct irq_data *data) { + unsigned int irq = data->irq; + /* disable ISA iqs : only do something if the driver has been * verified to be Q40 "compatible" - right now IDE, NE2K * Any driver should not attempt to sleep across disable_irq !! diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c index 97fa9ed..5d45e00 100644 --- a/arch/m68k/sun3/sun3ints.c +++ b/arch/m68k/sun3/sun3ints.c @@ -86,12 +86,22 @@ static void sun3_inthandle(unsigned int irq, struct pt_regs *fp) __m68k_handle_int(irq, fp); } +static void sun3_irq_enable(struct irq_data *data) +{ + sun3_enable_irq(data->irq); +}; + +static void sun3_irq_disable(struct irq_data *data) +{ + sun3_disable_irq(data->irq); +}; + static struct irq_chip sun3_irq_chip = { .name = "sun3", .irq_startup = m68k_irq_startup, .irq_shutdown = m68k_irq_shutdown, - .irq_enable = sun3_enable_irq, - .irq_disable = sun3_disable_irq, + .irq_enable = sun3_irq_enable, + .irq_disable = sun3_irq_disable, }; void __init sun3_init_IRQ(void) -- cgit v1.1 From 13d6da35813babaa1bc8c6799b2666191911100e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 19 Apr 2011 20:10:53 +0200 Subject: m68k/irq: Rename setup_irq() to m68k_setup_irq() and make it static It has nothing to do with the standard one in Signed-off-by: Geert Uytterhoeven Acked-by: Thomas Gleixner --- arch/m68k/kernel/ints.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c index 404d832..e68a3bd 100644 --- a/arch/m68k/kernel/ints.c +++ b/arch/m68k/kernel/ints.c @@ -176,7 +176,7 @@ struct irq_data *new_irq_node(void) return NULL; } -int setup_irq(unsigned int irq, struct irq_data *node) +static int m68k_setup_irq(unsigned int irq, struct irq_data *node) { struct irq_chip *contr; struct irq_data **prev; @@ -232,7 +232,7 @@ int request_irq(unsigned int irq, node->dev_id = dev_id; node->devname = devname; - res = setup_irq(irq, node); + res = m68k_setup_irq(irq, node); if (res) node->handler = NULL; -- cgit v1.1 From 40a72c8f711bdf8ae3e4f945261ced5432dcac4d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 27 May 2011 22:33:41 +0200 Subject: m68k/irq: Extract irq_set_chip() Signed-off-by: Geert Uytterhoeven Acked-by: Thomas Gleixner --- arch/m68k/kernel/ints.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c index e68a3bd..4f9868e 100644 --- a/arch/m68k/kernel/ints.c +++ b/arch/m68k/kernel/ints.c @@ -55,6 +55,12 @@ static struct irq_data *irq_list[NR_IRQS]; static struct irq_chip *irq_chip[NR_IRQS]; static int irq_depth[NR_IRQS]; +static inline int irq_set_chip(unsigned int irq, struct irq_chip *chip) +{ + irq_chip[irq] = chip; + return 0; +} + static int m68k_first_user_vec; static struct irq_chip auto_irq_chip = { @@ -94,7 +100,7 @@ void __init init_IRQ(void) } for (i = IRQ_AUTO_1; i <= IRQ_AUTO_7; i++) - irq_chip[i] = &auto_irq_chip; + irq_set_chip(i, &auto_irq_chip); mach_init_IRQ(); } @@ -134,7 +140,7 @@ void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, BUG_ON(IRQ_USER + cnt > NR_IRQS); m68k_first_user_vec = vec; for (i = 0; i < cnt; i++) - irq_chip[IRQ_USER + i] = &user_irq_chip; + irq_set_chip(IRQ_USER + i, &user_irq_chip); *user_irqvec_fixup = vec - IRQ_USER; if (handler) *user_irqhandler_fixup = (u32)handler; @@ -157,7 +163,7 @@ void m68k_setup_irq_chip(struct irq_chip *contr, unsigned int irq, int i; for (i = 0; i < cnt; i++) - irq_chip[irq + i] = contr; + irq_set_chip(irq + i, contr); } struct irq_data *new_irq_node(void) -- cgit v1.1 From edb347256c44366888debb4f9e8477ac700a9026 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 1 Jun 2011 11:15:21 +0200 Subject: m68k/irq: Add m68k_setup_irq_controller() This is a wrapper around m68k_setup_irq_chip() that discards its dummy second parameter, to ease the future transition to genirq. Signed-off-by: Geert Uytterhoeven --- arch/m68k/amiga/amiints.c | 3 ++- arch/m68k/amiga/cia.c | 6 ++++-- arch/m68k/apollo/dn_ints.c | 3 ++- arch/m68k/atari/ataints.c | 3 ++- arch/m68k/include/asm/irq.h | 2 ++ arch/m68k/mac/macints.c | 2 +- arch/m68k/q40/q40ints.c | 3 ++- arch/m68k/sun3/sun3ints.c | 3 ++- 8 files changed, 17 insertions(+), 8 deletions(-) diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c index 09a695b..8af5ea3 100644 --- a/arch/m68k/amiga/amiints.c +++ b/arch/m68k/amiga/amiints.c @@ -80,7 +80,8 @@ void __init amiga_init_IRQ(void) if (request_irq(IRQ_AUTO_5, ami_int5, 0, "int5", NULL)) pr_err("Couldn't register int%d\n", 5); - m68k_setup_irq_chip(&amiga_irq_chip, IRQ_USER, AMI_STD_IRQS); + m68k_setup_irq_controller(&amiga_irq_chip, handle_simple_irq, IRQ_USER, + AMI_STD_IRQS); /* turn off PCMCIA interrupts */ if (AMIGAHW_PRESENT(PCMCIA)) diff --git a/arch/m68k/amiga/cia.c b/arch/m68k/amiga/cia.c index b04b453..84663ae 100644 --- a/arch/m68k/amiga/cia.c +++ b/arch/m68k/amiga/cia.c @@ -168,14 +168,16 @@ static struct irq_chip auto_irq_chip = { void __init cia_init_IRQ(struct ciabase *base) { - m68k_setup_irq_chip(&cia_irq_chip, base->cia_irq, CIA_IRQS); + m68k_setup_irq_controller(&cia_irq_chip, handle_simple_irq, + base->cia_irq, CIA_IRQS); /* clear any pending interrupt and turn off all interrupts */ cia_set_irq(base, CIA_ICR_ALL); cia_able_irq(base, CIA_ICR_ALL); /* override auto int and install CIA handler */ - m68k_setup_irq_chip(&auto_irq_chip, base->handler_irq, 1); + m68k_setup_irq_controller(&auto_irq_chip, handle_simple_irq, + base->handler_irq, 1); m68k_irq_startup_irq(base->handler_irq); if (request_irq(base->handler_irq, cia_handler, IRQF_SHARED, base->name, base)) diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c index 2bdab49..bdc4428 100644 --- a/arch/m68k/apollo/dn_ints.c +++ b/arch/m68k/apollo/dn_ints.c @@ -43,5 +43,6 @@ static struct irq_chip apollo_irq_chip = { void __init dn_init_IRQ(void) { m68k_setup_user_interrupt(VEC_USER + 96, 16, dn_process_int); - m68k_setup_irq_chip(&apollo_irq_chip, IRQ_APOLLO, 16); + m68k_setup_irq_controller(&apollo_irq_chip, handle_simple_irq, + IRQ_APOLLO, 16); } diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c index 7f4e5a9..6149ff9 100644 --- a/arch/m68k/atari/ataints.c +++ b/arch/m68k/atari/ataints.c @@ -374,7 +374,8 @@ static struct irq_chip atari_irq_chip = { void __init atari_init_IRQ(void) { m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER, NULL); - m68k_setup_irq_chip(&atari_irq_chip, 1, NUM_ATARI_SOURCES - 1); + m68k_setup_irq_controller(&atari_irq_chip, handle_simple_irq, 1, + NUM_ATARI_SOURCES - 1); /* Initialize the MFP(s) */ diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h index 423f064..d0b7efd 100644 --- a/arch/m68k/include/asm/irq.h +++ b/arch/m68k/include/asm/irq.h @@ -115,6 +115,8 @@ extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_re extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, void (*handler)(unsigned int, struct pt_regs *)); extern void m68k_setup_irq_chip(struct irq_chip *, unsigned int, unsigned int); +#define m68k_setup_irq_controller(chip, dummy, irq, cnt) \ + m68k_setup_irq_chip((chip), (irq), (cnt)) asmlinkage void m68k_handle_int(unsigned int); asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *); diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c index 3cee6d2..98497d2 100644 --- a/arch/m68k/mac/macints.c +++ b/arch/m68k/mac/macints.c @@ -214,7 +214,7 @@ void __init mac_init_IRQ(void) #ifdef DEBUG_MACINTS printk("mac_init_IRQ(): Setting things up...\n"); #endif - m68k_setup_irq_chip(&mac_irq_chip, IRQ_USER, + m68k_setup_irq_controller(&mac_irq_chip, handle_simple_irq, IRQ_USER, NUM_MAC_SOURCES - IRQ_USER); /* Make sure the SONIC interrupt is cleared or things get ugly */ #ifdef SHUTUP_SONIC diff --git a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c index cb245f9..a8a5ce8 100644 --- a/arch/m68k/q40/q40ints.c +++ b/arch/m68k/q40/q40ints.c @@ -82,7 +82,8 @@ static int disabled; void __init q40_init_IRQ(void) { - m68k_setup_irq_chip(&q40_irq_chip, 1, Q40_IRQ_MAX); + m68k_setup_irq_controller(&q40_irq_chip, handle_simple_irq, 1, + Q40_IRQ_MAX); /* setup handler for ISA ints */ m68k_setup_auto_interrupt(q40_irq_handler); diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c index 5d45e00..2046127 100644 --- a/arch/m68k/sun3/sun3ints.c +++ b/arch/m68k/sun3/sun3ints.c @@ -109,7 +109,8 @@ void __init sun3_init_IRQ(void) *sun3_intreg = 1; m68k_setup_auto_interrupt(sun3_inthandle); - m68k_setup_irq_chip(&sun3_irq_chip, IRQ_AUTO_1, 7); + m68k_setup_irq_controller(&sun3_irq_chip, handle_simple_irq, + IRQ_AUTO_1, 7); m68k_setup_user_interrupt(VEC_USER, 128, NULL); if (request_irq(IRQ_AUTO_5, sun3_int5, 0, "int5", NULL)) -- cgit v1.1 From 1425df87c25b15400c9f26d57821bcfe01286b2a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 1 Jul 2011 20:39:19 +0200 Subject: m68k/irq: Rename {,__}m68k_handle_int() - Rename m68k_handle_int() to generic_handle_irq(), and drop the unneeded asmlinkage, - Rename __m68k_handle_int() to do_IRQ(). Signed-off-by: Geert Uytterhoeven --- arch/m68k/amiga/amiints.c | 24 ++++++++++++------------ arch/m68k/amiga/cia.c | 2 +- arch/m68k/apollo/dn_ints.c | 2 +- arch/m68k/include/asm/irq.h | 4 ++-- arch/m68k/kernel/entry_mm.S | 4 ++-- arch/m68k/kernel/ints.c | 10 +++++----- arch/m68k/mac/baboon.c | 2 +- arch/m68k/mac/oss.c | 4 ++-- arch/m68k/mac/psc.c | 2 +- arch/m68k/mac/via.c | 6 +++--- arch/m68k/q40/q40ints.c | 8 ++++---- arch/m68k/sun3/sun3ints.c | 2 +- 12 files changed, 35 insertions(+), 35 deletions(-) diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c index 8af5ea3..0daa7fc 100644 --- a/arch/m68k/amiga/amiints.c +++ b/arch/m68k/amiga/amiints.c @@ -124,19 +124,19 @@ static irqreturn_t ami_int1(int irq, void *dev_id) /* if serial transmit buffer empty, interrupt */ if (ints & IF_TBE) { amiga_custom.intreq = IF_TBE; - m68k_handle_int(IRQ_AMIGA_TBE); + generic_handle_irq(IRQ_AMIGA_TBE); } /* if floppy disk transfer complete, interrupt */ if (ints & IF_DSKBLK) { amiga_custom.intreq = IF_DSKBLK; - m68k_handle_int(IRQ_AMIGA_DSKBLK); + generic_handle_irq(IRQ_AMIGA_DSKBLK); } /* if software interrupt set, interrupt */ if (ints & IF_SOFT) { amiga_custom.intreq = IF_SOFT; - m68k_handle_int(IRQ_AMIGA_SOFT); + generic_handle_irq(IRQ_AMIGA_SOFT); } return IRQ_HANDLED; } @@ -148,19 +148,19 @@ static irqreturn_t ami_int3(int irq, void *dev_id) /* if a blitter interrupt */ if (ints & IF_BLIT) { amiga_custom.intreq = IF_BLIT; - m68k_handle_int(IRQ_AMIGA_BLIT); + generic_handle_irq(IRQ_AMIGA_BLIT); } /* if a copper interrupt */ if (ints & IF_COPER) { amiga_custom.intreq = IF_COPER; - m68k_handle_int(IRQ_AMIGA_COPPER); + generic_handle_irq(IRQ_AMIGA_COPPER); } /* if a vertical blank interrupt */ if (ints & IF_VERTB) { amiga_custom.intreq = IF_VERTB; - m68k_handle_int(IRQ_AMIGA_VERTB); + generic_handle_irq(IRQ_AMIGA_VERTB); } return IRQ_HANDLED; } @@ -172,25 +172,25 @@ static irqreturn_t ami_int4(int irq, void *dev_id) /* if audio 0 interrupt */ if (ints & IF_AUD0) { amiga_custom.intreq = IF_AUD0; - m68k_handle_int(IRQ_AMIGA_AUD0); + generic_handle_irq(IRQ_AMIGA_AUD0); } /* if audio 1 interrupt */ if (ints & IF_AUD1) { amiga_custom.intreq = IF_AUD1; - m68k_handle_int(IRQ_AMIGA_AUD1); + generic_handle_irq(IRQ_AMIGA_AUD1); } /* if audio 2 interrupt */ if (ints & IF_AUD2) { amiga_custom.intreq = IF_AUD2; - m68k_handle_int(IRQ_AMIGA_AUD2); + generic_handle_irq(IRQ_AMIGA_AUD2); } /* if audio 3 interrupt */ if (ints & IF_AUD3) { amiga_custom.intreq = IF_AUD3; - m68k_handle_int(IRQ_AMIGA_AUD3); + generic_handle_irq(IRQ_AMIGA_AUD3); } return IRQ_HANDLED; } @@ -202,13 +202,13 @@ static irqreturn_t ami_int5(int irq, void *dev_id) /* if serial receive buffer full interrupt */ if (ints & IF_RBF) { /* acknowledge of IF_RBF must be done by the serial interrupt */ - m68k_handle_int(IRQ_AMIGA_RBF); + generic_handle_irq(IRQ_AMIGA_RBF); } /* if a disk sync interrupt */ if (ints & IF_DSKSYN) { amiga_custom.intreq = IF_DSKSYN; - m68k_handle_int(IRQ_AMIGA_DSKSYN); + generic_handle_irq(IRQ_AMIGA_DSKSYN); } return IRQ_HANDLED; } diff --git a/arch/m68k/amiga/cia.c b/arch/m68k/amiga/cia.c index 84663ae..18c0e29 100644 --- a/arch/m68k/amiga/cia.c +++ b/arch/m68k/amiga/cia.c @@ -93,7 +93,7 @@ static irqreturn_t cia_handler(int irq, void *dev_id) amiga_custom.intreq = base->int_mask; for (; ints; mach_irq++, ints >>= 1) { if (ints & 1) - m68k_handle_int(mach_irq); + generic_handle_irq(mach_irq); } return IRQ_HANDLED; } diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c index bdc4428..4b76431 100644 --- a/arch/m68k/apollo/dn_ints.c +++ b/arch/m68k/apollo/dn_ints.c @@ -6,7 +6,7 @@ void dn_process_int(unsigned int irq, struct pt_regs *fp) { - __m68k_handle_int(irq, fp); + do_IRQ(irq, fp); *(volatile unsigned char *)(pica)=0x20; *(volatile unsigned char *)(picb)=0x20; diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h index d0b7efd..9a2bae8 100644 --- a/arch/m68k/include/asm/irq.h +++ b/arch/m68k/include/asm/irq.h @@ -118,8 +118,8 @@ extern void m68k_setup_irq_chip(struct irq_chip *, unsigned int, unsigned int); #define m68k_setup_irq_controller(chip, dummy, irq, cnt) \ m68k_setup_irq_chip((chip), (irq), (cnt)) -asmlinkage void m68k_handle_int(unsigned int); -asmlinkage void __m68k_handle_int(unsigned int, struct pt_regs *); +extern void generic_handle_irq(unsigned int); +asmlinkage void do_IRQ(int irq, struct pt_regs *regs); #else #define irq_canonicalize(irq) (irq) diff --git a/arch/m68k/kernel/entry_mm.S b/arch/m68k/kernel/entry_mm.S index bd0ec05..f5927d09 100644 --- a/arch/m68k/kernel/entry_mm.S +++ b/arch/m68k/kernel/entry_mm.S @@ -207,7 +207,7 @@ ENTRY(auto_inthandler) movel %sp,%sp@- movel %d0,%sp@- | put vector # on stack auto_irqhandler_fixup = . + 2 - jsr __m68k_handle_int | process the IRQ + jsr do_IRQ | process the IRQ addql #8,%sp | pop parameters off stack ret_from_interrupt: @@ -241,7 +241,7 @@ user_irqvec_fixup = . + 2 movel %sp,%sp@- movel %d0,%sp@- | put vector # on stack user_irqhandler_fixup = . + 2 - jsr __m68k_handle_int | process the IRQ + jsr do_IRQ | process the IRQ addql #8,%sp | pop parameters off stack subqb #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1) diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c index 4f9868e..15dbbe2 100644 --- a/arch/m68k/kernel/ints.c +++ b/arch/m68k/kernel/ints.c @@ -110,7 +110,7 @@ void __init init_IRQ(void) * @handler: called from auto vector interrupts * * setup the handler to be called from auto vector interrupts instead of the - * standard __m68k_handle_int(), it will be called with irq numbers in the range + * standard do_IRQ(), it will be called with irq numbers in the range * from IRQ_AUTO_1 - IRQ_AUTO_7. */ void __init m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)) @@ -129,7 +129,7 @@ void __init m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_re * setup user vector interrupts, this includes activating the specified range * of interrupts, only then these interrupts can be requested (note: this is * different from auto vector interrupts). An optional handler can be installed - * to be called instead of the default __m68k_handle_int(), it will be called + * to be called instead of the default do_IRQ(), it will be called * with irq numbers starting from IRQ_USER. */ void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, @@ -398,7 +398,7 @@ unsigned int irq_canonicalize(unsigned int irq) EXPORT_SYMBOL(irq_canonicalize); -asmlinkage void m68k_handle_int(unsigned int irq) +void generic_handle_irq(unsigned int irq) { struct irq_data *node; kstat_cpu(0).irqs[irq]++; @@ -409,11 +409,11 @@ asmlinkage void m68k_handle_int(unsigned int irq) } while (node); } -asmlinkage void __m68k_handle_int(unsigned int irq, struct pt_regs *regs) +asmlinkage void do_IRQ(int irq, struct pt_regs *regs) { struct pt_regs *old_regs; old_regs = set_irq_regs(regs); - m68k_handle_int(irq); + generic_handle_irq(irq); set_irq_regs(old_regs); } diff --git a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c index 2a96beb..f264791 100644 --- a/arch/m68k/mac/baboon.c +++ b/arch/m68k/mac/baboon.c @@ -72,7 +72,7 @@ static irqreturn_t baboon_irq(int irq, void *dev_id) do { if (events & irq_bit) { baboon->mb_ifr &= ~irq_bit; - m68k_handle_int(irq_num); + generic_handle_irq(irq_num); } irq_bit <<= 1; irq_num++; diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c index a9c0f5a..ad51241 100644 --- a/arch/m68k/mac/oss.c +++ b/arch/m68k/mac/oss.c @@ -113,7 +113,7 @@ static irqreturn_t oss_irq(int irq, void *dev_id) /* FIXME: call sound handler */ } else if (events & OSS_IP_SCSI) { oss->irq_pending &= ~OSS_IP_SCSI; - m68k_handle_int(IRQ_MAC_SCSI); + generic_handle_irq(IRQ_MAC_SCSI); } else { /* FIXME: error check here? */ } @@ -148,7 +148,7 @@ static irqreturn_t oss_nubus_irq(int irq, void *dev_id) irq_bit >>= 1; if (events & irq_bit) { oss->irq_pending &= ~irq_bit; - m68k_handle_int(NUBUS_SOURCE_BASE + i); + generic_handle_irq(NUBUS_SOURCE_BASE + i); } } while(events & (irq_bit - 1)); return IRQ_HANDLED; diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c index a4c3eb6..26c2b65 100644 --- a/arch/m68k/mac/psc.c +++ b/arch/m68k/mac/psc.c @@ -152,7 +152,7 @@ irqreturn_t psc_irq(int irq, void *dev_id) do { if (events & irq_bit) { psc_write_byte(pIFR, irq_bit); - m68k_handle_int(irq_num); + generic_handle_irq(irq_num); } irq_num++; irq_bit <<= 1; diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c index e71166d..0678570 100644 --- a/arch/m68k/mac/via.c +++ b/arch/m68k/mac/via.c @@ -460,7 +460,7 @@ irqreturn_t via1_irq(int irq, void *dev_id) do { if (events & irq_bit) { via1[vIFR] = irq_bit; - m68k_handle_int(irq_num); + generic_handle_irq(irq_num); } ++irq_num; irq_bit <<= 1; @@ -482,7 +482,7 @@ irqreturn_t via2_irq(int irq, void *dev_id) do { if (events & irq_bit) { via2[gIFR] = irq_bit | rbv_clear; - m68k_handle_int(irq_num); + generic_handle_irq(irq_num); } ++irq_num; irq_bit <<= 1; @@ -514,7 +514,7 @@ irqreturn_t via_nubus_irq(int irq, void *dev_id) do { if (events & slot_bit) { events &= ~slot_bit; - m68k_handle_int(slot_irq); + generic_handle_irq(slot_irq); } --slot_irq; slot_bit >>= 1; diff --git a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c index a8a5ce8..afe600c 100644 --- a/arch/m68k/q40/q40ints.c +++ b/arch/m68k/q40/q40ints.c @@ -220,11 +220,11 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp) switch (irq) { case 4: case 6: - __m68k_handle_int(Q40_IRQ_SAMPLE, fp); + do_IRQ(Q40_IRQ_SAMPLE, fp); return; } if (mir & Q40_IRQ_FRAME_MASK) { - __m68k_handle_int(Q40_IRQ_FRAME, fp); + do_IRQ(Q40_IRQ_FRAME, fp); master_outb(-1, FRAME_CLEAR_REG); } if ((mir & Q40_IRQ_SER_MASK) || (mir & Q40_IRQ_EXT_MASK)) { @@ -259,7 +259,7 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp) goto iirq; } q40_state[irq] |= IRQ_INPROGRESS; - __m68k_handle_int(irq, fp); + do_IRQ(irq, fp); q40_state[irq] &= ~IRQ_INPROGRESS; /* naively enable everything, if that fails than */ @@ -290,7 +290,7 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp) mir = master_inb(IIRQ_REG); /* should test whether keyboard irq is really enabled, doing it in defhand */ if (mir & Q40_IRQ_KEYB_MASK) - __m68k_handle_int(Q40_IRQ_KEYBOARD, fp); + do_IRQ(Q40_IRQ_KEYBOARD, fp); return; } diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c index 2046127..20ffee7 100644 --- a/arch/m68k/sun3/sun3ints.c +++ b/arch/m68k/sun3/sun3ints.c @@ -83,7 +83,7 @@ static void sun3_inthandle(unsigned int irq, struct pt_regs *fp) { *sun3_intreg &= ~(1 << irq); - __m68k_handle_int(irq, fp); + do_IRQ(irq, fp); } static void sun3_irq_enable(struct irq_data *data) -- cgit v1.1 From 5a2394534b160ce18f9a705cf9de40e77648f8a2 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 13 Jul 2011 22:33:13 +0200 Subject: m68k/irq: Remove obsolete IRQ_FLG_* users The m68k core irq code stopped honoring these flags during the irq restructuring in 2006. Signed-off-by: Geert Uytterhoeven --- arch/m68k/amiga/amiints.c | 29 ----------------------------- arch/m68k/hp300/time.c | 2 +- arch/m68k/kernel/ints.c | 19 ------------------- arch/m68k/mac/iop.c | 10 ++++------ arch/m68k/mac/oss.c | 13 +++++-------- arch/m68k/mac/via.c | 22 ++++++++-------------- arch/m68k/mvme147/config.c | 3 +-- drivers/macintosh/via-macii.c | 2 +- drivers/macintosh/via-maciisi.c | 4 ++-- 9 files changed, 22 insertions(+), 82 deletions(-) diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c index 0daa7fc..e5f3033 100644 --- a/arch/m68k/amiga/amiints.c +++ b/arch/m68k/amiga/amiints.c @@ -4,35 +4,6 @@ * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive * for more details. - * - * 11/07/96: rewritten interrupt handling, irq lists are exists now only for - * this sources where it makes sense (VERTB/PORTS/EXTER) and you must - * be careful that dev_id for this sources is unique since this the - * only possibility to distinguish between different handlers for - * free_irq. irq lists also have different irq flags: - * - IRQ_FLG_FAST: handler is inserted at top of list (after other - * fast handlers) - * - IRQ_FLG_SLOW: handler is inserted at bottom of list and before - * they're executed irq level is set to the previous - * one, but handlers don't need to be reentrant, if - * reentrance occurred, slow handlers will be just - * called again. - * The whole interrupt handling for CIAs is moved to cia.c - * /Roman Zippel - * - * 07/08/99: rewamp of the interrupt handling - we now have two types of - * interrupts, normal and fast handlers, fast handlers being - * marked with IRQF_DISABLED and runs with all other interrupts - * disabled. Normal interrupts disable their own source but - * run with all other interrupt sources enabled. - * PORTS and EXTER interrupts are always shared even if the - * drivers do not explicitly mark this when calling - * request_irq which they really should do. - * This is similar to the way interrupts are handled on all - * other architectures and makes a ton of sense besides - * having the advantage of making it easier to share - * drivers. - * /Jes */ #include diff --git a/arch/m68k/hp300/time.c b/arch/m68k/hp300/time.c index f6312c7..c87fe69 100644 --- a/arch/m68k/hp300/time.c +++ b/arch/m68k/hp300/time.c @@ -70,7 +70,7 @@ void __init hp300_sched_init(irq_handler_t vector) asm volatile(" movpw %0,%1@(5)" : : "d" (INTVAL), "a" (CLOCKBASE)); - if (request_irq(IRQ_AUTO_6, hp300_tick, IRQ_FLG_STD, "timer tick", vector)) + if (request_irq(IRQ_AUTO_6, hp300_tick, 0, "timer tick", vector)) pr_err("Couldn't register timer interrupt\n"); out_8(CLOCKBASE + CLKCR2, 0x1); /* select CR1 */ diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c index 15dbbe2..f6a4698 100644 --- a/arch/m68k/kernel/ints.c +++ b/arch/m68k/kernel/ints.c @@ -4,25 +4,6 @@ * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive * for more details. - * - * 07/03/96: Timer initialization, and thus mach_sched_init(), - * removed from request_irq() and moved to init_time(). - * We should therefore consider renaming our add_isr() and - * remove_isr() to request_irq() and free_irq() - * respectively, so they are compliant with the other - * architectures. /Jes - * 11/07/96: Changed all add_/remove_isr() to request_/free_irq() calls. - * Removed irq list support, if any machine needs an irq server - * it must implement this itself (as it's already done), instead - * only default handler are used with mach_default_handler. - * request_irq got some flags different from other architectures: - * - IRQ_FLG_REPLACE : Replace an existing handler (the default one - * can be replaced without this flag) - * - IRQ_FLG_LOCK : handler can't be replaced - * There are other machine depending flags, see there - * If you want to replace a default handler you should know what - * you're doing, since it might handle different other irq sources - * which must be served /Roman Zippel */ #include diff --git a/arch/m68k/mac/iop.c b/arch/m68k/mac/iop.c index 1ad4e9d..a5462cc 100644 --- a/arch/m68k/mac/iop.c +++ b/arch/m68k/mac/iop.c @@ -305,15 +305,13 @@ void __init iop_register_interrupts(void) { if (iop_ism_present) { if (oss_present) { - if (request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq, - IRQ_FLG_LOCK, "ISM IOP", - (void *) IOP_NUM_ISM)) + if (request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq, 0, + "ISM IOP", (void *)IOP_NUM_ISM)) pr_err("Couldn't register ISM IOP interrupt\n"); oss_irq_enable(IRQ_MAC_ADB); } else { - if (request_irq(IRQ_VIA2_0, iop_ism_irq, - IRQ_FLG_LOCK|IRQ_FLG_FAST, "ISM IOP", - (void *) IOP_NUM_ISM)) + if (request_irq(IRQ_VIA2_0, iop_ism_irq, 0, "ISM IOP", + (void *)IOP_NUM_ISM)) pr_err("Couldn't register ISM IOP interrupt\n"); } if (!iop_alive(iop_base[IOP_NUM_ISM])) { diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c index ad51241..1eb60f0 100644 --- a/arch/m68k/mac/oss.c +++ b/arch/m68k/mac/oss.c @@ -65,17 +65,14 @@ void __init oss_init(void) void __init oss_register_interrupts(void) { - if (request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK, - "scsi", (void *) oss)) + if (request_irq(OSS_IRQLEV_SCSI, oss_irq, 0, "scsi", (void *)oss)) pr_err("Couldn't register %s interrupt\n", "scsi"); - if (request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK, - "nubus", (void *) oss)) + if (request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, 0, "nubus", + (void *)oss)) pr_err("Couldn't register %s interrupt\n", "nubus"); - if (request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK, - "sound", (void *) oss)) + if (request_irq(OSS_IRQLEV_SOUND, oss_irq, 0, "sound", (void *)oss)) pr_err("Couldn't register %s interrupt\n", "sound"); - if (request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK, - "via1", (void *) via1)) + if (request_irq(OSS_IRQLEV_VIA1, via1_irq, 0, "via1", (void *)via1)) pr_err("Couldn't register %s interrupt\n", "via1"); } diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c index 0678570..af9ed33 100644 --- a/arch/m68k/mac/via.c +++ b/arch/m68k/mac/via.c @@ -281,7 +281,7 @@ void __init via_init_clock(irq_handler_t func) via1[vT1CL] = MAC_CLOCK_LOW; via1[vT1CH] = MAC_CLOCK_HIGH; - if (request_irq(IRQ_MAC_TIMER_1, func, IRQ_FLG_LOCK, "timer", func)) + if (request_irq(IRQ_MAC_TIMER_1, func, 0, "timer", func)) pr_err("Couldn't register %s interrupt\n", "timer"); } @@ -292,25 +292,19 @@ void __init via_init_clock(irq_handler_t func) void __init via_register_interrupts(void) { if (via_alt_mapping) { - if (request_irq(IRQ_AUTO_1, via1_irq, - IRQ_FLG_LOCK|IRQ_FLG_FAST, "software", - (void *) via1)) + if (request_irq(IRQ_AUTO_1, via1_irq, 0, "software", + (void *)via1)) pr_err("Couldn't register %s interrupt\n", "software"); - if (request_irq(IRQ_AUTO_6, via1_irq, - IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1", - (void *) via1)) + if (request_irq(IRQ_AUTO_6, via1_irq, 0, "via1", (void *)via1)) pr_err("Couldn't register %s interrupt\n", "via1"); } else { - if (request_irq(IRQ_AUTO_1, via1_irq, - IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1", - (void *) via1)) + if (request_irq(IRQ_AUTO_1, via1_irq, 0, "via1", (void *)via1)) pr_err("Couldn't register %s interrupt\n", "via1"); } - if (request_irq(IRQ_AUTO_2, via2_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST, - "via2", (void *) via2)) + if (request_irq(IRQ_AUTO_2, via2_irq, 0, "via2", (void *)via2)) pr_err("Couldn't register %s interrupt\n", "via2"); - if (request_irq(IRQ_MAC_NUBUS, via_nubus_irq, - IRQ_FLG_LOCK|IRQ_FLG_FAST, "nubus", (void *) via2)) + if (request_irq(IRQ_MAC_NUBUS, via_nubus_irq, 0, "nubus", + (void *)via2)) pr_err("Couldn't register %s interrupt\n", "nubus"); } diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c index 6cb9c3a..01f2adf 100644 --- a/arch/m68k/mvme147/config.c +++ b/arch/m68k/mvme147/config.c @@ -114,8 +114,7 @@ static irqreturn_t mvme147_timer_int (int irq, void *dev_id) void mvme147_sched_init (irq_handler_t timer_routine) { tick_handler = timer_routine; - if (request_irq(PCC_IRQ_TIMER1, mvme147_timer_int, IRQ_FLG_REPLACE, - "timer 1", NULL)) + if (request_irq(PCC_IRQ_TIMER1, mvme147_timer_int, 0, "timer 1", NULL)) pr_err("Couldn't register timer interrupt\n"); /* Init the clock with a value */ diff --git a/drivers/macintosh/via-macii.c b/drivers/macintosh/via-macii.c index 817f37a..c9570fc 100644 --- a/drivers/macintosh/via-macii.c +++ b/drivers/macintosh/via-macii.c @@ -159,7 +159,7 @@ int macii_init(void) err = macii_init_via(); if (err) goto out; - err = request_irq(IRQ_MAC_ADB, macii_interrupt, IRQ_FLG_LOCK, "ADB", + err = request_irq(IRQ_MAC_ADB, macii_interrupt, 0, "ADB", macii_interrupt); if (err) goto out; diff --git a/drivers/macintosh/via-maciisi.c b/drivers/macintosh/via-maciisi.c index 9ab5b0c..34d02a9 100644 --- a/drivers/macintosh/via-maciisi.c +++ b/drivers/macintosh/via-maciisi.c @@ -122,8 +122,8 @@ maciisi_init(void) return err; } - if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, IRQ_FLG_LOCK | IRQ_FLG_FAST, - "ADB", maciisi_interrupt)) { + if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, 0, "ADB", + maciisi_interrupt)) { printk(KERN_ERR "maciisi_init: can't get irq %d\n", IRQ_MAC_ADB); return -EAGAIN; } -- cgit v1.1 From 4936f63cb790e265eb30a1e1630bb90bd6af0e7a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 21 Apr 2011 22:50:52 +0200 Subject: m68k/irq: Add genirq support Disabled on all platforms for now Signed-off-by: Geert Uytterhoeven [v1] Acked-by: Thomas Gleixner --- arch/m68k/Kconfig | 17 ++++++++++++++ arch/m68k/include/asm/hardirq.h | 5 ++++ arch/m68k/include/asm/irq.h | 41 +++++++++++++++++++++++++------- arch/m68k/kernel/Makefile | 9 +++++-- arch/m68k/kernel/ints.c | 52 ++++++++++++++++++++++++++++++++++++++++- 5 files changed, 112 insertions(+), 12 deletions(-) diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 6c28582..a7597e1 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -84,6 +84,23 @@ config MMU_SUN3 bool depends on MMU && !MMU_MOTOROLA +config USE_GENERIC_HARDIRQS + bool "Use genirq" + depends on MMU + depends on !AMIGA + depends on !ATARI + depends on !MAC + depends on !APOLLO + depends on !MVME147 + depends on !MVME16x + depends on !BVME6000 + depends on !HP300 + depends on !SUN3X + depends on !Q40 + depends on !SUN3 + select HAVE_GENERIC_HARDIRQS + select GENERIC_IRQ_SHOW + menu "Platform setup" source arch/m68k/Kconfig.cpu diff --git a/arch/m68k/include/asm/hardirq.h b/arch/m68k/include/asm/hardirq.h index 870e534..db30ed2 100644 --- a/arch/m68k/include/asm/hardirq.h +++ b/arch/m68k/include/asm/hardirq.h @@ -18,6 +18,11 @@ #ifdef CONFIG_MMU +static inline void ack_bad_irq(unsigned int irq) +{ + pr_crit("unexpected IRQ trap at vector %02x\n", irq); +} + /* entry.S is sensitive to the offsets of these fields */ typedef struct { unsigned int __softirq_pending; diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h index 9a2bae8..518e61f 100644 --- a/arch/m68k/include/asm/irq.h +++ b/arch/m68k/include/asm/irq.h @@ -27,11 +27,6 @@ #ifdef CONFIG_MMU -#include -#include -#include -#include - /* * Interrupt source definitions * General interrupt sources are the level 1-7. @@ -54,10 +49,6 @@ #define IRQ_USER 8 -extern unsigned int irq_canonicalize(unsigned int irq); - -struct pt_regs; - /* * various flags for request_irq() - the Amiga now uses the standard * mechanism like all other architectures - IRQF_DISABLED and @@ -71,6 +62,15 @@ struct pt_regs; #define IRQ_FLG_STD (0x8000) /* internally used */ #endif +#ifndef CONFIG_GENERIC_HARDIRQS + +#include +#include +#include +#include + +struct pt_regs; + /* * This structure is used to chain together the ISRs for a particular * interrupt source (if it supports chaining). @@ -121,10 +121,33 @@ extern void m68k_setup_irq_chip(struct irq_chip *, unsigned int, unsigned int); extern void generic_handle_irq(unsigned int); asmlinkage void do_IRQ(int irq, struct pt_regs *regs); +#else /* CONFIG_GENERIC_HARDIRQS */ + +struct irq_data; +struct irq_chip; +struct irq_desc; +extern unsigned int m68k_irq_startup(struct irq_data *data); +extern unsigned int m68k_irq_startup_irq(unsigned int irq); +extern void m68k_irq_shutdown(struct irq_data *data); +extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, + struct pt_regs *)); +extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, + void (*handler)(unsigned int, + struct pt_regs *)); +extern void m68k_setup_irq_controller(struct irq_chip *, + void (*handle)(unsigned int irq, + struct irq_desc *desc), + unsigned int irq, unsigned int cnt); + +#endif /* CONFIG_GENERIC_HARDIRQS */ + +extern unsigned int irq_canonicalize(unsigned int irq); + #else #define irq_canonicalize(irq) (irq) #endif /* CONFIG_MMU */ asmlinkage void do_IRQ(int irq, struct pt_regs *regs); +extern atomic_t irq_err_count; #endif /* _M68K_IRQ_H_ */ diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile index e7f0f2e..1414257 100644 --- a/arch/m68k/kernel/Makefile +++ b/arch/m68k/kernel/Makefile @@ -9,13 +9,18 @@ extra-y += vmlinux.lds obj-y := entry.o m68k_ksyms.o module.o process.o ptrace.o setup.o signal.o \ sys_m68k.o syscalltable.o time.o traps.o -obj-$(CONFIG_MMU) += ints.o devres.o vectors.o +obj-$(CONFIG_MMU) += ints.o vectors.o devres-$(CONFIG_MMU) = ../../../kernel/irq/devres.o ifndef CONFIG_MMU_SUN3 obj-y += dma.o endif ifndef CONFIG_MMU -obj-y += init_task.o irq.o +obj-y += init_task.o +endif +ifdef CONFIG_GENERIC_HARDIRQS +obj-y += irq.o +else +obj-y += devres.o endif diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c index f6a4698..cea439f 100644 --- a/arch/m68k/kernel/ints.c +++ b/arch/m68k/kernel/ints.c @@ -31,6 +31,7 @@ extern u32 auto_irqhandler_fixup[]; extern u32 user_irqhandler_fixup[]; extern u16 user_irqvec_fixup[]; +#ifndef CONFIG_GENERIC_HARDIRQS /* table for system interrupt handlers */ static struct irq_data *irq_list[NR_IRQS]; static struct irq_chip *irq_chip[NR_IRQS]; @@ -41,6 +42,8 @@ static inline int irq_set_chip(unsigned int irq, struct irq_chip *chip) irq_chip[irq] = chip; return 0; } +#define irq_set_chip_and_handler(irq, chip, dummy) irq_set_chip(irq, chip) +#endif /* !CONFIG_GENERIC_HARDIRQS */ static int m68k_first_user_vec; @@ -56,8 +59,10 @@ static struct irq_chip user_irq_chip = { .irq_shutdown = m68k_irq_shutdown, }; +#ifndef CONFIG_GENERIC_HARDIRQS #define NUM_IRQ_NODES 100 static struct irq_data nodes[NUM_IRQ_NODES]; +#endif /* !CONFIG_GENERIC_HARDIRQS */ /* * void init_IRQ(void) @@ -81,7 +86,7 @@ void __init init_IRQ(void) } for (i = IRQ_AUTO_1; i <= IRQ_AUTO_7; i++) - irq_set_chip(i, &auto_irq_chip); + irq_set_chip_and_handler(i, &auto_irq_chip, handle_simple_irq); mach_init_IRQ(); } @@ -128,6 +133,35 @@ void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, flush_icache(); } +#ifdef CONFIG_GENERIC_HARDIRQS + +/** + * m68k_setup_irq_controller + * @chip: irq chip which controls specified irq + * @handle: flow handler which handles specified irq + * @irq: first irq to be managed by the controller + * @cnt: number of irqs to be managed by the controller + * + * Change the controller for the specified range of irq, which will be used to + * manage these irq. auto/user irq already have a default controller, which can + * be changed as well, but the controller probably should use m68k_irq_startup/ + * m68k_irq_shutdown. + */ +void m68k_setup_irq_controller(struct irq_chip *chip, + irq_flow_handler_t handle, unsigned int irq, + unsigned int cnt) +{ + int i; + + for (i = 0; i < cnt; i++) { + irq_set_chip(irq + i, chip); + if (handle) + irq_set_handler(irq + i, handle); + } +} + +#else /* !CONFIG_GENERIC_HARDIRQS */ + /** * m68k_setup_irq_chip * @contr: irq controller which controls specified irq @@ -316,6 +350,8 @@ void disable_irq_nosync(unsigned int irq) __attribute__((alias("disable_irq"))); EXPORT_SYMBOL(disable_irq_nosync); +#endif /* !CONFIG_GENERIC_HARDIRQS */ + unsigned int m68k_irq_startup_irq(unsigned int irq) { if (irq <= IRQ_AUTO_7) @@ -341,6 +377,8 @@ void m68k_irq_shutdown(struct irq_data *data) } +#ifndef CONFIG_GENERIC_HARDIRQS + /* * Do we need these probe functions on the m68k? * @@ -367,6 +405,7 @@ int probe_irq_off (unsigned long irqs) } EXPORT_SYMBOL(probe_irq_off); +#endif /* CONFIG_GENERIC_HARDIRQS */ unsigned int irq_canonicalize(unsigned int irq) { @@ -379,6 +418,7 @@ unsigned int irq_canonicalize(unsigned int irq) EXPORT_SYMBOL(irq_canonicalize); +#ifndef CONFIG_GENERIC_HARDIRQS void generic_handle_irq(unsigned int irq) { struct irq_data *node; @@ -428,3 +468,13 @@ void init_irq_proc(void) /* Insert /proc/irq driver here */ } #endif + +#else /* CONFIG_GENERIC_HARDIRQS */ + +asmlinkage void handle_badint(struct pt_regs *regs) +{ + atomic_inc(&irq_err_count); + pr_warn("unexpected interrupt from %u\n", regs->vector); +} + +#endif /* CONFIG_GENERIC_HARDIRQS */ -- cgit v1.1 From e59629ddc6eddbd00e81b4afb814583cfcc4706d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 29 Apr 2011 23:35:21 +0200 Subject: m68k/atari: Convert Atari to genirq Signed-off-by: Geert Uytterhoeven [v1] Acked-by: Thomas Gleixner --- arch/m68k/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index a7597e1..9d60f40 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -88,7 +88,6 @@ config USE_GENERIC_HARDIRQS bool "Use genirq" depends on MMU depends on !AMIGA - depends on !ATARI depends on !MAC depends on !APOLLO depends on !MVME147 -- cgit v1.1 From 34971bad3a1511db7b76eeb2337819967a135075 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 18 Aug 2011 19:36:30 +0200 Subject: m68k/atari: Remove code and comments about different irq types This code was obsoleted during the irq restructuring in 2006. Signed-off-by: Geert Uytterhoeven --- arch/m68k/atari/ataints.c | 236 ---------------------------------------------- 1 file changed, 236 deletions(-) diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c index 6149ff9..af54455 100644 --- a/arch/m68k/atari/ataints.c +++ b/arch/m68k/atari/ataints.c @@ -60,244 +60,8 @@ * ): Autovector interrupts are 1..7, then follow ST-MFP, * TT-MFP, SCC, and finally VME interrupts. Vector numbers for the latter can * be allocated by atari_register_vme_int(). - * - * Each interrupt can be of three types: - * - * - SLOW: The handler runs with all interrupts enabled, except the one it - * was called by (to avoid reentering). This should be the usual method. - * But it is currently possible only for MFP ints, since only the MFP - * offers an easy way to mask interrupts. - * - * - FAST: The handler runs with all interrupts disabled. This should be used - * only for really fast handlers, that just do actions immediately - * necessary, and let the rest do a bottom half or task queue. - * - * - PRIORITIZED: The handler can be interrupted by higher-level ints - * (greater IPL, no MFP priorities!). This is the method of choice for ints - * which should be slow, but are not from a MFP. - * - * The feature of more than one handler for one int source is still there, but - * only applicable if all handers are of the same type. To not slow down - * processing of ints with only one handler by the chaining feature, the list - * calling function atari_call_irq_list() is only plugged in at the time the - * second handler is registered. - * - * Implementation notes: For fast-as-possible int handling, there are separate - * entry points for each type (slow/fast/prio). The assembler handler calls - * the irq directly in the usual case, no C wrapper is involved. In case of - * multiple handlers, atari_call_irq_list() is registered as handler and calls - * in turn the real irq's. To ease access from assembler level to the irq - * function pointer and accompanying data, these two are stored in a separate - * array, irq_handler[]. The rest of data (type, name) are put into a second - * array, irq_param, that is accessed from C only. For each slow interrupt (32 - * in all) there are separate handler functions, which makes it possible to - * hard-code the MFP register address and value, are necessary to mask the - * int. If there'd be only one generic function, lots of calculations would be - * needed to determine MFP register and int mask from the vector number :-( - * - * Furthermore, slow ints may not lower the IPL below its previous value - * (before the int happened). This is needed so that an int of class PRIO, on - * that this int may be stacked, cannot be reentered. This feature is - * implemented as follows: If the stack frame format is 1 (throwaway), the int - * is not stacked, and the IPL is anded with 0xfbff, resulting in a new level - * 2, which still blocks the HSYNC, but no interrupts of interest. If the - * frame format is 0, the int is nested, and the old IPL value can be found in - * the sr copy in the frame. */ -#if 0 - -#define NUM_INT_SOURCES (8 + NUM_ATARI_SOURCES) - -typedef void (*asm_irq_handler)(void); - -struct irqhandler { - irqreturn_t (*handler)(int, void *, struct pt_regs *); - void *dev_id; -}; - -struct irqparam { - unsigned long flags; - const char *devname; -}; - -/* - * Array with irq's and their parameter data. This array is accessed from low - * level assembler code, so an element size of 8 allows usage of index scaling - * addressing mode. - */ -static struct irqhandler irq_handler[NUM_INT_SOURCES]; - -/* - * This array hold the rest of parameters of int handlers: type - * (slow,fast,prio) and the name of the handler. These values are only - * accessed from C - */ -static struct irqparam irq_param[NUM_INT_SOURCES]; - -/* check for valid int number (complex, sigh...) */ -#define IS_VALID_INTNO(n) \ - ((n) > 0 && \ - /* autovec and ST-MFP ok anyway */ \ - (((n) < TTMFP_SOURCE_BASE) || \ - /* TT-MFP ok if present */ \ - ((n) >= TTMFP_SOURCE_BASE && (n) < SCC_SOURCE_BASE && \ - ATARIHW_PRESENT(TT_MFP)) || \ - /* SCC ok if present and number even */ \ - ((n) >= SCC_SOURCE_BASE && (n) < VME_SOURCE_BASE && \ - !((n) & 1) && ATARIHW_PRESENT(SCC)) || \ - /* greater numbers ok if they are registered VME vectors */ \ - ((n) >= VME_SOURCE_BASE && (n) < VME_SOURCE_BASE + VME_MAX_SOURCES && \ - free_vme_vec_bitmap & (1 << ((n) - VME_SOURCE_BASE))))) - - -/* - * Here start the assembler entry points for interrupts - */ - -#define IRQ_NAME(nr) atari_slow_irq_##nr##_handler(void) - -#define BUILD_SLOW_IRQ(n) \ -asmlinkage void IRQ_NAME(n); \ -/* Dummy function to allow asm with operands. */ \ -void atari_slow_irq_##n##_dummy (void) { \ -__asm__ (__ALIGN_STR "\n" \ -"atari_slow_irq_" #n "_handler:\t" \ -" addl %6,%5\n" /* preempt_count() += HARDIRQ_OFFSET */ \ - SAVE_ALL_INT "\n" \ - GET_CURRENT(%%d0) "\n" \ -" andb #~(1<<(%c3&7)),%a4:w\n" /* mask this interrupt */ \ - /* get old IPL from stack frame */ \ -" bfextu %%sp@(%c2){#5,#3},%%d0\n" \ -" movew %%sr,%%d1\n" \ -" bfins %%d0,%%d1{#21,#3}\n" \ -" movew %%d1,%%sr\n" /* set IPL = previous value */ \ -" addql #1,%a0\n" \ -" lea %a1,%%a0\n" \ -" pea %%sp@\n" /* push addr of frame */ \ -" movel %%a0@(4),%%sp@-\n" /* push handler data */ \ -" pea (%c3+8)\n" /* push int number */ \ -" movel %%a0@,%%a0\n" \ -" jbsr %%a0@\n" /* call the handler */ \ -" addql #8,%%sp\n" \ -" addql #4,%%sp\n" \ -" orw #0x0600,%%sr\n" \ -" andw #0xfeff,%%sr\n" /* set IPL = 6 again */ \ -" orb #(1<<(%c3&7)),%a4:w\n" /* now unmask the int again */ \ -" jbra ret_from_interrupt\n" \ - : : "i" (&kstat_cpu(0).irqs[n+8]), "i" (&irq_handler[n+8]), \ - "n" (PT_OFF_SR), "n" (n), \ - "i" (n & 8 ? (n & 16 ? &tt_mfp.int_mk_a : &st_mfp.int_mk_a) \ - : (n & 16 ? &tt_mfp.int_mk_b : &st_mfp.int_mk_b)), \ - "m" (preempt_count()), "di" (HARDIRQ_OFFSET) \ -); \ - for (;;); /* fake noreturn */ \ -} - -BUILD_SLOW_IRQ(0); -BUILD_SLOW_IRQ(1); -BUILD_SLOW_IRQ(2); -BUILD_SLOW_IRQ(3); -BUILD_SLOW_IRQ(4); -BUILD_SLOW_IRQ(5); -BUILD_SLOW_IRQ(6); -BUILD_SLOW_IRQ(7); -BUILD_SLOW_IRQ(8); -BUILD_SLOW_IRQ(9); -BUILD_SLOW_IRQ(10); -BUILD_SLOW_IRQ(11); -BUILD_SLOW_IRQ(12); -BUILD_SLOW_IRQ(13); -BUILD_SLOW_IRQ(14); -BUILD_SLOW_IRQ(15); -BUILD_SLOW_IRQ(16); -BUILD_SLOW_IRQ(17); -BUILD_SLOW_IRQ(18); -BUILD_SLOW_IRQ(19); -BUILD_SLOW_IRQ(20); -BUILD_SLOW_IRQ(21); -BUILD_SLOW_IRQ(22); -BUILD_SLOW_IRQ(23); -BUILD_SLOW_IRQ(24); -BUILD_SLOW_IRQ(25); -BUILD_SLOW_IRQ(26); -BUILD_SLOW_IRQ(27); -BUILD_SLOW_IRQ(28); -BUILD_SLOW_IRQ(29); -BUILD_SLOW_IRQ(30); -BUILD_SLOW_IRQ(31); - -asm_irq_handler slow_handlers[32] = { - [0] = atari_slow_irq_0_handler, - [1] = atari_slow_irq_1_handler, - [2] = atari_slow_irq_2_handler, - [3] = atari_slow_irq_3_handler, - [4] = atari_slow_irq_4_handler, - [5] = atari_slow_irq_5_handler, - [6] = atari_slow_irq_6_handler, - [7] = atari_slow_irq_7_handler, - [8] = atari_slow_irq_8_handler, - [9] = atari_slow_irq_9_handler, - [10] = atari_slow_irq_10_handler, - [11] = atari_slow_irq_11_handler, - [12] = atari_slow_irq_12_handler, - [13] = atari_slow_irq_13_handler, - [14] = atari_slow_irq_14_handler, - [15] = atari_slow_irq_15_handler, - [16] = atari_slow_irq_16_handler, - [17] = atari_slow_irq_17_handler, - [18] = atari_slow_irq_18_handler, - [19] = atari_slow_irq_19_handler, - [20] = atari_slow_irq_20_handler, - [21] = atari_slow_irq_21_handler, - [22] = atari_slow_irq_22_handler, - [23] = atari_slow_irq_23_handler, - [24] = atari_slow_irq_24_handler, - [25] = atari_slow_irq_25_handler, - [26] = atari_slow_irq_26_handler, - [27] = atari_slow_irq_27_handler, - [28] = atari_slow_irq_28_handler, - [29] = atari_slow_irq_29_handler, - [30] = atari_slow_irq_30_handler, - [31] = atari_slow_irq_31_handler -}; - -asmlinkage void atari_fast_irq_handler( void ); -asmlinkage void atari_prio_irq_handler( void ); - -/* Dummy function to allow asm with operands. */ -void atari_fast_prio_irq_dummy (void) { -__asm__ (__ALIGN_STR "\n" -"atari_fast_irq_handler:\n\t" - "orw #0x700,%%sr\n" /* disable all interrupts */ -"atari_prio_irq_handler:\n\t" - "addl %3,%2\n\t" /* preempt_count() += HARDIRQ_OFFSET */ - SAVE_ALL_INT "\n\t" - GET_CURRENT(%%d0) "\n\t" - /* get vector number from stack frame and convert to source */ - "bfextu %%sp@(%c1){#4,#10},%%d0\n\t" - "subw #(0x40-8),%%d0\n\t" - "jpl 1f\n\t" - "addw #(0x40-8-0x18),%%d0\n" - "1:\tlea %a0,%%a0\n\t" - "addql #1,%%a0@(%%d0:l:4)\n\t" - "lea irq_handler,%%a0\n\t" - "lea %%a0@(%%d0:l:8),%%a0\n\t" - "pea %%sp@\n\t" /* push frame address */ - "movel %%a0@(4),%%sp@-\n\t" /* push handler data */ - "movel %%d0,%%sp@-\n\t" /* push int number */ - "movel %%a0@,%%a0\n\t" - "jsr %%a0@\n\t" /* and call the handler */ - "addql #8,%%sp\n\t" - "addql #4,%%sp\n\t" - "jbra ret_from_interrupt" - : : "i" (&kstat_cpu(0).irqs), "n" (PT_OFF_FORMATVEC), - "m" (preempt_count()), "di" (HARDIRQ_OFFSET) -); - for (;;); -} -#endif - /* * Bitmap for free interrupt vector numbers * (new vectors starting from 0x70 can be allocated by -- cgit v1.1 From 92b1bd5f1aa88ce4760c02814bfcbb58ad521984 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 31 May 2011 11:11:01 +0200 Subject: m68k/amiga: Refactor amiints.c - Remove filename in comments, - Reorder functions so we no longer need forward declarations. Signed-off-by: Geert Uytterhoeven --- arch/m68k/amiga/amiints.c | 98 +++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 51 deletions(-) diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c index e5f3033..c8f9eac 100644 --- a/arch/m68k/amiga/amiints.c +++ b/arch/m68k/amiga/amiints.c @@ -1,5 +1,5 @@ /* - * linux/arch/m68k/amiga/amiints.c -- Amiga Linux interrupt handling code + * Amiga Linux interrupt handling code * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive @@ -16,56 +16,6 @@ #include #include -static void amiga_irq_enable(struct irq_data *data); -static void amiga_irq_disable(struct irq_data *data); -static irqreturn_t ami_int1(int irq, void *dev_id); -static irqreturn_t ami_int3(int irq, void *dev_id); -static irqreturn_t ami_int4(int irq, void *dev_id); -static irqreturn_t ami_int5(int irq, void *dev_id); - -static struct irq_chip amiga_irq_chip = { - .name = "amiga", - .irq_enable = amiga_irq_enable, - .irq_disable = amiga_irq_disable, -}; - -/* - * void amiga_init_IRQ(void) - * - * Parameters: None - * - * Returns: Nothing - * - * This function should be called during kernel startup to initialize - * the amiga IRQ handling routines. - */ - -void __init amiga_init_IRQ(void) -{ - if (request_irq(IRQ_AUTO_1, ami_int1, 0, "int1", NULL)) - pr_err("Couldn't register int%d\n", 1); - if (request_irq(IRQ_AUTO_3, ami_int3, 0, "int3", NULL)) - pr_err("Couldn't register int%d\n", 3); - if (request_irq(IRQ_AUTO_4, ami_int4, 0, "int4", NULL)) - pr_err("Couldn't register int%d\n", 4); - if (request_irq(IRQ_AUTO_5, ami_int5, 0, "int5", NULL)) - pr_err("Couldn't register int%d\n", 5); - - m68k_setup_irq_controller(&amiga_irq_chip, handle_simple_irq, IRQ_USER, - AMI_STD_IRQS); - - /* turn off PCMCIA interrupts */ - if (AMIGAHW_PRESENT(PCMCIA)) - gayle.inten = GAYLE_IRQ_IDE; - - /* turn off all interrupts and enable the master interrupt bit */ - amiga_custom.intena = 0x7fff; - amiga_custom.intreq = 0x7fff; - amiga_custom.intena = IF_SETCLR | IF_INTEN; - - cia_init_IRQ(&ciaa_base); - cia_init_IRQ(&ciab_base); -} /* * Enable/disable a particular machine specific interrupt source. @@ -84,6 +34,13 @@ static void amiga_irq_disable(struct irq_data *data) amiga_custom.intena = 1 << (data->irq - IRQ_USER); } +static struct irq_chip amiga_irq_chip = { + .name = "amiga", + .irq_enable = amiga_irq_enable, + .irq_disable = amiga_irq_disable, +}; + + /* * The builtin Amiga hardware interrupt handlers. */ @@ -183,3 +140,42 @@ static irqreturn_t ami_int5(int irq, void *dev_id) } return IRQ_HANDLED; } + + +/* + * void amiga_init_IRQ(void) + * + * Parameters: None + * + * Returns: Nothing + * + * This function should be called during kernel startup to initialize + * the amiga IRQ handling routines. + */ + +void __init amiga_init_IRQ(void) +{ + if (request_irq(IRQ_AUTO_1, ami_int1, 0, "int1", NULL)) + pr_err("Couldn't register int%d\n", 1); + if (request_irq(IRQ_AUTO_3, ami_int3, 0, "int3", NULL)) + pr_err("Couldn't register int%d\n", 3); + if (request_irq(IRQ_AUTO_4, ami_int4, 0, "int4", NULL)) + pr_err("Couldn't register int%d\n", 4); + if (request_irq(IRQ_AUTO_5, ami_int5, 0, "int5", NULL)) + pr_err("Couldn't register int%d\n", 5); + + m68k_setup_irq_controller(&amiga_irq_chip, handle_simple_irq, IRQ_USER, + AMI_STD_IRQS); + + /* turn off PCMCIA interrupts */ + if (AMIGAHW_PRESENT(PCMCIA)) + gayle.inten = GAYLE_IRQ_IDE; + + /* turn off all interrupts and enable the master interrupt bit */ + amiga_custom.intena = 0x7fff; + amiga_custom.intreq = 0x7fff; + amiga_custom.intena = IF_SETCLR | IF_INTEN; + + cia_init_IRQ(&ciaa_base); + cia_init_IRQ(&ciab_base); +} -- cgit v1.1 From 978ef7e6d0e02083e4a62ab4411922bdeffa36a4 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 31 May 2011 22:08:28 +0200 Subject: m68k/amiga: Convert Amiga to genirq Signed-off-by: Geert Uytterhoeven --- arch/m68k/Kconfig | 1 - arch/m68k/amiga/amiints.c | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 9d60f40..9000921 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -87,7 +87,6 @@ config MMU_SUN3 config USE_GENERIC_HARDIRQS bool "Use genirq" depends on MMU - depends on !AMIGA depends on !MAC depends on !APOLLO depends on !MVME147 diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c index c8f9eac..c3da534 100644 --- a/arch/m68k/amiga/amiints.c +++ b/arch/m68k/amiga/amiints.c @@ -9,6 +9,9 @@ #include #include #include +#ifdef CONFIG_GENERIC_HARDIRQS +#include +#endif #include #include -- cgit v1.1 From fb1b646aa3bcae2f8211136a6b40228c7c9d236c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 1 Jun 2011 11:49:18 +0200 Subject: m68k/amiga: Optimize interrupts using chain handlers Signed-off-by: Geert Uytterhoeven --- arch/m68k/amiga/amiints.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c index c3da534..a8da471 100644 --- a/arch/m68k/amiga/amiints.c +++ b/arch/m68k/amiga/amiints.c @@ -48,6 +48,99 @@ static struct irq_chip amiga_irq_chip = { * The builtin Amiga hardware interrupt handlers. */ +#ifdef CONFIG_GENERIC_HARDIRQS +static void ami_int1(unsigned int irq, struct irq_desc *desc) +{ + unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; + + /* if serial transmit buffer empty, interrupt */ + if (ints & IF_TBE) { + amiga_custom.intreq = IF_TBE; + generic_handle_irq(IRQ_AMIGA_TBE); + } + + /* if floppy disk transfer complete, interrupt */ + if (ints & IF_DSKBLK) { + amiga_custom.intreq = IF_DSKBLK; + generic_handle_irq(IRQ_AMIGA_DSKBLK); + } + + /* if software interrupt set, interrupt */ + if (ints & IF_SOFT) { + amiga_custom.intreq = IF_SOFT; + generic_handle_irq(IRQ_AMIGA_SOFT); + } +} + +static void ami_int3(unsigned int irq, struct irq_desc *desc) +{ + unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; + + /* if a blitter interrupt */ + if (ints & IF_BLIT) { + amiga_custom.intreq = IF_BLIT; + generic_handle_irq(IRQ_AMIGA_BLIT); + } + + /* if a copper interrupt */ + if (ints & IF_COPER) { + amiga_custom.intreq = IF_COPER; + generic_handle_irq(IRQ_AMIGA_COPPER); + } + + /* if a vertical blank interrupt */ + if (ints & IF_VERTB) { + amiga_custom.intreq = IF_VERTB; + generic_handle_irq(IRQ_AMIGA_VERTB); + } +} + +static void ami_int4(unsigned int irq, struct irq_desc *desc) +{ + unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; + + /* if audio 0 interrupt */ + if (ints & IF_AUD0) { + amiga_custom.intreq = IF_AUD0; + generic_handle_irq(IRQ_AMIGA_AUD0); + } + + /* if audio 1 interrupt */ + if (ints & IF_AUD1) { + amiga_custom.intreq = IF_AUD1; + generic_handle_irq(IRQ_AMIGA_AUD1); + } + + /* if audio 2 interrupt */ + if (ints & IF_AUD2) { + amiga_custom.intreq = IF_AUD2; + generic_handle_irq(IRQ_AMIGA_AUD2); + } + + /* if audio 3 interrupt */ + if (ints & IF_AUD3) { + amiga_custom.intreq = IF_AUD3; + generic_handle_irq(IRQ_AMIGA_AUD3); + } +} + +static void ami_int5(unsigned int irq, struct irq_desc *desc) +{ + unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; + + /* if serial receive buffer full interrupt */ + if (ints & IF_RBF) { + /* acknowledge of IF_RBF must be done by the serial interrupt */ + generic_handle_irq(IRQ_AMIGA_RBF); + } + + /* if a disk sync interrupt */ + if (ints & IF_DSKSYN) { + amiga_custom.intreq = IF_DSKSYN; + generic_handle_irq(IRQ_AMIGA_DSKSYN); + } +} +#else /* !CONFIG_GENERIC_HARDIRQS */ static irqreturn_t ami_int1(int irq, void *dev_id) { unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; @@ -143,6 +236,7 @@ static irqreturn_t ami_int5(int irq, void *dev_id) } return IRQ_HANDLED; } +#endif /* !CONFIG_GENERIC_HARDIRQS */ /* @@ -158,6 +252,15 @@ static irqreturn_t ami_int5(int irq, void *dev_id) void __init amiga_init_IRQ(void) { +#ifdef CONFIG_GENERIC_HARDIRQS + m68k_setup_irq_controller(&amiga_irq_chip, handle_simple_irq, IRQ_USER, + AMI_STD_IRQS); + + irq_set_chained_handler(IRQ_AUTO_1, ami_int1); + irq_set_chained_handler(IRQ_AUTO_3, ami_int3); + irq_set_chained_handler(IRQ_AUTO_4, ami_int4); + irq_set_chained_handler(IRQ_AUTO_5, ami_int5); +#else /* !CONFIG_GENERIC_HARDIRQS */ if (request_irq(IRQ_AUTO_1, ami_int1, 0, "int1", NULL)) pr_err("Couldn't register int%d\n", 1); if (request_irq(IRQ_AUTO_3, ami_int3, 0, "int3", NULL)) @@ -169,6 +272,7 @@ void __init amiga_init_IRQ(void) m68k_setup_irq_controller(&amiga_irq_chip, handle_simple_irq, IRQ_USER, AMI_STD_IRQS); +#endif /* !CONFIG_GENERIC_HARDIRQS */ /* turn off PCMCIA interrupts */ if (AMIGAHW_PRESENT(PCMCIA)) -- cgit v1.1 From ddc7fd25d09678f8252c0321ef4b66e8451abe7d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 13 Jul 2011 21:48:30 +0200 Subject: m68k/mac: Convert Mac to genirq Signed-off-by: Geert Uytterhoeven --- arch/m68k/Kconfig | 1 - arch/m68k/mac/baboon.c | 3 +++ arch/m68k/mac/oss.c | 3 +++ arch/m68k/mac/psc.c | 3 +++ arch/m68k/mac/via.c | 3 +++ 5 files changed, 12 insertions(+), 1 deletion(-) diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 9000921..9ba1a89 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -87,7 +87,6 @@ config MMU_SUN3 config USE_GENERIC_HARDIRQS bool "Use genirq" depends on MMU - depends on !MAC depends on !APOLLO depends on !MVME147 depends on !MVME16x diff --git a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c index f264791..ff11746 100644 --- a/arch/m68k/mac/baboon.c +++ b/arch/m68k/mac/baboon.c @@ -11,6 +11,9 @@ #include #include #include +#ifdef CONFIG_GENERIC_HARDIRQS +#include +#endif #include #include diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c index 1eb60f0..ed95270 100644 --- a/arch/m68k/mac/oss.c +++ b/arch/m68k/mac/oss.c @@ -19,6 +19,9 @@ #include #include #include +#ifdef CONFIG_GENERIC_HARDIRQS +#include +#endif #include #include diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c index 26c2b65..0a34b7a 100644 --- a/arch/m68k/mac/psc.c +++ b/arch/m68k/mac/psc.c @@ -18,6 +18,9 @@ #include #include #include +#ifdef CONFIG_GENERIC_HARDIRQS +#include +#endif #include #include diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c index af9ed33..bde156c 100644 --- a/arch/m68k/mac/via.c +++ b/arch/m68k/mac/via.c @@ -28,6 +28,9 @@ #include #include #include +#ifdef CONFIG_GENERIC_HARDIRQS +#include +#endif #include #include -- cgit v1.1 From 9145db564eae98134de8eb8d64b47d7177eccfdd Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 10 Aug 2011 12:48:29 +0200 Subject: m68k/mac: Optimize interrupts using chain handlers Signed-off-by: Geert Uytterhoeven --- arch/m68k/mac/baboon.c | 38 +++++++++++++ arch/m68k/mac/oss.c | 106 +++++++++++++++++++++++++++++------- arch/m68k/mac/psc.c | 74 +++++++++++++++++++------ arch/m68k/mac/via.c | 143 ++++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 298 insertions(+), 63 deletions(-) diff --git a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c index ff11746..425144c 100644 --- a/arch/m68k/mac/baboon.c +++ b/arch/m68k/mac/baboon.c @@ -56,6 +56,39 @@ void __init baboon_init(void) * Baboon interrupt handler. This works a lot like a VIA. */ +#ifdef CONFIG_GENERIC_HARDIRQS +static void baboon_irq(unsigned int irq, struct irq_desc *desc) +{ + int irq_bit, irq_num; + unsigned char events; + +#ifdef DEBUG_IRQS + printk("baboon_irq: mb_control %02X mb_ifr %02X mb_status %02X\n", + (uint) baboon->mb_control, (uint) baboon->mb_ifr, + (uint) baboon->mb_status); +#endif + + events = baboon->mb_ifr & 0x07; + if (!events) + return; + + irq_num = IRQ_BABOON_0; + irq_bit = 1; + do { + if (events & irq_bit) { + baboon->mb_ifr &= ~irq_bit; + generic_handle_irq(irq_num); + } + irq_bit <<= 1; + irq_num++; + } while(events >= irq_bit); +#if 0 + if (baboon->mb_ifr & 0x02) macide_ack_intr(NULL); + /* for now we need to smash all interrupts */ + baboon->mb_ifr &= ~events; +#endif +} +#else static irqreturn_t baboon_irq(int irq, void *dev_id) { int irq_bit, irq_num; @@ -87,6 +120,7 @@ static irqreturn_t baboon_irq(int irq, void *dev_id) #endif return IRQ_HANDLED; } +#endif /* * Register the Baboon interrupt dispatcher on nubus slot $C. @@ -95,8 +129,12 @@ static irqreturn_t baboon_irq(int irq, void *dev_id) void __init baboon_register_interrupts(void) { baboon_disabled = 0; +#ifdef CONFIG_GENERIC_HARDIRQS + irq_set_chained_handler(IRQ_NUBUS_C, baboon_irq); +#else if (request_irq(IRQ_NUBUS_C, baboon_irq, 0, "baboon", (void *)baboon)) pr_err("Couldn't register baboon interrupt\n"); +#endif } /* diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c index ed95270..cc784c2 100644 --- a/arch/m68k/mac/oss.c +++ b/arch/m68k/mac/oss.c @@ -32,10 +32,11 @@ int oss_present; volatile struct mac_oss *oss; -static irqreturn_t oss_irq(int, void *); -static irqreturn_t oss_nubus_irq(int, void *); - +#ifdef CONFIG_GENERIC_HARDIRQS +extern void via1_irq(unsigned int irq, struct irq_desc *desc); +#else extern irqreturn_t via1_irq(int, void *); +#endif /* * Initialize the OSS @@ -63,23 +64,6 @@ void __init oss_init(void) } /* - * Register the OSS and NuBus interrupt dispatchers. - */ - -void __init oss_register_interrupts(void) -{ - if (request_irq(OSS_IRQLEV_SCSI, oss_irq, 0, "scsi", (void *)oss)) - pr_err("Couldn't register %s interrupt\n", "scsi"); - if (request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, 0, "nubus", - (void *)oss)) - pr_err("Couldn't register %s interrupt\n", "nubus"); - if (request_irq(OSS_IRQLEV_SOUND, oss_irq, 0, "sound", (void *)oss)) - pr_err("Couldn't register %s interrupt\n", "sound"); - if (request_irq(OSS_IRQLEV_VIA1, via1_irq, 0, "via1", (void *)via1)) - pr_err("Couldn't register %s interrupt\n", "via1"); -} - -/* * Initialize OSS for Nubus access */ @@ -92,6 +76,34 @@ void __init oss_nubus_init(void) * and SCSI; everything else is routed to its own autovector IRQ. */ +#ifdef CONFIG_GENERIC_HARDIRQS +static void oss_irq(unsigned int irq, struct irq_desc *desc) +{ + int events; + + events = oss->irq_pending & (OSS_IP_SOUND|OSS_IP_SCSI); + if (!events) + return; + +#ifdef DEBUG_IRQS + if ((console_loglevel == 10) && !(events & OSS_IP_SCSI)) { + printk("oss_irq: irq %u events = 0x%04X\n", irq, + (int) oss->irq_pending); + } +#endif + /* FIXME: how do you clear a pending IRQ? */ + + if (events & OSS_IP_SOUND) { + oss->irq_pending &= ~OSS_IP_SOUND; + /* FIXME: call sound handler */ + } else if (events & OSS_IP_SCSI) { + oss->irq_pending &= ~OSS_IP_SCSI; + generic_handle_irq(IRQ_MAC_SCSI); + } else { + /* FIXME: error check here? */ + } +} +#else static irqreturn_t oss_irq(int irq, void *dev_id) { int events; @@ -119,6 +131,7 @@ static irqreturn_t oss_irq(int irq, void *dev_id) } return IRQ_HANDLED; } +#endif /* * Nubus IRQ handler, OSS style @@ -126,6 +139,34 @@ static irqreturn_t oss_irq(int irq, void *dev_id) * Unlike the VIA/RBV this is on its own autovector interrupt level. */ +#ifdef CONFIG_GENERIC_HARDIRQS +static void oss_nubus_irq(unsigned int irq, struct irq_desc *desc) +{ + int events, irq_bit, i; + + events = oss->irq_pending & OSS_IP_NUBUS; + if (!events) + return; + +#ifdef DEBUG_NUBUS_INT + if (console_loglevel > 7) { + printk("oss_nubus_irq: events = 0x%04X\n", events); + } +#endif + /* There are only six slots on the OSS, not seven */ + + i = 6; + irq_bit = 0x40; + do { + --i; + irq_bit >>= 1; + if (events & irq_bit) { + oss->irq_pending &= ~irq_bit; + generic_handle_irq(NUBUS_SOURCE_BASE + i); + } + } while(events & (irq_bit - 1)); +} +#else static irqreturn_t oss_nubus_irq(int irq, void *dev_id) { int events, irq_bit, i; @@ -153,6 +194,31 @@ static irqreturn_t oss_nubus_irq(int irq, void *dev_id) } while(events & (irq_bit - 1)); return IRQ_HANDLED; } +#endif + +/* + * Register the OSS and NuBus interrupt dispatchers. + */ + +void __init oss_register_interrupts(void) +{ +#ifdef CONFIG_GENERIC_HARDIRQS + irq_set_chained_handler(OSS_IRQLEV_SCSI, oss_irq); + irq_set_chained_handler(OSS_IRQLEV_NUBUS, oss_nubus_irq); + irq_set_chained_handler(OSS_IRQLEV_SOUND, oss_irq); + irq_set_chained_handler(OSS_IRQLEV_VIA1, via1_irq); +#else /* !CONFIG_GENERIC_HARDIRQS */ + if (request_irq(OSS_IRQLEV_SCSI, oss_irq, 0, "scsi", (void *)oss)) + pr_err("Couldn't register %s interrupt\n", "scsi"); + if (request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, 0, "nubus", + (void *)oss)) + pr_err("Couldn't register %s interrupt\n", "nubus"); + if (request_irq(OSS_IRQLEV_SOUND, oss_irq, 0, "sound", (void *)oss)) + pr_err("Couldn't register %s interrupt\n", "sound"); + if (request_irq(OSS_IRQLEV_VIA1, via1_irq, 0, "via1", (void *)via1)) + pr_err("Couldn't register %s interrupt\n", "via1"); +#endif /* !CONFIG_GENERIC_HARDIRQS */ +} /* * Enable an OSS interrupt diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c index 0a34b7a..52840b8 100644 --- a/arch/m68k/mac/psc.c +++ b/arch/m68k/mac/psc.c @@ -33,8 +33,6 @@ int psc_present; volatile __u8 *psc; -irqreturn_t psc_irq(int, void *); - /* * Debugging dump, used in various places to see what's going on. */ @@ -115,26 +113,40 @@ void __init psc_init(void) } /* - * Register the PSC interrupt dispatchers for autovector interrupts 3-6. + * PSC interrupt handler. It's a lot like the VIA interrupt handler. */ -void __init psc_register_interrupts(void) +#ifdef CONFIG_GENERIC_HARDIRQS +static void psc_irq(unsigned int irq, struct irq_desc *desc) { - if (request_irq(IRQ_AUTO_3, psc_irq, 0, "psc3", (void *) 0x30)) - pr_err("Couldn't register psc%d interrupt\n", 3); - if (request_irq(IRQ_AUTO_4, psc_irq, 0, "psc4", (void *) 0x40)) - pr_err("Couldn't register psc%d interrupt\n", 4); - if (request_irq(IRQ_AUTO_5, psc_irq, 0, "psc5", (void *) 0x50)) - pr_err("Couldn't register psc%d interrupt\n", 5); - if (request_irq(IRQ_AUTO_6, psc_irq, 0, "psc6", (void *) 0x60)) - pr_err("Couldn't register psc%d interrupt\n", 6); -} + unsigned int offset = (unsigned int)irq_desc_get_handler_data(desc); + int pIFR = pIFRbase + offset; + int pIER = pIERbase + offset; + int irq_num; + unsigned char irq_bit, events; -/* - * PSC interrupt handler. It's a lot like the VIA interrupt handler. - */ +#ifdef DEBUG_IRQS + printk("psc_irq: irq %u pIFR = 0x%02X pIER = 0x%02X\n", + irq, (int) psc_read_byte(pIFR), (int) psc_read_byte(pIER)); +#endif -irqreturn_t psc_irq(int irq, void *dev_id) + events = psc_read_byte(pIFR) & psc_read_byte(pIER) & 0xF; + if (!events) + return; + + irq_num = irq << 3; + irq_bit = 1; + do { + if (events & irq_bit) { + psc_write_byte(pIFR, irq_bit); + generic_handle_irq(irq_num); + } + irq_num++; + irq_bit <<= 1; + } while (events >= irq_bit); +} +#else +static irqreturn_t psc_irq(int irq, void *dev_id) { int pIFR = pIFRbase + ((int) dev_id); int pIER = pIERbase + ((int) dev_id); @@ -162,6 +174,34 @@ irqreturn_t psc_irq(int irq, void *dev_id) } while (events >= irq_bit); return IRQ_HANDLED; } +#endif + +/* + * Register the PSC interrupt dispatchers for autovector interrupts 3-6. + */ + +void __init psc_register_interrupts(void) +{ +#ifdef CONFIG_GENERIC_HARDIRQS + irq_set_chained_handler(IRQ_AUTO_3, psc_irq); + irq_set_handler_data(IRQ_AUTO_3, (void *)0x30); + irq_set_chained_handler(IRQ_AUTO_4, psc_irq); + irq_set_handler_data(IRQ_AUTO_4, (void *)0x40); + irq_set_chained_handler(IRQ_AUTO_5, psc_irq); + irq_set_handler_data(IRQ_AUTO_5, (void *)0x50); + irq_set_chained_handler(IRQ_AUTO_6, psc_irq); + irq_set_handler_data(IRQ_AUTO_6, (void *)0x60); +#else /* !CONFIG_GENERIC_HARDIRQS */ + if (request_irq(IRQ_AUTO_3, psc_irq, 0, "psc3", (void *) 0x30)) + pr_err("Couldn't register psc%d interrupt\n", 3); + if (request_irq(IRQ_AUTO_4, psc_irq, 0, "psc4", (void *) 0x40)) + pr_err("Couldn't register psc%d interrupt\n", 4); + if (request_irq(IRQ_AUTO_5, psc_irq, 0, "psc5", (void *) 0x50)) + pr_err("Couldn't register psc%d interrupt\n", 5); + if (request_irq(IRQ_AUTO_6, psc_irq, 0, "psc6", (void *) 0x60)) + pr_err("Couldn't register psc%d interrupt\n", 6); +#endif /* !CONFIG_GENERIC_HARDIRQS */ +} void psc_irq_enable(int irq) { int irq_src = IRQ_SRC(irq); diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c index bde156c..b8156ac 100644 --- a/arch/m68k/mac/via.c +++ b/arch/m68k/mac/via.c @@ -80,9 +80,6 @@ static int gIER,gIFR,gBufA,gBufB; static u8 nubus_disabled; void via_debug_dump(void); -irqreturn_t via1_irq(int, void *); -irqreturn_t via2_irq(int, void *); -irqreturn_t via_nubus_irq(int, void *); void via_irq_enable(int irq); void via_irq_disable(int irq); void via_irq_clear(int irq); @@ -289,29 +286,6 @@ void __init via_init_clock(irq_handler_t func) } /* - * Register the interrupt dispatchers for VIA or RBV machines only. - */ - -void __init via_register_interrupts(void) -{ - if (via_alt_mapping) { - if (request_irq(IRQ_AUTO_1, via1_irq, 0, "software", - (void *)via1)) - pr_err("Couldn't register %s interrupt\n", "software"); - if (request_irq(IRQ_AUTO_6, via1_irq, 0, "via1", (void *)via1)) - pr_err("Couldn't register %s interrupt\n", "via1"); - } else { - if (request_irq(IRQ_AUTO_1, via1_irq, 0, "via1", (void *)via1)) - pr_err("Couldn't register %s interrupt\n", "via1"); - } - if (request_irq(IRQ_AUTO_2, via2_irq, 0, "via2", (void *)via2)) - pr_err("Couldn't register %s interrupt\n", "via2"); - if (request_irq(IRQ_MAC_NUBUS, via_nubus_irq, 0, "nubus", - (void *)via2)) - pr_err("Couldn't register %s interrupt\n", "nubus"); -} - -/* * Debugging dump, used in various places to see what's going on. */ @@ -443,6 +417,49 @@ void __init via_nubus_init(void) * via6522.c :-), disable/pending masks added. */ +#ifdef CONFIG_GENERIC_HARDIRQS +void via1_irq(unsigned int irq, struct irq_desc *desc) +{ + int irq_num; + unsigned char irq_bit, events; + + events = via1[vIFR] & via1[vIER] & 0x7F; + if (!events) + return; + + irq_num = VIA1_SOURCE_BASE; + irq_bit = 1; + do { + if (events & irq_bit) { + via1[vIFR] = irq_bit; + generic_handle_irq(irq_num); + } + ++irq_num; + irq_bit <<= 1; + } while (events >= irq_bit); +} + +static void via2_irq(unsigned int irq, struct irq_desc *desc) +{ + int irq_num; + unsigned char irq_bit, events; + + events = via2[gIFR] & via2[gIER] & 0x7F; + if (!events) + return; + + irq_num = VIA2_SOURCE_BASE; + irq_bit = 1; + do { + if (events & irq_bit) { + via2[gIFR] = irq_bit | rbv_clear; + generic_handle_irq(irq_num); + } + ++irq_num; + irq_bit <<= 1; + } while (events >= irq_bit); +} +#else irqreturn_t via1_irq(int irq, void *dev_id) { int irq_num; @@ -486,12 +503,49 @@ irqreturn_t via2_irq(int irq, void *dev_id) } while (events >= irq_bit); return IRQ_HANDLED; } +#endif /* * Dispatch Nubus interrupts. We are called as a secondary dispatch by the * VIA2 dispatcher as a fast interrupt handler. */ +#ifdef CONFIG_GENERIC_HARDIRQS +void via_nubus_irq(unsigned int irq, struct irq_desc *desc) +{ + int slot_irq; + unsigned char slot_bit, events; + + events = ~via2[gBufA] & 0x7F; + if (rbv_present) + events &= via2[rSIER]; + else + events &= ~via2[vDirA]; + if (!events) + return; + + do { + slot_irq = IRQ_NUBUS_F; + slot_bit = 0x40; + do { + if (events & slot_bit) { + events &= ~slot_bit; + generic_handle_irq(slot_irq); + } + --slot_irq; + slot_bit >>= 1; + } while (events); + + /* clear the CA1 interrupt and make certain there's no more. */ + via2[gIFR] = 0x02 | rbv_clear; + events = ~via2[gBufA] & 0x7F; + if (rbv_present) + events &= via2[rSIER]; + else + events &= ~via2[vDirA]; + } while (events); +} +#else irqreturn_t via_nubus_irq(int irq, void *dev_id) { int slot_irq; @@ -527,6 +581,43 @@ irqreturn_t via_nubus_irq(int irq, void *dev_id) } while (events); return IRQ_HANDLED; } +#endif + +/* + * Register the interrupt dispatchers for VIA or RBV machines only. + */ + +void __init via_register_interrupts(void) +{ +#ifdef CONFIG_GENERIC_HARDIRQS + if (via_alt_mapping) { + /* software interrupt */ + irq_set_chained_handler(IRQ_AUTO_1, via1_irq); + /* via1 interrupt */ + irq_set_chained_handler(IRQ_AUTO_6, via1_irq); + } else { + irq_set_chained_handler(IRQ_AUTO_1, via1_irq); + } + irq_set_chained_handler(IRQ_AUTO_2, via2_irq); + irq_set_chained_handler(IRQ_MAC_NUBUS, via_nubus_irq); +#else + if (via_alt_mapping) { + if (request_irq(IRQ_AUTO_1, via1_irq, 0, "software", + (void *)via1)) + pr_err("Couldn't register %s interrupt\n", "software"); + if (request_irq(IRQ_AUTO_6, via1_irq, 0, "via1", (void *)via1)) + pr_err("Couldn't register %s interrupt\n", "via1"); + } else { + if (request_irq(IRQ_AUTO_1, via1_irq, 0, "via1", (void *)via1)) + pr_err("Couldn't register %s interrupt\n", "via1"); + } + if (request_irq(IRQ_AUTO_2, via2_irq, 0, "via2", (void *)via2)) + pr_err("Couldn't register %s interrupt\n", "via2"); + if (request_irq(IRQ_MAC_NUBUS, via_nubus_irq, 0, "nubus", + (void *)via2)) + pr_err("Couldn't register %s interrupt\n", "nubus"); +#endif +} void via_irq_enable(int irq) { int irq_src = IRQ_SRC(irq); -- cgit v1.1 From efaf6d28fc768bfa373f7377c4b0484cbdf9f67e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sat, 13 Aug 2011 21:02:22 +0200 Subject: m68k/hp300: Convert HP9000/300 and HP9000/400 to genirq Signed-off-by: Geert Uytterhoeven Cc: Philip Blundell --- arch/m68k/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 9ba1a89..e4bd0c9 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -91,7 +91,6 @@ config USE_GENERIC_HARDIRQS depends on !MVME147 depends on !MVME16x depends on !BVME6000 - depends on !HP300 depends on !SUN3X depends on !Q40 depends on !SUN3 -- cgit v1.1 From 6c490c4da4642ec9e7569c8b50a98a22c71ad184 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sat, 13 Aug 2011 21:11:00 +0200 Subject: m68k/vme: Convert VME to genirq Signed-off-by: Geert Uytterhoeven Cc: Richard Hirst --- arch/m68k/Kconfig | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index e4bd0c9..8ae37a8 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -88,9 +88,6 @@ config USE_GENERIC_HARDIRQS bool "Use genirq" depends on MMU depends on !APOLLO - depends on !MVME147 - depends on !MVME16x - depends on !BVME6000 depends on !SUN3X depends on !Q40 depends on !SUN3 -- cgit v1.1 From bc7485acd09405d9544783d773ee040af4a5c861 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 18 Aug 2011 14:45:57 +0200 Subject: m68k/apollo: Convert Apollo to genirq Replace the custom user vector interrupt handler that calls do_IRQ() and does an EOI by handle_fasteoi_irq(). Signed-off-by: Geert Uytterhoeven Cc: Peter De Schrijver --- arch/m68k/Kconfig | 1 - arch/m68k/apollo/dn_ints.c | 25 +++++++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 8ae37a8..f2dc708 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -87,7 +87,6 @@ config MMU_SUN3 config USE_GENERIC_HARDIRQS bool "Use genirq" depends on MMU - depends on !APOLLO depends on !SUN3X depends on !Q40 depends on !SUN3 diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c index 4b76431..fc190b3 100644 --- a/arch/m68k/apollo/dn_ints.c +++ b/arch/m68k/apollo/dn_ints.c @@ -1,9 +1,14 @@ #include - +#ifdef CONFIG_GENERIC_HARDIRQS +#include +#else #include +#endif + #include #include +#ifndef CONFIG_GENERIC_HARDIRQS void dn_process_int(unsigned int irq, struct pt_regs *fp) { do_IRQ(irq, fp); @@ -11,6 +16,7 @@ void dn_process_int(unsigned int irq, struct pt_regs *fp) *(volatile unsigned char *)(pica)=0x20; *(volatile unsigned char *)(picb)=0x20; } +#endif unsigned int apollo_irq_startup(struct irq_data *data) { @@ -33,16 +39,31 @@ void apollo_irq_shutdown(struct irq_data *data) *(volatile unsigned char *)(picb+1) |= (1 << (irq - 8)); } +#ifdef CONFIG_GENERIC_HARDIRQS +void apollo_irq_eoi(struct irq_data *data) +{ + *(volatile unsigned char *)(pica) = 0x20; + *(volatile unsigned char *)(picb) = 0x20; +} +#endif + static struct irq_chip apollo_irq_chip = { .name = "apollo", .irq_startup = apollo_irq_startup, .irq_shutdown = apollo_irq_shutdown, +#ifdef CONFIG_GENERIC_HARDIRQS + .irq_eoi = apollo_irq_eoi, +#endif }; void __init dn_init_IRQ(void) { +#ifdef CONFIG_GENERIC_HARDIRQS + m68k_setup_user_interrupt(VEC_USER + 96, 16, NULL); +#else m68k_setup_user_interrupt(VEC_USER + 96, 16, dn_process_int); - m68k_setup_irq_controller(&apollo_irq_chip, handle_simple_irq, +#endif + m68k_setup_irq_controller(&apollo_irq_chip, handle_fasteoi_irq, IRQ_APOLLO, 16); } -- cgit v1.1 From 4045513286462a3c12140fac0559f09bcb5e7f10 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 18 Aug 2011 22:46:01 +0200 Subject: m68k/sun3: Use the kstat_irqs_cpu() wrapper Signed-off-by: Geert Uytterhoeven Acked-by: Sam Creasey --- arch/m68k/sun3/sun3ints.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c index 20ffee7..1273eb8 100644 --- a/arch/m68k/sun3/sun3ints.c +++ b/arch/m68k/sun3/sun3ints.c @@ -51,14 +51,19 @@ void sun3_disable_irq(unsigned int irq) static irqreturn_t sun3_int7(int irq, void *dev_id) { + unsigned int cnt; + *sun3_intreg |= (1 << irq); - if (!(kstat_cpu(0).irqs[irq] % 2000)) - sun3_leds(led_pattern[(kstat_cpu(0).irqs[irq] % 16000) / 2000]); + cnt = kstat_irqs_cpu(irq, 0); + if (!(cnt % 2000)) + sun3_leds(led_pattern[cnt % 16000 / 2000]); return IRQ_HANDLED; } static irqreturn_t sun3_int5(int irq, void *dev_id) { + unsigned int cnt; + #ifdef CONFIG_SUN3 intersil_clear(); #endif @@ -68,8 +73,9 @@ static irqreturn_t sun3_int5(int irq, void *dev_id) #endif xtime_update(1); update_process_times(user_mode(get_irq_regs())); - if (!(kstat_cpu(0).irqs[irq] % 20)) - sun3_leds(led_pattern[(kstat_cpu(0).irqs[irq] % 160) / 20]); + cnt = kstat_irqs_cpu(irq, 0); + if (!(cnt % 20)) + sun3_leds(led_pattern[cnt % 160 / 20]); return IRQ_HANDLED; } -- cgit v1.1 From dda7535912255015ecf7264c1d6691a09f8ba487 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 18 Aug 2011 14:46:46 +0200 Subject: m68k/sun3: Convert Sun3/3x to genirq Replace the custom irq handler that masks the irq and calls do_IRQ(), and the unmasking in the individual handlers, by handle_level_irq(). Signed-off-by: Geert Uytterhoeven Cc: Sam Creasey --- arch/m68k/Kconfig | 2 -- arch/m68k/sun3/sun3ints.c | 16 ++++++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index f2dc708..290f9c8 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -87,9 +87,7 @@ config MMU_SUN3 config USE_GENERIC_HARDIRQS bool "Use genirq" depends on MMU - depends on !SUN3X depends on !Q40 - depends on !SUN3 select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_SHOW diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c index 1273eb8..626b601 100644 --- a/arch/m68k/sun3/sun3ints.c +++ b/arch/m68k/sun3/sun3ints.c @@ -53,7 +53,9 @@ static irqreturn_t sun3_int7(int irq, void *dev_id) { unsigned int cnt; +#ifndef CONFIG_GENERIC_HARDIRQS *sun3_intreg |= (1 << irq); +#endif cnt = kstat_irqs_cpu(irq, 0); if (!(cnt % 2000)) sun3_leds(led_pattern[cnt % 16000 / 2000]); @@ -67,7 +69,9 @@ static irqreturn_t sun3_int5(int irq, void *dev_id) #ifdef CONFIG_SUN3 intersil_clear(); #endif +#ifndef CONFIG_GENERIC_HARDIRQS *sun3_intreg |= (1 << irq); +#endif #ifdef CONFIG_SUN3 intersil_clear(); #endif @@ -85,12 +89,14 @@ static irqreturn_t sun3_vec255(int irq, void *dev_id) return IRQ_HANDLED; } +#ifndef CONFIG_GENERIC_HARDIRQS static void sun3_inthandle(unsigned int irq, struct pt_regs *fp) { *sun3_intreg &= ~(1 << irq); do_IRQ(irq, fp); } +#endif static void sun3_irq_enable(struct irq_data *data) { @@ -108,15 +114,21 @@ static struct irq_chip sun3_irq_chip = { .irq_shutdown = m68k_irq_shutdown, .irq_enable = sun3_irq_enable, .irq_disable = sun3_irq_disable, +#ifdef CONFIG_GENERIC_HARDIRQS + .irq_mask = sun3_irq_disable, + .irq_unmask = sun3_irq_enable, +#endif }; void __init sun3_init_IRQ(void) { *sun3_intreg = 1; +#ifndef CONFIG_GENERIC_HARDIRQS m68k_setup_auto_interrupt(sun3_inthandle); - m68k_setup_irq_controller(&sun3_irq_chip, handle_simple_irq, - IRQ_AUTO_1, 7); +#endif + m68k_setup_irq_controller(&sun3_irq_chip, handle_level_irq, IRQ_AUTO_1, + 7); m68k_setup_user_interrupt(VEC_USER, 128, NULL); if (request_irq(IRQ_AUTO_5, sun3_int5, 0, "int5", NULL)) -- cgit v1.1 From a03010ed9b399fdbc28ac8836e0a6d4b15403f9f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 18 Aug 2011 14:47:16 +0200 Subject: m68k/q40: Convert Q40/Q60 to genirq q40_irq_handler() must be kept to translate ISA IRQs to the range 1-15. q40_probe_irq_o{ff,n}() become unused. Signed-off-by: Geert Uytterhoeven Cc: Richard Zidlicky --- arch/m68k/Kconfig | 1 - arch/m68k/include/asm/q40ints.h | 2 ++ arch/m68k/q40/q40ints.c | 8 +++++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 290f9c8..06198ce 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -87,7 +87,6 @@ config MMU_SUN3 config USE_GENERIC_HARDIRQS bool "Use genirq" depends on MMU - depends on !Q40 select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_SHOW diff --git a/arch/m68k/include/asm/q40ints.h b/arch/m68k/include/asm/q40ints.h index 3d970af..01cdbb4 100644 --- a/arch/m68k/include/asm/q40ints.h +++ b/arch/m68k/include/asm/q40ints.h @@ -25,5 +25,7 @@ #define Q40_IRQ14_MASK (1<<6) #define Q40_IRQ15_MASK (1<<7) +#ifndef CONFIG_GENERIC_HARDIRQS extern unsigned long q40_probe_irq_on (void); extern int q40_probe_irq_off (unsigned long irqs); +#endif diff --git a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c index afe600c..f1e5288 100644 --- a/arch/m68k/q40/q40ints.c +++ b/arch/m68k/q40/q40ints.c @@ -15,10 +15,14 @@ #include #include #include +#ifdef CONFIG_GENERIC_HARDIRQS +#include +#else +#include +#endif #include #include -#include #include #include @@ -326,6 +330,7 @@ void q40_irq_disable(struct irq_data *data) } } +#ifndef CONFIG_GENERIC_HARDIRQS unsigned long q40_probe_irq_on(void) { printk("irq probing not working - reconfigure the driver to avoid this\n"); @@ -335,3 +340,4 @@ int q40_probe_irq_off(unsigned long irqs) { return -1; } +#endif -- cgit v1.1 From d890d73995257b4e10cdd7d55bad80e34a71ba22 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 11 Sep 2011 11:28:04 +0200 Subject: m68k/irq: Remove obsolete m68k irq framework Signed-off-by: Geert Uytterhoeven --- arch/m68k/Kconfig | 10 +- arch/m68k/amiga/amiints.c | 114 --------------- arch/m68k/apollo/dn_ints.c | 22 --- arch/m68k/include/asm/irq.h | 63 --------- arch/m68k/include/asm/q40ints.h | 5 - arch/m68k/kernel/Makefile | 10 +- arch/m68k/kernel/ints.c | 297 ---------------------------------------- arch/m68k/mac/baboon.c | 41 ------ arch/m68k/mac/oss.c | 78 ----------- arch/m68k/mac/psc.c | 44 ------ arch/m68k/mac/via.c | 104 -------------- arch/m68k/q40/q40ints.c | 16 --- arch/m68k/sun3/sun3ints.c | 20 --- 13 files changed, 4 insertions(+), 820 deletions(-) diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 06198ce..361d540 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -4,8 +4,8 @@ config M68K select HAVE_IDE select HAVE_AOUT if MMU select GENERIC_ATOMIC64 if MMU - select HAVE_GENERIC_HARDIRQS if !MMU - select GENERIC_IRQ_SHOW if !MMU + select HAVE_GENERIC_HARDIRQS + select GENERIC_IRQ_SHOW select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS config RWSEM_GENERIC_SPINLOCK @@ -84,12 +84,6 @@ config MMU_SUN3 bool depends on MMU && !MMU_MOTOROLA -config USE_GENERIC_HARDIRQS - bool "Use genirq" - depends on MMU - select HAVE_GENERIC_HARDIRQS - select GENERIC_IRQ_SHOW - menu "Platform setup" source arch/m68k/Kconfig.cpu diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c index a8da471..47b5f90 100644 --- a/arch/m68k/amiga/amiints.c +++ b/arch/m68k/amiga/amiints.c @@ -9,9 +9,7 @@ #include #include #include -#ifdef CONFIG_GENERIC_HARDIRQS #include -#endif #include #include @@ -48,7 +46,6 @@ static struct irq_chip amiga_irq_chip = { * The builtin Amiga hardware interrupt handlers. */ -#ifdef CONFIG_GENERIC_HARDIRQS static void ami_int1(unsigned int irq, struct irq_desc *desc) { unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; @@ -140,103 +137,6 @@ static void ami_int5(unsigned int irq, struct irq_desc *desc) generic_handle_irq(IRQ_AMIGA_DSKSYN); } } -#else /* !CONFIG_GENERIC_HARDIRQS */ -static irqreturn_t ami_int1(int irq, void *dev_id) -{ - unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; - - /* if serial transmit buffer empty, interrupt */ - if (ints & IF_TBE) { - amiga_custom.intreq = IF_TBE; - generic_handle_irq(IRQ_AMIGA_TBE); - } - - /* if floppy disk transfer complete, interrupt */ - if (ints & IF_DSKBLK) { - amiga_custom.intreq = IF_DSKBLK; - generic_handle_irq(IRQ_AMIGA_DSKBLK); - } - - /* if software interrupt set, interrupt */ - if (ints & IF_SOFT) { - amiga_custom.intreq = IF_SOFT; - generic_handle_irq(IRQ_AMIGA_SOFT); - } - return IRQ_HANDLED; -} - -static irqreturn_t ami_int3(int irq, void *dev_id) -{ - unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; - - /* if a blitter interrupt */ - if (ints & IF_BLIT) { - amiga_custom.intreq = IF_BLIT; - generic_handle_irq(IRQ_AMIGA_BLIT); - } - - /* if a copper interrupt */ - if (ints & IF_COPER) { - amiga_custom.intreq = IF_COPER; - generic_handle_irq(IRQ_AMIGA_COPPER); - } - - /* if a vertical blank interrupt */ - if (ints & IF_VERTB) { - amiga_custom.intreq = IF_VERTB; - generic_handle_irq(IRQ_AMIGA_VERTB); - } - return IRQ_HANDLED; -} - -static irqreturn_t ami_int4(int irq, void *dev_id) -{ - unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; - - /* if audio 0 interrupt */ - if (ints & IF_AUD0) { - amiga_custom.intreq = IF_AUD0; - generic_handle_irq(IRQ_AMIGA_AUD0); - } - - /* if audio 1 interrupt */ - if (ints & IF_AUD1) { - amiga_custom.intreq = IF_AUD1; - generic_handle_irq(IRQ_AMIGA_AUD1); - } - - /* if audio 2 interrupt */ - if (ints & IF_AUD2) { - amiga_custom.intreq = IF_AUD2; - generic_handle_irq(IRQ_AMIGA_AUD2); - } - - /* if audio 3 interrupt */ - if (ints & IF_AUD3) { - amiga_custom.intreq = IF_AUD3; - generic_handle_irq(IRQ_AMIGA_AUD3); - } - return IRQ_HANDLED; -} - -static irqreturn_t ami_int5(int irq, void *dev_id) -{ - unsigned short ints = amiga_custom.intreqr & amiga_custom.intenar; - - /* if serial receive buffer full interrupt */ - if (ints & IF_RBF) { - /* acknowledge of IF_RBF must be done by the serial interrupt */ - generic_handle_irq(IRQ_AMIGA_RBF); - } - - /* if a disk sync interrupt */ - if (ints & IF_DSKSYN) { - amiga_custom.intreq = IF_DSKSYN; - generic_handle_irq(IRQ_AMIGA_DSKSYN); - } - return IRQ_HANDLED; -} -#endif /* !CONFIG_GENERIC_HARDIRQS */ /* @@ -252,7 +152,6 @@ static irqreturn_t ami_int5(int irq, void *dev_id) void __init amiga_init_IRQ(void) { -#ifdef CONFIG_GENERIC_HARDIRQS m68k_setup_irq_controller(&amiga_irq_chip, handle_simple_irq, IRQ_USER, AMI_STD_IRQS); @@ -260,19 +159,6 @@ void __init amiga_init_IRQ(void) irq_set_chained_handler(IRQ_AUTO_3, ami_int3); irq_set_chained_handler(IRQ_AUTO_4, ami_int4); irq_set_chained_handler(IRQ_AUTO_5, ami_int5); -#else /* !CONFIG_GENERIC_HARDIRQS */ - if (request_irq(IRQ_AUTO_1, ami_int1, 0, "int1", NULL)) - pr_err("Couldn't register int%d\n", 1); - if (request_irq(IRQ_AUTO_3, ami_int3, 0, "int3", NULL)) - pr_err("Couldn't register int%d\n", 3); - if (request_irq(IRQ_AUTO_4, ami_int4, 0, "int4", NULL)) - pr_err("Couldn't register int%d\n", 4); - if (request_irq(IRQ_AUTO_5, ami_int5, 0, "int5", NULL)) - pr_err("Couldn't register int%d\n", 5); - - m68k_setup_irq_controller(&amiga_irq_chip, handle_simple_irq, IRQ_USER, - AMI_STD_IRQS); -#endif /* !CONFIG_GENERIC_HARDIRQS */ /* turn off PCMCIA interrupts */ if (AMIGAHW_PRESENT(PCMCIA)) diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c index fc190b3..b7d0aa3 100644 --- a/arch/m68k/apollo/dn_ints.c +++ b/arch/m68k/apollo/dn_ints.c @@ -1,23 +1,9 @@ #include -#ifdef CONFIG_GENERIC_HARDIRQS #include -#else -#include -#endif #include #include -#ifndef CONFIG_GENERIC_HARDIRQS -void dn_process_int(unsigned int irq, struct pt_regs *fp) -{ - do_IRQ(irq, fp); - - *(volatile unsigned char *)(pica)=0x20; - *(volatile unsigned char *)(picb)=0x20; -} -#endif - unsigned int apollo_irq_startup(struct irq_data *data) { unsigned int irq = data->irq; @@ -39,31 +25,23 @@ void apollo_irq_shutdown(struct irq_data *data) *(volatile unsigned char *)(picb+1) |= (1 << (irq - 8)); } -#ifdef CONFIG_GENERIC_HARDIRQS void apollo_irq_eoi(struct irq_data *data) { *(volatile unsigned char *)(pica) = 0x20; *(volatile unsigned char *)(picb) = 0x20; } -#endif static struct irq_chip apollo_irq_chip = { .name = "apollo", .irq_startup = apollo_irq_startup, .irq_shutdown = apollo_irq_shutdown, -#ifdef CONFIG_GENERIC_HARDIRQS .irq_eoi = apollo_irq_eoi, -#endif }; void __init dn_init_IRQ(void) { -#ifdef CONFIG_GENERIC_HARDIRQS m68k_setup_user_interrupt(VEC_USER + 96, 16, NULL); -#else - m68k_setup_user_interrupt(VEC_USER + 96, 16, dn_process_int); -#endif m68k_setup_irq_controller(&apollo_irq_chip, handle_fasteoi_irq, IRQ_APOLLO, 16); } diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h index 518e61f..94349a5 100644 --- a/arch/m68k/include/asm/irq.h +++ b/arch/m68k/include/asm/irq.h @@ -62,67 +62,6 @@ #define IRQ_FLG_STD (0x8000) /* internally used */ #endif -#ifndef CONFIG_GENERIC_HARDIRQS - -#include -#include -#include -#include - -struct pt_regs; - -/* - * This structure is used to chain together the ISRs for a particular - * interrupt source (if it supports chaining). - */ -struct irq_data { - unsigned int irq; - irqreturn_t (*handler)(int, void *); - void *dev_id; - struct irq_data *next; - unsigned long flags; - const char *devname; -}; - -/* - * This structure has only 4 elements for speed reasons - */ -struct irq_handler { - int (*handler)(int, void *); - unsigned long flags; - void *dev_id; - const char *devname; -}; - -struct irq_chip { - const char *name; - unsigned int (*irq_startup)(struct irq_data *data); - void (*irq_shutdown)(struct irq_data *data); - void (*irq_enable)(struct irq_data *data); - void (*irq_disable)(struct irq_data *data); -}; - -extern unsigned int m68k_irq_startup(struct irq_data *data); -extern unsigned int m68k_irq_startup_irq(unsigned int irq); -extern void m68k_irq_shutdown(struct irq_data *data); - -/* - * This function returns a new struct irq_data - */ -extern struct irq_data *new_irq_node(void); - -extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)); -extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, - void (*handler)(unsigned int, struct pt_regs *)); -extern void m68k_setup_irq_chip(struct irq_chip *, unsigned int, unsigned int); -#define m68k_setup_irq_controller(chip, dummy, irq, cnt) \ - m68k_setup_irq_chip((chip), (irq), (cnt)) - -extern void generic_handle_irq(unsigned int); -asmlinkage void do_IRQ(int irq, struct pt_regs *regs); - -#else /* CONFIG_GENERIC_HARDIRQS */ - struct irq_data; struct irq_chip; struct irq_desc; @@ -139,8 +78,6 @@ extern void m68k_setup_irq_controller(struct irq_chip *, struct irq_desc *desc), unsigned int irq, unsigned int cnt); -#endif /* CONFIG_GENERIC_HARDIRQS */ - extern unsigned int irq_canonicalize(unsigned int irq); #else diff --git a/arch/m68k/include/asm/q40ints.h b/arch/m68k/include/asm/q40ints.h index 01cdbb4..22f12c9 100644 --- a/arch/m68k/include/asm/q40ints.h +++ b/arch/m68k/include/asm/q40ints.h @@ -24,8 +24,3 @@ #define Q40_IRQ10_MASK (1<<5) #define Q40_IRQ14_MASK (1<<6) #define Q40_IRQ15_MASK (1<<7) - -#ifndef CONFIG_GENERIC_HARDIRQS -extern unsigned long q40_probe_irq_on (void); -extern int q40_probe_irq_off (unsigned long irqs); -#endif diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile index 1414257..c569619 100644 --- a/arch/m68k/kernel/Makefile +++ b/arch/m68k/kernel/Makefile @@ -6,11 +6,10 @@ extra-$(CONFIG_MMU) := head.o extra-$(CONFIG_SUN3) := sun3-head.o extra-y += vmlinux.lds -obj-y := entry.o m68k_ksyms.o module.o process.o ptrace.o setup.o signal.o \ - sys_m68k.o syscalltable.o time.o traps.o +obj-y := entry.o irq.o m68k_ksyms.o module.o process.o ptrace.o setup.o \ + signal.o sys_m68k.o syscalltable.o time.o traps.o obj-$(CONFIG_MMU) += ints.o vectors.o -devres-$(CONFIG_MMU) = ../../../kernel/irq/devres.o ifndef CONFIG_MMU_SUN3 obj-y += dma.o @@ -18,9 +17,4 @@ endif ifndef CONFIG_MMU obj-y += init_task.o endif -ifdef CONFIG_GENERIC_HARDIRQS -obj-y += irq.o -else -obj-y += devres.o -endif diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c index cea439f..e2b056b 100644 --- a/arch/m68k/kernel/ints.c +++ b/arch/m68k/kernel/ints.c @@ -31,20 +31,6 @@ extern u32 auto_irqhandler_fixup[]; extern u32 user_irqhandler_fixup[]; extern u16 user_irqvec_fixup[]; -#ifndef CONFIG_GENERIC_HARDIRQS -/* table for system interrupt handlers */ -static struct irq_data *irq_list[NR_IRQS]; -static struct irq_chip *irq_chip[NR_IRQS]; -static int irq_depth[NR_IRQS]; - -static inline int irq_set_chip(unsigned int irq, struct irq_chip *chip) -{ - irq_chip[irq] = chip; - return 0; -} -#define irq_set_chip_and_handler(irq, chip, dummy) irq_set_chip(irq, chip) -#endif /* !CONFIG_GENERIC_HARDIRQS */ - static int m68k_first_user_vec; static struct irq_chip auto_irq_chip = { @@ -59,11 +45,6 @@ static struct irq_chip user_irq_chip = { .irq_shutdown = m68k_irq_shutdown, }; -#ifndef CONFIG_GENERIC_HARDIRQS -#define NUM_IRQ_NODES 100 -static struct irq_data nodes[NUM_IRQ_NODES]; -#endif /* !CONFIG_GENERIC_HARDIRQS */ - /* * void init_IRQ(void) * @@ -133,8 +114,6 @@ void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, flush_icache(); } -#ifdef CONFIG_GENERIC_HARDIRQS - /** * m68k_setup_irq_controller * @chip: irq chip which controls specified irq @@ -160,198 +139,6 @@ void m68k_setup_irq_controller(struct irq_chip *chip, } } -#else /* !CONFIG_GENERIC_HARDIRQS */ - -/** - * m68k_setup_irq_chip - * @contr: irq controller which controls specified irq - * @irq: first irq to be managed by the controller - * - * Change the controller for the specified range of irq, which will be used to - * manage these irq. auto/user irq already have a default controller, which can - * be changed as well, but the controller probably should use m68k_irq_startup/ - * m68k_irq_shutdown. - */ -void m68k_setup_irq_chip(struct irq_chip *contr, unsigned int irq, - unsigned int cnt) -{ - int i; - - for (i = 0; i < cnt; i++) - irq_set_chip(irq + i, contr); -} - -struct irq_data *new_irq_node(void) -{ - struct irq_data *node; - short i; - - for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--) { - if (!node->handler) { - memset(node, 0, sizeof(*node)); - return node; - } - } - - printk ("new_irq_node: out of nodes\n"); - return NULL; -} - -static int m68k_setup_irq(unsigned int irq, struct irq_data *node) -{ - struct irq_chip *contr; - struct irq_data **prev; - unsigned long flags; - - if (irq >= NR_IRQS || !(contr = irq_chip[irq])) { - printk("%s: Incorrect IRQ %d from %s\n", - __func__, irq, node->devname); - return -ENXIO; - } - - local_irq_save(flags); - - prev = irq_list + irq; - if (*prev) { - /* Can't share interrupts unless both agree to */ - if (!((*prev)->flags & node->flags & IRQF_SHARED)) { - local_irq_restore(flags); - return -EBUSY; - } - while (*prev) - prev = &(*prev)->next; - } - - if (!irq_list[irq]) { - if (contr->irq_startup) - contr->irq_startup(node); - else - contr->irq_enable(node); - } - node->next = NULL; - *prev = node; - - local_irq_restore(flags); - - return 0; -} - -int request_irq(unsigned int irq, - irq_handler_t handler, - unsigned long flags, const char *devname, void *dev_id) -{ - struct irq_data *node; - int res; - - node = new_irq_node(); - if (!node) - return -ENOMEM; - - node->irq = irq; - node->handler = handler; - node->flags = flags; - node->dev_id = dev_id; - node->devname = devname; - - res = m68k_setup_irq(irq, node); - if (res) - node->handler = NULL; - - return res; -} - -EXPORT_SYMBOL(request_irq); - -void free_irq(unsigned int irq, void *dev_id) -{ - struct irq_chip *contr; - struct irq_data **p, *node; - unsigned long flags; - - if (irq >= NR_IRQS || !(contr = irq_chip[irq])) { - printk("%s: Incorrect IRQ %d\n", __func__, irq); - return; - } - - local_irq_save(flags); - - p = irq_list + irq; - while ((node = *p)) { - if (node->dev_id == dev_id) - break; - p = &node->next; - } - - if (node) { - *p = node->next; - node->handler = NULL; - } else - printk("%s: Removing probably wrong IRQ %d\n", - __func__, irq); - - if (!irq_list[irq]) { - if (contr->irq_shutdown) - contr->irq_shutdown(node); - else - contr->irq_disable(node); - } - - local_irq_restore(flags); -} - -EXPORT_SYMBOL(free_irq); - -void enable_irq(unsigned int irq) -{ - struct irq_chip *contr; - unsigned long flags; - - if (irq >= NR_IRQS || !(contr = irq_chip[irq])) { - printk("%s: Incorrect IRQ %d\n", - __func__, irq); - return; - } - - local_irq_save(flags); - if (irq_depth[irq]) { - if (!--irq_depth[irq]) { - if (contr->irq_enable) - contr->irq_enable(irq_list[irq]); - } - } else - WARN_ON(1); - local_irq_restore(flags); -} - -EXPORT_SYMBOL(enable_irq); - -void disable_irq(unsigned int irq) -{ - struct irq_chip *contr; - unsigned long flags; - - if (irq >= NR_IRQS || !(contr = irq_chip[irq])) { - printk("%s: Incorrect IRQ %d\n", - __func__, irq); - return; - } - - local_irq_save(flags); - if (!irq_depth[irq]++) { - if (contr->irq_disable) - contr->irq_disable(irq_list[irq]); - } - local_irq_restore(flags); -} - -EXPORT_SYMBOL(disable_irq); - -void disable_irq_nosync(unsigned int irq) __attribute__((alias("disable_irq"))); - -EXPORT_SYMBOL(disable_irq_nosync); - -#endif /* !CONFIG_GENERIC_HARDIRQS */ - unsigned int m68k_irq_startup_irq(unsigned int irq) { if (irq <= IRQ_AUTO_7) @@ -377,36 +164,6 @@ void m68k_irq_shutdown(struct irq_data *data) } -#ifndef CONFIG_GENERIC_HARDIRQS - -/* - * Do we need these probe functions on the m68k? - * - * ... may be useful with ISA devices - */ -unsigned long probe_irq_on (void) -{ -#ifdef CONFIG_Q40 - if (MACH_IS_Q40) - return q40_probe_irq_on(); -#endif - return 0; -} - -EXPORT_SYMBOL(probe_irq_on); - -int probe_irq_off (unsigned long irqs) -{ -#ifdef CONFIG_Q40 - if (MACH_IS_Q40) - return q40_probe_irq_off(irqs); -#endif - return 0; -} - -EXPORT_SYMBOL(probe_irq_off); -#endif /* CONFIG_GENERIC_HARDIRQS */ - unsigned int irq_canonicalize(unsigned int irq) { #ifdef CONFIG_Q40 @@ -418,63 +175,9 @@ unsigned int irq_canonicalize(unsigned int irq) EXPORT_SYMBOL(irq_canonicalize); -#ifndef CONFIG_GENERIC_HARDIRQS -void generic_handle_irq(unsigned int irq) -{ - struct irq_data *node; - kstat_cpu(0).irqs[irq]++; - node = irq_list[irq]; - do { - node->handler(irq, node->dev_id); - node = node->next; - } while (node); -} - -asmlinkage void do_IRQ(int irq, struct pt_regs *regs) -{ - struct pt_regs *old_regs; - old_regs = set_irq_regs(regs); - generic_handle_irq(irq); - set_irq_regs(old_regs); -} - -asmlinkage void handle_badint(struct pt_regs *regs) -{ - kstat_cpu(0).irqs[0]++; - printk("unexpected interrupt from %u\n", regs->vector); -} - -int show_interrupts(struct seq_file *p, void *v) -{ - struct irq_chip *contr; - struct irq_data *node; - int i = *(loff_t *) v; - - /* autovector interrupts */ - if (irq_list[i]) { - contr = irq_chip[i]; - node = irq_list[i]; - seq_printf(p, "%-8s %3u: %10u %s", contr->name, i, kstat_cpu(0).irqs[i], node->devname); - while ((node = node->next)) - seq_printf(p, ", %s", node->devname); - seq_puts(p, "\n"); - } - return 0; -} - -#ifdef CONFIG_PROC_FS -void init_irq_proc(void) -{ - /* Insert /proc/irq driver here */ -} -#endif - -#else /* CONFIG_GENERIC_HARDIRQS */ asmlinkage void handle_badint(struct pt_regs *regs) { atomic_inc(&irq_err_count); pr_warn("unexpected interrupt from %u\n", regs->vector); } - -#endif /* CONFIG_GENERIC_HARDIRQS */ diff --git a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c index 425144c..b55ead2 100644 --- a/arch/m68k/mac/baboon.c +++ b/arch/m68k/mac/baboon.c @@ -11,9 +11,7 @@ #include #include #include -#ifdef CONFIG_GENERIC_HARDIRQS #include -#endif #include #include @@ -56,7 +54,6 @@ void __init baboon_init(void) * Baboon interrupt handler. This works a lot like a VIA. */ -#ifdef CONFIG_GENERIC_HARDIRQS static void baboon_irq(unsigned int irq, struct irq_desc *desc) { int irq_bit, irq_num; @@ -88,39 +85,6 @@ static void baboon_irq(unsigned int irq, struct irq_desc *desc) baboon->mb_ifr &= ~events; #endif } -#else -static irqreturn_t baboon_irq(int irq, void *dev_id) -{ - int irq_bit, irq_num; - unsigned char events; - -#ifdef DEBUG_IRQS - printk("baboon_irq: mb_control %02X mb_ifr %02X mb_status %02X\n", - (uint) baboon->mb_control, (uint) baboon->mb_ifr, - (uint) baboon->mb_status); -#endif - - if (!(events = baboon->mb_ifr & 0x07)) - return IRQ_NONE; - - irq_num = IRQ_BABOON_0; - irq_bit = 1; - do { - if (events & irq_bit) { - baboon->mb_ifr &= ~irq_bit; - generic_handle_irq(irq_num); - } - irq_bit <<= 1; - irq_num++; - } while(events >= irq_bit); -#if 0 - if (baboon->mb_ifr & 0x02) macide_ack_intr(NULL); - /* for now we need to smash all interrupts */ - baboon->mb_ifr &= ~events; -#endif - return IRQ_HANDLED; -} -#endif /* * Register the Baboon interrupt dispatcher on nubus slot $C. @@ -129,12 +93,7 @@ static irqreturn_t baboon_irq(int irq, void *dev_id) void __init baboon_register_interrupts(void) { baboon_disabled = 0; -#ifdef CONFIG_GENERIC_HARDIRQS irq_set_chained_handler(IRQ_NUBUS_C, baboon_irq); -#else - if (request_irq(IRQ_NUBUS_C, baboon_irq, 0, "baboon", (void *)baboon)) - pr_err("Couldn't register baboon interrupt\n"); -#endif } /* diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c index cc784c2..a4c82da 100644 --- a/arch/m68k/mac/oss.c +++ b/arch/m68k/mac/oss.c @@ -19,9 +19,7 @@ #include #include #include -#ifdef CONFIG_GENERIC_HARDIRQS #include -#endif #include #include @@ -32,11 +30,7 @@ int oss_present; volatile struct mac_oss *oss; -#ifdef CONFIG_GENERIC_HARDIRQS extern void via1_irq(unsigned int irq, struct irq_desc *desc); -#else -extern irqreturn_t via1_irq(int, void *); -#endif /* * Initialize the OSS @@ -76,7 +70,6 @@ void __init oss_nubus_init(void) * and SCSI; everything else is routed to its own autovector IRQ. */ -#ifdef CONFIG_GENERIC_HARDIRQS static void oss_irq(unsigned int irq, struct irq_desc *desc) { int events; @@ -103,35 +96,6 @@ static void oss_irq(unsigned int irq, struct irq_desc *desc) /* FIXME: error check here? */ } } -#else -static irqreturn_t oss_irq(int irq, void *dev_id) -{ - int events; - - events = oss->irq_pending & (OSS_IP_SOUND|OSS_IP_SCSI); - if (!events) - return IRQ_NONE; - -#ifdef DEBUG_IRQS - if ((console_loglevel == 10) && !(events & OSS_IP_SCSI)) { - printk("oss_irq: irq %d events = 0x%04X\n", irq, - (int) oss->irq_pending); - } -#endif - /* FIXME: how do you clear a pending IRQ? */ - - if (events & OSS_IP_SOUND) { - oss->irq_pending &= ~OSS_IP_SOUND; - /* FIXME: call sound handler */ - } else if (events & OSS_IP_SCSI) { - oss->irq_pending &= ~OSS_IP_SCSI; - generic_handle_irq(IRQ_MAC_SCSI); - } else { - /* FIXME: error check here? */ - } - return IRQ_HANDLED; -} -#endif /* * Nubus IRQ handler, OSS style @@ -139,7 +103,6 @@ static irqreturn_t oss_irq(int irq, void *dev_id) * Unlike the VIA/RBV this is on its own autovector interrupt level. */ -#ifdef CONFIG_GENERIC_HARDIRQS static void oss_nubus_irq(unsigned int irq, struct irq_desc *desc) { int events, irq_bit, i; @@ -166,35 +129,6 @@ static void oss_nubus_irq(unsigned int irq, struct irq_desc *desc) } } while(events & (irq_bit - 1)); } -#else -static irqreturn_t oss_nubus_irq(int irq, void *dev_id) -{ - int events, irq_bit, i; - - events = oss->irq_pending & OSS_IP_NUBUS; - if (!events) - return IRQ_NONE; - -#ifdef DEBUG_NUBUS_INT - if (console_loglevel > 7) { - printk("oss_nubus_irq: events = 0x%04X\n", events); - } -#endif - /* There are only six slots on the OSS, not seven */ - - i = 6; - irq_bit = 0x40; - do { - --i; - irq_bit >>= 1; - if (events & irq_bit) { - oss->irq_pending &= ~irq_bit; - generic_handle_irq(NUBUS_SOURCE_BASE + i); - } - } while(events & (irq_bit - 1)); - return IRQ_HANDLED; -} -#endif /* * Register the OSS and NuBus interrupt dispatchers. @@ -202,22 +136,10 @@ static irqreturn_t oss_nubus_irq(int irq, void *dev_id) void __init oss_register_interrupts(void) { -#ifdef CONFIG_GENERIC_HARDIRQS irq_set_chained_handler(OSS_IRQLEV_SCSI, oss_irq); irq_set_chained_handler(OSS_IRQLEV_NUBUS, oss_nubus_irq); irq_set_chained_handler(OSS_IRQLEV_SOUND, oss_irq); irq_set_chained_handler(OSS_IRQLEV_VIA1, via1_irq); -#else /* !CONFIG_GENERIC_HARDIRQS */ - if (request_irq(OSS_IRQLEV_SCSI, oss_irq, 0, "scsi", (void *)oss)) - pr_err("Couldn't register %s interrupt\n", "scsi"); - if (request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, 0, "nubus", - (void *)oss)) - pr_err("Couldn't register %s interrupt\n", "nubus"); - if (request_irq(OSS_IRQLEV_SOUND, oss_irq, 0, "sound", (void *)oss)) - pr_err("Couldn't register %s interrupt\n", "sound"); - if (request_irq(OSS_IRQLEV_VIA1, via1_irq, 0, "via1", (void *)via1)) - pr_err("Couldn't register %s interrupt\n", "via1"); -#endif /* !CONFIG_GENERIC_HARDIRQS */ } /* diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c index 52840b8..e6c2d20 100644 --- a/arch/m68k/mac/psc.c +++ b/arch/m68k/mac/psc.c @@ -18,9 +18,7 @@ #include #include #include -#ifdef CONFIG_GENERIC_HARDIRQS #include -#endif #include #include @@ -116,7 +114,6 @@ void __init psc_init(void) * PSC interrupt handler. It's a lot like the VIA interrupt handler. */ -#ifdef CONFIG_GENERIC_HARDIRQS static void psc_irq(unsigned int irq, struct irq_desc *desc) { unsigned int offset = (unsigned int)irq_desc_get_handler_data(desc); @@ -145,36 +142,6 @@ static void psc_irq(unsigned int irq, struct irq_desc *desc) irq_bit <<= 1; } while (events >= irq_bit); } -#else -static irqreturn_t psc_irq(int irq, void *dev_id) -{ - int pIFR = pIFRbase + ((int) dev_id); - int pIER = pIERbase + ((int) dev_id); - int irq_num; - unsigned char irq_bit, events; - -#ifdef DEBUG_IRQS - printk("psc_irq: irq %d pIFR = 0x%02X pIER = 0x%02X\n", - irq, (int) psc_read_byte(pIFR), (int) psc_read_byte(pIER)); -#endif - - events = psc_read_byte(pIFR) & psc_read_byte(pIER) & 0xF; - if (!events) - return IRQ_NONE; - - irq_num = irq << 3; - irq_bit = 1; - do { - if (events & irq_bit) { - psc_write_byte(pIFR, irq_bit); - generic_handle_irq(irq_num); - } - irq_num++; - irq_bit <<= 1; - } while (events >= irq_bit); - return IRQ_HANDLED; -} -#endif /* * Register the PSC interrupt dispatchers for autovector interrupts 3-6. @@ -182,7 +149,6 @@ static irqreturn_t psc_irq(int irq, void *dev_id) void __init psc_register_interrupts(void) { -#ifdef CONFIG_GENERIC_HARDIRQS irq_set_chained_handler(IRQ_AUTO_3, psc_irq); irq_set_handler_data(IRQ_AUTO_3, (void *)0x30); irq_set_chained_handler(IRQ_AUTO_4, psc_irq); @@ -191,16 +157,6 @@ void __init psc_register_interrupts(void) irq_set_handler_data(IRQ_AUTO_5, (void *)0x50); irq_set_chained_handler(IRQ_AUTO_6, psc_irq); irq_set_handler_data(IRQ_AUTO_6, (void *)0x60); -#else /* !CONFIG_GENERIC_HARDIRQS */ - if (request_irq(IRQ_AUTO_3, psc_irq, 0, "psc3", (void *) 0x30)) - pr_err("Couldn't register psc%d interrupt\n", 3); - if (request_irq(IRQ_AUTO_4, psc_irq, 0, "psc4", (void *) 0x40)) - pr_err("Couldn't register psc%d interrupt\n", 4); - if (request_irq(IRQ_AUTO_5, psc_irq, 0, "psc5", (void *) 0x50)) - pr_err("Couldn't register psc%d interrupt\n", 5); - if (request_irq(IRQ_AUTO_6, psc_irq, 0, "psc6", (void *) 0x60)) - pr_err("Couldn't register psc%d interrupt\n", 6); -#endif /* !CONFIG_GENERIC_HARDIRQS */ } void psc_irq_enable(int irq) { diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c index b8156ac..f1600ad 100644 --- a/arch/m68k/mac/via.c +++ b/arch/m68k/mac/via.c @@ -28,9 +28,7 @@ #include #include #include -#ifdef CONFIG_GENERIC_HARDIRQS #include -#endif #include #include @@ -417,7 +415,6 @@ void __init via_nubus_init(void) * via6522.c :-), disable/pending masks added. */ -#ifdef CONFIG_GENERIC_HARDIRQS void via1_irq(unsigned int irq, struct irq_desc *desc) { int irq_num; @@ -459,58 +456,12 @@ static void via2_irq(unsigned int irq, struct irq_desc *desc) irq_bit <<= 1; } while (events >= irq_bit); } -#else -irqreturn_t via1_irq(int irq, void *dev_id) -{ - int irq_num; - unsigned char irq_bit, events; - - events = via1[vIFR] & via1[vIER] & 0x7F; - if (!events) - return IRQ_NONE; - - irq_num = VIA1_SOURCE_BASE; - irq_bit = 1; - do { - if (events & irq_bit) { - via1[vIFR] = irq_bit; - generic_handle_irq(irq_num); - } - ++irq_num; - irq_bit <<= 1; - } while (events >= irq_bit); - return IRQ_HANDLED; -} - -irqreturn_t via2_irq(int irq, void *dev_id) -{ - int irq_num; - unsigned char irq_bit, events; - - events = via2[gIFR] & via2[gIER] & 0x7F; - if (!events) - return IRQ_NONE; - - irq_num = VIA2_SOURCE_BASE; - irq_bit = 1; - do { - if (events & irq_bit) { - via2[gIFR] = irq_bit | rbv_clear; - generic_handle_irq(irq_num); - } - ++irq_num; - irq_bit <<= 1; - } while (events >= irq_bit); - return IRQ_HANDLED; -} -#endif /* * Dispatch Nubus interrupts. We are called as a secondary dispatch by the * VIA2 dispatcher as a fast interrupt handler. */ -#ifdef CONFIG_GENERIC_HARDIRQS void via_nubus_irq(unsigned int irq, struct irq_desc *desc) { int slot_irq; @@ -545,43 +496,6 @@ void via_nubus_irq(unsigned int irq, struct irq_desc *desc) events &= ~via2[vDirA]; } while (events); } -#else -irqreturn_t via_nubus_irq(int irq, void *dev_id) -{ - int slot_irq; - unsigned char slot_bit, events; - - events = ~via2[gBufA] & 0x7F; - if (rbv_present) - events &= via2[rSIER]; - else - events &= ~via2[vDirA]; - if (!events) - return IRQ_NONE; - - do { - slot_irq = IRQ_NUBUS_F; - slot_bit = 0x40; - do { - if (events & slot_bit) { - events &= ~slot_bit; - generic_handle_irq(slot_irq); - } - --slot_irq; - slot_bit >>= 1; - } while (events); - - /* clear the CA1 interrupt and make certain there's no more. */ - via2[gIFR] = 0x02 | rbv_clear; - events = ~via2[gBufA] & 0x7F; - if (rbv_present) - events &= via2[rSIER]; - else - events &= ~via2[vDirA]; - } while (events); - return IRQ_HANDLED; -} -#endif /* * Register the interrupt dispatchers for VIA or RBV machines only. @@ -589,7 +503,6 @@ irqreturn_t via_nubus_irq(int irq, void *dev_id) void __init via_register_interrupts(void) { -#ifdef CONFIG_GENERIC_HARDIRQS if (via_alt_mapping) { /* software interrupt */ irq_set_chained_handler(IRQ_AUTO_1, via1_irq); @@ -600,23 +513,6 @@ void __init via_register_interrupts(void) } irq_set_chained_handler(IRQ_AUTO_2, via2_irq); irq_set_chained_handler(IRQ_MAC_NUBUS, via_nubus_irq); -#else - if (via_alt_mapping) { - if (request_irq(IRQ_AUTO_1, via1_irq, 0, "software", - (void *)via1)) - pr_err("Couldn't register %s interrupt\n", "software"); - if (request_irq(IRQ_AUTO_6, via1_irq, 0, "via1", (void *)via1)) - pr_err("Couldn't register %s interrupt\n", "via1"); - } else { - if (request_irq(IRQ_AUTO_1, via1_irq, 0, "via1", (void *)via1)) - pr_err("Couldn't register %s interrupt\n", "via1"); - } - if (request_irq(IRQ_AUTO_2, via2_irq, 0, "via2", (void *)via2)) - pr_err("Couldn't register %s interrupt\n", "via2"); - if (request_irq(IRQ_MAC_NUBUS, via_nubus_irq, 0, "nubus", - (void *)via2)) - pr_err("Couldn't register %s interrupt\n", "nubus"); -#endif } void via_irq_enable(int irq) { diff --git a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c index f1e5288..2b88849 100644 --- a/arch/m68k/q40/q40ints.c +++ b/arch/m68k/q40/q40ints.c @@ -15,11 +15,7 @@ #include #include #include -#ifdef CONFIG_GENERIC_HARDIRQS #include -#else -#include -#endif #include #include @@ -329,15 +325,3 @@ void q40_irq_disable(struct irq_data *data) printk("disable_irq nesting count %d\n",mext_disabled); } } - -#ifndef CONFIG_GENERIC_HARDIRQS -unsigned long q40_probe_irq_on(void) -{ - printk("irq probing not working - reconfigure the driver to avoid this\n"); - return -1; -} -int q40_probe_irq_off(unsigned long irqs) -{ - return -1; -} -#endif diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c index 626b601..7eb3781 100644 --- a/arch/m68k/sun3/sun3ints.c +++ b/arch/m68k/sun3/sun3ints.c @@ -53,9 +53,6 @@ static irqreturn_t sun3_int7(int irq, void *dev_id) { unsigned int cnt; -#ifndef CONFIG_GENERIC_HARDIRQS - *sun3_intreg |= (1 << irq); -#endif cnt = kstat_irqs_cpu(irq, 0); if (!(cnt % 2000)) sun3_leds(led_pattern[cnt % 16000 / 2000]); @@ -69,9 +66,6 @@ static irqreturn_t sun3_int5(int irq, void *dev_id) #ifdef CONFIG_SUN3 intersil_clear(); #endif -#ifndef CONFIG_GENERIC_HARDIRQS - *sun3_intreg |= (1 << irq); -#endif #ifdef CONFIG_SUN3 intersil_clear(); #endif @@ -89,15 +83,6 @@ static irqreturn_t sun3_vec255(int irq, void *dev_id) return IRQ_HANDLED; } -#ifndef CONFIG_GENERIC_HARDIRQS -static void sun3_inthandle(unsigned int irq, struct pt_regs *fp) -{ - *sun3_intreg &= ~(1 << irq); - - do_IRQ(irq, fp); -} -#endif - static void sun3_irq_enable(struct irq_data *data) { sun3_enable_irq(data->irq); @@ -114,19 +99,14 @@ static struct irq_chip sun3_irq_chip = { .irq_shutdown = m68k_irq_shutdown, .irq_enable = sun3_irq_enable, .irq_disable = sun3_irq_disable, -#ifdef CONFIG_GENERIC_HARDIRQS .irq_mask = sun3_irq_disable, .irq_unmask = sun3_irq_enable, -#endif }; void __init sun3_init_IRQ(void) { *sun3_intreg = 1; -#ifndef CONFIG_GENERIC_HARDIRQS - m68k_setup_auto_interrupt(sun3_inthandle); -#endif m68k_setup_irq_controller(&sun3_irq_chip, handle_level_irq, IRQ_AUTO_1, 7); m68k_setup_user_interrupt(VEC_USER, 128, NULL); -- cgit v1.1 From f30a6484f1bcb410d0af0c24f34b8e3d92682a05 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 11 Sep 2011 11:54:50 +0200 Subject: m68k/irq: Remove obsolete support for user vector interrupt fixups It was used on Apollo only, before its conversion to genirq. Signed-off-by: Geert Uytterhoeven --- arch/m68k/apollo/dn_ints.c | 2 +- arch/m68k/atari/ataints.c | 2 +- arch/m68k/bvme6000/config.c | 2 +- arch/m68k/include/asm/irq.h | 4 +--- arch/m68k/kernel/entry_mm.S | 3 +-- arch/m68k/kernel/ints.c | 11 ++--------- arch/m68k/mvme147/config.c | 2 +- arch/m68k/mvme16x/config.c | 2 +- arch/m68k/sun3/sun3ints.c | 2 +- 9 files changed, 10 insertions(+), 20 deletions(-) diff --git a/arch/m68k/apollo/dn_ints.c b/arch/m68k/apollo/dn_ints.c index b7d0aa3..17be1e7 100644 --- a/arch/m68k/apollo/dn_ints.c +++ b/arch/m68k/apollo/dn_ints.c @@ -41,7 +41,7 @@ static struct irq_chip apollo_irq_chip = { void __init dn_init_IRQ(void) { - m68k_setup_user_interrupt(VEC_USER + 96, 16, NULL); + m68k_setup_user_interrupt(VEC_USER + 96, 16); m68k_setup_irq_controller(&apollo_irq_chip, handle_fasteoi_irq, IRQ_APOLLO, 16); } diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c index af54455..6d196da 100644 --- a/arch/m68k/atari/ataints.c +++ b/arch/m68k/atari/ataints.c @@ -137,7 +137,7 @@ static struct irq_chip atari_irq_chip = { void __init atari_init_IRQ(void) { - m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER, NULL); + m68k_setup_user_interrupt(VEC_USER, NUM_ATARI_SOURCES - IRQ_USER); m68k_setup_irq_controller(&atari_irq_chip, handle_simple_irq, 1, NUM_ATARI_SOURCES - 1); diff --git a/arch/m68k/bvme6000/config.c b/arch/m68k/bvme6000/config.c index 1edd950..8128647 100644 --- a/arch/m68k/bvme6000/config.c +++ b/arch/m68k/bvme6000/config.c @@ -86,7 +86,7 @@ static void bvme6000_get_model(char *model) */ static void __init bvme6000_init_IRQ(void) { - m68k_setup_user_interrupt(VEC_USER, 192, NULL); + m68k_setup_user_interrupt(VEC_USER, 192); } void __init config_bvme6000(void) diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h index 94349a5..6198df5 100644 --- a/arch/m68k/include/asm/irq.h +++ b/arch/m68k/include/asm/irq.h @@ -70,9 +70,7 @@ extern unsigned int m68k_irq_startup_irq(unsigned int irq); extern void m68k_irq_shutdown(struct irq_data *data); extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_regs *)); -extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, - void (*handler)(unsigned int, - struct pt_regs *)); +extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt); extern void m68k_setup_irq_controller(struct irq_chip *, void (*handle)(unsigned int irq, struct irq_desc *desc), diff --git a/arch/m68k/kernel/entry_mm.S b/arch/m68k/kernel/entry_mm.S index f5927d09..c713f51 100644 --- a/arch/m68k/kernel/entry_mm.S +++ b/arch/m68k/kernel/entry_mm.S @@ -48,7 +48,7 @@ .globl sys_fork, sys_clone, sys_vfork .globl ret_from_interrupt, bad_interrupt .globl auto_irqhandler_fixup -.globl user_irqvec_fixup, user_irqhandler_fixup +.globl user_irqvec_fixup .text ENTRY(buserr) @@ -240,7 +240,6 @@ user_irqvec_fixup = . + 2 movel %sp,%sp@- movel %d0,%sp@- | put vector # on stack -user_irqhandler_fixup = . + 2 jsr do_IRQ | process the IRQ addql #8,%sp | pop parameters off stack diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c index e2b056b..74fefac 100644 --- a/arch/m68k/kernel/ints.c +++ b/arch/m68k/kernel/ints.c @@ -28,7 +28,6 @@ #endif extern u32 auto_irqhandler_fixup[]; -extern u32 user_irqhandler_fixup[]; extern u16 user_irqvec_fixup[]; static int m68k_first_user_vec; @@ -91,16 +90,12 @@ void __init m68k_setup_auto_interrupt(void (*handler)(unsigned int, struct pt_re * m68k_setup_user_interrupt * @vec: first user vector interrupt to handle * @cnt: number of active user vector interrupts - * @handler: called from user vector interrupts * * setup user vector interrupts, this includes activating the specified range * of interrupts, only then these interrupts can be requested (note: this is - * different from auto vector interrupts). An optional handler can be installed - * to be called instead of the default do_IRQ(), it will be called - * with irq numbers starting from IRQ_USER. + * different from auto vector interrupts). */ -void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, - void (*handler)(unsigned int, struct pt_regs *)) +void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt) { int i; @@ -109,8 +104,6 @@ void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt, for (i = 0; i < cnt; i++) irq_set_chip(IRQ_USER + i, &user_irq_chip); *user_irqvec_fixup = vec - IRQ_USER; - if (handler) - *user_irqhandler_fixup = (u32)handler; flush_icache(); } diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c index 01f2adf..5de924e 100644 --- a/arch/m68k/mvme147/config.c +++ b/arch/m68k/mvme147/config.c @@ -81,7 +81,7 @@ static void mvme147_get_model(char *model) void __init mvme147_init_IRQ(void) { - m68k_setup_user_interrupt(VEC_USER, 192, NULL); + m68k_setup_user_interrupt(VEC_USER, 192); } void __init config_mvme147(void) diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c index 0b28e26..31a66d9 100644 --- a/arch/m68k/mvme16x/config.c +++ b/arch/m68k/mvme16x/config.c @@ -117,7 +117,7 @@ static void mvme16x_get_hardware_list(struct seq_file *m) static void __init mvme16x_init_IRQ (void) { - m68k_setup_user_interrupt(VEC_USER, 192, NULL); + m68k_setup_user_interrupt(VEC_USER, 192); } #define pcc2chip ((volatile u_char *)0xfff42000) diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c index 7eb3781..78b60f5 100644 --- a/arch/m68k/sun3/sun3ints.c +++ b/arch/m68k/sun3/sun3ints.c @@ -109,7 +109,7 @@ void __init sun3_init_IRQ(void) m68k_setup_irq_controller(&sun3_irq_chip, handle_level_irq, IRQ_AUTO_1, 7); - m68k_setup_user_interrupt(VEC_USER, 128, NULL); + m68k_setup_user_interrupt(VEC_USER, 128); if (request_irq(IRQ_AUTO_5, sun3_int5, 0, "int5", NULL)) pr_err("Couldn't register %s interrupt\n", "int5"); -- cgit v1.1 From 2690e2148b730c53acb8797821468d0ea1673f25 Mon Sep 17 00:00:00 2001 From: Finn Thain Date: Sun, 11 Sep 2011 23:40:50 +1000 Subject: m68k/mac: Remove mac_irq_{en,dis}able() wrappers Signed-off-by: Finn Thain Signed-off-by: Geert Uytterhoeven --- arch/m68k/include/asm/macintosh.h | 2 ++ arch/m68k/mac/baboon.c | 7 ++----- arch/m68k/mac/macints.c | 25 +++++++------------------ 3 files changed, 11 insertions(+), 23 deletions(-) diff --git a/arch/m68k/include/asm/macintosh.h b/arch/m68k/include/asm/macintosh.h index c2a1c5e..12ebe43 100644 --- a/arch/m68k/include/asm/macintosh.h +++ b/arch/m68k/include/asm/macintosh.h @@ -12,6 +12,8 @@ extern void mac_reset(void); extern void mac_poweroff(void); extern void mac_init_IRQ(void); extern int mac_irq_pending(unsigned int); +extern void mac_irq_enable(struct irq_data *data); +extern void mac_irq_disable(struct irq_data *data); /* * Floppy driver magic hook - probably shouldn't be here diff --git a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c index b55ead2..b403924 100644 --- a/arch/m68k/mac/baboon.c +++ b/arch/m68k/mac/baboon.c @@ -21,9 +21,6 @@ /* #define DEBUG_IRQS */ -extern void mac_enable_irq(unsigned int); -extern void mac_disable_irq(unsigned int); - int baboon_present; static volatile struct baboon *baboon; static unsigned char baboon_disabled; @@ -111,7 +108,7 @@ void baboon_irq_enable(int irq) baboon_disabled &= ~(1 << irq_idx); if (!baboon_disabled) - mac_enable_irq(IRQ_NUBUS_C); + mac_irq_enable(irq_get_irq_data(IRQ_NUBUS_C)); } void baboon_irq_disable(int irq) @@ -124,7 +121,7 @@ void baboon_irq_disable(int irq) baboon_disabled |= 1 << irq_idx; if (baboon_disabled) - mac_disable_irq(IRQ_NUBUS_C); + mac_irq_disable(irq_get_irq_data(IRQ_NUBUS_C)); } void baboon_irq_clear(int irq) diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c index 98497d2..ba220b7 100644 --- a/arch/m68k/mac/macints.c +++ b/arch/m68k/mac/macints.c @@ -190,19 +190,6 @@ irqreturn_t mac_debug_handler(int, void *); /* #define DEBUG_MACINTS */ -void mac_enable_irq(unsigned int irq); -void mac_disable_irq(unsigned int irq); - -static void mac_irq_enable(struct irq_data *data) -{ - mac_enable_irq(data->irq); -} - -static void mac_irq_disable(struct irq_data *data) -{ - mac_disable_irq(data->irq); -} - static struct irq_chip mac_irq_chip = { .name = "mac", .irq_enable = mac_irq_enable, @@ -250,16 +237,17 @@ void __init mac_init_IRQ(void) } /* - * mac_enable_irq - enable an interrupt source - * mac_disable_irq - disable an interrupt source + * mac_irq_enable - enable an interrupt source + * mac_irq_disable - disable an interrupt source * mac_clear_irq - clears a pending interrupt - * mac_pending_irq - Returns the pending status of an IRQ (nonzero = pending) + * mac_irq_pending - returns the pending status of an IRQ (nonzero = pending) * * These routines are just dispatchers to the VIA/OSS/PSC routines. */ -void mac_enable_irq(unsigned int irq) +void mac_irq_enable(struct irq_data *data) { + int irq = data->irq; int irq_src = IRQ_SRC(irq); switch(irq_src) { @@ -292,8 +280,9 @@ void mac_enable_irq(unsigned int irq) } } -void mac_disable_irq(unsigned int irq) +void mac_irq_disable(struct irq_data *data) { + int irq = data->irq; int irq_src = IRQ_SRC(irq); switch(irq_src) { -- cgit v1.1 From 8ff8584e51d4d3fbe08ede413c4a221223766323 Mon Sep 17 00:00:00 2001 From: David Daney Date: Tue, 8 Nov 2011 14:54:55 -0800 Subject: MIPS: Hook up process_vm_readv and process_vm_writev system calls. Signed-off-by: David Daney To: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2918/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/unistd.h | 18 ++++++++++++------ arch/mips/kernel/scall32-o32.S | 2 ++ arch/mips/kernel/scall64-64.S | 2 ++ arch/mips/kernel/scall64-n32.S | 2 ++ arch/mips/kernel/scall64-o32.S | 2 ++ 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h index ecea787..d8dad53 100644 --- a/arch/mips/include/asm/unistd.h +++ b/arch/mips/include/asm/unistd.h @@ -365,16 +365,18 @@ #define __NR_syncfs (__NR_Linux + 342) #define __NR_sendmmsg (__NR_Linux + 343) #define __NR_setns (__NR_Linux + 344) +#define __NR_process_vm_readv (__NR_Linux + 345) +#define __NR_process_vm_writev (__NR_Linux + 346) /* * Offset of the last Linux o32 flavoured syscall */ -#define __NR_Linux_syscalls 344 +#define __NR_Linux_syscalls 346 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ #define __NR_O32_Linux 4000 -#define __NR_O32_Linux_syscalls 344 +#define __NR_O32_Linux_syscalls 346 #if _MIPS_SIM == _MIPS_SIM_ABI64 @@ -686,16 +688,18 @@ #define __NR_syncfs (__NR_Linux + 301) #define __NR_sendmmsg (__NR_Linux + 302) #define __NR_setns (__NR_Linux + 303) +#define __NR_process_vm_readv (__NR_Linux + 304) +#define __NR_process_vm_writev (__NR_Linux + 305) /* * Offset of the last Linux 64-bit flavoured syscall */ -#define __NR_Linux_syscalls 303 +#define __NR_Linux_syscalls 305 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ #define __NR_64_Linux 5000 -#define __NR_64_Linux_syscalls 303 +#define __NR_64_Linux_syscalls 305 #if _MIPS_SIM == _MIPS_SIM_NABI32 @@ -1012,16 +1016,18 @@ #define __NR_syncfs (__NR_Linux + 306) #define __NR_sendmmsg (__NR_Linux + 307) #define __NR_setns (__NR_Linux + 308) +#define __NR_process_vm_readv (__NR_Linux + 309) +#define __NR_process_vm_writev (__NR_Linux + 310) /* * Offset of the last N32 flavoured syscall */ -#define __NR_Linux_syscalls 308 +#define __NR_Linux_syscalls 310 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ #define __NR_N32_Linux 6000 -#define __NR_N32_Linux_syscalls 308 +#define __NR_N32_Linux_syscalls 310 #ifdef __KERNEL__ diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 4792065..a632bc1 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -591,6 +591,8 @@ einval: li v0, -ENOSYS sys sys_syncfs 1 sys sys_sendmmsg 4 sys sys_setns 2 + sys sys_process_vm_readv 6 /* 4345 */ + sys sys_process_vm_writev 6 .endm /* We pre-compute the number of _instruction_ bytes needed to diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index fb7334b..3b5a5e9 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -430,4 +430,6 @@ sys_call_table: PTR sys_syncfs PTR sys_sendmmsg PTR sys_setns + PTR sys_process_vm_readv + PTR sys_process_vm_writev /* 5305 */ .size sys_call_table,.-sys_call_table diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 6de1f59..6be6f70 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -430,4 +430,6 @@ EXPORT(sysn32_call_table) PTR sys_syncfs PTR compat_sys_sendmmsg PTR sys_setns + PTR compat_sys_process_vm_readv + PTR compat_sys_process_vm_writev /* 6310 */ .size sysn32_call_table,.-sysn32_call_table diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 1d81316..5422855 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -548,4 +548,6 @@ sys_call_table: PTR sys_syncfs PTR compat_sys_sendmmsg PTR sys_setns + PTR compat_sys_process_vm_readv /* 4345 */ + PTR compat_sys_process_vm_writev .size sys_call_table,.-sys_call_table -- cgit v1.1 From 76ee4557137ce12a60a1e1a070ed341182163a64 Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Tue, 8 Nov 2011 19:57:59 +0900 Subject: ARM: EXYNOS: Fix compiler error with THIS_MODULE CC arch/arm/mach-exynos/cpuidle.o arch/arm/mach-exynos/cpuidle.c:36: error: 'THIS_MODULE' undeclared here (not in a function) arch/arm/mach-exynos/cpuidle.c: In function 'exynos4_enter_idle': arch/arm/mach-exynos/cpuidle.c:42: error: storage size of 'before' isn't known arch/arm/mach-exynos/cpuidle.c:42: error: storage size of 'after' isn't known arch/arm/mach-exynos/cpuidle.c:46: error: implicit declaration of function 'do_gettimeofday' arch/arm/mach-exynos/cpuidle.c:52: error: 'USEC_PER_SEC' undeclared (first use in this function) arch/arm/mach-exynos/cpuidle.c:52: error: (Each undeclared identifier is reported only once arch/arm/mach-exynos/cpuidle.c:52: error: for each function it appears in.) arch/arm/mach-exynos/cpuidle.c:42: warning: unused variable 'after' arch/arm/mach-exynos/cpuidle.c:42: warning: unused variable 'before' make[1]: *** [arch/arm/mach-exynos/cpuidle.o] Error 1 Signed-off-by: Kyungmin Park [kgene.kim@samsung.com: Fixed as per Stephen's suggestion] Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/cpuidle.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-exynos/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c index 35f6502..4ebb382 100644 --- a/arch/arm/mach-exynos/cpuidle.c +++ b/arch/arm/mach-exynos/cpuidle.c @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include -- cgit v1.1 From 6d2dd054295e26dad0a84e2fe2029a1428242f8b Mon Sep 17 00:00:00 2001 From: Marcos Paulo de Souza Date: Mon, 31 Oct 2011 23:50:16 -0200 Subject: [libata] libata-scsi.c: Add function parameter documentation Add the documentation of parameters of ata_change_queue_depth to silence the warning of make xmldocs Signed-off-by: Marcos paulo de Souza Acked-by: Randy Dunlap Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 72a9770..2a5412e 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1217,6 +1217,10 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev) /** * __ata_change_queue_depth - helper for ata_scsi_change_queue_depth + * @ap: ATA port to which the device change the queue depth + * @sdev: SCSI device to configure queue depth for + * @queue_depth: new queue depth + * @reason: calling context * * libsas and libata have different approaches for associating a sdev to * its ata_port. -- cgit v1.1 From 003456145f0d23b73f080abd1fd7981788438693 Mon Sep 17 00:00:00 2001 From: JiSheng Zhang Date: Mon, 31 Oct 2011 21:20:10 +0800 Subject: ahci_platform: use dev_get_platdata() Use dev_get_platdata() to retrieve the struct ahci_platform_data data from the platform. Signed-off-by: JiSheng Zhang Signed-off-by: Jeff Garzik --- drivers/ata/ahci_platform.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 004f2ce..ec55595 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -65,7 +65,7 @@ static struct scsi_host_template ahci_platform_sht = { static int __init ahci_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct ahci_platform_data *pdata = dev->platform_data; + struct ahci_platform_data *pdata = dev_get_platdata(dev); const struct platform_device_id *id = platform_get_device_id(pdev); struct ata_port_info pi = ahci_port_info[id->driver_data]; const struct ata_port_info *ppi[] = { &pi, NULL }; @@ -191,7 +191,7 @@ err0: static int __devexit ahci_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct ahci_platform_data *pdata = dev->platform_data; + struct ahci_platform_data *pdata = dev_get_platdata(dev); struct ata_host *host = dev_get_drvdata(dev); ata_host_detach(host); -- cgit v1.1 From 142924cf402f9c0568004f0e2a27988fe3556c61 Mon Sep 17 00:00:00 2001 From: Chris Dunlop Date: Mon, 24 Oct 2011 10:38:18 +1100 Subject: sata_sis.c: trivial spelling fix Trivial spelling fix. Signed-off-by: Chris Dunlop Signed-off-by: Jeff Garzik --- drivers/ata/sata_sis.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index 447d9c0..95ec435 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c @@ -104,7 +104,7 @@ static const struct ata_port_info sis_port_info = { }; MODULE_AUTHOR("Uwe Koziolek"); -MODULE_DESCRIPTION("low-level driver for Silicon Integratad Systems SATA controller"); +MODULE_DESCRIPTION("low-level driver for Silicon Integrated Systems SATA controller"); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, sis_pci_tbl); MODULE_VERSION(DRV_VERSION); -- cgit v1.1 From 7a46c0780babea7d0b3f277a33ea243be38eb942 Mon Sep 17 00:00:00 2001 From: Gwendal Grignou Date: Wed, 19 Oct 2011 17:17:02 -0700 Subject: [libata] Issue SRST to Sil3726 PMP Reenable sending SRST to devices connected behind a Sil3726 PMP. This allow staggered spinups and handles drives that spins up slowly. While the drives spin up, the PMP will not accept SRST. Most controller reissues the reset until the drive is ready, while some [Sil3124] returns an error. In ata_eh_error, wait 10s before reset the ATA port and try again. Signed-off-by: Gwendal Grignou Acked-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-eh.c | 12 +++++++++++- drivers/ata/libata-pmp.c | 7 ++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index f22957c..a9b2820 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2883,7 +2883,7 @@ int ata_eh_reset(struct ata_link *link, int classify, sata_scr_read(link, SCR_STATUS, &sstatus)) rc = -ERESTART; - if (rc == -ERESTART || try >= max_tries) { + if (try >= max_tries) { /* * Thaw host port even if reset failed, so that the port * can be retried on the next phy event. This risks @@ -2909,6 +2909,16 @@ int ata_eh_reset(struct ata_link *link, int classify, ata_eh_acquire(ap); } + /* + * While disks spinup behind PMP, some controllers fail sending SRST. + * They need to be reset - as well as the PMP - before retrying. + */ + if (rc == -ERESTART) { + if (ata_is_host_link(link)) + ata_eh_thaw_port(ap); + goto out; + } + if (try == max_tries - 1) { sata_down_spd_limit(link, 0); if (slave) diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index 104462d..21b80c5 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c @@ -389,12 +389,9 @@ static void sata_pmp_quirks(struct ata_port *ap) /* link reports offline after LPM */ link->flags |= ATA_LFLAG_NO_LPM; - /* Class code report is unreliable and SRST - * times out under certain configurations. - */ + /* Class code report is unreliable. */ if (link->pmp < 5) - link->flags |= ATA_LFLAG_NO_SRST | - ATA_LFLAG_ASSUME_ATA; + link->flags |= ATA_LFLAG_ASSUME_ATA; /* port 5 is for SEMB device and it doesn't like SRST */ if (link->pmp == 5) -- cgit v1.1 From c9703765f3d5ab27909011dee4a05affe48e4442 Mon Sep 17 00:00:00 2001 From: Keng-Yu Lin Date: Wed, 9 Nov 2011 01:47:36 -0500 Subject: [libata] ahci: Add ASMedia ASM1061 support Signed-off-by: Keng-Yu Lin Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 3 +++ include/linux/pci_ids.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index fb7b90b..cf26222 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -390,6 +390,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { /* Promise */ { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ + /* Asmedia */ + { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1061 */ + /* Generic, PCI class code for AHCI */ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci }, diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 3fdf251..172ba70 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2405,6 +2405,8 @@ #define PCI_VENDOR_ID_AZWAVE 0x1a3b +#define PCI_VENDOR_ID_ASMEDIA 0x1b21 + #define PCI_VENDOR_ID_TEKRAM 0x1de1 #define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29 -- cgit v1.1 From 8d1c963a2e0c57dfe7f9c356389902e500cf1cfd Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Tue, 8 Nov 2011 20:37:26 +0100 Subject: ALSA: HDA: Remove quirk for Toshiba T110 According to the bug reporter, model=auto is needed to make the internal microphone work. BugLink: https://bugs.launchpad.net/bugs/819699 Reported-by: Andrej (agno01) Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 5e706e4..0de2119 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3062,7 +3062,6 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS), SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), - SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", CXT5066_LAPTOP), SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), -- cgit v1.1 From 0836b5cdd23d573bf7ec57f73ff774b3ad660bf4 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Fri, 4 Nov 2011 01:13:20 +0000 Subject: ARM: picoxcell: add extra temp register to addruart 639da5ee3 (ARM: add an extra temp register to the low level debugging addruart macro) didn't include picoxcell as it hadn't been merged at the time. Fix up the compile breakage by adding the extra temp parameter. Signed-off-by: Jamie Iles --- arch/arm/mach-picoxcell/include/mach/debug-macro.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-picoxcell/include/mach/debug-macro.S b/arch/arm/mach-picoxcell/include/mach/debug-macro.S index 8f2c234..58d4ee3 100644 --- a/arch/arm/mach-picoxcell/include/mach/debug-macro.S +++ b/arch/arm/mach-picoxcell/include/mach/debug-macro.S @@ -14,7 +14,7 @@ #define UART_SHIFT 2 - .macro addruart, rp, rv + .macro addruart, rp, rv, tmp ldr \rv, =PHYS_TO_IO(PICOXCELL_UART1_BASE) ldr \rp, =PICOXCELL_UART1_BASE .endm -- cgit v1.1 From f7f9bdfadfda07afb904a9767468e38c2d1a6033 Mon Sep 17 00:00:00 2001 From: Julian Wollrath Date: Wed, 9 Nov 2011 10:02:40 +0100 Subject: ALSA: hda - fix internal mic on Dell Vostro 3500 laptop Fix the not working internal mic on Dell Vostro 3500 laptop by introducing the new model dell-vostro-3500. Signed-off-by: Julian Wollrath Cc: Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/HD-Audio-Models.txt | 1 + sound/pci/hda/patch_sigmatel.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt index 4f34432..edad99a 100644 --- a/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/Documentation/sound/alsa/HD-Audio-Models.txt @@ -349,6 +349,7 @@ STAC92HD83* ref Reference board mic-ref Reference board with power management for ports dell-s14 Dell laptop + dell-vostro-3500 Dell Vostro 3500 laptop hp HP laptops with (inverted) mute-LED hp-dv7-4000 HP dv-7 4000 auto BIOS setup (default) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 4e715fe..edc2b7b 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -95,6 +95,7 @@ enum { STAC_92HD83XXX_REF, STAC_92HD83XXX_PWR_REF, STAC_DELL_S14, + STAC_DELL_VOSTRO_3500, STAC_92HD83XXX_HP, STAC_92HD83XXX_HP_cNB11_INTQUAD, STAC_HP_DV7_4000, @@ -1659,6 +1660,12 @@ static const unsigned int dell_s14_pin_configs[10] = { 0x40f000f0, 0x40f000f0, }; +static const unsigned int dell_vostro_3500_pin_configs[10] = { + 0x02a11020, 0x0221101f, 0x400000f0, 0x90170110, + 0x400000f1, 0x400000f2, 0x400000f3, 0x90a60160, + 0x400000f4, 0x400000f5, +}; + static const unsigned int hp_dv7_4000_pin_configs[10] = { 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110, 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140, @@ -1675,6 +1682,7 @@ static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, [STAC_DELL_S14] = dell_s14_pin_configs, + [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs, [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs, [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, }; @@ -1684,6 +1692,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { [STAC_92HD83XXX_REF] = "ref", [STAC_92HD83XXX_PWR_REF] = "mic-ref", [STAC_DELL_S14] = "dell-s14", + [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500", [STAC_92HD83XXX_HP] = "hp", [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", [STAC_HP_DV7_4000] = "hp-dv7-4000", @@ -1697,6 +1706,8 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { "DFI LanParty", STAC_92HD83XXX_REF), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, "unknown Dell", STAC_DELL_S14), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028, + "Dell Vostro 3500", STAC_DELL_VOSTRO_3500), SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600, "HP", STAC_92HD83XXX_HP), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656, -- cgit v1.1 From 55c0008be67a27944b6705251d9a8d4c56c67701 Mon Sep 17 00:00:00 2001 From: Alexey Fisher Date: Wed, 9 Nov 2011 11:39:24 +0100 Subject: ALSA: snd_usb_audio: add Logitech HD Webcam c510 to quirk-384 Logitech HD Webcam c510 provide wrong mixer resolution. Add it to "res = 384" quirk. Signed-off-by: Alexey Fisher Signed-off-by: Takashi Iwai --- sound/usb/mixer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index c5444e0..ab23869 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -799,6 +799,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, case USB_ID(0x046d, 0x0808): case USB_ID(0x046d, 0x0809): + case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */ case USB_ID(0x046d, 0x0991): /* Most audio usb devices lie about volume resolution. * Most Logitech webcams have res = 384. -- cgit v1.1 From 44656fa03926e7363ab41c565619800a4b3b1322 Mon Sep 17 00:00:00 2001 From: David Daney Date: Tue, 8 Nov 2011 10:20:10 -0800 Subject: kbuild: Fix missing system calls check on mips. Commit 5f7efb4 (Kbuild: append missing-syscalls to the default target list) broke MIPS build. Reported-tested-and-acked-by: Ralf Baechle Signed-off-by: David Daney Signed-off-by: Michal Marek --- Kbuild | 2 +- arch/mips/Makefile | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Kbuild b/Kbuild index 4caab4f..b8b708a 100644 --- a/Kbuild +++ b/Kbuild @@ -92,7 +92,7 @@ always += missing-syscalls targets += missing-syscalls quiet_cmd_syscalls = CALL $< - cmd_syscalls = $(CONFIG_SHELL) $< $(CC) $(c_flags) + cmd_syscalls = $(CONFIG_SHELL) $< $(CC) $(c_flags) $(missing_syscalls_flags) missing-syscalls: scripts/checksyscalls.sh $(offsets-file) FORCE $(call cmd,syscalls) diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 9b4cb00..0be3186 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -286,11 +286,11 @@ CLEAN_FILES += vmlinux.32 vmlinux.64 archprepare: ifdef CONFIG_MIPS32_N32 @echo ' Checking missing-syscalls for N32' - $(Q)$(MAKE) $(build)=. missing-syscalls ccflags-y="-mabi=n32" + $(Q)$(MAKE) $(build)=. missing-syscalls missing_syscalls_flags="-mabi=n32" endif ifdef CONFIG_MIPS32_O32 @echo ' Checking missing-syscalls for O32' - $(Q)$(MAKE) $(build)=. missing-syscalls ccflags-y="-mabi=32" + $(Q)$(MAKE) $(build)=. missing-syscalls missing_syscalls_flags="-mabi=32" endif install: -- cgit v1.1 From e0e20753c15fc418d94fee826af394907df856d8 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Thu, 27 Oct 2011 20:38:24 -0700 Subject: pinctrl: fix "warning: 'struct pinctrl_dev' declared inside parameter list" when pinctl subsystem is not selected, when compiling drivers including the include/linux/pinctrl/pinctrl.h, we will get the warning as below: In file included from include/linux/pinctrl/pinmux.h:17, from drivers/tty/serial/sirfsoc_uart.c:25: include/linux/pinctrl/pinctrl.h:126: warning: 'struct pinctrl_dev' declared inside parameter list include/linux/pinctrl/pinctrl.h:126: warning: its scope is only this definition or declaration, which is probably not what you want Signed-off-by: Barry Song Signed-off-by: Linus Walleij --- include/linux/pinctrl/pinctrl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index 3605e94..04c0110 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -121,6 +121,7 @@ extern const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev); extern void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev); #else +struct pinctrl_dev; /* Sufficiently stupid default function when pinctrl is not in use */ static inline bool pin_is_valid(struct pinctrl_dev *pctldev, int pin) -- cgit v1.1 From b3c41f4c18de9aa90315dd0d197f8485b00e3cc5 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 18 Sep 2011 09:56:35 +0800 Subject: ARM: at91: usart: drop static map regs for dbgu In commit fb149f9e28354 we introduce ioremap support for static map_io, we do not need this register entry anymore. Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Nicolas Ferre --- arch/arm/mach-at91/at91cap9_devices.c | 5 ++--- arch/arm/mach-at91/at91rm9200_devices.c | 5 ++--- arch/arm/mach-at91/at91sam9260_devices.c | 5 ++--- arch/arm/mach-at91/at91sam9261_devices.c | 5 ++--- arch/arm/mach-at91/at91sam9263_devices.c | 5 ++--- arch/arm/mach-at91/at91sam9g45_devices.c | 5 ++--- arch/arm/mach-at91/at91sam9rl_devices.c | 5 ++--- 7 files changed, 14 insertions(+), 21 deletions(-) diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c index a4401d6..b9739ba 100644 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ b/arch/arm/mach-at91/at91cap9_devices.c @@ -1021,8 +1021,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {} #if defined(CONFIG_SERIAL_ATMEL) static struct resource dbgu_resources[] = { [0] = { - .start = AT91_VA_BASE_SYS + AT91_DBGU, - .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .start = AT91_BASE_SYS + AT91_DBGU, + .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -1035,7 +1035,6 @@ static struct resource dbgu_resources[] = { static struct atmel_uart_data dbgu_data = { .use_dma_tx = 0, .use_dma_rx = 0, /* DBGU not capable of receive DMA */ - .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), }; static u64 dbgu_dmamask = DMA_BIT_MASK(32); diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 01d8bbd..66591fa 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -877,8 +877,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {} #if defined(CONFIG_SERIAL_ATMEL) static struct resource dbgu_resources[] = { [0] = { - .start = AT91_VA_BASE_SYS + AT91_DBGU, - .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .start = AT91_BASE_SYS + AT91_DBGU, + .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -891,7 +891,6 @@ static struct resource dbgu_resources[] = { static struct atmel_uart_data dbgu_data = { .use_dma_tx = 0, .use_dma_rx = 0, /* DBGU not capable of receive DMA */ - .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), }; static u64 dbgu_dmamask = DMA_BIT_MASK(32); diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index 24b6f8c..25e3464 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -837,8 +837,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {} #if defined(CONFIG_SERIAL_ATMEL) static struct resource dbgu_resources[] = { [0] = { - .start = AT91_VA_BASE_SYS + AT91_DBGU, - .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .start = AT91_BASE_SYS + AT91_DBGU, + .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -851,7 +851,6 @@ static struct resource dbgu_resources[] = { static struct atmel_uart_data dbgu_data = { .use_dma_tx = 0, .use_dma_rx = 0, /* DBGU not capable of receive DMA */ - .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), }; static u64 dbgu_dmamask = DMA_BIT_MASK(32); diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index 3b70b389..ae78f4d 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -816,8 +816,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {} #if defined(CONFIG_SERIAL_ATMEL) static struct resource dbgu_resources[] = { [0] = { - .start = AT91_VA_BASE_SYS + AT91_DBGU, - .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .start = AT91_BASE_SYS + AT91_DBGU, + .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -830,7 +830,6 @@ static struct resource dbgu_resources[] = { static struct atmel_uart_data dbgu_data = { .use_dma_tx = 0, .use_dma_rx = 0, /* DBGU not capable of receive DMA */ - .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), }; static u64 dbgu_dmamask = DMA_BIT_MASK(32); diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index 3faa1fd..ad017eb 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -1196,8 +1196,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {} static struct resource dbgu_resources[] = { [0] = { - .start = AT91_VA_BASE_SYS + AT91_DBGU, - .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .start = AT91_BASE_SYS + AT91_DBGU, + .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -1210,7 +1210,6 @@ static struct resource dbgu_resources[] = { static struct atmel_uart_data dbgu_data = { .use_dma_tx = 0, .use_dma_rx = 0, /* DBGU not capable of receive DMA */ - .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), }; static u64 dbgu_dmamask = DMA_BIT_MASK(32); diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 000b5e1..ad00953 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -1332,8 +1332,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {} #if defined(CONFIG_SERIAL_ATMEL) static struct resource dbgu_resources[] = { [0] = { - .start = AT91_VA_BASE_SYS + AT91_DBGU, - .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .start = AT91_BASE_SYS + AT91_DBGU, + .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -1346,7 +1346,6 @@ static struct resource dbgu_resources[] = { static struct atmel_uart_data dbgu_data = { .use_dma_tx = 0, .use_dma_rx = 0, - .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), }; static u64 dbgu_dmamask = DMA_BIT_MASK(32); diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c index 305a851..429b6d7 100644 --- a/arch/arm/mach-at91/at91sam9rl_devices.c +++ b/arch/arm/mach-at91/at91sam9rl_devices.c @@ -908,8 +908,8 @@ void __init at91_add_device_ssc(unsigned id, unsigned pins) {} #if defined(CONFIG_SERIAL_ATMEL) static struct resource dbgu_resources[] = { [0] = { - .start = AT91_VA_BASE_SYS + AT91_DBGU, - .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .start = AT91_BASE_SYS + AT91_DBGU, + .end = AT91_BASE_SYS + AT91_DBGU + SZ_512 - 1, .flags = IORESOURCE_MEM, }, [1] = { @@ -922,7 +922,6 @@ static struct resource dbgu_resources[] = { static struct atmel_uart_data dbgu_data = { .use_dma_tx = 0, .use_dma_rx = 0, /* DBGU not capable of receive DMA */ - .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), }; static u64 dbgu_dmamask = DMA_BIT_MASK(32); -- cgit v1.1 From 30458edf667b77012573e649fced3cf5c01efe82 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 2 Nov 2011 15:02:43 +0800 Subject: at91: vmalloc fix missing AT91_VIRT_BASE define VMALLOC_END is defined in terms of AT91_VIRT_BASE but this needs mach/hardware.h for it's definition. In file included from arch/arm/mach-at91/board-usb-a926x.c:26:0: include/linux/mm.h: In function 'is_vmalloc_addr': include/linux/mm.h:305:41: error: 'AT91_VIRT_BASE' undeclared (first use in this function) include/linux/mm.h:305:41: note: each undeclared identifier is reported only once for each function it appears in Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Cc: Nicolas Ferre Signed-off-by: Jamie Iles --- arch/arm/mach-at91/include/mach/vmalloc.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-at91/include/mach/vmalloc.h b/arch/arm/mach-at91/include/mach/vmalloc.h index 8eb459f..8e4a1bd 100644 --- a/arch/arm/mach-at91/include/mach/vmalloc.h +++ b/arch/arm/mach-at91/include/mach/vmalloc.h @@ -21,6 +21,8 @@ #ifndef __ASM_ARCH_VMALLOC_H #define __ASM_ARCH_VMALLOC_H +#include + #define VMALLOC_END (AT91_VIRT_BASE & PGDIR_MASK) #endif -- cgit v1.1 From b2eb5309fbc680406d6bf3b182178f0cfaf951fb Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Mon, 19 Sep 2011 19:26:52 +0800 Subject: at91/yl-9200: Fix section mismatch Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/mach-at91/board-yl-9200.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-at91/board-yl-9200.c b/arch/arm/mach-at91/board-yl-9200.c index 649b052..12a3f95 100644 --- a/arch/arm/mach-at91/board-yl-9200.c +++ b/arch/arm/mach-at91/board-yl-9200.c @@ -384,7 +384,7 @@ static struct spi_board_info yl9200_spi_devices[] = { #include