diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-06-02 07:01:37 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-06-03 14:06:13 -0400 |
commit | 19d337dff95cbf76edd3ad95c0cee2732c3e1ec5 (patch) | |
tree | 33326eeb09cb9664cc8427a5dc7cd2b08b5a57c3 /arch | |
parent | 0f6399c4c525b518644a9b09f8d6fb125a418c4d (diff) |
rfkill: rewrite
This patch completely rewrites the rfkill core to address
the following deficiencies:
* all rfkill drivers need to implement polling where necessary
rather than having one central implementation
* updating the rfkill state cannot be done from arbitrary
contexts, forcing drivers to use schedule_work and requiring
lots of code
* rfkill drivers need to keep track of soft/hard blocked
internally -- the core should do this
* the rfkill API has many unexpected quirks, for example being
asymmetric wrt. alloc/free and register/unregister
* rfkill can call back into a driver from within a function the
driver called -- this is prone to deadlocks and generally
should be avoided
* rfkill-input pointlessly is a separate module
* drivers need to #ifdef rfkill functions (unless they want to
depend on or select RFKILL) -- rfkill should provide inlines
that do nothing if it isn't compiled in
* the rfkill structure is not opaque -- drivers need to initialise
it correctly (lots of sanity checking code required) -- instead
force drivers to pass the right variables to rfkill_alloc()
* the documentation is hard to read because it always assumes the
reader is completely clueless and contains way TOO MANY CAPS
* the rfkill code needlessly uses a lot of locks and atomic
operations in locked sections
* fix LED trigger to actually change the LED when the radio state
changes -- this wasn't done before
Tested-by: Alan Jenkins <alan-jenkins@tuffmail.co.uk>
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br> [thinkpad]
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-pxa/tosa-bt.c | 30 | ||||
-rw-r--r-- | arch/arm/mach-pxa/tosa.c | 1 |
2 files changed, 15 insertions, 16 deletions
diff --git a/arch/arm/mach-pxa/tosa-bt.c b/arch/arm/mach-pxa/tosa-bt.c index bde42aa29374..c31e601eb49c 100644 --- a/arch/arm/mach-pxa/tosa-bt.c +++ b/arch/arm/mach-pxa/tosa-bt.c | |||
@@ -35,21 +35,25 @@ static void tosa_bt_off(struct tosa_bt_data *data) | |||
35 | gpio_set_value(data->gpio_reset, 0); | 35 | gpio_set_value(data->gpio_reset, 0); |
36 | } | 36 | } |
37 | 37 | ||
38 | static int tosa_bt_toggle_radio(void *data, enum rfkill_state state) | 38 | static int tosa_bt_set_block(void *data, bool blocked) |
39 | { | 39 | { |
40 | pr_info("BT_RADIO going: %s\n", | 40 | pr_info("BT_RADIO going: %s\n", blocked ? "off" : "on"); |
41 | state == RFKILL_STATE_UNBLOCKED ? "on" : "off"); | ||
42 | 41 | ||
43 | if (state == RFKILL_STATE_UNBLOCKED) { | 42 | if (!blocked) { |
44 | pr_info("TOSA_BT: going ON\n"); | 43 | pr_info("TOSA_BT: going ON\n"); |
45 | tosa_bt_on(data); | 44 | tosa_bt_on(data); |
46 | } else { | 45 | } else { |
47 | pr_info("TOSA_BT: going OFF\n"); | 46 | pr_info("TOSA_BT: going OFF\n"); |
48 | tosa_bt_off(data); | 47 | tosa_bt_off(data); |
49 | } | 48 | } |
49 | |||
50 | return 0; | 50 | return 0; |
51 | } | 51 | } |
52 | 52 | ||
53 | static const struct rfkill_ops tosa_bt_rfkill_ops = { | ||
54 | .set_block = tosa_bt_set_block, | ||
55 | }; | ||
56 | |||
53 | static int tosa_bt_probe(struct platform_device *dev) | 57 | static int tosa_bt_probe(struct platform_device *dev) |
54 | { | 58 | { |
55 | int rc; | 59 | int rc; |
@@ -70,18 +74,14 @@ static int tosa_bt_probe(struct platform_device *dev) | |||
70 | if (rc) | 74 | if (rc) |
71 | goto err_pwr_dir; | 75 | goto err_pwr_dir; |
72 | 76 | ||
73 | rfk = rfkill_allocate(&dev->dev, RFKILL_TYPE_BLUETOOTH); | 77 | rfk = rfkill_alloc("tosa-bt", &dev->dev, RFKILL_TYPE_BLUETOOTH, |
78 | &tosa_bt_rfkill_ops, data); | ||
74 | if (!rfk) { | 79 | if (!rfk) { |
75 | rc = -ENOMEM; | 80 | rc = -ENOMEM; |
76 | goto err_rfk_alloc; | 81 | goto err_rfk_alloc; |
77 | } | 82 | } |
78 | 83 | ||
79 | rfk->name = "tosa-bt"; | 84 | rfkill_set_led_trigger_name(rfk, "tosa-bt"); |
80 | rfk->toggle_radio = tosa_bt_toggle_radio; | ||
81 | rfk->data = data; | ||
82 | #ifdef CONFIG_RFKILL_LEDS | ||
83 | rfk->led_trigger.name = "tosa-bt"; | ||
84 | #endif | ||
85 | 85 | ||
86 | rc = rfkill_register(rfk); | 86 | rc = rfkill_register(rfk); |
87 | if (rc) | 87 | if (rc) |
@@ -92,9 +92,7 @@ static int tosa_bt_probe(struct platform_device *dev) | |||
92 | return 0; | 92 | return 0; |
93 | 93 | ||
94 | err_rfkill: | 94 | err_rfkill: |
95 | if (rfk) | 95 | rfkill_destroy(rfk); |
96 | rfkill_free(rfk); | ||
97 | rfk = NULL; | ||
98 | err_rfk_alloc: | 96 | err_rfk_alloc: |
99 | tosa_bt_off(data); | 97 | tosa_bt_off(data); |
100 | err_pwr_dir: | 98 | err_pwr_dir: |
@@ -113,8 +111,10 @@ static int __devexit tosa_bt_remove(struct platform_device *dev) | |||
113 | 111 | ||
114 | platform_set_drvdata(dev, NULL); | 112 | platform_set_drvdata(dev, NULL); |
115 | 113 | ||
116 | if (rfk) | 114 | if (rfk) { |
117 | rfkill_unregister(rfk); | 115 | rfkill_unregister(rfk); |
116 | rfkill_destroy(rfk); | ||
117 | } | ||
118 | rfk = NULL; | 118 | rfk = NULL; |
119 | 119 | ||
120 | tosa_bt_off(data); | 120 | tosa_bt_off(data); |
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index afac5b6d3d78..58ce807fe440 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <linux/input.h> | 31 | #include <linux/input.h> |
32 | #include <linux/gpio.h> | 32 | #include <linux/gpio.h> |
33 | #include <linux/pda_power.h> | 33 | #include <linux/pda_power.h> |
34 | #include <linux/rfkill.h> | ||
35 | #include <linux/spi/spi.h> | 34 | #include <linux/spi/spi.h> |
36 | 35 | ||
37 | #include <asm/setup.h> | 36 | #include <asm/setup.h> |