From 4f94851ea879c29b6e08ae3fc92f9fd1ad8512f7 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 22 Oct 2012 15:57:57 +0200 Subject: [PATCH] --- yaml --- r: 335608 b: refs/heads/master c: 4cf2d3b1b6ff9b7b6af1d2dbf1b63aa465250bc2 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/clk/ux500/u8500_clk.c | 19 +++++- trunk/drivers/leds/ledtrig-cpu.c | 21 +++++++ trunk/kernel/futex.c | 41 ++++++------- trunk/scripts/kconfig/expr.h | 5 +- trunk/scripts/kconfig/list.h | 91 ----------------------------- trunk/scripts/kconfig/lkc_proto.h | 4 +- trunk/scripts/kconfig/mconf.c | 6 +- trunk/scripts/kconfig/menu.c | 14 ++--- 9 files changed, 73 insertions(+), 130 deletions(-) delete mode 100644 trunk/scripts/kconfig/list.h diff --git a/[refs] b/[refs] index 7888ddcf5146..2f84ec63f499 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 70c80dfd579a62e41f8fea024206645cf03cec80 +refs/heads/master: 4cf2d3b1b6ff9b7b6af1d2dbf1b63aa465250bc2 diff --git a/trunk/drivers/clk/ux500/u8500_clk.c b/trunk/drivers/clk/ux500/u8500_clk.c index ca4a25ed844c..7ad01aa30efe 100644 --- a/trunk/drivers/clk/ux500/u8500_clk.c +++ b/trunk/drivers/clk/ux500/u8500_clk.c @@ -228,6 +228,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", U8500_CLKRST1_BASE, BIT(2), 0); + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.1"); + clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", U8500_CLKRST1_BASE, BIT(3), 0); clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", U8500_CLKRST1_BASE, @@ -239,6 +241,7 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", U8500_CLKRST1_BASE, BIT(6), 0); + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.2"); clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", U8500_CLKRST1_BASE, BIT(7), 0); @@ -255,11 +258,14 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", U8500_CLKRST1_BASE, BIT(10), 0); + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.4"); + clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", U8500_CLKRST1_BASE, BIT(11), 0); clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", U8500_CLKRST2_BASE, BIT(0), 0); + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.3"); clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", U8500_CLKRST2_BASE, BIT(1), 0); @@ -284,7 +290,6 @@ void u8500_clk_init(void) BIT(6), 0); clk_register_clkdev(clk, "apb_pclk", "sdi1"); - clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", U8500_CLKRST2_BASE, BIT(7), 0); clk_register_clkdev(clk, "apb_pclk", "sdi3"); @@ -318,8 +323,10 @@ void u8500_clk_init(void) BIT(1), 0); clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", U8500_CLKRST3_BASE, BIT(2), 0); + clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", U8500_CLKRST3_BASE, BIT(3), 0); + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.0"); clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", U8500_CLKRST3_BASE, BIT(4), 0); @@ -401,6 +408,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk", U8500_CLKRST1_BASE, BIT(2), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "nmk-i2c.1"); + clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk", U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk", @@ -412,17 +421,23 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk", U8500_CLKRST1_BASE, BIT(6), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "nmk-i2c.2"); + clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk", U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); /* FIXME: Redefinition of BIT(3). */ + clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk", U8500_CLKRST1_BASE, BIT(9), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "nmk-i2c.4"); + clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk", U8500_CLKRST1_BASE, BIT(10), CLK_SET_RATE_GATE); /* Periph2 */ clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk", U8500_CLKRST2_BASE, BIT(0), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "nmk-i2c.3"); clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmcclk", U8500_CLKRST2_BASE, BIT(2), CLK_SET_RATE_GATE); @@ -452,8 +467,10 @@ void u8500_clk_init(void) U8500_CLKRST3_BASE, BIT(1), CLK_SET_RATE_GATE); clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk", U8500_CLKRST3_BASE, BIT(2), CLK_SET_RATE_GATE); + clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk", U8500_CLKRST3_BASE, BIT(3), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "nmk-i2c.0"); clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmcclk", U8500_CLKRST3_BASE, BIT(4), CLK_SET_RATE_GATE); diff --git a/trunk/drivers/leds/ledtrig-cpu.c b/trunk/drivers/leds/ledtrig-cpu.c index 4239b3955ff0..b312056da14d 100644 --- a/trunk/drivers/leds/ledtrig-cpu.c +++ b/trunk/drivers/leds/ledtrig-cpu.c @@ -33,6 +33,8 @@ struct led_trigger_cpu { char name[MAX_NAME_LEN]; struct led_trigger *_trig; + struct mutex lock; + int lock_is_inited; }; static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig); @@ -48,6 +50,12 @@ void ledtrig_cpu(enum cpu_led_event ledevt) { struct led_trigger_cpu *trig = &__get_cpu_var(cpu_trig); + /* mutex lock should be initialized before calling mutex_call() */ + if (!trig->lock_is_inited) + return; + + mutex_lock(&trig->lock); + /* Locate the correct CPU LED */ switch (ledevt) { case CPU_LED_IDLE_END: @@ -67,6 +75,8 @@ void ledtrig_cpu(enum cpu_led_event ledevt) /* Will leave the LED as it is */ break; } + + mutex_unlock(&trig->lock); } EXPORT_SYMBOL(ledtrig_cpu); @@ -107,9 +117,14 @@ static int __init ledtrig_cpu_init(void) for_each_possible_cpu(cpu) { struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); + mutex_init(&trig->lock); + snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu); + mutex_lock(&trig->lock); led_trigger_register_simple(trig->name, &trig->_trig); + trig->lock_is_inited = 1; + mutex_unlock(&trig->lock); } register_syscore_ops(&ledtrig_cpu_syscore_ops); @@ -127,9 +142,15 @@ static void __exit ledtrig_cpu_exit(void) for_each_possible_cpu(cpu) { struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); + mutex_lock(&trig->lock); + led_trigger_unregister_simple(trig->_trig); trig->_trig = NULL; memset(trig->name, 0, MAX_NAME_LEN); + trig->lock_is_inited = 0; + + mutex_unlock(&trig->lock); + mutex_destroy(&trig->lock); } unregister_syscore_ops(&ledtrig_cpu_syscore_ops); diff --git a/trunk/kernel/futex.c b/trunk/kernel/futex.c index 20ef219bbe9b..3717e7b306e0 100644 --- a/trunk/kernel/futex.c +++ b/trunk/kernel/futex.c @@ -716,7 +716,7 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, struct futex_pi_state **ps, struct task_struct *task, int set_waiters) { - int lock_taken, ret, force_take = 0; + int lock_taken, ret, ownerdied = 0; u32 uval, newval, curval, vpid = task_pid_vnr(task); retry: @@ -755,15 +755,17 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, newval = curval | FUTEX_WAITERS; /* - * Should we force take the futex? See below. + * There are two cases, where a futex might have no owner (the + * owner TID is 0): OWNER_DIED. We take over the futex in this + * case. We also do an unconditional take over, when the owner + * of the futex died. + * + * This is safe as we are protected by the hash bucket lock ! */ - if (unlikely(force_take)) { - /* - * Keep the OWNER_DIED and the WAITERS bit and set the - * new TID value. - */ + if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) { + /* Keep the OWNER_DIED bit */ newval = (curval & ~FUTEX_TID_MASK) | vpid; - force_take = 0; + ownerdied = 0; lock_taken = 1; } @@ -773,7 +775,7 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, goto retry; /* - * We took the lock due to forced take over. + * We took the lock due to owner died take over. */ if (unlikely(lock_taken)) return 1; @@ -788,25 +790,20 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, switch (ret) { case -ESRCH: /* - * We failed to find an owner for this - * futex. So we have no pi_state to block - * on. This can happen in two cases: - * - * 1) The owner died - * 2) A stale FUTEX_WAITERS bit - * - * Re-read the futex value. + * No owner found for this futex. Check if the + * OWNER_DIED bit is set to figure out whether + * this is a robust futex or not. */ if (get_futex_value_locked(&curval, uaddr)) return -EFAULT; /* - * If the owner died or we have a stale - * WAITERS bit the owner TID in the user space - * futex is 0. + * We simply start over in case of a robust + * futex. The code above will take the futex + * and return happy. */ - if (!(curval & FUTEX_TID_MASK)) { - force_take = 1; + if (curval & FUTEX_OWNER_DIED) { + ownerdied = 1; goto retry; } default: diff --git a/trunk/scripts/kconfig/expr.h b/trunk/scripts/kconfig/expr.h index cdd48600e02a..bd2e09895553 100644 --- a/trunk/scripts/kconfig/expr.h +++ b/trunk/scripts/kconfig/expr.h @@ -12,7 +12,7 @@ extern "C" { #include #include -#include "list.h" +#include #ifndef __cplusplus #include #endif @@ -175,11 +175,12 @@ struct menu { #define MENU_ROOT 0x0002 struct jump_key { - struct list_head entries; + CIRCLEQ_ENTRY(jump_key) entries; size_t offset; struct menu *target; int index; }; +CIRCLEQ_HEAD(jk_head, jump_key); #define JUMP_NB 9 diff --git a/trunk/scripts/kconfig/list.h b/trunk/scripts/kconfig/list.h deleted file mode 100644 index 0ae730be5f49..000000000000 --- a/trunk/scripts/kconfig/list.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef LIST_H -#define LIST_H - -/* - * Copied from include/linux/... - */ - -#undef offsetof -#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) - -/** - * container_of - cast a member of a structure out to the containing structure - * @ptr: the pointer to the member. - * @type: the type of the container struct this is embedded in. - * @member: the name of the member within the struct. - * - */ -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) - - -struct list_head { - struct list_head *next, *prev; -}; - - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -/** - * list_entry - get the struct for this entry - * @ptr: the &struct list_head pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - */ -#define list_entry(ptr, type, member) \ - container_of(ptr, type, member) - -/** - * list_for_each_entry - iterate over list of given type - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_empty - tests whether a list is empty - * @head: the list to test. - */ -static inline int list_empty(const struct list_head *head) -{ - return head->next == head; -} - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_add(struct list_head *_new, - struct list_head *prev, - struct list_head *next) -{ - next->prev = _new; - _new->next = next; - _new->prev = prev; - prev->next = _new; -} - -/** - * list_add_tail - add a new entry - * @new: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - */ -static inline void list_add_tail(struct list_head *_new, struct list_head *head) -{ - __list_add(_new, head->prev, head); -} - -#endif diff --git a/trunk/scripts/kconfig/lkc_proto.h b/trunk/scripts/kconfig/lkc_proto.h index ef1a7381f956..1d1c08537f1e 100644 --- a/trunk/scripts/kconfig/lkc_proto.h +++ b/trunk/scripts/kconfig/lkc_proto.h @@ -21,9 +21,9 @@ P(menu_get_root_menu,struct menu *,(struct menu *menu)); P(menu_get_parent_menu,struct menu *,(struct menu *menu)); P(menu_has_help,bool,(struct menu *menu)); P(menu_get_help,const char *,(struct menu *menu)); -P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct list_head +P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct jk_head *head)); -P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct list_head +P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct jk_head *head)); P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help)); diff --git a/trunk/scripts/kconfig/mconf.c b/trunk/scripts/kconfig/mconf.c index 53975cf87608..48f67448af7b 100644 --- a/trunk/scripts/kconfig/mconf.c +++ b/trunk/scripts/kconfig/mconf.c @@ -312,7 +312,7 @@ static void set_config_filename(const char *config_filename) struct search_data { - struct list_head *head; + struct jk_head *head; struct menu **targets; int *keys; }; @@ -323,7 +323,7 @@ static void update_text(char *buf, size_t start, size_t end, void *_data) struct jump_key *pos; int k = 0; - list_for_each_entry(pos, data->head, entries) { + CIRCLEQ_FOREACH(pos, data->head, entries) { if (pos->offset >= start && pos->offset < end) { char header[4]; @@ -375,7 +375,7 @@ static void search_conf(void) sym_arr = sym_re_search(dialog_input); do { - LIST_HEAD(head); + struct jk_head head = CIRCLEQ_HEAD_INITIALIZER(head); struct menu *targets[JUMP_NB]; int keys[JUMP_NB + 1], i; struct search_data data = { diff --git a/trunk/scripts/kconfig/menu.c b/trunk/scripts/kconfig/menu.c index e98a05c8e508..a3cade659f89 100644 --- a/trunk/scripts/kconfig/menu.c +++ b/trunk/scripts/kconfig/menu.c @@ -508,7 +508,7 @@ const char *menu_get_help(struct menu *menu) } static void get_prompt_str(struct gstr *r, struct property *prop, - struct list_head *head) + struct jk_head *head) { int i, j; struct menu *submenu[8], *menu, *location = NULL; @@ -544,13 +544,12 @@ static void get_prompt_str(struct gstr *r, struct property *prop, } else jump->target = location; - if (list_empty(head)) + if (CIRCLEQ_EMPTY(head)) jump->index = 0; else - jump->index = list_entry(head->prev, struct jump_key, - entries)->index + 1; + jump->index = CIRCLEQ_LAST(head)->index + 1; - list_add_tail(&jump->entries, head); + CIRCLEQ_INSERT_TAIL(head, jump, entries); } if (i > 0) { @@ -574,8 +573,7 @@ static void get_prompt_str(struct gstr *r, struct property *prop, /* * head is optional and may be NULL */ -void get_symbol_str(struct gstr *r, struct symbol *sym, - struct list_head *head) +void get_symbol_str(struct gstr *r, struct symbol *sym, struct jk_head *head) { bool hit; struct property *prop; @@ -614,7 +612,7 @@ void get_symbol_str(struct gstr *r, struct symbol *sym, str_append(r, "\n\n"); } -struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head) +struct gstr get_relations_str(struct symbol **sym_arr, struct jk_head *head) { struct symbol *sym; struct gstr res = str_new();