diff options
author | James Morris <jmorris@namei.org> | 2008-11-13 19:29:12 -0500 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2008-11-13 19:29:12 -0500 |
commit | 2b828925652340277a889cbc11b2d0637f7cdaf7 (patch) | |
tree | 32fcb3d3e466fc419fad2d3717956a5b5ad3d35a /drivers | |
parent | 3a3b7ce9336952ea7b9564d976d068a238976c9d (diff) | |
parent | 58e20d8d344b0ee083febb18c2b021d2427e56ca (diff) |
Merge branch 'master' into next
Conflicts:
security/keys/internal.h
security/keys/process_keys.c
security/keys/request_key.c
Fixed conflicts above by using the non 'tsk' versions.
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'drivers')
225 files changed, 9865 insertions, 1566 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index f4f632917509..b0243fd55ac0 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -312,9 +312,13 @@ config ACPI_DEBUG | |||
312 | bool "Debug Statements" | 312 | bool "Debug Statements" |
313 | default n | 313 | default n |
314 | help | 314 | help |
315 | The ACPI driver can optionally report errors with a great deal | 315 | The ACPI subsystem can produce debug output. Saying Y enables this |
316 | of verbosity. Saying Y enables these statements. This will increase | 316 | output and increases the kernel size by around 50K. |
317 | your kernel size by around 50K. | 317 | |
318 | Use the acpi.debug_layer and acpi.debug_level kernel command-line | ||
319 | parameters documented in Documentation/acpi/debug.txt and | ||
320 | Documentation/kernel-parameters.txt to control the type and | ||
321 | amount of debug output. | ||
318 | 322 | ||
319 | config ACPI_DEBUG_FUNC_TRACE | 323 | config ACPI_DEBUG_FUNC_TRACE |
320 | bool "Additionally enable ACPI function tracing" | 324 | bool "Additionally enable ACPI function tracing" |
@@ -324,14 +328,6 @@ config ACPI_DEBUG_FUNC_TRACE | |||
324 | ACPI Debug Statements slow down ACPI processing. Function trace | 328 | ACPI Debug Statements slow down ACPI processing. Function trace |
325 | is about half of the penalty and is rarely useful. | 329 | is about half of the penalty and is rarely useful. |
326 | 330 | ||
327 | config ACPI_EC | ||
328 | bool | ||
329 | default y | ||
330 | help | ||
331 | This driver is required on some systems for the proper operation of | ||
332 | the battery and thermal drivers. If you are compiling for a | ||
333 | mobile system, say Y. | ||
334 | |||
335 | config ACPI_PCI_SLOT | 331 | config ACPI_PCI_SLOT |
336 | tristate "PCI slot detection driver" | 332 | tristate "PCI slot detection driver" |
337 | default n | 333 | default n |
@@ -341,10 +337,6 @@ config ACPI_PCI_SLOT | |||
341 | help you correlate PCI bus addresses with the physical geography | 337 | help you correlate PCI bus addresses with the physical geography |
342 | of your slots. If you are unsure, say N. | 338 | of your slots. If you are unsure, say N. |
343 | 339 | ||
344 | config ACPI_POWER | ||
345 | bool | ||
346 | default y | ||
347 | |||
348 | config ACPI_SYSTEM | 340 | config ACPI_SYSTEM |
349 | bool | 341 | bool |
350 | default y | 342 | default y |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index d91c027ece8f..3c0c93300f12 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -39,19 +39,23 @@ obj-y += sleep/ | |||
39 | obj-y += bus.o glue.o | 39 | obj-y += bus.o glue.o |
40 | obj-y += scan.o | 40 | obj-y += scan.o |
41 | # Keep EC driver first. Initialization of others depend on it. | 41 | # Keep EC driver first. Initialization of others depend on it. |
42 | obj-$(CONFIG_ACPI_EC) += ec.o | 42 | obj-y += ec.o |
43 | obj-$(CONFIG_ACPI_AC) += ac.o | 43 | obj-$(CONFIG_ACPI_AC) += ac.o |
44 | obj-$(CONFIG_ACPI_BATTERY) += battery.o | 44 | obj-$(CONFIG_ACPI_BATTERY) += battery.o |
45 | obj-$(CONFIG_ACPI_BUTTON) += button.o | 45 | obj-$(CONFIG_ACPI_BUTTON) += button.o |
46 | obj-$(CONFIG_ACPI_FAN) += fan.o | 46 | obj-$(CONFIG_ACPI_FAN) += fan.o |
47 | obj-$(CONFIG_ACPI_DOCK) += dock.o | 47 | obj-$(CONFIG_ACPI_DOCK) += dock.o |
48 | obj-$(CONFIG_ACPI_VIDEO) += video.o | 48 | obj-$(CONFIG_ACPI_VIDEO) += video.o |
49 | ifdef CONFIG_ACPI_VIDEO | ||
50 | obj-y += video_detect.o | ||
51 | endif | ||
52 | |||
49 | obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o | 53 | obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o |
50 | obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o | 54 | obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o |
51 | obj-$(CONFIG_ACPI_PROCESSOR) += processor.o | 55 | obj-$(CONFIG_ACPI_PROCESSOR) += processor.o |
52 | obj-$(CONFIG_ACPI_CONTAINER) += container.o | 56 | obj-$(CONFIG_ACPI_CONTAINER) += container.o |
53 | obj-$(CONFIG_ACPI_THERMAL) += thermal.o | 57 | obj-$(CONFIG_ACPI_THERMAL) += thermal.o |
54 | obj-$(CONFIG_ACPI_POWER) += power.o | 58 | obj-y += power.o |
55 | obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o | 59 | obj-$(CONFIG_ACPI_SYSTEM) += system.o event.o |
56 | obj-$(CONFIG_ACPI_DEBUG) += debug.o | 60 | obj-$(CONFIG_ACPI_DEBUG) += debug.o |
57 | obj-$(CONFIG_ACPI_NUMA) += numa.o | 61 | obj-$(CONFIG_ACPI_NUMA) += numa.o |
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index d72a1b6c8a94..9b917dac7732 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <acpi/acpi_bus.h> | 37 | #include <acpi/acpi_bus.h> |
38 | #include <acpi/acpi_drivers.h> | 38 | #include <acpi/acpi_drivers.h> |
39 | 39 | ||
40 | #define ACPI_AC_COMPONENT 0x00020000 | ||
41 | #define ACPI_AC_CLASS "ac_adapter" | 40 | #define ACPI_AC_CLASS "ac_adapter" |
42 | #define ACPI_AC_DEVICE_NAME "AC Adapter" | 41 | #define ACPI_AC_DEVICE_NAME "AC Adapter" |
43 | #define ACPI_AC_FILE_STATE "state" | 42 | #define ACPI_AC_FILE_STATE "state" |
@@ -242,7 +241,7 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) | |||
242 | acpi_ac_get_state(ac); | 241 | acpi_ac_get_state(ac); |
243 | acpi_bus_generate_proc_event(device, event, (u32) ac->state); | 242 | acpi_bus_generate_proc_event(device, event, (u32) ac->state); |
244 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 243 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
245 | device->dev.bus_id, event, | 244 | dev_name(&device->dev), event, |
246 | (u32) ac->state); | 245 | (u32) ac->state); |
247 | #ifdef CONFIG_ACPI_SYSFS_POWER | 246 | #ifdef CONFIG_ACPI_SYSFS_POWER |
248 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); | 247 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); |
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 71d21c51c45f..63a17b55b39b 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/memory_hotplug.h> | 32 | #include <linux/memory_hotplug.h> |
33 | #include <acpi/acpi_drivers.h> | 33 | #include <acpi/acpi_drivers.h> |
34 | 34 | ||
35 | #define ACPI_MEMORY_DEVICE_COMPONENT 0x08000000UL | ||
36 | #define ACPI_MEMORY_DEVICE_CLASS "memory" | 35 | #define ACPI_MEMORY_DEVICE_CLASS "memory" |
37 | #define ACPI_MEMORY_DEVICE_HID "PNP0C80" | 36 | #define ACPI_MEMORY_DEVICE_HID "PNP0C80" |
38 | #define ACPI_MEMORY_DEVICE_NAME "Hotplug Mem Device" | 37 | #define ACPI_MEMORY_DEVICE_NAME "Hotplug Mem Device" |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index b2133e89ad9a..1423b0c0cd2e 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -46,7 +46,6 @@ | |||
46 | 46 | ||
47 | #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF | 47 | #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF |
48 | 48 | ||
49 | #define ACPI_BATTERY_COMPONENT 0x00040000 | ||
50 | #define ACPI_BATTERY_CLASS "battery" | 49 | #define ACPI_BATTERY_CLASS "battery" |
51 | #define ACPI_BATTERY_DEVICE_NAME "Battery" | 50 | #define ACPI_BATTERY_DEVICE_NAME "Battery" |
52 | #define ACPI_BATTERY_NOTIFY_STATUS 0x80 | 51 | #define ACPI_BATTERY_NOTIFY_STATUS 0x80 |
@@ -782,7 +781,7 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) | |||
782 | acpi_bus_generate_proc_event(device, event, | 781 | acpi_bus_generate_proc_event(device, event, |
783 | acpi_battery_present(battery)); | 782 | acpi_battery_present(battery)); |
784 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 783 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
785 | device->dev.bus_id, event, | 784 | dev_name(&device->dev), event, |
786 | acpi_battery_present(battery)); | 785 | acpi_battery_present(battery)); |
787 | #ifdef CONFIG_ACPI_SYSFS_POWER | 786 | #ifdef CONFIG_ACPI_SYSFS_POWER |
788 | /* acpi_batter_update could remove power_supply object */ | 787 | /* acpi_batter_update could remove power_supply object */ |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index c797c6473f31..7edf6d913c13 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -688,6 +688,14 @@ void __init acpi_early_init(void) | |||
688 | if (acpi_disabled) | 688 | if (acpi_disabled) |
689 | return; | 689 | return; |
690 | 690 | ||
691 | /* | ||
692 | * ACPI CA initializes acpi_dbg_level to non-zero, which means | ||
693 | * we get debug output merely by turning on CONFIG_ACPI_DEBUG. | ||
694 | * Turn it off so we don't get output unless the user specifies | ||
695 | * acpi.debug_level. | ||
696 | */ | ||
697 | acpi_dbg_level = 0; | ||
698 | |||
691 | printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION); | 699 | printk(KERN_INFO PREFIX "Core revision %08x\n", ACPI_CA_VERSION); |
692 | 700 | ||
693 | /* enable workarounds, unless strict ACPI spec. compliance */ | 701 | /* enable workarounds, unless strict ACPI spec. compliance */ |
@@ -774,7 +782,7 @@ static int __init acpi_bus_init(void) | |||
774 | "Unable to initialize ACPI OS objects\n"); | 782 | "Unable to initialize ACPI OS objects\n"); |
775 | goto error1; | 783 | goto error1; |
776 | } | 784 | } |
777 | #ifdef CONFIG_ACPI_EC | 785 | |
778 | /* | 786 | /* |
779 | * ACPI 2.0 requires the EC driver to be loaded and work before | 787 | * ACPI 2.0 requires the EC driver to be loaded and work before |
780 | * the EC device is found in the namespace (i.e. before acpi_initialize_objects() | 788 | * the EC device is found in the namespace (i.e. before acpi_initialize_objects() |
@@ -785,7 +793,6 @@ static int __init acpi_bus_init(void) | |||
785 | */ | 793 | */ |
786 | status = acpi_ec_ecdt_probe(); | 794 | status = acpi_ec_ecdt_probe(); |
787 | /* Ignore result. Not having an ECDT is not fatal. */ | 795 | /* Ignore result. Not having an ECDT is not fatal. */ |
788 | #endif | ||
789 | 796 | ||
790 | status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION); | 797 | status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION); |
791 | if (ACPI_FAILURE(status)) { | 798 | if (ACPI_FAILURE(status)) { |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index cb046c3fc3f2..171fd914f435 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <acpi/acpi_bus.h> | 33 | #include <acpi/acpi_bus.h> |
34 | #include <acpi/acpi_drivers.h> | 34 | #include <acpi/acpi_drivers.h> |
35 | 35 | ||
36 | #define ACPI_BUTTON_COMPONENT 0x00080000 | ||
37 | #define ACPI_BUTTON_CLASS "button" | 36 | #define ACPI_BUTTON_CLASS "button" |
38 | #define ACPI_BUTTON_FILE_INFO "info" | 37 | #define ACPI_BUTTON_FILE_INFO "info" |
39 | #define ACPI_BUTTON_FILE_STATE "state" | 38 | #define ACPI_BUTTON_FILE_STATE "state" |
@@ -479,7 +478,7 @@ static int acpi_button_add(struct acpi_device *device) | |||
479 | device->wakeup.gpe_number, | 478 | device->wakeup.gpe_number, |
480 | ACPI_GPE_TYPE_WAKE_RUN); | 479 | ACPI_GPE_TYPE_WAKE_RUN); |
481 | acpi_enable_gpe(device->wakeup.gpe_device, | 480 | acpi_enable_gpe(device->wakeup.gpe_device, |
482 | device->wakeup.gpe_number, ACPI_NOT_ISR); | 481 | device->wakeup.gpe_number); |
483 | device->wakeup.state.enabled = 1; | 482 | device->wakeup.state.enabled = 1; |
484 | } | 483 | } |
485 | 484 | ||
diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c index 4441e84b28a9..307963bd1043 100644 --- a/drivers/acpi/cm_sbs.c +++ b/drivers/acpi/cm_sbs.c | |||
@@ -34,7 +34,6 @@ | |||
34 | ACPI_MODULE_NAME("cm_sbs"); | 34 | ACPI_MODULE_NAME("cm_sbs"); |
35 | #define ACPI_AC_CLASS "ac_adapter" | 35 | #define ACPI_AC_CLASS "ac_adapter" |
36 | #define ACPI_BATTERY_CLASS "battery" | 36 | #define ACPI_BATTERY_CLASS "battery" |
37 | #define ACPI_SBS_COMPONENT 0x00080000 | ||
38 | #define _COMPONENT ACPI_SBS_COMPONENT | 37 | #define _COMPONENT ACPI_SBS_COMPONENT |
39 | static struct proc_dir_entry *acpi_ac_dir; | 38 | static struct proc_dir_entry *acpi_ac_dir; |
40 | static struct proc_dir_entry *acpi_battery_dir; | 39 | static struct proc_dir_entry *acpi_battery_dir; |
@@ -105,9 +104,3 @@ void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir_param) | |||
105 | return; | 104 | return; |
106 | } | 105 | } |
107 | EXPORT_SYMBOL(acpi_unlock_battery_dir); | 106 | EXPORT_SYMBOL(acpi_unlock_battery_dir); |
108 | |||
109 | static int __init acpi_cm_sbs_init(void) | ||
110 | { | ||
111 | return 0; | ||
112 | } | ||
113 | subsys_initcall(acpi_cm_sbs_init); | ||
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 134818b265a9..17020c12623c 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #define INSTALL_NOTIFY_HANDLER 1 | 41 | #define INSTALL_NOTIFY_HANDLER 1 |
42 | #define UNINSTALL_NOTIFY_HANDLER 2 | 42 | #define UNINSTALL_NOTIFY_HANDLER 2 |
43 | 43 | ||
44 | #define ACPI_CONTAINER_COMPONENT 0x01000000 | ||
45 | #define _COMPONENT ACPI_CONTAINER_COMPONENT | 44 | #define _COMPONENT ACPI_CONTAINER_COMPONENT |
46 | ACPI_MODULE_NAME("container"); | 45 | ACPI_MODULE_NAME("container"); |
47 | 46 | ||
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c index abf36b4b1d1d..c48396892008 100644 --- a/drivers/acpi/debug.c +++ b/drivers/acpi/debug.c | |||
@@ -44,6 +44,21 @@ static const struct acpi_dlayer acpi_debug_layers[] = { | |||
44 | ACPI_DEBUG_INIT(ACPI_CA_DISASSEMBLER), | 44 | ACPI_DEBUG_INIT(ACPI_CA_DISASSEMBLER), |
45 | ACPI_DEBUG_INIT(ACPI_COMPILER), | 45 | ACPI_DEBUG_INIT(ACPI_COMPILER), |
46 | ACPI_DEBUG_INIT(ACPI_TOOLS), | 46 | ACPI_DEBUG_INIT(ACPI_TOOLS), |
47 | |||
48 | ACPI_DEBUG_INIT(ACPI_BUS_COMPONENT), | ||
49 | ACPI_DEBUG_INIT(ACPI_AC_COMPONENT), | ||
50 | ACPI_DEBUG_INIT(ACPI_BATTERY_COMPONENT), | ||
51 | ACPI_DEBUG_INIT(ACPI_BUTTON_COMPONENT), | ||
52 | ACPI_DEBUG_INIT(ACPI_SBS_COMPONENT), | ||
53 | ACPI_DEBUG_INIT(ACPI_FAN_COMPONENT), | ||
54 | ACPI_DEBUG_INIT(ACPI_PCI_COMPONENT), | ||
55 | ACPI_DEBUG_INIT(ACPI_POWER_COMPONENT), | ||
56 | ACPI_DEBUG_INIT(ACPI_CONTAINER_COMPONENT), | ||
57 | ACPI_DEBUG_INIT(ACPI_SYSTEM_COMPONENT), | ||
58 | ACPI_DEBUG_INIT(ACPI_THERMAL_COMPONENT), | ||
59 | ACPI_DEBUG_INIT(ACPI_MEMORY_DEVICE_COMPONENT), | ||
60 | ACPI_DEBUG_INIT(ACPI_VIDEO_COMPONENT), | ||
61 | ACPI_DEBUG_INIT(ACPI_PROCESSOR_COMPONENT), | ||
47 | }; | 62 | }; |
48 | 63 | ||
49 | static const struct acpi_dlevel acpi_debug_levels[] = { | 64 | static const struct acpi_dlevel acpi_debug_levels[] = { |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index ef42316f89f5..cf41f9fc24a7 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -70,7 +70,7 @@ enum ec_command { | |||
70 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ | 70 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ |
71 | #define ACPI_EC_UDELAY 100 /* Wait 100us before polling EC again */ | 71 | #define ACPI_EC_UDELAY 100 /* Wait 100us before polling EC again */ |
72 | 72 | ||
73 | #define ACPI_EC_STORM_THRESHOLD 20 /* number of false interrupts | 73 | #define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts |
74 | per one transaction */ | 74 | per one transaction */ |
75 | 75 | ||
76 | enum { | 76 | enum { |
@@ -100,8 +100,11 @@ struct transaction { | |||
100 | u8 *rdata; | 100 | u8 *rdata; |
101 | unsigned short irq_count; | 101 | unsigned short irq_count; |
102 | u8 command; | 102 | u8 command; |
103 | u8 wi; | ||
104 | u8 ri; | ||
103 | u8 wlen; | 105 | u8 wlen; |
104 | u8 rlen; | 106 | u8 rlen; |
107 | bool done; | ||
105 | }; | 108 | }; |
106 | 109 | ||
107 | static struct acpi_ec { | 110 | static struct acpi_ec { |
@@ -178,34 +181,45 @@ static int ec_transaction_done(struct acpi_ec *ec) | |||
178 | unsigned long flags; | 181 | unsigned long flags; |
179 | int ret = 0; | 182 | int ret = 0; |
180 | spin_lock_irqsave(&ec->curr_lock, flags); | 183 | spin_lock_irqsave(&ec->curr_lock, flags); |
181 | if (!ec->curr || (!ec->curr->wlen && !ec->curr->rlen)) | 184 | if (!ec->curr || ec->curr->done) |
182 | ret = 1; | 185 | ret = 1; |
183 | spin_unlock_irqrestore(&ec->curr_lock, flags); | 186 | spin_unlock_irqrestore(&ec->curr_lock, flags); |
184 | return ret; | 187 | return ret; |
185 | } | 188 | } |
186 | 189 | ||
190 | static void start_transaction(struct acpi_ec *ec) | ||
191 | { | ||
192 | ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0; | ||
193 | ec->curr->done = false; | ||
194 | acpi_ec_write_cmd(ec, ec->curr->command); | ||
195 | } | ||
196 | |||
187 | static void gpe_transaction(struct acpi_ec *ec, u8 status) | 197 | static void gpe_transaction(struct acpi_ec *ec, u8 status) |
188 | { | 198 | { |
189 | unsigned long flags; | 199 | unsigned long flags; |
190 | spin_lock_irqsave(&ec->curr_lock, flags); | 200 | spin_lock_irqsave(&ec->curr_lock, flags); |
191 | if (!ec->curr) | 201 | if (!ec->curr) |
192 | goto unlock; | 202 | goto unlock; |
193 | if (ec->curr->wlen > 0) { | 203 | if (ec->curr->wlen > ec->curr->wi) { |
194 | if ((status & ACPI_EC_FLAG_IBF) == 0) { | 204 | if ((status & ACPI_EC_FLAG_IBF) == 0) |
195 | acpi_ec_write_data(ec, *(ec->curr->wdata++)); | 205 | acpi_ec_write_data(ec, |
196 | --ec->curr->wlen; | 206 | ec->curr->wdata[ec->curr->wi++]); |
197 | } else | 207 | else |
198 | /* false interrupt, state didn't change */ | 208 | goto err; |
199 | ++ec->curr->irq_count; | 209 | } else if (ec->curr->rlen > ec->curr->ri) { |
200 | |||
201 | } else if (ec->curr->rlen > 0) { | ||
202 | if ((status & ACPI_EC_FLAG_OBF) == 1) { | 210 | if ((status & ACPI_EC_FLAG_OBF) == 1) { |
203 | *(ec->curr->rdata++) = acpi_ec_read_data(ec); | 211 | ec->curr->rdata[ec->curr->ri++] = acpi_ec_read_data(ec); |
204 | --ec->curr->rlen; | 212 | if (ec->curr->rlen == ec->curr->ri) |
213 | ec->curr->done = true; | ||
205 | } else | 214 | } else |
206 | /* false interrupt, state didn't change */ | 215 | goto err; |
207 | ++ec->curr->irq_count; | 216 | } else if (ec->curr->wlen == ec->curr->wi && |
208 | } | 217 | (status & ACPI_EC_FLAG_IBF) == 0) |
218 | ec->curr->done = true; | ||
219 | goto unlock; | ||
220 | err: | ||
221 | /* false interrupt, state didn't change */ | ||
222 | ++ec->curr->irq_count; | ||
209 | unlock: | 223 | unlock: |
210 | spin_unlock_irqrestore(&ec->curr_lock, flags); | 224 | spin_unlock_irqrestore(&ec->curr_lock, flags); |
211 | } | 225 | } |
@@ -215,6 +229,15 @@ static int acpi_ec_wait(struct acpi_ec *ec) | |||
215 | if (wait_event_timeout(ec->wait, ec_transaction_done(ec), | 229 | if (wait_event_timeout(ec->wait, ec_transaction_done(ec), |
216 | msecs_to_jiffies(ACPI_EC_DELAY))) | 230 | msecs_to_jiffies(ACPI_EC_DELAY))) |
217 | return 0; | 231 | return 0; |
232 | /* try restart command if we get any false interrupts */ | ||
233 | if (ec->curr->irq_count && | ||
234 | (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) { | ||
235 | pr_debug(PREFIX "controller reset, restart transaction\n"); | ||
236 | start_transaction(ec); | ||
237 | if (wait_event_timeout(ec->wait, ec_transaction_done(ec), | ||
238 | msecs_to_jiffies(ACPI_EC_DELAY))) | ||
239 | return 0; | ||
240 | } | ||
218 | /* missing GPEs, switch back to poll mode */ | 241 | /* missing GPEs, switch back to poll mode */ |
219 | if (printk_ratelimit()) | 242 | if (printk_ratelimit()) |
220 | pr_info(PREFIX "missing confirmations, " | 243 | pr_info(PREFIX "missing confirmations, " |
@@ -239,10 +262,10 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state) | |||
239 | static int ec_poll(struct acpi_ec *ec) | 262 | static int ec_poll(struct acpi_ec *ec) |
240 | { | 263 | { |
241 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); | 264 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); |
242 | msleep(1); | 265 | udelay(ACPI_EC_UDELAY); |
243 | while (time_before(jiffies, delay)) { | 266 | while (time_before(jiffies, delay)) { |
244 | gpe_transaction(ec, acpi_ec_read_status(ec)); | 267 | gpe_transaction(ec, acpi_ec_read_status(ec)); |
245 | msleep(1); | 268 | udelay(ACPI_EC_UDELAY); |
246 | if (ec_transaction_done(ec)) | 269 | if (ec_transaction_done(ec)) |
247 | return 0; | 270 | return 0; |
248 | } | 271 | } |
@@ -259,14 +282,13 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
259 | /* disable GPE during transaction if storm is detected */ | 282 | /* disable GPE during transaction if storm is detected */ |
260 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | 283 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
261 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | 284 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); |
262 | acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); | 285 | acpi_disable_gpe(NULL, ec->gpe); |
263 | } | 286 | } |
264 | /* start transaction */ | 287 | /* start transaction */ |
265 | spin_lock_irqsave(&ec->curr_lock, tmp); | 288 | spin_lock_irqsave(&ec->curr_lock, tmp); |
266 | /* following two actions should be kept atomic */ | 289 | /* following two actions should be kept atomic */ |
267 | t->irq_count = 0; | ||
268 | ec->curr = t; | 290 | ec->curr = t; |
269 | acpi_ec_write_cmd(ec, ec->curr->command); | 291 | start_transaction(ec); |
270 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) | 292 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) |
271 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 293 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
272 | spin_unlock_irqrestore(&ec->curr_lock, tmp); | 294 | spin_unlock_irqrestore(&ec->curr_lock, tmp); |
@@ -283,10 +305,11 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
283 | /* check if we received SCI during transaction */ | 305 | /* check if we received SCI during transaction */ |
284 | ec_check_sci(ec, acpi_ec_read_status(ec)); | 306 | ec_check_sci(ec, acpi_ec_read_status(ec)); |
285 | /* it is safe to enable GPE outside of transaction */ | 307 | /* it is safe to enable GPE outside of transaction */ |
286 | acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); | 308 | acpi_enable_gpe(NULL, ec->gpe); |
287 | } else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && | 309 | } else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && |
288 | t->irq_count > ACPI_EC_STORM_THRESHOLD) { | 310 | t->irq_count > ACPI_EC_STORM_THRESHOLD) { |
289 | pr_debug(PREFIX "GPE storm detected\n"); | 311 | pr_info(PREFIX "GPE storm detected, " |
312 | "transactions will use polling mode\n"); | ||
290 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); | 313 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); |
291 | } | 314 | } |
292 | return ret; | 315 | return ret; |
@@ -558,17 +581,26 @@ static u32 acpi_ec_gpe_handler(void *data) | |||
558 | pr_debug(PREFIX "~~~> interrupt\n"); | 581 | pr_debug(PREFIX "~~~> interrupt\n"); |
559 | status = acpi_ec_read_status(ec); | 582 | status = acpi_ec_read_status(ec); |
560 | 583 | ||
561 | gpe_transaction(ec, status); | 584 | if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) { |
562 | if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0) | 585 | gpe_transaction(ec, status); |
563 | wake_up(&ec->wait); | 586 | if (ec_transaction_done(ec) && |
587 | (status & ACPI_EC_FLAG_IBF) == 0) | ||
588 | wake_up(&ec->wait); | ||
589 | } | ||
564 | 590 | ||
565 | ec_check_sci(ec, status); | 591 | ec_check_sci(ec, status); |
566 | if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && | 592 | if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) && |
567 | !test_bit(EC_FLAGS_NO_GPE, &ec->flags)) { | 593 | !test_bit(EC_FLAGS_NO_GPE, &ec->flags)) { |
568 | /* this is non-query, must be confirmation */ | 594 | /* this is non-query, must be confirmation */ |
569 | if (printk_ratelimit()) | 595 | if (!test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
570 | pr_info(PREFIX "non-query interrupt received," | 596 | if (printk_ratelimit()) |
597 | pr_info(PREFIX "non-query interrupt received," | ||
598 | " switching to interrupt mode\n"); | ||
599 | } else { | ||
600 | /* hush, STORM switches the mode every transaction */ | ||
601 | pr_debug(PREFIX "non-query interrupt received," | ||
571 | " switching to interrupt mode\n"); | 602 | " switching to interrupt mode\n"); |
603 | } | ||
572 | set_bit(EC_FLAGS_GPE_MODE, &ec->flags); | 604 | set_bit(EC_FLAGS_GPE_MODE, &ec->flags); |
573 | } | 605 | } |
574 | return ACPI_INTERRUPT_HANDLED; | 606 | return ACPI_INTERRUPT_HANDLED; |
@@ -736,7 +768,7 @@ static acpi_status | |||
736 | ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) | 768 | ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) |
737 | { | 769 | { |
738 | acpi_status status; | 770 | acpi_status status; |
739 | unsigned long long tmp; | 771 | unsigned long long tmp = 0; |
740 | 772 | ||
741 | struct acpi_ec *ec = context; | 773 | struct acpi_ec *ec = context; |
742 | status = acpi_walk_resources(handle, METHOD_NAME__CRS, | 774 | status = acpi_walk_resources(handle, METHOD_NAME__CRS, |
@@ -751,6 +783,7 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) | |||
751 | return status; | 783 | return status; |
752 | ec->gpe = tmp; | 784 | ec->gpe = tmp; |
753 | /* Use the global lock for all EC transactions? */ | 785 | /* Use the global lock for all EC transactions? */ |
786 | tmp = 0; | ||
754 | acpi_evaluate_integer(handle, "_GLK", NULL, &tmp); | 787 | acpi_evaluate_integer(handle, "_GLK", NULL, &tmp); |
755 | ec->global_lock = tmp; | 788 | ec->global_lock = tmp; |
756 | ec->handle = handle; | 789 | ec->handle = handle; |
@@ -868,7 +901,7 @@ static int ec_install_handlers(struct acpi_ec *ec) | |||
868 | if (ACPI_FAILURE(status)) | 901 | if (ACPI_FAILURE(status)) |
869 | return -ENODEV; | 902 | return -ENODEV; |
870 | acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); | 903 | acpi_set_gpe_type(NULL, ec->gpe, ACPI_GPE_TYPE_RUNTIME); |
871 | acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); | 904 | acpi_enable_gpe(NULL, ec->gpe); |
872 | status = acpi_install_address_space_handler(ec->handle, | 905 | status = acpi_install_address_space_handler(ec->handle, |
873 | ACPI_ADR_SPACE_EC, | 906 | ACPI_ADR_SPACE_EC, |
874 | &acpi_ec_space_handler, | 907 | &acpi_ec_space_handler, |
@@ -1007,7 +1040,7 @@ static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state) | |||
1007 | /* Stop using GPE */ | 1040 | /* Stop using GPE */ |
1008 | set_bit(EC_FLAGS_NO_GPE, &ec->flags); | 1041 | set_bit(EC_FLAGS_NO_GPE, &ec->flags); |
1009 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | 1042 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); |
1010 | acpi_disable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); | 1043 | acpi_disable_gpe(NULL, ec->gpe); |
1011 | return 0; | 1044 | return 0; |
1012 | } | 1045 | } |
1013 | 1046 | ||
@@ -1016,7 +1049,7 @@ static int acpi_ec_resume(struct acpi_device *device) | |||
1016 | struct acpi_ec *ec = acpi_driver_data(device); | 1049 | struct acpi_ec *ec = acpi_driver_data(device); |
1017 | /* Enable use of GPE back */ | 1050 | /* Enable use of GPE back */ |
1018 | clear_bit(EC_FLAGS_NO_GPE, &ec->flags); | 1051 | clear_bit(EC_FLAGS_NO_GPE, &ec->flags); |
1019 | acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR); | 1052 | acpi_enable_gpe(NULL, ec->gpe); |
1020 | return 0; | 1053 | return 0; |
1021 | } | 1054 | } |
1022 | 1055 | ||
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c index c5e53aae86f7..f45c74fe745e 100644 --- a/drivers/acpi/events/evgpe.c +++ b/drivers/acpi/events/evgpe.c | |||
@@ -289,8 +289,6 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
289 | */ | 289 | */ |
290 | status = acpi_hw_low_disable_gpe(gpe_event_info); | 290 | status = acpi_hw_low_disable_gpe(gpe_event_info); |
291 | return_ACPI_STATUS(status); | 291 | return_ACPI_STATUS(status); |
292 | |||
293 | return_ACPI_STATUS(AE_OK); | ||
294 | } | 292 | } |
295 | 293 | ||
296 | /******************************************************************************* | 294 | /******************************************************************************* |
diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c index 73bfd6bf962f..41554f736b68 100644 --- a/drivers/acpi/events/evxfevnt.c +++ b/drivers/acpi/events/evxfevnt.c | |||
@@ -248,21 +248,15 @@ ACPI_EXPORT_SYMBOL(acpi_set_gpe_type) | |||
248 | * DESCRIPTION: Enable an ACPI event (general purpose) | 248 | * DESCRIPTION: Enable an ACPI event (general purpose) |
249 | * | 249 | * |
250 | ******************************************************************************/ | 250 | ******************************************************************************/ |
251 | acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) | 251 | acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) |
252 | { | 252 | { |
253 | acpi_status status = AE_OK; | 253 | acpi_status status = AE_OK; |
254 | acpi_cpu_flags flags; | ||
254 | struct acpi_gpe_event_info *gpe_event_info; | 255 | struct acpi_gpe_event_info *gpe_event_info; |
255 | 256 | ||
256 | ACPI_FUNCTION_TRACE(acpi_enable_gpe); | 257 | ACPI_FUNCTION_TRACE(acpi_enable_gpe); |
257 | 258 | ||
258 | /* Use semaphore lock if not executing at interrupt level */ | 259 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); |
259 | |||
260 | if (flags & ACPI_NOT_ISR) { | ||
261 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
262 | if (ACPI_FAILURE(status)) { | ||
263 | return_ACPI_STATUS(status); | ||
264 | } | ||
265 | } | ||
266 | 260 | ||
267 | /* Ensure that we have a valid GPE number */ | 261 | /* Ensure that we have a valid GPE number */ |
268 | 262 | ||
@@ -277,9 +271,7 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) | |||
277 | status = acpi_ev_enable_gpe(gpe_event_info, TRUE); | 271 | status = acpi_ev_enable_gpe(gpe_event_info, TRUE); |
278 | 272 | ||
279 | unlock_and_exit: | 273 | unlock_and_exit: |
280 | if (flags & ACPI_NOT_ISR) { | 274 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
281 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
282 | } | ||
283 | return_ACPI_STATUS(status); | 275 | return_ACPI_STATUS(status); |
284 | } | 276 | } |
285 | 277 | ||
@@ -299,22 +291,15 @@ ACPI_EXPORT_SYMBOL(acpi_enable_gpe) | |||
299 | * DESCRIPTION: Disable an ACPI event (general purpose) | 291 | * DESCRIPTION: Disable an ACPI event (general purpose) |
300 | * | 292 | * |
301 | ******************************************************************************/ | 293 | ******************************************************************************/ |
302 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) | 294 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) |
303 | { | 295 | { |
304 | acpi_status status = AE_OK; | 296 | acpi_status status = AE_OK; |
297 | acpi_cpu_flags flags; | ||
305 | struct acpi_gpe_event_info *gpe_event_info; | 298 | struct acpi_gpe_event_info *gpe_event_info; |
306 | 299 | ||
307 | ACPI_FUNCTION_TRACE(acpi_disable_gpe); | 300 | ACPI_FUNCTION_TRACE(acpi_disable_gpe); |
308 | 301 | ||
309 | /* Use semaphore lock if not executing at interrupt level */ | 302 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); |
310 | |||
311 | if (flags & ACPI_NOT_ISR) { | ||
312 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
313 | if (ACPI_FAILURE(status)) { | ||
314 | return_ACPI_STATUS(status); | ||
315 | } | ||
316 | } | ||
317 | |||
318 | /* Ensure that we have a valid GPE number */ | 303 | /* Ensure that we have a valid GPE number */ |
319 | 304 | ||
320 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | 305 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); |
@@ -325,10 +310,8 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u32 flags) | |||
325 | 310 | ||
326 | status = acpi_ev_disable_gpe(gpe_event_info); | 311 | status = acpi_ev_disable_gpe(gpe_event_info); |
327 | 312 | ||
328 | unlock_and_exit: | 313 | unlock_and_exit: |
329 | if (flags & ACPI_NOT_ISR) { | 314 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
330 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
331 | } | ||
332 | return_ACPI_STATUS(status); | 315 | return_ACPI_STATUS(status); |
333 | } | 316 | } |
334 | 317 | ||
@@ -521,6 +504,9 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) | |||
521 | if (value) | 504 | if (value) |
522 | *event_status |= ACPI_EVENT_FLAG_SET; | 505 | *event_status |= ACPI_EVENT_FLAG_SET; |
523 | 506 | ||
507 | if (acpi_gbl_fixed_event_handlers[event].handler) | ||
508 | *event_status |= ACPI_EVENT_FLAG_HANDLE; | ||
509 | |||
524 | return_ACPI_STATUS(status); | 510 | return_ACPI_STATUS(status); |
525 | } | 511 | } |
526 | 512 | ||
@@ -571,6 +557,9 @@ acpi_get_gpe_status(acpi_handle gpe_device, | |||
571 | 557 | ||
572 | status = acpi_hw_get_gpe_status(gpe_event_info, event_status); | 558 | status = acpi_hw_get_gpe_status(gpe_event_info, event_status); |
573 | 559 | ||
560 | if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) | ||
561 | *event_status |= ACPI_EVENT_FLAG_HANDLE; | ||
562 | |||
574 | unlock_and_exit: | 563 | unlock_and_exit: |
575 | if (flags & ACPI_NOT_ISR) { | 564 | if (flags & ACPI_NOT_ISR) { |
576 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | 565 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 60d54d1f6b19..eaaee1660bdf 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <acpi/acpi_bus.h> | 34 | #include <acpi/acpi_bus.h> |
35 | #include <acpi/acpi_drivers.h> | 35 | #include <acpi/acpi_drivers.h> |
36 | 36 | ||
37 | #define ACPI_FAN_COMPONENT 0x00200000 | ||
38 | #define ACPI_FAN_CLASS "fan" | 37 | #define ACPI_FAN_CLASS "fan" |
39 | #define ACPI_FAN_FILE_STATE "state" | 38 | #define ACPI_FAN_FILE_STATE "state" |
40 | 39 | ||
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 24649ada08df..adec3d15810a 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -140,6 +140,46 @@ struct device *acpi_get_physical_device(acpi_handle handle) | |||
140 | 140 | ||
141 | EXPORT_SYMBOL(acpi_get_physical_device); | 141 | EXPORT_SYMBOL(acpi_get_physical_device); |
142 | 142 | ||
143 | /* ToDo: When a PCI bridge is found, return the PCI device behind the bridge | ||
144 | * This should work in general, but did not on a Lenovo T61 for the | ||
145 | * graphics card. But this must be fixed when the PCI device is | ||
146 | * bound and the kernel device struct is attached to the acpi device | ||
147 | * Note: A success call will increase reference count by one | ||
148 | * Do call put_device(dev) on the returned device then | ||
149 | */ | ||
150 | struct device *acpi_get_physical_pci_device(acpi_handle handle) | ||
151 | { | ||
152 | struct device *dev; | ||
153 | long long device_id; | ||
154 | acpi_status status; | ||
155 | |||
156 | status = | ||
157 | acpi_evaluate_integer(handle, "_ADR", NULL, &device_id); | ||
158 | |||
159 | if (ACPI_FAILURE(status)) | ||
160 | return NULL; | ||
161 | |||
162 | /* We need to attempt to determine whether the _ADR refers to a | ||
163 | PCI device or not. There's no terribly good way to do this, | ||
164 | so the best we can hope for is to assume that there'll never | ||
165 | be a device in the host bridge */ | ||
166 | if (device_id >= 0x10000) { | ||
167 | /* It looks like a PCI device. Does it exist? */ | ||
168 | dev = acpi_get_physical_device(handle); | ||
169 | } else { | ||
170 | /* It doesn't look like a PCI device. Does its parent | ||
171 | exist? */ | ||
172 | acpi_handle phandle; | ||
173 | if (acpi_get_parent(handle, &phandle)) | ||
174 | return NULL; | ||
175 | dev = acpi_get_physical_device(phandle); | ||
176 | } | ||
177 | if (!dev) | ||
178 | return NULL; | ||
179 | return dev; | ||
180 | } | ||
181 | EXPORT_SYMBOL(acpi_get_physical_pci_device); | ||
182 | |||
143 | static int acpi_bind_one(struct device *dev, acpi_handle handle) | 183 | static int acpi_bind_one(struct device *dev, acpi_handle handle) |
144 | { | 184 | { |
145 | struct acpi_device *acpi_dev; | 185 | struct acpi_device *acpi_dev; |
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index fcfdef7b4fdd..e52ad91ce2dc 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c | |||
@@ -531,7 +531,7 @@ int __init acpi_irq_penalty_init(void) | |||
531 | return 0; | 531 | return 0; |
532 | } | 532 | } |
533 | 533 | ||
534 | static int acpi_irq_balance; /* 0: static, 1: balance */ | 534 | static int acpi_irq_balance = -1; /* 0: static, 1: balance */ |
535 | 535 | ||
536 | static int acpi_pci_link_allocate(struct acpi_pci_link *link) | 536 | static int acpi_pci_link_allocate(struct acpi_pci_link *link) |
537 | { | 537 | { |
@@ -950,10 +950,17 @@ device_initcall(irqrouter_init_sysfs); | |||
950 | 950 | ||
951 | static int __init acpi_pci_link_init(void) | 951 | static int __init acpi_pci_link_init(void) |
952 | { | 952 | { |
953 | |||
954 | if (acpi_noirq) | 953 | if (acpi_noirq) |
955 | return 0; | 954 | return 0; |
956 | 955 | ||
956 | if (acpi_irq_balance == -1) { | ||
957 | /* no command line switch: enable balancing in IOAPIC mode */ | ||
958 | if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) | ||
959 | acpi_irq_balance = 1; | ||
960 | else | ||
961 | acpi_irq_balance = 0; | ||
962 | } | ||
963 | |||
957 | acpi_link.count = 0; | 964 | acpi_link.count = 0; |
958 | INIT_LIST_HEAD(&acpi_link.entries); | 965 | INIT_LIST_HEAD(&acpi_link.entries); |
959 | 966 | ||
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 1b8f67d21d53..642554b1b60c 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -376,15 +376,9 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type) | |||
376 | 376 | ||
377 | static int __init acpi_pci_root_init(void) | 377 | static int __init acpi_pci_root_init(void) |
378 | { | 378 | { |
379 | |||
380 | if (acpi_pci_disabled) | 379 | if (acpi_pci_disabled) |
381 | return 0; | 380 | return 0; |
382 | 381 | ||
383 | /* DEBUG: | ||
384 | acpi_dbg_layer = ACPI_PCI_COMPONENT; | ||
385 | acpi_dbg_level = 0xFFFFFFFF; | ||
386 | */ | ||
387 | |||
388 | if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0) | 382 | if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0) |
389 | return -ENODEV; | 383 | return -ENODEV; |
390 | 384 | ||
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index a1718e56103b..bb7d50dd2818 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -44,9 +44,8 @@ | |||
44 | #include <acpi/acpi_bus.h> | 44 | #include <acpi/acpi_bus.h> |
45 | #include <acpi/acpi_drivers.h> | 45 | #include <acpi/acpi_drivers.h> |
46 | 46 | ||
47 | #define _COMPONENT ACPI_POWER_COMPONENT | 47 | #define _COMPONENT ACPI_POWER_COMPONENT |
48 | ACPI_MODULE_NAME("power"); | 48 | ACPI_MODULE_NAME("power"); |
49 | #define ACPI_POWER_COMPONENT 0x00800000 | ||
50 | #define ACPI_POWER_CLASS "power_resource" | 49 | #define ACPI_POWER_CLASS "power_resource" |
51 | #define ACPI_POWER_DEVICE_NAME "Power Resource" | 50 | #define ACPI_POWER_DEVICE_NAME "Power Resource" |
52 | #define ACPI_POWER_FILE_INFO "info" | 51 | #define ACPI_POWER_FILE_INFO "info" |
@@ -153,7 +152,8 @@ static int acpi_power_get_state(acpi_handle handle, int *state) | |||
153 | ACPI_POWER_RESOURCE_STATE_OFF; | 152 | ACPI_POWER_RESOURCE_STATE_OFF; |
154 | 153 | ||
155 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n", | 154 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n", |
156 | acpi_ut_get_node_name(handle), state ? "on" : "off")); | 155 | acpi_ut_get_node_name(handle), |
156 | *state ? "on" : "off")); | ||
157 | 157 | ||
158 | return 0; | 158 | return 0; |
159 | } | 159 | } |
@@ -516,11 +516,6 @@ int acpi_power_transition(struct acpi_device *device, int state) | |||
516 | cl = &device->power.states[device->power.state].resources; | 516 | cl = &device->power.states[device->power.state].resources; |
517 | tl = &device->power.states[state].resources; | 517 | tl = &device->power.states[state].resources; |
518 | 518 | ||
519 | if (!cl->count && !tl->count) { | ||
520 | result = -ENODEV; | ||
521 | goto end; | ||
522 | } | ||
523 | |||
524 | /* TBD: Resources must be ordered. */ | 519 | /* TBD: Resources must be ordered. */ |
525 | 520 | ||
526 | /* | 521 | /* |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 24a362f8034c..34948362f41d 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -59,7 +59,6 @@ | |||
59 | #include <acpi/acpi_drivers.h> | 59 | #include <acpi/acpi_drivers.h> |
60 | #include <acpi/processor.h> | 60 | #include <acpi/processor.h> |
61 | 61 | ||
62 | #define ACPI_PROCESSOR_COMPONENT 0x01000000 | ||
63 | #define ACPI_PROCESSOR_CLASS "processor" | 62 | #define ACPI_PROCESSOR_CLASS "processor" |
64 | #define ACPI_PROCESSOR_DEVICE_NAME "Processor" | 63 | #define ACPI_PROCESSOR_DEVICE_NAME "Processor" |
65 | #define ACPI_PROCESSOR_FILE_INFO "info" | 64 | #define ACPI_PROCESSOR_FILE_INFO "info" |
@@ -89,6 +88,7 @@ static int acpi_processor_handle_eject(struct acpi_processor *pr); | |||
89 | 88 | ||
90 | 89 | ||
91 | static const struct acpi_device_id processor_device_ids[] = { | 90 | static const struct acpi_device_id processor_device_ids[] = { |
91 | {ACPI_PROCESSOR_OBJECT_HID, 0}, | ||
92 | {ACPI_PROCESSOR_HID, 0}, | 92 | {ACPI_PROCESSOR_HID, 0}, |
93 | {"", 0}, | 93 | {"", 0}, |
94 | }; | 94 | }; |
@@ -409,7 +409,7 @@ static int acpi_processor_remove_fs(struct acpi_device *device) | |||
409 | /* Use the acpiid in MADT to map cpus in case of SMP */ | 409 | /* Use the acpiid in MADT to map cpus in case of SMP */ |
410 | 410 | ||
411 | #ifndef CONFIG_SMP | 411 | #ifndef CONFIG_SMP |
412 | static int get_cpu_id(acpi_handle handle, u32 acpi_id) {return -1;} | 412 | static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) { return -1; } |
413 | #else | 413 | #else |
414 | 414 | ||
415 | static struct acpi_table_madt *madt; | 415 | static struct acpi_table_madt *madt; |
@@ -428,27 +428,35 @@ static int map_lapic_id(struct acpi_subtable_header *entry, | |||
428 | } | 428 | } |
429 | 429 | ||
430 | static int map_lsapic_id(struct acpi_subtable_header *entry, | 430 | static int map_lsapic_id(struct acpi_subtable_header *entry, |
431 | u32 acpi_id, int *apic_id) | 431 | int device_declaration, u32 acpi_id, int *apic_id) |
432 | { | 432 | { |
433 | struct acpi_madt_local_sapic *lsapic = | 433 | struct acpi_madt_local_sapic *lsapic = |
434 | (struct acpi_madt_local_sapic *)entry; | 434 | (struct acpi_madt_local_sapic *)entry; |
435 | u32 tmp = (lsapic->id << 8) | lsapic->eid; | ||
436 | |||
435 | /* Only check enabled APICs*/ | 437 | /* Only check enabled APICs*/ |
436 | if (lsapic->lapic_flags & ACPI_MADT_ENABLED) { | 438 | if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED)) |
437 | /* First check against id */ | 439 | return 0; |
438 | if (lsapic->processor_id == acpi_id) { | 440 | |
439 | *apic_id = (lsapic->id << 8) | lsapic->eid; | 441 | /* Device statement declaration type */ |
440 | return 1; | 442 | if (device_declaration) { |
441 | /* Check against optional uid */ | 443 | if (entry->length < 16) |
442 | } else if (entry->length >= 16 && | 444 | printk(KERN_ERR PREFIX |
443 | lsapic->uid == acpi_id) { | 445 | "Invalid LSAPIC with Device type processor (SAPIC ID %#x)\n", |
444 | *apic_id = lsapic->uid; | 446 | tmp); |
445 | return 1; | 447 | else if (lsapic->uid == acpi_id) |
446 | } | 448 | goto found; |
447 | } | 449 | /* Processor statement declaration type */ |
450 | } else if (lsapic->processor_id == acpi_id) | ||
451 | goto found; | ||
452 | |||
448 | return 0; | 453 | return 0; |
454 | found: | ||
455 | *apic_id = tmp; | ||
456 | return 1; | ||
449 | } | 457 | } |
450 | 458 | ||
451 | static int map_madt_entry(u32 acpi_id) | 459 | static int map_madt_entry(int type, u32 acpi_id) |
452 | { | 460 | { |
453 | unsigned long madt_end, entry; | 461 | unsigned long madt_end, entry; |
454 | int apic_id = -1; | 462 | int apic_id = -1; |
@@ -469,7 +477,7 @@ static int map_madt_entry(u32 acpi_id) | |||
469 | if (map_lapic_id(header, acpi_id, &apic_id)) | 477 | if (map_lapic_id(header, acpi_id, &apic_id)) |
470 | break; | 478 | break; |
471 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { | 479 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { |
472 | if (map_lsapic_id(header, acpi_id, &apic_id)) | 480 | if (map_lsapic_id(header, type, acpi_id, &apic_id)) |
473 | break; | 481 | break; |
474 | } | 482 | } |
475 | entry += header->length; | 483 | entry += header->length; |
@@ -477,7 +485,7 @@ static int map_madt_entry(u32 acpi_id) | |||
477 | return apic_id; | 485 | return apic_id; |
478 | } | 486 | } |
479 | 487 | ||
480 | static int map_mat_entry(acpi_handle handle, u32 acpi_id) | 488 | static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) |
481 | { | 489 | { |
482 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 490 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
483 | union acpi_object *obj; | 491 | union acpi_object *obj; |
@@ -500,7 +508,7 @@ static int map_mat_entry(acpi_handle handle, u32 acpi_id) | |||
500 | if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { | 508 | if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { |
501 | map_lapic_id(header, acpi_id, &apic_id); | 509 | map_lapic_id(header, acpi_id, &apic_id); |
502 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { | 510 | } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { |
503 | map_lsapic_id(header, acpi_id, &apic_id); | 511 | map_lsapic_id(header, type, acpi_id, &apic_id); |
504 | } | 512 | } |
505 | 513 | ||
506 | exit: | 514 | exit: |
@@ -509,14 +517,14 @@ exit: | |||
509 | return apic_id; | 517 | return apic_id; |
510 | } | 518 | } |
511 | 519 | ||
512 | static int get_cpu_id(acpi_handle handle, u32 acpi_id) | 520 | static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) |
513 | { | 521 | { |
514 | int i; | 522 | int i; |
515 | int apic_id = -1; | 523 | int apic_id = -1; |
516 | 524 | ||
517 | apic_id = map_mat_entry(handle, acpi_id); | 525 | apic_id = map_mat_entry(handle, type, acpi_id); |
518 | if (apic_id == -1) | 526 | if (apic_id == -1) |
519 | apic_id = map_madt_entry(acpi_id); | 527 | apic_id = map_madt_entry(type, acpi_id); |
520 | if (apic_id == -1) | 528 | if (apic_id == -1) |
521 | return apic_id; | 529 | return apic_id; |
522 | 530 | ||
@@ -532,15 +540,16 @@ static int get_cpu_id(acpi_handle handle, u32 acpi_id) | |||
532 | Driver Interface | 540 | Driver Interface |
533 | -------------------------------------------------------------------------- */ | 541 | -------------------------------------------------------------------------- */ |
534 | 542 | ||
535 | static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) | 543 | static int acpi_processor_get_info(struct acpi_device *device) |
536 | { | 544 | { |
537 | acpi_status status = 0; | 545 | acpi_status status = 0; |
538 | union acpi_object object = { 0 }; | 546 | union acpi_object object = { 0 }; |
539 | struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; | 547 | struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; |
540 | int cpu_index; | 548 | struct acpi_processor *pr; |
549 | int cpu_index, device_declaration = 0; | ||
541 | static int cpu0_initialized; | 550 | static int cpu0_initialized; |
542 | 551 | ||
543 | 552 | pr = acpi_driver_data(device); | |
544 | if (!pr) | 553 | if (!pr) |
545 | return -EINVAL; | 554 | return -EINVAL; |
546 | 555 | ||
@@ -561,22 +570,23 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) | |||
561 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 570 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
562 | "No bus mastering arbitration control\n")); | 571 | "No bus mastering arbitration control\n")); |
563 | 572 | ||
564 | /* Check if it is a Device with HID and UID */ | 573 | if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_HID)) { |
565 | if (has_uid) { | 574 | /* |
575 | * Declared with "Device" statement; match _UID. | ||
576 | * Note that we don't handle string _UIDs yet. | ||
577 | */ | ||
566 | unsigned long long value; | 578 | unsigned long long value; |
567 | status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID, | 579 | status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID, |
568 | NULL, &value); | 580 | NULL, &value); |
569 | if (ACPI_FAILURE(status)) { | 581 | if (ACPI_FAILURE(status)) { |
570 | printk(KERN_ERR PREFIX "Evaluating processor _UID\n"); | 582 | printk(KERN_ERR PREFIX |
583 | "Evaluating processor _UID [%#x]\n", status); | ||
571 | return -ENODEV; | 584 | return -ENODEV; |
572 | } | 585 | } |
586 | device_declaration = 1; | ||
573 | pr->acpi_id = value; | 587 | pr->acpi_id = value; |
574 | } else { | 588 | } else { |
575 | /* | 589 | /* Declared with "Processor" statement; match ProcessorID */ |
576 | * Evalute the processor object. Note that it is common on SMP to | ||
577 | * have the first (boot) processor with a valid PBLK address while | ||
578 | * all others have a NULL address. | ||
579 | */ | ||
580 | status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); | 590 | status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); |
581 | if (ACPI_FAILURE(status)) { | 591 | if (ACPI_FAILURE(status)) { |
582 | printk(KERN_ERR PREFIX "Evaluating processor object\n"); | 592 | printk(KERN_ERR PREFIX "Evaluating processor object\n"); |
@@ -584,12 +594,13 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) | |||
584 | } | 594 | } |
585 | 595 | ||
586 | /* | 596 | /* |
587 | * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. | 597 | * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. |
588 | * >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c | 598 | * >>> 'acpi_get_processor_id(acpi_id, &id)' in |
589 | */ | 599 | * arch/xxx/acpi.c |
600 | */ | ||
590 | pr->acpi_id = object.processor.proc_id; | 601 | pr->acpi_id = object.processor.proc_id; |
591 | } | 602 | } |
592 | cpu_index = get_cpu_id(pr->handle, pr->acpi_id); | 603 | cpu_index = get_cpu_id(pr->handle, device_declaration, pr->acpi_id); |
593 | 604 | ||
594 | /* Handle UP system running SMP kernel, with no LAPIC in MADT */ | 605 | /* Handle UP system running SMP kernel, with no LAPIC in MADT */ |
595 | if (!cpu0_initialized && (cpu_index == -1) && | 606 | if (!cpu0_initialized && (cpu_index == -1) && |
@@ -661,7 +672,7 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) | |||
661 | 672 | ||
662 | pr = acpi_driver_data(device); | 673 | pr = acpi_driver_data(device); |
663 | 674 | ||
664 | result = acpi_processor_get_info(pr, device->flags.unique_id); | 675 | result = acpi_processor_get_info(device); |
665 | if (result) { | 676 | if (result) { |
666 | /* Processor is physically not present */ | 677 | /* Processor is physically not present */ |
667 | return 0; | 678 | return 0; |
@@ -761,20 +772,20 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data) | |||
761 | acpi_bus_generate_proc_event(device, event, | 772 | acpi_bus_generate_proc_event(device, event, |
762 | pr->performance_platform_limit); | 773 | pr->performance_platform_limit); |
763 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 774 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
764 | device->dev.bus_id, event, | 775 | dev_name(&device->dev), event, |
765 | pr->performance_platform_limit); | 776 | pr->performance_platform_limit); |
766 | break; | 777 | break; |
767 | case ACPI_PROCESSOR_NOTIFY_POWER: | 778 | case ACPI_PROCESSOR_NOTIFY_POWER: |
768 | acpi_processor_cst_has_changed(pr); | 779 | acpi_processor_cst_has_changed(pr); |
769 | acpi_bus_generate_proc_event(device, event, 0); | 780 | acpi_bus_generate_proc_event(device, event, 0); |
770 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 781 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
771 | device->dev.bus_id, event, 0); | 782 | dev_name(&device->dev), event, 0); |
772 | break; | 783 | break; |
773 | case ACPI_PROCESSOR_NOTIFY_THROTTLING: | 784 | case ACPI_PROCESSOR_NOTIFY_THROTTLING: |
774 | acpi_processor_tstate_has_changed(pr); | 785 | acpi_processor_tstate_has_changed(pr); |
775 | acpi_bus_generate_proc_event(device, event, 0); | 786 | acpi_bus_generate_proc_event(device, event, 0); |
776 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 787 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
777 | device->dev.bus_id, event, 0); | 788 | dev_name(&device->dev), event, 0); |
778 | default: | 789 | default: |
779 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 790 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
780 | "Unsupported event [0x%x]\n", event)); | 791 | "Unsupported event [0x%x]\n", event)); |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 81b40ed5379e..5f8d746a9b81 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -59,7 +59,6 @@ | |||
59 | #include <acpi/processor.h> | 59 | #include <acpi/processor.h> |
60 | #include <asm/processor.h> | 60 | #include <asm/processor.h> |
61 | 61 | ||
62 | #define ACPI_PROCESSOR_COMPONENT 0x01000000 | ||
63 | #define ACPI_PROCESSOR_CLASS "processor" | 62 | #define ACPI_PROCESSOR_CLASS "processor" |
64 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 63 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
65 | ACPI_MODULE_NAME("processor_idle"); | 64 | ACPI_MODULE_NAME("processor_idle"); |
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index dbcf260ea93f..0d7b772bef50 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
@@ -44,9 +44,9 @@ | |||
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | #include <acpi/acpi_bus.h> | 46 | #include <acpi/acpi_bus.h> |
47 | #include <acpi/acpi_drivers.h> | ||
47 | #include <acpi/processor.h> | 48 | #include <acpi/processor.h> |
48 | 49 | ||
49 | #define ACPI_PROCESSOR_COMPONENT 0x01000000 | ||
50 | #define ACPI_PROCESSOR_CLASS "processor" | 50 | #define ACPI_PROCESSOR_CLASS "processor" |
51 | #define ACPI_PROCESSOR_FILE_PERFORMANCE "performance" | 51 | #define ACPI_PROCESSOR_FILE_PERFORMANCE "performance" |
52 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 52 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index ef34b18f95ca..b1eb376fae45 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <acpi/processor.h> | 40 | #include <acpi/processor.h> |
41 | #include <acpi/acpi_drivers.h> | 41 | #include <acpi/acpi_drivers.h> |
42 | 42 | ||
43 | #define ACPI_PROCESSOR_COMPONENT 0x01000000 | ||
44 | #define ACPI_PROCESSOR_CLASS "processor" | 43 | #define ACPI_PROCESSOR_CLASS "processor" |
45 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 44 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
46 | ACPI_MODULE_NAME("processor_thermal"); | 45 | ACPI_MODULE_NAME("processor_thermal"); |
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index 3da2df93d924..a0c38c94a8a0 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c | |||
@@ -38,9 +38,9 @@ | |||
38 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
39 | 39 | ||
40 | #include <acpi/acpi_bus.h> | 40 | #include <acpi/acpi_bus.h> |
41 | #include <acpi/acpi_drivers.h> | ||
41 | #include <acpi/processor.h> | 42 | #include <acpi/processor.h> |
42 | 43 | ||
43 | #define ACPI_PROCESSOR_COMPONENT 0x01000000 | ||
44 | #define ACPI_PROCESSOR_CLASS "processor" | 44 | #define ACPI_PROCESSOR_CLASS "processor" |
45 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT | 45 | #define _COMPONENT ACPI_PROCESSOR_COMPONENT |
46 | ACPI_MODULE_NAME("processor_throttling"); | 46 | ACPI_MODULE_NAME("processor_throttling"); |
diff --git a/drivers/acpi/reboot.c b/drivers/acpi/reboot.c index 755baf2ca70a..a6b662c00b67 100644 --- a/drivers/acpi/reboot.c +++ b/drivers/acpi/reboot.c | |||
@@ -15,28 +15,9 @@ void acpi_reboot(void) | |||
15 | 15 | ||
16 | rr = &acpi_gbl_FADT.reset_register; | 16 | rr = &acpi_gbl_FADT.reset_register; |
17 | 17 | ||
18 | /* | 18 | /* Is the reset register supported? */ |
19 | * Is the ACPI reset register supported? | 19 | if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) || |
20 | * | 20 | rr->bit_width != 8 || rr->bit_offset != 0) |
21 | * According to ACPI 3.0, FADT.flags.RESET_REG_SUP indicates | ||
22 | * whether the ACPI reset mechanism is supported. | ||
23 | * | ||
24 | * However, some boxes have this bit clear, yet a valid | ||
25 | * ACPI_RESET_REG & RESET_VALUE, and ACPI reboot is the only | ||
26 | * mechanism that works for them after S3. | ||
27 | * | ||
28 | * This suggests that other operating systems may not be checking | ||
29 | * the RESET_REG_SUP bit, and are using other means to decide | ||
30 | * whether to use the ACPI reboot mechanism or not. | ||
31 | * | ||
32 | * So when acpi reboot is requested, | ||
33 | * only the reset_register is checked. If the following | ||
34 | * conditions are met, it indicates that the reset register is supported. | ||
35 | * a. reset_register is not zero | ||
36 | * b. the access width is eight | ||
37 | * c. the bit_offset is zero | ||
38 | */ | ||
39 | if (!(rr->address) || rr->bit_width != 8 || rr->bit_offset != 0) | ||
40 | return; | 21 | return; |
41 | 22 | ||
42 | reset_value = acpi_gbl_FADT.reset_value; | 23 | reset_value = acpi_gbl_FADT.reset_value; |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index a9dda8e0f9f9..bd5253ee5c85 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -109,8 +109,7 @@ static int acpi_bus_hot_remove_device(void *context) | |||
109 | return 0; | 109 | return 0; |
110 | 110 | ||
111 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 111 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
112 | "Hot-removing device %s...\n", device->dev.bus_id)); | 112 | "Hot-removing device %s...\n", dev_name(&device->dev))); |
113 | |||
114 | 113 | ||
115 | if (acpi_bus_trim(device, 1)) { | 114 | if (acpi_bus_trim(device, 1)) { |
116 | printk(KERN_ERR PREFIX | 115 | printk(KERN_ERR PREFIX |
@@ -460,7 +459,7 @@ static int acpi_device_register(struct acpi_device *device, | |||
460 | acpi_device_bus_id->instance_no = 0; | 459 | acpi_device_bus_id->instance_no = 0; |
461 | list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); | 460 | list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); |
462 | } | 461 | } |
463 | sprintf(device->dev.bus_id, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no); | 462 | dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no); |
464 | 463 | ||
465 | if (device->parent) { | 464 | if (device->parent) { |
466 | list_add_tail(&device->node, &device->parent->children); | 465 | list_add_tail(&device->node, &device->parent->children); |
@@ -484,7 +483,8 @@ static int acpi_device_register(struct acpi_device *device, | |||
484 | 483 | ||
485 | result = acpi_device_setup_files(device); | 484 | result = acpi_device_setup_files(device); |
486 | if(result) | 485 | if(result) |
487 | printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n", device->dev.bus_id); | 486 | printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n", |
487 | dev_name(&device->dev)); | ||
488 | 488 | ||
489 | device->removal_type = ACPI_BUS_REMOVAL_NORMAL; | 489 | device->removal_type = ACPI_BUS_REMOVAL_NORMAL; |
490 | return 0; | 490 | return 0; |
@@ -919,36 +919,6 @@ static void acpi_device_get_busid(struct acpi_device *device, | |||
919 | } | 919 | } |
920 | } | 920 | } |
921 | 921 | ||
922 | static int | ||
923 | acpi_video_bus_match(struct acpi_device *device) | ||
924 | { | ||
925 | acpi_handle h_dummy; | ||
926 | |||
927 | if (!device) | ||
928 | return -EINVAL; | ||
929 | |||
930 | /* Since there is no HID, CID for ACPI Video drivers, we have | ||
931 | * to check well known required nodes for each feature we support. | ||
932 | */ | ||
933 | |||
934 | /* Does this device able to support video switching ? */ | ||
935 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) && | ||
936 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy))) | ||
937 | return 0; | ||
938 | |||
939 | /* Does this device able to retrieve a video ROM ? */ | ||
940 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy))) | ||
941 | return 0; | ||
942 | |||
943 | /* Does this device able to configure which video head to be POSTed ? */ | ||
944 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy)) && | ||
945 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy)) && | ||
946 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy))) | ||
947 | return 0; | ||
948 | |||
949 | return -ENODEV; | ||
950 | } | ||
951 | |||
952 | /* | 922 | /* |
953 | * acpi_bay_match - see if a device is an ejectable driver bay | 923 | * acpi_bay_match - see if a device is an ejectable driver bay |
954 | * | 924 | * |
@@ -1031,7 +1001,7 @@ static void acpi_device_set_id(struct acpi_device *device, | |||
1031 | will get autoloaded and the device might still match | 1001 | will get autoloaded and the device might still match |
1032 | against another driver. | 1002 | against another driver. |
1033 | */ | 1003 | */ |
1034 | if (ACPI_SUCCESS(acpi_video_bus_match(device))) | 1004 | if (acpi_is_video_device(device)) |
1035 | cid_add = ACPI_VIDEO_HID; | 1005 | cid_add = ACPI_VIDEO_HID; |
1036 | else if (ACPI_SUCCESS(acpi_bay_match(device))) | 1006 | else if (ACPI_SUCCESS(acpi_bay_match(device))) |
1037 | cid_add = ACPI_BAY_HID; | 1007 | cid_add = ACPI_BAY_HID; |
@@ -1043,7 +1013,7 @@ static void acpi_device_set_id(struct acpi_device *device, | |||
1043 | hid = ACPI_POWER_HID; | 1013 | hid = ACPI_POWER_HID; |
1044 | break; | 1014 | break; |
1045 | case ACPI_BUS_TYPE_PROCESSOR: | 1015 | case ACPI_BUS_TYPE_PROCESSOR: |
1046 | hid = ACPI_PROCESSOR_HID; | 1016 | hid = ACPI_PROCESSOR_OBJECT_HID; |
1047 | break; | 1017 | break; |
1048 | case ACPI_BUS_TYPE_SYSTEM: | 1018 | case ACPI_BUS_TYPE_SYSTEM: |
1049 | hid = ACPI_SYSTEM_HID; | 1019 | hid = ACPI_SYSTEM_HID; |
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c index 631ee2ee2ca0..64e591ba86f2 100644 --- a/drivers/acpi/sleep/proc.c +++ b/drivers/acpi/sleep/proc.c | |||
@@ -366,8 +366,8 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) | |||
366 | dev->wakeup.state.enabled ? "enabled" : "disabled"); | 366 | dev->wakeup.state.enabled ? "enabled" : "disabled"); |
367 | if (ldev) | 367 | if (ldev) |
368 | seq_printf(seq, "%s:%s", | 368 | seq_printf(seq, "%s:%s", |
369 | ldev->bus ? ldev->bus->name : "no-bus", | 369 | dev_name(ldev) ? ldev->bus->name : "no-bus", |
370 | ldev->bus_id); | 370 | dev_name(ldev)); |
371 | seq_printf(seq, "\n"); | 371 | seq_printf(seq, "\n"); |
372 | put_device(ldev); | 372 | put_device(ldev); |
373 | 373 | ||
diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c index 38655eb132dc..dea4c23df764 100644 --- a/drivers/acpi/sleep/wakeup.c +++ b/drivers/acpi/sleep/wakeup.c | |||
@@ -88,7 +88,7 @@ void acpi_enable_wakeup_device(u8 sleep_state) | |||
88 | spin_unlock(&acpi_device_lock); | 88 | spin_unlock(&acpi_device_lock); |
89 | if (!dev->wakeup.flags.run_wake) | 89 | if (!dev->wakeup.flags.run_wake) |
90 | acpi_enable_gpe(dev->wakeup.gpe_device, | 90 | acpi_enable_gpe(dev->wakeup.gpe_device, |
91 | dev->wakeup.gpe_number, ACPI_ISR); | 91 | dev->wakeup.gpe_number); |
92 | spin_lock(&acpi_device_lock); | 92 | spin_lock(&acpi_device_lock); |
93 | } | 93 | } |
94 | spin_unlock(&acpi_device_lock); | 94 | spin_unlock(&acpi_device_lock); |
@@ -122,7 +122,7 @@ void acpi_disable_wakeup_device(u8 sleep_state) | |||
122 | ACPI_GPE_TYPE_WAKE_RUN); | 122 | ACPI_GPE_TYPE_WAKE_RUN); |
123 | /* Re-enable it, since set_gpe_type will disable it */ | 123 | /* Re-enable it, since set_gpe_type will disable it */ |
124 | acpi_enable_gpe(dev->wakeup.gpe_device, | 124 | acpi_enable_gpe(dev->wakeup.gpe_device, |
125 | dev->wakeup.gpe_number, ACPI_NOT_ISR); | 125 | dev->wakeup.gpe_number); |
126 | spin_lock(&acpi_device_lock); | 126 | spin_lock(&acpi_device_lock); |
127 | } | 127 | } |
128 | continue; | 128 | continue; |
@@ -133,7 +133,7 @@ void acpi_disable_wakeup_device(u8 sleep_state) | |||
133 | /* Never disable run-wake GPE */ | 133 | /* Never disable run-wake GPE */ |
134 | if (!dev->wakeup.flags.run_wake) { | 134 | if (!dev->wakeup.flags.run_wake) { |
135 | acpi_disable_gpe(dev->wakeup.gpe_device, | 135 | acpi_disable_gpe(dev->wakeup.gpe_device, |
136 | dev->wakeup.gpe_number, ACPI_NOT_ISR); | 136 | dev->wakeup.gpe_number); |
137 | acpi_clear_gpe(dev->wakeup.gpe_device, | 137 | acpi_clear_gpe(dev->wakeup.gpe_device, |
138 | dev->wakeup.gpe_number, ACPI_NOT_ISR); | 138 | dev->wakeup.gpe_number, ACPI_NOT_ISR); |
139 | } | 139 | } |
@@ -162,7 +162,7 @@ static int __init acpi_wakeup_device_init(void) | |||
162 | dev->wakeup.gpe_number, | 162 | dev->wakeup.gpe_number, |
163 | ACPI_GPE_TYPE_WAKE_RUN); | 163 | ACPI_GPE_TYPE_WAKE_RUN); |
164 | acpi_enable_gpe(dev->wakeup.gpe_device, | 164 | acpi_enable_gpe(dev->wakeup.gpe_device, |
165 | dev->wakeup.gpe_number, ACPI_NOT_ISR); | 165 | dev->wakeup.gpe_number); |
166 | dev->wakeup.state.enabled = 1; | 166 | dev->wakeup.state.enabled = 1; |
167 | spin_lock(&acpi_device_lock); | 167 | spin_lock(&acpi_device_lock); |
168 | } | 168 | } |
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 1d74171b7940..6e4107f82403 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c | |||
@@ -78,9 +78,15 @@ static ssize_t acpi_table_show(struct kobject *kobj, | |||
78 | container_of(bin_attr, struct acpi_table_attr, attr); | 78 | container_of(bin_attr, struct acpi_table_attr, attr); |
79 | struct acpi_table_header *table_header = NULL; | 79 | struct acpi_table_header *table_header = NULL; |
80 | acpi_status status; | 80 | acpi_status status; |
81 | char name[ACPI_NAME_SIZE]; | ||
82 | |||
83 | if (strncmp(table_attr->name, "NULL", 4)) | ||
84 | memcpy(name, table_attr->name, ACPI_NAME_SIZE); | ||
85 | else | ||
86 | memcpy(name, "\0\0\0\0", 4); | ||
81 | 87 | ||
82 | status = | 88 | status = |
83 | acpi_get_table(table_attr->name, table_attr->instance, | 89 | acpi_get_table(name, table_attr->instance, |
84 | &table_header); | 90 | &table_header); |
85 | if (ACPI_FAILURE(status)) | 91 | if (ACPI_FAILURE(status)) |
86 | return -ENODEV; | 92 | return -ENODEV; |
@@ -95,21 +101,24 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr, | |||
95 | struct acpi_table_header *header = NULL; | 101 | struct acpi_table_header *header = NULL; |
96 | struct acpi_table_attr *attr = NULL; | 102 | struct acpi_table_attr *attr = NULL; |
97 | 103 | ||
98 | memcpy(table_attr->name, table_header->signature, ACPI_NAME_SIZE); | 104 | if (table_header->signature[0] != '\0') |
105 | memcpy(table_attr->name, table_header->signature, | ||
106 | ACPI_NAME_SIZE); | ||
107 | else | ||
108 | memcpy(table_attr->name, "NULL", 4); | ||
99 | 109 | ||
100 | list_for_each_entry(attr, &acpi_table_attr_list, node) { | 110 | list_for_each_entry(attr, &acpi_table_attr_list, node) { |
101 | if (!memcmp(table_header->signature, attr->name, | 111 | if (!memcmp(table_attr->name, attr->name, ACPI_NAME_SIZE)) |
102 | ACPI_NAME_SIZE)) | ||
103 | if (table_attr->instance < attr->instance) | 112 | if (table_attr->instance < attr->instance) |
104 | table_attr->instance = attr->instance; | 113 | table_attr->instance = attr->instance; |
105 | } | 114 | } |
106 | table_attr->instance++; | 115 | table_attr->instance++; |
107 | 116 | ||
108 | if (table_attr->instance > 1 || (table_attr->instance == 1 && | 117 | if (table_attr->instance > 1 || (table_attr->instance == 1 && |
109 | !acpi_get_table(table_header-> | 118 | !acpi_get_table |
110 | signature, 2, | 119 | (table_header->signature, 2, &header))) |
111 | &header))) | 120 | sprintf(table_attr->name + ACPI_NAME_SIZE, "%d", |
112 | sprintf(table_attr->name + 4, "%d", table_attr->instance); | 121 | table_attr->instance); |
113 | 122 | ||
114 | table_attr->attr.size = 0; | 123 | table_attr->attr.size = 0; |
115 | table_attr->attr.read = acpi_table_show; | 124 | table_attr->attr.read = acpi_table_show; |
@@ -167,7 +176,6 @@ static int acpi_system_sysfs_init(void) | |||
167 | #define COUNT_ERROR 2 /* other */ | 176 | #define COUNT_ERROR 2 /* other */ |
168 | #define NUM_COUNTERS_EXTRA 3 | 177 | #define NUM_COUNTERS_EXTRA 3 |
169 | 178 | ||
170 | #define ACPI_EVENT_VALID 0x01 | ||
171 | struct event_counter { | 179 | struct event_counter { |
172 | u32 count; | 180 | u32 count; |
173 | u32 flags; | 181 | u32 flags; |
@@ -312,12 +320,6 @@ static int get_status(u32 index, acpi_event_status *status, acpi_handle *handle) | |||
312 | } else if (index < (num_gpes + ACPI_NUM_FIXED_EVENTS)) | 320 | } else if (index < (num_gpes + ACPI_NUM_FIXED_EVENTS)) |
313 | result = acpi_get_event_status(index - num_gpes, status); | 321 | result = acpi_get_event_status(index - num_gpes, status); |
314 | 322 | ||
315 | /* | ||
316 | * sleep/power button GPE/Fixed Event is enabled after acpi_system_init, | ||
317 | * check the status at runtime and mark it as valid once it's enabled | ||
318 | */ | ||
319 | if (!result && (*status & ACPI_EVENT_FLAG_ENABLED)) | ||
320 | all_counters[index].flags |= ACPI_EVENT_VALID; | ||
321 | end: | 323 | end: |
322 | return result; | 324 | return result; |
323 | } | 325 | } |
@@ -346,12 +348,14 @@ static ssize_t counter_show(struct kobject *kobj, | |||
346 | if (result) | 348 | if (result) |
347 | goto end; | 349 | goto end; |
348 | 350 | ||
349 | if (!(all_counters[index].flags & ACPI_EVENT_VALID)) | 351 | if (!(status & ACPI_EVENT_FLAG_HANDLE)) |
350 | size += sprintf(buf + size, " invalid"); | 352 | size += sprintf(buf + size, " invalid"); |
351 | else if (status & ACPI_EVENT_FLAG_ENABLED) | 353 | else if (status & ACPI_EVENT_FLAG_ENABLED) |
352 | size += sprintf(buf + size, " enable"); | 354 | size += sprintf(buf + size, " enabled"); |
355 | else if (status & ACPI_EVENT_FLAG_WAKE_ENABLED) | ||
356 | size += sprintf(buf + size, " wake_enabled"); | ||
353 | else | 357 | else |
354 | size += sprintf(buf + size, " disable"); | 358 | size += sprintf(buf + size, " disabled"); |
355 | 359 | ||
356 | end: | 360 | end: |
357 | size += sprintf(buf + size, "\n"); | 361 | size += sprintf(buf + size, "\n"); |
@@ -385,7 +389,7 @@ static ssize_t counter_set(struct kobject *kobj, | |||
385 | if (result) | 389 | if (result) |
386 | goto end; | 390 | goto end; |
387 | 391 | ||
388 | if (!(all_counters[index].flags & ACPI_EVENT_VALID)) { | 392 | if (!(status & ACPI_EVENT_FLAG_HANDLE)) { |
389 | printk(KERN_WARNING PREFIX | 393 | printk(KERN_WARNING PREFIX |
390 | "Can not change Invalid GPE/Fixed Event status\n"); | 394 | "Can not change Invalid GPE/Fixed Event status\n"); |
391 | return -EINVAL; | 395 | return -EINVAL; |
@@ -394,10 +398,10 @@ static ssize_t counter_set(struct kobject *kobj, | |||
394 | if (index < num_gpes) { | 398 | if (index < num_gpes) { |
395 | if (!strcmp(buf, "disable\n") && | 399 | if (!strcmp(buf, "disable\n") && |
396 | (status & ACPI_EVENT_FLAG_ENABLED)) | 400 | (status & ACPI_EVENT_FLAG_ENABLED)) |
397 | result = acpi_disable_gpe(handle, index, ACPI_NOT_ISR); | 401 | result = acpi_disable_gpe(handle, index); |
398 | else if (!strcmp(buf, "enable\n") && | 402 | else if (!strcmp(buf, "enable\n") && |
399 | !(status & ACPI_EVENT_FLAG_ENABLED)) | 403 | !(status & ACPI_EVENT_FLAG_ENABLED)) |
400 | result = acpi_enable_gpe(handle, index, ACPI_NOT_ISR); | 404 | result = acpi_enable_gpe(handle, index); |
401 | else if (!strcmp(buf, "clear\n") && | 405 | else if (!strcmp(buf, "clear\n") && |
402 | (status & ACPI_EVENT_FLAG_SET)) | 406 | (status & ACPI_EVENT_FLAG_SET)) |
403 | result = acpi_clear_gpe(handle, index, ACPI_NOT_ISR); | 407 | result = acpi_clear_gpe(handle, index, ACPI_NOT_ISR); |
diff --git a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c index 2c7885e7ffba..2817158fb6a1 100644 --- a/drivers/acpi/tables/tbfadt.c +++ b/drivers/acpi/tables/tbfadt.c | |||
@@ -304,7 +304,7 @@ static void acpi_tb_convert_fadt(void) | |||
304 | * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at | 304 | * The ACPI 1.0 reserved fields that will be zeroed are the bytes located at |
305 | * offset 45, 55, 95, and the word located at offset 109, 110. | 305 | * offset 45, 55, 95, and the word located at offset 109, 110. |
306 | */ | 306 | */ |
307 | if (acpi_gbl_FADT.header.revision < 3) { | 307 | if (acpi_gbl_FADT.header.revision < FADT2_REVISION_ID) { |
308 | acpi_gbl_FADT.preferred_profile = 0; | 308 | acpi_gbl_FADT.preferred_profile = 0; |
309 | acpi_gbl_FADT.pstate_control = 0; | 309 | acpi_gbl_FADT.pstate_control = 0; |
310 | acpi_gbl_FADT.cst_control = 0; | 310 | acpi_gbl_FADT.cst_control = 0; |
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index ad6cae938f0b..073ff09218a9 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <acpi/acpi_bus.h> | 47 | #include <acpi/acpi_bus.h> |
48 | #include <acpi/acpi_drivers.h> | 48 | #include <acpi/acpi_drivers.h> |
49 | 49 | ||
50 | #define ACPI_THERMAL_COMPONENT 0x04000000 | ||
51 | #define ACPI_THERMAL_CLASS "thermal_zone" | 50 | #define ACPI_THERMAL_CLASS "thermal_zone" |
52 | #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" | 51 | #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" |
53 | #define ACPI_THERMAL_FILE_STATE "state" | 52 | #define ACPI_THERMAL_FILE_STATE "state" |
@@ -576,7 +575,7 @@ static int acpi_thermal_critical(struct acpi_thermal *tz) | |||
576 | acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL, | 575 | acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL, |
577 | tz->trips.critical.flags.enabled); | 576 | tz->trips.critical.flags.enabled); |
578 | acpi_bus_generate_netlink_event(tz->device->pnp.device_class, | 577 | acpi_bus_generate_netlink_event(tz->device->pnp.device_class, |
579 | tz->device->dev.bus_id, | 578 | dev_name(&tz->device->dev), |
580 | ACPI_THERMAL_NOTIFY_CRITICAL, | 579 | ACPI_THERMAL_NOTIFY_CRITICAL, |
581 | tz->trips.critical.flags.enabled); | 580 | tz->trips.critical.flags.enabled); |
582 | 581 | ||
@@ -605,7 +604,7 @@ static int acpi_thermal_hot(struct acpi_thermal *tz) | |||
605 | acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT, | 604 | acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT, |
606 | tz->trips.hot.flags.enabled); | 605 | tz->trips.hot.flags.enabled); |
607 | acpi_bus_generate_netlink_event(tz->device->pnp.device_class, | 606 | acpi_bus_generate_netlink_event(tz->device->pnp.device_class, |
608 | tz->device->dev.bus_id, | 607 | dev_name(&tz->device->dev), |
609 | ACPI_THERMAL_NOTIFY_HOT, | 608 | ACPI_THERMAL_NOTIFY_HOT, |
610 | tz->trips.hot.flags.enabled); | 609 | tz->trips.hot.flags.enabled); |
611 | 610 | ||
@@ -1592,14 +1591,14 @@ static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) | |||
1592 | acpi_thermal_check(tz); | 1591 | acpi_thermal_check(tz); |
1593 | acpi_bus_generate_proc_event(device, event, 0); | 1592 | acpi_bus_generate_proc_event(device, event, 0); |
1594 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 1593 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
1595 | device->dev.bus_id, event, 0); | 1594 | dev_name(&device->dev), event, 0); |
1596 | break; | 1595 | break; |
1597 | case ACPI_THERMAL_NOTIFY_DEVICES: | 1596 | case ACPI_THERMAL_NOTIFY_DEVICES: |
1598 | acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES); | 1597 | acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES); |
1599 | acpi_thermal_check(tz); | 1598 | acpi_thermal_check(tz); |
1600 | acpi_bus_generate_proc_event(device, event, 0); | 1599 | acpi_bus_generate_proc_event(device, event, 0); |
1601 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 1600 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
1602 | device->dev.bus_id, event, 0); | 1601 | dev_name(&device->dev), event, 0); |
1603 | break; | 1602 | break; |
1604 | default: | 1603 | default: |
1605 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 1604 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index a29b0ccac65a..baa441929720 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include <acpi/acpi_bus.h> | 41 | #include <acpi/acpi_bus.h> |
42 | #include <acpi/acpi_drivers.h> | 42 | #include <acpi/acpi_drivers.h> |
43 | 43 | ||
44 | #define ACPI_VIDEO_COMPONENT 0x08000000 | ||
45 | #define ACPI_VIDEO_CLASS "video" | 44 | #define ACPI_VIDEO_CLASS "video" |
46 | #define ACPI_VIDEO_BUS_NAME "Video Bus" | 45 | #define ACPI_VIDEO_BUS_NAME "Video Bus" |
47 | #define ACPI_VIDEO_DEVICE_NAME "Video Device" | 46 | #define ACPI_VIDEO_DEVICE_NAME "Video Device" |
@@ -739,7 +738,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
739 | device->cap._DSS = 1; | 738 | device->cap._DSS = 1; |
740 | } | 739 | } |
741 | 740 | ||
742 | max_level = acpi_video_init_brightness(device); | 741 | if (acpi_video_backlight_support()) |
742 | max_level = acpi_video_init_brightness(device); | ||
743 | 743 | ||
744 | if (device->cap._BCL && device->cap._BCM && max_level > 0) { | 744 | if (device->cap._BCL && device->cap._BCM && max_level > 0) { |
745 | int result; | 745 | int result; |
@@ -785,18 +785,21 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
785 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | 785 | printk(KERN_ERR PREFIX "Create sysfs link\n"); |
786 | 786 | ||
787 | } | 787 | } |
788 | if (device->cap._DCS && device->cap._DSS){ | 788 | |
789 | static int count = 0; | 789 | if (acpi_video_display_switch_support()) { |
790 | char *name; | 790 | |
791 | name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); | 791 | if (device->cap._DCS && device->cap._DSS) { |
792 | if (!name) | 792 | static int count; |
793 | return; | 793 | char *name; |
794 | sprintf(name, "acpi_video%d", count++); | 794 | name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); |
795 | device->output_dev = video_output_register(name, | 795 | if (!name) |
796 | NULL, device, &acpi_output_properties); | 796 | return; |
797 | kfree(name); | 797 | sprintf(name, "acpi_video%d", count++); |
798 | device->output_dev = video_output_register(name, | ||
799 | NULL, device, &acpi_output_properties); | ||
800 | kfree(name); | ||
801 | } | ||
798 | } | 802 | } |
799 | return; | ||
800 | } | 803 | } |
801 | 804 | ||
802 | /* | 805 | /* |
@@ -842,11 +845,16 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video) | |||
842 | static int acpi_video_bus_check(struct acpi_video_bus *video) | 845 | static int acpi_video_bus_check(struct acpi_video_bus *video) |
843 | { | 846 | { |
844 | acpi_status status = -ENOENT; | 847 | acpi_status status = -ENOENT; |
845 | 848 | struct device *dev; | |
846 | 849 | ||
847 | if (!video) | 850 | if (!video) |
848 | return -EINVAL; | 851 | return -EINVAL; |
849 | 852 | ||
853 | dev = acpi_get_physical_pci_device(video->device->handle); | ||
854 | if (!dev) | ||
855 | return -ENODEV; | ||
856 | put_device(dev); | ||
857 | |||
850 | /* Since there is no HID, CID and so on for VGA driver, we have | 858 | /* Since there is no HID, CID and so on for VGA driver, we have |
851 | * to check well known required nodes. | 859 | * to check well known required nodes. |
852 | */ | 860 | */ |
@@ -2094,12 +2102,6 @@ static int __init acpi_video_init(void) | |||
2094 | { | 2102 | { |
2095 | int result = 0; | 2103 | int result = 0; |
2096 | 2104 | ||
2097 | |||
2098 | /* | ||
2099 | acpi_dbg_level = 0xFFFFFFFF; | ||
2100 | acpi_dbg_layer = 0x08000000; | ||
2101 | */ | ||
2102 | |||
2103 | acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); | 2105 | acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir); |
2104 | if (!acpi_video_dir) | 2106 | if (!acpi_video_dir) |
2105 | return -ENODEV; | 2107 | return -ENODEV; |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c new file mode 100644 index 000000000000..f022eb6f5637 --- /dev/null +++ b/drivers/acpi/video_detect.c | |||
@@ -0,0 +1,267 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 SuSE Linux Products GmbH | ||
3 | * Thomas Renninger <trenn@suse.de> | ||
4 | * | ||
5 | * May be copied or modified under the terms of the GNU General Public License | ||
6 | * | ||
7 | * video_detect.c: | ||
8 | * Provides acpi_is_video_device() for early scanning of ACPI devices in scan.c | ||
9 | * There a Linux specific (Spec does not provide a HID for video devices) is | ||
10 | * assinged | ||
11 | * | ||
12 | * After PCI devices are glued with ACPI devices | ||
13 | * acpi_get_physical_pci_device() can be called to identify ACPI graphics | ||
14 | * devices for which a real graphics card is plugged in | ||
15 | * | ||
16 | * Now acpi_video_get_capabilities() can be called to check which | ||
17 | * capabilities the graphics cards plugged in support. The check for general | ||
18 | * video capabilities will be triggered by the first caller of | ||
19 | * acpi_video_get_capabilities(NULL); which will happen when the first | ||
20 | * backlight (or display output) switching supporting driver calls: | ||
21 | * acpi_video_backlight_support(); | ||
22 | * | ||
23 | * Depending on whether ACPI graphics extensions (cmp. ACPI spec Appendix B) | ||
24 | * are available, video.ko should be used to handle the device. | ||
25 | * | ||
26 | * Otherwise vendor specific drivers like thinkpad_acpi, asus_acpi, | ||
27 | * sony_acpi,... can take care about backlight brightness and display output | ||
28 | * switching. | ||
29 | * | ||
30 | * If CONFIG_ACPI_VIDEO is neither set as "compiled in" (y) nor as a module (m) | ||
31 | * this file will not be compiled, acpi_video_get_capabilities() and | ||
32 | * acpi_video_backlight_support() will always return 0 and vendor specific | ||
33 | * drivers always can handle backlight. | ||
34 | * | ||
35 | */ | ||
36 | |||
37 | #include <linux/acpi.h> | ||
38 | #include <linux/dmi.h> | ||
39 | |||
40 | ACPI_MODULE_NAME("video"); | ||
41 | #define _COMPONENT ACPI_VIDEO_COMPONENT | ||
42 | |||
43 | static long acpi_video_support; | ||
44 | static bool acpi_video_caps_checked; | ||
45 | |||
46 | static acpi_status | ||
47 | acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context, | ||
48 | void **retyurn_value) | ||
49 | { | ||
50 | long *cap = context; | ||
51 | acpi_handle h_dummy; | ||
52 | |||
53 | if (ACPI_SUCCESS(acpi_get_handle(handle, "_BCM", &h_dummy)) && | ||
54 | ACPI_SUCCESS(acpi_get_handle(handle, "_BCL", &h_dummy))) { | ||
55 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight " | ||
56 | "support\n")); | ||
57 | *cap |= ACPI_VIDEO_BACKLIGHT; | ||
58 | /* We have backlight support, no need to scan further */ | ||
59 | return AE_CTRL_TERMINATE; | ||
60 | } | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | /* Returns true if the device is a video device which can be handled by | ||
65 | * video.ko. | ||
66 | * The device will get a Linux specific CID added in scan.c to | ||
67 | * identify the device as an ACPI graphics device | ||
68 | * Be aware that the graphics device may not be physically present | ||
69 | * Use acpi_video_get_capabilities() to detect general ACPI video | ||
70 | * capabilities of present cards | ||
71 | */ | ||
72 | long acpi_is_video_device(struct acpi_device *device) | ||
73 | { | ||
74 | acpi_handle h_dummy; | ||
75 | long video_caps = 0; | ||
76 | |||
77 | if (!device) | ||
78 | return 0; | ||
79 | |||
80 | /* Does this device able to support video switching ? */ | ||
81 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) && | ||
82 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy))) | ||
83 | video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING; | ||
84 | |||
85 | /* Does this device able to retrieve a video ROM ? */ | ||
86 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy))) | ||
87 | video_caps |= ACPI_VIDEO_ROM_AVAILABLE; | ||
88 | |||
89 | /* Does this device able to configure which video head to be POSTed ? */ | ||
90 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy)) && | ||
91 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy)) && | ||
92 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy))) | ||
93 | video_caps |= ACPI_VIDEO_DEVICE_POSTING; | ||
94 | |||
95 | /* Only check for backlight functionality if one of the above hit. */ | ||
96 | if (video_caps) | ||
97 | acpi_walk_namespace(ACPI_TYPE_DEVICE, device->handle, | ||
98 | ACPI_UINT32_MAX, acpi_backlight_cap_match, | ||
99 | &video_caps, NULL); | ||
100 | |||
101 | return video_caps; | ||
102 | } | ||
103 | EXPORT_SYMBOL(acpi_is_video_device); | ||
104 | |||
105 | static acpi_status | ||
106 | find_video(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
107 | { | ||
108 | long *cap = context; | ||
109 | struct device *dev; | ||
110 | struct acpi_device *acpi_dev; | ||
111 | |||
112 | const struct acpi_device_id video_ids[] = { | ||
113 | {ACPI_VIDEO_HID, 0}, | ||
114 | {"", 0}, | ||
115 | }; | ||
116 | if (acpi_bus_get_device(handle, &acpi_dev)) | ||
117 | return AE_OK; | ||
118 | |||
119 | if (!acpi_match_device_ids(acpi_dev, video_ids)) { | ||
120 | dev = acpi_get_physical_pci_device(handle); | ||
121 | if (!dev) | ||
122 | return AE_OK; | ||
123 | put_device(dev); | ||
124 | *cap |= acpi_is_video_device(acpi_dev); | ||
125 | } | ||
126 | return AE_OK; | ||
127 | } | ||
128 | |||
129 | /* | ||
130 | * Returns the video capabilities of a specific ACPI graphics device | ||
131 | * | ||
132 | * if NULL is passed as argument all ACPI devices are enumerated and | ||
133 | * all graphics capabilities of physically present devices are | ||
134 | * summerized and returned. This is cached and done only once. | ||
135 | */ | ||
136 | long acpi_video_get_capabilities(acpi_handle graphics_handle) | ||
137 | { | ||
138 | long caps = 0; | ||
139 | struct acpi_device *tmp_dev; | ||
140 | acpi_status status; | ||
141 | |||
142 | if (acpi_video_caps_checked && graphics_handle == NULL) | ||
143 | return acpi_video_support; | ||
144 | |||
145 | if (!graphics_handle) { | ||
146 | /* Only do the global walk through all graphics devices once */ | ||
147 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
148 | ACPI_UINT32_MAX, find_video, | ||
149 | &caps, NULL); | ||
150 | /* There might be boot param flags set already... */ | ||
151 | acpi_video_support |= caps; | ||
152 | acpi_video_caps_checked = 1; | ||
153 | /* Add blacklists here. Be careful to use the right *DMI* bits | ||
154 | * to still be able to override logic via boot params, e.g.: | ||
155 | * | ||
156 | * if (dmi_name_in_vendors("XY")) { | ||
157 | * acpi_video_support |= | ||
158 | * ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR; | ||
159 | * acpi_video_support |= | ||
160 | * ACPI_VIDEO_BACKLIGHT_DMI_VENDOR; | ||
161 | *} | ||
162 | */ | ||
163 | } else { | ||
164 | status = acpi_bus_get_device(graphics_handle, &tmp_dev); | ||
165 | if (ACPI_FAILURE(status)) { | ||
166 | ACPI_EXCEPTION((AE_INFO, status, "Invalid device")); | ||
167 | return 0; | ||
168 | } | ||
169 | acpi_walk_namespace(ACPI_TYPE_DEVICE, graphics_handle, | ||
170 | ACPI_UINT32_MAX, find_video, | ||
171 | &caps, NULL); | ||
172 | } | ||
173 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "We have 0x%lX video support %s %s\n", | ||
174 | graphics_handle ? caps : acpi_video_support, | ||
175 | graphics_handle ? "on device " : "in general", | ||
176 | graphics_handle ? acpi_device_bid(tmp_dev) : "")); | ||
177 | return caps; | ||
178 | } | ||
179 | EXPORT_SYMBOL(acpi_video_get_capabilities); | ||
180 | |||
181 | /* Returns true if video.ko can do backlight switching */ | ||
182 | int acpi_video_backlight_support(void) | ||
183 | { | ||
184 | /* | ||
185 | * We must check whether the ACPI graphics device is physically plugged | ||
186 | * in. Therefore this must be called after binding PCI and ACPI devices | ||
187 | */ | ||
188 | if (!acpi_video_caps_checked) | ||
189 | acpi_video_get_capabilities(NULL); | ||
190 | |||
191 | /* First check for boot param -> highest prio */ | ||
192 | if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR) | ||
193 | return 0; | ||
194 | else if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO) | ||
195 | return 1; | ||
196 | |||
197 | /* Then check for DMI blacklist -> second highest prio */ | ||
198 | if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_DMI_VENDOR) | ||
199 | return 0; | ||
200 | else if (acpi_video_support & ACPI_VIDEO_BACKLIGHT_DMI_VIDEO) | ||
201 | return 1; | ||
202 | |||
203 | /* Then go the default way */ | ||
204 | return acpi_video_support & ACPI_VIDEO_BACKLIGHT; | ||
205 | } | ||
206 | EXPORT_SYMBOL(acpi_video_backlight_support); | ||
207 | |||
208 | /* | ||
209 | * Returns true if video.ko can do display output switching. | ||
210 | * This does not work well/at all with binary graphics drivers | ||
211 | * which disable system io ranges and do it on their own. | ||
212 | */ | ||
213 | int acpi_video_display_switch_support(void) | ||
214 | { | ||
215 | if (!acpi_video_caps_checked) | ||
216 | acpi_video_get_capabilities(NULL); | ||
217 | |||
218 | if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR) | ||
219 | return 0; | ||
220 | else if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO) | ||
221 | return 1; | ||
222 | |||
223 | if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR) | ||
224 | return 0; | ||
225 | else if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VIDEO) | ||
226 | return 1; | ||
227 | |||
228 | return acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING; | ||
229 | } | ||
230 | EXPORT_SYMBOL(acpi_video_display_switch_support); | ||
231 | |||
232 | /* | ||
233 | * Use acpi_display_output=vendor/video or acpi_backlight=vendor/video | ||
234 | * To force that backlight or display output switching is processed by vendor | ||
235 | * specific acpi drivers or video.ko driver. | ||
236 | */ | ||
237 | int __init acpi_backlight(char *str) | ||
238 | { | ||
239 | if (str == NULL || *str == '\0') | ||
240 | return 1; | ||
241 | else { | ||
242 | if (!strcmp("vendor", str)) | ||
243 | acpi_video_support |= | ||
244 | ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR; | ||
245 | if (!strcmp("video", str)) | ||
246 | acpi_video_support |= | ||
247 | ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO; | ||
248 | } | ||
249 | return 1; | ||
250 | } | ||
251 | __setup("acpi_backlight=", acpi_backlight); | ||
252 | |||
253 | int __init acpi_display_output(char *str) | ||
254 | { | ||
255 | if (str == NULL || *str == '\0') | ||
256 | return 1; | ||
257 | else { | ||
258 | if (!strcmp("vendor", str)) | ||
259 | acpi_video_support |= | ||
260 | ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR; | ||
261 | if (!strcmp("video", str)) | ||
262 | acpi_video_support |= | ||
263 | ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO; | ||
264 | } | ||
265 | return 1; | ||
266 | } | ||
267 | __setup("acpi_display_output=", acpi_display_output); | ||
diff --git a/drivers/acpi/wmi.c b/drivers/acpi/wmi.c index 47cd7baf9b1b..8a8b377712c9 100644 --- a/drivers/acpi/wmi.c +++ b/drivers/acpi/wmi.c | |||
@@ -660,7 +660,7 @@ static void acpi_wmi_notify(acpi_handle handle, u32 event, void *data) | |||
660 | wblock->handler(event, wblock->handler_data); | 660 | wblock->handler(event, wblock->handler_data); |
661 | 661 | ||
662 | acpi_bus_generate_netlink_event( | 662 | acpi_bus_generate_netlink_event( |
663 | device->pnp.device_class, device->dev.bus_id, | 663 | device->pnp.device_class, dev_name(&device->dev), |
664 | event, 0); | 664 | event, 0); |
665 | break; | 665 | break; |
666 | } | 666 | } |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 622350d9b2e3..4214bfb13bbd 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -612,7 +612,7 @@ u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev) | |||
612 | if (tf->flags & ATA_TFLAG_LBA48) { | 612 | if (tf->flags & ATA_TFLAG_LBA48) { |
613 | block |= (u64)tf->hob_lbah << 40; | 613 | block |= (u64)tf->hob_lbah << 40; |
614 | block |= (u64)tf->hob_lbam << 32; | 614 | block |= (u64)tf->hob_lbam << 32; |
615 | block |= tf->hob_lbal << 24; | 615 | block |= (u64)tf->hob_lbal << 24; |
616 | } else | 616 | } else |
617 | block |= (tf->device & 0xf) << 24; | 617 | block |= (tf->device & 0xf) << 24; |
618 | 618 | ||
@@ -1712,6 +1712,8 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, | |||
1712 | else | 1712 | else |
1713 | tag = 0; | 1713 | tag = 0; |
1714 | 1714 | ||
1715 | if (test_and_set_bit(tag, &ap->qc_allocated)) | ||
1716 | BUG(); | ||
1715 | qc = __ata_qc_from_tag(ap, tag); | 1717 | qc = __ata_qc_from_tag(ap, tag); |
1716 | 1718 | ||
1717 | qc->tag = tag; | 1719 | qc->tag = tag; |
@@ -4563,6 +4565,37 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) | |||
4563 | } | 4565 | } |
4564 | 4566 | ||
4565 | /** | 4567 | /** |
4568 | * ata_qc_new - Request an available ATA command, for queueing | ||
4569 | * @ap: Port associated with device @dev | ||
4570 | * @dev: Device from whom we request an available command structure | ||
4571 | * | ||
4572 | * LOCKING: | ||
4573 | * None. | ||
4574 | */ | ||
4575 | |||
4576 | static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) | ||
4577 | { | ||
4578 | struct ata_queued_cmd *qc = NULL; | ||
4579 | unsigned int i; | ||
4580 | |||
4581 | /* no command while frozen */ | ||
4582 | if (unlikely(ap->pflags & ATA_PFLAG_FROZEN)) | ||
4583 | return NULL; | ||
4584 | |||
4585 | /* the last tag is reserved for internal command. */ | ||
4586 | for (i = 0; i < ATA_MAX_QUEUE - 1; i++) | ||
4587 | if (!test_and_set_bit(i, &ap->qc_allocated)) { | ||
4588 | qc = __ata_qc_from_tag(ap, i); | ||
4589 | break; | ||
4590 | } | ||
4591 | |||
4592 | if (qc) | ||
4593 | qc->tag = i; | ||
4594 | |||
4595 | return qc; | ||
4596 | } | ||
4597 | |||
4598 | /** | ||
4566 | * ata_qc_new_init - Request an available ATA command, and initialize it | 4599 | * ata_qc_new_init - Request an available ATA command, and initialize it |
4567 | * @dev: Device from whom we request an available command structure | 4600 | * @dev: Device from whom we request an available command structure |
4568 | * @tag: command tag | 4601 | * @tag: command tag |
@@ -4571,20 +4604,16 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) | |||
4571 | * None. | 4604 | * None. |
4572 | */ | 4605 | */ |
4573 | 4606 | ||
4574 | struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag) | 4607 | struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev) |
4575 | { | 4608 | { |
4576 | struct ata_port *ap = dev->link->ap; | 4609 | struct ata_port *ap = dev->link->ap; |
4577 | struct ata_queued_cmd *qc; | 4610 | struct ata_queued_cmd *qc; |
4578 | 4611 | ||
4579 | if (unlikely(ap->pflags & ATA_PFLAG_FROZEN)) | 4612 | qc = ata_qc_new(ap); |
4580 | return NULL; | ||
4581 | |||
4582 | qc = __ata_qc_from_tag(ap, tag); | ||
4583 | if (qc) { | 4613 | if (qc) { |
4584 | qc->scsicmd = NULL; | 4614 | qc->scsicmd = NULL; |
4585 | qc->ap = ap; | 4615 | qc->ap = ap; |
4586 | qc->dev = dev; | 4616 | qc->dev = dev; |
4587 | qc->tag = tag; | ||
4588 | 4617 | ||
4589 | ata_qc_reinit(qc); | 4618 | ata_qc_reinit(qc); |
4590 | } | 4619 | } |
@@ -4592,6 +4621,31 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag) | |||
4592 | return qc; | 4621 | return qc; |
4593 | } | 4622 | } |
4594 | 4623 | ||
4624 | /** | ||
4625 | * ata_qc_free - free unused ata_queued_cmd | ||
4626 | * @qc: Command to complete | ||
4627 | * | ||
4628 | * Designed to free unused ata_queued_cmd object | ||
4629 | * in case something prevents using it. | ||
4630 | * | ||
4631 | * LOCKING: | ||
4632 | * spin_lock_irqsave(host lock) | ||
4633 | */ | ||
4634 | void ata_qc_free(struct ata_queued_cmd *qc) | ||
4635 | { | ||
4636 | struct ata_port *ap = qc->ap; | ||
4637 | unsigned int tag; | ||
4638 | |||
4639 | WARN_ON(qc == NULL); /* ata_qc_from_tag _might_ return NULL */ | ||
4640 | |||
4641 | qc->flags = 0; | ||
4642 | tag = qc->tag; | ||
4643 | if (likely(ata_tag_valid(tag))) { | ||
4644 | qc->tag = ATA_TAG_POISON; | ||
4645 | clear_bit(tag, &ap->qc_allocated); | ||
4646 | } | ||
4647 | } | ||
4648 | |||
4595 | void __ata_qc_complete(struct ata_queued_cmd *qc) | 4649 | void __ata_qc_complete(struct ata_queued_cmd *qc) |
4596 | { | 4650 | { |
4597 | struct ata_port *ap = qc->ap; | 4651 | struct ata_port *ap = qc->ap; |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 8077bdf5d30d..32da9a93ce44 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -610,9 +610,6 @@ void ata_scsi_error(struct Scsi_Host *host) | |||
610 | if (ata_ncq_enabled(dev)) | 610 | if (ata_ncq_enabled(dev)) |
611 | ehc->saved_ncq_enabled |= 1 << devno; | 611 | ehc->saved_ncq_enabled |= 1 << devno; |
612 | } | 612 | } |
613 | |||
614 | /* set last reset timestamp to some time in the past */ | ||
615 | ehc->last_reset = jiffies - 60 * HZ; | ||
616 | } | 613 | } |
617 | 614 | ||
618 | ap->pflags |= ATA_PFLAG_EH_IN_PROGRESS; | 615 | ap->pflags |= ATA_PFLAG_EH_IN_PROGRESS; |
@@ -2281,17 +2278,21 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2281 | if (link->flags & ATA_LFLAG_NO_SRST) | 2278 | if (link->flags & ATA_LFLAG_NO_SRST) |
2282 | softreset = NULL; | 2279 | softreset = NULL; |
2283 | 2280 | ||
2284 | now = jiffies; | 2281 | /* make sure each reset attemp is at least COOL_DOWN apart */ |
2285 | deadline = ata_deadline(ehc->last_reset, ATA_EH_RESET_COOL_DOWN); | 2282 | if (ehc->i.flags & ATA_EHI_DID_RESET) { |
2286 | if (time_before(now, deadline)) | 2283 | now = jiffies; |
2287 | schedule_timeout_uninterruptible(deadline - now); | 2284 | WARN_ON(time_after(ehc->last_reset, now)); |
2285 | deadline = ata_deadline(ehc->last_reset, | ||
2286 | ATA_EH_RESET_COOL_DOWN); | ||
2287 | if (time_before(now, deadline)) | ||
2288 | schedule_timeout_uninterruptible(deadline - now); | ||
2289 | } | ||
2288 | 2290 | ||
2289 | spin_lock_irqsave(ap->lock, flags); | 2291 | spin_lock_irqsave(ap->lock, flags); |
2290 | ap->pflags |= ATA_PFLAG_RESETTING; | 2292 | ap->pflags |= ATA_PFLAG_RESETTING; |
2291 | spin_unlock_irqrestore(ap->lock, flags); | 2293 | spin_unlock_irqrestore(ap->lock, flags); |
2292 | 2294 | ||
2293 | ata_eh_about_to_do(link, NULL, ATA_EH_RESET); | 2295 | ata_eh_about_to_do(link, NULL, ATA_EH_RESET); |
2294 | ehc->last_reset = jiffies; | ||
2295 | 2296 | ||
2296 | ata_link_for_each_dev(dev, link) { | 2297 | ata_link_for_each_dev(dev, link) { |
2297 | /* If we issue an SRST then an ATA drive (not ATAPI) | 2298 | /* If we issue an SRST then an ATA drive (not ATAPI) |
@@ -2379,7 +2380,6 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2379 | /* | 2380 | /* |
2380 | * Perform reset | 2381 | * Perform reset |
2381 | */ | 2382 | */ |
2382 | ehc->last_reset = jiffies; | ||
2383 | if (ata_is_host_link(link)) | 2383 | if (ata_is_host_link(link)) |
2384 | ata_eh_freeze_port(ap); | 2384 | ata_eh_freeze_port(ap); |
2385 | 2385 | ||
@@ -2391,6 +2391,7 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2391 | reset == softreset ? "soft" : "hard"); | 2391 | reset == softreset ? "soft" : "hard"); |
2392 | 2392 | ||
2393 | /* mark that this EH session started with reset */ | 2393 | /* mark that this EH session started with reset */ |
2394 | ehc->last_reset = jiffies; | ||
2394 | if (reset == hardreset) | 2395 | if (reset == hardreset) |
2395 | ehc->i.flags |= ATA_EHI_DID_HARDRESET; | 2396 | ehc->i.flags |= ATA_EHI_DID_HARDRESET; |
2396 | else | 2397 | else |
@@ -2535,7 +2536,7 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
2535 | ata_eh_done(link, NULL, ATA_EH_RESET); | 2536 | ata_eh_done(link, NULL, ATA_EH_RESET); |
2536 | if (slave) | 2537 | if (slave) |
2537 | ata_eh_done(slave, NULL, ATA_EH_RESET); | 2538 | ata_eh_done(slave, NULL, ATA_EH_RESET); |
2538 | ehc->last_reset = jiffies; | 2539 | ehc->last_reset = jiffies; /* update to completion time */ |
2539 | ehc->i.action |= ATA_EH_REVALIDATE; | 2540 | ehc->i.action |= ATA_EH_REVALIDATE; |
2540 | 2541 | ||
2541 | rc = 0; | 2542 | rc = 0; |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 3fa75eac135d..47c7afcb36f2 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -709,11 +709,7 @@ static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev, | |||
709 | { | 709 | { |
710 | struct ata_queued_cmd *qc; | 710 | struct ata_queued_cmd *qc; |
711 | 711 | ||
712 | if (cmd->request->tag != -1) | 712 | qc = ata_qc_new_init(dev); |
713 | qc = ata_qc_new_init(dev, cmd->request->tag); | ||
714 | else | ||
715 | qc = ata_qc_new_init(dev, 0); | ||
716 | |||
717 | if (qc) { | 713 | if (qc) { |
718 | qc->scsicmd = cmd; | 714 | qc->scsicmd = cmd; |
719 | qc->scsidone = done; | 715 | qc->scsidone = done; |
@@ -1108,17 +1104,7 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, | |||
1108 | 1104 | ||
1109 | depth = min(sdev->host->can_queue, ata_id_queue_depth(dev->id)); | 1105 | depth = min(sdev->host->can_queue, ata_id_queue_depth(dev->id)); |
1110 | depth = min(ATA_MAX_QUEUE - 1, depth); | 1106 | depth = min(ATA_MAX_QUEUE - 1, depth); |
1111 | 1107 | scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, depth); | |
1112 | /* | ||
1113 | * If this device is behind a port multiplier, we have | ||
1114 | * to share the tag map between all devices on that PMP. | ||
1115 | * Set up the shared tag map here and we get automatic. | ||
1116 | */ | ||
1117 | if (dev->link->ap->pmp_link) | ||
1118 | scsi_init_shared_tag_map(sdev->host, ATA_MAX_QUEUE - 1); | ||
1119 | |||
1120 | scsi_set_tag_type(sdev, MSG_SIMPLE_TAG); | ||
1121 | scsi_activate_tcq(sdev, depth); | ||
1122 | } | 1108 | } |
1123 | 1109 | ||
1124 | return 0; | 1110 | return 0; |
@@ -1958,11 +1944,6 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) | |||
1958 | hdr[1] |= (1 << 7); | 1944 | hdr[1] |= (1 << 7); |
1959 | 1945 | ||
1960 | memcpy(rbuf, hdr, sizeof(hdr)); | 1946 | memcpy(rbuf, hdr, sizeof(hdr)); |
1961 | |||
1962 | /* if ncq, set tags supported */ | ||
1963 | if (ata_id_has_ncq(args->id)) | ||
1964 | rbuf[7] |= (1 << 1); | ||
1965 | |||
1966 | memcpy(&rbuf[8], "ATA ", 8); | 1947 | memcpy(&rbuf[8], "ATA ", 8); |
1967 | ata_id_string(args->id, &rbuf[16], ATA_ID_PROD, 16); | 1948 | ata_id_string(args->id, &rbuf[16], ATA_ID_PROD, 16); |
1968 | ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV, 4); | 1949 | ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV, 4); |
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index d3831d39bdaa..fe2839e58774 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h | |||
@@ -74,7 +74,7 @@ extern struct ata_link *ata_dev_phys_link(struct ata_device *dev); | |||
74 | extern void ata_force_cbl(struct ata_port *ap); | 74 | extern void ata_force_cbl(struct ata_port *ap); |
75 | extern u64 ata_tf_to_lba(const struct ata_taskfile *tf); | 75 | extern u64 ata_tf_to_lba(const struct ata_taskfile *tf); |
76 | extern u64 ata_tf_to_lba48(const struct ata_taskfile *tf); | 76 | extern u64 ata_tf_to_lba48(const struct ata_taskfile *tf); |
77 | extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag); | 77 | extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev); |
78 | extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, | 78 | extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, |
79 | u64 block, u32 n_block, unsigned int tf_flags, | 79 | u64 block, u32 n_block, unsigned int tf_flags, |
80 | unsigned int tag); | 80 | unsigned int tag); |
@@ -103,6 +103,7 @@ extern int ata_dev_configure(struct ata_device *dev); | |||
103 | extern int sata_down_spd_limit(struct ata_link *link); | 103 | extern int sata_down_spd_limit(struct ata_link *link); |
104 | extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); | 104 | extern int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel); |
105 | extern void ata_sg_clean(struct ata_queued_cmd *qc); | 105 | extern void ata_sg_clean(struct ata_queued_cmd *qc); |
106 | extern void ata_qc_free(struct ata_queued_cmd *qc); | ||
106 | extern void ata_qc_issue(struct ata_queued_cmd *qc); | 107 | extern void ata_qc_issue(struct ata_queued_cmd *qc); |
107 | extern void __ata_qc_complete(struct ata_queued_cmd *qc); | 108 | extern void __ata_qc_complete(struct ata_queued_cmd *qc); |
108 | extern int atapi_check_dma(struct ata_queued_cmd *qc); | 109 | extern int atapi_check_dma(struct ata_queued_cmd *qc); |
@@ -118,22 +119,6 @@ extern struct ata_port *ata_port_alloc(struct ata_host *host); | |||
118 | extern void ata_dev_enable_pm(struct ata_device *dev, enum link_pm policy); | 119 | extern void ata_dev_enable_pm(struct ata_device *dev, enum link_pm policy); |
119 | extern void ata_lpm_schedule(struct ata_port *ap, enum link_pm); | 120 | extern void ata_lpm_schedule(struct ata_port *ap, enum link_pm); |
120 | 121 | ||
121 | /** | ||
122 | * ata_qc_free - free unused ata_queued_cmd | ||
123 | * @qc: Command to complete | ||
124 | * | ||
125 | * Designed to free unused ata_queued_cmd object | ||
126 | * in case something prevents using it. | ||
127 | * | ||
128 | * LOCKING: | ||
129 | * spin_lock_irqsave(host lock) | ||
130 | */ | ||
131 | static inline void ata_qc_free(struct ata_queued_cmd *qc) | ||
132 | { | ||
133 | qc->flags = 0; | ||
134 | qc->tag = ATA_TAG_POISON; | ||
135 | } | ||
136 | |||
137 | /* libata-acpi.c */ | 122 | /* libata-acpi.c */ |
138 | #ifdef CONFIG_ATA_ACPI | 123 | #ifdef CONFIG_ATA_ACPI |
139 | extern void ata_acpi_associate_sata_port(struct ata_port *ap); | 124 | extern void ata_acpi_associate_sata_port(struct ata_port *ap); |
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c index 1b2d4a0f5f74..8b236af84c2e 100644 --- a/drivers/ata/pata_cs5535.c +++ b/drivers/ata/pata_cs5535.c | |||
@@ -72,7 +72,6 @@ | |||
72 | /** | 72 | /** |
73 | * cs5535_cable_detect - detect cable type | 73 | * cs5535_cable_detect - detect cable type |
74 | * @ap: Port to detect on | 74 | * @ap: Port to detect on |
75 | * @deadline: deadline jiffies for the operation | ||
76 | * | 75 | * |
77 | * Perform cable detection for ATA66 capable cable. Return a libata | 76 | * Perform cable detection for ATA66 capable cable. Return a libata |
78 | * cable type. | 77 | * cable type. |
diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c index 73f8332cb679..afed92976198 100644 --- a/drivers/ata/pata_cs5536.c +++ b/drivers/ata/pata_cs5536.c | |||
@@ -110,7 +110,6 @@ static inline int cs5536_write(struct pci_dev *pdev, int reg, int val) | |||
110 | /** | 110 | /** |
111 | * cs5536_cable_detect - detect cable type | 111 | * cs5536_cable_detect - detect cable type |
112 | * @ap: Port to detect on | 112 | * @ap: Port to detect on |
113 | * @deadline: deadline jiffies for the operation | ||
114 | * | 113 | * |
115 | * Perform cable detection for ATA66 capable cable. Return a libata | 114 | * Perform cable detection for ATA66 capable cable. Return a libata |
116 | * cable type. | 115 | * cable type. |
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index 271cb64d429e..64b2e2281ee7 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c | |||
@@ -416,6 +416,7 @@ static struct pcmcia_device_id pcmcia_devices[] = { | |||
416 | PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), | 416 | PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), |
417 | PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), | 417 | PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), |
418 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6), | 418 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6), |
419 | PCMCIA_DEVICE_PROD_ID2("Flash Card", 0x5a362506), | ||
419 | PCMCIA_DEVICE_NULL, | 420 | PCMCIA_DEVICE_NULL, |
420 | }; | 421 | }; |
421 | 422 | ||
diff --git a/drivers/ata/pata_sch.c b/drivers/ata/pata_sch.c index c8cc027789fe..6aeeeeb34124 100644 --- a/drivers/ata/pata_sch.c +++ b/drivers/ata/pata_sch.c | |||
@@ -83,7 +83,7 @@ static struct ata_port_operations sch_pata_ops = { | |||
83 | }; | 83 | }; |
84 | 84 | ||
85 | static struct ata_port_info sch_port_info = { | 85 | static struct ata_port_info sch_port_info = { |
86 | .flags = 0, | 86 | .flags = ATA_FLAG_SLAVE_POSS, |
87 | .pio_mask = ATA_PIO4, /* pio0-4 */ | 87 | .pio_mask = ATA_PIO4, /* pio0-4 */ |
88 | .mwdma_mask = ATA_MWDMA2, /* mwdma0-2 */ | 88 | .mwdma_mask = ATA_MWDMA2, /* mwdma0-2 */ |
89 | .udma_mask = ATA_UDMA5, /* udma0-5 */ | 89 | .udma_mask = ATA_UDMA5, /* udma0-5 */ |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 4023885353e0..12de1fdaa6c6 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -96,6 +96,8 @@ static const struct pci_device_id cciss_pci_device_id[] = { | |||
96 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3245}, | 96 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3245}, |
97 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3247}, | 97 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3247}, |
98 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249}, | 98 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249}, |
99 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324A}, | ||
100 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324B}, | ||
99 | {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 101 | {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
100 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, | 102 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, |
101 | {0,} | 103 | {0,} |
@@ -133,6 +135,8 @@ static struct board_type products[] = { | |||
133 | {0x3245103C, "Smart Array P410i", &SA5_access}, | 135 | {0x3245103C, "Smart Array P410i", &SA5_access}, |
134 | {0x3247103C, "Smart Array P411", &SA5_access}, | 136 | {0x3247103C, "Smart Array P411", &SA5_access}, |
135 | {0x3249103C, "Smart Array P812", &SA5_access}, | 137 | {0x3249103C, "Smart Array P812", &SA5_access}, |
138 | {0x324A103C, "Smart Array P712m", &SA5_access}, | ||
139 | {0x324B103C, "Smart Array P711m", &SA5_access}, | ||
136 | {0xFFFF103C, "Unknown Smart Array", &SA5_access}, | 140 | {0xFFFF103C, "Unknown Smart Array", &SA5_access}, |
137 | }; | 141 | }; |
138 | 142 | ||
@@ -1366,6 +1370,7 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, | |||
1366 | disk->first_minor = drv_index << NWD_SHIFT; | 1370 | disk->first_minor = drv_index << NWD_SHIFT; |
1367 | disk->fops = &cciss_fops; | 1371 | disk->fops = &cciss_fops; |
1368 | disk->private_data = &h->drv[drv_index]; | 1372 | disk->private_data = &h->drv[drv_index]; |
1373 | disk->driverfs_dev = &h->pdev->dev; | ||
1369 | 1374 | ||
1370 | /* Set up queue information */ | 1375 | /* Set up queue information */ |
1371 | blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask); | 1376 | blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask); |
@@ -3404,7 +3409,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3404 | int i; | 3409 | int i; |
3405 | int j = 0; | 3410 | int j = 0; |
3406 | int rc; | 3411 | int rc; |
3407 | int dac; | 3412 | int dac, return_code; |
3413 | InquiryData_struct *inq_buff = NULL; | ||
3408 | 3414 | ||
3409 | i = alloc_cciss_hba(); | 3415 | i = alloc_cciss_hba(); |
3410 | if (i < 0) | 3416 | if (i < 0) |
@@ -3510,6 +3516,25 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3510 | /* Turn the interrupts on so we can service requests */ | 3516 | /* Turn the interrupts on so we can service requests */ |
3511 | hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON); | 3517 | hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON); |
3512 | 3518 | ||
3519 | /* Get the firmware version */ | ||
3520 | inq_buff = kzalloc(sizeof(InquiryData_struct), GFP_KERNEL); | ||
3521 | if (inq_buff == NULL) { | ||
3522 | printk(KERN_ERR "cciss: out of memory\n"); | ||
3523 | goto clean4; | ||
3524 | } | ||
3525 | |||
3526 | return_code = sendcmd_withirq(CISS_INQUIRY, i, inq_buff, | ||
3527 | sizeof(InquiryData_struct), 0, 0 , 0, TYPE_CMD); | ||
3528 | if (return_code == IO_OK) { | ||
3529 | hba[i]->firm_ver[0] = inq_buff->data_byte[32]; | ||
3530 | hba[i]->firm_ver[1] = inq_buff->data_byte[33]; | ||
3531 | hba[i]->firm_ver[2] = inq_buff->data_byte[34]; | ||
3532 | hba[i]->firm_ver[3] = inq_buff->data_byte[35]; | ||
3533 | } else { /* send command failed */ | ||
3534 | printk(KERN_WARNING "cciss: unable to determine firmware" | ||
3535 | " version of controller\n"); | ||
3536 | } | ||
3537 | |||
3513 | cciss_procinit(i); | 3538 | cciss_procinit(i); |
3514 | 3539 | ||
3515 | hba[i]->cciss_max_sectors = 2048; | 3540 | hba[i]->cciss_max_sectors = 2048; |
@@ -3520,6 +3545,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3520 | return 1; | 3545 | return 1; |
3521 | 3546 | ||
3522 | clean4: | 3547 | clean4: |
3548 | kfree(inq_buff); | ||
3523 | #ifdef CONFIG_CISS_SCSI_TAPE | 3549 | #ifdef CONFIG_CISS_SCSI_TAPE |
3524 | kfree(hba[i]->scsi_rejects.complete); | 3550 | kfree(hba[i]->scsi_rejects.complete); |
3525 | #endif | 3551 | #endif |
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index 47d233c6d0b3..5d39df14ed90 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c | |||
@@ -567,7 +567,12 @@ static int __init cpqarray_init(void) | |||
567 | num_cntlrs_reg++; | 567 | num_cntlrs_reg++; |
568 | } | 568 | } |
569 | 569 | ||
570 | return(num_cntlrs_reg); | 570 | if (num_cntlrs_reg) |
571 | return 0; | ||
572 | else { | ||
573 | pci_unregister_driver(&cpqarray_pci_driver); | ||
574 | return -ENODEV; | ||
575 | } | ||
571 | } | 576 | } |
572 | 577 | ||
573 | /* Function to find the first free pointer into our hba[] array */ | 578 | /* Function to find the first free pointer into our hba[] array */ |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 8a59aaa21be5..7a88dfd4427b 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -422,9 +422,11 @@ struct ipmi_smi { | |||
422 | /** | 422 | /** |
423 | * The driver model view of the IPMI messaging driver. | 423 | * The driver model view of the IPMI messaging driver. |
424 | */ | 424 | */ |
425 | static struct device_driver ipmidriver = { | 425 | static struct platform_driver ipmidriver = { |
426 | .name = "ipmi", | 426 | .driver = { |
427 | .bus = &platform_bus_type | 427 | .name = "ipmi", |
428 | .bus = &platform_bus_type | ||
429 | } | ||
428 | }; | 430 | }; |
429 | static DEFINE_MUTEX(ipmidriver_mutex); | 431 | static DEFINE_MUTEX(ipmidriver_mutex); |
430 | 432 | ||
@@ -2384,9 +2386,9 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum, | |||
2384 | * representing the interfaced BMC already | 2386 | * representing the interfaced BMC already |
2385 | */ | 2387 | */ |
2386 | if (bmc->guid_set) | 2388 | if (bmc->guid_set) |
2387 | old_bmc = ipmi_find_bmc_guid(&ipmidriver, bmc->guid); | 2389 | old_bmc = ipmi_find_bmc_guid(&ipmidriver.driver, bmc->guid); |
2388 | else | 2390 | else |
2389 | old_bmc = ipmi_find_bmc_prod_dev_id(&ipmidriver, | 2391 | old_bmc = ipmi_find_bmc_prod_dev_id(&ipmidriver.driver, |
2390 | bmc->id.product_id, | 2392 | bmc->id.product_id, |
2391 | bmc->id.device_id); | 2393 | bmc->id.device_id); |
2392 | 2394 | ||
@@ -2416,7 +2418,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum, | |||
2416 | snprintf(name, sizeof(name), | 2418 | snprintf(name, sizeof(name), |
2417 | "ipmi_bmc.%4.4x", bmc->id.product_id); | 2419 | "ipmi_bmc.%4.4x", bmc->id.product_id); |
2418 | 2420 | ||
2419 | while (ipmi_find_bmc_prod_dev_id(&ipmidriver, | 2421 | while (ipmi_find_bmc_prod_dev_id(&ipmidriver.driver, |
2420 | bmc->id.product_id, | 2422 | bmc->id.product_id, |
2421 | bmc->id.device_id)) { | 2423 | bmc->id.device_id)) { |
2422 | if (!warn_printed) { | 2424 | if (!warn_printed) { |
@@ -2446,7 +2448,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum, | |||
2446 | " Unable to allocate platform device\n"); | 2448 | " Unable to allocate platform device\n"); |
2447 | return -ENOMEM; | 2449 | return -ENOMEM; |
2448 | } | 2450 | } |
2449 | bmc->dev->dev.driver = &ipmidriver; | 2451 | bmc->dev->dev.driver = &ipmidriver.driver; |
2450 | dev_set_drvdata(&bmc->dev->dev, bmc); | 2452 | dev_set_drvdata(&bmc->dev->dev, bmc); |
2451 | kref_init(&bmc->refcount); | 2453 | kref_init(&bmc->refcount); |
2452 | 2454 | ||
@@ -4247,7 +4249,7 @@ static int ipmi_init_msghandler(void) | |||
4247 | if (initialized) | 4249 | if (initialized) |
4248 | return 0; | 4250 | return 0; |
4249 | 4251 | ||
4250 | rv = driver_register(&ipmidriver); | 4252 | rv = driver_register(&ipmidriver.driver); |
4251 | if (rv) { | 4253 | if (rv) { |
4252 | printk(KERN_ERR PFX "Could not register IPMI driver\n"); | 4254 | printk(KERN_ERR PFX "Could not register IPMI driver\n"); |
4253 | return rv; | 4255 | return rv; |
@@ -4308,7 +4310,7 @@ static __exit void cleanup_ipmi(void) | |||
4308 | remove_proc_entry(proc_ipmi_root->name, NULL); | 4310 | remove_proc_entry(proc_ipmi_root->name, NULL); |
4309 | #endif /* CONFIG_PROC_FS */ | 4311 | #endif /* CONFIG_PROC_FS */ |
4310 | 4312 | ||
4311 | driver_unregister(&ipmidriver); | 4313 | driver_unregister(&ipmidriver.driver); |
4312 | 4314 | ||
4313 | initialized = 0; | 4315 | initialized = 0; |
4314 | 4316 | ||
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 3123bf57ad91..3000135f2ead 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -114,9 +114,11 @@ static char *si_to_str[] = { "kcs", "smic", "bt" }; | |||
114 | 114 | ||
115 | #define DEVICE_NAME "ipmi_si" | 115 | #define DEVICE_NAME "ipmi_si" |
116 | 116 | ||
117 | static struct device_driver ipmi_driver = { | 117 | static struct platform_driver ipmi_driver = { |
118 | .name = DEVICE_NAME, | 118 | .driver = { |
119 | .bus = &platform_bus_type | 119 | .name = DEVICE_NAME, |
120 | .bus = &platform_bus_type | ||
121 | } | ||
120 | }; | 122 | }; |
121 | 123 | ||
122 | 124 | ||
@@ -2868,7 +2870,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2868 | goto out_err; | 2870 | goto out_err; |
2869 | } | 2871 | } |
2870 | new_smi->dev = &new_smi->pdev->dev; | 2872 | new_smi->dev = &new_smi->pdev->dev; |
2871 | new_smi->dev->driver = &ipmi_driver; | 2873 | new_smi->dev->driver = &ipmi_driver.driver; |
2872 | 2874 | ||
2873 | rv = platform_device_add(new_smi->pdev); | 2875 | rv = platform_device_add(new_smi->pdev); |
2874 | if (rv) { | 2876 | if (rv) { |
@@ -2983,7 +2985,7 @@ static __devinit int init_ipmi_si(void) | |||
2983 | initialized = 1; | 2985 | initialized = 1; |
2984 | 2986 | ||
2985 | /* Register the device drivers. */ | 2987 | /* Register the device drivers. */ |
2986 | rv = driver_register(&ipmi_driver); | 2988 | rv = driver_register(&ipmi_driver.driver); |
2987 | if (rv) { | 2989 | if (rv) { |
2988 | printk(KERN_ERR | 2990 | printk(KERN_ERR |
2989 | "init_ipmi_si: Unable to register driver: %d\n", | 2991 | "init_ipmi_si: Unable to register driver: %d\n", |
@@ -3052,7 +3054,7 @@ static __devinit int init_ipmi_si(void) | |||
3052 | #ifdef CONFIG_PPC_OF | 3054 | #ifdef CONFIG_PPC_OF |
3053 | of_unregister_platform_driver(&ipmi_of_platform_driver); | 3055 | of_unregister_platform_driver(&ipmi_of_platform_driver); |
3054 | #endif | 3056 | #endif |
3055 | driver_unregister(&ipmi_driver); | 3057 | driver_unregister(&ipmi_driver.driver); |
3056 | printk(KERN_WARNING | 3058 | printk(KERN_WARNING |
3057 | "ipmi_si: Unable to find any System Interface(s)\n"); | 3059 | "ipmi_si: Unable to find any System Interface(s)\n"); |
3058 | return -ENODEV; | 3060 | return -ENODEV; |
@@ -3151,7 +3153,7 @@ static __exit void cleanup_ipmi_si(void) | |||
3151 | cleanup_one_si(e); | 3153 | cleanup_one_si(e); |
3152 | mutex_unlock(&smi_infos_lock); | 3154 | mutex_unlock(&smi_infos_lock); |
3153 | 3155 | ||
3154 | driver_unregister(&ipmi_driver); | 3156 | driver_unregister(&ipmi_driver.driver); |
3155 | } | 3157 | } |
3156 | module_exit(cleanup_ipmi_si); | 3158 | module_exit(cleanup_ipmi_si); |
3157 | 3159 | ||
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 7d30ee1d3fca..04e4549299ba 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -7,12 +7,14 @@ | |||
7 | * Original driver code supplied by Multi-Tech | 7 | * Original driver code supplied by Multi-Tech |
8 | * | 8 | * |
9 | * Changes | 9 | * Changes |
10 | * 1/9/98 alan@redhat.com Merge to 2.0.x kernel tree | 10 | * 1/9/98 alan@lxorguk.ukuu.org.uk |
11 | * Merge to 2.0.x kernel tree | ||
11 | * Obtain and use official major/minors | 12 | * Obtain and use official major/minors |
12 | * Loader switched to a misc device | 13 | * Loader switched to a misc device |
13 | * (fixed range check bug as a side effect) | 14 | * (fixed range check bug as a side effect) |
14 | * Printk clean up | 15 | * Printk clean up |
15 | * 9/12/98 alan@redhat.com Rough port to 2.1.x | 16 | * 9/12/98 alan@lxorguk.ukuu.org.uk |
17 | * Rough port to 2.1.x | ||
16 | * | 18 | * |
17 | * 10/6/99 sameer Merged the ISA and PCI drivers to | 19 | * 10/6/99 sameer Merged the ISA and PCI drivers to |
18 | * a new unified driver. | 20 | * a new unified driver. |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 8beef50f95a0..047766915411 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -14,7 +14,8 @@ | |||
14 | * (at your option) any later version. | 14 | * (at your option) any later version. |
15 | * | 15 | * |
16 | * Fed through a cleanup, indent and remove of non 2.6 code by Alan Cox | 16 | * Fed through a cleanup, indent and remove of non 2.6 code by Alan Cox |
17 | * <alan@redhat.com>. The original 1.8 code is available on www.moxa.com. | 17 | * <alan@lxorguk.ukuu.org.uk>. The original 1.8 code is available on |
18 | * www.moxa.com. | ||
18 | * - Fixed x86_64 cleanness | 19 | * - Fixed x86_64 cleanness |
19 | */ | 20 | */ |
20 | 21 | ||
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 2457b07dabd6..f4374437a033 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c | |||
@@ -523,7 +523,7 @@ static int acpi_driver_registered; | |||
523 | 523 | ||
524 | static int sonypi_ec_write(u8 addr, u8 value) | 524 | static int sonypi_ec_write(u8 addr, u8 value) |
525 | { | 525 | { |
526 | #ifdef CONFIG_ACPI_EC | 526 | #ifdef CONFIG_ACPI |
527 | if (SONYPI_ACPI_ACTIVE) | 527 | if (SONYPI_ACPI_ACTIVE) |
528 | return ec_write(addr, value); | 528 | return ec_write(addr, value); |
529 | #endif | 529 | #endif |
@@ -539,7 +539,7 @@ static int sonypi_ec_write(u8 addr, u8 value) | |||
539 | 539 | ||
540 | static int sonypi_ec_read(u8 addr, u8 *value) | 540 | static int sonypi_ec_read(u8 addr, u8 *value) |
541 | { | 541 | { |
542 | #ifdef CONFIG_ACPI_EC | 542 | #ifdef CONFIG_ACPI |
543 | if (SONYPI_ACPI_ACTIVE) | 543 | if (SONYPI_ACPI_ACTIVE) |
544 | return ec_read(addr, value); | 544 | return ec_read(addr, value); |
545 | #endif | 545 | #endif |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index d8f83e26e4a4..a5af6072e2b3 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -1644,7 +1644,10 @@ static void reset_terminal(struct vc_data *vc, int do_clear) | |||
1644 | vc->vc_tab_stop[1] = | 1644 | vc->vc_tab_stop[1] = |
1645 | vc->vc_tab_stop[2] = | 1645 | vc->vc_tab_stop[2] = |
1646 | vc->vc_tab_stop[3] = | 1646 | vc->vc_tab_stop[3] = |
1647 | vc->vc_tab_stop[4] = 0x01010101; | 1647 | vc->vc_tab_stop[4] = |
1648 | vc->vc_tab_stop[5] = | ||
1649 | vc->vc_tab_stop[6] = | ||
1650 | vc->vc_tab_stop[7] = 0x01010101; | ||
1648 | 1651 | ||
1649 | vc->vc_bell_pitch = DEFAULT_BELL_PITCH; | 1652 | vc->vc_bell_pitch = DEFAULT_BELL_PITCH; |
1650 | vc->vc_bell_duration = DEFAULT_BELL_DURATION; | 1653 | vc->vc_bell_duration = DEFAULT_BELL_DURATION; |
@@ -1935,7 +1938,10 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) | |||
1935 | vc->vc_tab_stop[1] = | 1938 | vc->vc_tab_stop[1] = |
1936 | vc->vc_tab_stop[2] = | 1939 | vc->vc_tab_stop[2] = |
1937 | vc->vc_tab_stop[3] = | 1940 | vc->vc_tab_stop[3] = |
1938 | vc->vc_tab_stop[4] = 0; | 1941 | vc->vc_tab_stop[4] = |
1942 | vc->vc_tab_stop[5] = | ||
1943 | vc->vc_tab_stop[6] = | ||
1944 | vc->vc_tab_stop[7] = 0; | ||
1939 | } | 1945 | } |
1940 | return; | 1946 | return; |
1941 | case 'm': | 1947 | case 'm': |
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 5bed73329ef8..8504a2108557 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c | |||
@@ -65,12 +65,14 @@ static void cpuidle_idle_call(void) | |||
65 | return; | 65 | return; |
66 | } | 66 | } |
67 | 67 | ||
68 | #if 0 | ||
69 | /* shows regressions, re-enable for 2.6.29 */ | ||
68 | /* | 70 | /* |
69 | * run any timers that can be run now, at this point | 71 | * run any timers that can be run now, at this point |
70 | * before calculating the idle duration etc. | 72 | * before calculating the idle duration etc. |
71 | */ | 73 | */ |
72 | hrtimer_peek_ahead_timers(); | 74 | hrtimer_peek_ahead_timers(); |
73 | 75 | #endif | |
74 | /* ask the governor for the next state */ | 76 | /* ask the governor for the next state */ |
75 | next_state = cpuidle_curr_governor->select(dev); | 77 | next_state = cpuidle_curr_governor->select(dev); |
76 | if (need_resched()) | 78 | if (need_resched()) |
diff --git a/drivers/dca/dca-core.c b/drivers/dca/dca-core.c index ec249d2db633..d883e1b8bb8c 100644 --- a/drivers/dca/dca-core.c +++ b/drivers/dca/dca-core.c | |||
@@ -270,6 +270,6 @@ static void __exit dca_exit(void) | |||
270 | dca_sysfs_exit(); | 270 | dca_sysfs_exit(); |
271 | } | 271 | } |
272 | 272 | ||
273 | module_init(dca_init); | 273 | subsys_initcall(dca_init); |
274 | module_exit(dca_exit); | 274 | module_exit(dca_exit); |
275 | 275 | ||
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index dc003a3a787d..5317e08221ec 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c | |||
@@ -399,8 +399,8 @@ int dma_async_device_register(struct dma_device *device) | |||
399 | chan->chan_id = chancnt++; | 399 | chan->chan_id = chancnt++; |
400 | chan->dev.class = &dma_devclass; | 400 | chan->dev.class = &dma_devclass; |
401 | chan->dev.parent = device->dev; | 401 | chan->dev.parent = device->dev; |
402 | snprintf(chan->dev.bus_id, BUS_ID_SIZE, "dma%dchan%d", | 402 | dev_set_name(&chan->dev, "dma%dchan%d", |
403 | device->dev_id, chan->chan_id); | 403 | device->dev_id, chan->chan_id); |
404 | 404 | ||
405 | rc = device_register(&chan->dev); | 405 | rc = device_register(&chan->dev); |
406 | if (rc) { | 406 | if (rc) { |
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index d1e381e35a9e..ed9636bfb54a 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c | |||
@@ -20,11 +20,11 @@ static unsigned int test_buf_size = 16384; | |||
20 | module_param(test_buf_size, uint, S_IRUGO); | 20 | module_param(test_buf_size, uint, S_IRUGO); |
21 | MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer"); | 21 | MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer"); |
22 | 22 | ||
23 | static char test_channel[BUS_ID_SIZE]; | 23 | static char test_channel[20]; |
24 | module_param_string(channel, test_channel, sizeof(test_channel), S_IRUGO); | 24 | module_param_string(channel, test_channel, sizeof(test_channel), S_IRUGO); |
25 | MODULE_PARM_DESC(channel, "Bus ID of the channel to test (default: any)"); | 25 | MODULE_PARM_DESC(channel, "Bus ID of the channel to test (default: any)"); |
26 | 26 | ||
27 | static char test_device[BUS_ID_SIZE]; | 27 | static char test_device[20]; |
28 | module_param_string(device, test_device, sizeof(test_device), S_IRUGO); | 28 | module_param_string(device, test_device, sizeof(test_device), S_IRUGO); |
29 | MODULE_PARM_DESC(device, "Bus ID of the DMA Engine to test (default: any)"); | 29 | MODULE_PARM_DESC(device, "Bus ID of the DMA Engine to test (default: any)"); |
30 | 30 | ||
@@ -80,14 +80,14 @@ static bool dmatest_match_channel(struct dma_chan *chan) | |||
80 | { | 80 | { |
81 | if (test_channel[0] == '\0') | 81 | if (test_channel[0] == '\0') |
82 | return true; | 82 | return true; |
83 | return strcmp(chan->dev.bus_id, test_channel) == 0; | 83 | return strcmp(dev_name(&chan->dev), test_channel) == 0; |
84 | } | 84 | } |
85 | 85 | ||
86 | static bool dmatest_match_device(struct dma_device *device) | 86 | static bool dmatest_match_device(struct dma_device *device) |
87 | { | 87 | { |
88 | if (test_device[0] == '\0') | 88 | if (test_device[0] == '\0') |
89 | return true; | 89 | return true; |
90 | return strcmp(device->dev->bus_id, test_device) == 0; | 90 | return strcmp(dev_name(device->dev), test_device) == 0; |
91 | } | 91 | } |
92 | 92 | ||
93 | static unsigned long dmatest_random(void) | 93 | static unsigned long dmatest_random(void) |
@@ -332,7 +332,7 @@ static enum dma_state_client dmatest_add_channel(struct dma_chan *chan) | |||
332 | 332 | ||
333 | dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL); | 333 | dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL); |
334 | if (!dtc) { | 334 | if (!dtc) { |
335 | pr_warning("dmatest: No memory for %s\n", chan->dev.bus_id); | 335 | pr_warning("dmatest: No memory for %s\n", dev_name(&chan->dev)); |
336 | return DMA_NAK; | 336 | return DMA_NAK; |
337 | } | 337 | } |
338 | 338 | ||
@@ -343,16 +343,16 @@ static enum dma_state_client dmatest_add_channel(struct dma_chan *chan) | |||
343 | thread = kzalloc(sizeof(struct dmatest_thread), GFP_KERNEL); | 343 | thread = kzalloc(sizeof(struct dmatest_thread), GFP_KERNEL); |
344 | if (!thread) { | 344 | if (!thread) { |
345 | pr_warning("dmatest: No memory for %s-test%u\n", | 345 | pr_warning("dmatest: No memory for %s-test%u\n", |
346 | chan->dev.bus_id, i); | 346 | dev_name(&chan->dev), i); |
347 | break; | 347 | break; |
348 | } | 348 | } |
349 | thread->chan = dtc->chan; | 349 | thread->chan = dtc->chan; |
350 | smp_wmb(); | 350 | smp_wmb(); |
351 | thread->task = kthread_run(dmatest_func, thread, "%s-test%u", | 351 | thread->task = kthread_run(dmatest_func, thread, "%s-test%u", |
352 | chan->dev.bus_id, i); | 352 | dev_name(&chan->dev), i); |
353 | if (IS_ERR(thread->task)) { | 353 | if (IS_ERR(thread->task)) { |
354 | pr_warning("dmatest: Failed to run thread %s-test%u\n", | 354 | pr_warning("dmatest: Failed to run thread %s-test%u\n", |
355 | chan->dev.bus_id, i); | 355 | dev_name(&chan->dev), i); |
356 | kfree(thread); | 356 | kfree(thread); |
357 | break; | 357 | break; |
358 | } | 358 | } |
@@ -362,7 +362,7 @@ static enum dma_state_client dmatest_add_channel(struct dma_chan *chan) | |||
362 | list_add_tail(&thread->node, &dtc->threads); | 362 | list_add_tail(&thread->node, &dtc->threads); |
363 | } | 363 | } |
364 | 364 | ||
365 | pr_info("dmatest: Started %u threads using %s\n", i, chan->dev.bus_id); | 365 | pr_info("dmatest: Started %u threads using %s\n", i, dev_name(&chan->dev)); |
366 | 366 | ||
367 | list_add_tail(&dtc->node, &dmatest_channels); | 367 | list_add_tail(&dtc->node, &dmatest_channels); |
368 | nr_channels++; | 368 | nr_channels++; |
@@ -379,7 +379,7 @@ static enum dma_state_client dmatest_remove_channel(struct dma_chan *chan) | |||
379 | list_del(&dtc->node); | 379 | list_del(&dtc->node); |
380 | dmatest_cleanup_channel(dtc); | 380 | dmatest_cleanup_channel(dtc); |
381 | pr_debug("dmatest: lost channel %s\n", | 381 | pr_debug("dmatest: lost channel %s\n", |
382 | chan->dev.bus_id); | 382 | dev_name(&chan->dev)); |
383 | return DMA_ACK; | 383 | return DMA_ACK; |
384 | } | 384 | } |
385 | } | 385 | } |
@@ -418,7 +418,7 @@ dmatest_event(struct dma_client *client, struct dma_chan *chan, | |||
418 | 418 | ||
419 | default: | 419 | default: |
420 | pr_info("dmatest: Unhandled event %u (%s)\n", | 420 | pr_info("dmatest: Unhandled event %u (%s)\n", |
421 | state, chan->dev.bus_id); | 421 | state, dev_name(&chan->dev)); |
422 | break; | 422 | break; |
423 | } | 423 | } |
424 | 424 | ||
diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c index b0438c4f0c30..ecd743f7cc61 100644 --- a/drivers/dma/ioat_dma.c +++ b/drivers/dma/ioat_dma.c | |||
@@ -525,7 +525,7 @@ static dma_cookie_t ioat1_tx_submit(struct dma_async_tx_descriptor *tx) | |||
525 | } | 525 | } |
526 | 526 | ||
527 | hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS; | 527 | hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS; |
528 | if (new->async_tx.callback) { | 528 | if (first->async_tx.callback) { |
529 | hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN; | 529 | hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN; |
530 | if (first != new) { | 530 | if (first != new) { |
531 | /* move callback into to last desc */ | 531 | /* move callback into to last desc */ |
@@ -617,7 +617,7 @@ static dma_cookie_t ioat2_tx_submit(struct dma_async_tx_descriptor *tx) | |||
617 | } | 617 | } |
618 | 618 | ||
619 | hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_CP_STS; | 619 | hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_CP_STS; |
620 | if (new->async_tx.callback) { | 620 | if (first->async_tx.callback) { |
621 | hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN; | 621 | hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN; |
622 | if (first != new) { | 622 | if (first != new) { |
623 | /* move callback into to last desc */ | 623 | /* move callback into to last desc */ |
@@ -807,6 +807,12 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan) | |||
807 | struct ioat_desc_sw *desc, *_desc; | 807 | struct ioat_desc_sw *desc, *_desc; |
808 | int in_use_descs = 0; | 808 | int in_use_descs = 0; |
809 | 809 | ||
810 | /* Before freeing channel resources first check | ||
811 | * if they have been previously allocated for this channel. | ||
812 | */ | ||
813 | if (ioat_chan->desccount == 0) | ||
814 | return; | ||
815 | |||
810 | tasklet_disable(&ioat_chan->cleanup_task); | 816 | tasklet_disable(&ioat_chan->cleanup_task); |
811 | ioat_dma_memcpy_cleanup(ioat_chan); | 817 | ioat_dma_memcpy_cleanup(ioat_chan); |
812 | 818 | ||
@@ -869,6 +875,7 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan) | |||
869 | ioat_chan->last_completion = ioat_chan->completion_addr = 0; | 875 | ioat_chan->last_completion = ioat_chan->completion_addr = 0; |
870 | ioat_chan->pending = 0; | 876 | ioat_chan->pending = 0; |
871 | ioat_chan->dmacount = 0; | 877 | ioat_chan->dmacount = 0; |
878 | ioat_chan->desccount = 0; | ||
872 | ioat_chan->watchdog_completion = 0; | 879 | ioat_chan->watchdog_completion = 0; |
873 | ioat_chan->last_compl_desc_addr_hw = 0; | 880 | ioat_chan->last_compl_desc_addr_hw = 0; |
874 | ioat_chan->watchdog_tcp_cookie = | 881 | ioat_chan->watchdog_tcp_cookie = |
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c index 71fba82462cb..c7a9306d951d 100644 --- a/drivers/dma/iop-adma.c +++ b/drivers/dma/iop-adma.c | |||
@@ -411,6 +411,7 @@ iop_adma_tx_submit(struct dma_async_tx_descriptor *tx) | |||
411 | int slot_cnt; | 411 | int slot_cnt; |
412 | int slots_per_op; | 412 | int slots_per_op; |
413 | dma_cookie_t cookie; | 413 | dma_cookie_t cookie; |
414 | dma_addr_t next_dma; | ||
414 | 415 | ||
415 | grp_start = sw_desc->group_head; | 416 | grp_start = sw_desc->group_head; |
416 | slot_cnt = grp_start->slot_cnt; | 417 | slot_cnt = grp_start->slot_cnt; |
@@ -425,12 +426,12 @@ iop_adma_tx_submit(struct dma_async_tx_descriptor *tx) | |||
425 | &old_chain_tail->chain_node); | 426 | &old_chain_tail->chain_node); |
426 | 427 | ||
427 | /* fix up the hardware chain */ | 428 | /* fix up the hardware chain */ |
428 | iop_desc_set_next_desc(old_chain_tail, grp_start->async_tx.phys); | 429 | next_dma = grp_start->async_tx.phys; |
430 | iop_desc_set_next_desc(old_chain_tail, next_dma); | ||
431 | BUG_ON(iop_desc_get_next_desc(old_chain_tail) != next_dma); /* flush */ | ||
429 | 432 | ||
430 | /* 1/ don't add pre-chained descriptors | 433 | /* check for pre-chained descriptors */ |
431 | * 2/ dummy read to flush next_desc write | 434 | iop_paranoia(iop_desc_get_next_desc(sw_desc)); |
432 | */ | ||
433 | BUG_ON(iop_desc_get_next_desc(sw_desc)); | ||
434 | 435 | ||
435 | /* increment the pending count by the number of slots | 436 | /* increment the pending count by the number of slots |
436 | * memcpy operations have a 1:1 (slot:operation) relation | 437 | * memcpy operations have a 1:1 (slot:operation) relation |
diff --git a/drivers/dma/iovlock.c b/drivers/dma/iovlock.c index e763d723e4cf..9f6fe46a9b87 100644 --- a/drivers/dma/iovlock.c +++ b/drivers/dma/iovlock.c | |||
@@ -55,7 +55,6 @@ struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len) | |||
55 | int nr_iovecs = 0; | 55 | int nr_iovecs = 0; |
56 | int iovec_len_used = 0; | 56 | int iovec_len_used = 0; |
57 | int iovec_pages_used = 0; | 57 | int iovec_pages_used = 0; |
58 | long err; | ||
59 | 58 | ||
60 | /* don't pin down non-user-based iovecs */ | 59 | /* don't pin down non-user-based iovecs */ |
61 | if (segment_eq(get_fs(), KERNEL_DS)) | 60 | if (segment_eq(get_fs(), KERNEL_DS)) |
@@ -72,23 +71,21 @@ struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len) | |||
72 | local_list = kmalloc(sizeof(*local_list) | 71 | local_list = kmalloc(sizeof(*local_list) |
73 | + (nr_iovecs * sizeof (struct dma_page_list)) | 72 | + (nr_iovecs * sizeof (struct dma_page_list)) |
74 | + (iovec_pages_used * sizeof (struct page*)), GFP_KERNEL); | 73 | + (iovec_pages_used * sizeof (struct page*)), GFP_KERNEL); |
75 | if (!local_list) { | 74 | if (!local_list) |
76 | err = -ENOMEM; | ||
77 | goto out; | 75 | goto out; |
78 | } | ||
79 | 76 | ||
80 | /* list of pages starts right after the page list array */ | 77 | /* list of pages starts right after the page list array */ |
81 | pages = (struct page **) &local_list->page_list[nr_iovecs]; | 78 | pages = (struct page **) &local_list->page_list[nr_iovecs]; |
82 | 79 | ||
80 | local_list->nr_iovecs = 0; | ||
81 | |||
83 | for (i = 0; i < nr_iovecs; i++) { | 82 | for (i = 0; i < nr_iovecs; i++) { |
84 | struct dma_page_list *page_list = &local_list->page_list[i]; | 83 | struct dma_page_list *page_list = &local_list->page_list[i]; |
85 | 84 | ||
86 | len -= iov[i].iov_len; | 85 | len -= iov[i].iov_len; |
87 | 86 | ||
88 | if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len)) { | 87 | if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len)) |
89 | err = -EFAULT; | ||
90 | goto unpin; | 88 | goto unpin; |
91 | } | ||
92 | 89 | ||
93 | page_list->nr_pages = num_pages_spanned(&iov[i]); | 90 | page_list->nr_pages = num_pages_spanned(&iov[i]); |
94 | page_list->base_address = iov[i].iov_base; | 91 | page_list->base_address = iov[i].iov_base; |
@@ -109,10 +106,8 @@ struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len) | |||
109 | NULL); | 106 | NULL); |
110 | up_read(¤t->mm->mmap_sem); | 107 | up_read(¤t->mm->mmap_sem); |
111 | 108 | ||
112 | if (ret != page_list->nr_pages) { | 109 | if (ret != page_list->nr_pages) |
113 | err = -ENOMEM; | ||
114 | goto unpin; | 110 | goto unpin; |
115 | } | ||
116 | 111 | ||
117 | local_list->nr_iovecs = i + 1; | 112 | local_list->nr_iovecs = i + 1; |
118 | } | 113 | } |
@@ -122,7 +117,7 @@ struct dma_pinned_list *dma_pin_iovec_pages(struct iovec *iov, size_t len) | |||
122 | unpin: | 117 | unpin: |
123 | dma_unpin_iovec_pages(local_list); | 118 | dma_unpin_iovec_pages(local_list); |
124 | out: | 119 | out: |
125 | return ERR_PTR(err); | 120 | return NULL; |
126 | } | 121 | } |
127 | 122 | ||
128 | void dma_unpin_iovec_pages(struct dma_pinned_list *pinned_list) | 123 | void dma_unpin_iovec_pages(struct dma_pinned_list *pinned_list) |
diff --git a/drivers/edac/i5000_edac.c b/drivers/edac/i5000_edac.c index f0d9b415db50..d335086f4a26 100644 --- a/drivers/edac/i5000_edac.c +++ b/drivers/edac/i5000_edac.c | |||
@@ -1381,6 +1381,7 @@ static int i5000_probe1(struct pci_dev *pdev, int dev_idx) | |||
1381 | if (mci == NULL) | 1381 | if (mci == NULL) |
1382 | return -ENOMEM; | 1382 | return -ENOMEM; |
1383 | 1383 | ||
1384 | kobject_get(&mci->edac_mci_kobj); | ||
1384 | debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); | 1385 | debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); |
1385 | 1386 | ||
1386 | mci->dev = &pdev->dev; /* record ptr to the generic device */ | 1387 | mci->dev = &pdev->dev; /* record ptr to the generic device */ |
@@ -1453,6 +1454,7 @@ fail1: | |||
1453 | i5000_put_devices(mci); | 1454 | i5000_put_devices(mci); |
1454 | 1455 | ||
1455 | fail0: | 1456 | fail0: |
1457 | kobject_put(&mci->edac_mci_kobj); | ||
1456 | edac_mc_free(mci); | 1458 | edac_mc_free(mci); |
1457 | return -ENODEV; | 1459 | return -ENODEV; |
1458 | } | 1460 | } |
@@ -1498,7 +1500,7 @@ static void __devexit i5000_remove_one(struct pci_dev *pdev) | |||
1498 | 1500 | ||
1499 | /* retrieve references to resources, and free those resources */ | 1501 | /* retrieve references to resources, and free those resources */ |
1500 | i5000_put_devices(mci); | 1502 | i5000_put_devices(mci); |
1501 | 1503 | kobject_put(&mci->edac_mci_kobj); | |
1502 | edac_mc_free(mci); | 1504 | edac_mc_free(mci); |
1503 | } | 1505 | } |
1504 | 1506 | ||
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c index 3fccdd484100..6b9be42c7b98 100644 --- a/drivers/firewire/fw-device.c +++ b/drivers/firewire/fw-device.c | |||
@@ -587,8 +587,7 @@ static void create_units(struct fw_device *device) | |||
587 | unit->device.bus = &fw_bus_type; | 587 | unit->device.bus = &fw_bus_type; |
588 | unit->device.type = &fw_unit_type; | 588 | unit->device.type = &fw_unit_type; |
589 | unit->device.parent = &device->device; | 589 | unit->device.parent = &device->device; |
590 | snprintf(unit->device.bus_id, sizeof(unit->device.bus_id), | 590 | dev_set_name(&unit->device, "%s.%d", dev_name(&device->device), i++); |
591 | "%s.%d", device->device.bus_id, i++); | ||
592 | 591 | ||
593 | init_fw_attribute_group(&unit->device, | 592 | init_fw_attribute_group(&unit->device, |
594 | fw_unit_attributes, | 593 | fw_unit_attributes, |
@@ -711,8 +710,7 @@ static void fw_device_init(struct work_struct *work) | |||
711 | device->device.type = &fw_device_type; | 710 | device->device.type = &fw_device_type; |
712 | device->device.parent = device->card->device; | 711 | device->device.parent = device->card->device; |
713 | device->device.devt = MKDEV(fw_cdev_major, minor); | 712 | device->device.devt = MKDEV(fw_cdev_major, minor); |
714 | snprintf(device->device.bus_id, sizeof(device->device.bus_id), | 713 | dev_set_name(&device->device, "fw%d", minor); |
715 | "fw%d", minor); | ||
716 | 714 | ||
717 | init_fw_attribute_group(&device->device, | 715 | init_fw_attribute_group(&device->device, |
718 | fw_device_attributes, | 716 | fw_device_attributes, |
@@ -741,13 +739,13 @@ static void fw_device_init(struct work_struct *work) | |||
741 | if (device->config_rom_retries) | 739 | if (device->config_rom_retries) |
742 | fw_notify("created device %s: GUID %08x%08x, S%d00, " | 740 | fw_notify("created device %s: GUID %08x%08x, S%d00, " |
743 | "%d config ROM retries\n", | 741 | "%d config ROM retries\n", |
744 | device->device.bus_id, | 742 | dev_name(&device->device), |
745 | device->config_rom[3], device->config_rom[4], | 743 | device->config_rom[3], device->config_rom[4], |
746 | 1 << device->max_speed, | 744 | 1 << device->max_speed, |
747 | device->config_rom_retries); | 745 | device->config_rom_retries); |
748 | else | 746 | else |
749 | fw_notify("created device %s: GUID %08x%08x, S%d00\n", | 747 | fw_notify("created device %s: GUID %08x%08x, S%d00\n", |
750 | device->device.bus_id, | 748 | dev_name(&device->device), |
751 | device->config_rom[3], device->config_rom[4], | 749 | device->config_rom[3], device->config_rom[4], |
752 | 1 << device->max_speed); | 750 | 1 << device->max_speed); |
753 | device->config_rom_retries = 0; | 751 | device->config_rom_retries = 0; |
@@ -883,12 +881,12 @@ static void fw_device_refresh(struct work_struct *work) | |||
883 | FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) | 881 | FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) |
884 | goto gone; | 882 | goto gone; |
885 | 883 | ||
886 | fw_notify("refreshed device %s\n", device->device.bus_id); | 884 | fw_notify("refreshed device %s\n", dev_name(&device->device)); |
887 | device->config_rom_retries = 0; | 885 | device->config_rom_retries = 0; |
888 | goto out; | 886 | goto out; |
889 | 887 | ||
890 | give_up: | 888 | give_up: |
891 | fw_notify("giving up on refresh of device %s\n", device->device.bus_id); | 889 | fw_notify("giving up on refresh of device %s\n", dev_name(&device->device)); |
892 | gone: | 890 | gone: |
893 | atomic_set(&device->state, FW_DEVICE_SHUTDOWN); | 891 | atomic_set(&device->state, FW_DEVICE_SHUTDOWN); |
894 | fw_device_shutdown(work); | 892 | fw_device_shutdown(work); |
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 8e16bfbdcb3d..46610b090415 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c | |||
@@ -2468,7 +2468,7 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
2468 | goto fail_self_id; | 2468 | goto fail_self_id; |
2469 | 2469 | ||
2470 | fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n", | 2470 | fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n", |
2471 | dev->dev.bus_id, version >> 16, version & 0xff); | 2471 | dev_name(&dev->dev), version >> 16, version & 0xff); |
2472 | return 0; | 2472 | return 0; |
2473 | 2473 | ||
2474 | fail_self_id: | 2474 | fail_self_id: |
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index d334cac5e1fc..97df6dac3a82 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c | |||
@@ -1135,7 +1135,7 @@ static int sbp2_probe(struct device *dev) | |||
1135 | tgt->unit = unit; | 1135 | tgt->unit = unit; |
1136 | kref_init(&tgt->kref); | 1136 | kref_init(&tgt->kref); |
1137 | INIT_LIST_HEAD(&tgt->lu_list); | 1137 | INIT_LIST_HEAD(&tgt->lu_list); |
1138 | tgt->bus_id = unit->device.bus_id; | 1138 | tgt->bus_id = dev_name(&unit->device); |
1139 | tgt->guid = (u64)device->config_rom[3] << 32 | device->config_rom[4]; | 1139 | tgt->guid = (u64)device->config_rom[3] << 32 | device->config_rom[4]; |
1140 | 1140 | ||
1141 | if (fw_device_enable_phys_dma(device) < 0) | 1141 | if (fw_device_enable_phys_dma(device) < 0) |
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 3e526b6d00cb..8daf4793ac32 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c | |||
@@ -81,9 +81,9 @@ static void dmi_table(u8 *buf, int len, int num, | |||
81 | const struct dmi_header *dm = (const struct dmi_header *)data; | 81 | const struct dmi_header *dm = (const struct dmi_header *)data; |
82 | 82 | ||
83 | /* | 83 | /* |
84 | * We want to know the total length (formated area and strings) | 84 | * We want to know the total length (formatted area and |
85 | * before decoding to make sure we won't run off the table in | 85 | * strings) before decoding to make sure we won't run off the |
86 | * dmi_decode or dmi_string | 86 | * table in dmi_decode or dmi_string |
87 | */ | 87 | */ |
88 | data += dm->length; | 88 | data += dm->length; |
89 | while ((data - buf < len - 1) && (data[0] || data[1])) | 89 | while ((data - buf < len - 1) && (data[0] || data[1])) |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 7f2ee27fe76b..48f49d93d249 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -65,6 +65,14 @@ config GPIO_SYSFS | |||
65 | 65 | ||
66 | # put expanders in the right section, in alphabetical order | 66 | # put expanders in the right section, in alphabetical order |
67 | 67 | ||
68 | comment "Memory mapped GPIO expanders:" | ||
69 | |||
70 | config GPIO_XILINX | ||
71 | bool "Xilinx GPIO support" | ||
72 | depends on PPC_OF | ||
73 | help | ||
74 | Say yes here to support the Xilinx FPGA GPIO device | ||
75 | |||
68 | comment "I2C GPIO expanders:" | 76 | comment "I2C GPIO expanders:" |
69 | 77 | ||
70 | config GPIO_MAX732X | 78 | config GPIO_MAX732X |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 6aafdeb9ad03..49ac64e515e6 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -10,4 +10,5 @@ obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o | |||
10 | obj-$(CONFIG_GPIO_PCA953X) += pca953x.o | 10 | obj-$(CONFIG_GPIO_PCA953X) += pca953x.o |
11 | obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o | 11 | obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o |
12 | obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o | 12 | obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o |
13 | obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o | ||
13 | obj-$(CONFIG_GPIO_BT8XX) += bt8xxgpio.o | 14 | obj-$(CONFIG_GPIO_BT8XX) += bt8xxgpio.o |
diff --git a/drivers/gpio/xilinx_gpio.c b/drivers/gpio/xilinx_gpio.c new file mode 100644 index 000000000000..3c1177abebd3 --- /dev/null +++ b/drivers/gpio/xilinx_gpio.c | |||
@@ -0,0 +1,235 @@ | |||
1 | /* | ||
2 | * Xilinx gpio driver | ||
3 | * | ||
4 | * Copyright 2008 Xilinx, Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * You should have received a copy of the GNU General Public License | ||
11 | * along with this program; if not, write to the Free Software | ||
12 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
13 | */ | ||
14 | |||
15 | #include <linux/init.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/of_device.h> | ||
18 | #include <linux/of_platform.h> | ||
19 | #include <linux/of_gpio.h> | ||
20 | #include <linux/io.h> | ||
21 | #include <linux/gpio.h> | ||
22 | |||
23 | /* Register Offset Definitions */ | ||
24 | #define XGPIO_DATA_OFFSET (0x0) /* Data register */ | ||
25 | #define XGPIO_TRI_OFFSET (0x4) /* I/O direction register */ | ||
26 | |||
27 | struct xgpio_instance { | ||
28 | struct of_mm_gpio_chip mmchip; | ||
29 | u32 gpio_state; /* GPIO state shadow register */ | ||
30 | u32 gpio_dir; /* GPIO direction shadow register */ | ||
31 | spinlock_t gpio_lock; /* Lock used for synchronization */ | ||
32 | }; | ||
33 | |||
34 | /** | ||
35 | * xgpio_get - Read the specified signal of the GPIO device. | ||
36 | * @gc: Pointer to gpio_chip device structure. | ||
37 | * @gpio: GPIO signal number. | ||
38 | * | ||
39 | * This function reads the specified signal of the GPIO device. It returns 0 if | ||
40 | * the signal clear, 1 if signal is set or negative value on error. | ||
41 | */ | ||
42 | static int xgpio_get(struct gpio_chip *gc, unsigned int gpio) | ||
43 | { | ||
44 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | ||
45 | |||
46 | return (in_be32(mm_gc->regs + XGPIO_DATA_OFFSET) >> gpio) & 1; | ||
47 | } | ||
48 | |||
49 | /** | ||
50 | * xgpio_set - Write the specified signal of the GPIO device. | ||
51 | * @gc: Pointer to gpio_chip device structure. | ||
52 | * @gpio: GPIO signal number. | ||
53 | * @val: Value to be written to specified signal. | ||
54 | * | ||
55 | * This function writes the specified value in to the specified signal of the | ||
56 | * GPIO device. | ||
57 | */ | ||
58 | static void xgpio_set(struct gpio_chip *gc, unsigned int gpio, int val) | ||
59 | { | ||
60 | unsigned long flags; | ||
61 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | ||
62 | struct xgpio_instance *chip = | ||
63 | container_of(mm_gc, struct xgpio_instance, mmchip); | ||
64 | |||
65 | spin_lock_irqsave(&chip->gpio_lock, flags); | ||
66 | |||
67 | /* Write to GPIO signal and set its direction to output */ | ||
68 | if (val) | ||
69 | chip->gpio_state |= 1 << gpio; | ||
70 | else | ||
71 | chip->gpio_state &= ~(1 << gpio); | ||
72 | out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state); | ||
73 | |||
74 | spin_unlock_irqrestore(&chip->gpio_lock, flags); | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * xgpio_dir_in - Set the direction of the specified GPIO signal as input. | ||
79 | * @gc: Pointer to gpio_chip device structure. | ||
80 | * @gpio: GPIO signal number. | ||
81 | * | ||
82 | * This function sets the direction of specified GPIO signal as input. | ||
83 | * It returns 0 if direction of GPIO signals is set as input otherwise it | ||
84 | * returns negative error value. | ||
85 | */ | ||
86 | static int xgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) | ||
87 | { | ||
88 | unsigned long flags; | ||
89 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | ||
90 | struct xgpio_instance *chip = | ||
91 | container_of(mm_gc, struct xgpio_instance, mmchip); | ||
92 | |||
93 | spin_lock_irqsave(&chip->gpio_lock, flags); | ||
94 | |||
95 | /* Set the GPIO bit in shadow register and set direction as input */ | ||
96 | chip->gpio_dir |= (1 << gpio); | ||
97 | out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir); | ||
98 | |||
99 | spin_unlock_irqrestore(&chip->gpio_lock, flags); | ||
100 | |||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | /** | ||
105 | * xgpio_dir_out - Set the direction of the specified GPIO signal as output. | ||
106 | * @gc: Pointer to gpio_chip device structure. | ||
107 | * @gpio: GPIO signal number. | ||
108 | * @val: Value to be written to specified signal. | ||
109 | * | ||
110 | * This function sets the direction of specified GPIO signal as output. If all | ||
111 | * GPIO signals of GPIO chip is configured as input then it returns | ||
112 | * error otherwise it returns 0. | ||
113 | */ | ||
114 | static int xgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | ||
115 | { | ||
116 | unsigned long flags; | ||
117 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | ||
118 | struct xgpio_instance *chip = | ||
119 | container_of(mm_gc, struct xgpio_instance, mmchip); | ||
120 | |||
121 | spin_lock_irqsave(&chip->gpio_lock, flags); | ||
122 | |||
123 | /* Write state of GPIO signal */ | ||
124 | if (val) | ||
125 | chip->gpio_state |= 1 << gpio; | ||
126 | else | ||
127 | chip->gpio_state &= ~(1 << gpio); | ||
128 | out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state); | ||
129 | |||
130 | /* Clear the GPIO bit in shadow register and set direction as output */ | ||
131 | chip->gpio_dir &= (~(1 << gpio)); | ||
132 | out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir); | ||
133 | |||
134 | spin_unlock_irqrestore(&chip->gpio_lock, flags); | ||
135 | |||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | /** | ||
140 | * xgpio_save_regs - Set initial values of GPIO pins | ||
141 | * @mm_gc: pointer to memory mapped GPIO chip structure | ||
142 | */ | ||
143 | static void xgpio_save_regs(struct of_mm_gpio_chip *mm_gc) | ||
144 | { | ||
145 | struct xgpio_instance *chip = | ||
146 | container_of(mm_gc, struct xgpio_instance, mmchip); | ||
147 | |||
148 | out_be32(mm_gc->regs + XGPIO_DATA_OFFSET, chip->gpio_state); | ||
149 | out_be32(mm_gc->regs + XGPIO_TRI_OFFSET, chip->gpio_dir); | ||
150 | } | ||
151 | |||
152 | /** | ||
153 | * xgpio_of_probe - Probe method for the GPIO device. | ||
154 | * @np: pointer to device tree node | ||
155 | * | ||
156 | * This function probes the GPIO device in the device tree. It initializes the | ||
157 | * driver data structure. It returns 0, if the driver is bound to the GPIO | ||
158 | * device, or a negative value if there is an error. | ||
159 | */ | ||
160 | static int __devinit xgpio_of_probe(struct device_node *np) | ||
161 | { | ||
162 | struct xgpio_instance *chip; | ||
163 | struct of_gpio_chip *ofchip; | ||
164 | int status = 0; | ||
165 | const u32 *tree_info; | ||
166 | |||
167 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
168 | if (!chip) | ||
169 | return -ENOMEM; | ||
170 | ofchip = &chip->mmchip.of_gc; | ||
171 | |||
172 | /* Update GPIO state shadow register with default value */ | ||
173 | tree_info = of_get_property(np, "xlnx,dout-default", NULL); | ||
174 | if (tree_info) | ||
175 | chip->gpio_state = *tree_info; | ||
176 | |||
177 | /* Update GPIO direction shadow register with default value */ | ||
178 | chip->gpio_dir = 0xFFFFFFFF; /* By default, all pins are inputs */ | ||
179 | tree_info = of_get_property(np, "xlnx,tri-default", NULL); | ||
180 | if (tree_info) | ||
181 | chip->gpio_dir = *tree_info; | ||
182 | |||
183 | /* Check device node and parent device node for device width */ | ||
184 | ofchip->gc.ngpio = 32; /* By default assume full GPIO controller */ | ||
185 | tree_info = of_get_property(np, "xlnx,gpio-width", NULL); | ||
186 | if (!tree_info) | ||
187 | tree_info = of_get_property(np->parent, | ||
188 | "xlnx,gpio-width", NULL); | ||
189 | if (tree_info) | ||
190 | ofchip->gc.ngpio = *tree_info; | ||
191 | |||
192 | spin_lock_init(&chip->gpio_lock); | ||
193 | |||
194 | ofchip->gpio_cells = 2; | ||
195 | ofchip->gc.direction_input = xgpio_dir_in; | ||
196 | ofchip->gc.direction_output = xgpio_dir_out; | ||
197 | ofchip->gc.get = xgpio_get; | ||
198 | ofchip->gc.set = xgpio_set; | ||
199 | |||
200 | chip->mmchip.save_regs = xgpio_save_regs; | ||
201 | |||
202 | /* Call the OF gpio helper to setup and register the GPIO device */ | ||
203 | status = of_mm_gpiochip_add(np, &chip->mmchip); | ||
204 | if (status) { | ||
205 | kfree(chip); | ||
206 | pr_err("%s: error in probe function with status %d\n", | ||
207 | np->full_name, status); | ||
208 | return status; | ||
209 | } | ||
210 | pr_info("XGpio: %s: registered\n", np->full_name); | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | static struct of_device_id xgpio_of_match[] __devinitdata = { | ||
215 | { .compatible = "xlnx,xps-gpio-1.00.a", }, | ||
216 | { /* end of list */ }, | ||
217 | }; | ||
218 | |||
219 | static int __init xgpio_init(void) | ||
220 | { | ||
221 | struct device_node *np; | ||
222 | |||
223 | for_each_matching_node(np, xgpio_of_match) | ||
224 | xgpio_of_probe(np); | ||
225 | |||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | /* Make sure we get initialized before anyone else tries to use us */ | ||
230 | subsys_initcall(xgpio_init); | ||
231 | /* No exit call at the moment as we cannot unregister of GPIO chips */ | ||
232 | |||
233 | MODULE_AUTHOR("Xilinx, Inc."); | ||
234 | MODULE_DESCRIPTION("Xilinx GPIO driver"); | ||
235 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 96f416afc3f6..3ab1e9cc4692 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -266,11 +266,19 @@ int drm_init(struct drm_driver *driver) | |||
266 | for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) { | 266 | for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) { |
267 | pid = (struct pci_device_id *)&driver->pci_driver.id_table[i]; | 267 | pid = (struct pci_device_id *)&driver->pci_driver.id_table[i]; |
268 | 268 | ||
269 | /* Loop around setting up a DRM device for each PCI device | ||
270 | * matching our ID and device class. If we had the internal | ||
271 | * function that pci_get_subsys and pci_get_class used, we'd | ||
272 | * be able to just pass pid in instead of doing a two-stage | ||
273 | * thing. | ||
274 | */ | ||
269 | pdev = NULL; | 275 | pdev = NULL; |
270 | /* pass back in pdev to account for multiple identical cards */ | ||
271 | while ((pdev = | 276 | while ((pdev = |
272 | pci_get_subsys(pid->vendor, pid->device, pid->subvendor, | 277 | pci_get_subsys(pid->vendor, pid->device, pid->subvendor, |
273 | pid->subdevice, pdev)) != NULL) { | 278 | pid->subdevice, pdev)) != NULL) { |
279 | if ((pdev->class & pid->class_mask) != pid->class) | ||
280 | continue; | ||
281 | |||
274 | /* stealth mode requires a manual probe */ | 282 | /* stealth mode requires a manual probe */ |
275 | pci_dev_get(pdev); | 283 | pci_dev_get(pdev); |
276 | drm_get_dev(pdev, pid, driver); | 284 | drm_get_dev(pdev, pid, driver); |
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 212a94f715b2..15c8dabc3e97 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -280,8 +280,6 @@ int drm_irq_uninstall(struct drm_device * dev) | |||
280 | 280 | ||
281 | drm_vblank_cleanup(dev); | 281 | drm_vblank_cleanup(dev); |
282 | 282 | ||
283 | dev->locked_tasklet_func = NULL; | ||
284 | |||
285 | return 0; | 283 | return 0; |
286 | } | 284 | } |
287 | EXPORT_SYMBOL(drm_irq_uninstall); | 285 | EXPORT_SYMBOL(drm_irq_uninstall); |
@@ -699,81 +697,3 @@ void drm_handle_vblank(struct drm_device *dev, int crtc) | |||
699 | drm_vbl_send_signals(dev, crtc); | 697 | drm_vbl_send_signals(dev, crtc); |
700 | } | 698 | } |
701 | EXPORT_SYMBOL(drm_handle_vblank); | 699 | EXPORT_SYMBOL(drm_handle_vblank); |
702 | |||
703 | /** | ||
704 | * Tasklet wrapper function. | ||
705 | * | ||
706 | * \param data DRM device in disguise. | ||
707 | * | ||
708 | * Attempts to grab the HW lock and calls the driver callback on success. On | ||
709 | * failure, leave the lock marked as contended so the callback can be called | ||
710 | * from drm_unlock(). | ||
711 | */ | ||
712 | static void drm_locked_tasklet_func(unsigned long data) | ||
713 | { | ||
714 | struct drm_device *dev = (struct drm_device *)data; | ||
715 | unsigned long irqflags; | ||
716 | void (*tasklet_func)(struct drm_device *); | ||
717 | |||
718 | spin_lock_irqsave(&dev->tasklet_lock, irqflags); | ||
719 | tasklet_func = dev->locked_tasklet_func; | ||
720 | spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); | ||
721 | |||
722 | if (!tasklet_func || | ||
723 | !drm_lock_take(&dev->lock, | ||
724 | DRM_KERNEL_CONTEXT)) { | ||
725 | return; | ||
726 | } | ||
727 | |||
728 | dev->lock.lock_time = jiffies; | ||
729 | atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); | ||
730 | |||
731 | spin_lock_irqsave(&dev->tasklet_lock, irqflags); | ||
732 | tasklet_func = dev->locked_tasklet_func; | ||
733 | dev->locked_tasklet_func = NULL; | ||
734 | spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); | ||
735 | |||
736 | if (tasklet_func != NULL) | ||
737 | tasklet_func(dev); | ||
738 | |||
739 | drm_lock_free(&dev->lock, | ||
740 | DRM_KERNEL_CONTEXT); | ||
741 | } | ||
742 | |||
743 | /** | ||
744 | * Schedule a tasklet to call back a driver hook with the HW lock held. | ||
745 | * | ||
746 | * \param dev DRM device. | ||
747 | * \param func Driver callback. | ||
748 | * | ||
749 | * This is intended for triggering actions that require the HW lock from an | ||
750 | * interrupt handler. The lock will be grabbed ASAP after the interrupt handler | ||
751 | * completes. Note that the callback may be called from interrupt or process | ||
752 | * context, it must not make any assumptions about this. Also, the HW lock will | ||
753 | * be held with the kernel context or any client context. | ||
754 | */ | ||
755 | void drm_locked_tasklet(struct drm_device *dev, void (*func)(struct drm_device *)) | ||
756 | { | ||
757 | unsigned long irqflags; | ||
758 | static DECLARE_TASKLET(drm_tasklet, drm_locked_tasklet_func, 0); | ||
759 | |||
760 | if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ) || | ||
761 | test_bit(TASKLET_STATE_SCHED, &drm_tasklet.state)) | ||
762 | return; | ||
763 | |||
764 | spin_lock_irqsave(&dev->tasklet_lock, irqflags); | ||
765 | |||
766 | if (dev->locked_tasklet_func) { | ||
767 | spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); | ||
768 | return; | ||
769 | } | ||
770 | |||
771 | dev->locked_tasklet_func = func; | ||
772 | |||
773 | spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); | ||
774 | |||
775 | drm_tasklet.data = (unsigned long)dev; | ||
776 | |||
777 | tasklet_hi_schedule(&drm_tasklet); | ||
778 | } | ||
779 | EXPORT_SYMBOL(drm_locked_tasklet); | ||
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c index 888159e03d26..1cfa72031f8f 100644 --- a/drivers/gpu/drm/drm_lock.c +++ b/drivers/gpu/drm/drm_lock.c | |||
@@ -154,8 +154,6 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
154 | int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv) | 154 | int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv) |
155 | { | 155 | { |
156 | struct drm_lock *lock = data; | 156 | struct drm_lock *lock = data; |
157 | unsigned long irqflags; | ||
158 | void (*tasklet_func)(struct drm_device *); | ||
159 | 157 | ||
160 | if (lock->context == DRM_KERNEL_CONTEXT) { | 158 | if (lock->context == DRM_KERNEL_CONTEXT) { |
161 | DRM_ERROR("Process %d using kernel context %d\n", | 159 | DRM_ERROR("Process %d using kernel context %d\n", |
@@ -163,13 +161,6 @@ int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
163 | return -EINVAL; | 161 | return -EINVAL; |
164 | } | 162 | } |
165 | 163 | ||
166 | spin_lock_irqsave(&dev->tasklet_lock, irqflags); | ||
167 | tasklet_func = dev->locked_tasklet_func; | ||
168 | dev->locked_tasklet_func = NULL; | ||
169 | spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); | ||
170 | if (tasklet_func != NULL) | ||
171 | tasklet_func(dev); | ||
172 | |||
173 | atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]); | 164 | atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]); |
174 | 165 | ||
175 | /* kernel_context_switch isn't used by any of the x86 drm | 166 | /* kernel_context_switch isn't used by any of the x86 drm |
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 141e33004a76..66c96ec66672 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
@@ -92,7 +92,6 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev, | |||
92 | 92 | ||
93 | spin_lock_init(&dev->count_lock); | 93 | spin_lock_init(&dev->count_lock); |
94 | spin_lock_init(&dev->drw_lock); | 94 | spin_lock_init(&dev->drw_lock); |
95 | spin_lock_init(&dev->tasklet_lock); | ||
96 | spin_lock_init(&dev->lock.spinlock); | 95 | spin_lock_init(&dev->lock.spinlock); |
97 | init_timer(&dev->timer); | 96 | init_timer(&dev->timer); |
98 | mutex_init(&dev->struct_mutex); | 97 | mutex_init(&dev->struct_mutex); |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 256e22963ae4..0d215e38606a 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -154,6 +154,9 @@ static int i915_dma_cleanup(struct drm_device * dev) | |||
154 | if (I915_NEED_GFX_HWS(dev)) | 154 | if (I915_NEED_GFX_HWS(dev)) |
155 | i915_free_hws(dev); | 155 | i915_free_hws(dev); |
156 | 156 | ||
157 | dev_priv->sarea = NULL; | ||
158 | dev_priv->sarea_priv = NULL; | ||
159 | |||
157 | return 0; | 160 | return 0; |
158 | } | 161 | } |
159 | 162 | ||
@@ -442,7 +445,7 @@ static void i915_emit_breadcrumb(struct drm_device *dev) | |||
442 | 445 | ||
443 | BEGIN_LP_RING(4); | 446 | BEGIN_LP_RING(4); |
444 | OUT_RING(MI_STORE_DWORD_INDEX); | 447 | OUT_RING(MI_STORE_DWORD_INDEX); |
445 | OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT); | 448 | OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); |
446 | OUT_RING(dev_priv->counter); | 449 | OUT_RING(dev_priv->counter); |
447 | OUT_RING(0); | 450 | OUT_RING(0); |
448 | ADVANCE_LP_RING(); | 451 | ADVANCE_LP_RING(); |
@@ -573,7 +576,7 @@ static int i915_dispatch_flip(struct drm_device * dev) | |||
573 | 576 | ||
574 | BEGIN_LP_RING(4); | 577 | BEGIN_LP_RING(4); |
575 | OUT_RING(MI_STORE_DWORD_INDEX); | 578 | OUT_RING(MI_STORE_DWORD_INDEX); |
576 | OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT); | 579 | OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); |
577 | OUT_RING(dev_priv->counter); | 580 | OUT_RING(dev_priv->counter); |
578 | OUT_RING(0); | 581 | OUT_RING(0); |
579 | ADVANCE_LP_RING(); | 582 | ADVANCE_LP_RING(); |
@@ -608,7 +611,6 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, | |||
608 | struct drm_file *file_priv) | 611 | struct drm_file *file_priv) |
609 | { | 612 | { |
610 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 613 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
611 | u32 *hw_status = dev_priv->hw_status_page; | ||
612 | drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) | 614 | drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) |
613 | dev_priv->sarea_priv; | 615 | dev_priv->sarea_priv; |
614 | drm_i915_batchbuffer_t *batch = data; | 616 | drm_i915_batchbuffer_t *batch = data; |
@@ -634,7 +636,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, | |||
634 | mutex_unlock(&dev->struct_mutex); | 636 | mutex_unlock(&dev->struct_mutex); |
635 | 637 | ||
636 | if (sarea_priv) | 638 | if (sarea_priv) |
637 | sarea_priv->last_dispatch = (int)hw_status[5]; | 639 | sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); |
638 | return ret; | 640 | return ret; |
639 | } | 641 | } |
640 | 642 | ||
@@ -642,7 +644,6 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, | |||
642 | struct drm_file *file_priv) | 644 | struct drm_file *file_priv) |
643 | { | 645 | { |
644 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 646 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
645 | u32 *hw_status = dev_priv->hw_status_page; | ||
646 | drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) | 647 | drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) |
647 | dev_priv->sarea_priv; | 648 | dev_priv->sarea_priv; |
648 | drm_i915_cmdbuffer_t *cmdbuf = data; | 649 | drm_i915_cmdbuffer_t *cmdbuf = data; |
@@ -670,7 +671,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, | |||
670 | } | 671 | } |
671 | 672 | ||
672 | if (sarea_priv) | 673 | if (sarea_priv) |
673 | sarea_priv->last_dispatch = (int)hw_status[5]; | 674 | sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); |
674 | return 0; | 675 | return 0; |
675 | } | 676 | } |
676 | 677 | ||
@@ -849,8 +850,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
849 | * be lost or delayed | 850 | * be lost or delayed |
850 | */ | 851 | */ |
851 | if (!IS_I945G(dev) && !IS_I945GM(dev) && !IS_I965GM(dev)) | 852 | if (!IS_I945G(dev) && !IS_I945GM(dev) && !IS_I965GM(dev)) |
852 | if (pci_enable_msi(dev->pdev)) | 853 | pci_enable_msi(dev->pdev); |
853 | DRM_ERROR("failed to enable MSI\n"); | ||
854 | 854 | ||
855 | intel_opregion_init(dev); | 855 | intel_opregion_init(dev); |
856 | 856 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 572dcd0e3e0d..ef1c0b8f8d07 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -88,13 +88,6 @@ struct mem_block { | |||
88 | struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */ | 88 | struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */ |
89 | }; | 89 | }; |
90 | 90 | ||
91 | typedef struct _drm_i915_vbl_swap { | ||
92 | struct list_head head; | ||
93 | drm_drawable_t drw_id; | ||
94 | unsigned int pipe; | ||
95 | unsigned int sequence; | ||
96 | } drm_i915_vbl_swap_t; | ||
97 | |||
98 | struct opregion_header; | 91 | struct opregion_header; |
99 | struct opregion_acpi; | 92 | struct opregion_acpi; |
100 | struct opregion_swsci; | 93 | struct opregion_swsci; |
@@ -146,10 +139,6 @@ typedef struct drm_i915_private { | |||
146 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; | 139 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; |
147 | int vblank_pipe; | 140 | int vblank_pipe; |
148 | 141 | ||
149 | spinlock_t swaps_lock; | ||
150 | drm_i915_vbl_swap_t vbl_swaps; | ||
151 | unsigned int swaps_pending; | ||
152 | |||
153 | struct intel_opregion opregion; | 142 | struct intel_opregion opregion; |
154 | 143 | ||
155 | /* Register state */ | 144 | /* Register state */ |
@@ -157,6 +146,7 @@ typedef struct drm_i915_private { | |||
157 | u32 saveDSPACNTR; | 146 | u32 saveDSPACNTR; |
158 | u32 saveDSPBCNTR; | 147 | u32 saveDSPBCNTR; |
159 | u32 saveDSPARB; | 148 | u32 saveDSPARB; |
149 | u32 saveRENDERSTANDBY; | ||
160 | u32 savePIPEACONF; | 150 | u32 savePIPEACONF; |
161 | u32 savePIPEBCONF; | 151 | u32 savePIPEBCONF; |
162 | u32 savePIPEASRC; | 152 | u32 savePIPEASRC; |
@@ -241,9 +231,6 @@ typedef struct drm_i915_private { | |||
241 | u8 saveDACDATA[256*3]; /* 256 3-byte colors */ | 231 | u8 saveDACDATA[256*3]; /* 256 3-byte colors */ |
242 | u8 saveCR[37]; | 232 | u8 saveCR[37]; |
243 | 233 | ||
244 | /** Work task for vblank-related ring access */ | ||
245 | struct work_struct vblank_work; | ||
246 | |||
247 | struct { | 234 | struct { |
248 | struct drm_mm gtt_space; | 235 | struct drm_mm gtt_space; |
249 | 236 | ||
@@ -444,7 +431,6 @@ extern int i915_irq_wait(struct drm_device *dev, void *data, | |||
444 | void i915_user_irq_get(struct drm_device *dev); | 431 | void i915_user_irq_get(struct drm_device *dev); |
445 | void i915_user_irq_put(struct drm_device *dev); | 432 | void i915_user_irq_put(struct drm_device *dev); |
446 | 433 | ||
447 | extern void i915_vblank_work_handler(struct work_struct *work); | ||
448 | extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); | 434 | extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); |
449 | extern void i915_driver_irq_preinstall(struct drm_device * dev); | 435 | extern void i915_driver_irq_preinstall(struct drm_device * dev); |
450 | extern int i915_driver_irq_postinstall(struct drm_device *dev); | 436 | extern int i915_driver_irq_postinstall(struct drm_device *dev); |
@@ -622,8 +608,9 @@ static inline void opregion_enable_asle(struct drm_device *dev) { return; } | |||
622 | * The area from dword 0x20 to 0x3ff is available for driver usage. | 608 | * The area from dword 0x20 to 0x3ff is available for driver usage. |
623 | */ | 609 | */ |
624 | #define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) | 610 | #define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg]) |
625 | #define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, 5) | 611 | #define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX) |
626 | #define I915_GEM_HWS_INDEX 0x20 | 612 | #define I915_GEM_HWS_INDEX 0x20 |
613 | #define I915_BREADCRUMB_INDEX 0x21 | ||
627 | 614 | ||
628 | extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | 615 | extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); |
629 | 616 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b0ec73fa6a93..6b4a2bd20640 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1455,11 +1455,9 @@ i915_gem_object_set_domain_range(struct drm_gem_object *obj, | |||
1455 | read_domains, write_domain); | 1455 | read_domains, write_domain); |
1456 | 1456 | ||
1457 | /* Wait on any GPU rendering to the object to be flushed. */ | 1457 | /* Wait on any GPU rendering to the object to be flushed. */ |
1458 | if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) { | 1458 | ret = i915_gem_object_wait_rendering(obj); |
1459 | ret = i915_gem_object_wait_rendering(obj); | 1459 | if (ret) |
1460 | if (ret) | 1460 | return ret; |
1461 | return ret; | ||
1462 | } | ||
1463 | 1461 | ||
1464 | if (obj_priv->page_cpu_valid == NULL) { | 1462 | if (obj_priv->page_cpu_valid == NULL) { |
1465 | obj_priv->page_cpu_valid = drm_calloc(1, obj->size / PAGE_SIZE, | 1463 | obj_priv->page_cpu_valid = drm_calloc(1, obj->size / PAGE_SIZE, |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 26f48932a51e..82752d6177a4 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -80,211 +80,6 @@ i915_pipe_enabled(struct drm_device *dev, int pipe) | |||
80 | return 0; | 80 | return 0; |
81 | } | 81 | } |
82 | 82 | ||
83 | /** | ||
84 | * Emit blits for scheduled buffer swaps. | ||
85 | * | ||
86 | * This function will be called with the HW lock held. | ||
87 | * Because this function must grab the ring mutex (dev->struct_mutex), | ||
88 | * it can no longer run at soft irq time. We'll fix this when we do | ||
89 | * the DRI2 swap buffer work. | ||
90 | */ | ||
91 | static void i915_vblank_tasklet(struct drm_device *dev) | ||
92 | { | ||
93 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
94 | unsigned long irqflags; | ||
95 | struct list_head *list, *tmp, hits, *hit; | ||
96 | int nhits, nrects, slice[2], upper[2], lower[2], i; | ||
97 | unsigned counter[2]; | ||
98 | struct drm_drawable_info *drw; | ||
99 | drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv; | ||
100 | u32 cpp = dev_priv->cpp; | ||
101 | u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD | | ||
102 | XY_SRC_COPY_BLT_WRITE_ALPHA | | ||
103 | XY_SRC_COPY_BLT_WRITE_RGB) | ||
104 | : XY_SRC_COPY_BLT_CMD; | ||
105 | u32 src_pitch = sarea_priv->pitch * cpp; | ||
106 | u32 dst_pitch = sarea_priv->pitch * cpp; | ||
107 | u32 ropcpp = (0xcc << 16) | ((cpp - 1) << 24); | ||
108 | RING_LOCALS; | ||
109 | |||
110 | mutex_lock(&dev->struct_mutex); | ||
111 | |||
112 | if (IS_I965G(dev) && sarea_priv->front_tiled) { | ||
113 | cmd |= XY_SRC_COPY_BLT_DST_TILED; | ||
114 | dst_pitch >>= 2; | ||
115 | } | ||
116 | if (IS_I965G(dev) && sarea_priv->back_tiled) { | ||
117 | cmd |= XY_SRC_COPY_BLT_SRC_TILED; | ||
118 | src_pitch >>= 2; | ||
119 | } | ||
120 | |||
121 | counter[0] = drm_vblank_count(dev, 0); | ||
122 | counter[1] = drm_vblank_count(dev, 1); | ||
123 | |||
124 | DRM_DEBUG("\n"); | ||
125 | |||
126 | INIT_LIST_HEAD(&hits); | ||
127 | |||
128 | nhits = nrects = 0; | ||
129 | |||
130 | spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); | ||
131 | |||
132 | /* Find buffer swaps scheduled for this vertical blank */ | ||
133 | list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) { | ||
134 | drm_i915_vbl_swap_t *vbl_swap = | ||
135 | list_entry(list, drm_i915_vbl_swap_t, head); | ||
136 | int pipe = vbl_swap->pipe; | ||
137 | |||
138 | if ((counter[pipe] - vbl_swap->sequence) > (1<<23)) | ||
139 | continue; | ||
140 | |||
141 | list_del(list); | ||
142 | dev_priv->swaps_pending--; | ||
143 | drm_vblank_put(dev, pipe); | ||
144 | |||
145 | spin_unlock(&dev_priv->swaps_lock); | ||
146 | spin_lock(&dev->drw_lock); | ||
147 | |||
148 | drw = drm_get_drawable_info(dev, vbl_swap->drw_id); | ||
149 | |||
150 | list_for_each(hit, &hits) { | ||
151 | drm_i915_vbl_swap_t *swap_cmp = | ||
152 | list_entry(hit, drm_i915_vbl_swap_t, head); | ||
153 | struct drm_drawable_info *drw_cmp = | ||
154 | drm_get_drawable_info(dev, swap_cmp->drw_id); | ||
155 | |||
156 | /* Make sure both drawables are still | ||
157 | * around and have some rectangles before | ||
158 | * we look inside to order them for the | ||
159 | * blts below. | ||
160 | */ | ||
161 | if (drw_cmp && drw_cmp->num_rects > 0 && | ||
162 | drw && drw->num_rects > 0 && | ||
163 | drw_cmp->rects[0].y1 > drw->rects[0].y1) { | ||
164 | list_add_tail(list, hit); | ||
165 | break; | ||
166 | } | ||
167 | } | ||
168 | |||
169 | spin_unlock(&dev->drw_lock); | ||
170 | |||
171 | /* List of hits was empty, or we reached the end of it */ | ||
172 | if (hit == &hits) | ||
173 | list_add_tail(list, hits.prev); | ||
174 | |||
175 | nhits++; | ||
176 | |||
177 | spin_lock(&dev_priv->swaps_lock); | ||
178 | } | ||
179 | |||
180 | if (nhits == 0) { | ||
181 | spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); | ||
182 | mutex_unlock(&dev->struct_mutex); | ||
183 | return; | ||
184 | } | ||
185 | |||
186 | spin_unlock(&dev_priv->swaps_lock); | ||
187 | |||
188 | i915_kernel_lost_context(dev); | ||
189 | |||
190 | if (IS_I965G(dev)) { | ||
191 | BEGIN_LP_RING(4); | ||
192 | |||
193 | OUT_RING(GFX_OP_DRAWRECT_INFO_I965); | ||
194 | OUT_RING(0); | ||
195 | OUT_RING(((sarea_priv->width - 1) & 0xffff) | ((sarea_priv->height - 1) << 16)); | ||
196 | OUT_RING(0); | ||
197 | ADVANCE_LP_RING(); | ||
198 | } else { | ||
199 | BEGIN_LP_RING(6); | ||
200 | |||
201 | OUT_RING(GFX_OP_DRAWRECT_INFO); | ||
202 | OUT_RING(0); | ||
203 | OUT_RING(0); | ||
204 | OUT_RING(sarea_priv->width | sarea_priv->height << 16); | ||
205 | OUT_RING(sarea_priv->width | sarea_priv->height << 16); | ||
206 | OUT_RING(0); | ||
207 | |||
208 | ADVANCE_LP_RING(); | ||
209 | } | ||
210 | |||
211 | sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT; | ||
212 | |||
213 | upper[0] = upper[1] = 0; | ||
214 | slice[0] = max(sarea_priv->pipeA_h / nhits, 1); | ||
215 | slice[1] = max(sarea_priv->pipeB_h / nhits, 1); | ||
216 | lower[0] = sarea_priv->pipeA_y + slice[0]; | ||
217 | lower[1] = sarea_priv->pipeB_y + slice[0]; | ||
218 | |||
219 | spin_lock(&dev->drw_lock); | ||
220 | |||
221 | /* Emit blits for buffer swaps, partitioning both outputs into as many | ||
222 | * slices as there are buffer swaps scheduled in order to avoid tearing | ||
223 | * (based on the assumption that a single buffer swap would always | ||
224 | * complete before scanout starts). | ||
225 | */ | ||
226 | for (i = 0; i++ < nhits; | ||
227 | upper[0] = lower[0], lower[0] += slice[0], | ||
228 | upper[1] = lower[1], lower[1] += slice[1]) { | ||
229 | if (i == nhits) | ||
230 | lower[0] = lower[1] = sarea_priv->height; | ||
231 | |||
232 | list_for_each(hit, &hits) { | ||
233 | drm_i915_vbl_swap_t *swap_hit = | ||
234 | list_entry(hit, drm_i915_vbl_swap_t, head); | ||
235 | struct drm_clip_rect *rect; | ||
236 | int num_rects, pipe; | ||
237 | unsigned short top, bottom; | ||
238 | |||
239 | drw = drm_get_drawable_info(dev, swap_hit->drw_id); | ||
240 | |||
241 | /* The drawable may have been destroyed since | ||
242 | * the vblank swap was queued | ||
243 | */ | ||
244 | if (!drw) | ||
245 | continue; | ||
246 | |||
247 | rect = drw->rects; | ||
248 | pipe = swap_hit->pipe; | ||
249 | top = upper[pipe]; | ||
250 | bottom = lower[pipe]; | ||
251 | |||
252 | for (num_rects = drw->num_rects; num_rects--; rect++) { | ||
253 | int y1 = max(rect->y1, top); | ||
254 | int y2 = min(rect->y2, bottom); | ||
255 | |||
256 | if (y1 >= y2) | ||
257 | continue; | ||
258 | |||
259 | BEGIN_LP_RING(8); | ||
260 | |||
261 | OUT_RING(cmd); | ||
262 | OUT_RING(ropcpp | dst_pitch); | ||
263 | OUT_RING((y1 << 16) | rect->x1); | ||
264 | OUT_RING((y2 << 16) | rect->x2); | ||
265 | OUT_RING(sarea_priv->front_offset); | ||
266 | OUT_RING((y1 << 16) | rect->x1); | ||
267 | OUT_RING(src_pitch); | ||
268 | OUT_RING(sarea_priv->back_offset); | ||
269 | |||
270 | ADVANCE_LP_RING(); | ||
271 | } | ||
272 | } | ||
273 | } | ||
274 | |||
275 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); | ||
276 | mutex_unlock(&dev->struct_mutex); | ||
277 | |||
278 | list_for_each_safe(hit, tmp, &hits) { | ||
279 | drm_i915_vbl_swap_t *swap_hit = | ||
280 | list_entry(hit, drm_i915_vbl_swap_t, head); | ||
281 | |||
282 | list_del(hit); | ||
283 | |||
284 | drm_free(swap_hit, sizeof(*swap_hit), DRM_MEM_DRIVER); | ||
285 | } | ||
286 | } | ||
287 | |||
288 | /* Called from drm generic code, passed a 'crtc', which | 83 | /* Called from drm generic code, passed a 'crtc', which |
289 | * we use as a pipe index | 84 | * we use as a pipe index |
290 | */ | 85 | */ |
@@ -322,40 +117,6 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) | |||
322 | return count; | 117 | return count; |
323 | } | 118 | } |
324 | 119 | ||
325 | void | ||
326 | i915_vblank_work_handler(struct work_struct *work) | ||
327 | { | ||
328 | drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, | ||
329 | vblank_work); | ||
330 | struct drm_device *dev = dev_priv->dev; | ||
331 | unsigned long irqflags; | ||
332 | |||
333 | if (dev->lock.hw_lock == NULL) { | ||
334 | i915_vblank_tasklet(dev); | ||
335 | return; | ||
336 | } | ||
337 | |||
338 | spin_lock_irqsave(&dev->tasklet_lock, irqflags); | ||
339 | dev->locked_tasklet_func = i915_vblank_tasklet; | ||
340 | spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); | ||
341 | |||
342 | /* Try to get the lock now, if this fails, the lock | ||
343 | * holder will execute the tasklet during unlock | ||
344 | */ | ||
345 | if (!drm_lock_take(&dev->lock, DRM_KERNEL_CONTEXT)) | ||
346 | return; | ||
347 | |||
348 | dev->lock.lock_time = jiffies; | ||
349 | atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); | ||
350 | |||
351 | spin_lock_irqsave(&dev->tasklet_lock, irqflags); | ||
352 | dev->locked_tasklet_func = NULL; | ||
353 | spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); | ||
354 | |||
355 | i915_vblank_tasklet(dev); | ||
356 | drm_lock_free(&dev->lock, DRM_KERNEL_CONTEXT); | ||
357 | } | ||
358 | |||
359 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | 120 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) |
360 | { | 121 | { |
361 | struct drm_device *dev = (struct drm_device *) arg; | 122 | struct drm_device *dev = (struct drm_device *) arg; |
@@ -433,9 +194,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
433 | if (iir & I915_ASLE_INTERRUPT) | 194 | if (iir & I915_ASLE_INTERRUPT) |
434 | opregion_asle_intr(dev); | 195 | opregion_asle_intr(dev); |
435 | 196 | ||
436 | if (vblank && dev_priv->swaps_pending > 0) | ||
437 | schedule_work(&dev_priv->vblank_work); | ||
438 | |||
439 | return IRQ_HANDLED; | 197 | return IRQ_HANDLED; |
440 | } | 198 | } |
441 | 199 | ||
@@ -454,12 +212,10 @@ static int i915_emit_irq(struct drm_device * dev) | |||
454 | if (dev_priv->sarea_priv) | 212 | if (dev_priv->sarea_priv) |
455 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter; | 213 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter; |
456 | 214 | ||
457 | BEGIN_LP_RING(6); | 215 | BEGIN_LP_RING(4); |
458 | OUT_RING(MI_STORE_DWORD_INDEX); | 216 | OUT_RING(MI_STORE_DWORD_INDEX); |
459 | OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT); | 217 | OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); |
460 | OUT_RING(dev_priv->counter); | 218 | OUT_RING(dev_priv->counter); |
461 | OUT_RING(0); | ||
462 | OUT_RING(0); | ||
463 | OUT_RING(MI_USER_INTERRUPT); | 219 | OUT_RING(MI_USER_INTERRUPT); |
464 | ADVANCE_LP_RING(); | 220 | ADVANCE_LP_RING(); |
465 | 221 | ||
@@ -696,123 +452,21 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data, | |||
696 | int i915_vblank_swap(struct drm_device *dev, void *data, | 452 | int i915_vblank_swap(struct drm_device *dev, void *data, |
697 | struct drm_file *file_priv) | 453 | struct drm_file *file_priv) |
698 | { | 454 | { |
699 | drm_i915_private_t *dev_priv = dev->dev_private; | 455 | /* The delayed swap mechanism was fundamentally racy, and has been |
700 | drm_i915_vblank_swap_t *swap = data; | 456 | * removed. The model was that the client requested a delayed flip/swap |
701 | drm_i915_vbl_swap_t *vbl_swap, *vbl_old; | 457 | * from the kernel, then waited for vblank before continuing to perform |
702 | unsigned int pipe, seqtype, curseq; | 458 | * rendering. The problem was that the kernel might wake the client |
703 | unsigned long irqflags; | 459 | * up before it dispatched the vblank swap (since the lock has to be |
704 | struct list_head *list; | 460 | * held while touching the ringbuffer), in which case the client would |
705 | int ret; | 461 | * clear and start the next frame before the swap occurred, and |
706 | 462 | * flicker would occur in addition to likely missing the vblank. | |
707 | if (!dev_priv || !dev_priv->sarea_priv) { | 463 | * |
708 | DRM_ERROR("%s called with no initialization\n", __func__); | 464 | * In the absence of this ioctl, userland falls back to a correct path |
709 | return -EINVAL; | 465 | * of waiting for a vblank, then dispatching the swap on its own. |
710 | } | 466 | * Context switching to userland and back is plenty fast enough for |
711 | 467 | * meeting the requirements of vblank swapping. | |
712 | if (dev_priv->sarea_priv->rotation) { | ||
713 | DRM_DEBUG("Rotation not supported\n"); | ||
714 | return -EINVAL; | ||
715 | } | ||
716 | |||
717 | if (swap->seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE | | ||
718 | _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS)) { | ||
719 | DRM_ERROR("Invalid sequence type 0x%x\n", swap->seqtype); | ||
720 | return -EINVAL; | ||
721 | } | ||
722 | |||
723 | pipe = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0; | ||
724 | |||
725 | seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE); | ||
726 | |||
727 | if (!(dev_priv->vblank_pipe & (1 << pipe))) { | ||
728 | DRM_ERROR("Invalid pipe %d\n", pipe); | ||
729 | return -EINVAL; | ||
730 | } | ||
731 | |||
732 | spin_lock_irqsave(&dev->drw_lock, irqflags); | ||
733 | |||
734 | if (!drm_get_drawable_info(dev, swap->drawable)) { | ||
735 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); | ||
736 | DRM_DEBUG("Invalid drawable ID %d\n", swap->drawable); | ||
737 | return -EINVAL; | ||
738 | } | ||
739 | |||
740 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); | ||
741 | |||
742 | /* | ||
743 | * We take the ref here and put it when the swap actually completes | ||
744 | * in the tasklet. | ||
745 | */ | 468 | */ |
746 | ret = drm_vblank_get(dev, pipe); | 469 | return -EINVAL; |
747 | if (ret) | ||
748 | return ret; | ||
749 | curseq = drm_vblank_count(dev, pipe); | ||
750 | |||
751 | if (seqtype == _DRM_VBLANK_RELATIVE) | ||
752 | swap->sequence += curseq; | ||
753 | |||
754 | if ((curseq - swap->sequence) <= (1<<23)) { | ||
755 | if (swap->seqtype & _DRM_VBLANK_NEXTONMISS) { | ||
756 | swap->sequence = curseq + 1; | ||
757 | } else { | ||
758 | DRM_DEBUG("Missed target sequence\n"); | ||
759 | drm_vblank_put(dev, pipe); | ||
760 | return -EINVAL; | ||
761 | } | ||
762 | } | ||
763 | |||
764 | vbl_swap = drm_calloc(1, sizeof(*vbl_swap), DRM_MEM_DRIVER); | ||
765 | |||
766 | if (!vbl_swap) { | ||
767 | DRM_ERROR("Failed to allocate memory to queue swap\n"); | ||
768 | drm_vblank_put(dev, pipe); | ||
769 | return -ENOMEM; | ||
770 | } | ||
771 | |||
772 | vbl_swap->drw_id = swap->drawable; | ||
773 | vbl_swap->pipe = pipe; | ||
774 | vbl_swap->sequence = swap->sequence; | ||
775 | |||
776 | spin_lock_irqsave(&dev_priv->swaps_lock, irqflags); | ||
777 | |||
778 | list_for_each(list, &dev_priv->vbl_swaps.head) { | ||
779 | vbl_old = list_entry(list, drm_i915_vbl_swap_t, head); | ||
780 | |||
781 | if (vbl_old->drw_id == swap->drawable && | ||
782 | vbl_old->pipe == pipe && | ||
783 | vbl_old->sequence == swap->sequence) { | ||
784 | spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); | ||
785 | drm_vblank_put(dev, pipe); | ||
786 | drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER); | ||
787 | DRM_DEBUG("Already scheduled\n"); | ||
788 | return 0; | ||
789 | } | ||
790 | } | ||
791 | |||
792 | if (dev_priv->swaps_pending >= 10) { | ||
793 | DRM_DEBUG("Too many swaps queued\n"); | ||
794 | DRM_DEBUG(" pipe 0: %d pipe 1: %d\n", | ||
795 | drm_vblank_count(dev, 0), | ||
796 | drm_vblank_count(dev, 1)); | ||
797 | |||
798 | list_for_each(list, &dev_priv->vbl_swaps.head) { | ||
799 | vbl_old = list_entry(list, drm_i915_vbl_swap_t, head); | ||
800 | DRM_DEBUG("\tdrw %x pipe %d seq %x\n", | ||
801 | vbl_old->drw_id, vbl_old->pipe, | ||
802 | vbl_old->sequence); | ||
803 | } | ||
804 | spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); | ||
805 | drm_vblank_put(dev, pipe); | ||
806 | drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER); | ||
807 | return -EBUSY; | ||
808 | } | ||
809 | |||
810 | list_add_tail(&vbl_swap->head, &dev_priv->vbl_swaps.head); | ||
811 | dev_priv->swaps_pending++; | ||
812 | |||
813 | spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags); | ||
814 | |||
815 | return 0; | ||
816 | } | 470 | } |
817 | 471 | ||
818 | /* drm_dma.h hooks | 472 | /* drm_dma.h hooks |
@@ -831,11 +485,6 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
831 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 485 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
832 | int ret, num_pipes = 2; | 486 | int ret, num_pipes = 2; |
833 | 487 | ||
834 | spin_lock_init(&dev_priv->swaps_lock); | ||
835 | INIT_LIST_HEAD(&dev_priv->vbl_swaps.head); | ||
836 | INIT_WORK(&dev_priv->vblank_work, i915_vblank_work_handler); | ||
837 | dev_priv->swaps_pending = 0; | ||
838 | |||
839 | /* Set initial unmasked IRQs to just the selected vblank pipes. */ | 488 | /* Set initial unmasked IRQs to just the selected vblank pipes. */ |
840 | dev_priv->irq_mask_reg = ~0; | 489 | dev_priv->irq_mask_reg = ~0; |
841 | 490 | ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5c2d9f206d05..0e476eba36e6 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -527,6 +527,9 @@ | |||
527 | #define C0DRB3 0x10206 | 527 | #define C0DRB3 0x10206 |
528 | #define C1DRB3 0x10606 | 528 | #define C1DRB3 0x10606 |
529 | 529 | ||
530 | /** GM965 GM45 render standby register */ | ||
531 | #define MCHBAR_RENDER_STANDBY 0x111B8 | ||
532 | |||
530 | /* | 533 | /* |
531 | * Overlay regs | 534 | * Overlay regs |
532 | */ | 535 | */ |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 603fe742ccd4..5ddc6e595c0c 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -240,6 +240,10 @@ int i915_save_state(struct drm_device *dev) | |||
240 | 240 | ||
241 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | 241 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); |
242 | 242 | ||
243 | /* Render Standby */ | ||
244 | if (IS_I965G(dev) && IS_MOBILE(dev)) | ||
245 | dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY); | ||
246 | |||
243 | /* Display arbitration control */ | 247 | /* Display arbitration control */ |
244 | dev_priv->saveDSPARB = I915_READ(DSPARB); | 248 | dev_priv->saveDSPARB = I915_READ(DSPARB); |
245 | 249 | ||
@@ -365,6 +369,11 @@ int i915_restore_state(struct drm_device *dev) | |||
365 | 369 | ||
366 | pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); | 370 | pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); |
367 | 371 | ||
372 | /* Render Standby */ | ||
373 | if (IS_I965G(dev) && IS_MOBILE(dev)) | ||
374 | I915_WRITE(MCHBAR_RENDER_STANDBY, dev_priv->saveRENDERSTANDBY); | ||
375 | |||
376 | /* Display arbitration */ | ||
368 | I915_WRITE(DSPARB, dev_priv->saveDSPARB); | 377 | I915_WRITE(DSPARB, dev_priv->saveDSPARB); |
369 | 378 | ||
370 | /* Pipe & plane A info */ | 379 | /* Pipe & plane A info */ |
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index 073894824e6b..abdc1ae38467 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c | |||
@@ -1751,6 +1751,12 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) | |||
1751 | else | 1751 | else |
1752 | dev_priv->flags |= RADEON_IS_PCI; | 1752 | dev_priv->flags |= RADEON_IS_PCI; |
1753 | 1753 | ||
1754 | ret = drm_addmap(dev, drm_get_resource_start(dev, 2), | ||
1755 | drm_get_resource_len(dev, 2), _DRM_REGISTERS, | ||
1756 | _DRM_READ_ONLY | _DRM_DRIVER, &dev_priv->mmio); | ||
1757 | if (ret != 0) | ||
1758 | return ret; | ||
1759 | |||
1754 | DRM_DEBUG("%s card detected\n", | 1760 | DRM_DEBUG("%s card detected\n", |
1755 | ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); | 1761 | ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); |
1756 | return ret; | 1762 | return ret; |
@@ -1767,12 +1773,6 @@ int radeon_driver_firstopen(struct drm_device *dev) | |||
1767 | 1773 | ||
1768 | dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; | 1774 | dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; |
1769 | 1775 | ||
1770 | ret = drm_addmap(dev, drm_get_resource_start(dev, 2), | ||
1771 | drm_get_resource_len(dev, 2), _DRM_REGISTERS, | ||
1772 | _DRM_READ_ONLY, &dev_priv->mmio); | ||
1773 | if (ret != 0) | ||
1774 | return ret; | ||
1775 | |||
1776 | dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0); | 1776 | dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0); |
1777 | ret = drm_addmap(dev, dev_priv->fb_aper_offset, | 1777 | ret = drm_addmap(dev, dev_priv->fb_aper_offset, |
1778 | drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER, | 1778 | drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER, |
@@ -1788,6 +1788,9 @@ int radeon_driver_unload(struct drm_device *dev) | |||
1788 | drm_radeon_private_t *dev_priv = dev->dev_private; | 1788 | drm_radeon_private_t *dev_priv = dev->dev_private; |
1789 | 1789 | ||
1790 | DRM_DEBUG("\n"); | 1790 | DRM_DEBUG("\n"); |
1791 | |||
1792 | drm_rmmap(dev, dev_priv->mmio); | ||
1793 | |||
1791 | drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); | 1794 | drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); |
1792 | 1795 | ||
1793 | dev->dev_private = NULL; | 1796 | dev->dev_private = NULL; |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h index 02f5575ba395..7a183789be97 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h | |||
@@ -287,7 +287,6 @@ typedef struct drm_radeon_private { | |||
287 | unsigned long gart_textures_offset; | 287 | unsigned long gart_textures_offset; |
288 | 288 | ||
289 | drm_local_map_t *sarea; | 289 | drm_local_map_t *sarea; |
290 | drm_local_map_t *mmio; | ||
291 | drm_local_map_t *cp_ring; | 290 | drm_local_map_t *cp_ring; |
292 | drm_local_map_t *ring_rptr; | 291 | drm_local_map_t *ring_rptr; |
293 | drm_local_map_t *gart_textures; | 292 | drm_local_map_t *gart_textures; |
@@ -318,6 +317,7 @@ typedef struct drm_radeon_private { | |||
318 | 317 | ||
319 | int num_gb_pipes; | 318 | int num_gb_pipes; |
320 | int track_flush; | 319 | int track_flush; |
320 | drm_local_map_t *mmio; | ||
321 | } drm_radeon_private_t; | 321 | } drm_radeon_private_t; |
322 | 322 | ||
323 | typedef struct drm_radeon_buf_priv { | 323 | typedef struct drm_radeon_buf_priv { |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 1903e7515650..d3671b4049c0 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1265,6 +1265,7 @@ static const struct hid_device_id hid_blacklist[] = { | |||
1265 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, | 1265 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, |
1266 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERIC_13BA, USB_DEVICE_ID_GENERIC_13BA_KBD_MOUSE) }, | 1266 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERIC_13BA, USB_DEVICE_ID_GENERIC_13BA_KBD_MOUSE) }, |
1267 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, | 1267 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, |
1268 | { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) }, | ||
1268 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, | 1269 | { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, |
1269 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, | 1270 | { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, |
1270 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, | 1271 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 5cc404291736..f05bcbbbb0d5 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -253,6 +253,9 @@ | |||
253 | #define USB_VENDOR_ID_KBGEAR 0x084e | 253 | #define USB_VENDOR_ID_KBGEAR 0x084e |
254 | #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 | 254 | #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 |
255 | 255 | ||
256 | #define USB_VENDOR_ID_KWORLD 0x1b80 | ||
257 | #define USB_DEVICE_ID_KWORLD_RADIO_FM700 0xd700 | ||
258 | |||
256 | #define USB_VENDOR_ID_LABTEC 0x1020 | 259 | #define USB_VENDOR_ID_LABTEC 0x1020 |
257 | #define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006 | 260 | #define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006 |
258 | 261 | ||
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 6de1e0ffd391..c709e821f04b 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -159,6 +159,16 @@ config SENSORS_ADM9240 | |||
159 | This driver can also be built as a module. If so, the module | 159 | This driver can also be built as a module. If so, the module |
160 | will be called adm9240. | 160 | will be called adm9240. |
161 | 161 | ||
162 | config SENSORS_ADT7462 | ||
163 | tristate "Analog Devices ADT7462" | ||
164 | depends on I2C && EXPERIMENTAL | ||
165 | help | ||
166 | If you say yes here you get support for the Analog Devices | ||
167 | ADT7462 temperature monitoring chips. | ||
168 | |||
169 | This driver can also be built as a module. If so, the module | ||
170 | will be called adt7462. | ||
171 | |||
162 | config SENSORS_ADT7470 | 172 | config SENSORS_ADT7470 |
163 | tristate "Analog Devices ADT7470" | 173 | tristate "Analog Devices ADT7470" |
164 | depends on I2C && EXPERIMENTAL | 174 | depends on I2C && EXPERIMENTAL |
@@ -825,6 +835,25 @@ config SENSORS_HDAPS | |||
825 | Say Y here if you have an applicable laptop and want to experience | 835 | Say Y here if you have an applicable laptop and want to experience |
826 | the awesome power of hdaps. | 836 | the awesome power of hdaps. |
827 | 837 | ||
838 | config SENSORS_LIS3LV02D | ||
839 | tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer" | ||
840 | depends on ACPI && INPUT | ||
841 | default n | ||
842 | help | ||
843 | This driver provides support for the LIS3LV02Dx accelerometer. In | ||
844 | particular, it can be found in a number of HP laptops, which have the | ||
845 | "Mobile Data Protection System 3D" or "3D DriveGuard" feature. On such | ||
846 | systems the driver should load automatically (via ACPI). The | ||
847 | accelerometer might also be found in other systems, connected via SPI | ||
848 | or I2C. The accelerometer data is readable via | ||
849 | /sys/devices/platform/lis3lv02d. | ||
850 | |||
851 | This driver also provides an absolute input class device, allowing | ||
852 | the laptop to act as a pinball machine-esque joystick. | ||
853 | |||
854 | This driver can also be built as a module. If so, the module | ||
855 | will be called lis3lv02d. | ||
856 | |||
828 | config SENSORS_APPLESMC | 857 | config SENSORS_APPLESMC |
829 | tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)" | 858 | tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)" |
830 | depends on INPUT && X86 | 859 | depends on INPUT && X86 |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 042d5a78622e..58fc5be5355d 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -25,6 +25,7 @@ obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o | |||
25 | obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o | 25 | obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o |
26 | obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o | 26 | obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o |
27 | obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o | 27 | obj-$(CONFIG_SENSORS_ADS7828) += ads7828.o |
28 | obj-$(CONFIG_SENSORS_ADT7462) += adt7462.o | ||
28 | obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o | 29 | obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o |
29 | obj-$(CONFIG_SENSORS_ADT7473) += adt7473.o | 30 | obj-$(CONFIG_SENSORS_ADT7473) += adt7473.o |
30 | obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o | 31 | obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o |
@@ -48,6 +49,7 @@ obj-$(CONFIG_SENSORS_IBMAEM) += ibmaem.o | |||
48 | obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o | 49 | obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o |
49 | obj-$(CONFIG_SENSORS_IT87) += it87.o | 50 | obj-$(CONFIG_SENSORS_IT87) += it87.o |
50 | obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o | 51 | obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o |
52 | obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o | ||
51 | obj-$(CONFIG_SENSORS_LM63) += lm63.o | 53 | obj-$(CONFIG_SENSORS_LM63) += lm63.o |
52 | obj-$(CONFIG_SENSORS_LM70) += lm70.o | 54 | obj-$(CONFIG_SENSORS_LM70) += lm70.o |
53 | obj-$(CONFIG_SENSORS_LM75) += lm75.o | 55 | obj-$(CONFIG_SENSORS_LM75) += lm75.o |
diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c new file mode 100644 index 000000000000..66107b4dc12a --- /dev/null +++ b/drivers/hwmon/adt7462.c | |||
@@ -0,0 +1,2002 @@ | |||
1 | /* | ||
2 | * A hwmon driver for the Analog Devices ADT7462 | ||
3 | * Copyright (C) 2008 IBM | ||
4 | * | ||
5 | * Author: Darrick J. Wong <djwong@us.ibm.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/jiffies.h> | ||
24 | #include <linux/i2c.h> | ||
25 | #include <linux/hwmon.h> | ||
26 | #include <linux/hwmon-sysfs.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/mutex.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/log2.h> | ||
31 | |||
32 | /* Addresses to scan */ | ||
33 | static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END }; | ||
34 | |||
35 | /* Insmod parameters */ | ||
36 | I2C_CLIENT_INSMOD_1(adt7462); | ||
37 | |||
38 | /* ADT7462 registers */ | ||
39 | #define ADT7462_REG_DEVICE 0x3D | ||
40 | #define ADT7462_REG_VENDOR 0x3E | ||
41 | #define ADT7462_REG_REVISION 0x3F | ||
42 | |||
43 | #define ADT7462_REG_MIN_TEMP_BASE_ADDR 0x44 | ||
44 | #define ADT7462_REG_MIN_TEMP_MAX_ADDR 0x47 | ||
45 | #define ADT7462_REG_MAX_TEMP_BASE_ADDR 0x48 | ||
46 | #define ADT7462_REG_MAX_TEMP_MAX_ADDR 0x4B | ||
47 | #define ADT7462_REG_TEMP_BASE_ADDR 0x88 | ||
48 | #define ADT7462_REG_TEMP_MAX_ADDR 0x8F | ||
49 | |||
50 | #define ADT7462_REG_FAN_BASE_ADDR 0x98 | ||
51 | #define ADT7462_REG_FAN_MAX_ADDR 0x9F | ||
52 | #define ADT7462_REG_FAN2_BASE_ADDR 0xA2 | ||
53 | #define ADT7462_REG_FAN2_MAX_ADDR 0xA9 | ||
54 | #define ADT7462_REG_FAN_ENABLE 0x07 | ||
55 | #define ADT7462_REG_FAN_MIN_BASE_ADDR 0x78 | ||
56 | #define ADT7462_REG_FAN_MIN_MAX_ADDR 0x7F | ||
57 | |||
58 | #define ADT7462_REG_CFG2 0x02 | ||
59 | #define ADT7462_FSPD_MASK 0x20 | ||
60 | |||
61 | #define ADT7462_REG_PWM_BASE_ADDR 0xAA | ||
62 | #define ADT7462_REG_PWM_MAX_ADDR 0xAD | ||
63 | #define ADT7462_REG_PWM_MIN_BASE_ADDR 0x28 | ||
64 | #define ADT7462_REG_PWM_MIN_MAX_ADDR 0x2B | ||
65 | #define ADT7462_REG_PWM_MAX 0x2C | ||
66 | #define ADT7462_REG_PWM_TEMP_MIN_BASE_ADDR 0x5C | ||
67 | #define ADT7462_REG_PWM_TEMP_MIN_MAX_ADDR 0x5F | ||
68 | #define ADT7462_REG_PWM_TEMP_RANGE_BASE_ADDR 0x60 | ||
69 | #define ADT7462_REG_PWM_TEMP_RANGE_MAX_ADDR 0x63 | ||
70 | #define ADT7462_PWM_HYST_MASK 0x0F | ||
71 | #define ADT7462_PWM_RANGE_MASK 0xF0 | ||
72 | #define ADT7462_PWM_RANGE_SHIFT 4 | ||
73 | #define ADT7462_REG_PWM_CFG_BASE_ADDR 0x21 | ||
74 | #define ADT7462_REG_PWM_CFG_MAX_ADDR 0x24 | ||
75 | #define ADT7462_PWM_CHANNEL_MASK 0xE0 | ||
76 | #define ADT7462_PWM_CHANNEL_SHIFT 5 | ||
77 | |||
78 | #define ADT7462_REG_PIN_CFG_BASE_ADDR 0x10 | ||
79 | #define ADT7462_REG_PIN_CFG_MAX_ADDR 0x13 | ||
80 | #define ADT7462_PIN7_INPUT 0x01 /* cfg0 */ | ||
81 | #define ADT7462_DIODE3_INPUT 0x20 | ||
82 | #define ADT7462_DIODE1_INPUT 0x40 | ||
83 | #define ADT7462_VID_INPUT 0x80 | ||
84 | #define ADT7462_PIN22_INPUT 0x04 /* cfg1 */ | ||
85 | #define ADT7462_PIN21_INPUT 0x08 | ||
86 | #define ADT7462_PIN19_INPUT 0x10 | ||
87 | #define ADT7462_PIN15_INPUT 0x20 | ||
88 | #define ADT7462_PIN13_INPUT 0x40 | ||
89 | #define ADT7462_PIN8_INPUT 0x80 | ||
90 | #define ADT7462_PIN23_MASK 0x03 | ||
91 | #define ADT7462_PIN23_SHIFT 0 | ||
92 | #define ADT7462_PIN26_MASK 0x0C /* cfg2 */ | ||
93 | #define ADT7462_PIN26_SHIFT 2 | ||
94 | #define ADT7462_PIN25_MASK 0x30 | ||
95 | #define ADT7462_PIN25_SHIFT 4 | ||
96 | #define ADT7462_PIN24_MASK 0xC0 | ||
97 | #define ADT7462_PIN24_SHIFT 6 | ||
98 | #define ADT7462_PIN26_VOLT_INPUT 0x08 | ||
99 | #define ADT7462_PIN25_VOLT_INPUT 0x20 | ||
100 | #define ADT7462_PIN28_SHIFT 6 /* cfg3 */ | ||
101 | #define ADT7462_PIN28_VOLT 0x5 | ||
102 | |||
103 | #define ADT7462_REG_ALARM1 0xB8 | ||
104 | #define ADT7462_LT_ALARM 0x02 | ||
105 | #define ADT7462_R1T_ALARM 0x04 | ||
106 | #define ADT7462_R2T_ALARM 0x08 | ||
107 | #define ADT7462_R3T_ALARM 0x10 | ||
108 | #define ADT7462_REG_ALARM2 0xBB | ||
109 | #define ADT7462_V0_ALARM 0x01 | ||
110 | #define ADT7462_V1_ALARM 0x02 | ||
111 | #define ADT7462_V2_ALARM 0x04 | ||
112 | #define ADT7462_V3_ALARM 0x08 | ||
113 | #define ADT7462_V4_ALARM 0x10 | ||
114 | #define ADT7462_V5_ALARM 0x20 | ||
115 | #define ADT7462_V6_ALARM 0x40 | ||
116 | #define ADT7462_V7_ALARM 0x80 | ||
117 | #define ADT7462_REG_ALARM3 0xBC | ||
118 | #define ADT7462_V8_ALARM 0x08 | ||
119 | #define ADT7462_V9_ALARM 0x10 | ||
120 | #define ADT7462_V10_ALARM 0x20 | ||
121 | #define ADT7462_V11_ALARM 0x40 | ||
122 | #define ADT7462_V12_ALARM 0x80 | ||
123 | #define ADT7462_REG_ALARM4 0xBD | ||
124 | #define ADT7462_F0_ALARM 0x01 | ||
125 | #define ADT7462_F1_ALARM 0x02 | ||
126 | #define ADT7462_F2_ALARM 0x04 | ||
127 | #define ADT7462_F3_ALARM 0x08 | ||
128 | #define ADT7462_F4_ALARM 0x10 | ||
129 | #define ADT7462_F5_ALARM 0x20 | ||
130 | #define ADT7462_F6_ALARM 0x40 | ||
131 | #define ADT7462_F7_ALARM 0x80 | ||
132 | #define ADT7462_ALARM1 0x0000 | ||
133 | #define ADT7462_ALARM2 0x0100 | ||
134 | #define ADT7462_ALARM3 0x0200 | ||
135 | #define ADT7462_ALARM4 0x0300 | ||
136 | #define ADT7462_ALARM_REG_SHIFT 8 | ||
137 | #define ADT7462_ALARM_FLAG_MASK 0x0F | ||
138 | |||
139 | #define ADT7462_TEMP_COUNT 4 | ||
140 | #define ADT7462_TEMP_REG(x) (ADT7462_REG_TEMP_BASE_ADDR + (x * 2)) | ||
141 | #define ADT7462_TEMP_MIN_REG(x) (ADT7462_REG_MIN_TEMP_BASE_ADDR + (x)) | ||
142 | #define ADT7462_TEMP_MAX_REG(x) (ADT7462_REG_MAX_TEMP_BASE_ADDR + (x)) | ||
143 | #define TEMP_FRAC_OFFSET 6 | ||
144 | |||
145 | #define ADT7462_FAN_COUNT 8 | ||
146 | #define ADT7462_REG_FAN_MIN(x) (ADT7462_REG_FAN_MIN_BASE_ADDR + (x)) | ||
147 | |||
148 | #define ADT7462_PWM_COUNT 4 | ||
149 | #define ADT7462_REG_PWM(x) (ADT7462_REG_PWM_BASE_ADDR + (x)) | ||
150 | #define ADT7462_REG_PWM_MIN(x) (ADT7462_REG_PWM_MIN_BASE_ADDR + (x)) | ||
151 | #define ADT7462_REG_PWM_TMIN(x) \ | ||
152 | (ADT7462_REG_PWM_TEMP_MIN_BASE_ADDR + (x)) | ||
153 | #define ADT7462_REG_PWM_TRANGE(x) \ | ||
154 | (ADT7462_REG_PWM_TEMP_RANGE_BASE_ADDR + (x)) | ||
155 | |||
156 | #define ADT7462_PIN_CFG_REG_COUNT 4 | ||
157 | #define ADT7462_REG_PIN_CFG(x) (ADT7462_REG_PIN_CFG_BASE_ADDR + (x)) | ||
158 | #define ADT7462_REG_PWM_CFG(x) (ADT7462_REG_PWM_CFG_BASE_ADDR + (x)) | ||
159 | |||
160 | #define ADT7462_ALARM_REG_COUNT 4 | ||
161 | |||
162 | /* | ||
163 | * The chip can measure 13 different voltage sources: | ||
164 | * | ||
165 | * 1. +12V1 (pin 7) | ||
166 | * 2. Vccp1/+2.5V/+1.8V/+1.5V (pin 23) | ||
167 | * 3. +12V3 (pin 22) | ||
168 | * 4. +5V (pin 21) | ||
169 | * 5. +1.25V/+0.9V (pin 19) | ||
170 | * 6. +2.5V/+1.8V (pin 15) | ||
171 | * 7. +3.3v (pin 13) | ||
172 | * 8. +12V2 (pin 8) | ||
173 | * 9. Vbatt/FSB_Vtt (pin 26) | ||
174 | * A. +3.3V/+1.2V1 (pin 25) | ||
175 | * B. Vccp2/+2.5V/+1.8V/+1.5V (pin 24) | ||
176 | * C. +1.5V ICH (only if BOTH pin 28/29 are set to +1.5V) | ||
177 | * D. +1.5V 3GPIO (only if BOTH pin 28/29 are set to +1.5V) | ||
178 | * | ||
179 | * Each of these 13 has a factor to convert raw to voltage. Even better, | ||
180 | * the pins can be connected to other sensors (tach/gpio/hot/etc), which | ||
181 | * makes the bookkeeping tricky. | ||
182 | * | ||
183 | * Some, but not all, of these voltages have low/high limits. | ||
184 | */ | ||
185 | #define ADT7462_VOLT_COUNT 12 | ||
186 | |||
187 | #define ADT7462_VENDOR 0x41 | ||
188 | #define ADT7462_DEVICE 0x62 | ||
189 | /* datasheet only mentions a revision 4 */ | ||
190 | #define ADT7462_REVISION 0x04 | ||
191 | |||
192 | /* How often do we reread sensors values? (In jiffies) */ | ||
193 | #define SENSOR_REFRESH_INTERVAL (2 * HZ) | ||
194 | |||
195 | /* How often do we reread sensor limit values? (In jiffies) */ | ||
196 | #define LIMIT_REFRESH_INTERVAL (60 * HZ) | ||
197 | |||
198 | /* datasheet says to divide this number by the fan reading to get fan rpm */ | ||
199 | #define FAN_PERIOD_TO_RPM(x) ((90000 * 60) / (x)) | ||
200 | #define FAN_RPM_TO_PERIOD FAN_PERIOD_TO_RPM | ||
201 | #define FAN_PERIOD_INVALID 65535 | ||
202 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) | ||
203 | |||
204 | #define MASK_AND_SHIFT(value, prefix) \ | ||
205 | (((value) & prefix##_MASK) >> prefix##_SHIFT) | ||
206 | |||
207 | #define ROUND_DIV(x, divisor) (((x) + ((divisor) / 2)) / (divisor)) | ||
208 | |||
209 | struct adt7462_data { | ||
210 | struct device *hwmon_dev; | ||
211 | struct attribute_group attrs; | ||
212 | struct mutex lock; | ||
213 | char sensors_valid; | ||
214 | char limits_valid; | ||
215 | unsigned long sensors_last_updated; /* In jiffies */ | ||
216 | unsigned long limits_last_updated; /* In jiffies */ | ||
217 | |||
218 | u8 temp[ADT7462_TEMP_COUNT]; | ||
219 | /* bits 6-7 are quarter pieces of temp */ | ||
220 | u8 temp_frac[ADT7462_TEMP_COUNT]; | ||
221 | u8 temp_min[ADT7462_TEMP_COUNT]; | ||
222 | u8 temp_max[ADT7462_TEMP_COUNT]; | ||
223 | u16 fan[ADT7462_FAN_COUNT]; | ||
224 | u8 fan_enabled; | ||
225 | u8 fan_min[ADT7462_FAN_COUNT]; | ||
226 | u8 cfg2; | ||
227 | u8 pwm[ADT7462_PWM_COUNT]; | ||
228 | u8 pin_cfg[ADT7462_PIN_CFG_REG_COUNT]; | ||
229 | u8 voltages[ADT7462_VOLT_COUNT]; | ||
230 | u8 volt_max[ADT7462_VOLT_COUNT]; | ||
231 | u8 volt_min[ADT7462_VOLT_COUNT]; | ||
232 | u8 pwm_min[ADT7462_PWM_COUNT]; | ||
233 | u8 pwm_tmin[ADT7462_PWM_COUNT]; | ||
234 | u8 pwm_trange[ADT7462_PWM_COUNT]; | ||
235 | u8 pwm_max; /* only one per chip */ | ||
236 | u8 pwm_cfg[ADT7462_PWM_COUNT]; | ||
237 | u8 alarms[ADT7462_ALARM_REG_COUNT]; | ||
238 | }; | ||
239 | |||
240 | static int adt7462_probe(struct i2c_client *client, | ||
241 | const struct i2c_device_id *id); | ||
242 | static int adt7462_detect(struct i2c_client *client, int kind, | ||
243 | struct i2c_board_info *info); | ||
244 | static int adt7462_remove(struct i2c_client *client); | ||
245 | |||
246 | static const struct i2c_device_id adt7462_id[] = { | ||
247 | { "adt7462", adt7462 }, | ||
248 | { } | ||
249 | }; | ||
250 | MODULE_DEVICE_TABLE(i2c, adt7462_id); | ||
251 | |||
252 | static struct i2c_driver adt7462_driver = { | ||
253 | .class = I2C_CLASS_HWMON, | ||
254 | .driver = { | ||
255 | .name = "adt7462", | ||
256 | }, | ||
257 | .probe = adt7462_probe, | ||
258 | .remove = adt7462_remove, | ||
259 | .id_table = adt7462_id, | ||
260 | .detect = adt7462_detect, | ||
261 | .address_data = &addr_data, | ||
262 | }; | ||
263 | |||
264 | /* | ||
265 | * 16-bit registers on the ADT7462 are low-byte first. The data sheet says | ||
266 | * that the low byte must be read before the high byte. | ||
267 | */ | ||
268 | static inline int adt7462_read_word_data(struct i2c_client *client, u8 reg) | ||
269 | { | ||
270 | u16 foo; | ||
271 | foo = i2c_smbus_read_byte_data(client, reg); | ||
272 | foo |= ((u16)i2c_smbus_read_byte_data(client, reg + 1) << 8); | ||
273 | return foo; | ||
274 | } | ||
275 | |||
276 | /* For some reason these registers are not contiguous. */ | ||
277 | static int ADT7462_REG_FAN(int fan) | ||
278 | { | ||
279 | if (fan < 4) | ||
280 | return ADT7462_REG_FAN_BASE_ADDR + (2 * fan); | ||
281 | return ADT7462_REG_FAN2_BASE_ADDR + (2 * (fan - 4)); | ||
282 | } | ||
283 | |||
284 | /* Voltage registers are scattered everywhere */ | ||
285 | static int ADT7462_REG_VOLT_MAX(struct adt7462_data *data, int which) | ||
286 | { | ||
287 | switch (which) { | ||
288 | case 0: | ||
289 | if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) | ||
290 | return 0x7C; | ||
291 | break; | ||
292 | case 1: | ||
293 | return 0x69; | ||
294 | case 2: | ||
295 | if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) | ||
296 | return 0x7F; | ||
297 | break; | ||
298 | case 3: | ||
299 | if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) | ||
300 | return 0x7E; | ||
301 | break; | ||
302 | case 4: | ||
303 | if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) | ||
304 | return 0x4B; | ||
305 | break; | ||
306 | case 5: | ||
307 | if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) | ||
308 | return 0x49; | ||
309 | break; | ||
310 | case 6: | ||
311 | if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) | ||
312 | return 0x68; | ||
313 | break; | ||
314 | case 7: | ||
315 | if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) | ||
316 | return 0x7D; | ||
317 | break; | ||
318 | case 8: | ||
319 | if (!(data->pin_cfg[2] & ADT7462_PIN26_VOLT_INPUT)) | ||
320 | return 0x6C; | ||
321 | break; | ||
322 | case 9: | ||
323 | if (!(data->pin_cfg[2] & ADT7462_PIN25_VOLT_INPUT)) | ||
324 | return 0x6B; | ||
325 | break; | ||
326 | case 10: | ||
327 | return 0x6A; | ||
328 | case 11: | ||
329 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | ||
330 | ADT7462_PIN28_VOLT && | ||
331 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | ||
332 | return 0x50; | ||
333 | break; | ||
334 | case 12: | ||
335 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | ||
336 | ADT7462_PIN28_VOLT && | ||
337 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | ||
338 | return 0x4C; | ||
339 | break; | ||
340 | } | ||
341 | return -ENODEV; | ||
342 | } | ||
343 | |||
344 | static int ADT7462_REG_VOLT_MIN(struct adt7462_data *data, int which) | ||
345 | { | ||
346 | switch (which) { | ||
347 | case 0: | ||
348 | if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) | ||
349 | return 0x6D; | ||
350 | break; | ||
351 | case 1: | ||
352 | return 0x72; | ||
353 | case 2: | ||
354 | if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) | ||
355 | return 0x6F; | ||
356 | break; | ||
357 | case 3: | ||
358 | if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) | ||
359 | return 0x71; | ||
360 | break; | ||
361 | case 4: | ||
362 | if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) | ||
363 | return 0x47; | ||
364 | break; | ||
365 | case 5: | ||
366 | if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) | ||
367 | return 0x45; | ||
368 | break; | ||
369 | case 6: | ||
370 | if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) | ||
371 | return 0x70; | ||
372 | break; | ||
373 | case 7: | ||
374 | if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) | ||
375 | return 0x6E; | ||
376 | break; | ||
377 | case 8: | ||
378 | if (!(data->pin_cfg[2] & ADT7462_PIN26_VOLT_INPUT)) | ||
379 | return 0x75; | ||
380 | break; | ||
381 | case 9: | ||
382 | if (!(data->pin_cfg[2] & ADT7462_PIN25_VOLT_INPUT)) | ||
383 | return 0x74; | ||
384 | break; | ||
385 | case 10: | ||
386 | return 0x73; | ||
387 | case 11: | ||
388 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | ||
389 | ADT7462_PIN28_VOLT && | ||
390 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | ||
391 | return 0x76; | ||
392 | break; | ||
393 | case 12: | ||
394 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | ||
395 | ADT7462_PIN28_VOLT && | ||
396 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | ||
397 | return 0x77; | ||
398 | break; | ||
399 | } | ||
400 | return -ENODEV; | ||
401 | } | ||
402 | |||
403 | static int ADT7462_REG_VOLT(struct adt7462_data *data, int which) | ||
404 | { | ||
405 | switch (which) { | ||
406 | case 0: | ||
407 | if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) | ||
408 | return 0xA3; | ||
409 | break; | ||
410 | case 1: | ||
411 | return 0x90; | ||
412 | case 2: | ||
413 | if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) | ||
414 | return 0xA9; | ||
415 | break; | ||
416 | case 3: | ||
417 | if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) | ||
418 | return 0xA7; | ||
419 | break; | ||
420 | case 4: | ||
421 | if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) | ||
422 | return 0x8F; | ||
423 | break; | ||
424 | case 5: | ||
425 | if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) | ||
426 | return 0x8B; | ||
427 | break; | ||
428 | case 6: | ||
429 | if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) | ||
430 | return 0x96; | ||
431 | break; | ||
432 | case 7: | ||
433 | if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) | ||
434 | return 0xA5; | ||
435 | break; | ||
436 | case 8: | ||
437 | if (!(data->pin_cfg[2] & ADT7462_PIN26_VOLT_INPUT)) | ||
438 | return 0x93; | ||
439 | break; | ||
440 | case 9: | ||
441 | if (!(data->pin_cfg[2] & ADT7462_PIN25_VOLT_INPUT)) | ||
442 | return 0x92; | ||
443 | break; | ||
444 | case 10: | ||
445 | return 0x91; | ||
446 | case 11: | ||
447 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | ||
448 | ADT7462_PIN28_VOLT && | ||
449 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | ||
450 | return 0x94; | ||
451 | break; | ||
452 | case 12: | ||
453 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | ||
454 | ADT7462_PIN28_VOLT && | ||
455 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | ||
456 | return 0x95; | ||
457 | break; | ||
458 | } | ||
459 | return -ENODEV; | ||
460 | } | ||
461 | |||
462 | /* Provide labels for sysfs */ | ||
463 | static const char *voltage_label(struct adt7462_data *data, int which) | ||
464 | { | ||
465 | switch (which) { | ||
466 | case 0: | ||
467 | if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) | ||
468 | return "+12V1"; | ||
469 | break; | ||
470 | case 1: | ||
471 | switch (MASK_AND_SHIFT(data->pin_cfg[1], ADT7462_PIN23)) { | ||
472 | case 0: | ||
473 | return "Vccp1"; | ||
474 | case 1: | ||
475 | return "+2.5V"; | ||
476 | case 2: | ||
477 | return "+1.8V"; | ||
478 | case 3: | ||
479 | return "+1.5V"; | ||
480 | } | ||
481 | case 2: | ||
482 | if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) | ||
483 | return "+12V3"; | ||
484 | break; | ||
485 | case 3: | ||
486 | if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) | ||
487 | return "+5V"; | ||
488 | break; | ||
489 | case 4: | ||
490 | if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) { | ||
491 | if (data->pin_cfg[1] & ADT7462_PIN19_INPUT) | ||
492 | return "+0.9V"; | ||
493 | return "+1.25V"; | ||
494 | } | ||
495 | break; | ||
496 | case 5: | ||
497 | if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) { | ||
498 | if (data->pin_cfg[1] & ADT7462_PIN19_INPUT) | ||
499 | return "+1.8V"; | ||
500 | return "+2.5V"; | ||
501 | } | ||
502 | break; | ||
503 | case 6: | ||
504 | if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) | ||
505 | return "+3.3V"; | ||
506 | break; | ||
507 | case 7: | ||
508 | if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) | ||
509 | return "+12V2"; | ||
510 | break; | ||
511 | case 8: | ||
512 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN26)) { | ||
513 | case 0: | ||
514 | return "Vbatt"; | ||
515 | case 1: | ||
516 | return "FSB_Vtt"; | ||
517 | } | ||
518 | break; | ||
519 | case 9: | ||
520 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN25)) { | ||
521 | case 0: | ||
522 | return "+3.3V"; | ||
523 | case 1: | ||
524 | return "+1.2V1"; | ||
525 | } | ||
526 | break; | ||
527 | case 10: | ||
528 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN24)) { | ||
529 | case 0: | ||
530 | return "Vccp2"; | ||
531 | case 1: | ||
532 | return "+2.5V"; | ||
533 | case 2: | ||
534 | return "+1.8V"; | ||
535 | case 3: | ||
536 | return "+1.5"; | ||
537 | } | ||
538 | case 11: | ||
539 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | ||
540 | ADT7462_PIN28_VOLT && | ||
541 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | ||
542 | return "+1.5V ICH"; | ||
543 | break; | ||
544 | case 12: | ||
545 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | ||
546 | ADT7462_PIN28_VOLT && | ||
547 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | ||
548 | return "+1.5V 3GPIO"; | ||
549 | break; | ||
550 | } | ||
551 | return "N/A"; | ||
552 | } | ||
553 | |||
554 | /* Multipliers are actually in uV, not mV. */ | ||
555 | static int voltage_multiplier(struct adt7462_data *data, int which) | ||
556 | { | ||
557 | switch (which) { | ||
558 | case 0: | ||
559 | if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) | ||
560 | return 62500; | ||
561 | break; | ||
562 | case 1: | ||
563 | switch (MASK_AND_SHIFT(data->pin_cfg[1], ADT7462_PIN23)) { | ||
564 | case 0: | ||
565 | if (data->pin_cfg[0] & ADT7462_VID_INPUT) | ||
566 | return 12500; | ||
567 | return 6250; | ||
568 | case 1: | ||
569 | return 13000; | ||
570 | case 2: | ||
571 | return 9400; | ||
572 | case 3: | ||
573 | return 7800; | ||
574 | } | ||
575 | case 2: | ||
576 | if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) | ||
577 | return 62500; | ||
578 | break; | ||
579 | case 3: | ||
580 | if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) | ||
581 | return 26000; | ||
582 | break; | ||
583 | case 4: | ||
584 | if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) { | ||
585 | if (data->pin_cfg[1] & ADT7462_PIN19_INPUT) | ||
586 | return 4690; | ||
587 | return 6500; | ||
588 | } | ||
589 | break; | ||
590 | case 5: | ||
591 | if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) { | ||
592 | if (data->pin_cfg[1] & ADT7462_PIN15_INPUT) | ||
593 | return 9400; | ||
594 | return 13000; | ||
595 | } | ||
596 | break; | ||
597 | case 6: | ||
598 | if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) | ||
599 | return 17200; | ||
600 | break; | ||
601 | case 7: | ||
602 | if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) | ||
603 | return 62500; | ||
604 | break; | ||
605 | case 8: | ||
606 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN26)) { | ||
607 | case 0: | ||
608 | return 15600; | ||
609 | case 1: | ||
610 | return 6250; | ||
611 | } | ||
612 | break; | ||
613 | case 9: | ||
614 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN25)) { | ||
615 | case 0: | ||
616 | return 17200; | ||
617 | case 1: | ||
618 | return 6250; | ||
619 | } | ||
620 | break; | ||
621 | case 10: | ||
622 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN24)) { | ||
623 | case 0: | ||
624 | return 6250; | ||
625 | case 1: | ||
626 | return 13000; | ||
627 | case 2: | ||
628 | return 9400; | ||
629 | case 3: | ||
630 | return 7800; | ||
631 | } | ||
632 | case 11: | ||
633 | case 12: | ||
634 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | ||
635 | ADT7462_PIN28_VOLT && | ||
636 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | ||
637 | return 7800; | ||
638 | } | ||
639 | return 0; | ||
640 | } | ||
641 | |||
642 | static int temp_enabled(struct adt7462_data *data, int which) | ||
643 | { | ||
644 | switch (which) { | ||
645 | case 0: | ||
646 | case 2: | ||
647 | return 1; | ||
648 | case 1: | ||
649 | if (data->pin_cfg[0] & ADT7462_DIODE1_INPUT) | ||
650 | return 1; | ||
651 | break; | ||
652 | case 3: | ||
653 | if (data->pin_cfg[0] & ADT7462_DIODE3_INPUT) | ||
654 | return 1; | ||
655 | break; | ||
656 | } | ||
657 | return 0; | ||
658 | } | ||
659 | |||
660 | static const char *temp_label(struct adt7462_data *data, int which) | ||
661 | { | ||
662 | switch (which) { | ||
663 | case 0: | ||
664 | return "local"; | ||
665 | case 1: | ||
666 | if (data->pin_cfg[0] & ADT7462_DIODE1_INPUT) | ||
667 | return "remote1"; | ||
668 | break; | ||
669 | case 2: | ||
670 | return "remote2"; | ||
671 | case 3: | ||
672 | if (data->pin_cfg[0] & ADT7462_DIODE3_INPUT) | ||
673 | return "remote3"; | ||
674 | break; | ||
675 | } | ||
676 | return "N/A"; | ||
677 | } | ||
678 | |||
679 | /* Map Trange register values to mC */ | ||
680 | #define NUM_TRANGE_VALUES 16 | ||
681 | static const int trange_values[NUM_TRANGE_VALUES] = { | ||
682 | 2000, | ||
683 | 2500, | ||
684 | 3300, | ||
685 | 4000, | ||
686 | 5000, | ||
687 | 6700, | ||
688 | 8000, | ||
689 | 10000, | ||
690 | 13300, | ||
691 | 16000, | ||
692 | 20000, | ||
693 | 26700, | ||
694 | 32000, | ||
695 | 40000, | ||
696 | 53300, | ||
697 | 80000 | ||
698 | }; | ||
699 | |||
700 | static int find_trange_value(int trange) | ||
701 | { | ||
702 | int i; | ||
703 | |||
704 | for (i = 0; i < NUM_TRANGE_VALUES; i++) | ||
705 | if (trange_values[i] == trange) | ||
706 | return i; | ||
707 | |||
708 | return -ENODEV; | ||
709 | } | ||
710 | |||
711 | static struct adt7462_data *adt7462_update_device(struct device *dev) | ||
712 | { | ||
713 | struct i2c_client *client = to_i2c_client(dev); | ||
714 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
715 | unsigned long local_jiffies = jiffies; | ||
716 | int i; | ||
717 | |||
718 | mutex_lock(&data->lock); | ||
719 | if (time_before(local_jiffies, data->sensors_last_updated + | ||
720 | SENSOR_REFRESH_INTERVAL) | ||
721 | && data->sensors_valid) | ||
722 | goto no_sensor_update; | ||
723 | |||
724 | for (i = 0; i < ADT7462_TEMP_COUNT; i++) { | ||
725 | /* | ||
726 | * Reading the fractional register locks the integral | ||
727 | * register until both have been read. | ||
728 | */ | ||
729 | data->temp_frac[i] = i2c_smbus_read_byte_data(client, | ||
730 | ADT7462_TEMP_REG(i)); | ||
731 | data->temp[i] = i2c_smbus_read_byte_data(client, | ||
732 | ADT7462_TEMP_REG(i) + 1); | ||
733 | } | ||
734 | |||
735 | for (i = 0; i < ADT7462_FAN_COUNT; i++) | ||
736 | data->fan[i] = adt7462_read_word_data(client, | ||
737 | ADT7462_REG_FAN(i)); | ||
738 | |||
739 | data->fan_enabled = i2c_smbus_read_byte_data(client, | ||
740 | ADT7462_REG_FAN_ENABLE); | ||
741 | |||
742 | for (i = 0; i < ADT7462_PWM_COUNT; i++) | ||
743 | data->pwm[i] = i2c_smbus_read_byte_data(client, | ||
744 | ADT7462_REG_PWM(i)); | ||
745 | |||
746 | for (i = 0; i < ADT7462_PIN_CFG_REG_COUNT; i++) | ||
747 | data->pin_cfg[i] = i2c_smbus_read_byte_data(client, | ||
748 | ADT7462_REG_PIN_CFG(i)); | ||
749 | |||
750 | for (i = 0; i < ADT7462_VOLT_COUNT; i++) { | ||
751 | int reg = ADT7462_REG_VOLT(data, i); | ||
752 | if (!reg) | ||
753 | data->voltages[i] = 0; | ||
754 | else | ||
755 | data->voltages[i] = i2c_smbus_read_byte_data(client, | ||
756 | reg); | ||
757 | } | ||
758 | |||
759 | data->alarms[0] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM1); | ||
760 | data->alarms[1] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM2); | ||
761 | data->alarms[2] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM3); | ||
762 | data->alarms[3] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM4); | ||
763 | |||
764 | data->sensors_last_updated = local_jiffies; | ||
765 | data->sensors_valid = 1; | ||
766 | |||
767 | no_sensor_update: | ||
768 | if (time_before(local_jiffies, data->limits_last_updated + | ||
769 | LIMIT_REFRESH_INTERVAL) | ||
770 | && data->limits_valid) | ||
771 | goto out; | ||
772 | |||
773 | for (i = 0; i < ADT7462_TEMP_COUNT; i++) { | ||
774 | data->temp_min[i] = i2c_smbus_read_byte_data(client, | ||
775 | ADT7462_TEMP_MIN_REG(i)); | ||
776 | data->temp_max[i] = i2c_smbus_read_byte_data(client, | ||
777 | ADT7462_TEMP_MAX_REG(i)); | ||
778 | } | ||
779 | |||
780 | for (i = 0; i < ADT7462_FAN_COUNT; i++) | ||
781 | data->fan_min[i] = i2c_smbus_read_byte_data(client, | ||
782 | ADT7462_REG_FAN_MIN(i)); | ||
783 | |||
784 | for (i = 0; i < ADT7462_VOLT_COUNT; i++) { | ||
785 | int reg = ADT7462_REG_VOLT_MAX(data, i); | ||
786 | data->volt_max[i] = | ||
787 | (reg ? i2c_smbus_read_byte_data(client, reg) : 0); | ||
788 | |||
789 | reg = ADT7462_REG_VOLT_MIN(data, i); | ||
790 | data->volt_min[i] = | ||
791 | (reg ? i2c_smbus_read_byte_data(client, reg) : 0); | ||
792 | } | ||
793 | |||
794 | for (i = 0; i < ADT7462_PWM_COUNT; i++) { | ||
795 | data->pwm_min[i] = i2c_smbus_read_byte_data(client, | ||
796 | ADT7462_REG_PWM_MIN(i)); | ||
797 | data->pwm_tmin[i] = i2c_smbus_read_byte_data(client, | ||
798 | ADT7462_REG_PWM_TMIN(i)); | ||
799 | data->pwm_trange[i] = i2c_smbus_read_byte_data(client, | ||
800 | ADT7462_REG_PWM_TRANGE(i)); | ||
801 | data->pwm_cfg[i] = i2c_smbus_read_byte_data(client, | ||
802 | ADT7462_REG_PWM_CFG(i)); | ||
803 | } | ||
804 | |||
805 | data->pwm_max = i2c_smbus_read_byte_data(client, ADT7462_REG_PWM_MAX); | ||
806 | |||
807 | data->cfg2 = i2c_smbus_read_byte_data(client, ADT7462_REG_CFG2); | ||
808 | |||
809 | data->limits_last_updated = local_jiffies; | ||
810 | data->limits_valid = 1; | ||
811 | |||
812 | out: | ||
813 | mutex_unlock(&data->lock); | ||
814 | return data; | ||
815 | } | ||
816 | |||
817 | static ssize_t show_temp_min(struct device *dev, | ||
818 | struct device_attribute *devattr, | ||
819 | char *buf) | ||
820 | { | ||
821 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
822 | struct adt7462_data *data = adt7462_update_device(dev); | ||
823 | |||
824 | if (!temp_enabled(data, attr->index)) | ||
825 | return sprintf(buf, "0\n"); | ||
826 | |||
827 | return sprintf(buf, "%d\n", 1000 * (data->temp_min[attr->index] - 64)); | ||
828 | } | ||
829 | |||
830 | static ssize_t set_temp_min(struct device *dev, | ||
831 | struct device_attribute *devattr, | ||
832 | const char *buf, | ||
833 | size_t count) | ||
834 | { | ||
835 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
836 | struct i2c_client *client = to_i2c_client(dev); | ||
837 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
838 | long temp; | ||
839 | |||
840 | if (strict_strtol(buf, 10, &temp) || !temp_enabled(data, attr->index)) | ||
841 | return -EINVAL; | ||
842 | |||
843 | temp = ROUND_DIV(temp, 1000) + 64; | ||
844 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
845 | |||
846 | mutex_lock(&data->lock); | ||
847 | data->temp_min[attr->index] = temp; | ||
848 | i2c_smbus_write_byte_data(client, ADT7462_TEMP_MIN_REG(attr->index), | ||
849 | temp); | ||
850 | mutex_unlock(&data->lock); | ||
851 | |||
852 | return count; | ||
853 | } | ||
854 | |||
855 | static ssize_t show_temp_max(struct device *dev, | ||
856 | struct device_attribute *devattr, | ||
857 | char *buf) | ||
858 | { | ||
859 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
860 | struct adt7462_data *data = adt7462_update_device(dev); | ||
861 | |||
862 | if (!temp_enabled(data, attr->index)) | ||
863 | return sprintf(buf, "0\n"); | ||
864 | |||
865 | return sprintf(buf, "%d\n", 1000 * (data->temp_max[attr->index] - 64)); | ||
866 | } | ||
867 | |||
868 | static ssize_t set_temp_max(struct device *dev, | ||
869 | struct device_attribute *devattr, | ||
870 | const char *buf, | ||
871 | size_t count) | ||
872 | { | ||
873 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
874 | struct i2c_client *client = to_i2c_client(dev); | ||
875 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
876 | long temp; | ||
877 | |||
878 | if (strict_strtol(buf, 10, &temp) || !temp_enabled(data, attr->index)) | ||
879 | return -EINVAL; | ||
880 | |||
881 | temp = ROUND_DIV(temp, 1000) + 64; | ||
882 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
883 | |||
884 | mutex_lock(&data->lock); | ||
885 | data->temp_max[attr->index] = temp; | ||
886 | i2c_smbus_write_byte_data(client, ADT7462_TEMP_MAX_REG(attr->index), | ||
887 | temp); | ||
888 | mutex_unlock(&data->lock); | ||
889 | |||
890 | return count; | ||
891 | } | ||
892 | |||
893 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, | ||
894 | char *buf) | ||
895 | { | ||
896 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
897 | struct adt7462_data *data = adt7462_update_device(dev); | ||
898 | u8 frac = data->temp_frac[attr->index] >> TEMP_FRAC_OFFSET; | ||
899 | |||
900 | if (!temp_enabled(data, attr->index)) | ||
901 | return sprintf(buf, "0\n"); | ||
902 | |||
903 | return sprintf(buf, "%d\n", 1000 * (data->temp[attr->index] - 64) + | ||
904 | 250 * frac); | ||
905 | } | ||
906 | |||
907 | static ssize_t show_temp_label(struct device *dev, | ||
908 | struct device_attribute *devattr, | ||
909 | char *buf) | ||
910 | { | ||
911 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
912 | struct adt7462_data *data = adt7462_update_device(dev); | ||
913 | |||
914 | return sprintf(buf, "%s\n", temp_label(data, attr->index)); | ||
915 | } | ||
916 | |||
917 | static ssize_t show_volt_max(struct device *dev, | ||
918 | struct device_attribute *devattr, | ||
919 | char *buf) | ||
920 | { | ||
921 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
922 | struct adt7462_data *data = adt7462_update_device(dev); | ||
923 | int x = voltage_multiplier(data, attr->index); | ||
924 | |||
925 | x *= data->volt_max[attr->index]; | ||
926 | x /= 1000; /* convert from uV to mV */ | ||
927 | |||
928 | return sprintf(buf, "%d\n", x); | ||
929 | } | ||
930 | |||
931 | static ssize_t set_volt_max(struct device *dev, | ||
932 | struct device_attribute *devattr, | ||
933 | const char *buf, | ||
934 | size_t count) | ||
935 | { | ||
936 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
937 | struct i2c_client *client = to_i2c_client(dev); | ||
938 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
939 | int x = voltage_multiplier(data, attr->index); | ||
940 | long temp; | ||
941 | |||
942 | if (strict_strtol(buf, 10, &temp) || !x) | ||
943 | return -EINVAL; | ||
944 | |||
945 | temp *= 1000; /* convert mV to uV */ | ||
946 | temp = ROUND_DIV(temp, x); | ||
947 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
948 | |||
949 | mutex_lock(&data->lock); | ||
950 | data->volt_max[attr->index] = temp; | ||
951 | i2c_smbus_write_byte_data(client, | ||
952 | ADT7462_REG_VOLT_MAX(data, attr->index), | ||
953 | temp); | ||
954 | mutex_unlock(&data->lock); | ||
955 | |||
956 | return count; | ||
957 | } | ||
958 | |||
959 | static ssize_t show_volt_min(struct device *dev, | ||
960 | struct device_attribute *devattr, | ||
961 | char *buf) | ||
962 | { | ||
963 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
964 | struct adt7462_data *data = adt7462_update_device(dev); | ||
965 | int x = voltage_multiplier(data, attr->index); | ||
966 | |||
967 | x *= data->volt_min[attr->index]; | ||
968 | x /= 1000; /* convert from uV to mV */ | ||
969 | |||
970 | return sprintf(buf, "%d\n", x); | ||
971 | } | ||
972 | |||
973 | static ssize_t set_volt_min(struct device *dev, | ||
974 | struct device_attribute *devattr, | ||
975 | const char *buf, | ||
976 | size_t count) | ||
977 | { | ||
978 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
979 | struct i2c_client *client = to_i2c_client(dev); | ||
980 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
981 | int x = voltage_multiplier(data, attr->index); | ||
982 | long temp; | ||
983 | |||
984 | if (strict_strtol(buf, 10, &temp) || !x) | ||
985 | return -EINVAL; | ||
986 | |||
987 | temp *= 1000; /* convert mV to uV */ | ||
988 | temp = ROUND_DIV(temp, x); | ||
989 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
990 | |||
991 | mutex_lock(&data->lock); | ||
992 | data->volt_min[attr->index] = temp; | ||
993 | i2c_smbus_write_byte_data(client, | ||
994 | ADT7462_REG_VOLT_MIN(data, attr->index), | ||
995 | temp); | ||
996 | mutex_unlock(&data->lock); | ||
997 | |||
998 | return count; | ||
999 | } | ||
1000 | |||
1001 | static ssize_t show_voltage(struct device *dev, | ||
1002 | struct device_attribute *devattr, | ||
1003 | char *buf) | ||
1004 | { | ||
1005 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
1006 | struct adt7462_data *data = adt7462_update_device(dev); | ||
1007 | int x = voltage_multiplier(data, attr->index); | ||
1008 | |||
1009 | x *= data->voltages[attr->index]; | ||
1010 | x /= 1000; /* convert from uV to mV */ | ||
1011 | |||
1012 | return sprintf(buf, "%d\n", x); | ||
1013 | } | ||
1014 | |||
1015 | static ssize_t show_voltage_label(struct device *dev, | ||
1016 | struct device_attribute *devattr, | ||
1017 | char *buf) | ||
1018 | { | ||
1019 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
1020 | struct adt7462_data *data = adt7462_update_device(dev); | ||
1021 | |||
1022 | return sprintf(buf, "%s\n", voltage_label(data, attr->index)); | ||
1023 | } | ||
1024 | |||
1025 | static ssize_t show_alarm(struct device *dev, | ||
1026 | struct device_attribute *devattr, | ||
1027 | char *buf) | ||
1028 | { | ||
1029 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
1030 | struct adt7462_data *data = adt7462_update_device(dev); | ||
1031 | int reg = attr->index >> ADT7462_ALARM_REG_SHIFT; | ||
1032 | int mask = attr->index & ADT7462_ALARM_FLAG_MASK; | ||
1033 | |||
1034 | if (data->alarms[reg] & mask) | ||
1035 | return sprintf(buf, "1\n"); | ||
1036 | else | ||
1037 | return sprintf(buf, "0\n"); | ||
1038 | } | ||
1039 | |||
1040 | static int fan_enabled(struct adt7462_data *data, int fan) | ||
1041 | { | ||
1042 | return data->fan_enabled & (1 << fan); | ||
1043 | } | ||
1044 | |||
1045 | static ssize_t show_fan_min(struct device *dev, | ||
1046 | struct device_attribute *devattr, | ||
1047 | char *buf) | ||
1048 | { | ||
1049 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
1050 | struct adt7462_data *data = adt7462_update_device(dev); | ||
1051 | u16 temp; | ||
1052 | |||
1053 | /* Only the MSB of the min fan period is stored... */ | ||
1054 | temp = data->fan_min[attr->index]; | ||
1055 | temp <<= 8; | ||
1056 | |||
1057 | if (!fan_enabled(data, attr->index) || | ||
1058 | !FAN_DATA_VALID(temp)) | ||
1059 | return sprintf(buf, "0\n"); | ||
1060 | |||
1061 | return sprintf(buf, "%d\n", FAN_PERIOD_TO_RPM(temp)); | ||
1062 | } | ||
1063 | |||
1064 | static ssize_t set_fan_min(struct device *dev, | ||
1065 | struct device_attribute *devattr, | ||
1066 | const char *buf, size_t count) | ||
1067 | { | ||
1068 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
1069 | struct i2c_client *client = to_i2c_client(dev); | ||
1070 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
1071 | long temp; | ||
1072 | |||
1073 | if (strict_strtol(buf, 10, &temp) || !temp || | ||
1074 | !fan_enabled(data, attr->index)) | ||
1075 | return -EINVAL; | ||
1076 | |||
1077 | temp = FAN_RPM_TO_PERIOD(temp); | ||
1078 | temp >>= 8; | ||
1079 | temp = SENSORS_LIMIT(temp, 1, 255); | ||
1080 | |||
1081 | mutex_lock(&data->lock); | ||
1082 | data->fan_min[attr->index] = temp; | ||
1083 | i2c_smbus_write_byte_data(client, ADT7462_REG_FAN_MIN(attr->index), | ||
1084 | temp); | ||
1085 | mutex_unlock(&data->lock); | ||
1086 | |||
1087 | return count; | ||
1088 | } | ||
1089 | |||
1090 | static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, | ||
1091 | char *buf) | ||
1092 | { | ||
1093 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
1094 | struct adt7462_data *data = adt7462_update_device(dev); | ||
1095 | |||
1096 | if (!fan_enabled(data, attr->index) || | ||
1097 | !FAN_DATA_VALID(data->fan[attr->index])) | ||
1098 | return sprintf(buf, "0\n"); | ||
1099 | |||
1100 | return sprintf(buf, "%d\n", | ||
1101 | FAN_PERIOD_TO_RPM(data->fan[attr->index])); | ||
1102 | } | ||
1103 | |||
1104 | static ssize_t show_force_pwm_max(struct device *dev, | ||
1105 | struct device_attribute *devattr, | ||
1106 | char *buf) | ||
1107 | { | ||
1108 | struct adt7462_data *data = adt7462_update_device(dev); | ||
1109 | return sprintf(buf, "%d\n", (data->cfg2 & ADT7462_FSPD_MASK ? 1 : 0)); | ||
1110 | } | ||
1111 | |||
1112 | static ssize_t set_force_pwm_max(struct device *dev, | ||
1113 | struct device_attribute *devattr, | ||
1114 | const char *buf, | ||
1115 | size_t count) | ||
1116 | { | ||
1117 | struct i2c_client *client = to_i2c_client(dev); | ||
1118 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
1119 | long temp; | ||
1120 | u8 reg; | ||
1121 | |||
1122 | if (strict_strtol(buf, 10, &temp)) | ||
1123 | return -EINVAL; | ||
1124 | |||
1125 | mutex_lock(&data->lock); | ||
1126 | reg = i2c_smbus_read_byte_data(client, ADT7462_REG_CFG2); | ||
1127 | if (temp) | ||
1128 | reg |= ADT7462_FSPD_MASK; | ||
1129 | else | ||
1130 | reg &= ~ADT7462_FSPD_MASK; | ||
1131 | data->cfg2 = reg; | ||
1132 | i2c_smbus_write_byte_data(client, ADT7462_REG_CFG2, reg); | ||
1133 | mutex_unlock(&data->lock); | ||
1134 | |||
1135 | return count; | ||
1136 | } | ||
1137 | |||
1138 | static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, | ||
1139 | char *buf) | ||
1140 | { | ||
1141 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
1142 | struct adt7462_data *data = adt7462_update_device(dev); | ||
1143 | return sprintf(buf, "%d\n", data->pwm[attr->index]); | ||
1144 | } | ||
1145 | |||
1146 | static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, | ||
1147 | const char *buf, size_t count) | ||
1148 | { | ||
1149 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
1150 | struct i2c_client *client = to_i2c_client(dev); | ||
1151 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
1152 | long temp; | ||
1153 | |||
1154 | if (strict_strtol(buf, 10, &temp)) | ||
1155 | return -EINVAL; | ||
1156 | |||
1157 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
1158 | |||
1159 | mutex_lock(&data->lock); | ||
1160 | data->pwm[attr->index] = temp; | ||
1161 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM(attr->index), temp); | ||
1162 | mutex_unlock(&data->lock); | ||
1163 | |||
1164 | return count; | ||
1165 | } | ||
1166 | |||
1167 | static ssize_t show_pwm_max(struct device *dev, | ||
1168 | struct device_attribute *devattr, | ||
1169 | char *buf) | ||
1170 | { | ||
1171 | struct adt7462_data *data = adt7462_update_device(dev); | ||
1172 | return sprintf(buf, "%d\n", data->pwm_max); | ||
1173 | } | ||
1174 | |||
1175 | static ssize_t set_pwm_max(struct device *dev, | ||
1176 | struct device_attribute *devattr, | ||
1177 | const char *buf, | ||
1178 | size_t count) | ||
1179 | { | ||
1180 | struct i2c_client *client = to_i2c_client(dev); | ||
1181 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
1182 | long temp; | ||
1183 | |||
1184 | if (strict_strtol(buf, 10, &temp)) | ||
1185 | return -EINVAL; | ||
1186 | |||
1187 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
1188 | |||
1189 | mutex_lock(&data->lock); | ||
1190 | data->pwm_max = temp; | ||
1191 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_MAX, temp); | ||
1192 | mutex_unlock(&data->lock); | ||
1193 | |||
1194 | return count; | ||
1195 | } | ||
1196 | |||
1197 | static ssize_t show_pwm_min(struct device *dev, | ||
1198 | struct device_attribute *devattr, | ||
1199 | char *buf) | ||
1200 | { | ||
1201 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
1202 | struct adt7462_data *data = adt7462_update_device(dev); | ||
1203 | return sprintf(buf, "%d\n", data->pwm_min[attr->index]); | ||
1204 | } | ||
1205 | |||
1206 | static ssize_t set_pwm_min(struct device *dev, | ||
1207 | struct device_attribute *devattr, | ||
1208 | const char *buf, | ||
1209 | size_t count) | ||
1210 | { | ||
1211 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
1212 | struct i2c_client *client = to_i2c_client(dev); | ||
1213 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
1214 | long temp; | ||
1215 | |||
1216 | if (strict_strtol(buf, 10, &temp)) | ||
1217 | return -EINVAL; | ||
1218 | |||
1219 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
1220 | |||
1221 | mutex_lock(&data->lock); | ||
1222 | data->pwm_min[attr->index] = temp; | ||
1223 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_MIN(attr->index), | ||
1224 | temp); | ||
1225 | mutex_unlock(&data->lock); | ||
1226 | |||
1227 | return count; | ||
1228 | } | ||
1229 | |||
1230 | static ssize_t show_pwm_hyst(struct device *dev, | ||
1231 | struct device_attribute *devattr, | ||
1232 | char *buf) | ||
1233 | { | ||
1234 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
1235 | struct adt7462_data *data = adt7462_update_device(dev); | ||
1236 | return sprintf(buf, "%d\n", 1000 * | ||
1237 | (data->pwm_trange[attr->index] & ADT7462_PWM_HYST_MASK)); | ||
1238 | } | ||
1239 | |||
1240 | static ssize_t set_pwm_hyst(struct device *dev, | ||
1241 | struct device_attribute *devattr, | ||
1242 | const char *buf, | ||
1243 | size_t count) | ||
1244 | { | ||
1245 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
1246 | struct i2c_client *client = to_i2c_client(dev); | ||
1247 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
1248 | long temp; | ||
1249 | |||
1250 | if (strict_strtol(buf, 10, &temp)) | ||
1251 | return -EINVAL; | ||
1252 | |||
1253 | temp = ROUND_DIV(temp, 1000); | ||
1254 | temp = SENSORS_LIMIT(temp, 0, 15); | ||
1255 | |||
1256 | /* package things up */ | ||
1257 | temp &= ADT7462_PWM_HYST_MASK; | ||
1258 | temp |= data->pwm_trange[attr->index] & ADT7462_PWM_RANGE_MASK; | ||
1259 | |||
1260 | mutex_lock(&data->lock); | ||
1261 | data->pwm_trange[attr->index] = temp; | ||
1262 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_TRANGE(attr->index), | ||
1263 | temp); | ||
1264 | mutex_unlock(&data->lock); | ||
1265 | |||
1266 | return count; | ||
1267 | } | ||
1268 | |||
1269 | static ssize_t show_pwm_tmax(struct device *dev, | ||
1270 | struct device_attribute *devattr, | ||
1271 | char *buf) | ||
1272 | { | ||
1273 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
1274 | struct adt7462_data *data = adt7462_update_device(dev); | ||
1275 | |||
1276 | /* tmax = tmin + trange */ | ||
1277 | int trange = trange_values[data->pwm_trange[attr->index] >> | ||
1278 | ADT7462_PWM_RANGE_SHIFT]; | ||
1279 | int tmin = (data->pwm_tmin[attr->index] - 64) * 1000; | ||
1280 | |||
1281 | return sprintf(buf, "%d\n", tmin + trange); | ||
1282 | } | ||
1283 | |||
1284 | static ssize_t set_pwm_tmax(struct device *dev, | ||
1285 | struct device_attribute *devattr, | ||
1286 | const char *buf, | ||
1287 | size_t count) | ||
1288 | { | ||
1289 | int temp; | ||
1290 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
1291 | struct i2c_client *client = to_i2c_client(dev); | ||
1292 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
1293 | int tmin, trange_value; | ||
1294 | long trange; | ||
1295 | |||
1296 | if (strict_strtol(buf, 10, &trange)) | ||
1297 | return -EINVAL; | ||
1298 | |||
1299 | /* trange = tmax - tmin */ | ||
1300 | tmin = (data->pwm_tmin[attr->index] - 64) * 1000; | ||
1301 | trange_value = find_trange_value(trange - tmin); | ||
1302 | |||
1303 | if (trange_value < 0) | ||
1304 | return -EINVAL; | ||
1305 | |||
1306 | temp = trange_value << ADT7462_PWM_RANGE_SHIFT; | ||
1307 | temp |= data->pwm_trange[attr->index] & ADT7462_PWM_HYST_MASK; | ||
1308 | |||
1309 | mutex_lock(&data->lock); | ||
1310 | data->pwm_trange[attr->index] = temp; | ||
1311 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_TRANGE(attr->index), | ||
1312 | temp); | ||
1313 | mutex_unlock(&data->lock); | ||
1314 | |||
1315 | return count; | ||
1316 | } | ||
1317 | |||
1318 | static ssize_t show_pwm_tmin(struct device *dev, | ||
1319 | struct device_attribute *devattr, | ||
1320 | char *buf) | ||
1321 | { | ||
1322 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
1323 | struct adt7462_data *data = adt7462_update_device(dev); | ||
1324 | return sprintf(buf, "%d\n", 1000 * (data->pwm_tmin[attr->index] - 64)); | ||
1325 | } | ||
1326 | |||
1327 | static ssize_t set_pwm_tmin(struct device *dev, | ||
1328 | struct device_attribute *devattr, | ||
1329 | const char *buf, | ||
1330 | size_t count) | ||
1331 | { | ||
1332 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
1333 | struct i2c_client *client = to_i2c_client(dev); | ||
1334 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
1335 | long temp; | ||
1336 | |||
1337 | if (strict_strtol(buf, 10, &temp)) | ||
1338 | return -EINVAL; | ||
1339 | |||
1340 | temp = ROUND_DIV(temp, 1000) + 64; | ||
1341 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
1342 | |||
1343 | mutex_lock(&data->lock); | ||
1344 | data->pwm_tmin[attr->index] = temp; | ||
1345 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_TMIN(attr->index), | ||
1346 | temp); | ||
1347 | mutex_unlock(&data->lock); | ||
1348 | |||
1349 | return count; | ||
1350 | } | ||
1351 | |||
1352 | static ssize_t show_pwm_auto(struct device *dev, | ||
1353 | struct device_attribute *devattr, | ||
1354 | char *buf) | ||
1355 | { | ||
1356 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
1357 | struct adt7462_data *data = adt7462_update_device(dev); | ||
1358 | int cfg = data->pwm_cfg[attr->index] >> ADT7462_PWM_CHANNEL_SHIFT; | ||
1359 | |||
1360 | switch (cfg) { | ||
1361 | case 4: /* off */ | ||
1362 | return sprintf(buf, "0\n"); | ||
1363 | case 7: /* manual */ | ||
1364 | return sprintf(buf, "1\n"); | ||
1365 | default: /* automatic */ | ||
1366 | return sprintf(buf, "2\n"); | ||
1367 | } | ||
1368 | } | ||
1369 | |||
1370 | static void set_pwm_channel(struct i2c_client *client, | ||
1371 | struct adt7462_data *data, | ||
1372 | int which, | ||
1373 | int value) | ||
1374 | { | ||
1375 | int temp = data->pwm_cfg[which] & ~ADT7462_PWM_CHANNEL_MASK; | ||
1376 | temp |= value << ADT7462_PWM_CHANNEL_SHIFT; | ||
1377 | |||
1378 | mutex_lock(&data->lock); | ||
1379 | data->pwm_cfg[which] = temp; | ||
1380 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_CFG(which), temp); | ||
1381 | mutex_unlock(&data->lock); | ||
1382 | } | ||
1383 | |||
1384 | static ssize_t set_pwm_auto(struct device *dev, | ||
1385 | struct device_attribute *devattr, | ||
1386 | const char *buf, | ||
1387 | size_t count) | ||
1388 | { | ||
1389 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
1390 | struct i2c_client *client = to_i2c_client(dev); | ||
1391 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
1392 | long temp; | ||
1393 | |||
1394 | if (strict_strtol(buf, 10, &temp)) | ||
1395 | return -EINVAL; | ||
1396 | |||
1397 | switch (temp) { | ||
1398 | case 0: /* off */ | ||
1399 | set_pwm_channel(client, data, attr->index, 4); | ||
1400 | return count; | ||
1401 | case 1: /* manual */ | ||
1402 | set_pwm_channel(client, data, attr->index, 7); | ||
1403 | return count; | ||
1404 | default: | ||
1405 | return -EINVAL; | ||
1406 | } | ||
1407 | } | ||
1408 | |||
1409 | static ssize_t show_pwm_auto_temp(struct device *dev, | ||
1410 | struct device_attribute *devattr, | ||
1411 | char *buf) | ||
1412 | { | ||
1413 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
1414 | struct adt7462_data *data = adt7462_update_device(dev); | ||
1415 | int channel = data->pwm_cfg[attr->index] >> ADT7462_PWM_CHANNEL_SHIFT; | ||
1416 | |||
1417 | switch (channel) { | ||
1418 | case 0: /* temp[1234] only */ | ||
1419 | case 1: | ||
1420 | case 2: | ||
1421 | case 3: | ||
1422 | return sprintf(buf, "%d\n", (1 << channel)); | ||
1423 | case 5: /* temp1 & temp4 */ | ||
1424 | return sprintf(buf, "9\n"); | ||
1425 | case 6: | ||
1426 | return sprintf(buf, "15\n"); | ||
1427 | default: | ||
1428 | return sprintf(buf, "0\n"); | ||
1429 | } | ||
1430 | } | ||
1431 | |||
1432 | static int cvt_auto_temp(int input) | ||
1433 | { | ||
1434 | if (input == 0xF) | ||
1435 | return 6; | ||
1436 | if (input == 0x9) | ||
1437 | return 5; | ||
1438 | if (input < 1 || !is_power_of_2(input)) | ||
1439 | return -EINVAL; | ||
1440 | return ilog2(input); | ||
1441 | } | ||
1442 | |||
1443 | static ssize_t set_pwm_auto_temp(struct device *dev, | ||
1444 | struct device_attribute *devattr, | ||
1445 | const char *buf, | ||
1446 | size_t count) | ||
1447 | { | ||
1448 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
1449 | struct i2c_client *client = to_i2c_client(dev); | ||
1450 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
1451 | long temp; | ||
1452 | |||
1453 | if (strict_strtol(buf, 10, &temp)) | ||
1454 | return -EINVAL; | ||
1455 | |||
1456 | temp = cvt_auto_temp(temp); | ||
1457 | if (temp < 0) | ||
1458 | return temp; | ||
1459 | |||
1460 | set_pwm_channel(client, data, attr->index, temp); | ||
1461 | |||
1462 | return count; | ||
1463 | } | ||
1464 | |||
1465 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
1466 | set_temp_max, 0); | ||
1467 | static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
1468 | set_temp_max, 1); | ||
1469 | static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
1470 | set_temp_max, 2); | ||
1471 | static SENSOR_DEVICE_ATTR(temp4_max, S_IWUSR | S_IRUGO, show_temp_max, | ||
1472 | set_temp_max, 3); | ||
1473 | |||
1474 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
1475 | set_temp_min, 0); | ||
1476 | static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
1477 | set_temp_min, 1); | ||
1478 | static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
1479 | set_temp_min, 2); | ||
1480 | static SENSOR_DEVICE_ATTR(temp4_min, S_IWUSR | S_IRUGO, show_temp_min, | ||
1481 | set_temp_min, 3); | ||
1482 | |||
1483 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); | ||
1484 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); | ||
1485 | static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); | ||
1486 | static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3); | ||
1487 | |||
1488 | static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_temp_label, NULL, 0); | ||
1489 | static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_temp_label, NULL, 1); | ||
1490 | static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, show_temp_label, NULL, 2); | ||
1491 | static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, show_temp_label, NULL, 3); | ||
1492 | |||
1493 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, | ||
1494 | ADT7462_ALARM1 | ADT7462_LT_ALARM); | ||
1495 | static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, | ||
1496 | ADT7462_ALARM1 | ADT7462_R1T_ALARM); | ||
1497 | static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, | ||
1498 | ADT7462_ALARM1 | ADT7462_R2T_ALARM); | ||
1499 | static SENSOR_DEVICE_ATTR(temp4_alarm, S_IRUGO, show_alarm, NULL, | ||
1500 | ADT7462_ALARM1 | ADT7462_R3T_ALARM); | ||
1501 | |||
1502 | static SENSOR_DEVICE_ATTR(in1_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
1503 | set_volt_max, 0); | ||
1504 | static SENSOR_DEVICE_ATTR(in2_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
1505 | set_volt_max, 1); | ||
1506 | static SENSOR_DEVICE_ATTR(in3_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
1507 | set_volt_max, 2); | ||
1508 | static SENSOR_DEVICE_ATTR(in4_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
1509 | set_volt_max, 3); | ||
1510 | static SENSOR_DEVICE_ATTR(in5_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
1511 | set_volt_max, 4); | ||
1512 | static SENSOR_DEVICE_ATTR(in6_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
1513 | set_volt_max, 5); | ||
1514 | static SENSOR_DEVICE_ATTR(in7_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
1515 | set_volt_max, 6); | ||
1516 | static SENSOR_DEVICE_ATTR(in8_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
1517 | set_volt_max, 7); | ||
1518 | static SENSOR_DEVICE_ATTR(in9_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
1519 | set_volt_max, 8); | ||
1520 | static SENSOR_DEVICE_ATTR(in10_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
1521 | set_volt_max, 9); | ||
1522 | static SENSOR_DEVICE_ATTR(in11_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
1523 | set_volt_max, 10); | ||
1524 | static SENSOR_DEVICE_ATTR(in12_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
1525 | set_volt_max, 11); | ||
1526 | static SENSOR_DEVICE_ATTR(in13_max, S_IWUSR | S_IRUGO, show_volt_max, | ||
1527 | set_volt_max, 12); | ||
1528 | |||
1529 | static SENSOR_DEVICE_ATTR(in1_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
1530 | set_volt_min, 0); | ||
1531 | static SENSOR_DEVICE_ATTR(in2_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
1532 | set_volt_min, 1); | ||
1533 | static SENSOR_DEVICE_ATTR(in3_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
1534 | set_volt_min, 2); | ||
1535 | static SENSOR_DEVICE_ATTR(in4_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
1536 | set_volt_min, 3); | ||
1537 | static SENSOR_DEVICE_ATTR(in5_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
1538 | set_volt_min, 4); | ||
1539 | static SENSOR_DEVICE_ATTR(in6_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
1540 | set_volt_min, 5); | ||
1541 | static SENSOR_DEVICE_ATTR(in7_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
1542 | set_volt_min, 6); | ||
1543 | static SENSOR_DEVICE_ATTR(in8_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
1544 | set_volt_min, 7); | ||
1545 | static SENSOR_DEVICE_ATTR(in9_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
1546 | set_volt_min, 8); | ||
1547 | static SENSOR_DEVICE_ATTR(in10_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
1548 | set_volt_min, 9); | ||
1549 | static SENSOR_DEVICE_ATTR(in11_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
1550 | set_volt_min, 10); | ||
1551 | static SENSOR_DEVICE_ATTR(in12_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
1552 | set_volt_min, 11); | ||
1553 | static SENSOR_DEVICE_ATTR(in13_min, S_IWUSR | S_IRUGO, show_volt_min, | ||
1554 | set_volt_min, 12); | ||
1555 | |||
1556 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_voltage, NULL, 0); | ||
1557 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_voltage, NULL, 1); | ||
1558 | static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_voltage, NULL, 2); | ||
1559 | static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_voltage, NULL, 3); | ||
1560 | static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_voltage, NULL, 4); | ||
1561 | static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_voltage, NULL, 5); | ||
1562 | static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_voltage, NULL, 6); | ||
1563 | static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_voltage, NULL, 7); | ||
1564 | static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_voltage, NULL, 8); | ||
1565 | static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_voltage, NULL, 9); | ||
1566 | static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, show_voltage, NULL, 10); | ||
1567 | static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, show_voltage, NULL, 11); | ||
1568 | static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, show_voltage, NULL, 12); | ||
1569 | |||
1570 | static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, show_voltage_label, NULL, 0); | ||
1571 | static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, show_voltage_label, NULL, 1); | ||
1572 | static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_voltage_label, NULL, 2); | ||
1573 | static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, show_voltage_label, NULL, 3); | ||
1574 | static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, show_voltage_label, NULL, 4); | ||
1575 | static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, show_voltage_label, NULL, 5); | ||
1576 | static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_voltage_label, NULL, 6); | ||
1577 | static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_voltage_label, NULL, 7); | ||
1578 | static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_voltage_label, NULL, 8); | ||
1579 | static SENSOR_DEVICE_ATTR(in10_label, S_IRUGO, show_voltage_label, NULL, 9); | ||
1580 | static SENSOR_DEVICE_ATTR(in11_label, S_IRUGO, show_voltage_label, NULL, 10); | ||
1581 | static SENSOR_DEVICE_ATTR(in12_label, S_IRUGO, show_voltage_label, NULL, 11); | ||
1582 | static SENSOR_DEVICE_ATTR(in13_label, S_IRUGO, show_voltage_label, NULL, 12); | ||
1583 | |||
1584 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, | ||
1585 | ADT7462_ALARM2 | ADT7462_V0_ALARM); | ||
1586 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, | ||
1587 | ADT7462_ALARM2 | ADT7462_V7_ALARM); | ||
1588 | static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, | ||
1589 | ADT7462_ALARM2 | ADT7462_V2_ALARM); | ||
1590 | static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, | ||
1591 | ADT7462_ALARM2 | ADT7462_V6_ALARM); | ||
1592 | static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, | ||
1593 | ADT7462_ALARM2 | ADT7462_V5_ALARM); | ||
1594 | static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, | ||
1595 | ADT7462_ALARM2 | ADT7462_V4_ALARM); | ||
1596 | static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, | ||
1597 | ADT7462_ALARM2 | ADT7462_V3_ALARM); | ||
1598 | static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, | ||
1599 | ADT7462_ALARM2 | ADT7462_V1_ALARM); | ||
1600 | static SENSOR_DEVICE_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, | ||
1601 | ADT7462_ALARM3 | ADT7462_V10_ALARM); | ||
1602 | static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL, | ||
1603 | ADT7462_ALARM3 | ADT7462_V9_ALARM); | ||
1604 | static SENSOR_DEVICE_ATTR(in11_alarm, S_IRUGO, show_alarm, NULL, | ||
1605 | ADT7462_ALARM3 | ADT7462_V8_ALARM); | ||
1606 | static SENSOR_DEVICE_ATTR(in12_alarm, S_IRUGO, show_alarm, NULL, | ||
1607 | ADT7462_ALARM3 | ADT7462_V11_ALARM); | ||
1608 | static SENSOR_DEVICE_ATTR(in13_alarm, S_IRUGO, show_alarm, NULL, | ||
1609 | ADT7462_ALARM3 | ADT7462_V12_ALARM); | ||
1610 | |||
1611 | static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
1612 | set_fan_min, 0); | ||
1613 | static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
1614 | set_fan_min, 1); | ||
1615 | static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
1616 | set_fan_min, 2); | ||
1617 | static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
1618 | set_fan_min, 3); | ||
1619 | static SENSOR_DEVICE_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
1620 | set_fan_min, 4); | ||
1621 | static SENSOR_DEVICE_ATTR(fan6_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
1622 | set_fan_min, 5); | ||
1623 | static SENSOR_DEVICE_ATTR(fan7_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
1624 | set_fan_min, 6); | ||
1625 | static SENSOR_DEVICE_ATTR(fan8_min, S_IWUSR | S_IRUGO, show_fan_min, | ||
1626 | set_fan_min, 7); | ||
1627 | |||
1628 | static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); | ||
1629 | static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); | ||
1630 | static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); | ||
1631 | static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3); | ||
1632 | static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4); | ||
1633 | static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan, NULL, 5); | ||
1634 | static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan, NULL, 6); | ||
1635 | static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan, NULL, 7); | ||
1636 | |||
1637 | static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, | ||
1638 | ADT7462_ALARM4 | ADT7462_F0_ALARM); | ||
1639 | static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, | ||
1640 | ADT7462_ALARM4 | ADT7462_F1_ALARM); | ||
1641 | static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, | ||
1642 | ADT7462_ALARM4 | ADT7462_F2_ALARM); | ||
1643 | static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, | ||
1644 | ADT7462_ALARM4 | ADT7462_F3_ALARM); | ||
1645 | static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, | ||
1646 | ADT7462_ALARM4 | ADT7462_F4_ALARM); | ||
1647 | static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_alarm, NULL, | ||
1648 | ADT7462_ALARM4 | ADT7462_F5_ALARM); | ||
1649 | static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_alarm, NULL, | ||
1650 | ADT7462_ALARM4 | ADT7462_F6_ALARM); | ||
1651 | static SENSOR_DEVICE_ATTR(fan8_alarm, S_IRUGO, show_alarm, NULL, | ||
1652 | ADT7462_ALARM4 | ADT7462_F7_ALARM); | ||
1653 | |||
1654 | static SENSOR_DEVICE_ATTR(force_pwm_max, S_IWUSR | S_IRUGO, | ||
1655 | show_force_pwm_max, set_force_pwm_max, 0); | ||
1656 | |||
1657 | static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0); | ||
1658 | static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1); | ||
1659 | static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2); | ||
1660 | static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 3); | ||
1661 | |||
1662 | static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO, | ||
1663 | show_pwm_min, set_pwm_min, 0); | ||
1664 | static SENSOR_DEVICE_ATTR(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO, | ||
1665 | show_pwm_min, set_pwm_min, 1); | ||
1666 | static SENSOR_DEVICE_ATTR(pwm3_auto_point1_pwm, S_IWUSR | S_IRUGO, | ||
1667 | show_pwm_min, set_pwm_min, 2); | ||
1668 | static SENSOR_DEVICE_ATTR(pwm4_auto_point1_pwm, S_IWUSR | S_IRUGO, | ||
1669 | show_pwm_min, set_pwm_min, 3); | ||
1670 | |||
1671 | static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
1672 | show_pwm_max, set_pwm_max, 0); | ||
1673 | static SENSOR_DEVICE_ATTR(pwm2_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
1674 | show_pwm_max, set_pwm_max, 1); | ||
1675 | static SENSOR_DEVICE_ATTR(pwm3_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
1676 | show_pwm_max, set_pwm_max, 2); | ||
1677 | static SENSOR_DEVICE_ATTR(pwm4_auto_point2_pwm, S_IWUSR | S_IRUGO, | ||
1678 | show_pwm_max, set_pwm_max, 3); | ||
1679 | |||
1680 | static SENSOR_DEVICE_ATTR(temp1_auto_point1_hyst, S_IWUSR | S_IRUGO, | ||
1681 | show_pwm_hyst, set_pwm_hyst, 0); | ||
1682 | static SENSOR_DEVICE_ATTR(temp2_auto_point1_hyst, S_IWUSR | S_IRUGO, | ||
1683 | show_pwm_hyst, set_pwm_hyst, 1); | ||
1684 | static SENSOR_DEVICE_ATTR(temp3_auto_point1_hyst, S_IWUSR | S_IRUGO, | ||
1685 | show_pwm_hyst, set_pwm_hyst, 2); | ||
1686 | static SENSOR_DEVICE_ATTR(temp4_auto_point1_hyst, S_IWUSR | S_IRUGO, | ||
1687 | show_pwm_hyst, set_pwm_hyst, 3); | ||
1688 | |||
1689 | static SENSOR_DEVICE_ATTR(temp1_auto_point2_hyst, S_IWUSR | S_IRUGO, | ||
1690 | show_pwm_hyst, set_pwm_hyst, 0); | ||
1691 | static SENSOR_DEVICE_ATTR(temp2_auto_point2_hyst, S_IWUSR | S_IRUGO, | ||
1692 | show_pwm_hyst, set_pwm_hyst, 1); | ||
1693 | static SENSOR_DEVICE_ATTR(temp3_auto_point2_hyst, S_IWUSR | S_IRUGO, | ||
1694 | show_pwm_hyst, set_pwm_hyst, 2); | ||
1695 | static SENSOR_DEVICE_ATTR(temp4_auto_point2_hyst, S_IWUSR | S_IRUGO, | ||
1696 | show_pwm_hyst, set_pwm_hyst, 3); | ||
1697 | |||
1698 | static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
1699 | show_pwm_tmin, set_pwm_tmin, 0); | ||
1700 | static SENSOR_DEVICE_ATTR(temp2_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
1701 | show_pwm_tmin, set_pwm_tmin, 1); | ||
1702 | static SENSOR_DEVICE_ATTR(temp3_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
1703 | show_pwm_tmin, set_pwm_tmin, 2); | ||
1704 | static SENSOR_DEVICE_ATTR(temp4_auto_point1_temp, S_IWUSR | S_IRUGO, | ||
1705 | show_pwm_tmin, set_pwm_tmin, 3); | ||
1706 | |||
1707 | static SENSOR_DEVICE_ATTR(temp1_auto_point2_temp, S_IWUSR | S_IRUGO, | ||
1708 | show_pwm_tmax, set_pwm_tmax, 0); | ||
1709 | static SENSOR_DEVICE_ATTR(temp2_auto_point2_temp, S_IWUSR | S_IRUGO, | ||
1710 | show_pwm_tmax, set_pwm_tmax, 1); | ||
1711 | static SENSOR_DEVICE_ATTR(temp3_auto_point2_temp, S_IWUSR | S_IRUGO, | ||
1712 | show_pwm_tmax, set_pwm_tmax, 2); | ||
1713 | static SENSOR_DEVICE_ATTR(temp4_auto_point2_temp, S_IWUSR | S_IRUGO, | ||
1714 | show_pwm_tmax, set_pwm_tmax, 3); | ||
1715 | |||
1716 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_auto, | ||
1717 | set_pwm_auto, 0); | ||
1718 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_auto, | ||
1719 | set_pwm_auto, 1); | ||
1720 | static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_auto, | ||
1721 | set_pwm_auto, 2); | ||
1722 | static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_auto, | ||
1723 | set_pwm_auto, 3); | ||
1724 | |||
1725 | static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IWUSR | S_IRUGO, | ||
1726 | show_pwm_auto_temp, set_pwm_auto_temp, 0); | ||
1727 | static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IWUSR | S_IRUGO, | ||
1728 | show_pwm_auto_temp, set_pwm_auto_temp, 1); | ||
1729 | static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO, | ||
1730 | show_pwm_auto_temp, set_pwm_auto_temp, 2); | ||
1731 | static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IWUSR | S_IRUGO, | ||
1732 | show_pwm_auto_temp, set_pwm_auto_temp, 3); | ||
1733 | |||
1734 | static struct attribute *adt7462_attr[] = | ||
1735 | { | ||
1736 | &sensor_dev_attr_temp1_max.dev_attr.attr, | ||
1737 | &sensor_dev_attr_temp2_max.dev_attr.attr, | ||
1738 | &sensor_dev_attr_temp3_max.dev_attr.attr, | ||
1739 | &sensor_dev_attr_temp4_max.dev_attr.attr, | ||
1740 | |||
1741 | &sensor_dev_attr_temp1_min.dev_attr.attr, | ||
1742 | &sensor_dev_attr_temp2_min.dev_attr.attr, | ||
1743 | &sensor_dev_attr_temp3_min.dev_attr.attr, | ||
1744 | &sensor_dev_attr_temp4_min.dev_attr.attr, | ||
1745 | |||
1746 | &sensor_dev_attr_temp1_input.dev_attr.attr, | ||
1747 | &sensor_dev_attr_temp2_input.dev_attr.attr, | ||
1748 | &sensor_dev_attr_temp3_input.dev_attr.attr, | ||
1749 | &sensor_dev_attr_temp4_input.dev_attr.attr, | ||
1750 | |||
1751 | &sensor_dev_attr_temp1_label.dev_attr.attr, | ||
1752 | &sensor_dev_attr_temp2_label.dev_attr.attr, | ||
1753 | &sensor_dev_attr_temp3_label.dev_attr.attr, | ||
1754 | &sensor_dev_attr_temp4_label.dev_attr.attr, | ||
1755 | |||
1756 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, | ||
1757 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, | ||
1758 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, | ||
1759 | &sensor_dev_attr_temp4_alarm.dev_attr.attr, | ||
1760 | |||
1761 | &sensor_dev_attr_in1_max.dev_attr.attr, | ||
1762 | &sensor_dev_attr_in2_max.dev_attr.attr, | ||
1763 | &sensor_dev_attr_in3_max.dev_attr.attr, | ||
1764 | &sensor_dev_attr_in4_max.dev_attr.attr, | ||
1765 | &sensor_dev_attr_in5_max.dev_attr.attr, | ||
1766 | &sensor_dev_attr_in6_max.dev_attr.attr, | ||
1767 | &sensor_dev_attr_in7_max.dev_attr.attr, | ||
1768 | &sensor_dev_attr_in8_max.dev_attr.attr, | ||
1769 | &sensor_dev_attr_in9_max.dev_attr.attr, | ||
1770 | &sensor_dev_attr_in10_max.dev_attr.attr, | ||
1771 | &sensor_dev_attr_in11_max.dev_attr.attr, | ||
1772 | &sensor_dev_attr_in12_max.dev_attr.attr, | ||
1773 | &sensor_dev_attr_in13_max.dev_attr.attr, | ||
1774 | |||
1775 | &sensor_dev_attr_in1_min.dev_attr.attr, | ||
1776 | &sensor_dev_attr_in2_min.dev_attr.attr, | ||
1777 | &sensor_dev_attr_in3_min.dev_attr.attr, | ||
1778 | &sensor_dev_attr_in4_min.dev_attr.attr, | ||
1779 | &sensor_dev_attr_in5_min.dev_attr.attr, | ||
1780 | &sensor_dev_attr_in6_min.dev_attr.attr, | ||
1781 | &sensor_dev_attr_in7_min.dev_attr.attr, | ||
1782 | &sensor_dev_attr_in8_min.dev_attr.attr, | ||
1783 | &sensor_dev_attr_in9_min.dev_attr.attr, | ||
1784 | &sensor_dev_attr_in10_min.dev_attr.attr, | ||
1785 | &sensor_dev_attr_in11_min.dev_attr.attr, | ||
1786 | &sensor_dev_attr_in12_min.dev_attr.attr, | ||
1787 | &sensor_dev_attr_in13_min.dev_attr.attr, | ||
1788 | |||
1789 | &sensor_dev_attr_in1_input.dev_attr.attr, | ||
1790 | &sensor_dev_attr_in2_input.dev_attr.attr, | ||
1791 | &sensor_dev_attr_in3_input.dev_attr.attr, | ||
1792 | &sensor_dev_attr_in4_input.dev_attr.attr, | ||
1793 | &sensor_dev_attr_in5_input.dev_attr.attr, | ||
1794 | &sensor_dev_attr_in6_input.dev_attr.attr, | ||
1795 | &sensor_dev_attr_in7_input.dev_attr.attr, | ||
1796 | &sensor_dev_attr_in8_input.dev_attr.attr, | ||
1797 | &sensor_dev_attr_in9_input.dev_attr.attr, | ||
1798 | &sensor_dev_attr_in10_input.dev_attr.attr, | ||
1799 | &sensor_dev_attr_in11_input.dev_attr.attr, | ||
1800 | &sensor_dev_attr_in12_input.dev_attr.attr, | ||
1801 | &sensor_dev_attr_in13_input.dev_attr.attr, | ||
1802 | |||
1803 | &sensor_dev_attr_in1_label.dev_attr.attr, | ||
1804 | &sensor_dev_attr_in2_label.dev_attr.attr, | ||
1805 | &sensor_dev_attr_in3_label.dev_attr.attr, | ||
1806 | &sensor_dev_attr_in4_label.dev_attr.attr, | ||
1807 | &sensor_dev_attr_in5_label.dev_attr.attr, | ||
1808 | &sensor_dev_attr_in6_label.dev_attr.attr, | ||
1809 | &sensor_dev_attr_in7_label.dev_attr.attr, | ||
1810 | &sensor_dev_attr_in8_label.dev_attr.attr, | ||
1811 | &sensor_dev_attr_in9_label.dev_attr.attr, | ||
1812 | &sensor_dev_attr_in10_label.dev_attr.attr, | ||
1813 | &sensor_dev_attr_in11_label.dev_attr.attr, | ||
1814 | &sensor_dev_attr_in12_label.dev_attr.attr, | ||
1815 | &sensor_dev_attr_in13_label.dev_attr.attr, | ||
1816 | |||
1817 | &sensor_dev_attr_in1_alarm.dev_attr.attr, | ||
1818 | &sensor_dev_attr_in2_alarm.dev_attr.attr, | ||
1819 | &sensor_dev_attr_in3_alarm.dev_attr.attr, | ||
1820 | &sensor_dev_attr_in4_alarm.dev_attr.attr, | ||
1821 | &sensor_dev_attr_in5_alarm.dev_attr.attr, | ||
1822 | &sensor_dev_attr_in6_alarm.dev_attr.attr, | ||
1823 | &sensor_dev_attr_in7_alarm.dev_attr.attr, | ||
1824 | &sensor_dev_attr_in8_alarm.dev_attr.attr, | ||
1825 | &sensor_dev_attr_in9_alarm.dev_attr.attr, | ||
1826 | &sensor_dev_attr_in10_alarm.dev_attr.attr, | ||
1827 | &sensor_dev_attr_in11_alarm.dev_attr.attr, | ||
1828 | &sensor_dev_attr_in12_alarm.dev_attr.attr, | ||
1829 | &sensor_dev_attr_in13_alarm.dev_attr.attr, | ||
1830 | |||
1831 | &sensor_dev_attr_fan1_min.dev_attr.attr, | ||
1832 | &sensor_dev_attr_fan2_min.dev_attr.attr, | ||
1833 | &sensor_dev_attr_fan3_min.dev_attr.attr, | ||
1834 | &sensor_dev_attr_fan4_min.dev_attr.attr, | ||
1835 | &sensor_dev_attr_fan5_min.dev_attr.attr, | ||
1836 | &sensor_dev_attr_fan6_min.dev_attr.attr, | ||
1837 | &sensor_dev_attr_fan7_min.dev_attr.attr, | ||
1838 | &sensor_dev_attr_fan8_min.dev_attr.attr, | ||
1839 | |||
1840 | &sensor_dev_attr_fan1_input.dev_attr.attr, | ||
1841 | &sensor_dev_attr_fan2_input.dev_attr.attr, | ||
1842 | &sensor_dev_attr_fan3_input.dev_attr.attr, | ||
1843 | &sensor_dev_attr_fan4_input.dev_attr.attr, | ||
1844 | &sensor_dev_attr_fan5_input.dev_attr.attr, | ||
1845 | &sensor_dev_attr_fan6_input.dev_attr.attr, | ||
1846 | &sensor_dev_attr_fan7_input.dev_attr.attr, | ||
1847 | &sensor_dev_attr_fan8_input.dev_attr.attr, | ||
1848 | |||
1849 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, | ||
1850 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, | ||
1851 | &sensor_dev_attr_fan3_alarm.dev_attr.attr, | ||
1852 | &sensor_dev_attr_fan4_alarm.dev_attr.attr, | ||
1853 | &sensor_dev_attr_fan5_alarm.dev_attr.attr, | ||
1854 | &sensor_dev_attr_fan6_alarm.dev_attr.attr, | ||
1855 | &sensor_dev_attr_fan7_alarm.dev_attr.attr, | ||
1856 | &sensor_dev_attr_fan8_alarm.dev_attr.attr, | ||
1857 | |||
1858 | &sensor_dev_attr_force_pwm_max.dev_attr.attr, | ||
1859 | &sensor_dev_attr_pwm1.dev_attr.attr, | ||
1860 | &sensor_dev_attr_pwm2.dev_attr.attr, | ||
1861 | &sensor_dev_attr_pwm3.dev_attr.attr, | ||
1862 | &sensor_dev_attr_pwm4.dev_attr.attr, | ||
1863 | |||
1864 | &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, | ||
1865 | &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, | ||
1866 | &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr, | ||
1867 | &sensor_dev_attr_pwm4_auto_point1_pwm.dev_attr.attr, | ||
1868 | |||
1869 | &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, | ||
1870 | &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr, | ||
1871 | &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr, | ||
1872 | &sensor_dev_attr_pwm4_auto_point2_pwm.dev_attr.attr, | ||
1873 | |||
1874 | &sensor_dev_attr_temp1_auto_point1_hyst.dev_attr.attr, | ||
1875 | &sensor_dev_attr_temp2_auto_point1_hyst.dev_attr.attr, | ||
1876 | &sensor_dev_attr_temp3_auto_point1_hyst.dev_attr.attr, | ||
1877 | &sensor_dev_attr_temp4_auto_point1_hyst.dev_attr.attr, | ||
1878 | |||
1879 | &sensor_dev_attr_temp1_auto_point2_hyst.dev_attr.attr, | ||
1880 | &sensor_dev_attr_temp2_auto_point2_hyst.dev_attr.attr, | ||
1881 | &sensor_dev_attr_temp3_auto_point2_hyst.dev_attr.attr, | ||
1882 | &sensor_dev_attr_temp4_auto_point2_hyst.dev_attr.attr, | ||
1883 | |||
1884 | &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr, | ||
1885 | &sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr, | ||
1886 | &sensor_dev_attr_temp3_auto_point1_temp.dev_attr.attr, | ||
1887 | &sensor_dev_attr_temp4_auto_point1_temp.dev_attr.attr, | ||
1888 | |||
1889 | &sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr, | ||
1890 | &sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr, | ||
1891 | &sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr, | ||
1892 | &sensor_dev_attr_temp4_auto_point2_temp.dev_attr.attr, | ||
1893 | |||
1894 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | ||
1895 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | ||
1896 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, | ||
1897 | &sensor_dev_attr_pwm4_enable.dev_attr.attr, | ||
1898 | |||
1899 | &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr, | ||
1900 | &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr, | ||
1901 | &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr, | ||
1902 | &sensor_dev_attr_pwm4_auto_channels_temp.dev_attr.attr, | ||
1903 | NULL | ||
1904 | }; | ||
1905 | |||
1906 | /* Return 0 if detection is successful, -ENODEV otherwise */ | ||
1907 | static int adt7462_detect(struct i2c_client *client, int kind, | ||
1908 | struct i2c_board_info *info) | ||
1909 | { | ||
1910 | struct i2c_adapter *adapter = client->adapter; | ||
1911 | |||
1912 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
1913 | return -ENODEV; | ||
1914 | |||
1915 | if (kind <= 0) { | ||
1916 | int vendor, device, revision; | ||
1917 | |||
1918 | vendor = i2c_smbus_read_byte_data(client, ADT7462_REG_VENDOR); | ||
1919 | if (vendor != ADT7462_VENDOR) | ||
1920 | return -ENODEV; | ||
1921 | |||
1922 | device = i2c_smbus_read_byte_data(client, ADT7462_REG_DEVICE); | ||
1923 | if (device != ADT7462_DEVICE) | ||
1924 | return -ENODEV; | ||
1925 | |||
1926 | revision = i2c_smbus_read_byte_data(client, | ||
1927 | ADT7462_REG_REVISION); | ||
1928 | if (revision != ADT7462_REVISION) | ||
1929 | return -ENODEV; | ||
1930 | } else | ||
1931 | dev_dbg(&adapter->dev, "detection forced\n"); | ||
1932 | |||
1933 | strlcpy(info->type, "adt7462", I2C_NAME_SIZE); | ||
1934 | |||
1935 | return 0; | ||
1936 | } | ||
1937 | |||
1938 | static int adt7462_probe(struct i2c_client *client, | ||
1939 | const struct i2c_device_id *id) | ||
1940 | { | ||
1941 | struct adt7462_data *data; | ||
1942 | int err; | ||
1943 | |||
1944 | data = kzalloc(sizeof(struct adt7462_data), GFP_KERNEL); | ||
1945 | if (!data) { | ||
1946 | err = -ENOMEM; | ||
1947 | goto exit; | ||
1948 | } | ||
1949 | |||
1950 | i2c_set_clientdata(client, data); | ||
1951 | mutex_init(&data->lock); | ||
1952 | |||
1953 | dev_info(&client->dev, "%s chip found\n", client->name); | ||
1954 | |||
1955 | /* Register sysfs hooks */ | ||
1956 | data->attrs.attrs = adt7462_attr; | ||
1957 | err = sysfs_create_group(&client->dev.kobj, &data->attrs); | ||
1958 | if (err) | ||
1959 | goto exit_free; | ||
1960 | |||
1961 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
1962 | if (IS_ERR(data->hwmon_dev)) { | ||
1963 | err = PTR_ERR(data->hwmon_dev); | ||
1964 | goto exit_remove; | ||
1965 | } | ||
1966 | |||
1967 | return 0; | ||
1968 | |||
1969 | exit_remove: | ||
1970 | sysfs_remove_group(&client->dev.kobj, &data->attrs); | ||
1971 | exit_free: | ||
1972 | kfree(data); | ||
1973 | exit: | ||
1974 | return err; | ||
1975 | } | ||
1976 | |||
1977 | static int adt7462_remove(struct i2c_client *client) | ||
1978 | { | ||
1979 | struct adt7462_data *data = i2c_get_clientdata(client); | ||
1980 | |||
1981 | hwmon_device_unregister(data->hwmon_dev); | ||
1982 | sysfs_remove_group(&client->dev.kobj, &data->attrs); | ||
1983 | kfree(data); | ||
1984 | return 0; | ||
1985 | } | ||
1986 | |||
1987 | static int __init adt7462_init(void) | ||
1988 | { | ||
1989 | return i2c_add_driver(&adt7462_driver); | ||
1990 | } | ||
1991 | |||
1992 | static void __exit adt7462_exit(void) | ||
1993 | { | ||
1994 | i2c_del_driver(&adt7462_driver); | ||
1995 | } | ||
1996 | |||
1997 | MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); | ||
1998 | MODULE_DESCRIPTION("ADT7462 driver"); | ||
1999 | MODULE_LICENSE("GPL"); | ||
2000 | |||
2001 | module_init(adt7462_init); | ||
2002 | module_exit(adt7462_exit); | ||
diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c index d368d8f845e1..1311a595147e 100644 --- a/drivers/hwmon/adt7470.c +++ b/drivers/hwmon/adt7470.c | |||
@@ -137,6 +137,8 @@ I2C_CLIENT_INSMOD_1(adt7470); | |||
137 | #define FAN_PERIOD_INVALID 65535 | 137 | #define FAN_PERIOD_INVALID 65535 |
138 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) | 138 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) |
139 | 139 | ||
140 | #define ROUND_DIV(x, divisor) (((x) + ((divisor) / 2)) / (divisor)) | ||
141 | |||
140 | struct adt7470_data { | 142 | struct adt7470_data { |
141 | struct device *hwmon_dev; | 143 | struct device *hwmon_dev; |
142 | struct attribute_group attrs; | 144 | struct attribute_group attrs; |
@@ -353,7 +355,13 @@ static ssize_t set_temp_min(struct device *dev, | |||
353 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 355 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
354 | struct i2c_client *client = to_i2c_client(dev); | 356 | struct i2c_client *client = to_i2c_client(dev); |
355 | struct adt7470_data *data = i2c_get_clientdata(client); | 357 | struct adt7470_data *data = i2c_get_clientdata(client); |
356 | int temp = simple_strtol(buf, NULL, 10) / 1000; | 358 | long temp; |
359 | |||
360 | if (strict_strtol(buf, 10, &temp)) | ||
361 | return -EINVAL; | ||
362 | |||
363 | temp = ROUND_DIV(temp, 1000); | ||
364 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
357 | 365 | ||
358 | mutex_lock(&data->lock); | 366 | mutex_lock(&data->lock); |
359 | data->temp_min[attr->index] = temp; | 367 | data->temp_min[attr->index] = temp; |
@@ -381,7 +389,13 @@ static ssize_t set_temp_max(struct device *dev, | |||
381 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 389 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
382 | struct i2c_client *client = to_i2c_client(dev); | 390 | struct i2c_client *client = to_i2c_client(dev); |
383 | struct adt7470_data *data = i2c_get_clientdata(client); | 391 | struct adt7470_data *data = i2c_get_clientdata(client); |
384 | int temp = simple_strtol(buf, NULL, 10) / 1000; | 392 | long temp; |
393 | |||
394 | if (strict_strtol(buf, 10, &temp)) | ||
395 | return -EINVAL; | ||
396 | |||
397 | temp = ROUND_DIV(temp, 1000); | ||
398 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
385 | 399 | ||
386 | mutex_lock(&data->lock); | 400 | mutex_lock(&data->lock); |
387 | data->temp_max[attr->index] = temp; | 401 | data->temp_max[attr->index] = temp; |
@@ -430,11 +444,13 @@ static ssize_t set_fan_max(struct device *dev, | |||
430 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 444 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
431 | struct i2c_client *client = to_i2c_client(dev); | 445 | struct i2c_client *client = to_i2c_client(dev); |
432 | struct adt7470_data *data = i2c_get_clientdata(client); | 446 | struct adt7470_data *data = i2c_get_clientdata(client); |
433 | int temp = simple_strtol(buf, NULL, 10); | 447 | long temp; |
434 | 448 | ||
435 | if (!temp) | 449 | if (strict_strtol(buf, 10, &temp) || !temp) |
436 | return -EINVAL; | 450 | return -EINVAL; |
451 | |||
437 | temp = FAN_RPM_TO_PERIOD(temp); | 452 | temp = FAN_RPM_TO_PERIOD(temp); |
453 | temp = SENSORS_LIMIT(temp, 1, 65534); | ||
438 | 454 | ||
439 | mutex_lock(&data->lock); | 455 | mutex_lock(&data->lock); |
440 | data->fan_max[attr->index] = temp; | 456 | data->fan_max[attr->index] = temp; |
@@ -465,11 +481,13 @@ static ssize_t set_fan_min(struct device *dev, | |||
465 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 481 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
466 | struct i2c_client *client = to_i2c_client(dev); | 482 | struct i2c_client *client = to_i2c_client(dev); |
467 | struct adt7470_data *data = i2c_get_clientdata(client); | 483 | struct adt7470_data *data = i2c_get_clientdata(client); |
468 | int temp = simple_strtol(buf, NULL, 10); | 484 | long temp; |
469 | 485 | ||
470 | if (!temp) | 486 | if (strict_strtol(buf, 10, &temp) || !temp) |
471 | return -EINVAL; | 487 | return -EINVAL; |
488 | |||
472 | temp = FAN_RPM_TO_PERIOD(temp); | 489 | temp = FAN_RPM_TO_PERIOD(temp); |
490 | temp = SENSORS_LIMIT(temp, 1, 65534); | ||
473 | 491 | ||
474 | mutex_lock(&data->lock); | 492 | mutex_lock(&data->lock); |
475 | data->fan_min[attr->index] = temp; | 493 | data->fan_min[attr->index] = temp; |
@@ -507,9 +525,12 @@ static ssize_t set_force_pwm_max(struct device *dev, | |||
507 | { | 525 | { |
508 | struct i2c_client *client = to_i2c_client(dev); | 526 | struct i2c_client *client = to_i2c_client(dev); |
509 | struct adt7470_data *data = i2c_get_clientdata(client); | 527 | struct adt7470_data *data = i2c_get_clientdata(client); |
510 | int temp = simple_strtol(buf, NULL, 10); | 528 | long temp; |
511 | u8 reg; | 529 | u8 reg; |
512 | 530 | ||
531 | if (strict_strtol(buf, 10, &temp)) | ||
532 | return -EINVAL; | ||
533 | |||
513 | mutex_lock(&data->lock); | 534 | mutex_lock(&data->lock); |
514 | data->force_pwm_max = temp; | 535 | data->force_pwm_max = temp; |
515 | reg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG); | 536 | reg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG); |
@@ -537,7 +558,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, | |||
537 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 558 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
538 | struct i2c_client *client = to_i2c_client(dev); | 559 | struct i2c_client *client = to_i2c_client(dev); |
539 | struct adt7470_data *data = i2c_get_clientdata(client); | 560 | struct adt7470_data *data = i2c_get_clientdata(client); |
540 | int temp = simple_strtol(buf, NULL, 10); | 561 | long temp; |
562 | |||
563 | if (strict_strtol(buf, 10, &temp)) | ||
564 | return -EINVAL; | ||
565 | |||
566 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
541 | 567 | ||
542 | mutex_lock(&data->lock); | 568 | mutex_lock(&data->lock); |
543 | data->pwm[attr->index] = temp; | 569 | data->pwm[attr->index] = temp; |
@@ -564,7 +590,12 @@ static ssize_t set_pwm_max(struct device *dev, | |||
564 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 590 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
565 | struct i2c_client *client = to_i2c_client(dev); | 591 | struct i2c_client *client = to_i2c_client(dev); |
566 | struct adt7470_data *data = i2c_get_clientdata(client); | 592 | struct adt7470_data *data = i2c_get_clientdata(client); |
567 | int temp = simple_strtol(buf, NULL, 10); | 593 | long temp; |
594 | |||
595 | if (strict_strtol(buf, 10, &temp)) | ||
596 | return -EINVAL; | ||
597 | |||
598 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
568 | 599 | ||
569 | mutex_lock(&data->lock); | 600 | mutex_lock(&data->lock); |
570 | data->pwm_max[attr->index] = temp; | 601 | data->pwm_max[attr->index] = temp; |
@@ -592,7 +623,12 @@ static ssize_t set_pwm_min(struct device *dev, | |||
592 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 623 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
593 | struct i2c_client *client = to_i2c_client(dev); | 624 | struct i2c_client *client = to_i2c_client(dev); |
594 | struct adt7470_data *data = i2c_get_clientdata(client); | 625 | struct adt7470_data *data = i2c_get_clientdata(client); |
595 | int temp = simple_strtol(buf, NULL, 10); | 626 | long temp; |
627 | |||
628 | if (strict_strtol(buf, 10, &temp)) | ||
629 | return -EINVAL; | ||
630 | |||
631 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
596 | 632 | ||
597 | mutex_lock(&data->lock); | 633 | mutex_lock(&data->lock); |
598 | data->pwm_min[attr->index] = temp; | 634 | data->pwm_min[attr->index] = temp; |
@@ -630,7 +666,13 @@ static ssize_t set_pwm_tmin(struct device *dev, | |||
630 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 666 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
631 | struct i2c_client *client = to_i2c_client(dev); | 667 | struct i2c_client *client = to_i2c_client(dev); |
632 | struct adt7470_data *data = i2c_get_clientdata(client); | 668 | struct adt7470_data *data = i2c_get_clientdata(client); |
633 | int temp = simple_strtol(buf, NULL, 10) / 1000; | 669 | long temp; |
670 | |||
671 | if (strict_strtol(buf, 10, &temp)) | ||
672 | return -EINVAL; | ||
673 | |||
674 | temp = ROUND_DIV(temp, 1000); | ||
675 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
634 | 676 | ||
635 | mutex_lock(&data->lock); | 677 | mutex_lock(&data->lock); |
636 | data->pwm_tmin[attr->index] = temp; | 678 | data->pwm_tmin[attr->index] = temp; |
@@ -658,11 +700,14 @@ static ssize_t set_pwm_auto(struct device *dev, | |||
658 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 700 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
659 | struct i2c_client *client = to_i2c_client(dev); | 701 | struct i2c_client *client = to_i2c_client(dev); |
660 | struct adt7470_data *data = i2c_get_clientdata(client); | 702 | struct adt7470_data *data = i2c_get_clientdata(client); |
661 | int temp = simple_strtol(buf, NULL, 10); | ||
662 | int pwm_auto_reg = ADT7470_REG_PWM_CFG(attr->index); | 703 | int pwm_auto_reg = ADT7470_REG_PWM_CFG(attr->index); |
663 | int pwm_auto_reg_mask; | 704 | int pwm_auto_reg_mask; |
705 | long temp; | ||
664 | u8 reg; | 706 | u8 reg; |
665 | 707 | ||
708 | if (strict_strtol(buf, 10, &temp)) | ||
709 | return -EINVAL; | ||
710 | |||
666 | if (attr->index % 2) | 711 | if (attr->index % 2) |
667 | pwm_auto_reg_mask = ADT7470_PWM2_AUTO_MASK; | 712 | pwm_auto_reg_mask = ADT7470_PWM2_AUTO_MASK; |
668 | else | 713 | else |
@@ -716,10 +761,14 @@ static ssize_t set_pwm_auto_temp(struct device *dev, | |||
716 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 761 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
717 | struct i2c_client *client = to_i2c_client(dev); | 762 | struct i2c_client *client = to_i2c_client(dev); |
718 | struct adt7470_data *data = i2c_get_clientdata(client); | 763 | struct adt7470_data *data = i2c_get_clientdata(client); |
719 | int temp = cvt_auto_temp(simple_strtol(buf, NULL, 10)); | ||
720 | int pwm_auto_reg = ADT7470_REG_PWM_AUTO_TEMP(attr->index); | 764 | int pwm_auto_reg = ADT7470_REG_PWM_AUTO_TEMP(attr->index); |
765 | long temp; | ||
721 | u8 reg; | 766 | u8 reg; |
722 | 767 | ||
768 | if (strict_strtol(buf, 10, &temp)) | ||
769 | return -EINVAL; | ||
770 | |||
771 | temp = cvt_auto_temp(temp); | ||
723 | if (temp < 0) | 772 | if (temp < 0) |
724 | return temp; | 773 | return temp; |
725 | 774 | ||
diff --git a/drivers/hwmon/adt7473.c b/drivers/hwmon/adt7473.c index b9a8ea30c99c..18aa30866a6c 100644 --- a/drivers/hwmon/adt7473.c +++ b/drivers/hwmon/adt7473.c | |||
@@ -129,6 +129,8 @@ I2C_CLIENT_INSMOD_1(adt7473); | |||
129 | #define FAN_PERIOD_INVALID 65535 | 129 | #define FAN_PERIOD_INVALID 65535 |
130 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) | 130 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) |
131 | 131 | ||
132 | #define ROUND_DIV(x, divisor) (((x) + ((divisor) / 2)) / (divisor)) | ||
133 | |||
132 | struct adt7473_data { | 134 | struct adt7473_data { |
133 | struct device *hwmon_dev; | 135 | struct device *hwmon_dev; |
134 | struct attribute_group attrs; | 136 | struct attribute_group attrs; |
@@ -357,7 +359,12 @@ static ssize_t set_volt_min(struct device *dev, | |||
357 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 359 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
358 | struct i2c_client *client = to_i2c_client(dev); | 360 | struct i2c_client *client = to_i2c_client(dev); |
359 | struct adt7473_data *data = i2c_get_clientdata(client); | 361 | struct adt7473_data *data = i2c_get_clientdata(client); |
360 | int volt = encode_volt(attr->index, simple_strtol(buf, NULL, 10)); | 362 | long volt; |
363 | |||
364 | if (strict_strtol(buf, 10, &volt)) | ||
365 | return -EINVAL; | ||
366 | |||
367 | volt = encode_volt(attr->index, volt); | ||
361 | 368 | ||
362 | mutex_lock(&data->lock); | 369 | mutex_lock(&data->lock); |
363 | data->volt_min[attr->index] = volt; | 370 | data->volt_min[attr->index] = volt; |
@@ -386,7 +393,12 @@ static ssize_t set_volt_max(struct device *dev, | |||
386 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 393 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
387 | struct i2c_client *client = to_i2c_client(dev); | 394 | struct i2c_client *client = to_i2c_client(dev); |
388 | struct adt7473_data *data = i2c_get_clientdata(client); | 395 | struct adt7473_data *data = i2c_get_clientdata(client); |
389 | int volt = encode_volt(attr->index, simple_strtol(buf, NULL, 10)); | 396 | long volt; |
397 | |||
398 | if (strict_strtol(buf, 10, &volt)) | ||
399 | return -EINVAL; | ||
400 | |||
401 | volt = encode_volt(attr->index, volt); | ||
390 | 402 | ||
391 | mutex_lock(&data->lock); | 403 | mutex_lock(&data->lock); |
392 | data->volt_max[attr->index] = volt; | 404 | data->volt_max[attr->index] = volt; |
@@ -419,7 +431,8 @@ static int decode_temp(u8 twos_complement, u8 raw) | |||
419 | 431 | ||
420 | static u8 encode_temp(u8 twos_complement, int cooked) | 432 | static u8 encode_temp(u8 twos_complement, int cooked) |
421 | { | 433 | { |
422 | return twos_complement ? cooked & 0xFF : cooked + 64; | 434 | u8 ret = twos_complement ? cooked & 0xFF : cooked + 64; |
435 | return SENSORS_LIMIT(ret, 0, 255); | ||
423 | } | 436 | } |
424 | 437 | ||
425 | static ssize_t show_temp_min(struct device *dev, | 438 | static ssize_t show_temp_min(struct device *dev, |
@@ -441,7 +454,12 @@ static ssize_t set_temp_min(struct device *dev, | |||
441 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 454 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
442 | struct i2c_client *client = to_i2c_client(dev); | 455 | struct i2c_client *client = to_i2c_client(dev); |
443 | struct adt7473_data *data = i2c_get_clientdata(client); | 456 | struct adt7473_data *data = i2c_get_clientdata(client); |
444 | int temp = simple_strtol(buf, NULL, 10) / 1000; | 457 | long temp; |
458 | |||
459 | if (strict_strtol(buf, 10, &temp)) | ||
460 | return -EINVAL; | ||
461 | |||
462 | temp = ROUND_DIV(temp, 1000); | ||
445 | temp = encode_temp(data->temp_twos_complement, temp); | 463 | temp = encode_temp(data->temp_twos_complement, temp); |
446 | 464 | ||
447 | mutex_lock(&data->lock); | 465 | mutex_lock(&data->lock); |
@@ -472,7 +490,12 @@ static ssize_t set_temp_max(struct device *dev, | |||
472 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 490 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
473 | struct i2c_client *client = to_i2c_client(dev); | 491 | struct i2c_client *client = to_i2c_client(dev); |
474 | struct adt7473_data *data = i2c_get_clientdata(client); | 492 | struct adt7473_data *data = i2c_get_clientdata(client); |
475 | int temp = simple_strtol(buf, NULL, 10) / 1000; | 493 | long temp; |
494 | |||
495 | if (strict_strtol(buf, 10, &temp)) | ||
496 | return -EINVAL; | ||
497 | |||
498 | temp = ROUND_DIV(temp, 1000); | ||
476 | temp = encode_temp(data->temp_twos_complement, temp); | 499 | temp = encode_temp(data->temp_twos_complement, temp); |
477 | 500 | ||
478 | mutex_lock(&data->lock); | 501 | mutex_lock(&data->lock); |
@@ -515,11 +538,13 @@ static ssize_t set_fan_min(struct device *dev, | |||
515 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 538 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
516 | struct i2c_client *client = to_i2c_client(dev); | 539 | struct i2c_client *client = to_i2c_client(dev); |
517 | struct adt7473_data *data = i2c_get_clientdata(client); | 540 | struct adt7473_data *data = i2c_get_clientdata(client); |
518 | int temp = simple_strtol(buf, NULL, 10); | 541 | long temp; |
519 | 542 | ||
520 | if (!temp) | 543 | if (strict_strtol(buf, 10, &temp) || !temp) |
521 | return -EINVAL; | 544 | return -EINVAL; |
545 | |||
522 | temp = FAN_RPM_TO_PERIOD(temp); | 546 | temp = FAN_RPM_TO_PERIOD(temp); |
547 | temp = SENSORS_LIMIT(temp, 1, 65534); | ||
523 | 548 | ||
524 | mutex_lock(&data->lock); | 549 | mutex_lock(&data->lock); |
525 | data->fan_min[attr->index] = temp; | 550 | data->fan_min[attr->index] = temp; |
@@ -558,7 +583,10 @@ static ssize_t set_max_duty_at_crit(struct device *dev, | |||
558 | u8 reg; | 583 | u8 reg; |
559 | struct i2c_client *client = to_i2c_client(dev); | 584 | struct i2c_client *client = to_i2c_client(dev); |
560 | struct adt7473_data *data = i2c_get_clientdata(client); | 585 | struct adt7473_data *data = i2c_get_clientdata(client); |
561 | int temp = simple_strtol(buf, NULL, 10); | 586 | long temp; |
587 | |||
588 | if (strict_strtol(buf, 10, &temp)) | ||
589 | return -EINVAL; | ||
562 | 590 | ||
563 | mutex_lock(&data->lock); | 591 | mutex_lock(&data->lock); |
564 | data->max_duty_at_overheat = !!temp; | 592 | data->max_duty_at_overheat = !!temp; |
@@ -587,7 +615,12 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, | |||
587 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 615 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
588 | struct i2c_client *client = to_i2c_client(dev); | 616 | struct i2c_client *client = to_i2c_client(dev); |
589 | struct adt7473_data *data = i2c_get_clientdata(client); | 617 | struct adt7473_data *data = i2c_get_clientdata(client); |
590 | int temp = simple_strtol(buf, NULL, 10); | 618 | long temp; |
619 | |||
620 | if (strict_strtol(buf, 10, &temp)) | ||
621 | return -EINVAL; | ||
622 | |||
623 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
591 | 624 | ||
592 | mutex_lock(&data->lock); | 625 | mutex_lock(&data->lock); |
593 | data->pwm[attr->index] = temp; | 626 | data->pwm[attr->index] = temp; |
@@ -614,7 +647,12 @@ static ssize_t set_pwm_max(struct device *dev, | |||
614 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 647 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
615 | struct i2c_client *client = to_i2c_client(dev); | 648 | struct i2c_client *client = to_i2c_client(dev); |
616 | struct adt7473_data *data = i2c_get_clientdata(client); | 649 | struct adt7473_data *data = i2c_get_clientdata(client); |
617 | int temp = simple_strtol(buf, NULL, 10); | 650 | long temp; |
651 | |||
652 | if (strict_strtol(buf, 10, &temp)) | ||
653 | return -EINVAL; | ||
654 | |||
655 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
618 | 656 | ||
619 | mutex_lock(&data->lock); | 657 | mutex_lock(&data->lock); |
620 | data->pwm_max[attr->index] = temp; | 658 | data->pwm_max[attr->index] = temp; |
@@ -642,7 +680,12 @@ static ssize_t set_pwm_min(struct device *dev, | |||
642 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 680 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
643 | struct i2c_client *client = to_i2c_client(dev); | 681 | struct i2c_client *client = to_i2c_client(dev); |
644 | struct adt7473_data *data = i2c_get_clientdata(client); | 682 | struct adt7473_data *data = i2c_get_clientdata(client); |
645 | int temp = simple_strtol(buf, NULL, 10); | 683 | long temp; |
684 | |||
685 | if (strict_strtol(buf, 10, &temp)) | ||
686 | return -EINVAL; | ||
687 | |||
688 | temp = SENSORS_LIMIT(temp, 0, 255); | ||
646 | 689 | ||
647 | mutex_lock(&data->lock); | 690 | mutex_lock(&data->lock); |
648 | data->pwm_min[attr->index] = temp; | 691 | data->pwm_min[attr->index] = temp; |
@@ -672,7 +715,12 @@ static ssize_t set_temp_tmax(struct device *dev, | |||
672 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 715 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
673 | struct i2c_client *client = to_i2c_client(dev); | 716 | struct i2c_client *client = to_i2c_client(dev); |
674 | struct adt7473_data *data = i2c_get_clientdata(client); | 717 | struct adt7473_data *data = i2c_get_clientdata(client); |
675 | int temp = simple_strtol(buf, NULL, 10) / 1000; | 718 | long temp; |
719 | |||
720 | if (strict_strtol(buf, 10, &temp)) | ||
721 | return -EINVAL; | ||
722 | |||
723 | temp = ROUND_DIV(temp, 1000); | ||
676 | temp = encode_temp(data->temp_twos_complement, temp); | 724 | temp = encode_temp(data->temp_twos_complement, temp); |
677 | 725 | ||
678 | mutex_lock(&data->lock); | 726 | mutex_lock(&data->lock); |
@@ -703,7 +751,12 @@ static ssize_t set_temp_tmin(struct device *dev, | |||
703 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 751 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
704 | struct i2c_client *client = to_i2c_client(dev); | 752 | struct i2c_client *client = to_i2c_client(dev); |
705 | struct adt7473_data *data = i2c_get_clientdata(client); | 753 | struct adt7473_data *data = i2c_get_clientdata(client); |
706 | int temp = simple_strtol(buf, NULL, 10) / 1000; | 754 | long temp; |
755 | |||
756 | if (strict_strtol(buf, 10, &temp)) | ||
757 | return -EINVAL; | ||
758 | |||
759 | temp = ROUND_DIV(temp, 1000); | ||
707 | temp = encode_temp(data->temp_twos_complement, temp); | 760 | temp = encode_temp(data->temp_twos_complement, temp); |
708 | 761 | ||
709 | mutex_lock(&data->lock); | 762 | mutex_lock(&data->lock); |
@@ -741,7 +794,10 @@ static ssize_t set_pwm_enable(struct device *dev, | |||
741 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 794 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
742 | struct i2c_client *client = to_i2c_client(dev); | 795 | struct i2c_client *client = to_i2c_client(dev); |
743 | struct adt7473_data *data = i2c_get_clientdata(client); | 796 | struct adt7473_data *data = i2c_get_clientdata(client); |
744 | int temp = simple_strtol(buf, NULL, 10); | 797 | long temp; |
798 | |||
799 | if (strict_strtol(buf, 10, &temp)) | ||
800 | return -EINVAL; | ||
745 | 801 | ||
746 | switch (temp) { | 802 | switch (temp) { |
747 | case 0: | 803 | case 0: |
@@ -805,7 +861,10 @@ static ssize_t set_pwm_auto_temp(struct device *dev, | |||
805 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 861 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
806 | struct i2c_client *client = to_i2c_client(dev); | 862 | struct i2c_client *client = to_i2c_client(dev); |
807 | struct adt7473_data *data = i2c_get_clientdata(client); | 863 | struct adt7473_data *data = i2c_get_clientdata(client); |
808 | int temp = simple_strtol(buf, NULL, 10); | 864 | long temp; |
865 | |||
866 | if (strict_strtol(buf, 10, &temp)) | ||
867 | return -EINVAL; | ||
809 | 868 | ||
810 | switch (temp) { | 869 | switch (temp) { |
811 | case 1: | 870 | case 1: |
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index bc011da79e14..488e45cd43d7 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c | |||
@@ -116,6 +116,18 @@ static const char* temperature_sensors_sets[][36] = { | |||
116 | /* Set 9: Macbook Pro 3,1 (Santa Rosa) */ | 116 | /* Set 9: Macbook Pro 3,1 (Santa Rosa) */ |
117 | { "TALP", "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P", | 117 | { "TALP", "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P", |
118 | "Th0H", "Th1H", "Th2H", "Tm0P", "Ts0P", NULL }, | 118 | "Th0H", "Th1H", "Th2H", "Tm0P", "Ts0P", NULL }, |
119 | /* Set 10: iMac 5,1 */ | ||
120 | { "TA0P", "TC0D", "TC0P", "TG0D", "TH0P", "TO0P", "Tm0P", NULL }, | ||
121 | /* Set 11: Macbook 5,1 */ | ||
122 | { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0P", "TN0D", "TN0P", | ||
123 | "TTF0", "Th0H", "Th1H", "ThFH", "Ts0P", "Ts0S", NULL }, | ||
124 | /* Set 12: Macbook Pro 5,1 */ | ||
125 | { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TG0D", | ||
126 | "TG0F", "TG0H", "TG0P", "TG0T", "TG1H", "TN0D", "TN0P", "TTF0", | ||
127 | "Th2H", "Tm0P", "Ts0P", "Ts0S", NULL }, | ||
128 | /* Set 13: iMac 8,1 */ | ||
129 | { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TG0P", "TH0P", | ||
130 | "TL0P", "TO0P", "TW0P", "Tm0P", "Tp0P", NULL }, | ||
119 | }; | 131 | }; |
120 | 132 | ||
121 | /* List of keys used to read/write fan speeds */ | 133 | /* List of keys used to read/write fan speeds */ |
@@ -1268,7 +1280,7 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = { | |||
1268 | { .accelerometer = 0, .light = 0, .temperature_set = 4 }, | 1280 | { .accelerometer = 0, .light = 0, .temperature_set = 4 }, |
1269 | /* iMac: temperature set 5 */ | 1281 | /* iMac: temperature set 5 */ |
1270 | { .accelerometer = 0, .light = 0, .temperature_set = 5 }, | 1282 | { .accelerometer = 0, .light = 0, .temperature_set = 5 }, |
1271 | /* MacBook3: accelerometer and temperature set 6 */ | 1283 | /* MacBook3, MacBook4: accelerometer and temperature set 6 */ |
1272 | { .accelerometer = 1, .light = 0, .temperature_set = 6 }, | 1284 | { .accelerometer = 1, .light = 0, .temperature_set = 6 }, |
1273 | /* MacBook Air: accelerometer, backlight and temperature set 7 */ | 1285 | /* MacBook Air: accelerometer, backlight and temperature set 7 */ |
1274 | { .accelerometer = 1, .light = 1, .temperature_set = 7 }, | 1286 | { .accelerometer = 1, .light = 1, .temperature_set = 7 }, |
@@ -1276,6 +1288,14 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = { | |||
1276 | { .accelerometer = 1, .light = 1, .temperature_set = 8 }, | 1288 | { .accelerometer = 1, .light = 1, .temperature_set = 8 }, |
1277 | /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */ | 1289 | /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */ |
1278 | { .accelerometer = 1, .light = 1, .temperature_set = 9 }, | 1290 | { .accelerometer = 1, .light = 1, .temperature_set = 9 }, |
1291 | /* iMac 5: light sensor only, temperature set 10 */ | ||
1292 | { .accelerometer = 0, .light = 0, .temperature_set = 10 }, | ||
1293 | /* MacBook 5: accelerometer, backlight and temperature set 11 */ | ||
1294 | { .accelerometer = 1, .light = 1, .temperature_set = 11 }, | ||
1295 | /* MacBook Pro 5: accelerometer, backlight and temperature set 12 */ | ||
1296 | { .accelerometer = 1, .light = 1, .temperature_set = 12 }, | ||
1297 | /* iMac 8: light sensor only, temperature set 13 */ | ||
1298 | { .accelerometer = 0, .light = 0, .temperature_set = 13 }, | ||
1279 | }; | 1299 | }; |
1280 | 1300 | ||
1281 | /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". | 1301 | /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". |
@@ -1285,6 +1305,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { | |||
1285 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | 1305 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), |
1286 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") }, | 1306 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") }, |
1287 | &applesmc_dmi_data[7]}, | 1307 | &applesmc_dmi_data[7]}, |
1308 | { applesmc_dmi_match, "Apple MacBook Pro 5", { | ||
1309 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
1310 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5") }, | ||
1311 | &applesmc_dmi_data[12]}, | ||
1288 | { applesmc_dmi_match, "Apple MacBook Pro 4", { | 1312 | { applesmc_dmi_match, "Apple MacBook Pro 4", { |
1289 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | 1313 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), |
1290 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") }, | 1314 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") }, |
@@ -1305,6 +1329,14 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { | |||
1305 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1329 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
1306 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") }, | 1330 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") }, |
1307 | &applesmc_dmi_data[6]}, | 1331 | &applesmc_dmi_data[6]}, |
1332 | { applesmc_dmi_match, "Apple MacBook 4", { | ||
1333 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
1334 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4") }, | ||
1335 | &applesmc_dmi_data[6]}, | ||
1336 | { applesmc_dmi_match, "Apple MacBook 5", { | ||
1337 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
1338 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5") }, | ||
1339 | &applesmc_dmi_data[11]}, | ||
1308 | { applesmc_dmi_match, "Apple MacBook", { | 1340 | { applesmc_dmi_match, "Apple MacBook", { |
1309 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1341 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
1310 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") }, | 1342 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") }, |
@@ -1317,6 +1349,14 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { | |||
1317 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1349 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
1318 | DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") }, | 1350 | DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") }, |
1319 | &applesmc_dmi_data[4]}, | 1351 | &applesmc_dmi_data[4]}, |
1352 | { applesmc_dmi_match, "Apple iMac 8", { | ||
1353 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
1354 | DMI_MATCH(DMI_PRODUCT_NAME, "iMac8") }, | ||
1355 | &applesmc_dmi_data[13]}, | ||
1356 | { applesmc_dmi_match, "Apple iMac 5", { | ||
1357 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
1358 | DMI_MATCH(DMI_PRODUCT_NAME, "iMac5") }, | ||
1359 | &applesmc_dmi_data[10]}, | ||
1320 | { applesmc_dmi_match, "Apple iMac", { | 1360 | { applesmc_dmi_match, "Apple iMac", { |
1321 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1361 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
1322 | DMI_MATCH(DMI_PRODUCT_NAME,"iMac") }, | 1362 | DMI_MATCH(DMI_PRODUCT_NAME,"iMac") }, |
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c index 7b0ed5dea399..fe74609a7feb 100644 --- a/drivers/hwmon/ibmaem.c +++ b/drivers/hwmon/ibmaem.c | |||
@@ -88,9 +88,11 @@ | |||
88 | static DEFINE_IDR(aem_idr); | 88 | static DEFINE_IDR(aem_idr); |
89 | static DEFINE_SPINLOCK(aem_idr_lock); | 89 | static DEFINE_SPINLOCK(aem_idr_lock); |
90 | 90 | ||
91 | static struct device_driver aem_driver = { | 91 | static struct platform_driver aem_driver = { |
92 | .name = DRVNAME, | 92 | .driver = { |
93 | .bus = &platform_bus_type, | 93 | .name = DRVNAME, |
94 | .bus = &platform_bus_type, | ||
95 | } | ||
94 | }; | 96 | }; |
95 | 97 | ||
96 | struct aem_ipmi_data { | 98 | struct aem_ipmi_data { |
@@ -583,7 +585,7 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle) | |||
583 | data->pdev = platform_device_alloc(DRVNAME, data->id); | 585 | data->pdev = platform_device_alloc(DRVNAME, data->id); |
584 | if (!data->pdev) | 586 | if (!data->pdev) |
585 | goto dev_err; | 587 | goto dev_err; |
586 | data->pdev->dev.driver = &aem_driver; | 588 | data->pdev->dev.driver = &aem_driver.driver; |
587 | 589 | ||
588 | res = platform_device_add(data->pdev); | 590 | res = platform_device_add(data->pdev); |
589 | if (res) | 591 | if (res) |
@@ -716,7 +718,7 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe, | |||
716 | data->pdev = platform_device_alloc(DRVNAME, data->id); | 718 | data->pdev = platform_device_alloc(DRVNAME, data->id); |
717 | if (!data->pdev) | 719 | if (!data->pdev) |
718 | goto dev_err; | 720 | goto dev_err; |
719 | data->pdev->dev.driver = &aem_driver; | 721 | data->pdev->dev.driver = &aem_driver.driver; |
720 | 722 | ||
721 | res = platform_device_add(data->pdev); | 723 | res = platform_device_add(data->pdev); |
722 | if (res) | 724 | if (res) |
@@ -1085,7 +1087,7 @@ static int __init aem_init(void) | |||
1085 | { | 1087 | { |
1086 | int res; | 1088 | int res; |
1087 | 1089 | ||
1088 | res = driver_register(&aem_driver); | 1090 | res = driver_register(&aem_driver.driver); |
1089 | if (res) { | 1091 | if (res) { |
1090 | printk(KERN_ERR "Can't register aem driver\n"); | 1092 | printk(KERN_ERR "Can't register aem driver\n"); |
1091 | return res; | 1093 | return res; |
@@ -1097,7 +1099,7 @@ static int __init aem_init(void) | |||
1097 | return 0; | 1099 | return 0; |
1098 | 1100 | ||
1099 | ipmi_reg_err: | 1101 | ipmi_reg_err: |
1100 | driver_unregister(&aem_driver); | 1102 | driver_unregister(&aem_driver.driver); |
1101 | return res; | 1103 | return res; |
1102 | 1104 | ||
1103 | } | 1105 | } |
@@ -1107,7 +1109,7 @@ static void __exit aem_exit(void) | |||
1107 | struct aem_data *p1, *next1; | 1109 | struct aem_data *p1, *next1; |
1108 | 1110 | ||
1109 | ipmi_smi_watcher_unregister(&driver_data.bmc_events); | 1111 | ipmi_smi_watcher_unregister(&driver_data.bmc_events); |
1110 | driver_unregister(&aem_driver); | 1112 | driver_unregister(&aem_driver.driver); |
1111 | list_for_each_entry_safe(p1, next1, &driver_data.aem_devices, list) | 1113 | list_for_each_entry_safe(p1, next1, &driver_data.aem_devices, list) |
1112 | aem_delete(p1); | 1114 | aem_delete(p1); |
1113 | } | 1115 | } |
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c new file mode 100644 index 000000000000..752b5c44df9c --- /dev/null +++ b/drivers/hwmon/lis3lv02d.c | |||
@@ -0,0 +1,582 @@ | |||
1 | /* | ||
2 | * lis3lv02d.c - ST LIS3LV02DL accelerometer driver | ||
3 | * | ||
4 | * Copyright (C) 2007-2008 Yan Burman | ||
5 | * Copyright (C) 2008 Eric Piel | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/dmi.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/types.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/input.h> | ||
30 | #include <linux/kthread.h> | ||
31 | #include <linux/semaphore.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/wait.h> | ||
34 | #include <linux/poll.h> | ||
35 | #include <linux/freezer.h> | ||
36 | #include <linux/version.h> | ||
37 | #include <linux/uaccess.h> | ||
38 | #include <acpi/acpi_drivers.h> | ||
39 | #include <asm/atomic.h> | ||
40 | #include "lis3lv02d.h" | ||
41 | |||
42 | #define DRIVER_NAME "lis3lv02d" | ||
43 | #define ACPI_MDPS_CLASS "accelerometer" | ||
44 | |||
45 | /* joystick device poll interval in milliseconds */ | ||
46 | #define MDPS_POLL_INTERVAL 50 | ||
47 | /* | ||
48 | * The sensor can also generate interrupts (DRDY) but it's pretty pointless | ||
49 | * because their are generated even if the data do not change. So it's better | ||
50 | * to keep the interrupt for the free-fall event. The values are updated at | ||
51 | * 40Hz (at the lowest frequency), but as it can be pretty time consuming on | ||
52 | * some low processor, we poll the sensor only at 20Hz... enough for the | ||
53 | * joystick. | ||
54 | */ | ||
55 | |||
56 | /* Maximum value our axis may get for the input device (signed 12 bits) */ | ||
57 | #define MDPS_MAX_VAL 2048 | ||
58 | |||
59 | struct axis_conversion { | ||
60 | s8 x; | ||
61 | s8 y; | ||
62 | s8 z; | ||
63 | }; | ||
64 | |||
65 | struct acpi_lis3lv02d { | ||
66 | struct acpi_device *device; /* The ACPI device */ | ||
67 | struct input_dev *idev; /* input device */ | ||
68 | struct task_struct *kthread; /* kthread for input */ | ||
69 | struct mutex lock; | ||
70 | struct platform_device *pdev; /* platform device */ | ||
71 | atomic_t count; /* interrupt count after last read */ | ||
72 | int xcalib; /* calibrated null value for x */ | ||
73 | int ycalib; /* calibrated null value for y */ | ||
74 | int zcalib; /* calibrated null value for z */ | ||
75 | unsigned char is_on; /* whether the device is on or off */ | ||
76 | unsigned char usage; /* usage counter */ | ||
77 | struct axis_conversion ac; /* hw -> logical axis */ | ||
78 | }; | ||
79 | |||
80 | static struct acpi_lis3lv02d adev; | ||
81 | |||
82 | static int lis3lv02d_remove_fs(void); | ||
83 | static int lis3lv02d_add_fs(struct acpi_device *device); | ||
84 | |||
85 | /* For automatic insertion of the module */ | ||
86 | static struct acpi_device_id lis3lv02d_device_ids[] = { | ||
87 | {"HPQ0004", 0}, /* HP Mobile Data Protection System PNP */ | ||
88 | {"", 0}, | ||
89 | }; | ||
90 | MODULE_DEVICE_TABLE(acpi, lis3lv02d_device_ids); | ||
91 | |||
92 | /** | ||
93 | * lis3lv02d_acpi_init - ACPI _INI method: initialize the device. | ||
94 | * @handle: the handle of the device | ||
95 | * | ||
96 | * Returns AE_OK on success. | ||
97 | */ | ||
98 | static inline acpi_status lis3lv02d_acpi_init(acpi_handle handle) | ||
99 | { | ||
100 | return acpi_evaluate_object(handle, METHOD_NAME__INI, NULL, NULL); | ||
101 | } | ||
102 | |||
103 | /** | ||
104 | * lis3lv02d_acpi_read - ACPI ALRD method: read a register | ||
105 | * @handle: the handle of the device | ||
106 | * @reg: the register to read | ||
107 | * @ret: result of the operation | ||
108 | * | ||
109 | * Returns AE_OK on success. | ||
110 | */ | ||
111 | static acpi_status lis3lv02d_acpi_read(acpi_handle handle, int reg, u8 *ret) | ||
112 | { | ||
113 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; | ||
114 | struct acpi_object_list args = { 1, &arg0 }; | ||
115 | unsigned long long lret; | ||
116 | acpi_status status; | ||
117 | |||
118 | arg0.integer.value = reg; | ||
119 | |||
120 | status = acpi_evaluate_integer(handle, "ALRD", &args, &lret); | ||
121 | *ret = lret; | ||
122 | return status; | ||
123 | } | ||
124 | |||
125 | /** | ||
126 | * lis3lv02d_acpi_write - ACPI ALWR method: write to a register | ||
127 | * @handle: the handle of the device | ||
128 | * @reg: the register to write to | ||
129 | * @val: the value to write | ||
130 | * | ||
131 | * Returns AE_OK on success. | ||
132 | */ | ||
133 | static acpi_status lis3lv02d_acpi_write(acpi_handle handle, int reg, u8 val) | ||
134 | { | ||
135 | unsigned long long ret; /* Not used when writting */ | ||
136 | union acpi_object in_obj[2]; | ||
137 | struct acpi_object_list args = { 2, in_obj }; | ||
138 | |||
139 | in_obj[0].type = ACPI_TYPE_INTEGER; | ||
140 | in_obj[0].integer.value = reg; | ||
141 | in_obj[1].type = ACPI_TYPE_INTEGER; | ||
142 | in_obj[1].integer.value = val; | ||
143 | |||
144 | return acpi_evaluate_integer(handle, "ALWR", &args, &ret); | ||
145 | } | ||
146 | |||
147 | static s16 lis3lv02d_read_16(acpi_handle handle, int reg) | ||
148 | { | ||
149 | u8 lo, hi; | ||
150 | |||
151 | lis3lv02d_acpi_read(handle, reg, &lo); | ||
152 | lis3lv02d_acpi_read(handle, reg + 1, &hi); | ||
153 | /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */ | ||
154 | return (s16)((hi << 8) | lo); | ||
155 | } | ||
156 | |||
157 | /** | ||
158 | * lis3lv02d_get_axis - For the given axis, give the value converted | ||
159 | * @axis: 1,2,3 - can also be negative | ||
160 | * @hw_values: raw values returned by the hardware | ||
161 | * | ||
162 | * Returns the converted value. | ||
163 | */ | ||
164 | static inline int lis3lv02d_get_axis(s8 axis, int hw_values[3]) | ||
165 | { | ||
166 | if (axis > 0) | ||
167 | return hw_values[axis - 1]; | ||
168 | else | ||
169 | return -hw_values[-axis - 1]; | ||
170 | } | ||
171 | |||
172 | /** | ||
173 | * lis3lv02d_get_xyz - Get X, Y and Z axis values from the accelerometer | ||
174 | * @handle: the handle to the device | ||
175 | * @x: where to store the X axis value | ||
176 | * @y: where to store the Y axis value | ||
177 | * @z: where to store the Z axis value | ||
178 | * | ||
179 | * Note that 40Hz input device can eat up about 10% CPU at 800MHZ | ||
180 | */ | ||
181 | static void lis3lv02d_get_xyz(acpi_handle handle, int *x, int *y, int *z) | ||
182 | { | ||
183 | int position[3]; | ||
184 | |||
185 | position[0] = lis3lv02d_read_16(handle, OUTX_L); | ||
186 | position[1] = lis3lv02d_read_16(handle, OUTY_L); | ||
187 | position[2] = lis3lv02d_read_16(handle, OUTZ_L); | ||
188 | |||
189 | *x = lis3lv02d_get_axis(adev.ac.x, position); | ||
190 | *y = lis3lv02d_get_axis(adev.ac.y, position); | ||
191 | *z = lis3lv02d_get_axis(adev.ac.z, position); | ||
192 | } | ||
193 | |||
194 | static inline void lis3lv02d_poweroff(acpi_handle handle) | ||
195 | { | ||
196 | adev.is_on = 0; | ||
197 | /* disable X,Y,Z axis and power down */ | ||
198 | lis3lv02d_acpi_write(handle, CTRL_REG1, 0x00); | ||
199 | } | ||
200 | |||
201 | static void lis3lv02d_poweron(acpi_handle handle) | ||
202 | { | ||
203 | u8 val; | ||
204 | |||
205 | adev.is_on = 1; | ||
206 | lis3lv02d_acpi_init(handle); | ||
207 | lis3lv02d_acpi_write(handle, FF_WU_CFG, 0); | ||
208 | /* | ||
209 | * BDU: LSB and MSB values are not updated until both have been read. | ||
210 | * So the value read will always be correct. | ||
211 | * IEN: Interrupt for free-fall and DD, not for data-ready. | ||
212 | */ | ||
213 | lis3lv02d_acpi_read(handle, CTRL_REG2, &val); | ||
214 | val |= CTRL2_BDU | CTRL2_IEN; | ||
215 | lis3lv02d_acpi_write(handle, CTRL_REG2, val); | ||
216 | } | ||
217 | |||
218 | #ifdef CONFIG_PM | ||
219 | static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state) | ||
220 | { | ||
221 | /* make sure the device is off when we suspend */ | ||
222 | lis3lv02d_poweroff(device->handle); | ||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | static int lis3lv02d_resume(struct acpi_device *device) | ||
227 | { | ||
228 | /* put back the device in the right state (ACPI might turn it on) */ | ||
229 | mutex_lock(&adev.lock); | ||
230 | if (adev.usage > 0) | ||
231 | lis3lv02d_poweron(device->handle); | ||
232 | else | ||
233 | lis3lv02d_poweroff(device->handle); | ||
234 | mutex_unlock(&adev.lock); | ||
235 | return 0; | ||
236 | } | ||
237 | #else | ||
238 | #define lis3lv02d_suspend NULL | ||
239 | #define lis3lv02d_resume NULL | ||
240 | #endif | ||
241 | |||
242 | |||
243 | /* | ||
244 | * To be called before starting to use the device. It makes sure that the | ||
245 | * device will always be on until a call to lis3lv02d_decrease_use(). Not to be | ||
246 | * used from interrupt context. | ||
247 | */ | ||
248 | static void lis3lv02d_increase_use(struct acpi_lis3lv02d *dev) | ||
249 | { | ||
250 | mutex_lock(&dev->lock); | ||
251 | dev->usage++; | ||
252 | if (dev->usage == 1) { | ||
253 | if (!dev->is_on) | ||
254 | lis3lv02d_poweron(dev->device->handle); | ||
255 | } | ||
256 | mutex_unlock(&dev->lock); | ||
257 | } | ||
258 | |||
259 | /* | ||
260 | * To be called whenever a usage of the device is stopped. | ||
261 | * It will make sure to turn off the device when there is not usage. | ||
262 | */ | ||
263 | static void lis3lv02d_decrease_use(struct acpi_lis3lv02d *dev) | ||
264 | { | ||
265 | mutex_lock(&dev->lock); | ||
266 | dev->usage--; | ||
267 | if (dev->usage == 0) | ||
268 | lis3lv02d_poweroff(dev->device->handle); | ||
269 | mutex_unlock(&dev->lock); | ||
270 | } | ||
271 | |||
272 | /** | ||
273 | * lis3lv02d_joystick_kthread - Kthread polling function | ||
274 | * @data: unused - here to conform to threadfn prototype | ||
275 | */ | ||
276 | static int lis3lv02d_joystick_kthread(void *data) | ||
277 | { | ||
278 | int x, y, z; | ||
279 | |||
280 | while (!kthread_should_stop()) { | ||
281 | lis3lv02d_get_xyz(adev.device->handle, &x, &y, &z); | ||
282 | input_report_abs(adev.idev, ABS_X, x - adev.xcalib); | ||
283 | input_report_abs(adev.idev, ABS_Y, y - adev.ycalib); | ||
284 | input_report_abs(adev.idev, ABS_Z, z - adev.zcalib); | ||
285 | |||
286 | input_sync(adev.idev); | ||
287 | |||
288 | try_to_freeze(); | ||
289 | msleep_interruptible(MDPS_POLL_INTERVAL); | ||
290 | } | ||
291 | |||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | static int lis3lv02d_joystick_open(struct input_dev *input) | ||
296 | { | ||
297 | lis3lv02d_increase_use(&adev); | ||
298 | adev.kthread = kthread_run(lis3lv02d_joystick_kthread, NULL, "klis3lv02d"); | ||
299 | if (IS_ERR(adev.kthread)) { | ||
300 | lis3lv02d_decrease_use(&adev); | ||
301 | return PTR_ERR(adev.kthread); | ||
302 | } | ||
303 | |||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | static void lis3lv02d_joystick_close(struct input_dev *input) | ||
308 | { | ||
309 | kthread_stop(adev.kthread); | ||
310 | lis3lv02d_decrease_use(&adev); | ||
311 | } | ||
312 | |||
313 | |||
314 | static inline void lis3lv02d_calibrate_joystick(void) | ||
315 | { | ||
316 | lis3lv02d_get_xyz(adev.device->handle, &adev.xcalib, &adev.ycalib, &adev.zcalib); | ||
317 | } | ||
318 | |||
319 | static int lis3lv02d_joystick_enable(void) | ||
320 | { | ||
321 | int err; | ||
322 | |||
323 | if (adev.idev) | ||
324 | return -EINVAL; | ||
325 | |||
326 | adev.idev = input_allocate_device(); | ||
327 | if (!adev.idev) | ||
328 | return -ENOMEM; | ||
329 | |||
330 | lis3lv02d_calibrate_joystick(); | ||
331 | |||
332 | adev.idev->name = "ST LIS3LV02DL Accelerometer"; | ||
333 | adev.idev->phys = DRIVER_NAME "/input0"; | ||
334 | adev.idev->id.bustype = BUS_HOST; | ||
335 | adev.idev->id.vendor = 0; | ||
336 | adev.idev->dev.parent = &adev.pdev->dev; | ||
337 | adev.idev->open = lis3lv02d_joystick_open; | ||
338 | adev.idev->close = lis3lv02d_joystick_close; | ||
339 | |||
340 | set_bit(EV_ABS, adev.idev->evbit); | ||
341 | input_set_abs_params(adev.idev, ABS_X, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3); | ||
342 | input_set_abs_params(adev.idev, ABS_Y, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3); | ||
343 | input_set_abs_params(adev.idev, ABS_Z, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3); | ||
344 | |||
345 | err = input_register_device(adev.idev); | ||
346 | if (err) { | ||
347 | input_free_device(adev.idev); | ||
348 | adev.idev = NULL; | ||
349 | } | ||
350 | |||
351 | return err; | ||
352 | } | ||
353 | |||
354 | static void lis3lv02d_joystick_disable(void) | ||
355 | { | ||
356 | if (!adev.idev) | ||
357 | return; | ||
358 | |||
359 | input_unregister_device(adev.idev); | ||
360 | adev.idev = NULL; | ||
361 | } | ||
362 | |||
363 | |||
364 | /* | ||
365 | * Initialise the accelerometer and the various subsystems. | ||
366 | * Should be rather independant of the bus system. | ||
367 | */ | ||
368 | static int lis3lv02d_init_device(struct acpi_lis3lv02d *dev) | ||
369 | { | ||
370 | mutex_init(&dev->lock); | ||
371 | lis3lv02d_add_fs(dev->device); | ||
372 | lis3lv02d_increase_use(dev); | ||
373 | |||
374 | if (lis3lv02d_joystick_enable()) | ||
375 | printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n"); | ||
376 | |||
377 | lis3lv02d_decrease_use(dev); | ||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | static int lis3lv02d_dmi_matched(const struct dmi_system_id *dmi) | ||
382 | { | ||
383 | adev.ac = *((struct axis_conversion *)dmi->driver_data); | ||
384 | printk(KERN_INFO DRIVER_NAME ": hardware type %s found.\n", dmi->ident); | ||
385 | |||
386 | return 1; | ||
387 | } | ||
388 | |||
389 | /* Represents, for each axis seen by userspace, the corresponding hw axis (+1). | ||
390 | * If the value is negative, the opposite of the hw value is used. */ | ||
391 | static struct axis_conversion lis3lv02d_axis_normal = {1, 2, 3}; | ||
392 | static struct axis_conversion lis3lv02d_axis_y_inverted = {1, -2, 3}; | ||
393 | static struct axis_conversion lis3lv02d_axis_x_inverted = {-1, 2, 3}; | ||
394 | static struct axis_conversion lis3lv02d_axis_z_inverted = {1, 2, -3}; | ||
395 | static struct axis_conversion lis3lv02d_axis_xy_rotated_left = {-2, 1, 3}; | ||
396 | static struct axis_conversion lis3lv02d_axis_xy_swap_inverted = {-2, -1, 3}; | ||
397 | |||
398 | #define AXIS_DMI_MATCH(_ident, _name, _axis) { \ | ||
399 | .ident = _ident, \ | ||
400 | .callback = lis3lv02d_dmi_matched, \ | ||
401 | .matches = { \ | ||
402 | DMI_MATCH(DMI_PRODUCT_NAME, _name) \ | ||
403 | }, \ | ||
404 | .driver_data = &lis3lv02d_axis_##_axis \ | ||
405 | } | ||
406 | static struct dmi_system_id lis3lv02d_dmi_ids[] = { | ||
407 | /* product names are truncated to match all kinds of a same model */ | ||
408 | AXIS_DMI_MATCH("NC64x0", "HP Compaq nc64", x_inverted), | ||
409 | AXIS_DMI_MATCH("NC84x0", "HP Compaq nc84", z_inverted), | ||
410 | AXIS_DMI_MATCH("NX9420", "HP Compaq nx9420", x_inverted), | ||
411 | AXIS_DMI_MATCH("NW9440", "HP Compaq nw9440", x_inverted), | ||
412 | AXIS_DMI_MATCH("NC2510", "HP Compaq 2510", y_inverted), | ||
413 | AXIS_DMI_MATCH("NC8510", "HP Compaq 8510", xy_swap_inverted), | ||
414 | AXIS_DMI_MATCH("HP2133", "HP 2133", xy_rotated_left), | ||
415 | { NULL, } | ||
416 | /* Laptop models without axis info (yet): | ||
417 | * "NC651xx" "HP Compaq 651" | ||
418 | * "NC671xx" "HP Compaq 671" | ||
419 | * "NC6910" "HP Compaq 6910" | ||
420 | * HP Compaq 8710x Notebook PC / Mobile Workstation | ||
421 | * "NC2400" "HP Compaq nc2400" | ||
422 | * "NX74x0" "HP Compaq nx74" | ||
423 | * "NX6325" "HP Compaq nx6325" | ||
424 | * "NC4400" "HP Compaq nc4400" | ||
425 | */ | ||
426 | }; | ||
427 | |||
428 | static int lis3lv02d_add(struct acpi_device *device) | ||
429 | { | ||
430 | u8 val; | ||
431 | |||
432 | if (!device) | ||
433 | return -EINVAL; | ||
434 | |||
435 | adev.device = device; | ||
436 | strcpy(acpi_device_name(device), DRIVER_NAME); | ||
437 | strcpy(acpi_device_class(device), ACPI_MDPS_CLASS); | ||
438 | device->driver_data = &adev; | ||
439 | |||
440 | lis3lv02d_acpi_read(device->handle, WHO_AM_I, &val); | ||
441 | if ((val != LIS3LV02DL_ID) && (val != LIS302DL_ID)) { | ||
442 | printk(KERN_ERR DRIVER_NAME | ||
443 | ": Accelerometer chip not LIS3LV02D{L,Q}\n"); | ||
444 | } | ||
445 | |||
446 | /* If possible use a "standard" axes order */ | ||
447 | if (dmi_check_system(lis3lv02d_dmi_ids) == 0) { | ||
448 | printk(KERN_INFO DRIVER_NAME ": laptop model unknown, " | ||
449 | "using default axes configuration\n"); | ||
450 | adev.ac = lis3lv02d_axis_normal; | ||
451 | } | ||
452 | |||
453 | return lis3lv02d_init_device(&adev); | ||
454 | } | ||
455 | |||
456 | static int lis3lv02d_remove(struct acpi_device *device, int type) | ||
457 | { | ||
458 | if (!device) | ||
459 | return -EINVAL; | ||
460 | |||
461 | lis3lv02d_joystick_disable(); | ||
462 | lis3lv02d_poweroff(device->handle); | ||
463 | |||
464 | return lis3lv02d_remove_fs(); | ||
465 | } | ||
466 | |||
467 | |||
468 | /* Sysfs stuff */ | ||
469 | static ssize_t lis3lv02d_position_show(struct device *dev, | ||
470 | struct device_attribute *attr, char *buf) | ||
471 | { | ||
472 | int x, y, z; | ||
473 | |||
474 | lis3lv02d_increase_use(&adev); | ||
475 | lis3lv02d_get_xyz(adev.device->handle, &x, &y, &z); | ||
476 | lis3lv02d_decrease_use(&adev); | ||
477 | return sprintf(buf, "(%d,%d,%d)\n", x, y, z); | ||
478 | } | ||
479 | |||
480 | static ssize_t lis3lv02d_calibrate_show(struct device *dev, | ||
481 | struct device_attribute *attr, char *buf) | ||
482 | { | ||
483 | return sprintf(buf, "(%d,%d,%d)\n", adev.xcalib, adev.ycalib, adev.zcalib); | ||
484 | } | ||
485 | |||
486 | static ssize_t lis3lv02d_calibrate_store(struct device *dev, | ||
487 | struct device_attribute *attr, | ||
488 | const char *buf, size_t count) | ||
489 | { | ||
490 | lis3lv02d_increase_use(&adev); | ||
491 | lis3lv02d_calibrate_joystick(); | ||
492 | lis3lv02d_decrease_use(&adev); | ||
493 | return count; | ||
494 | } | ||
495 | |||
496 | /* conversion btw sampling rate and the register values */ | ||
497 | static int lis3lv02dl_df_val[4] = {40, 160, 640, 2560}; | ||
498 | static ssize_t lis3lv02d_rate_show(struct device *dev, | ||
499 | struct device_attribute *attr, char *buf) | ||
500 | { | ||
501 | u8 ctrl; | ||
502 | int val; | ||
503 | |||
504 | lis3lv02d_increase_use(&adev); | ||
505 | lis3lv02d_acpi_read(adev.device->handle, CTRL_REG1, &ctrl); | ||
506 | lis3lv02d_decrease_use(&adev); | ||
507 | val = (ctrl & (CTRL1_DF0 | CTRL1_DF1)) >> 4; | ||
508 | return sprintf(buf, "%d\n", lis3lv02dl_df_val[val]); | ||
509 | } | ||
510 | |||
511 | static DEVICE_ATTR(position, S_IRUGO, lis3lv02d_position_show, NULL); | ||
512 | static DEVICE_ATTR(calibrate, S_IRUGO|S_IWUSR, lis3lv02d_calibrate_show, | ||
513 | lis3lv02d_calibrate_store); | ||
514 | static DEVICE_ATTR(rate, S_IRUGO, lis3lv02d_rate_show, NULL); | ||
515 | |||
516 | static struct attribute *lis3lv02d_attributes[] = { | ||
517 | &dev_attr_position.attr, | ||
518 | &dev_attr_calibrate.attr, | ||
519 | &dev_attr_rate.attr, | ||
520 | NULL | ||
521 | }; | ||
522 | |||
523 | static struct attribute_group lis3lv02d_attribute_group = { | ||
524 | .attrs = lis3lv02d_attributes | ||
525 | }; | ||
526 | |||
527 | static int lis3lv02d_add_fs(struct acpi_device *device) | ||
528 | { | ||
529 | adev.pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); | ||
530 | if (IS_ERR(adev.pdev)) | ||
531 | return PTR_ERR(adev.pdev); | ||
532 | |||
533 | return sysfs_create_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group); | ||
534 | } | ||
535 | |||
536 | static int lis3lv02d_remove_fs(void) | ||
537 | { | ||
538 | sysfs_remove_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group); | ||
539 | platform_device_unregister(adev.pdev); | ||
540 | return 0; | ||
541 | } | ||
542 | |||
543 | /* For the HP MDPS aka 3D Driveguard */ | ||
544 | static struct acpi_driver lis3lv02d_driver = { | ||
545 | .name = DRIVER_NAME, | ||
546 | .class = ACPI_MDPS_CLASS, | ||
547 | .ids = lis3lv02d_device_ids, | ||
548 | .ops = { | ||
549 | .add = lis3lv02d_add, | ||
550 | .remove = lis3lv02d_remove, | ||
551 | .suspend = lis3lv02d_suspend, | ||
552 | .resume = lis3lv02d_resume, | ||
553 | } | ||
554 | }; | ||
555 | |||
556 | static int __init lis3lv02d_init_module(void) | ||
557 | { | ||
558 | int ret; | ||
559 | |||
560 | if (acpi_disabled) | ||
561 | return -ENODEV; | ||
562 | |||
563 | ret = acpi_bus_register_driver(&lis3lv02d_driver); | ||
564 | if (ret < 0) | ||
565 | return ret; | ||
566 | |||
567 | printk(KERN_INFO DRIVER_NAME " driver loaded.\n"); | ||
568 | |||
569 | return 0; | ||
570 | } | ||
571 | |||
572 | static void __exit lis3lv02d_exit_module(void) | ||
573 | { | ||
574 | acpi_bus_unregister_driver(&lis3lv02d_driver); | ||
575 | } | ||
576 | |||
577 | MODULE_DESCRIPTION("ST LIS3LV02Dx three-axis digital accelerometer driver"); | ||
578 | MODULE_AUTHOR("Yan Burman and Eric Piel"); | ||
579 | MODULE_LICENSE("GPL"); | ||
580 | |||
581 | module_init(lis3lv02d_init_module); | ||
582 | module_exit(lis3lv02d_exit_module); | ||
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h new file mode 100644 index 000000000000..330cfc60e948 --- /dev/null +++ b/drivers/hwmon/lis3lv02d.h | |||
@@ -0,0 +1,149 @@ | |||
1 | /* | ||
2 | * lis3lv02d.h - ST LIS3LV02DL accelerometer driver | ||
3 | * | ||
4 | * Copyright (C) 2007-2008 Yan Burman | ||
5 | * Copyright (C) 2008 Eric Piel | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | /* | ||
23 | * The actual chip is STMicroelectronics LIS3LV02DL or LIS3LV02DQ that seems to | ||
24 | * be connected via SPI. There exists also several similar chips (such as LIS302DL or | ||
25 | * LIS3L02DQ) but not in the HP laptops and they have slightly different registers. | ||
26 | * They can also be connected via I²C. | ||
27 | */ | ||
28 | |||
29 | #define LIS3LV02DL_ID 0x3A /* Also the LIS3LV02DQ */ | ||
30 | #define LIS302DL_ID 0x3B /* Also the LIS202DL! */ | ||
31 | |||
32 | enum lis3lv02d_reg { | ||
33 | WHO_AM_I = 0x0F, | ||
34 | OFFSET_X = 0x16, | ||
35 | OFFSET_Y = 0x17, | ||
36 | OFFSET_Z = 0x18, | ||
37 | GAIN_X = 0x19, | ||
38 | GAIN_Y = 0x1A, | ||
39 | GAIN_Z = 0x1B, | ||
40 | CTRL_REG1 = 0x20, | ||
41 | CTRL_REG2 = 0x21, | ||
42 | CTRL_REG3 = 0x22, | ||
43 | HP_FILTER_RESET = 0x23, | ||
44 | STATUS_REG = 0x27, | ||
45 | OUTX_L = 0x28, | ||
46 | OUTX_H = 0x29, | ||
47 | OUTY_L = 0x2A, | ||
48 | OUTY_H = 0x2B, | ||
49 | OUTZ_L = 0x2C, | ||
50 | OUTZ_H = 0x2D, | ||
51 | FF_WU_CFG = 0x30, | ||
52 | FF_WU_SRC = 0x31, | ||
53 | FF_WU_ACK = 0x32, | ||
54 | FF_WU_THS_L = 0x34, | ||
55 | FF_WU_THS_H = 0x35, | ||
56 | FF_WU_DURATION = 0x36, | ||
57 | DD_CFG = 0x38, | ||
58 | DD_SRC = 0x39, | ||
59 | DD_ACK = 0x3A, | ||
60 | DD_THSI_L = 0x3C, | ||
61 | DD_THSI_H = 0x3D, | ||
62 | DD_THSE_L = 0x3E, | ||
63 | DD_THSE_H = 0x3F, | ||
64 | }; | ||
65 | |||
66 | enum lis3lv02d_ctrl1 { | ||
67 | CTRL1_Xen = 0x01, | ||
68 | CTRL1_Yen = 0x02, | ||
69 | CTRL1_Zen = 0x04, | ||
70 | CTRL1_ST = 0x08, | ||
71 | CTRL1_DF0 = 0x10, | ||
72 | CTRL1_DF1 = 0x20, | ||
73 | CTRL1_PD0 = 0x40, | ||
74 | CTRL1_PD1 = 0x80, | ||
75 | }; | ||
76 | enum lis3lv02d_ctrl2 { | ||
77 | CTRL2_DAS = 0x01, | ||
78 | CTRL2_SIM = 0x02, | ||
79 | CTRL2_DRDY = 0x04, | ||
80 | CTRL2_IEN = 0x08, | ||
81 | CTRL2_BOOT = 0x10, | ||
82 | CTRL2_BLE = 0x20, | ||
83 | CTRL2_BDU = 0x40, /* Block Data Update */ | ||
84 | CTRL2_FS = 0x80, /* Full Scale selection */ | ||
85 | }; | ||
86 | |||
87 | |||
88 | enum lis3lv02d_ctrl3 { | ||
89 | CTRL3_CFS0 = 0x01, | ||
90 | CTRL3_CFS1 = 0x02, | ||
91 | CTRL3_FDS = 0x10, | ||
92 | CTRL3_HPFF = 0x20, | ||
93 | CTRL3_HPDD = 0x40, | ||
94 | CTRL3_ECK = 0x80, | ||
95 | }; | ||
96 | |||
97 | enum lis3lv02d_status_reg { | ||
98 | STATUS_XDA = 0x01, | ||
99 | STATUS_YDA = 0x02, | ||
100 | STATUS_ZDA = 0x04, | ||
101 | STATUS_XYZDA = 0x08, | ||
102 | STATUS_XOR = 0x10, | ||
103 | STATUS_YOR = 0x20, | ||
104 | STATUS_ZOR = 0x40, | ||
105 | STATUS_XYZOR = 0x80, | ||
106 | }; | ||
107 | |||
108 | enum lis3lv02d_ff_wu_cfg { | ||
109 | FF_WU_CFG_XLIE = 0x01, | ||
110 | FF_WU_CFG_XHIE = 0x02, | ||
111 | FF_WU_CFG_YLIE = 0x04, | ||
112 | FF_WU_CFG_YHIE = 0x08, | ||
113 | FF_WU_CFG_ZLIE = 0x10, | ||
114 | FF_WU_CFG_ZHIE = 0x20, | ||
115 | FF_WU_CFG_LIR = 0x40, | ||
116 | FF_WU_CFG_AOI = 0x80, | ||
117 | }; | ||
118 | |||
119 | enum lis3lv02d_ff_wu_src { | ||
120 | FF_WU_SRC_XL = 0x01, | ||
121 | FF_WU_SRC_XH = 0x02, | ||
122 | FF_WU_SRC_YL = 0x04, | ||
123 | FF_WU_SRC_YH = 0x08, | ||
124 | FF_WU_SRC_ZL = 0x10, | ||
125 | FF_WU_SRC_ZH = 0x20, | ||
126 | FF_WU_SRC_IA = 0x40, | ||
127 | }; | ||
128 | |||
129 | enum lis3lv02d_dd_cfg { | ||
130 | DD_CFG_XLIE = 0x01, | ||
131 | DD_CFG_XHIE = 0x02, | ||
132 | DD_CFG_YLIE = 0x04, | ||
133 | DD_CFG_YHIE = 0x08, | ||
134 | DD_CFG_ZLIE = 0x10, | ||
135 | DD_CFG_ZHIE = 0x20, | ||
136 | DD_CFG_LIR = 0x40, | ||
137 | DD_CFG_IEND = 0x80, | ||
138 | }; | ||
139 | |||
140 | enum lis3lv02d_dd_src { | ||
141 | DD_SRC_XL = 0x01, | ||
142 | DD_SRC_XH = 0x02, | ||
143 | DD_SRC_YL = 0x04, | ||
144 | DD_SRC_YH = 0x08, | ||
145 | DD_SRC_ZL = 0x10, | ||
146 | DD_SRC_ZH = 0x20, | ||
147 | DD_SRC_IA = 0x40, | ||
148 | }; | ||
149 | |||
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index 3ff0285396fa..cfc1ee90f5a3 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c | |||
@@ -39,7 +39,8 @@ | |||
39 | static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; | 39 | static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; |
40 | 40 | ||
41 | /* Insmod parameters */ | 41 | /* Insmod parameters */ |
42 | I2C_CLIENT_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102); | 42 | I2C_CLIENT_INSMOD_7(lm85b, lm85c, adm1027, adt7463, adt7468, emc6d100, |
43 | emc6d102); | ||
43 | 44 | ||
44 | /* The LM85 registers */ | 45 | /* The LM85 registers */ |
45 | 46 | ||
@@ -59,6 +60,12 @@ I2C_CLIENT_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102); | |||
59 | 60 | ||
60 | #define LM85_REG_COMPANY 0x3e | 61 | #define LM85_REG_COMPANY 0x3e |
61 | #define LM85_REG_VERSTEP 0x3f | 62 | #define LM85_REG_VERSTEP 0x3f |
63 | |||
64 | #define ADT7468_REG_CFG5 0x7c | ||
65 | #define ADT7468_OFF64 0x01 | ||
66 | #define IS_ADT7468_OFF64(data) \ | ||
67 | ((data)->type == adt7468 && !((data)->cfg5 & ADT7468_OFF64)) | ||
68 | |||
62 | /* These are the recognized values for the above regs */ | 69 | /* These are the recognized values for the above regs */ |
63 | #define LM85_COMPANY_NATIONAL 0x01 | 70 | #define LM85_COMPANY_NATIONAL 0x01 |
64 | #define LM85_COMPANY_ANALOG_DEV 0x41 | 71 | #define LM85_COMPANY_ANALOG_DEV 0x41 |
@@ -70,6 +77,8 @@ I2C_CLIENT_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102); | |||
70 | #define LM85_VERSTEP_ADM1027 0x60 | 77 | #define LM85_VERSTEP_ADM1027 0x60 |
71 | #define LM85_VERSTEP_ADT7463 0x62 | 78 | #define LM85_VERSTEP_ADT7463 0x62 |
72 | #define LM85_VERSTEP_ADT7463C 0x6A | 79 | #define LM85_VERSTEP_ADT7463C 0x6A |
80 | #define LM85_VERSTEP_ADT7468_1 0x71 | ||
81 | #define LM85_VERSTEP_ADT7468_2 0x72 | ||
73 | #define LM85_VERSTEP_EMC6D100_A0 0x60 | 82 | #define LM85_VERSTEP_EMC6D100_A0 0x60 |
74 | #define LM85_VERSTEP_EMC6D100_A1 0x61 | 83 | #define LM85_VERSTEP_EMC6D100_A1 0x61 |
75 | #define LM85_VERSTEP_EMC6D102 0x65 | 84 | #define LM85_VERSTEP_EMC6D102 0x65 |
@@ -306,6 +315,7 @@ struct lm85_data { | |||
306 | u8 vid; /* Register value */ | 315 | u8 vid; /* Register value */ |
307 | u8 vrm; /* VRM version */ | 316 | u8 vrm; /* VRM version */ |
308 | u32 alarms; /* Register encoding, combined */ | 317 | u32 alarms; /* Register encoding, combined */ |
318 | u8 cfg5; /* Config Register 5 on ADT7468 */ | ||
309 | struct lm85_autofan autofan[3]; | 319 | struct lm85_autofan autofan[3]; |
310 | struct lm85_zone zone[3]; | 320 | struct lm85_zone zone[3]; |
311 | }; | 321 | }; |
@@ -685,6 +695,9 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, | |||
685 | struct lm85_data *data = i2c_get_clientdata(client); | 695 | struct lm85_data *data = i2c_get_clientdata(client); |
686 | long val = simple_strtol(buf, NULL, 10); | 696 | long val = simple_strtol(buf, NULL, 10); |
687 | 697 | ||
698 | if (IS_ADT7468_OFF64(data)) | ||
699 | val += 64; | ||
700 | |||
688 | mutex_lock(&data->update_lock); | 701 | mutex_lock(&data->update_lock); |
689 | data->temp_min[nr] = TEMP_TO_REG(val); | 702 | data->temp_min[nr] = TEMP_TO_REG(val); |
690 | lm85_write_value(client, LM85_REG_TEMP_MIN(nr), data->temp_min[nr]); | 703 | lm85_write_value(client, LM85_REG_TEMP_MIN(nr), data->temp_min[nr]); |
@@ -708,6 +721,9 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | |||
708 | struct lm85_data *data = i2c_get_clientdata(client); | 721 | struct lm85_data *data = i2c_get_clientdata(client); |
709 | long val = simple_strtol(buf, NULL, 10); | 722 | long val = simple_strtol(buf, NULL, 10); |
710 | 723 | ||
724 | if (IS_ADT7468_OFF64(data)) | ||
725 | val += 64; | ||
726 | |||
711 | mutex_lock(&data->update_lock); | 727 | mutex_lock(&data->update_lock); |
712 | data->temp_max[nr] = TEMP_TO_REG(val); | 728 | data->temp_max[nr] = TEMP_TO_REG(val); |
713 | lm85_write_value(client, LM85_REG_TEMP_MAX(nr), data->temp_max[nr]); | 729 | lm85_write_value(client, LM85_REG_TEMP_MAX(nr), data->temp_max[nr]); |
@@ -1163,6 +1179,10 @@ static int lm85_detect(struct i2c_client *client, int kind, | |||
1163 | case LM85_VERSTEP_ADT7463C: | 1179 | case LM85_VERSTEP_ADT7463C: |
1164 | kind = adt7463; | 1180 | kind = adt7463; |
1165 | break; | 1181 | break; |
1182 | case LM85_VERSTEP_ADT7468_1: | ||
1183 | case LM85_VERSTEP_ADT7468_2: | ||
1184 | kind = adt7468; | ||
1185 | break; | ||
1166 | } | 1186 | } |
1167 | } else if (company == LM85_COMPANY_SMSC) { | 1187 | } else if (company == LM85_COMPANY_SMSC) { |
1168 | switch (verstep) { | 1188 | switch (verstep) { |
@@ -1195,6 +1215,9 @@ static int lm85_detect(struct i2c_client *client, int kind, | |||
1195 | case adt7463: | 1215 | case adt7463: |
1196 | type_name = "adt7463"; | 1216 | type_name = "adt7463"; |
1197 | break; | 1217 | break; |
1218 | case adt7468: | ||
1219 | type_name = "adt7468"; | ||
1220 | break; | ||
1198 | case emc6d100: | 1221 | case emc6d100: |
1199 | type_name = "emc6d100"; | 1222 | type_name = "emc6d100"; |
1200 | break; | 1223 | break; |
@@ -1246,10 +1269,11 @@ static int lm85_probe(struct i2c_client *client, | |||
1246 | if (err) | 1269 | if (err) |
1247 | goto err_kfree; | 1270 | goto err_kfree; |
1248 | 1271 | ||
1249 | /* The ADT7463 has an optional VRM 10 mode where pin 21 is used | 1272 | /* The ADT7463/68 have an optional VRM 10 mode where pin 21 is used |
1250 | as a sixth digital VID input rather than an analog input. */ | 1273 | as a sixth digital VID input rather than an analog input. */ |
1251 | data->vid = lm85_read_value(client, LM85_REG_VID); | 1274 | data->vid = lm85_read_value(client, LM85_REG_VID); |
1252 | if (!(data->type == adt7463 && (data->vid & 0x80))) | 1275 | if (!((data->type == adt7463 || data->type == adt7468) && |
1276 | (data->vid & 0x80))) | ||
1253 | if ((err = sysfs_create_group(&client->dev.kobj, | 1277 | if ((err = sysfs_create_group(&client->dev.kobj, |
1254 | &lm85_group_in4))) | 1278 | &lm85_group_in4))) |
1255 | goto err_remove_files; | 1279 | goto err_remove_files; |
@@ -1357,7 +1381,8 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1357 | * There are 2 additional resolution bits per channel and we | 1381 | * There are 2 additional resolution bits per channel and we |
1358 | * have room for 4, so we shift them to the left. | 1382 | * have room for 4, so we shift them to the left. |
1359 | */ | 1383 | */ |
1360 | if (data->type == adm1027 || data->type == adt7463) { | 1384 | if (data->type == adm1027 || data->type == adt7463 || |
1385 | data->type == adt7468) { | ||
1361 | int ext1 = lm85_read_value(client, | 1386 | int ext1 = lm85_read_value(client, |
1362 | ADM1027_REG_EXTEND_ADC1); | 1387 | ADM1027_REG_EXTEND_ADC1); |
1363 | int ext2 = lm85_read_value(client, | 1388 | int ext2 = lm85_read_value(client, |
@@ -1382,16 +1407,23 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1382 | lm85_read_value(client, LM85_REG_FAN(i)); | 1407 | lm85_read_value(client, LM85_REG_FAN(i)); |
1383 | } | 1408 | } |
1384 | 1409 | ||
1385 | if (!(data->type == adt7463 && (data->vid & 0x80))) { | 1410 | if (!((data->type == adt7463 || data->type == adt7468) && |
1411 | (data->vid & 0x80))) { | ||
1386 | data->in[4] = lm85_read_value(client, | 1412 | data->in[4] = lm85_read_value(client, |
1387 | LM85_REG_IN(4)); | 1413 | LM85_REG_IN(4)); |
1388 | } | 1414 | } |
1389 | 1415 | ||
1416 | if (data->type == adt7468) | ||
1417 | data->cfg5 = lm85_read_value(client, ADT7468_REG_CFG5); | ||
1418 | |||
1390 | for (i = 0; i <= 2; ++i) { | 1419 | for (i = 0; i <= 2; ++i) { |
1391 | data->temp[i] = | 1420 | data->temp[i] = |
1392 | lm85_read_value(client, LM85_REG_TEMP(i)); | 1421 | lm85_read_value(client, LM85_REG_TEMP(i)); |
1393 | data->pwm[i] = | 1422 | data->pwm[i] = |
1394 | lm85_read_value(client, LM85_REG_PWM(i)); | 1423 | lm85_read_value(client, LM85_REG_PWM(i)); |
1424 | |||
1425 | if (IS_ADT7468_OFF64(data)) | ||
1426 | data->temp[i] -= 64; | ||
1395 | } | 1427 | } |
1396 | 1428 | ||
1397 | data->alarms = lm85_read_value(client, LM85_REG_ALARM1); | 1429 | data->alarms = lm85_read_value(client, LM85_REG_ALARM1); |
@@ -1446,7 +1478,8 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1446 | lm85_read_value(client, LM85_REG_FAN_MIN(i)); | 1478 | lm85_read_value(client, LM85_REG_FAN_MIN(i)); |
1447 | } | 1479 | } |
1448 | 1480 | ||
1449 | if (!(data->type == adt7463 && (data->vid & 0x80))) { | 1481 | if (!((data->type == adt7463 || data->type == adt7468) && |
1482 | (data->vid & 0x80))) { | ||
1450 | data->in_min[4] = lm85_read_value(client, | 1483 | data->in_min[4] = lm85_read_value(client, |
1451 | LM85_REG_IN_MIN(4)); | 1484 | LM85_REG_IN_MIN(4)); |
1452 | data->in_max[4] = lm85_read_value(client, | 1485 | data->in_max[4] = lm85_read_value(client, |
@@ -1481,6 +1514,13 @@ static struct lm85_data *lm85_update_device(struct device *dev) | |||
1481 | lm85_read_value(client, LM85_REG_AFAN_LIMIT(i)); | 1514 | lm85_read_value(client, LM85_REG_AFAN_LIMIT(i)); |
1482 | data->zone[i].critical = | 1515 | data->zone[i].critical = |
1483 | lm85_read_value(client, LM85_REG_AFAN_CRITICAL(i)); | 1516 | lm85_read_value(client, LM85_REG_AFAN_CRITICAL(i)); |
1517 | |||
1518 | if (IS_ADT7468_OFF64(data)) { | ||
1519 | data->temp_min[i] -= 64; | ||
1520 | data->temp_max[i] -= 64; | ||
1521 | data->zone[i].limit -= 64; | ||
1522 | data->zone[i].critical -= 64; | ||
1523 | } | ||
1484 | } | 1524 | } |
1485 | 1525 | ||
1486 | i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1); | 1526 | i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1); |
diff --git a/drivers/idle/Kconfig b/drivers/idle/Kconfig index 108264de0ac9..f15e90a453d1 100644 --- a/drivers/idle/Kconfig +++ b/drivers/idle/Kconfig | |||
@@ -1,5 +1,6 @@ | |||
1 | 1 | ||
2 | menu "Memory power savings" | 2 | menu "Memory power savings" |
3 | depends on X86_64 | ||
3 | 4 | ||
4 | config I7300_IDLE_IOAT_CHANNEL | 5 | config I7300_IDLE_IOAT_CHANNEL |
5 | bool | 6 | bool |
@@ -7,7 +8,7 @@ config I7300_IDLE_IOAT_CHANNEL | |||
7 | config I7300_IDLE | 8 | config I7300_IDLE |
8 | tristate "Intel chipset idle memory power saving driver" | 9 | tristate "Intel chipset idle memory power saving driver" |
9 | select I7300_IDLE_IOAT_CHANNEL | 10 | select I7300_IDLE_IOAT_CHANNEL |
10 | depends on X86_64 && EXPERIMENTAL | 11 | depends on EXPERIMENTAL |
11 | help | 12 | help |
12 | Enable memory power savings when idle with certain Intel server | 13 | Enable memory power savings when idle with certain Intel server |
13 | chipsets. The chipset must have I/O AT support, such as the | 14 | chipsets. The chipset must have I/O AT support, such as the |
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c index 965cfdb84ebc..c19f23267157 100644 --- a/drivers/ieee1394/dv1394.c +++ b/drivers/ieee1394/dv1394.c | |||
@@ -1270,8 +1270,14 @@ static int dv1394_mmap(struct file *file, struct vm_area_struct *vma) | |||
1270 | struct video_card *video = file_to_video_card(file); | 1270 | struct video_card *video = file_to_video_card(file); |
1271 | int retval = -EINVAL; | 1271 | int retval = -EINVAL; |
1272 | 1272 | ||
1273 | /* serialize mmap */ | 1273 | /* |
1274 | mutex_lock(&video->mtx); | 1274 | * We cannot use the blocking variant mutex_lock here because .mmap |
1275 | * is called with mmap_sem held, while .ioctl, .read, .write acquire | ||
1276 | * video->mtx and subsequently call copy_to/from_user which will | ||
1277 | * grab mmap_sem in case of a page fault. | ||
1278 | */ | ||
1279 | if (!mutex_trylock(&video->mtx)) | ||
1280 | return -EAGAIN; | ||
1275 | 1281 | ||
1276 | if ( ! video_card_initialized(video) ) { | 1282 | if ( ! video_card_initialized(video) ) { |
1277 | retval = do_dv1394_init_default(video); | 1283 | retval = do_dv1394_init_default(video); |
diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c index 8dd09d850419..237d0c9d69c6 100644 --- a/drivers/ieee1394/hosts.c +++ b/drivers/ieee1394/hosts.c | |||
@@ -155,11 +155,11 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, | |||
155 | memcpy(&h->device, &nodemgr_dev_template_host, sizeof(h->device)); | 155 | memcpy(&h->device, &nodemgr_dev_template_host, sizeof(h->device)); |
156 | h->device.parent = dev; | 156 | h->device.parent = dev; |
157 | set_dev_node(&h->device, dev_to_node(dev)); | 157 | set_dev_node(&h->device, dev_to_node(dev)); |
158 | snprintf(h->device.bus_id, BUS_ID_SIZE, "fw-host%d", h->id); | 158 | dev_set_name(&h->device, "fw-host%d", h->id); |
159 | 159 | ||
160 | h->host_dev.parent = &h->device; | 160 | h->host_dev.parent = &h->device; |
161 | h->host_dev.class = &hpsb_host_class; | 161 | h->host_dev.class = &hpsb_host_class; |
162 | snprintf(h->host_dev.bus_id, BUS_ID_SIZE, "fw-host%d", h->id); | 162 | dev_set_name(&h->host_dev, "fw-host%d", h->id); |
163 | 163 | ||
164 | if (device_register(&h->device)) | 164 | if (device_register(&h->device)) |
165 | goto fail; | 165 | goto fail; |
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 2376b729e876..9e39f73282ee 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c | |||
@@ -826,13 +826,11 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, | |||
826 | memcpy(&ne->device, &nodemgr_dev_template_ne, | 826 | memcpy(&ne->device, &nodemgr_dev_template_ne, |
827 | sizeof(ne->device)); | 827 | sizeof(ne->device)); |
828 | ne->device.parent = &host->device; | 828 | ne->device.parent = &host->device; |
829 | snprintf(ne->device.bus_id, BUS_ID_SIZE, "%016Lx", | 829 | dev_set_name(&ne->device, "%016Lx", (unsigned long long)(ne->guid)); |
830 | (unsigned long long)(ne->guid)); | ||
831 | 830 | ||
832 | ne->node_dev.parent = &ne->device; | 831 | ne->node_dev.parent = &ne->device; |
833 | ne->node_dev.class = &nodemgr_ne_class; | 832 | ne->node_dev.class = &nodemgr_ne_class; |
834 | snprintf(ne->node_dev.bus_id, BUS_ID_SIZE, "%016Lx", | 833 | dev_set_name(&ne->node_dev, "%016Lx", (unsigned long long)(ne->guid)); |
835 | (unsigned long long)(ne->guid)); | ||
836 | 834 | ||
837 | if (device_register(&ne->device)) | 835 | if (device_register(&ne->device)) |
838 | goto fail_devreg; | 836 | goto fail_devreg; |
@@ -932,13 +930,11 @@ static void nodemgr_register_device(struct node_entry *ne, | |||
932 | 930 | ||
933 | ud->device.parent = parent; | 931 | ud->device.parent = parent; |
934 | 932 | ||
935 | snprintf(ud->device.bus_id, BUS_ID_SIZE, "%s-%u", | 933 | dev_set_name(&ud->device, "%s-%u", dev_name(&ne->device), ud->id); |
936 | ne->device.bus_id, ud->id); | ||
937 | 934 | ||
938 | ud->unit_dev.parent = &ud->device; | 935 | ud->unit_dev.parent = &ud->device; |
939 | ud->unit_dev.class = &nodemgr_ud_class; | 936 | ud->unit_dev.class = &nodemgr_ud_class; |
940 | snprintf(ud->unit_dev.bus_id, BUS_ID_SIZE, "%s-%u", | 937 | dev_set_name(&ud->unit_dev, "%s-%u", dev_name(&ne->device), ud->id); |
941 | ne->device.bus_id, ud->id); | ||
942 | 938 | ||
943 | if (device_register(&ud->device)) | 939 | if (device_register(&ud->device)) |
944 | goto fail_devreg; | 940 | goto fail_devreg; |
@@ -953,7 +949,7 @@ static void nodemgr_register_device(struct node_entry *ne, | |||
953 | fail_classdevreg: | 949 | fail_classdevreg: |
954 | device_unregister(&ud->device); | 950 | device_unregister(&ud->device); |
955 | fail_devreg: | 951 | fail_devreg: |
956 | HPSB_ERR("Failed to create unit %s", ud->device.bus_id); | 952 | HPSB_ERR("Failed to create unit %s", dev_name(&ud->device)); |
957 | } | 953 | } |
958 | 954 | ||
959 | 955 | ||
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index 9f19ac492106..bf7e761c12b1 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c | |||
@@ -2268,7 +2268,8 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer, | |||
2268 | return -EFAULT; | 2268 | return -EFAULT; |
2269 | } | 2269 | } |
2270 | 2270 | ||
2271 | mutex_lock(&fi->state_mutex); | 2271 | if (!mutex_trylock(&fi->state_mutex)) |
2272 | return -EAGAIN; | ||
2272 | 2273 | ||
2273 | switch (fi->state) { | 2274 | switch (fi->state) { |
2274 | case opened: | 2275 | case opened: |
@@ -2548,7 +2549,8 @@ static int raw1394_mmap(struct file *file, struct vm_area_struct *vma) | |||
2548 | struct file_info *fi = file->private_data; | 2549 | struct file_info *fi = file->private_data; |
2549 | int ret; | 2550 | int ret; |
2550 | 2551 | ||
2551 | mutex_lock(&fi->state_mutex); | 2552 | if (!mutex_trylock(&fi->state_mutex)) |
2553 | return -EAGAIN; | ||
2552 | 2554 | ||
2553 | if (fi->iso_state == RAW1394_ISO_INACTIVE) | 2555 | if (fi->iso_state == RAW1394_ISO_INACTIVE) |
2554 | ret = -EINVAL; | 2556 | ret = -EINVAL; |
@@ -2669,7 +2671,8 @@ static long raw1394_ioctl(struct file *file, unsigned int cmd, | |||
2669 | break; | 2671 | break; |
2670 | } | 2672 | } |
2671 | 2673 | ||
2672 | mutex_lock(&fi->state_mutex); | 2674 | if (!mutex_trylock(&fi->state_mutex)) |
2675 | return -EAGAIN; | ||
2673 | 2676 | ||
2674 | switch (fi->iso_state) { | 2677 | switch (fi->iso_state) { |
2675 | case RAW1394_ISO_INACTIVE: | 2678 | case RAW1394_ISO_INACTIVE: |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c index ecff98043589..160ef482712d 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c | |||
@@ -1102,9 +1102,7 @@ static u64 fw_vers_string_to_u64(struct iwch_dev *iwch_dev) | |||
1102 | char *cp, *next; | 1102 | char *cp, *next; |
1103 | unsigned fw_maj, fw_min, fw_mic; | 1103 | unsigned fw_maj, fw_min, fw_mic; |
1104 | 1104 | ||
1105 | rtnl_lock(); | ||
1106 | lldev->ethtool_ops->get_drvinfo(lldev, &info); | 1105 | lldev->ethtool_ops->get_drvinfo(lldev, &info); |
1107 | rtnl_unlock(); | ||
1108 | 1106 | ||
1109 | next = info.fw_version + 1; | 1107 | next = info.fw_version + 1; |
1110 | cp = strsep(&next, "."); | 1108 | cp = strsep(&next, "."); |
@@ -1192,9 +1190,7 @@ static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr, ch | |||
1192 | struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev; | 1190 | struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev; |
1193 | 1191 | ||
1194 | PDBG("%s dev 0x%p\n", __func__, dev); | 1192 | PDBG("%s dev 0x%p\n", __func__, dev); |
1195 | rtnl_lock(); | ||
1196 | lldev->ethtool_ops->get_drvinfo(lldev, &info); | 1193 | lldev->ethtool_ops->get_drvinfo(lldev, &info); |
1197 | rtnl_unlock(); | ||
1198 | return sprintf(buf, "%s\n", info.fw_version); | 1194 | return sprintf(buf, "%s\n", info.fw_version); |
1199 | } | 1195 | } |
1200 | 1196 | ||
@@ -1207,9 +1203,7 @@ static ssize_t show_hca(struct device *dev, struct device_attribute *attr, | |||
1207 | struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev; | 1203 | struct net_device *lldev = iwch_dev->rdev.t3cdev_p->lldev; |
1208 | 1204 | ||
1209 | PDBG("%s dev 0x%p\n", __func__, dev); | 1205 | PDBG("%s dev 0x%p\n", __func__, dev); |
1210 | rtnl_lock(); | ||
1211 | lldev->ethtool_ops->get_drvinfo(lldev, &info); | 1206 | lldev->ethtool_ops->get_drvinfo(lldev, &info); |
1212 | rtnl_unlock(); | ||
1213 | return sprintf(buf, "%s\n", info.driver); | 1207 | return sprintf(buf, "%s\n", info.driver); |
1214 | } | 1208 | } |
1215 | 1209 | ||
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c index 3e4585c2318a..19661b2f0406 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_qp.c +++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c | |||
@@ -745,7 +745,6 @@ int iwch_post_zb_read(struct iwch_qp *qhp) | |||
745 | wqe->read.rdmaop = T3_READ_REQ; | 745 | wqe->read.rdmaop = T3_READ_REQ; |
746 | wqe->read.reserved[0] = 0; | 746 | wqe->read.reserved[0] = 0; |
747 | wqe->read.reserved[1] = 0; | 747 | wqe->read.reserved[1] = 0; |
748 | wqe->read.reserved[2] = 0; | ||
749 | wqe->read.rem_stag = cpu_to_be32(1); | 748 | wqe->read.rem_stag = cpu_to_be32(1); |
750 | wqe->read.rem_to = cpu_to_be64(1); | 749 | wqe->read.rem_to = cpu_to_be64(1); |
751 | wqe->read.local_stag = cpu_to_be32(1); | 750 | wqe->read.local_stag = cpu_to_be32(1); |
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index cb55be04442c..757035ea246f 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/drivers/infiniband/hw/ehca/ehca_irq.c | |||
@@ -359,36 +359,48 @@ static void notify_port_conf_change(struct ehca_shca *shca, int port_num) | |||
359 | *old_attr = new_attr; | 359 | *old_attr = new_attr; |
360 | } | 360 | } |
361 | 361 | ||
362 | /* replay modify_qp for sqps -- return 0 if all is well, 1 if AQP1 destroyed */ | ||
363 | static int replay_modify_qp(struct ehca_sport *sport) | ||
364 | { | ||
365 | int aqp1_destroyed; | ||
366 | unsigned long flags; | ||
367 | |||
368 | spin_lock_irqsave(&sport->mod_sqp_lock, flags); | ||
369 | |||
370 | aqp1_destroyed = !sport->ibqp_sqp[IB_QPT_GSI]; | ||
371 | |||
372 | if (sport->ibqp_sqp[IB_QPT_SMI]) | ||
373 | ehca_recover_sqp(sport->ibqp_sqp[IB_QPT_SMI]); | ||
374 | if (!aqp1_destroyed) | ||
375 | ehca_recover_sqp(sport->ibqp_sqp[IB_QPT_GSI]); | ||
376 | |||
377 | spin_unlock_irqrestore(&sport->mod_sqp_lock, flags); | ||
378 | |||
379 | return aqp1_destroyed; | ||
380 | } | ||
381 | |||
362 | static void parse_ec(struct ehca_shca *shca, u64 eqe) | 382 | static void parse_ec(struct ehca_shca *shca, u64 eqe) |
363 | { | 383 | { |
364 | u8 ec = EHCA_BMASK_GET(NEQE_EVENT_CODE, eqe); | 384 | u8 ec = EHCA_BMASK_GET(NEQE_EVENT_CODE, eqe); |
365 | u8 port = EHCA_BMASK_GET(NEQE_PORT_NUMBER, eqe); | 385 | u8 port = EHCA_BMASK_GET(NEQE_PORT_NUMBER, eqe); |
366 | u8 spec_event; | 386 | u8 spec_event; |
367 | struct ehca_sport *sport = &shca->sport[port - 1]; | 387 | struct ehca_sport *sport = &shca->sport[port - 1]; |
368 | unsigned long flags; | ||
369 | 388 | ||
370 | switch (ec) { | 389 | switch (ec) { |
371 | case 0x30: /* port availability change */ | 390 | case 0x30: /* port availability change */ |
372 | if (EHCA_BMASK_GET(NEQE_PORT_AVAILABILITY, eqe)) { | 391 | if (EHCA_BMASK_GET(NEQE_PORT_AVAILABILITY, eqe)) { |
373 | int suppress_event; | 392 | /* only replay modify_qp calls in autodetect mode; |
374 | /* replay modify_qp for sqps */ | 393 | * if AQP1 was destroyed, the port is already down |
375 | spin_lock_irqsave(&sport->mod_sqp_lock, flags); | 394 | * again and we can drop the event. |
376 | suppress_event = !sport->ibqp_sqp[IB_QPT_GSI]; | 395 | */ |
377 | if (sport->ibqp_sqp[IB_QPT_SMI]) | 396 | if (ehca_nr_ports < 0) |
378 | ehca_recover_sqp(sport->ibqp_sqp[IB_QPT_SMI]); | 397 | if (replay_modify_qp(sport)) |
379 | if (!suppress_event) | 398 | break; |
380 | ehca_recover_sqp(sport->ibqp_sqp[IB_QPT_GSI]); | ||
381 | spin_unlock_irqrestore(&sport->mod_sqp_lock, flags); | ||
382 | |||
383 | /* AQP1 was destroyed, ignore this event */ | ||
384 | if (suppress_event) | ||
385 | break; | ||
386 | 399 | ||
387 | sport->port_state = IB_PORT_ACTIVE; | 400 | sport->port_state = IB_PORT_ACTIVE; |
388 | dispatch_port_event(shca, port, IB_EVENT_PORT_ACTIVE, | 401 | dispatch_port_event(shca, port, IB_EVENT_PORT_ACTIVE, |
389 | "is active"); | 402 | "is active"); |
390 | ehca_query_sma_attr(shca, port, | 403 | ehca_query_sma_attr(shca, port, &sport->saved_attr); |
391 | &sport->saved_attr); | ||
392 | } else { | 404 | } else { |
393 | sport->port_state = IB_PORT_DOWN; | 405 | sport->port_state = IB_PORT_DOWN; |
394 | dispatch_port_event(shca, port, IB_EVENT_PORT_ERR, | 406 | dispatch_port_event(shca, port, IB_EVENT_PORT_ERR, |
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index 4d54b9f64567..9e05ee2db39b 100644 --- a/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/drivers/infiniband/hw/ehca/ehca_qp.c | |||
@@ -860,6 +860,11 @@ static struct ehca_qp *internal_create_qp( | |||
860 | if (qp_type == IB_QPT_GSI) { | 860 | if (qp_type == IB_QPT_GSI) { |
861 | h_ret = ehca_define_sqp(shca, my_qp, init_attr); | 861 | h_ret = ehca_define_sqp(shca, my_qp, init_attr); |
862 | if (h_ret != H_SUCCESS) { | 862 | if (h_ret != H_SUCCESS) { |
863 | kfree(my_qp->mod_qp_parm); | ||
864 | my_qp->mod_qp_parm = NULL; | ||
865 | /* the QP pointer is no longer valid */ | ||
866 | shca->sport[init_attr->port_num - 1].ibqp_sqp[qp_type] = | ||
867 | NULL; | ||
863 | ret = ehca2ib_return_code(h_ret); | 868 | ret = ehca2ib_return_code(h_ret); |
864 | goto create_qp_exit6; | 869 | goto create_qp_exit6; |
865 | } | 870 | } |
diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c b/drivers/infiniband/hw/ipath/ipath_ruc.c index fc0f6d9e6030..2296832f94da 100644 --- a/drivers/infiniband/hw/ipath/ipath_ruc.c +++ b/drivers/infiniband/hw/ipath/ipath_ruc.c | |||
@@ -156,7 +156,7 @@ bail: | |||
156 | /** | 156 | /** |
157 | * ipath_get_rwqe - copy the next RWQE into the QP's RWQE | 157 | * ipath_get_rwqe - copy the next RWQE into the QP's RWQE |
158 | * @qp: the QP | 158 | * @qp: the QP |
159 | * @wr_id_only: update wr_id only, not SGEs | 159 | * @wr_id_only: update qp->r_wr_id only, not qp->r_sge |
160 | * | 160 | * |
161 | * Return 0 if no RWQE is available, otherwise return 1. | 161 | * Return 0 if no RWQE is available, otherwise return 1. |
162 | * | 162 | * |
@@ -173,8 +173,6 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only) | |||
173 | u32 tail; | 173 | u32 tail; |
174 | int ret; | 174 | int ret; |
175 | 175 | ||
176 | qp->r_sge.sg_list = qp->r_sg_list; | ||
177 | |||
178 | if (qp->ibqp.srq) { | 176 | if (qp->ibqp.srq) { |
179 | srq = to_isrq(qp->ibqp.srq); | 177 | srq = to_isrq(qp->ibqp.srq); |
180 | handler = srq->ibsrq.event_handler; | 178 | handler = srq->ibsrq.event_handler; |
@@ -206,8 +204,10 @@ int ipath_get_rwqe(struct ipath_qp *qp, int wr_id_only) | |||
206 | wqe = get_rwqe_ptr(rq, tail); | 204 | wqe = get_rwqe_ptr(rq, tail); |
207 | if (++tail >= rq->size) | 205 | if (++tail >= rq->size) |
208 | tail = 0; | 206 | tail = 0; |
209 | } while (!wr_id_only && !ipath_init_sge(qp, wqe, &qp->r_len, | 207 | if (wr_id_only) |
210 | &qp->r_sge)); | 208 | break; |
209 | qp->r_sge.sg_list = qp->r_sg_list; | ||
210 | } while (!ipath_init_sge(qp, wqe, &qp->r_len, &qp->r_sge)); | ||
211 | qp->r_wr_id = wqe->wr_id; | 211 | qp->r_wr_id = wqe->wr_id; |
212 | wq->tail = tail; | 212 | wq->tail = tail; |
213 | 213 | ||
diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c index 87f5c5a87b98..8e4d26d56a95 100644 --- a/drivers/infiniband/hw/mlx4/mr.c +++ b/drivers/infiniband/hw/mlx4/mr.c | |||
@@ -205,6 +205,7 @@ struct ib_mr *mlx4_ib_alloc_fast_reg_mr(struct ib_pd *pd, | |||
205 | goto err_mr; | 205 | goto err_mr; |
206 | 206 | ||
207 | mr->ibmr.rkey = mr->ibmr.lkey = mr->mmr.key; | 207 | mr->ibmr.rkey = mr->ibmr.lkey = mr->mmr.key; |
208 | mr->umem = NULL; | ||
208 | 209 | ||
209 | return &mr->ibmr; | 210 | return &mr->ibmr; |
210 | 211 | ||
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index a2b04d62b1a4..aa1dc41f04c8 100644 --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c | |||
@@ -95,6 +95,10 @@ unsigned int wqm_quanta = 0x10000; | |||
95 | module_param(wqm_quanta, int, 0644); | 95 | module_param(wqm_quanta, int, 0644); |
96 | MODULE_PARM_DESC(wqm_quanta, "WQM quanta"); | 96 | MODULE_PARM_DESC(wqm_quanta, "WQM quanta"); |
97 | 97 | ||
98 | static unsigned int limit_maxrdreqsz; | ||
99 | module_param(limit_maxrdreqsz, bool, 0644); | ||
100 | MODULE_PARM_DESC(limit_maxrdreqsz, "Limit max read request size to 256 Bytes"); | ||
101 | |||
98 | LIST_HEAD(nes_adapter_list); | 102 | LIST_HEAD(nes_adapter_list); |
99 | static LIST_HEAD(nes_dev_list); | 103 | static LIST_HEAD(nes_dev_list); |
100 | 104 | ||
@@ -588,6 +592,18 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i | |||
588 | nesdev->nesadapter->port_count; | 592 | nesdev->nesadapter->port_count; |
589 | } | 593 | } |
590 | 594 | ||
595 | if ((limit_maxrdreqsz || | ||
596 | ((nesdev->nesadapter->phy_type[0] == NES_PHY_TYPE_GLADIUS) && | ||
597 | (hw_rev == NE020_REV1))) && | ||
598 | (pcie_get_readrq(pcidev) > 256)) { | ||
599 | if (pcie_set_readrq(pcidev, 256)) | ||
600 | printk(KERN_ERR PFX "Unable to set max read request" | ||
601 | " to 256 bytes\n"); | ||
602 | else | ||
603 | nes_debug(NES_DBG_INIT, "Max read request size set" | ||
604 | " to 256 bytes\n"); | ||
605 | } | ||
606 | |||
591 | tasklet_init(&nesdev->dpc_tasklet, nes_dpc, (unsigned long)nesdev); | 607 | tasklet_init(&nesdev->dpc_tasklet, nes_dpc, (unsigned long)nesdev); |
592 | 608 | ||
593 | /* bring up the Control QP */ | 609 | /* bring up the Control QP */ |
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h index 610b9d859597..bc0b4de04450 100644 --- a/drivers/infiniband/hw/nes/nes_hw.h +++ b/drivers/infiniband/hw/nes/nes_hw.h | |||
@@ -40,6 +40,7 @@ | |||
40 | #define NES_PHY_TYPE_ARGUS 4 | 40 | #define NES_PHY_TYPE_ARGUS 4 |
41 | #define NES_PHY_TYPE_PUMA_1G 5 | 41 | #define NES_PHY_TYPE_PUMA_1G 5 |
42 | #define NES_PHY_TYPE_PUMA_10G 6 | 42 | #define NES_PHY_TYPE_PUMA_10G 6 |
43 | #define NES_PHY_TYPE_GLADIUS 7 | ||
43 | 44 | ||
44 | #define NES_MULTICAST_PF_MAX 8 | 45 | #define NES_MULTICAST_PF_MAX 8 |
45 | 46 | ||
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 932e56fcf774..d36c9a0bf1bb 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c | |||
@@ -220,14 +220,14 @@ static int nes_bind_mw(struct ib_qp *ibqp, struct ib_mw *ibmw, | |||
220 | if (nesqp->ibqp_state > IB_QPS_RTS) | 220 | if (nesqp->ibqp_state > IB_QPS_RTS) |
221 | return -EINVAL; | 221 | return -EINVAL; |
222 | 222 | ||
223 | spin_lock_irqsave(&nesqp->lock, flags); | 223 | spin_lock_irqsave(&nesqp->lock, flags); |
224 | 224 | ||
225 | head = nesqp->hwqp.sq_head; | 225 | head = nesqp->hwqp.sq_head; |
226 | qsize = nesqp->hwqp.sq_tail; | 226 | qsize = nesqp->hwqp.sq_tail; |
227 | 227 | ||
228 | /* Check for SQ overflow */ | 228 | /* Check for SQ overflow */ |
229 | if (((head + (2 * qsize) - nesqp->hwqp.sq_tail) % qsize) == (qsize - 1)) { | 229 | if (((head + (2 * qsize) - nesqp->hwqp.sq_tail) % qsize) == (qsize - 1)) { |
230 | spin_unlock_irqrestore(&nesqp->lock, flags); | 230 | spin_unlock_irqrestore(&nesqp->lock, flags); |
231 | return -EINVAL; | 231 | return -EINVAL; |
232 | } | 232 | } |
233 | 233 | ||
@@ -269,7 +269,7 @@ static int nes_bind_mw(struct ib_qp *ibqp, struct ib_mw *ibmw, | |||
269 | nes_write32(nesdev->regs+NES_WQE_ALLOC, | 269 | nes_write32(nesdev->regs+NES_WQE_ALLOC, |
270 | (1 << 24) | 0x00800000 | nesqp->hwqp.qp_id); | 270 | (1 << 24) | 0x00800000 | nesqp->hwqp.qp_id); |
271 | 271 | ||
272 | spin_unlock_irqrestore(&nesqp->lock, flags); | 272 | spin_unlock_irqrestore(&nesqp->lock, flags); |
273 | 273 | ||
274 | return 0; | 274 | return 0; |
275 | } | 275 | } |
@@ -349,7 +349,7 @@ static struct ib_fmr *nes_alloc_fmr(struct ib_pd *ibpd, | |||
349 | if (nesfmr->nesmr.pbls_used > nesadapter->free_4kpbl) { | 349 | if (nesfmr->nesmr.pbls_used > nesadapter->free_4kpbl) { |
350 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); | 350 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); |
351 | ret = -ENOMEM; | 351 | ret = -ENOMEM; |
352 | goto failed_vpbl_alloc; | 352 | goto failed_vpbl_avail; |
353 | } else { | 353 | } else { |
354 | nesadapter->free_4kpbl -= nesfmr->nesmr.pbls_used; | 354 | nesadapter->free_4kpbl -= nesfmr->nesmr.pbls_used; |
355 | } | 355 | } |
@@ -357,7 +357,7 @@ static struct ib_fmr *nes_alloc_fmr(struct ib_pd *ibpd, | |||
357 | if (nesfmr->nesmr.pbls_used > nesadapter->free_256pbl) { | 357 | if (nesfmr->nesmr.pbls_used > nesadapter->free_256pbl) { |
358 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); | 358 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); |
359 | ret = -ENOMEM; | 359 | ret = -ENOMEM; |
360 | goto failed_vpbl_alloc; | 360 | goto failed_vpbl_avail; |
361 | } else { | 361 | } else { |
362 | nesadapter->free_256pbl -= nesfmr->nesmr.pbls_used; | 362 | nesadapter->free_256pbl -= nesfmr->nesmr.pbls_used; |
363 | } | 363 | } |
@@ -391,14 +391,14 @@ static struct ib_fmr *nes_alloc_fmr(struct ib_pd *ibpd, | |||
391 | goto failed_vpbl_alloc; | 391 | goto failed_vpbl_alloc; |
392 | } | 392 | } |
393 | 393 | ||
394 | nesfmr->root_vpbl.leaf_vpbl = kzalloc(sizeof(*nesfmr->root_vpbl.leaf_vpbl)*1024, GFP_KERNEL); | 394 | nesfmr->leaf_pbl_cnt = nesfmr->nesmr.pbls_used-1; |
395 | nesfmr->root_vpbl.leaf_vpbl = kzalloc(sizeof(*nesfmr->root_vpbl.leaf_vpbl)*1024, GFP_ATOMIC); | ||
395 | if (!nesfmr->root_vpbl.leaf_vpbl) { | 396 | if (!nesfmr->root_vpbl.leaf_vpbl) { |
396 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); | 397 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); |
397 | ret = -ENOMEM; | 398 | ret = -ENOMEM; |
398 | goto failed_leaf_vpbl_alloc; | 399 | goto failed_leaf_vpbl_alloc; |
399 | } | 400 | } |
400 | 401 | ||
401 | nesfmr->leaf_pbl_cnt = nesfmr->nesmr.pbls_used-1; | ||
402 | nes_debug(NES_DBG_MR, "two level pbl, root_vpbl.pbl_vbase=%p" | 402 | nes_debug(NES_DBG_MR, "two level pbl, root_vpbl.pbl_vbase=%p" |
403 | " leaf_pbl_cnt=%d root_vpbl.leaf_vpbl=%p\n", | 403 | " leaf_pbl_cnt=%d root_vpbl.leaf_vpbl=%p\n", |
404 | nesfmr->root_vpbl.pbl_vbase, nesfmr->leaf_pbl_cnt, nesfmr->root_vpbl.leaf_vpbl); | 404 | nesfmr->root_vpbl.pbl_vbase, nesfmr->leaf_pbl_cnt, nesfmr->root_vpbl.leaf_vpbl); |
@@ -519,6 +519,16 @@ static struct ib_fmr *nes_alloc_fmr(struct ib_pd *ibpd, | |||
519 | nesfmr->root_vpbl.pbl_pbase); | 519 | nesfmr->root_vpbl.pbl_pbase); |
520 | 520 | ||
521 | failed_vpbl_alloc: | 521 | failed_vpbl_alloc: |
522 | if (nesfmr->nesmr.pbls_used != 0) { | ||
523 | spin_lock_irqsave(&nesadapter->pbl_lock, flags); | ||
524 | if (nesfmr->nesmr.pbl_4k) | ||
525 | nesadapter->free_4kpbl += nesfmr->nesmr.pbls_used; | ||
526 | else | ||
527 | nesadapter->free_256pbl += nesfmr->nesmr.pbls_used; | ||
528 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); | ||
529 | } | ||
530 | |||
531 | failed_vpbl_avail: | ||
522 | kfree(nesfmr); | 532 | kfree(nesfmr); |
523 | 533 | ||
524 | failed_fmr_alloc: | 534 | failed_fmr_alloc: |
@@ -534,18 +544,14 @@ static struct ib_fmr *nes_alloc_fmr(struct ib_pd *ibpd, | |||
534 | */ | 544 | */ |
535 | static int nes_dealloc_fmr(struct ib_fmr *ibfmr) | 545 | static int nes_dealloc_fmr(struct ib_fmr *ibfmr) |
536 | { | 546 | { |
547 | unsigned long flags; | ||
537 | struct nes_mr *nesmr = to_nesmr_from_ibfmr(ibfmr); | 548 | struct nes_mr *nesmr = to_nesmr_from_ibfmr(ibfmr); |
538 | struct nes_fmr *nesfmr = to_nesfmr(nesmr); | 549 | struct nes_fmr *nesfmr = to_nesfmr(nesmr); |
539 | struct nes_vnic *nesvnic = to_nesvnic(ibfmr->device); | 550 | struct nes_vnic *nesvnic = to_nesvnic(ibfmr->device); |
540 | struct nes_device *nesdev = nesvnic->nesdev; | 551 | struct nes_device *nesdev = nesvnic->nesdev; |
541 | struct nes_mr temp_nesmr = *nesmr; | 552 | struct nes_adapter *nesadapter = nesdev->nesadapter; |
542 | int i = 0; | 553 | int i = 0; |
543 | 554 | ||
544 | temp_nesmr.ibmw.device = ibfmr->device; | ||
545 | temp_nesmr.ibmw.pd = ibfmr->pd; | ||
546 | temp_nesmr.ibmw.rkey = ibfmr->rkey; | ||
547 | temp_nesmr.ibmw.uobject = NULL; | ||
548 | |||
549 | /* free the resources */ | 555 | /* free the resources */ |
550 | if (nesfmr->leaf_pbl_cnt == 0) { | 556 | if (nesfmr->leaf_pbl_cnt == 0) { |
551 | /* single PBL case */ | 557 | /* single PBL case */ |
@@ -561,8 +567,24 @@ static int nes_dealloc_fmr(struct ib_fmr *ibfmr) | |||
561 | pci_free_consistent(nesdev->pcidev, 8192, nesfmr->root_vpbl.pbl_vbase, | 567 | pci_free_consistent(nesdev->pcidev, 8192, nesfmr->root_vpbl.pbl_vbase, |
562 | nesfmr->root_vpbl.pbl_pbase); | 568 | nesfmr->root_vpbl.pbl_pbase); |
563 | } | 569 | } |
570 | nesmr->ibmw.device = ibfmr->device; | ||
571 | nesmr->ibmw.pd = ibfmr->pd; | ||
572 | nesmr->ibmw.rkey = ibfmr->rkey; | ||
573 | nesmr->ibmw.uobject = NULL; | ||
564 | 574 | ||
565 | return nes_dealloc_mw(&temp_nesmr.ibmw); | 575 | if (nesfmr->nesmr.pbls_used != 0) { |
576 | spin_lock_irqsave(&nesadapter->pbl_lock, flags); | ||
577 | if (nesfmr->nesmr.pbl_4k) { | ||
578 | nesadapter->free_4kpbl += nesfmr->nesmr.pbls_used; | ||
579 | WARN_ON(nesadapter->free_4kpbl > nesadapter->max_4kpbl); | ||
580 | } else { | ||
581 | nesadapter->free_256pbl += nesfmr->nesmr.pbls_used; | ||
582 | WARN_ON(nesadapter->free_256pbl > nesadapter->max_256pbl); | ||
583 | } | ||
584 | spin_unlock_irqrestore(&nesadapter->pbl_lock, flags); | ||
585 | } | ||
586 | |||
587 | return nes_dealloc_mw(&nesmr->ibmw); | ||
566 | } | 588 | } |
567 | 589 | ||
568 | 590 | ||
@@ -1595,7 +1617,7 @@ static struct ib_cq *nes_create_cq(struct ib_device *ibdev, int entries, | |||
1595 | nes_ucontext->mcrqf = req.mcrqf; | 1617 | nes_ucontext->mcrqf = req.mcrqf; |
1596 | if (nes_ucontext->mcrqf) { | 1618 | if (nes_ucontext->mcrqf) { |
1597 | if (nes_ucontext->mcrqf & 0x80000000) | 1619 | if (nes_ucontext->mcrqf & 0x80000000) |
1598 | nescq->hw_cq.cq_number = nesvnic->nic.qp_id + 12 + (nes_ucontext->mcrqf & 0xf) - 1; | 1620 | nescq->hw_cq.cq_number = nesvnic->nic.qp_id + 28 + 2 * ((nes_ucontext->mcrqf & 0xf) - 1); |
1599 | else if (nes_ucontext->mcrqf & 0x40000000) | 1621 | else if (nes_ucontext->mcrqf & 0x40000000) |
1600 | nescq->hw_cq.cq_number = nes_ucontext->mcrqf & 0xffff; | 1622 | nescq->hw_cq.cq_number = nes_ucontext->mcrqf & 0xffff; |
1601 | else | 1623 | else |
@@ -3212,7 +3234,7 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, | |||
3212 | if (nesqp->ibqp_state > IB_QPS_RTS) | 3234 | if (nesqp->ibqp_state > IB_QPS_RTS) |
3213 | return -EINVAL; | 3235 | return -EINVAL; |
3214 | 3236 | ||
3215 | spin_lock_irqsave(&nesqp->lock, flags); | 3237 | spin_lock_irqsave(&nesqp->lock, flags); |
3216 | 3238 | ||
3217 | head = nesqp->hwqp.sq_head; | 3239 | head = nesqp->hwqp.sq_head; |
3218 | 3240 | ||
@@ -3337,7 +3359,7 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, | |||
3337 | (counter << 24) | 0x00800000 | nesqp->hwqp.qp_id); | 3359 | (counter << 24) | 0x00800000 | nesqp->hwqp.qp_id); |
3338 | } | 3360 | } |
3339 | 3361 | ||
3340 | spin_unlock_irqrestore(&nesqp->lock, flags); | 3362 | spin_unlock_irqrestore(&nesqp->lock, flags); |
3341 | 3363 | ||
3342 | if (err) | 3364 | if (err) |
3343 | *bad_wr = ib_wr; | 3365 | *bad_wr = ib_wr; |
@@ -3368,7 +3390,7 @@ static int nes_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, | |||
3368 | if (nesqp->ibqp_state > IB_QPS_RTS) | 3390 | if (nesqp->ibqp_state > IB_QPS_RTS) |
3369 | return -EINVAL; | 3391 | return -EINVAL; |
3370 | 3392 | ||
3371 | spin_lock_irqsave(&nesqp->lock, flags); | 3393 | spin_lock_irqsave(&nesqp->lock, flags); |
3372 | 3394 | ||
3373 | head = nesqp->hwqp.rq_head; | 3395 | head = nesqp->hwqp.rq_head; |
3374 | 3396 | ||
@@ -3421,7 +3443,7 @@ static int nes_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, | |||
3421 | nes_write32(nesdev->regs+NES_WQE_ALLOC, (counter<<24) | nesqp->hwqp.qp_id); | 3443 | nes_write32(nesdev->regs+NES_WQE_ALLOC, (counter<<24) | nesqp->hwqp.qp_id); |
3422 | } | 3444 | } |
3423 | 3445 | ||
3424 | spin_unlock_irqrestore(&nesqp->lock, flags); | 3446 | spin_unlock_irqrestore(&nesqp->lock, flags); |
3425 | 3447 | ||
3426 | if (err) | 3448 | if (err) |
3427 | *bad_wr = ib_wr; | 3449 | *bad_wr = ib_wr; |
@@ -3453,7 +3475,7 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) | |||
3453 | 3475 | ||
3454 | nes_debug(NES_DBG_CQ, "\n"); | 3476 | nes_debug(NES_DBG_CQ, "\n"); |
3455 | 3477 | ||
3456 | spin_lock_irqsave(&nescq->lock, flags); | 3478 | spin_lock_irqsave(&nescq->lock, flags); |
3457 | 3479 | ||
3458 | head = nescq->hw_cq.cq_head; | 3480 | head = nescq->hw_cq.cq_head; |
3459 | cq_size = nescq->hw_cq.cq_size; | 3481 | cq_size = nescq->hw_cq.cq_size; |
@@ -3562,7 +3584,7 @@ static int nes_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) | |||
3562 | nes_debug(NES_DBG_CQ, "Reporting %u completions for CQ%u.\n", | 3584 | nes_debug(NES_DBG_CQ, "Reporting %u completions for CQ%u.\n", |
3563 | cqe_count, nescq->hw_cq.cq_number); | 3585 | cqe_count, nescq->hw_cq.cq_number); |
3564 | 3586 | ||
3565 | spin_unlock_irqrestore(&nescq->lock, flags); | 3587 | spin_unlock_irqrestore(&nescq->lock, flags); |
3566 | 3588 | ||
3567 | return cqe_count; | 3589 | return cqe_count; |
3568 | } | 3590 | } |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index fddded7900d1..85257f6b9576 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -106,12 +106,13 @@ int ipoib_open(struct net_device *dev) | |||
106 | 106 | ||
107 | ipoib_dbg(priv, "bringing up interface\n"); | 107 | ipoib_dbg(priv, "bringing up interface\n"); |
108 | 108 | ||
109 | napi_enable(&priv->napi); | ||
110 | set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); | 109 | set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); |
111 | 110 | ||
112 | if (ipoib_pkey_dev_delay_open(dev)) | 111 | if (ipoib_pkey_dev_delay_open(dev)) |
113 | return 0; | 112 | return 0; |
114 | 113 | ||
114 | napi_enable(&priv->napi); | ||
115 | |||
115 | if (ipoib_ib_dev_open(dev)) { | 116 | if (ipoib_ib_dev_open(dev)) { |
116 | napi_disable(&priv->napi); | 117 | napi_disable(&priv->napi); |
117 | return -EINVAL; | 118 | return -EINVAL; |
@@ -546,6 +547,7 @@ static int path_rec_start(struct net_device *dev, | |||
546 | if (path->query_id < 0) { | 547 | if (path->query_id < 0) { |
547 | ipoib_warn(priv, "ib_sa_path_rec_get failed: %d\n", path->query_id); | 548 | ipoib_warn(priv, "ib_sa_path_rec_get failed: %d\n", path->query_id); |
548 | path->query = NULL; | 549 | path->query = NULL; |
550 | complete(&path->done); | ||
549 | return path->query_id; | 551 | return path->query_id; |
550 | } | 552 | } |
551 | 553 | ||
@@ -662,7 +664,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, | |||
662 | skb_push(skb, sizeof *phdr); | 664 | skb_push(skb, sizeof *phdr); |
663 | __skb_queue_tail(&path->queue, skb); | 665 | __skb_queue_tail(&path->queue, skb); |
664 | 666 | ||
665 | if (path_rec_start(dev, path)) { | 667 | if (!path->query && path_rec_start(dev, path)) { |
666 | spin_unlock_irqrestore(&priv->lock, flags); | 668 | spin_unlock_irqrestore(&priv->lock, flags); |
667 | path_free(dev, path); | 669 | path_free(dev, path); |
668 | return; | 670 | return; |
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 190147c79e79..3b90c5c924ec 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
@@ -148,6 +148,8 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
148 | 148 | ||
149 | min_sectors = conf->array_sectors; | 149 | min_sectors = conf->array_sectors; |
150 | sector_div(min_sectors, PAGE_SIZE/sizeof(struct dev_info *)); | 150 | sector_div(min_sectors, PAGE_SIZE/sizeof(struct dev_info *)); |
151 | if (min_sectors == 0) | ||
152 | min_sectors = 1; | ||
151 | 153 | ||
152 | /* min_sectors is the minimum spacing that will fit the hash | 154 | /* min_sectors is the minimum spacing that will fit the hash |
153 | * table in one PAGE. This may be much smaller than needed. | 155 | * table in one PAGE. This may be much smaller than needed. |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 9abf6ed16535..1b1d32694f6f 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -3884,7 +3884,6 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) | |||
3884 | if (mode == 0) { | 3884 | if (mode == 0) { |
3885 | mdk_rdev_t *rdev; | 3885 | mdk_rdev_t *rdev; |
3886 | struct list_head *tmp; | 3886 | struct list_head *tmp; |
3887 | struct block_device *bdev; | ||
3888 | 3887 | ||
3889 | printk(KERN_INFO "md: %s stopped.\n", mdname(mddev)); | 3888 | printk(KERN_INFO "md: %s stopped.\n", mdname(mddev)); |
3890 | 3889 | ||
@@ -3941,11 +3940,6 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open) | |||
3941 | mddev->degraded = 0; | 3940 | mddev->degraded = 0; |
3942 | mddev->barriers_work = 0; | 3941 | mddev->barriers_work = 0; |
3943 | mddev->safemode = 0; | 3942 | mddev->safemode = 0; |
3944 | bdev = bdget_disk(mddev->gendisk, 0); | ||
3945 | if (bdev) { | ||
3946 | blkdev_ioctl(bdev, 0, BLKRRPART, 0); | ||
3947 | bdput(bdev); | ||
3948 | } | ||
3949 | kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE); | 3943 | kobject_uevent(&disk_to_dev(mddev->gendisk)->kobj, KOBJ_CHANGE); |
3950 | 3944 | ||
3951 | } else if (mddev->pers) | 3945 | } else if (mddev->pers) |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index da5129a24b18..970a96ef9b18 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -1137,7 +1137,7 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1137 | if (!enough(conf)) | 1137 | if (!enough(conf)) |
1138 | return -EINVAL; | 1138 | return -EINVAL; |
1139 | 1139 | ||
1140 | if (rdev->raid_disk) | 1140 | if (rdev->raid_disk >= 0) |
1141 | first = last = rdev->raid_disk; | 1141 | first = last = rdev->raid_disk; |
1142 | 1142 | ||
1143 | if (rdev->saved_raid_disk >= 0 && | 1143 | if (rdev->saved_raid_disk >= 0 && |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 5689d1f1d444..8557bf12cfb4 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
@@ -223,6 +223,8 @@ static void dvb_frontend_init(struct dvb_frontend *fe) | |||
223 | if (fe->ops.init) | 223 | if (fe->ops.init) |
224 | fe->ops.init(fe); | 224 | fe->ops.init(fe); |
225 | if (fe->ops.tuner_ops.init) { | 225 | if (fe->ops.tuner_ops.init) { |
226 | if (fe->ops.i2c_gate_ctrl) | ||
227 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
226 | fe->ops.tuner_ops.init(fe); | 228 | fe->ops.tuner_ops.init(fe); |
227 | if (fe->ops.i2c_gate_ctrl) | 229 | if (fe->ops.i2c_gate_ctrl) |
228 | fe->ops.i2c_gate_ctrl(fe, 0); | 230 | fe->ops.i2c_gate_ctrl(fe, 0); |
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 3c13bcfa6385..62b68c291d99 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
@@ -261,7 +261,7 @@ config DVB_USB_DW2102 | |||
261 | Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers | 261 | Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers |
262 | and the TeVii S650. | 262 | and the TeVii S650. |
263 | 263 | ||
264 | config DVB_USB_CINERGY_T2 | 264 | config DVB_USB_CINERGY_T2 |
265 | tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver" | 265 | tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver" |
266 | depends on DVB_USB | 266 | depends on DVB_USB |
267 | help | 267 | help |
@@ -283,6 +283,7 @@ config DVB_USB_ANYSEE | |||
283 | config DVB_USB_DTV5100 | 283 | config DVB_USB_DTV5100 |
284 | tristate "AME DTV-5100 USB2.0 DVB-T support" | 284 | tristate "AME DTV-5100 USB2.0 DVB-T support" |
285 | depends on DVB_USB | 285 | depends on DVB_USB |
286 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE | ||
286 | select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE | 287 | select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE |
287 | help | 288 | help |
288 | Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver. | 289 | Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver. |
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index cb0829c038ce..847d8fdd9ec4 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c | |||
@@ -31,13 +31,13 @@ | |||
31 | #include "mc44s80x.h" | 31 | #include "mc44s80x.h" |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | int dvb_usb_af9015_debug; | 34 | static int dvb_usb_af9015_debug; |
35 | module_param_named(debug, dvb_usb_af9015_debug, int, 0644); | 35 | module_param_named(debug, dvb_usb_af9015_debug, int, 0644); |
36 | MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); | 36 | MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); |
37 | int dvb_usb_af9015_remote; | 37 | static int dvb_usb_af9015_remote; |
38 | module_param_named(remote, dvb_usb_af9015_remote, int, 0644); | 38 | module_param_named(remote, dvb_usb_af9015_remote, int, 0644); |
39 | MODULE_PARM_DESC(remote, "select remote"); | 39 | MODULE_PARM_DESC(remote, "select remote"); |
40 | int dvb_usb_af9015_dual_mode; | 40 | static int dvb_usb_af9015_dual_mode; |
41 | module_param_named(dual_mode, dvb_usb_af9015_dual_mode, int, 0644); | 41 | module_param_named(dual_mode, dvb_usb_af9015_dual_mode, int, 0644); |
42 | MODULE_PARM_DESC(dual_mode, "enable dual mode"); | 42 | MODULE_PARM_DESC(dual_mode, "enable dual mode"); |
43 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 43 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
@@ -46,7 +46,7 @@ static DEFINE_MUTEX(af9015_usb_mutex); | |||
46 | 46 | ||
47 | static struct af9015_config af9015_config; | 47 | static struct af9015_config af9015_config; |
48 | static struct dvb_usb_device_properties af9015_properties[2]; | 48 | static struct dvb_usb_device_properties af9015_properties[2]; |
49 | int af9015_properties_count = ARRAY_SIZE(af9015_properties); | 49 | static int af9015_properties_count = ARRAY_SIZE(af9015_properties); |
50 | 50 | ||
51 | static struct af9013_config af9015_af9013_config[] = { | 51 | static struct af9013_config af9015_af9013_config[] = { |
52 | { | 52 | { |
@@ -549,7 +549,7 @@ static int af9015_eeprom_dump(struct dvb_usb_device *d) | |||
549 | return 0; | 549 | return 0; |
550 | } | 550 | } |
551 | 551 | ||
552 | int af9015_download_ir_table(struct dvb_usb_device *d) | 552 | static int af9015_download_ir_table(struct dvb_usb_device *d) |
553 | { | 553 | { |
554 | int i, packets = 0, ret; | 554 | int i, packets = 0, ret; |
555 | u16 addr = 0x9a56; /* ir-table start address */ | 555 | u16 addr = 0x9a56; /* ir-table start address */ |
@@ -999,7 +999,7 @@ static int af9015_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | |||
999 | } | 999 | } |
1000 | 1000 | ||
1001 | /* init 2nd I2C adapter */ | 1001 | /* init 2nd I2C adapter */ |
1002 | int af9015_i2c_init(struct dvb_usb_device *d) | 1002 | static int af9015_i2c_init(struct dvb_usb_device *d) |
1003 | { | 1003 | { |
1004 | int ret; | 1004 | int ret; |
1005 | struct af9015_state *state = d->priv; | 1005 | struct af9015_state *state = d->priv; |
@@ -1419,7 +1419,7 @@ static int af9015_usb_probe(struct usb_interface *intf, | |||
1419 | return ret; | 1419 | return ret; |
1420 | } | 1420 | } |
1421 | 1421 | ||
1422 | void af9015_i2c_exit(struct dvb_usb_device *d) | 1422 | static void af9015_i2c_exit(struct dvb_usb_device *d) |
1423 | { | 1423 | { |
1424 | struct af9015_state *state = d->priv; | 1424 | struct af9015_state *state = d->priv; |
1425 | deb_info("%s: \n", __func__); | 1425 | deb_info("%s: \n", __func__); |
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h index 882e8a4b3681..6c3c97293316 100644 --- a/drivers/media/dvb/dvb-usb/af9015.h +++ b/drivers/media/dvb/dvb-usb/af9015.h | |||
@@ -27,7 +27,6 @@ | |||
27 | #define DVB_USB_LOG_PREFIX "af9015" | 27 | #define DVB_USB_LOG_PREFIX "af9015" |
28 | #include "dvb-usb.h" | 28 | #include "dvb-usb.h" |
29 | 29 | ||
30 | extern int dvb_usb_af9015_debug; | ||
31 | #define deb_info(args...) dprintk(dvb_usb_af9015_debug, 0x01, args) | 30 | #define deb_info(args...) dprintk(dvb_usb_af9015_debug, 0x01, args) |
32 | #define deb_rc(args...) dprintk(dvb_usb_af9015_debug, 0x02, args) | 31 | #define deb_rc(args...) dprintk(dvb_usb_af9015_debug, 0x02, args) |
33 | #define deb_xfer(args...) dprintk(dvb_usb_af9015_debug, 0x04, args) | 32 | #define deb_xfer(args...) dprintk(dvb_usb_af9015_debug, 0x04, args) |
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index c786359fba03..cd2edbcaa097 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c | |||
@@ -46,7 +46,7 @@ module_param_named(delsys, dvb_usb_anysee_delsys, int, 0644); | |||
46 | MODULE_PARM_DESC(delsys, "select delivery mode (0=DVB-C, 1=DVB-T)"); | 46 | MODULE_PARM_DESC(delsys, "select delivery mode (0=DVB-C, 1=DVB-T)"); |
47 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 47 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
48 | 48 | ||
49 | static struct mutex anysee_usb_mutex; | 49 | static DEFINE_MUTEX(anysee_usb_mutex); |
50 | 50 | ||
51 | static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, | 51 | static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, |
52 | u8 *rbuf, u8 rlen) | 52 | u8 *rbuf, u8 rlen) |
@@ -456,8 +456,6 @@ static int anysee_probe(struct usb_interface *intf, | |||
456 | struct usb_host_interface *alt; | 456 | struct usb_host_interface *alt; |
457 | int ret; | 457 | int ret; |
458 | 458 | ||
459 | mutex_init(&anysee_usb_mutex); | ||
460 | |||
461 | /* There is one interface with two alternate settings. | 459 | /* There is one interface with two alternate settings. |
462 | Alternate setting 0 is for bulk transfer. | 460 | Alternate setting 0 is for bulk transfer. |
463 | Alternate setting 1 is for isochronous transfer. | 461 | Alternate setting 1 is for isochronous transfer. |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c index 5cef12a07f72..6fe71c6745eb 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c | |||
@@ -13,14 +13,14 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, | |||
13 | { | 13 | { |
14 | int actlen,ret = -ENOMEM; | 14 | int actlen,ret = -ENOMEM; |
15 | 15 | ||
16 | if (!d || wbuf == NULL || wlen == 0) | ||
17 | return -EINVAL; | ||
18 | |||
16 | if (d->props.generic_bulk_ctrl_endpoint == 0) { | 19 | if (d->props.generic_bulk_ctrl_endpoint == 0) { |
17 | err("endpoint for generic control not specified."); | 20 | err("endpoint for generic control not specified."); |
18 | return -EINVAL; | 21 | return -EINVAL; |
19 | } | 22 | } |
20 | 23 | ||
21 | if (wbuf == NULL || wlen == 0) | ||
22 | return -EINVAL; | ||
23 | |||
24 | if ((ret = mutex_lock_interruptible(&d->usb_mutex))) | 24 | if ((ret = mutex_lock_interruptible(&d->usb_mutex))) |
25 | return ret; | 25 | return ret; |
26 | 26 | ||
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c index 21c1060cf10e..692b68a9e73b 100644 --- a/drivers/media/dvb/frontends/af9013.c +++ b/drivers/media/dvb/frontends/af9013.c | |||
@@ -1187,7 +1187,7 @@ static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status) | |||
1187 | if (tmp) | 1187 | if (tmp) |
1188 | *status |= FE_HAS_SYNC | FE_HAS_LOCK; | 1188 | *status |= FE_HAS_SYNC | FE_HAS_LOCK; |
1189 | 1189 | ||
1190 | if (!*status & FE_HAS_SIGNAL) { | 1190 | if (!(*status & FE_HAS_SIGNAL)) { |
1191 | /* AGC lock */ | 1191 | /* AGC lock */ |
1192 | ret = af9013_read_reg_bits(state, 0xd1a0, 6, 1, &tmp); | 1192 | ret = af9013_read_reg_bits(state, 0xd1a0, 6, 1, &tmp); |
1193 | if (ret) | 1193 | if (ret) |
@@ -1196,7 +1196,7 @@ static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status) | |||
1196 | *status |= FE_HAS_SIGNAL; | 1196 | *status |= FE_HAS_SIGNAL; |
1197 | } | 1197 | } |
1198 | 1198 | ||
1199 | if (!*status & FE_HAS_CARRIER) { | 1199 | if (!(*status & FE_HAS_CARRIER)) { |
1200 | /* CFO lock */ | 1200 | /* CFO lock */ |
1201 | ret = af9013_read_reg_bits(state, 0xd333, 7, 1, &tmp); | 1201 | ret = af9013_read_reg_bits(state, 0xd333, 7, 1, &tmp); |
1202 | if (ret) | 1202 | if (ret) |
@@ -1205,7 +1205,7 @@ static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status) | |||
1205 | *status |= FE_HAS_CARRIER; | 1205 | *status |= FE_HAS_CARRIER; |
1206 | } | 1206 | } |
1207 | 1207 | ||
1208 | if (!*status & FE_HAS_CARRIER) { | 1208 | if (!(*status & FE_HAS_CARRIER)) { |
1209 | /* SFOE lock */ | 1209 | /* SFOE lock */ |
1210 | ret = af9013_read_reg_bits(state, 0xd334, 6, 1, &tmp); | 1210 | ret = af9013_read_reg_bits(state, 0xd334, 6, 1, &tmp); |
1211 | if (ret) | 1211 | if (ret) |
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 04cd7c04bdde..5189c4eb439f 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig | |||
@@ -355,6 +355,20 @@ config USB_SI470X | |||
355 | tristate "Silicon Labs Si470x FM Radio Receiver support" | 355 | tristate "Silicon Labs Si470x FM Radio Receiver support" |
356 | depends on USB && VIDEO_V4L2 | 356 | depends on USB && VIDEO_V4L2 |
357 | ---help--- | 357 | ---help--- |
358 | This is a driver for USB devices with the Silicon Labs SI470x | ||
359 | chip. Currently these devices are known to work: | ||
360 | - 10c4:818a: Silicon Labs USB FM Radio Reference Design | ||
361 | - 06e1:a155: ADS/Tech FM Radio Receiver (formerly Instant FM Music) | ||
362 | - 1b80:d700: KWorld USB FM Radio SnapMusic Mobile 700 (FM700) | ||
363 | |||
364 | Sound is provided by the ALSA USB Audio/MIDI driver. Therefore | ||
365 | if you don't want to use the device solely for RDS receiving, | ||
366 | it is recommended to also select SND_USB_AUDIO. | ||
367 | |||
368 | Please have a look at the documentation, especially on how | ||
369 | to redirect the audio stream from the radio to your sound device: | ||
370 | Documentation/video4linux/si470x.txt | ||
371 | |||
358 | Say Y here if you want to connect this type of radio to your | 372 | Say Y here if you want to connect this type of radio to your |
359 | computer's USB port. | 373 | computer's USB port. |
360 | 374 | ||
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index 5920cd306975..3e1830293de5 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c | |||
@@ -4,6 +4,7 @@ | |||
4 | * Driver for USB radios for the Silicon Labs Si470x FM Radio Receivers: | 4 | * Driver for USB radios for the Silicon Labs Si470x FM Radio Receivers: |
5 | * - Silicon Labs USB FM Radio Reference Design | 5 | * - Silicon Labs USB FM Radio Reference Design |
6 | * - ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF) | 6 | * - ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF) |
7 | * - KWorld USB FM Radio SnapMusic Mobile 700 (FM700) | ||
7 | * | 8 | * |
8 | * Copyright (c) 2008 Tobias Lorenz <tobias.lorenz@gmx.net> | 9 | * Copyright (c) 2008 Tobias Lorenz <tobias.lorenz@gmx.net> |
9 | * | 10 | * |
@@ -24,19 +25,6 @@ | |||
24 | 25 | ||
25 | 26 | ||
26 | /* | 27 | /* |
27 | * User Notes: | ||
28 | * - USB Audio is provided by the alsa snd_usb_audio module. | ||
29 | * For listing you have to redirect the sound, for example using: | ||
30 | * arecord -D hw:1,0 -r96000 -c2 -f S16_LE | artsdsp aplay -B - | ||
31 | * - regarding module parameters in /sys/module/radio_si470x/parameters: | ||
32 | * the contents of read-only files (0444) are not updated, even if | ||
33 | * space, band and de are changed using private video controls | ||
34 | * - increase tune_timeout, if you often get -EIO errors | ||
35 | * - hw_freq_seek returns -EAGAIN, when timed out or band limit is reached | ||
36 | */ | ||
37 | |||
38 | |||
39 | /* | ||
40 | * History: | 28 | * History: |
41 | * 2008-01-12 Tobias Lorenz <tobias.lorenz@gmx.net> | 29 | * 2008-01-12 Tobias Lorenz <tobias.lorenz@gmx.net> |
42 | * Version 1.0.0 | 30 | * Version 1.0.0 |
@@ -105,6 +93,9 @@ | |||
105 | * - afc indication | 93 | * - afc indication |
106 | * - more safety checks, let si470x_get_freq return errno | 94 | * - more safety checks, let si470x_get_freq return errno |
107 | * - vidioc behavior corrected according to v4l2 spec | 95 | * - vidioc behavior corrected according to v4l2 spec |
96 | * 2008-10-20 Alexey Klimov <klimov.linux@gmail.com> | ||
97 | * - add support for KWorld USB FM Radio FM700 | ||
98 | * - blacklisted KWorld radio in hid-core.c and hid-ids.h | ||
108 | * | 99 | * |
109 | * ToDo: | 100 | * ToDo: |
110 | * - add firmware download/update support | 101 | * - add firmware download/update support |
@@ -145,6 +136,8 @@ static struct usb_device_id si470x_usb_driver_id_table[] = { | |||
145 | { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) }, | 136 | { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) }, |
146 | /* ADS/Tech FM Radio Receiver (formerly Instant FM Music) */ | 137 | /* ADS/Tech FM Radio Receiver (formerly Instant FM Music) */ |
147 | { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) }, | 138 | { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) }, |
139 | /* KWorld USB FM Radio SnapMusic Mobile 700 (FM700) */ | ||
140 | { USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) }, | ||
148 | /* Terminating entry */ | 141 | /* Terminating entry */ |
149 | { } | 142 | { } |
150 | }; | 143 | }; |
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index a8c068e1de1c..1740b9ebdcef 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c | |||
@@ -1476,12 +1476,9 @@ static int cafe_v4l_open(struct inode *inode, struct file *filp) | |||
1476 | { | 1476 | { |
1477 | struct cafe_camera *cam; | 1477 | struct cafe_camera *cam; |
1478 | 1478 | ||
1479 | lock_kernel(); | ||
1480 | cam = cafe_find_dev(iminor(inode)); | 1479 | cam = cafe_find_dev(iminor(inode)); |
1481 | if (cam == NULL) { | 1480 | if (cam == NULL) |
1482 | unlock_kernel(); | ||
1483 | return -ENODEV; | 1481 | return -ENODEV; |
1484 | } | ||
1485 | filp->private_data = cam; | 1482 | filp->private_data = cam; |
1486 | 1483 | ||
1487 | mutex_lock(&cam->s_mutex); | 1484 | mutex_lock(&cam->s_mutex); |
@@ -1493,7 +1490,6 @@ static int cafe_v4l_open(struct inode *inode, struct file *filp) | |||
1493 | } | 1490 | } |
1494 | (cam->users)++; | 1491 | (cam->users)++; |
1495 | mutex_unlock(&cam->s_mutex); | 1492 | mutex_unlock(&cam->s_mutex); |
1496 | unlock_kernel(); | ||
1497 | return 0; | 1493 | return 0; |
1498 | } | 1494 | } |
1499 | 1495 | ||
diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c index bd5d9de5a008..e6ca4012b5f0 100644 --- a/drivers/media/video/compat_ioctl32.c +++ b/drivers/media/video/compat_ioctl32.c | |||
@@ -867,6 +867,7 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) | |||
867 | case VIDIOC_STREAMON32: | 867 | case VIDIOC_STREAMON32: |
868 | case VIDIOC_STREAMOFF32: | 868 | case VIDIOC_STREAMOFF32: |
869 | case VIDIOC_G_PARM: | 869 | case VIDIOC_G_PARM: |
870 | case VIDIOC_S_PARM: | ||
870 | case VIDIOC_G_STD: | 871 | case VIDIOC_G_STD: |
871 | case VIDIOC_S_STD: | 872 | case VIDIOC_S_STD: |
872 | case VIDIOC_G_TUNER: | 873 | case VIDIOC_G_TUNER: |
@@ -885,6 +886,8 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) | |||
885 | case VIDIOC_S_INPUT32: | 886 | case VIDIOC_S_INPUT32: |
886 | case VIDIOC_TRY_FMT32: | 887 | case VIDIOC_TRY_FMT32: |
887 | case VIDIOC_S_HW_FREQ_SEEK: | 888 | case VIDIOC_S_HW_FREQ_SEEK: |
889 | case VIDIOC_ENUM_FRAMESIZES: | ||
890 | case VIDIOC_ENUM_FRAMEINTERVALS: | ||
888 | ret = do_video_ioctl(file, cmd, arg); | 891 | ret = do_video_ioctl(file, cmd, arg); |
889 | break; | 892 | break; |
890 | 893 | ||
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 7a1a7830a6b3..7874d9790a51 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c | |||
@@ -448,7 +448,14 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) | |||
448 | mutex_init(&cx->gpio_lock); | 448 | mutex_init(&cx->gpio_lock); |
449 | 449 | ||
450 | spin_lock_init(&cx->lock); | 450 | spin_lock_init(&cx->lock); |
451 | spin_lock_init(&cx->dma_reg_lock); | 451 | |
452 | cx->work_queue = create_singlethread_workqueue(cx->name); | ||
453 | if (cx->work_queue == NULL) { | ||
454 | CX18_ERR("Could not create work queue\n"); | ||
455 | return -1; | ||
456 | } | ||
457 | |||
458 | INIT_WORK(&cx->work, cx18_work_handler); | ||
452 | 459 | ||
453 | /* start counting open_id at 1 */ | 460 | /* start counting open_id at 1 */ |
454 | cx->open_id = 1; | 461 | cx->open_id = 1; |
@@ -581,10 +588,10 @@ static void cx18_load_and_init_modules(struct cx18 *cx) | |||
581 | 588 | ||
582 | #ifdef MODULE | 589 | #ifdef MODULE |
583 | /* load modules */ | 590 | /* load modules */ |
584 | #ifndef CONFIG_MEDIA_TUNER | 591 | #ifdef CONFIG_MEDIA_TUNER_MODULE |
585 | hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER); | 592 | hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER); |
586 | #endif | 593 | #endif |
587 | #ifndef CONFIG_VIDEO_CS5345 | 594 | #ifdef CONFIG_VIDEO_CS5345_MODULE |
588 | hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345); | 595 | hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345); |
589 | #endif | 596 | #endif |
590 | #endif | 597 | #endif |
@@ -832,6 +839,7 @@ free_map: | |||
832 | free_mem: | 839 | free_mem: |
833 | release_mem_region(cx->base_addr, CX18_MEM_SIZE); | 840 | release_mem_region(cx->base_addr, CX18_MEM_SIZE); |
834 | free_workqueue: | 841 | free_workqueue: |
842 | destroy_workqueue(cx->work_queue); | ||
835 | err: | 843 | err: |
836 | if (retval == 0) | 844 | if (retval == 0) |
837 | retval = -ENODEV; | 845 | retval = -ENODEV; |
@@ -932,6 +940,9 @@ static void cx18_remove(struct pci_dev *pci_dev) | |||
932 | 940 | ||
933 | cx18_halt_firmware(cx); | 941 | cx18_halt_firmware(cx); |
934 | 942 | ||
943 | flush_workqueue(cx->work_queue); | ||
944 | destroy_workqueue(cx->work_queue); | ||
945 | |||
935 | cx18_streams_cleanup(cx, 1); | 946 | cx18_streams_cleanup(cx, 1); |
936 | 947 | ||
937 | exit_cx18_i2c(cx); | 948 | exit_cx18_i2c(cx); |
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index a4b1708fafe7..bbdd5f25041d 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h | |||
@@ -199,12 +199,15 @@ struct cx18_options { | |||
199 | #define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */ | 199 | #define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */ |
200 | 200 | ||
201 | /* per-cx18, i_flags */ | 201 | /* per-cx18, i_flags */ |
202 | #define CX18_F_I_LOADED_FW 0 /* Loaded the firmware the first time */ | 202 | #define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */ |
203 | #define CX18_F_I_EOS 4 /* End of encoder stream reached */ | 203 | #define CX18_F_I_EOS 4 /* End of encoder stream */ |
204 | #define CX18_F_I_RADIO_USER 5 /* The radio tuner is selected */ | 204 | #define CX18_F_I_RADIO_USER 5 /* radio tuner is selected */ |
205 | #define CX18_F_I_ENC_PAUSED 13 /* the encoder is paused */ | 205 | #define CX18_F_I_ENC_PAUSED 13 /* the encoder is paused */ |
206 | #define CX18_F_I_INITED 21 /* set after first open */ | 206 | #define CX18_F_I_HAVE_WORK 15 /* there is work to be done */ |
207 | #define CX18_F_I_FAILED 22 /* set if first open failed */ | 207 | #define CX18_F_I_WORK_HANDLER_DVB 18 /* work to be done for DVB */ |
208 | #define CX18_F_I_INITED 21 /* set after first open */ | ||
209 | #define CX18_F_I_FAILED 22 /* set if first open failed */ | ||
210 | #define CX18_F_I_WORK_INITED 23 /* worker thread initialized */ | ||
208 | 211 | ||
209 | /* These are the VBI types as they appear in the embedded VBI private packets. */ | 212 | /* These are the VBI types as they appear in the embedded VBI private packets. */ |
210 | #define CX18_SLICED_TYPE_TELETEXT_B (1) | 213 | #define CX18_SLICED_TYPE_TELETEXT_B (1) |
@@ -402,8 +405,6 @@ struct cx18 { | |||
402 | spinlock_t lock; /* lock access to this struct */ | 405 | spinlock_t lock; /* lock access to this struct */ |
403 | int search_pack_header; | 406 | int search_pack_header; |
404 | 407 | ||
405 | spinlock_t dma_reg_lock; /* lock access to DMA engine registers */ | ||
406 | |||
407 | int open_id; /* incremented each time an open occurs, used as | 408 | int open_id; /* incremented each time an open occurs, used as |
408 | unique ID. Starts at 1, so 0 can be used as | 409 | unique ID. Starts at 1, so 0 can be used as |
409 | uninitialized value in the stream->id. */ | 410 | uninitialized value in the stream->id. */ |
@@ -433,6 +434,9 @@ struct cx18 { | |||
433 | /* when the current DMA is finished this queue is woken up */ | 434 | /* when the current DMA is finished this queue is woken up */ |
434 | wait_queue_head_t dma_waitq; | 435 | wait_queue_head_t dma_waitq; |
435 | 436 | ||
437 | struct workqueue_struct *work_queue; | ||
438 | struct work_struct work; | ||
439 | |||
436 | /* i2c */ | 440 | /* i2c */ |
437 | struct i2c_adapter i2c_adap[2]; | 441 | struct i2c_adapter i2c_adap[2]; |
438 | struct i2c_algo_bit_data i2c_algo[2]; | 442 | struct i2c_algo_bit_data i2c_algo[2]; |
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c index afc694e7bdb2..4542e2e5e3d7 100644 --- a/drivers/media/video/cx18/cx18-dvb.c +++ b/drivers/media/video/cx18/cx18-dvb.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include "cx18-dvb.h" | 23 | #include "cx18-dvb.h" |
24 | #include "cx18-io.h" | 24 | #include "cx18-io.h" |
25 | #include "cx18-streams.h" | 25 | #include "cx18-streams.h" |
26 | #include "cx18-queue.h" | ||
27 | #include "cx18-scb.h" | ||
26 | #include "cx18-cards.h" | 28 | #include "cx18-cards.h" |
27 | #include "s5h1409.h" | 29 | #include "s5h1409.h" |
28 | #include "mxl5005s.h" | 30 | #include "mxl5005s.h" |
@@ -300,3 +302,24 @@ static int dvb_register(struct cx18_stream *stream) | |||
300 | 302 | ||
301 | return ret; | 303 | return ret; |
302 | } | 304 | } |
305 | |||
306 | void cx18_dvb_work_handler(struct cx18 *cx) | ||
307 | { | ||
308 | struct cx18_buffer *buf; | ||
309 | struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_TS]; | ||
310 | |||
311 | while ((buf = cx18_dequeue(s, &s->q_full)) != NULL) { | ||
312 | if (s->dvb.enabled) | ||
313 | dvb_dmx_swfilter(&s->dvb.demux, buf->buf, | ||
314 | buf->bytesused); | ||
315 | |||
316 | cx18_enqueue(s, buf, &s->q_free); | ||
317 | cx18_buf_sync_for_device(s, buf); | ||
318 | if (s->handle == CX18_INVALID_TASK_HANDLE) /* FIXME: improve */ | ||
319 | continue; | ||
320 | |||
321 | cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, | ||
322 | (void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, | ||
323 | 1, buf->id, s->buf_size); | ||
324 | } | ||
325 | } | ||
diff --git a/drivers/media/video/cx18/cx18-dvb.h b/drivers/media/video/cx18/cx18-dvb.h index bf8d8f6f5455..bbdcefc87f28 100644 --- a/drivers/media/video/cx18/cx18-dvb.h +++ b/drivers/media/video/cx18/cx18-dvb.h | |||
@@ -23,3 +23,4 @@ | |||
23 | 23 | ||
24 | int cx18_dvb_register(struct cx18_stream *stream); | 24 | int cx18_dvb_register(struct cx18_stream *stream); |
25 | void cx18_dvb_unregister(struct cx18_stream *stream); | 25 | void cx18_dvb_unregister(struct cx18_stream *stream); |
26 | void cx18_dvb_work_handler(struct cx18 *cx); | ||
diff --git a/drivers/media/video/cx18/cx18-io.c b/drivers/media/video/cx18/cx18-io.c index 700ab9439c16..220fae8d4ad7 100644 --- a/drivers/media/video/cx18/cx18-io.c +++ b/drivers/media/video/cx18/cx18-io.c | |||
@@ -88,6 +88,19 @@ void cx18_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr) | |||
88 | cx18_log_write_retries(cx, i, addr); | 88 | cx18_log_write_retries(cx, i, addr); |
89 | } | 89 | } |
90 | 90 | ||
91 | void _cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr, | ||
92 | u32 eval, u32 mask) | ||
93 | { | ||
94 | int i; | ||
95 | eval &= mask; | ||
96 | for (i = 0; i < CX18_MAX_MMIO_RETRIES; i++) { | ||
97 | cx18_writel_noretry(cx, val, addr); | ||
98 | if (eval == (cx18_readl_noretry(cx, addr) & mask)) | ||
99 | break; | ||
100 | } | ||
101 | cx18_log_write_retries(cx, i, addr); | ||
102 | } | ||
103 | |||
91 | void cx18_writew_retry(struct cx18 *cx, u16 val, void __iomem *addr) | 104 | void cx18_writew_retry(struct cx18 *cx, u16 val, void __iomem *addr) |
92 | { | 105 | { |
93 | int i; | 106 | int i; |
@@ -218,7 +231,7 @@ void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count) | |||
218 | void cx18_sw1_irq_enable(struct cx18 *cx, u32 val) | 231 | void cx18_sw1_irq_enable(struct cx18 *cx, u32 val) |
219 | { | 232 | { |
220 | u32 r; | 233 | u32 r; |
221 | cx18_write_reg(cx, val, SW1_INT_STATUS); | 234 | cx18_write_reg_expect(cx, val, SW1_INT_STATUS, ~val, val); |
222 | r = cx18_read_reg(cx, SW1_INT_ENABLE_PCI); | 235 | r = cx18_read_reg(cx, SW1_INT_ENABLE_PCI); |
223 | cx18_write_reg(cx, r | val, SW1_INT_ENABLE_PCI); | 236 | cx18_write_reg(cx, r | val, SW1_INT_ENABLE_PCI); |
224 | } | 237 | } |
@@ -233,7 +246,7 @@ void cx18_sw1_irq_disable(struct cx18 *cx, u32 val) | |||
233 | void cx18_sw2_irq_enable(struct cx18 *cx, u32 val) | 246 | void cx18_sw2_irq_enable(struct cx18 *cx, u32 val) |
234 | { | 247 | { |
235 | u32 r; | 248 | u32 r; |
236 | cx18_write_reg(cx, val, SW2_INT_STATUS); | 249 | cx18_write_reg_expect(cx, val, SW2_INT_STATUS, ~val, val); |
237 | r = cx18_read_reg(cx, SW2_INT_ENABLE_PCI); | 250 | r = cx18_read_reg(cx, SW2_INT_ENABLE_PCI); |
238 | cx18_write_reg(cx, r | val, SW2_INT_ENABLE_PCI); | 251 | cx18_write_reg(cx, r | val, SW2_INT_ENABLE_PCI); |
239 | } | 252 | } |
diff --git a/drivers/media/video/cx18/cx18-io.h b/drivers/media/video/cx18/cx18-io.h index 287a5e8bf67b..425244453ea7 100644 --- a/drivers/media/video/cx18/cx18-io.h +++ b/drivers/media/video/cx18/cx18-io.h | |||
@@ -133,6 +133,8 @@ static inline void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr) | |||
133 | cx18_writel_noretry(cx, val, addr); | 133 | cx18_writel_noretry(cx, val, addr); |
134 | } | 134 | } |
135 | 135 | ||
136 | void _cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr, | ||
137 | u32 eval, u32 mask); | ||
136 | 138 | ||
137 | static inline | 139 | static inline |
138 | void cx18_writew_noretry(struct cx18 *cx, u16 val, void __iomem *addr) | 140 | void cx18_writew_noretry(struct cx18 *cx, u16 val, void __iomem *addr) |
@@ -271,6 +273,21 @@ static inline void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg) | |||
271 | cx18_write_reg_noretry(cx, val, reg); | 273 | cx18_write_reg_noretry(cx, val, reg); |
272 | } | 274 | } |
273 | 275 | ||
276 | static inline void _cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg, | ||
277 | u32 eval, u32 mask) | ||
278 | { | ||
279 | _cx18_writel_expect(cx, val, cx->reg_mem + reg, eval, mask); | ||
280 | } | ||
281 | |||
282 | static inline void cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg, | ||
283 | u32 eval, u32 mask) | ||
284 | { | ||
285 | if (cx18_retry_mmio) | ||
286 | _cx18_write_reg_expect(cx, val, reg, eval, mask); | ||
287 | else | ||
288 | cx18_write_reg_noretry(cx, val, reg); | ||
289 | } | ||
290 | |||
274 | 291 | ||
275 | static inline u32 cx18_read_reg_noretry(struct cx18 *cx, u32 reg) | 292 | static inline u32 cx18_read_reg_noretry(struct cx18 *cx, u32 reg) |
276 | { | 293 | { |
diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/video/cx18/cx18-irq.c index 360330f5463f..5fbfbd0f1493 100644 --- a/drivers/media/video/cx18/cx18-irq.c +++ b/drivers/media/video/cx18/cx18-irq.c | |||
@@ -29,8 +29,20 @@ | |||
29 | #include "cx18-mailbox.h" | 29 | #include "cx18-mailbox.h" |
30 | #include "cx18-vbi.h" | 30 | #include "cx18-vbi.h" |
31 | #include "cx18-scb.h" | 31 | #include "cx18-scb.h" |
32 | #include "cx18-dvb.h" | ||
32 | 33 | ||
33 | #define DMA_MAGIC_COOKIE 0x000001fe | 34 | void cx18_work_handler(struct work_struct *work) |
35 | { | ||
36 | struct cx18 *cx = container_of(work, struct cx18, work); | ||
37 | if (test_and_clear_bit(CX18_F_I_WORK_INITED, &cx->i_flags)) { | ||
38 | struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; | ||
39 | /* This thread must use the FIFO scheduler as it | ||
40 | * is realtime sensitive. */ | ||
41 | sched_setscheduler(current, SCHED_FIFO, ¶m); | ||
42 | } | ||
43 | if (test_and_clear_bit(CX18_F_I_WORK_HANDLER_DVB, &cx->i_flags)) | ||
44 | cx18_dvb_work_handler(cx); | ||
45 | } | ||
34 | 46 | ||
35 | static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) | 47 | static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) |
36 | { | 48 | { |
@@ -67,17 +79,11 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) | |||
67 | if (buf) { | 79 | if (buf) { |
68 | cx18_buf_sync_for_cpu(s, buf); | 80 | cx18_buf_sync_for_cpu(s, buf); |
69 | if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) { | 81 | if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) { |
70 | /* process the buffer here */ | 82 | CX18_DEBUG_HI_DMA("TS recv bytesused = %d\n", |
71 | CX18_DEBUG_HI_DMA("TS recv and sent bytesused=%d\n", | ||
72 | buf->bytesused); | ||
73 | |||
74 | dvb_dmx_swfilter(&s->dvb.demux, buf->buf, | ||
75 | buf->bytesused); | 83 | buf->bytesused); |
76 | 84 | ||
77 | cx18_buf_sync_for_device(s, buf); | 85 | set_bit(CX18_F_I_WORK_HANDLER_DVB, &cx->i_flags); |
78 | cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, | 86 | set_bit(CX18_F_I_HAVE_WORK, &cx->i_flags); |
79 | (void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, | ||
80 | 1, buf->id, s->buf_size); | ||
81 | } else | 87 | } else |
82 | set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags); | 88 | set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags); |
83 | } else { | 89 | } else { |
@@ -109,7 +115,7 @@ static void epu_debug(struct cx18 *cx, struct cx18_mailbox *mb) | |||
109 | CX18_INFO("FW version: %s\n", p - 1); | 115 | CX18_INFO("FW version: %s\n", p - 1); |
110 | } | 116 | } |
111 | 117 | ||
112 | static void hpu_cmd(struct cx18 *cx, u32 sw1) | 118 | static void epu_cmd(struct cx18 *cx, u32 sw1) |
113 | { | 119 | { |
114 | struct cx18_mailbox mb; | 120 | struct cx18_mailbox mb; |
115 | 121 | ||
@@ -125,12 +131,31 @@ static void hpu_cmd(struct cx18 *cx, u32 sw1) | |||
125 | epu_debug(cx, &mb); | 131 | epu_debug(cx, &mb); |
126 | break; | 132 | break; |
127 | default: | 133 | default: |
128 | CX18_WARN("Unexpected mailbox command %08x\n", mb.cmd); | 134 | CX18_WARN("Unknown CPU_TO_EPU mailbox command %#08x\n", |
135 | mb.cmd); | ||
129 | break; | 136 | break; |
130 | } | 137 | } |
131 | } | 138 | } |
132 | if (sw1 & (IRQ_APU_TO_EPU | IRQ_HPU_TO_EPU)) | 139 | |
133 | CX18_WARN("Unexpected interrupt %08x\n", sw1); | 140 | if (sw1 & IRQ_APU_TO_EPU) { |
141 | cx18_memcpy_fromio(cx, &mb, &cx->scb->apu2epu_mb, sizeof(mb)); | ||
142 | CX18_WARN("Unknown APU_TO_EPU mailbox command %#08x\n", mb.cmd); | ||
143 | } | ||
144 | |||
145 | if (sw1 & IRQ_HPU_TO_EPU) { | ||
146 | cx18_memcpy_fromio(cx, &mb, &cx->scb->hpu2epu_mb, sizeof(mb)); | ||
147 | CX18_WARN("Unknown HPU_TO_EPU mailbox command %#08x\n", mb.cmd); | ||
148 | } | ||
149 | } | ||
150 | |||
151 | static void xpu_ack(struct cx18 *cx, u32 sw2) | ||
152 | { | ||
153 | if (sw2 & IRQ_CPU_TO_EPU_ACK) | ||
154 | wake_up(&cx->mb_cpu_waitq); | ||
155 | if (sw2 & IRQ_APU_TO_EPU_ACK) | ||
156 | wake_up(&cx->mb_apu_waitq); | ||
157 | if (sw2 & IRQ_HPU_TO_EPU_ACK) | ||
158 | wake_up(&cx->mb_hpu_waitq); | ||
134 | } | 159 | } |
135 | 160 | ||
136 | irqreturn_t cx18_irq_handler(int irq, void *dev_id) | 161 | irqreturn_t cx18_irq_handler(int irq, void *dev_id) |
@@ -140,43 +165,36 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id) | |||
140 | u32 sw2, sw2_mask; | 165 | u32 sw2, sw2_mask; |
141 | u32 hw2, hw2_mask; | 166 | u32 hw2, hw2_mask; |
142 | 167 | ||
143 | spin_lock(&cx->dma_reg_lock); | 168 | sw1_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI); |
144 | 169 | sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & sw1_mask; | |
170 | sw2_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI); | ||
171 | sw2 = cx18_read_reg(cx, SW2_INT_STATUS) & sw2_mask; | ||
145 | hw2_mask = cx18_read_reg(cx, HW2_INT_MASK5_PCI); | 172 | hw2_mask = cx18_read_reg(cx, HW2_INT_MASK5_PCI); |
146 | hw2 = cx18_read_reg(cx, HW2_INT_CLR_STATUS) & hw2_mask; | 173 | hw2 = cx18_read_reg(cx, HW2_INT_CLR_STATUS) & hw2_mask; |
147 | sw2_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU_ACK; | ||
148 | sw2 = cx18_read_reg(cx, SW2_INT_STATUS) & sw2_mask; | ||
149 | sw1_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI) | IRQ_EPU_TO_HPU; | ||
150 | sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & sw1_mask; | ||
151 | 174 | ||
152 | cx18_write_reg(cx, sw2&sw2_mask, SW2_INT_STATUS); | 175 | if (sw1) |
153 | cx18_write_reg(cx, sw1&sw1_mask, SW1_INT_STATUS); | 176 | cx18_write_reg_expect(cx, sw1, SW1_INT_STATUS, ~sw1, sw1); |
154 | cx18_write_reg(cx, hw2&hw2_mask, HW2_INT_CLR_STATUS); | 177 | if (sw2) |
178 | cx18_write_reg_expect(cx, sw2, SW2_INT_STATUS, ~sw2, sw2); | ||
179 | if (hw2) | ||
180 | cx18_write_reg_expect(cx, hw2, HW2_INT_CLR_STATUS, ~hw2, hw2); | ||
155 | 181 | ||
156 | if (sw1 || sw2 || hw2) | 182 | if (sw1 || sw2 || hw2) |
157 | CX18_DEBUG_HI_IRQ("SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2); | 183 | CX18_DEBUG_HI_IRQ("SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2); |
158 | 184 | ||
159 | /* To do: interrupt-based I2C handling | 185 | /* To do: interrupt-based I2C handling |
160 | if (hw2 & 0x00c00000) { | 186 | if (hw2 & (HW2_I2C1_INT|HW2_I2C2_INT)) { |
161 | } | 187 | } |
162 | */ | 188 | */ |
163 | 189 | ||
164 | if (sw2) { | 190 | if (sw2) |
165 | if (sw2 & (cx18_readl(cx, &cx->scb->cpu2hpu_irq_ack) | | 191 | xpu_ack(cx, sw2); |
166 | cx18_readl(cx, &cx->scb->cpu2epu_irq_ack))) | ||
167 | wake_up(&cx->mb_cpu_waitq); | ||
168 | if (sw2 & (cx18_readl(cx, &cx->scb->apu2hpu_irq_ack) | | ||
169 | cx18_readl(cx, &cx->scb->apu2epu_irq_ack))) | ||
170 | wake_up(&cx->mb_apu_waitq); | ||
171 | if (sw2 & cx18_readl(cx, &cx->scb->epu2hpu_irq_ack)) | ||
172 | wake_up(&cx->mb_epu_waitq); | ||
173 | if (sw2 & cx18_readl(cx, &cx->scb->hpu2epu_irq_ack)) | ||
174 | wake_up(&cx->mb_hpu_waitq); | ||
175 | } | ||
176 | 192 | ||
177 | if (sw1) | 193 | if (sw1) |
178 | hpu_cmd(cx, sw1); | 194 | epu_cmd(cx, sw1); |
179 | spin_unlock(&cx->dma_reg_lock); | 195 | |
196 | if (test_and_clear_bit(CX18_F_I_HAVE_WORK, &cx->i_flags)) | ||
197 | queue_work(cx->work_queue, &cx->work); | ||
180 | 198 | ||
181 | return (hw2 | sw1 | sw2) ? IRQ_HANDLED : IRQ_NONE; | 199 | return (sw1 || sw2 || hw2) ? IRQ_HANDLED : IRQ_NONE; |
182 | } | 200 | } |
diff --git a/drivers/media/video/cx18/cx18-irq.h b/drivers/media/video/cx18/cx18-irq.h index 379f704f5cba..6173ca3bc9e4 100644 --- a/drivers/media/video/cx18/cx18-irq.h +++ b/drivers/media/video/cx18/cx18-irq.h | |||
@@ -32,6 +32,4 @@ | |||
32 | 32 | ||
33 | irqreturn_t cx18_irq_handler(int irq, void *dev_id); | 33 | irqreturn_t cx18_irq_handler(int irq, void *dev_id); |
34 | 34 | ||
35 | void cx18_irq_work_handler(struct work_struct *work); | 35 | void cx18_work_handler(struct work_struct *work); |
36 | void cx18_dma_stream_dec_prepare(struct cx18_stream *s, u32 offset, int lock); | ||
37 | void cx18_unfinished_dma(unsigned long arg); | ||
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c index 9d18dd22de76..acff7dfb60df 100644 --- a/drivers/media/video/cx18/cx18-mailbox.c +++ b/drivers/media/video/cx18/cx18-mailbox.c | |||
@@ -83,7 +83,7 @@ static const struct cx18_api_info api_info[] = { | |||
83 | API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0), | 83 | API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0), |
84 | API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST), | 84 | API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST), |
85 | API_ENTRY(CPU, CX18_APU_RESETAI, API_FAST), | 85 | API_ENTRY(CPU, CX18_APU_RESETAI, API_FAST), |
86 | API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, 0), | 86 | API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW), |
87 | API_ENTRY(0, 0, 0), | 87 | API_ENTRY(0, 0, 0), |
88 | }; | 88 | }; |
89 | 89 | ||
@@ -176,7 +176,7 @@ long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb) | |||
176 | 176 | ||
177 | cx18_setup_page(cx, SCB_OFFSET); | 177 | cx18_setup_page(cx, SCB_OFFSET); |
178 | cx18_write_sync(cx, mb->request, &ack_mb->ack); | 178 | cx18_write_sync(cx, mb->request, &ack_mb->ack); |
179 | cx18_write_reg(cx, ack_irq, SW2_INT_SET); | 179 | cx18_write_reg_expect(cx, ack_irq, SW2_INT_SET, ack_irq, ack_irq); |
180 | return 0; | 180 | return 0; |
181 | } | 181 | } |
182 | 182 | ||
@@ -225,7 +225,7 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) | |||
225 | } | 225 | } |
226 | if (info->flags & API_FAST) | 226 | if (info->flags & API_FAST) |
227 | timeout /= 2; | 227 | timeout /= 2; |
228 | cx18_write_reg(cx, irq, SW1_INT_SET); | 228 | cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq); |
229 | 229 | ||
230 | while (!sig && cx18_readl(cx, &mb->ack) != cx18_readl(cx, &mb->request) | 230 | while (!sig && cx18_readl(cx, &mb->ack) != cx18_readl(cx, &mb->request) |
231 | && cnt < 660) { | 231 | && cnt < 660) { |
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c index a33ba04a2686..174682c2582f 100644 --- a/drivers/media/video/cx18/cx18-queue.c +++ b/drivers/media/video/cx18/cx18-queue.c | |||
@@ -88,15 +88,13 @@ struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, | |||
88 | 88 | ||
89 | if (buf->id != id) | 89 | if (buf->id != id) |
90 | continue; | 90 | continue; |
91 | |||
91 | buf->bytesused = bytesused; | 92 | buf->bytesused = bytesused; |
92 | /* the transport buffers are handled differently, | 93 | atomic_dec(&s->q_free.buffers); |
93 | they are not moved to the full queue */ | 94 | atomic_inc(&s->q_full.buffers); |
94 | if (s->type != CX18_ENC_STREAM_TYPE_TS) { | 95 | s->q_full.bytesused += buf->bytesused; |
95 | atomic_dec(&s->q_free.buffers); | 96 | list_move_tail(&buf->list, &s->q_full.list); |
96 | atomic_inc(&s->q_full.buffers); | 97 | |
97 | s->q_full.bytesused += buf->bytesused; | ||
98 | list_move_tail(&buf->list, &s->q_full.list); | ||
99 | } | ||
100 | spin_unlock(&s->qlock); | 98 | spin_unlock(&s->qlock); |
101 | return buf; | 99 | return buf; |
102 | } | 100 | } |
diff --git a/drivers/media/video/cx18/cx18-scb.h b/drivers/media/video/cx18/cx18-scb.h index 86b4cb15d163..594713bbed68 100644 --- a/drivers/media/video/cx18/cx18-scb.h +++ b/drivers/media/video/cx18/cx18-scb.h | |||
@@ -128,22 +128,22 @@ struct cx18_scb { | |||
128 | u32 apu2cpu_irq; | 128 | u32 apu2cpu_irq; |
129 | /* Value to write to register SW2 register set (0xC7003140) after the | 129 | /* Value to write to register SW2 register set (0xC7003140) after the |
130 | command is cleared */ | 130 | command is cleared */ |
131 | u32 apu2cpu_irq_ack; | 131 | u32 cpu2apu_irq_ack; |
132 | u32 reserved2[13]; | 132 | u32 reserved2[13]; |
133 | 133 | ||
134 | u32 hpu2cpu_mb_offset; | 134 | u32 hpu2cpu_mb_offset; |
135 | u32 hpu2cpu_irq; | 135 | u32 hpu2cpu_irq; |
136 | u32 hpu2cpu_irq_ack; | 136 | u32 cpu2hpu_irq_ack; |
137 | u32 reserved3[13]; | 137 | u32 reserved3[13]; |
138 | 138 | ||
139 | u32 ppu2cpu_mb_offset; | 139 | u32 ppu2cpu_mb_offset; |
140 | u32 ppu2cpu_irq; | 140 | u32 ppu2cpu_irq; |
141 | u32 ppu2cpu_irq_ack; | 141 | u32 cpu2ppu_irq_ack; |
142 | u32 reserved4[13]; | 142 | u32 reserved4[13]; |
143 | 143 | ||
144 | u32 epu2cpu_mb_offset; | 144 | u32 epu2cpu_mb_offset; |
145 | u32 epu2cpu_irq; | 145 | u32 epu2cpu_irq; |
146 | u32 epu2cpu_irq_ack; | 146 | u32 cpu2epu_irq_ack; |
147 | u32 reserved5[13]; | 147 | u32 reserved5[13]; |
148 | u32 reserved6[8]; | 148 | u32 reserved6[8]; |
149 | 149 | ||
@@ -153,22 +153,22 @@ struct cx18_scb { | |||
153 | u32 reserved11[7]; | 153 | u32 reserved11[7]; |
154 | u32 cpu2apu_mb_offset; | 154 | u32 cpu2apu_mb_offset; |
155 | u32 cpu2apu_irq; | 155 | u32 cpu2apu_irq; |
156 | u32 cpu2apu_irq_ack; | 156 | u32 apu2cpu_irq_ack; |
157 | u32 reserved12[13]; | 157 | u32 reserved12[13]; |
158 | 158 | ||
159 | u32 hpu2apu_mb_offset; | 159 | u32 hpu2apu_mb_offset; |
160 | u32 hpu2apu_irq; | 160 | u32 hpu2apu_irq; |
161 | u32 hpu2apu_irq_ack; | 161 | u32 apu2hpu_irq_ack; |
162 | u32 reserved13[13]; | 162 | u32 reserved13[13]; |
163 | 163 | ||
164 | u32 ppu2apu_mb_offset; | 164 | u32 ppu2apu_mb_offset; |
165 | u32 ppu2apu_irq; | 165 | u32 ppu2apu_irq; |
166 | u32 ppu2apu_irq_ack; | 166 | u32 apu2ppu_irq_ack; |
167 | u32 reserved14[13]; | 167 | u32 reserved14[13]; |
168 | 168 | ||
169 | u32 epu2apu_mb_offset; | 169 | u32 epu2apu_mb_offset; |
170 | u32 epu2apu_irq; | 170 | u32 epu2apu_irq; |
171 | u32 epu2apu_irq_ack; | 171 | u32 apu2epu_irq_ack; |
172 | u32 reserved15[13]; | 172 | u32 reserved15[13]; |
173 | u32 reserved16[8]; | 173 | u32 reserved16[8]; |
174 | 174 | ||
@@ -178,22 +178,22 @@ struct cx18_scb { | |||
178 | u32 reserved21[7]; | 178 | u32 reserved21[7]; |
179 | u32 cpu2hpu_mb_offset; | 179 | u32 cpu2hpu_mb_offset; |
180 | u32 cpu2hpu_irq; | 180 | u32 cpu2hpu_irq; |
181 | u32 cpu2hpu_irq_ack; | 181 | u32 hpu2cpu_irq_ack; |
182 | u32 reserved22[13]; | 182 | u32 reserved22[13]; |
183 | 183 | ||
184 | u32 apu2hpu_mb_offset; | 184 | u32 apu2hpu_mb_offset; |
185 | u32 apu2hpu_irq; | 185 | u32 apu2hpu_irq; |
186 | u32 apu2hpu_irq_ack; | 186 | u32 hpu2apu_irq_ack; |
187 | u32 reserved23[13]; | 187 | u32 reserved23[13]; |
188 | 188 | ||
189 | u32 ppu2hpu_mb_offset; | 189 | u32 ppu2hpu_mb_offset; |
190 | u32 ppu2hpu_irq; | 190 | u32 ppu2hpu_irq; |
191 | u32 ppu2hpu_irq_ack; | 191 | u32 hpu2ppu_irq_ack; |
192 | u32 reserved24[13]; | 192 | u32 reserved24[13]; |
193 | 193 | ||
194 | u32 epu2hpu_mb_offset; | 194 | u32 epu2hpu_mb_offset; |
195 | u32 epu2hpu_irq; | 195 | u32 epu2hpu_irq; |
196 | u32 epu2hpu_irq_ack; | 196 | u32 hpu2epu_irq_ack; |
197 | u32 reserved25[13]; | 197 | u32 reserved25[13]; |
198 | u32 reserved26[8]; | 198 | u32 reserved26[8]; |
199 | 199 | ||
@@ -203,22 +203,22 @@ struct cx18_scb { | |||
203 | u32 reserved31[7]; | 203 | u32 reserved31[7]; |
204 | u32 cpu2ppu_mb_offset; | 204 | u32 cpu2ppu_mb_offset; |
205 | u32 cpu2ppu_irq; | 205 | u32 cpu2ppu_irq; |
206 | u32 cpu2ppu_irq_ack; | 206 | u32 ppu2cpu_irq_ack; |
207 | u32 reserved32[13]; | 207 | u32 reserved32[13]; |
208 | 208 | ||
209 | u32 apu2ppu_mb_offset; | 209 | u32 apu2ppu_mb_offset; |
210 | u32 apu2ppu_irq; | 210 | u32 apu2ppu_irq; |
211 | u32 apu2ppu_irq_ack; | 211 | u32 ppu2apu_irq_ack; |
212 | u32 reserved33[13]; | 212 | u32 reserved33[13]; |
213 | 213 | ||
214 | u32 hpu2ppu_mb_offset; | 214 | u32 hpu2ppu_mb_offset; |
215 | u32 hpu2ppu_irq; | 215 | u32 hpu2ppu_irq; |
216 | u32 hpu2ppu_irq_ack; | 216 | u32 ppu2hpu_irq_ack; |
217 | u32 reserved34[13]; | 217 | u32 reserved34[13]; |
218 | 218 | ||
219 | u32 epu2ppu_mb_offset; | 219 | u32 epu2ppu_mb_offset; |
220 | u32 epu2ppu_irq; | 220 | u32 epu2ppu_irq; |
221 | u32 epu2ppu_irq_ack; | 221 | u32 ppu2epu_irq_ack; |
222 | u32 reserved35[13]; | 222 | u32 reserved35[13]; |
223 | u32 reserved36[8]; | 223 | u32 reserved36[8]; |
224 | 224 | ||
@@ -228,22 +228,22 @@ struct cx18_scb { | |||
228 | u32 reserved41[7]; | 228 | u32 reserved41[7]; |
229 | u32 cpu2epu_mb_offset; | 229 | u32 cpu2epu_mb_offset; |
230 | u32 cpu2epu_irq; | 230 | u32 cpu2epu_irq; |
231 | u32 cpu2epu_irq_ack; | 231 | u32 epu2cpu_irq_ack; |
232 | u32 reserved42[13]; | 232 | u32 reserved42[13]; |
233 | 233 | ||
234 | u32 apu2epu_mb_offset; | 234 | u32 apu2epu_mb_offset; |
235 | u32 apu2epu_irq; | 235 | u32 apu2epu_irq; |
236 | u32 apu2epu_irq_ack; | 236 | u32 epu2apu_irq_ack; |
237 | u32 reserved43[13]; | 237 | u32 reserved43[13]; |
238 | 238 | ||
239 | u32 hpu2epu_mb_offset; | 239 | u32 hpu2epu_mb_offset; |
240 | u32 hpu2epu_irq; | 240 | u32 hpu2epu_irq; |
241 | u32 hpu2epu_irq_ack; | 241 | u32 epu2hpu_irq_ack; |
242 | u32 reserved44[13]; | 242 | u32 reserved44[13]; |
243 | 243 | ||
244 | u32 ppu2epu_mb_offset; | 244 | u32 ppu2epu_mb_offset; |
245 | u32 ppu2epu_irq; | 245 | u32 ppu2epu_irq; |
246 | u32 ppu2epu_irq_ack; | 246 | u32 epu2ppu_irq_ack; |
247 | u32 reserved45[13]; | 247 | u32 reserved45[13]; |
248 | u32 reserved46[8]; | 248 | u32 reserved46[8]; |
249 | 249 | ||
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 078be6319556..d3ae5b4dfca7 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c | |||
@@ -1078,7 +1078,7 @@ static int mpeg_open(struct inode *inode, struct file *file) | |||
1078 | } | 1078 | } |
1079 | } | 1079 | } |
1080 | 1080 | ||
1081 | if (blackbird_initialize_codec(dev) < 0) { | 1081 | if (!atomic_read(&dev->core->mpeg_users) && blackbird_initialize_codec(dev) < 0) { |
1082 | if (drv) | 1082 | if (drv) |
1083 | drv->request_release(drv); | 1083 | drv->request_release(drv); |
1084 | unlock_kernel(); | 1084 | unlock_kernel(); |
@@ -1109,6 +1109,8 @@ static int mpeg_open(struct inode *inode, struct file *file) | |||
1109 | fh->mpegq.field); | 1109 | fh->mpegq.field); |
1110 | unlock_kernel(); | 1110 | unlock_kernel(); |
1111 | 1111 | ||
1112 | atomic_inc(&dev->core->mpeg_users); | ||
1113 | |||
1112 | return 0; | 1114 | return 0; |
1113 | } | 1115 | } |
1114 | 1116 | ||
@@ -1118,7 +1120,7 @@ static int mpeg_release(struct inode *inode, struct file *file) | |||
1118 | struct cx8802_dev *dev = fh->dev; | 1120 | struct cx8802_dev *dev = fh->dev; |
1119 | struct cx8802_driver *drv = NULL; | 1121 | struct cx8802_driver *drv = NULL; |
1120 | 1122 | ||
1121 | if (dev->mpeg_active) | 1123 | if (dev->mpeg_active && atomic_read(&dev->core->mpeg_users) == 1) |
1122 | blackbird_stop_codec(dev); | 1124 | blackbird_stop_codec(dev); |
1123 | 1125 | ||
1124 | cx8802_cancel_buffers(fh->dev); | 1126 | cx8802_cancel_buffers(fh->dev); |
@@ -1138,6 +1140,8 @@ static int mpeg_release(struct inode *inode, struct file *file) | |||
1138 | if (drv) | 1140 | if (drv) |
1139 | drv->request_release(drv); | 1141 | drv->request_release(drv); |
1140 | 1142 | ||
1143 | atomic_dec(&dev->core->mpeg_users); | ||
1144 | |||
1141 | return 0; | 1145 | return 0; |
1142 | } | 1146 | } |
1143 | 1147 | ||
@@ -1158,6 +1162,10 @@ static unsigned int | |||
1158 | mpeg_poll(struct file *file, struct poll_table_struct *wait) | 1162 | mpeg_poll(struct file *file, struct poll_table_struct *wait) |
1159 | { | 1163 | { |
1160 | struct cx8802_fh *fh = file->private_data; | 1164 | struct cx8802_fh *fh = file->private_data; |
1165 | struct cx8802_dev *dev = fh->dev; | ||
1166 | |||
1167 | if (!dev->mpeg_active) | ||
1168 | blackbird_start_codec(file, fh); | ||
1161 | 1169 | ||
1162 | return videobuf_poll_stream(file, &fh->mpegq, wait); | 1170 | return videobuf_poll_stream(file, &fh->mpegq, wait); |
1163 | } | 1171 | } |
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index cf6c30d4e545..309ca5e68063 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
@@ -598,6 +598,11 @@ static int dvb_register(struct cx8802_dev *dev) | |||
598 | struct videobuf_dvb_frontend *fe0, *fe1 = NULL; | 598 | struct videobuf_dvb_frontend *fe0, *fe1 = NULL; |
599 | int mfe_shared = 0; /* bus not shared by default */ | 599 | int mfe_shared = 0; /* bus not shared by default */ |
600 | 600 | ||
601 | if (0 != core->i2c_rc) { | ||
602 | printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name); | ||
603 | goto frontend_detach; | ||
604 | } | ||
605 | |||
601 | /* Get the first frontend */ | 606 | /* Get the first frontend */ |
602 | fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); | 607 | fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); |
603 | if (!fe0) | 608 | if (!fe0) |
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index a1c435b4b1cd..3ebdcd1d83f8 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c | |||
@@ -769,10 +769,6 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev, | |||
769 | struct cx8802_dev *dev; | 769 | struct cx8802_dev *dev; |
770 | struct cx88_core *core; | 770 | struct cx88_core *core; |
771 | int err; | 771 | int err; |
772 | #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) | ||
773 | struct videobuf_dvb_frontend *demod; | ||
774 | int i; | ||
775 | #endif | ||
776 | 772 | ||
777 | /* general setup */ | 773 | /* general setup */ |
778 | core = cx88_core_get(pci_dev); | 774 | core = cx88_core_get(pci_dev); |
@@ -803,15 +799,21 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev, | |||
803 | mutex_init(&dev->frontends.lock); | 799 | mutex_init(&dev->frontends.lock); |
804 | INIT_LIST_HEAD(&dev->frontends.felist); | 800 | INIT_LIST_HEAD(&dev->frontends.felist); |
805 | 801 | ||
806 | if (core->board.num_frontends) | 802 | if (core->board.num_frontends) { |
807 | printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, core->board.num_frontends); | 803 | struct videobuf_dvb_frontend *fe; |
808 | 804 | int i; | |
809 | for (i = 1; i <= core->board.num_frontends; i++) { | 805 | |
810 | demod = videobuf_dvb_alloc_frontend(&dev->frontends, i); | 806 | printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, |
811 | if(demod == NULL) { | 807 | core->board.num_frontends); |
812 | printk(KERN_ERR "%s() failed to alloc\n", __func__); | 808 | for (i = 1; i <= core->board.num_frontends; i++) { |
813 | err = -ENOMEM; | 809 | fe = videobuf_dvb_alloc_frontend(&dev->frontends, i); |
814 | goto fail_free; | 810 | if(fe == NULL) { |
811 | printk(KERN_ERR "%s() failed to alloc\n", | ||
812 | __func__); | ||
813 | videobuf_dvb_dealloc_frontends(&dev->frontends); | ||
814 | err = -ENOMEM; | ||
815 | goto fail_free; | ||
816 | } | ||
815 | } | 817 | } |
816 | } | 818 | } |
817 | #endif | 819 | #endif |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 61265fd04d56..b96ce991d968 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -1216,8 +1216,12 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) | |||
1216 | struct cx8800_fh *fh = priv; | 1216 | struct cx8800_fh *fh = priv; |
1217 | struct cx8800_dev *dev = fh->dev; | 1217 | struct cx8800_dev *dev = fh->dev; |
1218 | 1218 | ||
1219 | if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) | 1219 | /* We should remember that this driver also supports teletext, */ |
1220 | /* so we have to test if the v4l2_buf_type is VBI capture data. */ | ||
1221 | if (unlikely((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && | ||
1222 | (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE))) | ||
1220 | return -EINVAL; | 1223 | return -EINVAL; |
1224 | |||
1221 | if (unlikely(i != fh->type)) | 1225 | if (unlikely(i != fh->type)) |
1222 | return -EINVAL; | 1226 | return -EINVAL; |
1223 | 1227 | ||
@@ -1232,8 +1236,10 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) | |||
1232 | struct cx8800_dev *dev = fh->dev; | 1236 | struct cx8800_dev *dev = fh->dev; |
1233 | int err, res; | 1237 | int err, res; |
1234 | 1238 | ||
1235 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1239 | if ((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && |
1240 | (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE)) | ||
1236 | return -EINVAL; | 1241 | return -EINVAL; |
1242 | |||
1237 | if (i != fh->type) | 1243 | if (i != fh->type) |
1238 | return -EINVAL; | 1244 | return -EINVAL; |
1239 | 1245 | ||
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 76207c2856b7..f4240965be32 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -352,6 +352,7 @@ struct cx88_core { | |||
352 | /* various v4l controls */ | 352 | /* various v4l controls */ |
353 | u32 freq; | 353 | u32 freq; |
354 | atomic_t users; | 354 | atomic_t users; |
355 | atomic_t mpeg_users; | ||
355 | 356 | ||
356 | /* cx88-video needs to access cx8802 for hybrid tuner pll access. */ | 357 | /* cx88-video needs to access cx8802 for hybrid tuner pll access. */ |
357 | struct cx8802_dev *dvbdev; | 358 | struct cx8802_dev *dvbdev; |
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig index 4d0817471c9f..6b557c057fac 100644 --- a/drivers/media/video/gspca/Kconfig +++ b/drivers/media/video/gspca/Kconfig | |||
@@ -3,16 +3,16 @@ menuconfig USB_GSPCA | |||
3 | depends on VIDEO_V4L2 | 3 | depends on VIDEO_V4L2 |
4 | default m | 4 | default m |
5 | ---help--- | 5 | ---help--- |
6 | Say Y here if you want to enable selecting webcams based | 6 | Say Y here if you want to enable selecting webcams based |
7 | on the GSPCA framework. | 7 | on the GSPCA framework. |
8 | 8 | ||
9 | See <file:Documentation/video4linux/gspca.txt> for more info. | 9 | See <file:Documentation/video4linux/gspca.txt> for more info. |
10 | 10 | ||
11 | This driver uses the Video For Linux API. You must say Y or M to | 11 | This driver uses the Video For Linux API. You must say Y or M to |
12 | "Video For Linux" to use this driver. | 12 | "Video For Linux" to use this driver. |
13 | 13 | ||
14 | To compile this driver as modules, choose M here: the | 14 | To compile this driver as modules, choose M here: the |
15 | modules will be called gspca_main. | 15 | modules will be called gspca_main. |
16 | 16 | ||
17 | 17 | ||
18 | if USB_GSPCA && VIDEO_V4L2 | 18 | if USB_GSPCA && VIDEO_V4L2 |
@@ -23,190 +23,190 @@ config USB_GSPCA_CONEX | |||
23 | tristate "Conexant Camera Driver" | 23 | tristate "Conexant Camera Driver" |
24 | depends on VIDEO_V4L2 && USB_GSPCA | 24 | depends on VIDEO_V4L2 && USB_GSPCA |
25 | help | 25 | help |
26 | Say Y here if you want support for cameras based on the Conexant chip. | 26 | Say Y here if you want support for cameras based on the Conexant chip. |
27 | 27 | ||
28 | To compile this driver as a module, choose M here: the | 28 | To compile this driver as a module, choose M here: the |
29 | module will be called gspca_conex. | 29 | module will be called gspca_conex. |
30 | 30 | ||
31 | config USB_GSPCA_ETOMS | 31 | config USB_GSPCA_ETOMS |
32 | tristate "Etoms USB Camera Driver" | 32 | tristate "Etoms USB Camera Driver" |
33 | depends on VIDEO_V4L2 && USB_GSPCA | 33 | depends on VIDEO_V4L2 && USB_GSPCA |
34 | help | 34 | help |
35 | Say Y here if you want support for cameras based on the Etoms chip. | 35 | Say Y here if you want support for cameras based on the Etoms chip. |
36 | 36 | ||
37 | To compile this driver as a module, choose M here: the | 37 | To compile this driver as a module, choose M here: the |
38 | module will be called gspca_etoms. | 38 | module will be called gspca_etoms. |
39 | 39 | ||
40 | config USB_GSPCA_FINEPIX | 40 | config USB_GSPCA_FINEPIX |
41 | tristate "Fujifilm FinePix USB V4L2 driver" | 41 | tristate "Fujifilm FinePix USB V4L2 driver" |
42 | depends on VIDEO_V4L2 && USB_GSPCA | 42 | depends on VIDEO_V4L2 && USB_GSPCA |
43 | help | 43 | help |
44 | Say Y here if you want support for cameras based on the FinePix chip. | 44 | Say Y here if you want support for cameras based on the FinePix chip. |
45 | 45 | ||
46 | To compile this driver as a module, choose M here: the | 46 | To compile this driver as a module, choose M here: the |
47 | module will be called gspca_finepix. | 47 | module will be called gspca_finepix. |
48 | 48 | ||
49 | config USB_GSPCA_MARS | 49 | config USB_GSPCA_MARS |
50 | tristate "Mars USB Camera Driver" | 50 | tristate "Mars USB Camera Driver" |
51 | depends on VIDEO_V4L2 && USB_GSPCA | 51 | depends on VIDEO_V4L2 && USB_GSPCA |
52 | help | 52 | help |
53 | Say Y here if you want support for cameras based on the Mars chip. | 53 | Say Y here if you want support for cameras based on the Mars chip. |
54 | 54 | ||
55 | To compile this driver as a module, choose M here: the | 55 | To compile this driver as a module, choose M here: the |
56 | module will be called gspca_mars. | 56 | module will be called gspca_mars. |
57 | 57 | ||
58 | config USB_GSPCA_OV519 | 58 | config USB_GSPCA_OV519 |
59 | tristate "OV519 USB Camera Driver" | 59 | tristate "OV519 USB Camera Driver" |
60 | depends on VIDEO_V4L2 && USB_GSPCA | 60 | depends on VIDEO_V4L2 && USB_GSPCA |
61 | help | 61 | help |
62 | Say Y here if you want support for cameras based on the OV519 chip. | 62 | Say Y here if you want support for cameras based on the OV519 chip. |
63 | 63 | ||
64 | To compile this driver as a module, choose M here: the | 64 | To compile this driver as a module, choose M here: the |
65 | module will be called gspca_ov519. | 65 | module will be called gspca_ov519. |
66 | 66 | ||
67 | config USB_GSPCA_PAC207 | 67 | config USB_GSPCA_PAC207 |
68 | tristate "Pixart PAC207 USB Camera Driver" | 68 | tristate "Pixart PAC207 USB Camera Driver" |
69 | depends on VIDEO_V4L2 && USB_GSPCA | 69 | depends on VIDEO_V4L2 && USB_GSPCA |
70 | help | 70 | help |
71 | Say Y here if you want support for cameras based on the PAC207 chip. | 71 | Say Y here if you want support for cameras based on the PAC207 chip. |
72 | 72 | ||
73 | To compile this driver as a module, choose M here: the | 73 | To compile this driver as a module, choose M here: the |
74 | module will be called gspca_pac207. | 74 | module will be called gspca_pac207. |
75 | 75 | ||
76 | config USB_GSPCA_PAC7311 | 76 | config USB_GSPCA_PAC7311 |
77 | tristate "Pixart PAC7311 USB Camera Driver" | 77 | tristate "Pixart PAC7311 USB Camera Driver" |
78 | depends on VIDEO_V4L2 && USB_GSPCA | 78 | depends on VIDEO_V4L2 && USB_GSPCA |
79 | help | 79 | help |
80 | Say Y here if you want support for cameras based on the PAC7311 chip. | 80 | Say Y here if you want support for cameras based on the PAC7311 chip. |
81 | 81 | ||
82 | To compile this driver as a module, choose M here: the | 82 | To compile this driver as a module, choose M here: the |
83 | module will be called gspca_pac7311. | 83 | module will be called gspca_pac7311. |
84 | 84 | ||
85 | config USB_GSPCA_SONIXB | 85 | config USB_GSPCA_SONIXB |
86 | tristate "SN9C102 USB Camera Driver" | 86 | tristate "SN9C102 USB Camera Driver" |
87 | depends on VIDEO_V4L2 && USB_GSPCA | 87 | depends on VIDEO_V4L2 && USB_GSPCA |
88 | help | 88 | help |
89 | Say Y here if you want support for cameras based on the SONIXB chip. | 89 | Say Y here if you want support for cameras based on the SONIXB chip. |
90 | 90 | ||
91 | To compile this driver as a module, choose M here: the | 91 | To compile this driver as a module, choose M here: the |
92 | module will be called gspca_sonixb. | 92 | module will be called gspca_sonixb. |
93 | 93 | ||
94 | config USB_GSPCA_SONIXJ | 94 | config USB_GSPCA_SONIXJ |
95 | tristate "SONIX JPEG USB Camera Driver" | 95 | tristate "SONIX JPEG USB Camera Driver" |
96 | depends on VIDEO_V4L2 && USB_GSPCA | 96 | depends on VIDEO_V4L2 && USB_GSPCA |
97 | help | 97 | help |
98 | Say Y here if you want support for cameras based on the SONIXJ chip. | 98 | Say Y here if you want support for cameras based on the SONIXJ chip. |
99 | 99 | ||
100 | To compile this driver as a module, choose M here: the | 100 | To compile this driver as a module, choose M here: the |
101 | module will be called gspca_sonixj | 101 | module will be called gspca_sonixj |
102 | 102 | ||
103 | config USB_GSPCA_SPCA500 | 103 | config USB_GSPCA_SPCA500 |
104 | tristate "SPCA500 USB Camera Driver" | 104 | tristate "SPCA500 USB Camera Driver" |
105 | depends on VIDEO_V4L2 && USB_GSPCA | 105 | depends on VIDEO_V4L2 && USB_GSPCA |
106 | help | 106 | help |
107 | Say Y here if you want support for cameras based on the SPCA500 chip. | 107 | Say Y here if you want support for cameras based on the SPCA500 chip. |
108 | 108 | ||
109 | To compile this driver as a module, choose M here: the | 109 | To compile this driver as a module, choose M here: the |
110 | module will be called gspca_spca500. | 110 | module will be called gspca_spca500. |
111 | 111 | ||
112 | config USB_GSPCA_SPCA501 | 112 | config USB_GSPCA_SPCA501 |
113 | tristate "SPCA501 USB Camera Driver" | 113 | tristate "SPCA501 USB Camera Driver" |
114 | depends on VIDEO_V4L2 && USB_GSPCA | 114 | depends on VIDEO_V4L2 && USB_GSPCA |
115 | help | 115 | help |
116 | Say Y here if you want support for cameras based on the SPCA501 chip. | 116 | Say Y here if you want support for cameras based on the SPCA501 chip. |
117 | 117 | ||
118 | To compile this driver as a module, choose M here: the | 118 | To compile this driver as a module, choose M here: the |
119 | module will be called gspca_spca501. | 119 | module will be called gspca_spca501. |
120 | 120 | ||
121 | config USB_GSPCA_SPCA505 | 121 | config USB_GSPCA_SPCA505 |
122 | tristate "SPCA505 USB Camera Driver" | 122 | tristate "SPCA505 USB Camera Driver" |
123 | depends on VIDEO_V4L2 && USB_GSPCA | 123 | depends on VIDEO_V4L2 && USB_GSPCA |
124 | help | 124 | help |
125 | Say Y here if you want support for cameras based on the SPCA505 chip. | 125 | Say Y here if you want support for cameras based on the SPCA505 chip. |
126 | 126 | ||
127 | To compile this driver as a module, choose M here: the | 127 | To compile this driver as a module, choose M here: the |
128 | module will be called gspca_spca505. | 128 | module will be called gspca_spca505. |
129 | 129 | ||
130 | config USB_GSPCA_SPCA506 | 130 | config USB_GSPCA_SPCA506 |
131 | tristate "SPCA506 USB Camera Driver" | 131 | tristate "SPCA506 USB Camera Driver" |
132 | depends on VIDEO_V4L2 && USB_GSPCA | 132 | depends on VIDEO_V4L2 && USB_GSPCA |
133 | help | 133 | help |
134 | Say Y here if you want support for cameras based on the SPCA506 chip. | 134 | Say Y here if you want support for cameras based on the SPCA506 chip. |
135 | 135 | ||
136 | To compile this driver as a module, choose M here: the | 136 | To compile this driver as a module, choose M here: the |
137 | module will be called gspca_spca506. | 137 | module will be called gspca_spca506. |
138 | 138 | ||
139 | config USB_GSPCA_SPCA508 | 139 | config USB_GSPCA_SPCA508 |
140 | tristate "SPCA508 USB Camera Driver" | 140 | tristate "SPCA508 USB Camera Driver" |
141 | depends on VIDEO_V4L2 && USB_GSPCA | 141 | depends on VIDEO_V4L2 && USB_GSPCA |
142 | help | 142 | help |
143 | Say Y here if you want support for cameras based on the SPCA508 chip. | 143 | Say Y here if you want support for cameras based on the SPCA508 chip. |
144 | 144 | ||
145 | To compile this driver as a module, choose M here: the | 145 | To compile this driver as a module, choose M here: the |
146 | module will be called gspca_spca508. | 146 | module will be called gspca_spca508. |
147 | 147 | ||
148 | config USB_GSPCA_SPCA561 | 148 | config USB_GSPCA_SPCA561 |
149 | tristate "SPCA561 USB Camera Driver" | 149 | tristate "SPCA561 USB Camera Driver" |
150 | depends on VIDEO_V4L2 && USB_GSPCA | 150 | depends on VIDEO_V4L2 && USB_GSPCA |
151 | help | 151 | help |
152 | Say Y here if you want support for cameras based on the SPCA561 chip. | 152 | Say Y here if you want support for cameras based on the SPCA561 chip. |
153 | 153 | ||
154 | To compile this driver as a module, choose M here: the | 154 | To compile this driver as a module, choose M here: the |
155 | module will be called gspca_spca561. | 155 | module will be called gspca_spca561. |
156 | 156 | ||
157 | config USB_GSPCA_STK014 | 157 | config USB_GSPCA_STK014 |
158 | tristate "Syntek DV4000 (STK014) USB Camera Driver" | 158 | tristate "Syntek DV4000 (STK014) USB Camera Driver" |
159 | depends on VIDEO_V4L2 && USB_GSPCA | 159 | depends on VIDEO_V4L2 && USB_GSPCA |
160 | help | 160 | help |
161 | Say Y here if you want support for cameras based on the STK014 chip. | 161 | Say Y here if you want support for cameras based on the STK014 chip. |
162 | 162 | ||
163 | To compile this driver as a module, choose M here: the | 163 | To compile this driver as a module, choose M here: the |
164 | module will be called gspca_stk014. | 164 | module will be called gspca_stk014. |
165 | 165 | ||
166 | config USB_GSPCA_SUNPLUS | 166 | config USB_GSPCA_SUNPLUS |
167 | tristate "SUNPLUS USB Camera Driver" | 167 | tristate "SUNPLUS USB Camera Driver" |
168 | depends on VIDEO_V4L2 && USB_GSPCA | 168 | depends on VIDEO_V4L2 && USB_GSPCA |
169 | help | 169 | help |
170 | Say Y here if you want support for cameras based on the Sunplus | 170 | Say Y here if you want support for cameras based on the Sunplus |
171 | SPCA504(abc) SPCA533 SPCA536 chips. | 171 | SPCA504(abc) SPCA533 SPCA536 chips. |
172 | 172 | ||
173 | To compile this driver as a module, choose M here: the | 173 | To compile this driver as a module, choose M here: the |
174 | module will be called gspca_spca5xx. | 174 | module will be called gspca_spca5xx. |
175 | 175 | ||
176 | config USB_GSPCA_T613 | 176 | config USB_GSPCA_T613 |
177 | tristate "T613 (JPEG Compliance) USB Camera Driver" | 177 | tristate "T613 (JPEG Compliance) USB Camera Driver" |
178 | depends on VIDEO_V4L2 && USB_GSPCA | 178 | depends on VIDEO_V4L2 && USB_GSPCA |
179 | help | 179 | help |
180 | Say Y here if you want support for cameras based on the T613 chip. | 180 | Say Y here if you want support for cameras based on the T613 chip. |
181 | 181 | ||
182 | To compile this driver as a module, choose M here: the | 182 | To compile this driver as a module, choose M here: the |
183 | module will be called gspca_t613. | 183 | module will be called gspca_t613. |
184 | 184 | ||
185 | config USB_GSPCA_TV8532 | 185 | config USB_GSPCA_TV8532 |
186 | tristate "TV8532 USB Camera Driver" | 186 | tristate "TV8532 USB Camera Driver" |
187 | depends on VIDEO_V4L2 && USB_GSPCA | 187 | depends on VIDEO_V4L2 && USB_GSPCA |
188 | help | 188 | help |
189 | Say Y here if you want support for cameras based on the TV8531 chip. | 189 | Say Y here if you want support for cameras based on the TV8531 chip. |
190 | 190 | ||
191 | To compile this driver as a module, choose M here: the | 191 | To compile this driver as a module, choose M here: the |
192 | module will be called gspca_tv8532. | 192 | module will be called gspca_tv8532. |
193 | 193 | ||
194 | config USB_GSPCA_VC032X | 194 | config USB_GSPCA_VC032X |
195 | tristate "VC032X USB Camera Driver" | 195 | tristate "VC032X USB Camera Driver" |
196 | depends on VIDEO_V4L2 && USB_GSPCA | 196 | depends on VIDEO_V4L2 && USB_GSPCA |
197 | help | 197 | help |
198 | Say Y here if you want support for cameras based on the VC032X chip. | 198 | Say Y here if you want support for cameras based on the VC032X chip. |
199 | 199 | ||
200 | To compile this driver as a module, choose M here: the | 200 | To compile this driver as a module, choose M here: the |
201 | module will be called gspca_vc032x. | 201 | module will be called gspca_vc032x. |
202 | 202 | ||
203 | config USB_GSPCA_ZC3XX | 203 | config USB_GSPCA_ZC3XX |
204 | tristate "VC3xx USB Camera Driver" | 204 | tristate "ZC3XX USB Camera Driver" |
205 | depends on VIDEO_V4L2 && USB_GSPCA | 205 | depends on VIDEO_V4L2 && USB_GSPCA |
206 | help | 206 | help |
207 | Say Y here if you want support for cameras based on the ZC3XX chip. | 207 | Say Y here if you want support for cameras based on the ZC3XX chip. |
208 | 208 | ||
209 | To compile this driver as a module, choose M here: the | 209 | To compile this driver as a module, choose M here: the |
210 | module will be called gspca_zc3xx. | 210 | module will be called gspca_zc3xx. |
211 | 211 | ||
212 | endif | 212 | endif |
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index d0a4451dc46f..8b3101d347c3 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c | |||
@@ -2266,7 +2266,7 @@ static const struct usb_action hdcs2020b_NoFliker[] = { | |||
2266 | {} | 2266 | {} |
2267 | }; | 2267 | }; |
2268 | 2268 | ||
2269 | static const struct usb_action hv7131bxx_Initial[] = { | 2269 | static const struct usb_action hv7131bxx_Initial[] = { /* 320x240 */ |
2270 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | 2270 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, |
2271 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, | 2271 | {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, |
2272 | {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, | 2272 | {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, |
@@ -2290,7 +2290,7 @@ static const struct usb_action hv7131bxx_Initial[] = { | |||
2290 | {0xaa, 0x14, 0x0001}, | 2290 | {0xaa, 0x14, 0x0001}, |
2291 | {0xaa, 0x15, 0x00e8}, | 2291 | {0xaa, 0x15, 0x00e8}, |
2292 | {0xaa, 0x16, 0x0002}, | 2292 | {0xaa, 0x16, 0x0002}, |
2293 | {0xaa, 0x17, 0x0086}, | 2293 | {0xaa, 0x17, 0x0086}, /* 00,17,88,aa */ |
2294 | {0xaa, 0x31, 0x0038}, | 2294 | {0xaa, 0x31, 0x0038}, |
2295 | {0xaa, 0x32, 0x0038}, | 2295 | {0xaa, 0x32, 0x0038}, |
2296 | {0xaa, 0x33, 0x0038}, | 2296 | {0xaa, 0x33, 0x0038}, |
@@ -2309,7 +2309,7 @@ static const struct usb_action hv7131bxx_Initial[] = { | |||
2309 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, | 2309 | {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, |
2310 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, | 2310 | {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, |
2311 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, | 2311 | {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, |
2312 | {0xaa, 0x02, 0x0080}, /* {0xaa, 0x02, 0x0090}; */ | 2312 | {0xaa, 0x02, 0x0090}, /* 00,02,80,aa */ |
2313 | {0xa1, 0x01, 0x0002}, | 2313 | {0xa1, 0x01, 0x0002}, |
2314 | {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, | 2314 | {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, |
2315 | {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, | 2315 | {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, |
@@ -2374,7 +2374,7 @@ static const struct usb_action hv7131bxx_Initial[] = { | |||
2374 | {} | 2374 | {} |
2375 | }; | 2375 | }; |
2376 | 2376 | ||
2377 | static const struct usb_action hv7131bxx_InitialScale[] = { | 2377 | static const struct usb_action hv7131bxx_InitialScale[] = { /* 640x480*/ |
2378 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, | 2378 | {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, |
2379 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, | 2379 | {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, |
2380 | {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, | 2380 | {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, |
@@ -6388,6 +6388,8 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
6388 | /*fixme: is it really write to 011d and 018d for all other sensors? */ | 6388 | /*fixme: is it really write to 011d and 018d for all other sensors? */ |
6389 | brightness = sd->brightness; | 6389 | brightness = sd->brightness; |
6390 | reg_w(gspca_dev->dev, brightness, 0x011d); | 6390 | reg_w(gspca_dev->dev, brightness, 0x011d); |
6391 | if (sd->sensor == SENSOR_HV7131B) | ||
6392 | return; | ||
6391 | if (brightness < 0x70) | 6393 | if (brightness < 0x70) |
6392 | brightness += 0x10; | 6394 | brightness += 0x10; |
6393 | else | 6395 | else |
@@ -6529,6 +6531,7 @@ static void setquality(struct gspca_dev *gspca_dev) | |||
6529 | 6531 | ||
6530 | switch (sd->sensor) { | 6532 | switch (sd->sensor) { |
6531 | case SENSOR_GC0305: | 6533 | case SENSOR_GC0305: |
6534 | case SENSOR_HV7131B: | ||
6532 | case SENSOR_OV7620: | 6535 | case SENSOR_OV7620: |
6533 | case SENSOR_PO2030: | 6536 | case SENSOR_PO2030: |
6534 | return; | 6537 | return; |
@@ -7209,7 +7212,6 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
7209 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; | 7212 | mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; |
7210 | zc3_init = init_tb[(int) sd->sensor][mode]; | 7213 | zc3_init = init_tb[(int) sd->sensor][mode]; |
7211 | switch (sd->sensor) { | 7214 | switch (sd->sensor) { |
7212 | case SENSOR_HV7131B: | ||
7213 | case SENSOR_HV7131C: | 7215 | case SENSOR_HV7131C: |
7214 | zcxx_probeSensor(gspca_dev); | 7216 | zcxx_probeSensor(gspca_dev); |
7215 | break; | 7217 | break; |
diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig index 0069898bddab..c46bfb1569e3 100644 --- a/drivers/media/video/ivtv/Kconfig +++ b/drivers/media/video/ivtv/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config VIDEO_IVTV | 1 | config VIDEO_IVTV |
2 | tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support" | 2 | tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support" |
3 | depends on VIDEO_V4L1 && VIDEO_V4L2 && PCI && I2C && EXPERIMENTAL | 3 | depends on VIDEO_V4L2 && PCI && I2C |
4 | depends on INPUT # due to VIDEO_IR | 4 | depends on INPUT # due to VIDEO_IR |
5 | select I2C_ALGOBIT | 5 | select I2C_ALGOBIT |
6 | select VIDEO_IR | 6 | select VIDEO_IR |
@@ -12,7 +12,6 @@ config VIDEO_IVTV | |||
12 | select VIDEO_SAA711X | 12 | select VIDEO_SAA711X |
13 | select VIDEO_SAA717X | 13 | select VIDEO_SAA717X |
14 | select VIDEO_SAA7127 | 14 | select VIDEO_SAA7127 |
15 | select VIDEO_TVAUDIO | ||
16 | select VIDEO_CS53L32A | 15 | select VIDEO_CS53L32A |
17 | select VIDEO_M52790 | 16 | select VIDEO_M52790 |
18 | select VIDEO_WM8775 | 17 | select VIDEO_WM8775 |
@@ -32,7 +31,7 @@ config VIDEO_IVTV | |||
32 | 31 | ||
33 | config VIDEO_FB_IVTV | 32 | config VIDEO_FB_IVTV |
34 | tristate "Conexant cx23415 framebuffer support" | 33 | tristate "Conexant cx23415 framebuffer support" |
35 | depends on VIDEO_IVTV && FB && EXPERIMENTAL | 34 | depends on VIDEO_IVTV && FB |
36 | select FB_CFB_FILLRECT | 35 | select FB_CFB_FILLRECT |
37 | select FB_CFB_COPYAREA | 36 | select FB_CFB_COPYAREA |
38 | select FB_CFB_IMAGEBLIT | 37 | select FB_CFB_IMAGEBLIT |
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index d36485023b68..b69cc1d55e5b 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c | |||
@@ -875,43 +875,43 @@ static void ivtv_load_and_init_modules(struct ivtv *itv) | |||
875 | 875 | ||
876 | #ifdef MODULE | 876 | #ifdef MODULE |
877 | /* load modules */ | 877 | /* load modules */ |
878 | #ifndef CONFIG_MEDIA_TUNER | 878 | #ifdef CONFIG_MEDIA_TUNER_MODULE |
879 | hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER); | 879 | hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER); |
880 | #endif | 880 | #endif |
881 | #ifndef CONFIG_VIDEO_CX25840 | 881 | #ifdef CONFIG_VIDEO_CX25840_MODULE |
882 | hw = ivtv_request_module(itv, hw, "cx25840", IVTV_HW_CX25840); | 882 | hw = ivtv_request_module(itv, hw, "cx25840", IVTV_HW_CX25840); |
883 | #endif | 883 | #endif |
884 | #ifndef CONFIG_VIDEO_SAA711X | 884 | #ifdef CONFIG_VIDEO_SAA711X_MODULE |
885 | hw = ivtv_request_module(itv, hw, "saa7115", IVTV_HW_SAA711X); | 885 | hw = ivtv_request_module(itv, hw, "saa7115", IVTV_HW_SAA711X); |
886 | #endif | 886 | #endif |
887 | #ifndef CONFIG_VIDEO_SAA7127 | 887 | #ifdef CONFIG_VIDEO_SAA7127_MODULE |
888 | hw = ivtv_request_module(itv, hw, "saa7127", IVTV_HW_SAA7127); | 888 | hw = ivtv_request_module(itv, hw, "saa7127", IVTV_HW_SAA7127); |
889 | #endif | 889 | #endif |
890 | #ifndef CONFIG_VIDEO_SAA717X | 890 | #ifdef CONFIG_VIDEO_SAA717X_MODULE |
891 | hw = ivtv_request_module(itv, hw, "saa717x", IVTV_HW_SAA717X); | 891 | hw = ivtv_request_module(itv, hw, "saa717x", IVTV_HW_SAA717X); |
892 | #endif | 892 | #endif |
893 | #ifndef CONFIG_VIDEO_UPD64031A | 893 | #ifdef CONFIG_VIDEO_UPD64031A_MODULE |
894 | hw = ivtv_request_module(itv, hw, "upd64031a", IVTV_HW_UPD64031A); | 894 | hw = ivtv_request_module(itv, hw, "upd64031a", IVTV_HW_UPD64031A); |
895 | #endif | 895 | #endif |
896 | #ifndef CONFIG_VIDEO_UPD64083 | 896 | #ifdef CONFIG_VIDEO_UPD64083_MODULE |
897 | hw = ivtv_request_module(itv, hw, "upd64083", IVTV_HW_UPD6408X); | 897 | hw = ivtv_request_module(itv, hw, "upd64083", IVTV_HW_UPD6408X); |
898 | #endif | 898 | #endif |
899 | #ifndef CONFIG_VIDEO_MSP3400 | 899 | #ifdef CONFIG_VIDEO_MSP3400_MODULE |
900 | hw = ivtv_request_module(itv, hw, "msp3400", IVTV_HW_MSP34XX); | 900 | hw = ivtv_request_module(itv, hw, "msp3400", IVTV_HW_MSP34XX); |
901 | #endif | 901 | #endif |
902 | #ifndef CONFIG_VIDEO_VP27SMPX | 902 | #ifdef CONFIG_VIDEO_VP27SMPX_MODULE |
903 | hw = ivtv_request_module(itv, hw, "vp27smpx", IVTV_HW_VP27SMPX); | 903 | hw = ivtv_request_module(itv, hw, "vp27smpx", IVTV_HW_VP27SMPX); |
904 | #endif | 904 | #endif |
905 | #ifndef CONFIG_VIDEO_WM8775 | 905 | #ifdef CONFIG_VIDEO_WM8775_MODULE |
906 | hw = ivtv_request_module(itv, hw, "wm8775", IVTV_HW_WM8775); | 906 | hw = ivtv_request_module(itv, hw, "wm8775", IVTV_HW_WM8775); |
907 | #endif | 907 | #endif |
908 | #ifndef CONFIG_VIDEO_WM8739 | 908 | #ifdef CONFIG_VIDEO_WM8739_MODULE |
909 | hw = ivtv_request_module(itv, hw, "wm8739", IVTV_HW_WM8739); | 909 | hw = ivtv_request_module(itv, hw, "wm8739", IVTV_HW_WM8739); |
910 | #endif | 910 | #endif |
911 | #ifndef CONFIG_VIDEO_CS53L32A | 911 | #ifdef CONFIG_VIDEO_CS53L32A_MODULE |
912 | hw = ivtv_request_module(itv, hw, "cs53l32a", IVTV_HW_CS53L32A); | 912 | hw = ivtv_request_module(itv, hw, "cs53l32a", IVTV_HW_CS53L32A); |
913 | #endif | 913 | #endif |
914 | #ifndef CONFIG_VIDEO_M52790 | 914 | #ifdef CONFIG_VIDEO_M52790_MODULE |
915 | hw = ivtv_request_module(itv, hw, "m52790", IVTV_HW_M52790); | 915 | hw = ivtv_request_module(itv, hw, "m52790", IVTV_HW_M52790); |
916 | #endif | 916 | #endif |
917 | #endif | 917 | #endif |
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c index adf2ba79496a..37860698f782 100644 --- a/drivers/media/video/saa7110.c +++ b/drivers/media/video/saa7110.c | |||
@@ -47,7 +47,7 @@ module_param(debug, int, 0); | |||
47 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 47 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
48 | 48 | ||
49 | #define SAA7110_MAX_INPUT 9 /* 6 CVBS, 3 SVHS */ | 49 | #define SAA7110_MAX_INPUT 9 /* 6 CVBS, 3 SVHS */ |
50 | #define SAA7110_MAX_OUTPUT 0 /* its a decoder only */ | 50 | #define SAA7110_MAX_OUTPUT 1 /* 1 YUV */ |
51 | 51 | ||
52 | #define SAA7110_NR_REG 0x35 | 52 | #define SAA7110_NR_REG 0x35 |
53 | 53 | ||
@@ -327,7 +327,7 @@ saa7110_command (struct i2c_client *client, | |||
327 | 327 | ||
328 | case DECODER_SET_INPUT: | 328 | case DECODER_SET_INPUT: |
329 | v = *(int *) arg; | 329 | v = *(int *) arg; |
330 | if (v < 0 || v > SAA7110_MAX_INPUT) { | 330 | if (v < 0 || v >= SAA7110_MAX_INPUT) { |
331 | v4l_dbg(1, debug, client, "input=%d not available\n", v); | 331 | v4l_dbg(1, debug, client, "input=%d not available\n", v); |
332 | return -EINVAL; | 332 | return -EINVAL; |
333 | } | 333 | } |
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 249184452949..dfbe08a9ad9b 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c | |||
@@ -941,7 +941,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, | |||
941 | dev->name,(unsigned long long)pci_resource_start(pci_dev,0)); | 941 | dev->name,(unsigned long long)pci_resource_start(pci_dev,0)); |
942 | goto fail1; | 942 | goto fail1; |
943 | } | 943 | } |
944 | dev->lmmio = ioremap(pci_resource_start(pci_dev,0), 0x1000); | 944 | dev->lmmio = ioremap(pci_resource_start(pci_dev, 0), |
945 | pci_resource_len(pci_dev, 0)); | ||
945 | dev->bmmio = (__u8 __iomem *)dev->lmmio; | 946 | dev->bmmio = (__u8 __iomem *)dev->lmmio; |
946 | if (NULL == dev->lmmio) { | 947 | if (NULL == dev->lmmio) { |
947 | err = -EIO; | 948 | err = -EIO; |
diff --git a/drivers/media/video/usbvideo/ibmcam.c b/drivers/media/video/usbvideo/ibmcam.c index 28421d386f1e..c710bcd1df48 100644 --- a/drivers/media/video/usbvideo/ibmcam.c +++ b/drivers/media/video/usbvideo/ibmcam.c | |||
@@ -3695,7 +3695,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * | |||
3695 | unsigned char video_ep = 0; | 3695 | unsigned char video_ep = 0; |
3696 | 3696 | ||
3697 | if (debug >= 1) | 3697 | if (debug >= 1) |
3698 | dev_info(&uvd->dev->dev, "ibmcam_probe(%p,%u.)\n", intf, ifnum); | 3698 | dev_info(&dev->dev, "ibmcam_probe(%p,%u.)\n", intf, ifnum); |
3699 | 3699 | ||
3700 | /* We don't handle multi-config cameras */ | 3700 | /* We don't handle multi-config cameras */ |
3701 | if (dev->descriptor.bNumConfigurations != 1) | 3701 | if (dev->descriptor.bNumConfigurations != 1) |
@@ -3746,7 +3746,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * | |||
3746 | brand = "IBM PC Camera"; /* a.k.a. Xirlink C-It */ | 3746 | brand = "IBM PC Camera"; /* a.k.a. Xirlink C-It */ |
3747 | break; | 3747 | break; |
3748 | } | 3748 | } |
3749 | dev_info(&uvd->dev->dev, | 3749 | dev_info(&dev->dev, |
3750 | "%s USB camera found (model %d, rev. 0x%04x)\n", | 3750 | "%s USB camera found (model %d, rev. 0x%04x)\n", |
3751 | brand, model, le16_to_cpu(dev->descriptor.bcdDevice)); | 3751 | brand, model, le16_to_cpu(dev->descriptor.bcdDevice)); |
3752 | } while (0); | 3752 | } while (0); |
@@ -3754,7 +3754,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * | |||
3754 | /* Validate found interface: must have one ISO endpoint */ | 3754 | /* Validate found interface: must have one ISO endpoint */ |
3755 | nas = intf->num_altsetting; | 3755 | nas = intf->num_altsetting; |
3756 | if (debug > 0) | 3756 | if (debug > 0) |
3757 | dev_info(&uvd->dev->dev, "Number of alternate settings=%d.\n", | 3757 | dev_info(&dev->dev, "Number of alternate settings=%d.\n", |
3758 | nas); | 3758 | nas); |
3759 | if (nas < 2) { | 3759 | if (nas < 2) { |
3760 | err("Too few alternate settings for this camera!"); | 3760 | err("Too few alternate settings for this camera!"); |
@@ -3799,7 +3799,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * | |||
3799 | actInterface = i; | 3799 | actInterface = i; |
3800 | maxPS = le16_to_cpu(endpoint->wMaxPacketSize); | 3800 | maxPS = le16_to_cpu(endpoint->wMaxPacketSize); |
3801 | if (debug > 0) | 3801 | if (debug > 0) |
3802 | dev_info(&uvd->dev->dev, | 3802 | dev_info(&dev->dev, |
3803 | "Active setting=%d. " | 3803 | "Active setting=%d. " |
3804 | "maxPS=%d.\n", i, maxPS); | 3804 | "maxPS=%d.\n", i, maxPS); |
3805 | } else | 3805 | } else |
@@ -3840,7 +3840,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * | |||
3840 | RESTRICT_TO_RANGE(framerate, 0, 5); | 3840 | RESTRICT_TO_RANGE(framerate, 0, 5); |
3841 | break; | 3841 | break; |
3842 | default: | 3842 | default: |
3843 | dev_info(&uvd->dev->dev, "IBM camera: using 320x240\n"); | 3843 | dev_info(&dev->dev, "IBM camera: using 320x240\n"); |
3844 | size = SIZE_320x240; | 3844 | size = SIZE_320x240; |
3845 | /* No break here */ | 3845 | /* No break here */ |
3846 | case SIZE_320x240: | 3846 | case SIZE_320x240: |
@@ -3869,7 +3869,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * | |||
3869 | canvasY = 120; | 3869 | canvasY = 120; |
3870 | break; | 3870 | break; |
3871 | default: | 3871 | default: |
3872 | dev_info(&uvd->dev->dev, "IBM NetCamera: using 176x144\n"); | 3872 | dev_info(&dev->dev, "IBM NetCamera: using 176x144\n"); |
3873 | size = SIZE_176x144; | 3873 | size = SIZE_176x144; |
3874 | /* No break here */ | 3874 | /* No break here */ |
3875 | case SIZE_176x144: | 3875 | case SIZE_176x144: |
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c index a1abf95cf751..603ffd008c73 100644 --- a/drivers/message/fusion/mptlan.c +++ b/drivers/message/fusion/mptlan.c | |||
@@ -77,12 +77,6 @@ MODULE_VERSION(my_VERSION); | |||
77 | * Fusion MPT LAN private structures | 77 | * Fusion MPT LAN private structures |
78 | */ | 78 | */ |
79 | 79 | ||
80 | struct NAA_Hosed { | ||
81 | u16 NAA; | ||
82 | u8 ieee[FC_ALEN]; | ||
83 | struct NAA_Hosed *next; | ||
84 | }; | ||
85 | |||
86 | struct BufferControl { | 80 | struct BufferControl { |
87 | struct sk_buff *skb; | 81 | struct sk_buff *skb; |
88 | dma_addr_t dma; | 82 | dma_addr_t dma; |
@@ -159,11 +153,6 @@ static u8 LanCtx = MPT_MAX_PROTOCOL_DRIVERS; | |||
159 | static u32 max_buckets_out = 127; | 153 | static u32 max_buckets_out = 127; |
160 | static u32 tx_max_out_p = 127 - 16; | 154 | static u32 tx_max_out_p = 127 - 16; |
161 | 155 | ||
162 | #ifdef QLOGIC_NAA_WORKAROUND | ||
163 | static struct NAA_Hosed *mpt_bad_naa = NULL; | ||
164 | DEFINE_RWLOCK(bad_naa_lock); | ||
165 | #endif | ||
166 | |||
167 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 156 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
168 | /** | 157 | /** |
169 | * lan_reply - Handle all data sent from the hardware. | 158 | * lan_reply - Handle all data sent from the hardware. |
@@ -780,30 +769,6 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) | |||
780 | // ctx, skb, skb->data)); | 769 | // ctx, skb, skb->data)); |
781 | 770 | ||
782 | mac = skb_mac_header(skb); | 771 | mac = skb_mac_header(skb); |
783 | #ifdef QLOGIC_NAA_WORKAROUND | ||
784 | { | ||
785 | struct NAA_Hosed *nh; | ||
786 | |||
787 | /* Munge the NAA for Tx packets to QLogic boards, which don't follow | ||
788 | RFC 2625. The longer I look at this, the more my opinion of Qlogic | ||
789 | drops. */ | ||
790 | read_lock_irq(&bad_naa_lock); | ||
791 | for (nh = mpt_bad_naa; nh != NULL; nh=nh->next) { | ||
792 | if ((nh->ieee[0] == mac[0]) && | ||
793 | (nh->ieee[1] == mac[1]) && | ||
794 | (nh->ieee[2] == mac[2]) && | ||
795 | (nh->ieee[3] == mac[3]) && | ||
796 | (nh->ieee[4] == mac[4]) && | ||
797 | (nh->ieee[5] == mac[5])) { | ||
798 | cur_naa = nh->NAA; | ||
799 | dlprintk ((KERN_INFO "mptlan/sdu_send: using NAA value " | ||
800 | "= %04x.\n", cur_naa)); | ||
801 | break; | ||
802 | } | ||
803 | } | ||
804 | read_unlock_irq(&bad_naa_lock); | ||
805 | } | ||
806 | #endif | ||
807 | 772 | ||
808 | pTrans->TransactionDetails[0] = cpu_to_le32((cur_naa << 16) | | 773 | pTrans->TransactionDetails[0] = cpu_to_le32((cur_naa << 16) | |
809 | (mac[0] << 8) | | 774 | (mac[0] << 8) | |
@@ -1572,79 +1537,6 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev) | |||
1572 | 1537 | ||
1573 | fcllc = (struct fcllc *)skb->data; | 1538 | fcllc = (struct fcllc *)skb->data; |
1574 | 1539 | ||
1575 | #ifdef QLOGIC_NAA_WORKAROUND | ||
1576 | { | ||
1577 | u16 source_naa = fch->stype, found = 0; | ||
1578 | |||
1579 | /* Workaround for QLogic not following RFC 2625 in regards to the NAA | ||
1580 | value. */ | ||
1581 | |||
1582 | if ((source_naa & 0xF000) == 0) | ||
1583 | source_naa = swab16(source_naa); | ||
1584 | |||
1585 | if (fcllc->ethertype == htons(ETH_P_ARP)) | ||
1586 | dlprintk ((KERN_INFO "mptlan/type_trans: got arp req/rep w/ naa of " | ||
1587 | "%04x.\n", source_naa)); | ||
1588 | |||
1589 | if ((fcllc->ethertype == htons(ETH_P_ARP)) && | ||
1590 | ((source_naa >> 12) != MPT_LAN_NAA_RFC2625)){ | ||
1591 | struct NAA_Hosed *nh, *prevnh; | ||
1592 | int i; | ||
1593 | |||
1594 | dlprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep from " | ||
1595 | "system with non-RFC 2625 NAA value (%04x).\n", | ||
1596 | source_naa)); | ||
1597 | |||
1598 | write_lock_irq(&bad_naa_lock); | ||
1599 | for (prevnh = nh = mpt_bad_naa; nh != NULL; | ||
1600 | prevnh=nh, nh=nh->next) { | ||
1601 | if ((nh->ieee[0] == fch->saddr[0]) && | ||
1602 | (nh->ieee[1] == fch->saddr[1]) && | ||
1603 | (nh->ieee[2] == fch->saddr[2]) && | ||
1604 | (nh->ieee[3] == fch->saddr[3]) && | ||
1605 | (nh->ieee[4] == fch->saddr[4]) && | ||
1606 | (nh->ieee[5] == fch->saddr[5])) { | ||
1607 | found = 1; | ||
1608 | dlprintk ((KERN_INFO "mptlan/type_trans: ARP Re" | ||
1609 | "q/Rep w/ bad NAA from system already" | ||
1610 | " in DB.\n")); | ||
1611 | break; | ||
1612 | } | ||
1613 | } | ||
1614 | |||
1615 | if ((!found) && (nh == NULL)) { | ||
1616 | |||
1617 | nh = kmalloc(sizeof(struct NAA_Hosed), GFP_KERNEL); | ||
1618 | dlprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep w/" | ||
1619 | " bad NAA from system not yet in DB.\n")); | ||
1620 | |||
1621 | if (nh != NULL) { | ||
1622 | nh->next = NULL; | ||
1623 | if (!mpt_bad_naa) | ||
1624 | mpt_bad_naa = nh; | ||
1625 | if (prevnh) | ||
1626 | prevnh->next = nh; | ||
1627 | |||
1628 | nh->NAA = source_naa; /* Set the S_NAA value. */ | ||
1629 | for (i = 0; i < FC_ALEN; i++) | ||
1630 | nh->ieee[i] = fch->saddr[i]; | ||
1631 | dlprintk ((KERN_INFO "Got ARP from %02x:%02x:%02x:%02x:" | ||
1632 | "%02x:%02x with non-compliant S_NAA value.\n", | ||
1633 | fch->saddr[0], fch->saddr[1], fch->saddr[2], | ||
1634 | fch->saddr[3], fch->saddr[4],fch->saddr[5])); | ||
1635 | } else { | ||
1636 | printk (KERN_ERR "mptlan/type_trans: Unable to" | ||
1637 | " kmalloc a NAA_Hosed struct.\n"); | ||
1638 | } | ||
1639 | } else if (!found) { | ||
1640 | printk (KERN_ERR "mptlan/type_trans: found not" | ||
1641 | " set, but nh isn't null. Evil " | ||
1642 | "funkiness abounds.\n"); | ||
1643 | } | ||
1644 | write_unlock_irq(&bad_naa_lock); | ||
1645 | } | ||
1646 | } | ||
1647 | #endif | ||
1648 | 1540 | ||
1649 | /* Strip the SNAP header from ARP packets since we don't | 1541 | /* Strip the SNAP header from ARP packets since we don't |
1650 | * pass them through to the 802.2/SNAP layers. | 1542 | * pass them through to the 802.2/SNAP layers. |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 9494400e8fd0..fee7304102af 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -227,10 +227,20 @@ config HP_WMI | |||
227 | To compile this driver as a module, choose M here: the module will | 227 | To compile this driver as a module, choose M here: the module will |
228 | be called hp-wmi. | 228 | be called hp-wmi. |
229 | 229 | ||
230 | config ICS932S401 | ||
231 | tristate "Integrated Circuits ICS932S401" | ||
232 | depends on I2C && EXPERIMENTAL | ||
233 | help | ||
234 | If you say yes here you get support for the Integrated Circuits | ||
235 | ICS932S401 clock control chips. | ||
236 | |||
237 | This driver can also be built as a module. If so, the module | ||
238 | will be called ics932s401. | ||
239 | |||
230 | config MSI_LAPTOP | 240 | config MSI_LAPTOP |
231 | tristate "MSI Laptop Extras" | 241 | tristate "MSI Laptop Extras" |
232 | depends on X86 | 242 | depends on X86 |
233 | depends on ACPI_EC | 243 | depends on ACPI |
234 | depends on BACKLIGHT_CLASS_DEVICE | 244 | depends on BACKLIGHT_CLASS_DEVICE |
235 | ---help--- | 245 | ---help--- |
236 | This is a driver for laptops built by MSI (MICRO-STAR | 246 | This is a driver for laptops built by MSI (MICRO-STAR |
@@ -260,7 +270,7 @@ config PANASONIC_LAPTOP | |||
260 | config COMPAL_LAPTOP | 270 | config COMPAL_LAPTOP |
261 | tristate "Compal Laptop Extras" | 271 | tristate "Compal Laptop Extras" |
262 | depends on X86 | 272 | depends on X86 |
263 | depends on ACPI_EC | 273 | depends on ACPI |
264 | depends on BACKLIGHT_CLASS_DEVICE | 274 | depends on BACKLIGHT_CLASS_DEVICE |
265 | ---help--- | 275 | ---help--- |
266 | This is a driver for laptops built by Compal: | 276 | This is a driver for laptops built by Compal: |
@@ -488,4 +498,6 @@ config SGI_GRU_DEBUG | |||
488 | This option enables addition debugging code for the SGI GRU driver. If | 498 | This option enables addition debugging code for the SGI GRU driver. If |
489 | you are unsure, say N. | 499 | you are unsure, say N. |
490 | 500 | ||
501 | source "drivers/misc/c2port/Kconfig" | ||
502 | |||
491 | endif # MISC_DEVICES | 503 | endif # MISC_DEVICES |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 909e2468cdc9..817f7f5ab3bd 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
@@ -14,6 +14,7 @@ obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o | |||
14 | obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o | 14 | obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o |
15 | obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o | 15 | obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o |
16 | obj-$(CONFIG_HP_WMI) += hp-wmi.o | 16 | obj-$(CONFIG_HP_WMI) += hp-wmi.o |
17 | obj-$(CONFIG_ICS932S401) += ics932s401.o | ||
17 | obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o | 18 | obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o |
18 | obj-$(CONFIG_LKDTM) += lkdtm.o | 19 | obj-$(CONFIG_LKDTM) += lkdtm.o |
19 | obj-$(CONFIG_TIFM_CORE) += tifm_core.o | 20 | obj-$(CONFIG_TIFM_CORE) += tifm_core.o |
@@ -31,3 +32,4 @@ obj-$(CONFIG_KGDB_TESTS) += kgdbts.o | |||
31 | obj-$(CONFIG_SGI_XP) += sgi-xp/ | 32 | obj-$(CONFIG_SGI_XP) += sgi-xp/ |
32 | obj-$(CONFIG_SGI_GRU) += sgi-gru/ | 33 | obj-$(CONFIG_SGI_GRU) += sgi-gru/ |
33 | obj-$(CONFIG_HP_ILO) += hpilo.o | 34 | obj-$(CONFIG_HP_ILO) += hpilo.o |
35 | obj-$(CONFIG_C2PORT) += c2port/ | ||
diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c index 0532a2de2ce4..94c9f911824e 100644 --- a/drivers/misc/acer-wmi.c +++ b/drivers/misc/acer-wmi.c | |||
@@ -1297,6 +1297,12 @@ static int __init acer_wmi_init(void) | |||
1297 | 1297 | ||
1298 | set_quirks(); | 1298 | set_quirks(); |
1299 | 1299 | ||
1300 | if (!acpi_video_backlight_support() && has_cap(ACER_CAP_BRIGHTNESS)) { | ||
1301 | interface->capability &= ~ACER_CAP_BRIGHTNESS; | ||
1302 | printk(ACER_INFO "Brightness must be controlled by " | ||
1303 | "generic video driver\n"); | ||
1304 | } | ||
1305 | |||
1300 | if (platform_driver_register(&acer_platform_driver)) { | 1306 | if (platform_driver_register(&acer_platform_driver)) { |
1301 | printk(ACER_ERR "Unable to register platform driver.\n"); | 1307 | printk(ACER_ERR "Unable to register platform driver.\n"); |
1302 | goto error_platform_register; | 1308 | goto error_platform_register; |
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c index a9d5228724a6..8fb8b3591048 100644 --- a/drivers/misc/asus-laptop.c +++ b/drivers/misc/asus-laptop.c | |||
@@ -1208,9 +1208,13 @@ static int __init asus_laptop_init(void) | |||
1208 | 1208 | ||
1209 | dev = acpi_get_physical_device(hotk->device->handle); | 1209 | dev = acpi_get_physical_device(hotk->device->handle); |
1210 | 1210 | ||
1211 | result = asus_backlight_init(dev); | 1211 | if (!acpi_video_backlight_support()) { |
1212 | if (result) | 1212 | result = asus_backlight_init(dev); |
1213 | goto fail_backlight; | 1213 | if (result) |
1214 | goto fail_backlight; | ||
1215 | } else | ||
1216 | printk(ASUS_INFO "Brightness ignored, must be controlled by " | ||
1217 | "ACPI video driver\n"); | ||
1214 | 1218 | ||
1215 | result = asus_led_init(dev); | 1219 | result = asus_led_init(dev); |
1216 | if (result) | 1220 | if (result) |
diff --git a/drivers/misc/c2port/Kconfig b/drivers/misc/c2port/Kconfig new file mode 100644 index 000000000000..e46af9a5810d --- /dev/null +++ b/drivers/misc/c2port/Kconfig | |||
@@ -0,0 +1,35 @@ | |||
1 | # | ||
2 | # C2 port devices | ||
3 | # | ||
4 | |||
5 | menuconfig C2PORT | ||
6 | tristate "Silicon Labs C2 port support (EXPERIMENTAL)" | ||
7 | depends on EXPERIMENTAL | ||
8 | default no | ||
9 | help | ||
10 | This option enables support for Silicon Labs C2 port used to | ||
11 | program Silicon micro controller chips (and other 8051 compatible). | ||
12 | |||
13 | If your board have no such micro controllers you don't need this | ||
14 | interface at all. | ||
15 | |||
16 | To compile this driver as a module, choose M here: the module will | ||
17 | be called c2port_core. Note that you also need a client module | ||
18 | usually called c2port-*. | ||
19 | |||
20 | If you are not sure, say N here. | ||
21 | |||
22 | if C2PORT | ||
23 | |||
24 | config C2PORT_DURAMAR_2150 | ||
25 | tristate "C2 port support for Eurotech's Duramar 2150 (EXPERIMENTAL)" | ||
26 | depends on X86 && C2PORT | ||
27 | default no | ||
28 | help | ||
29 | This option enables C2 support for the Eurotech's Duramar 2150 | ||
30 | on board micro controller. | ||
31 | |||
32 | To compile this driver as a module, choose M here: the module will | ||
33 | be called c2port-duramar2150. | ||
34 | |||
35 | endif # C2PORT | ||
diff --git a/drivers/misc/c2port/Makefile b/drivers/misc/c2port/Makefile new file mode 100644 index 000000000000..3b2cf43d60f5 --- /dev/null +++ b/drivers/misc/c2port/Makefile | |||
@@ -0,0 +1,3 @@ | |||
1 | obj-$(CONFIG_C2PORT) += core.o | ||
2 | |||
3 | obj-$(CONFIG_C2PORT_DURAMAR_2150) += c2port-duramar2150.o | ||
diff --git a/drivers/misc/c2port/c2port-duramar2150.c b/drivers/misc/c2port/c2port-duramar2150.c new file mode 100644 index 000000000000..338dcc121507 --- /dev/null +++ b/drivers/misc/c2port/c2port-duramar2150.c | |||
@@ -0,0 +1,158 @@ | |||
1 | /* | ||
2 | * Silicon Labs C2 port Linux support for Eurotech Duramar 2150 | ||
3 | * | ||
4 | * Copyright (c) 2008 Rodolfo Giometti <giometti@linux.it> | ||
5 | * Copyright (c) 2008 Eurotech S.p.A. <info@eurotech.it> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation | ||
10 | */ | ||
11 | |||
12 | #include <linux/errno.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/c2port.h> | ||
19 | |||
20 | #define DATA_PORT 0x325 | ||
21 | #define DIR_PORT 0x326 | ||
22 | #define C2D (1 << 0) | ||
23 | #define C2CK (1 << 1) | ||
24 | |||
25 | static DEFINE_MUTEX(update_lock); | ||
26 | |||
27 | /* | ||
28 | * C2 port operations | ||
29 | */ | ||
30 | |||
31 | static void duramar2150_c2port_access(struct c2port_device *dev, int status) | ||
32 | { | ||
33 | u8 v; | ||
34 | |||
35 | mutex_lock(&update_lock); | ||
36 | |||
37 | v = inb(DIR_PORT); | ||
38 | |||
39 | /* 0 = input, 1 = output */ | ||
40 | if (status) | ||
41 | outb(v | (C2D | C2CK), DIR_PORT); | ||
42 | else | ||
43 | /* When access is "off" is important that both lines are set | ||
44 | * as inputs or hi-impedence */ | ||
45 | outb(v & ~(C2D | C2CK), DIR_PORT); | ||
46 | |||
47 | mutex_unlock(&update_lock); | ||
48 | } | ||
49 | |||
50 | static void duramar2150_c2port_c2d_dir(struct c2port_device *dev, int dir) | ||
51 | { | ||
52 | u8 v; | ||
53 | |||
54 | mutex_lock(&update_lock); | ||
55 | |||
56 | v = inb(DIR_PORT); | ||
57 | |||
58 | if (dir) | ||
59 | outb(v & ~C2D, DIR_PORT); | ||
60 | else | ||
61 | outb(v | C2D, DIR_PORT); | ||
62 | |||
63 | mutex_unlock(&update_lock); | ||
64 | } | ||
65 | |||
66 | static int duramar2150_c2port_c2d_get(struct c2port_device *dev) | ||
67 | { | ||
68 | return inb(DATA_PORT) & C2D; | ||
69 | } | ||
70 | |||
71 | static void duramar2150_c2port_c2d_set(struct c2port_device *dev, int status) | ||
72 | { | ||
73 | u8 v; | ||
74 | |||
75 | mutex_lock(&update_lock); | ||
76 | |||
77 | v = inb(DATA_PORT); | ||
78 | |||
79 | if (status) | ||
80 | outb(v | C2D, DATA_PORT); | ||
81 | else | ||
82 | outb(v & ~C2D, DATA_PORT); | ||
83 | |||
84 | mutex_unlock(&update_lock); | ||
85 | } | ||
86 | |||
87 | static void duramar2150_c2port_c2ck_set(struct c2port_device *dev, int status) | ||
88 | { | ||
89 | u8 v; | ||
90 | |||
91 | mutex_lock(&update_lock); | ||
92 | |||
93 | v = inb(DATA_PORT); | ||
94 | |||
95 | if (status) | ||
96 | outb(v | C2CK, DATA_PORT); | ||
97 | else | ||
98 | outb(v & ~C2CK, DATA_PORT); | ||
99 | |||
100 | mutex_unlock(&update_lock); | ||
101 | } | ||
102 | |||
103 | static struct c2port_ops duramar2150_c2port_ops = { | ||
104 | .block_size = 512, /* bytes */ | ||
105 | .blocks_num = 30, /* total flash size: 15360 bytes */ | ||
106 | |||
107 | .access = duramar2150_c2port_access, | ||
108 | .c2d_dir = duramar2150_c2port_c2d_dir, | ||
109 | .c2d_get = duramar2150_c2port_c2d_get, | ||
110 | .c2d_set = duramar2150_c2port_c2d_set, | ||
111 | .c2ck_set = duramar2150_c2port_c2ck_set, | ||
112 | }; | ||
113 | |||
114 | static struct c2port_device *duramar2150_c2port_dev; | ||
115 | |||
116 | /* | ||
117 | * Module stuff | ||
118 | */ | ||
119 | |||
120 | static int __init duramar2150_c2port_init(void) | ||
121 | { | ||
122 | struct resource *res; | ||
123 | int ret = 0; | ||
124 | |||
125 | res = request_region(0x325, 2, "c2port"); | ||
126 | if (!res) | ||
127 | return -EBUSY; | ||
128 | |||
129 | duramar2150_c2port_dev = c2port_device_register("uc", | ||
130 | &duramar2150_c2port_ops, NULL); | ||
131 | if (!duramar2150_c2port_dev) { | ||
132 | ret = -ENODEV; | ||
133 | goto free_region; | ||
134 | } | ||
135 | |||
136 | return 0; | ||
137 | |||
138 | free_region: | ||
139 | release_region(0x325, 2); | ||
140 | return ret; | ||
141 | } | ||
142 | |||
143 | static void __exit duramar2150_c2port_exit(void) | ||
144 | { | ||
145 | /* Setup the GPIOs as input by default (access = 0) */ | ||
146 | duramar2150_c2port_access(duramar2150_c2port_dev, 0); | ||
147 | |||
148 | c2port_device_unregister(duramar2150_c2port_dev); | ||
149 | |||
150 | release_region(0x325, 2); | ||
151 | } | ||
152 | |||
153 | module_init(duramar2150_c2port_init); | ||
154 | module_exit(duramar2150_c2port_exit); | ||
155 | |||
156 | MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); | ||
157 | MODULE_DESCRIPTION("Silicon Labs C2 port Linux support for Duramar 2150"); | ||
158 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/misc/c2port/core.c b/drivers/misc/c2port/core.c new file mode 100644 index 000000000000..976b35d1d035 --- /dev/null +++ b/drivers/misc/c2port/core.c | |||
@@ -0,0 +1,1002 @@ | |||
1 | /* | ||
2 | * Silicon Labs C2 port core Linux support | ||
3 | * | ||
4 | * Copyright (c) 2007 Rodolfo Giometti <giometti@linux.it> | ||
5 | * Copyright (c) 2007 Eurotech S.p.A. <info@eurotech.it> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/errno.h> | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/ctype.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/idr.h> | ||
21 | |||
22 | #include <linux/c2port.h> | ||
23 | |||
24 | #define DRIVER_NAME "c2port" | ||
25 | #define DRIVER_VERSION "0.51.0" | ||
26 | |||
27 | static DEFINE_SPINLOCK(c2port_idr_lock); | ||
28 | static DEFINE_IDR(c2port_idr); | ||
29 | |||
30 | /* | ||
31 | * Local variables | ||
32 | */ | ||
33 | |||
34 | static struct class *c2port_class; | ||
35 | |||
36 | /* | ||
37 | * C2 registers & commands defines | ||
38 | */ | ||
39 | |||
40 | /* C2 registers */ | ||
41 | #define C2PORT_DEVICEID 0x00 | ||
42 | #define C2PORT_REVID 0x01 | ||
43 | #define C2PORT_FPCTL 0x02 | ||
44 | #define C2PORT_FPDAT 0xB4 | ||
45 | |||
46 | /* C2 interface commands */ | ||
47 | #define C2PORT_GET_VERSION 0x01 | ||
48 | #define C2PORT_DEVICE_ERASE 0x03 | ||
49 | #define C2PORT_BLOCK_READ 0x06 | ||
50 | #define C2PORT_BLOCK_WRITE 0x07 | ||
51 | #define C2PORT_PAGE_ERASE 0x08 | ||
52 | |||
53 | /* C2 status return codes */ | ||
54 | #define C2PORT_INVALID_COMMAND 0x00 | ||
55 | #define C2PORT_COMMAND_FAILED 0x02 | ||
56 | #define C2PORT_COMMAND_OK 0x0d | ||
57 | |||
58 | /* | ||
59 | * C2 port low level signal managements | ||
60 | */ | ||
61 | |||
62 | static void c2port_reset(struct c2port_device *dev) | ||
63 | { | ||
64 | struct c2port_ops *ops = dev->ops; | ||
65 | |||
66 | /* To reset the device we have to keep clock line low for at least | ||
67 | * 20us. | ||
68 | */ | ||
69 | local_irq_disable(); | ||
70 | ops->c2ck_set(dev, 0); | ||
71 | udelay(25); | ||
72 | ops->c2ck_set(dev, 1); | ||
73 | local_irq_enable(); | ||
74 | |||
75 | udelay(1); | ||
76 | } | ||
77 | |||
78 | static void c2port_strobe_ck(struct c2port_device *dev) | ||
79 | { | ||
80 | struct c2port_ops *ops = dev->ops; | ||
81 | |||
82 | /* During hi-low-hi transition we disable local IRQs to avoid | ||
83 | * interructions since C2 port specification says that it must be | ||
84 | * shorter than 5us, otherwise the microcontroller may consider | ||
85 | * it as a reset signal! | ||
86 | */ | ||
87 | local_irq_disable(); | ||
88 | ops->c2ck_set(dev, 0); | ||
89 | udelay(1); | ||
90 | ops->c2ck_set(dev, 1); | ||
91 | local_irq_enable(); | ||
92 | |||
93 | udelay(1); | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * C2 port basic functions | ||
98 | */ | ||
99 | |||
100 | static void c2port_write_ar(struct c2port_device *dev, u8 addr) | ||
101 | { | ||
102 | struct c2port_ops *ops = dev->ops; | ||
103 | int i; | ||
104 | |||
105 | /* START field */ | ||
106 | c2port_strobe_ck(dev); | ||
107 | |||
108 | /* INS field (11b, LSB first) */ | ||
109 | ops->c2d_dir(dev, 0); | ||
110 | ops->c2d_set(dev, 1); | ||
111 | c2port_strobe_ck(dev); | ||
112 | ops->c2d_set(dev, 1); | ||
113 | c2port_strobe_ck(dev); | ||
114 | |||
115 | /* ADDRESS field */ | ||
116 | for (i = 0; i < 8; i++) { | ||
117 | ops->c2d_set(dev, addr & 0x01); | ||
118 | c2port_strobe_ck(dev); | ||
119 | |||
120 | addr >>= 1; | ||
121 | } | ||
122 | |||
123 | /* STOP field */ | ||
124 | ops->c2d_dir(dev, 1); | ||
125 | c2port_strobe_ck(dev); | ||
126 | } | ||
127 | |||
128 | static int c2port_read_ar(struct c2port_device *dev, u8 *addr) | ||
129 | { | ||
130 | struct c2port_ops *ops = dev->ops; | ||
131 | int i; | ||
132 | |||
133 | /* START field */ | ||
134 | c2port_strobe_ck(dev); | ||
135 | |||
136 | /* INS field (10b, LSB first) */ | ||
137 | ops->c2d_dir(dev, 0); | ||
138 | ops->c2d_set(dev, 0); | ||
139 | c2port_strobe_ck(dev); | ||
140 | ops->c2d_set(dev, 1); | ||
141 | c2port_strobe_ck(dev); | ||
142 | |||
143 | /* ADDRESS field */ | ||
144 | ops->c2d_dir(dev, 1); | ||
145 | *addr = 0; | ||
146 | for (i = 0; i < 8; i++) { | ||
147 | *addr >>= 1; /* shift in 8-bit ADDRESS field LSB first */ | ||
148 | |||
149 | c2port_strobe_ck(dev); | ||
150 | if (ops->c2d_get(dev)) | ||
151 | *addr |= 0x80; | ||
152 | } | ||
153 | |||
154 | /* STOP field */ | ||
155 | c2port_strobe_ck(dev); | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static int c2port_write_dr(struct c2port_device *dev, u8 data) | ||
161 | { | ||
162 | struct c2port_ops *ops = dev->ops; | ||
163 | int timeout, i; | ||
164 | |||
165 | /* START field */ | ||
166 | c2port_strobe_ck(dev); | ||
167 | |||
168 | /* INS field (01b, LSB first) */ | ||
169 | ops->c2d_dir(dev, 0); | ||
170 | ops->c2d_set(dev, 1); | ||
171 | c2port_strobe_ck(dev); | ||
172 | ops->c2d_set(dev, 0); | ||
173 | c2port_strobe_ck(dev); | ||
174 | |||
175 | /* LENGTH field (00b, LSB first -> 1 byte) */ | ||
176 | ops->c2d_set(dev, 0); | ||
177 | c2port_strobe_ck(dev); | ||
178 | ops->c2d_set(dev, 0); | ||
179 | c2port_strobe_ck(dev); | ||
180 | |||
181 | /* DATA field */ | ||
182 | for (i = 0; i < 8; i++) { | ||
183 | ops->c2d_set(dev, data & 0x01); | ||
184 | c2port_strobe_ck(dev); | ||
185 | |||
186 | data >>= 1; | ||
187 | } | ||
188 | |||
189 | /* WAIT field */ | ||
190 | ops->c2d_dir(dev, 1); | ||
191 | timeout = 20; | ||
192 | do { | ||
193 | c2port_strobe_ck(dev); | ||
194 | if (ops->c2d_get(dev)) | ||
195 | break; | ||
196 | |||
197 | udelay(1); | ||
198 | } while (--timeout > 0); | ||
199 | if (timeout == 0) | ||
200 | return -EIO; | ||
201 | |||
202 | /* STOP field */ | ||
203 | c2port_strobe_ck(dev); | ||
204 | |||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | static int c2port_read_dr(struct c2port_device *dev, u8 *data) | ||
209 | { | ||
210 | struct c2port_ops *ops = dev->ops; | ||
211 | int timeout, i; | ||
212 | |||
213 | /* START field */ | ||
214 | c2port_strobe_ck(dev); | ||
215 | |||
216 | /* INS field (00b, LSB first) */ | ||
217 | ops->c2d_dir(dev, 0); | ||
218 | ops->c2d_set(dev, 0); | ||
219 | c2port_strobe_ck(dev); | ||
220 | ops->c2d_set(dev, 0); | ||
221 | c2port_strobe_ck(dev); | ||
222 | |||
223 | /* LENGTH field (00b, LSB first -> 1 byte) */ | ||
224 | ops->c2d_set(dev, 0); | ||
225 | c2port_strobe_ck(dev); | ||
226 | ops->c2d_set(dev, 0); | ||
227 | c2port_strobe_ck(dev); | ||
228 | |||
229 | /* WAIT field */ | ||
230 | ops->c2d_dir(dev, 1); | ||
231 | timeout = 20; | ||
232 | do { | ||
233 | c2port_strobe_ck(dev); | ||
234 | if (ops->c2d_get(dev)) | ||
235 | break; | ||
236 | |||
237 | udelay(1); | ||
238 | } while (--timeout > 0); | ||
239 | if (timeout == 0) | ||
240 | return -EIO; | ||
241 | |||
242 | /* DATA field */ | ||
243 | *data = 0; | ||
244 | for (i = 0; i < 8; i++) { | ||
245 | *data >>= 1; /* shift in 8-bit DATA field LSB first */ | ||
246 | |||
247 | c2port_strobe_ck(dev); | ||
248 | if (ops->c2d_get(dev)) | ||
249 | *data |= 0x80; | ||
250 | } | ||
251 | |||
252 | /* STOP field */ | ||
253 | c2port_strobe_ck(dev); | ||
254 | |||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static int c2port_poll_in_busy(struct c2port_device *dev) | ||
259 | { | ||
260 | u8 addr; | ||
261 | int ret, timeout = 20; | ||
262 | |||
263 | do { | ||
264 | ret = (c2port_read_ar(dev, &addr)); | ||
265 | if (ret < 0) | ||
266 | return -EIO; | ||
267 | |||
268 | if (!(addr & 0x02)) | ||
269 | break; | ||
270 | |||
271 | udelay(1); | ||
272 | } while (--timeout > 0); | ||
273 | if (timeout == 0) | ||
274 | return -EIO; | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | static int c2port_poll_out_ready(struct c2port_device *dev) | ||
280 | { | ||
281 | u8 addr; | ||
282 | int ret, timeout = 10000; /* erase flash needs long time... */ | ||
283 | |||
284 | do { | ||
285 | ret = (c2port_read_ar(dev, &addr)); | ||
286 | if (ret < 0) | ||
287 | return -EIO; | ||
288 | |||
289 | if (addr & 0x01) | ||
290 | break; | ||
291 | |||
292 | udelay(1); | ||
293 | } while (--timeout > 0); | ||
294 | if (timeout == 0) | ||
295 | return -EIO; | ||
296 | |||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | /* | ||
301 | * sysfs methods | ||
302 | */ | ||
303 | |||
304 | static ssize_t c2port_show_name(struct device *dev, | ||
305 | struct device_attribute *attr, char *buf) | ||
306 | { | ||
307 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
308 | |||
309 | return sprintf(buf, "%s\n", c2dev->name); | ||
310 | } | ||
311 | |||
312 | static ssize_t c2port_show_flash_blocks_num(struct device *dev, | ||
313 | struct device_attribute *attr, char *buf) | ||
314 | { | ||
315 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
316 | struct c2port_ops *ops = c2dev->ops; | ||
317 | |||
318 | return sprintf(buf, "%d\n", ops->blocks_num); | ||
319 | } | ||
320 | |||
321 | static ssize_t c2port_show_flash_block_size(struct device *dev, | ||
322 | struct device_attribute *attr, char *buf) | ||
323 | { | ||
324 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
325 | struct c2port_ops *ops = c2dev->ops; | ||
326 | |||
327 | return sprintf(buf, "%d\n", ops->block_size); | ||
328 | } | ||
329 | |||
330 | static ssize_t c2port_show_flash_size(struct device *dev, | ||
331 | struct device_attribute *attr, char *buf) | ||
332 | { | ||
333 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
334 | struct c2port_ops *ops = c2dev->ops; | ||
335 | |||
336 | return sprintf(buf, "%d\n", ops->blocks_num * ops->block_size); | ||
337 | } | ||
338 | |||
339 | static ssize_t c2port_show_access(struct device *dev, | ||
340 | struct device_attribute *attr, char *buf) | ||
341 | { | ||
342 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
343 | |||
344 | return sprintf(buf, "%d\n", c2dev->access); | ||
345 | } | ||
346 | |||
347 | static ssize_t c2port_store_access(struct device *dev, | ||
348 | struct device_attribute *attr, | ||
349 | const char *buf, size_t count) | ||
350 | { | ||
351 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
352 | struct c2port_ops *ops = c2dev->ops; | ||
353 | int status, ret; | ||
354 | |||
355 | ret = sscanf(buf, "%d", &status); | ||
356 | if (ret != 1) | ||
357 | return -EINVAL; | ||
358 | |||
359 | mutex_lock(&c2dev->mutex); | ||
360 | |||
361 | c2dev->access = !!status; | ||
362 | |||
363 | /* If access is "on" clock should be HIGH _before_ setting the line | ||
364 | * as output and data line should be set as INPUT anyway */ | ||
365 | if (c2dev->access) | ||
366 | ops->c2ck_set(c2dev, 1); | ||
367 | ops->access(c2dev, c2dev->access); | ||
368 | if (c2dev->access) | ||
369 | ops->c2d_dir(c2dev, 1); | ||
370 | |||
371 | mutex_unlock(&c2dev->mutex); | ||
372 | |||
373 | return count; | ||
374 | } | ||
375 | |||
376 | static ssize_t c2port_store_reset(struct device *dev, | ||
377 | struct device_attribute *attr, | ||
378 | const char *buf, size_t count) | ||
379 | { | ||
380 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
381 | |||
382 | /* Check the device access status */ | ||
383 | if (!c2dev->access) | ||
384 | return -EBUSY; | ||
385 | |||
386 | mutex_lock(&c2dev->mutex); | ||
387 | |||
388 | c2port_reset(c2dev); | ||
389 | c2dev->flash_access = 0; | ||
390 | |||
391 | mutex_unlock(&c2dev->mutex); | ||
392 | |||
393 | return count; | ||
394 | } | ||
395 | |||
396 | static ssize_t __c2port_show_dev_id(struct c2port_device *dev, char *buf) | ||
397 | { | ||
398 | u8 data; | ||
399 | int ret; | ||
400 | |||
401 | /* Select DEVICEID register for C2 data register accesses */ | ||
402 | c2port_write_ar(dev, C2PORT_DEVICEID); | ||
403 | |||
404 | /* Read and return the device ID register */ | ||
405 | ret = c2port_read_dr(dev, &data); | ||
406 | if (ret < 0) | ||
407 | return ret; | ||
408 | |||
409 | return sprintf(buf, "%d\n", data); | ||
410 | } | ||
411 | |||
412 | static ssize_t c2port_show_dev_id(struct device *dev, | ||
413 | struct device_attribute *attr, char *buf) | ||
414 | { | ||
415 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
416 | ssize_t ret; | ||
417 | |||
418 | /* Check the device access status */ | ||
419 | if (!c2dev->access) | ||
420 | return -EBUSY; | ||
421 | |||
422 | mutex_lock(&c2dev->mutex); | ||
423 | ret = __c2port_show_dev_id(c2dev, buf); | ||
424 | mutex_unlock(&c2dev->mutex); | ||
425 | |||
426 | if (ret < 0) | ||
427 | dev_err(dev, "cannot read from %s\n", c2dev->name); | ||
428 | |||
429 | return ret; | ||
430 | } | ||
431 | |||
432 | static ssize_t __c2port_show_rev_id(struct c2port_device *dev, char *buf) | ||
433 | { | ||
434 | u8 data; | ||
435 | int ret; | ||
436 | |||
437 | /* Select REVID register for C2 data register accesses */ | ||
438 | c2port_write_ar(dev, C2PORT_REVID); | ||
439 | |||
440 | /* Read and return the revision ID register */ | ||
441 | ret = c2port_read_dr(dev, &data); | ||
442 | if (ret < 0) | ||
443 | return ret; | ||
444 | |||
445 | return sprintf(buf, "%d\n", data); | ||
446 | } | ||
447 | |||
448 | static ssize_t c2port_show_rev_id(struct device *dev, | ||
449 | struct device_attribute *attr, char *buf) | ||
450 | { | ||
451 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
452 | ssize_t ret; | ||
453 | |||
454 | /* Check the device access status */ | ||
455 | if (!c2dev->access) | ||
456 | return -EBUSY; | ||
457 | |||
458 | mutex_lock(&c2dev->mutex); | ||
459 | ret = __c2port_show_rev_id(c2dev, buf); | ||
460 | mutex_unlock(&c2dev->mutex); | ||
461 | |||
462 | if (ret < 0) | ||
463 | dev_err(c2dev->dev, "cannot read from %s\n", c2dev->name); | ||
464 | |||
465 | return ret; | ||
466 | } | ||
467 | |||
468 | static ssize_t c2port_show_flash_access(struct device *dev, | ||
469 | struct device_attribute *attr, char *buf) | ||
470 | { | ||
471 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
472 | |||
473 | return sprintf(buf, "%d\n", c2dev->flash_access); | ||
474 | } | ||
475 | |||
476 | static ssize_t __c2port_store_flash_access(struct c2port_device *dev, | ||
477 | int status) | ||
478 | { | ||
479 | int ret; | ||
480 | |||
481 | /* Check the device access status */ | ||
482 | if (!dev->access) | ||
483 | return -EBUSY; | ||
484 | |||
485 | dev->flash_access = !!status; | ||
486 | |||
487 | /* If flash_access is off we have nothing to do... */ | ||
488 | if (dev->flash_access == 0) | ||
489 | return 0; | ||
490 | |||
491 | /* Target the C2 flash programming control register for C2 data | ||
492 | * register access */ | ||
493 | c2port_write_ar(dev, C2PORT_FPCTL); | ||
494 | |||
495 | /* Write the first keycode to enable C2 Flash programming */ | ||
496 | ret = c2port_write_dr(dev, 0x02); | ||
497 | if (ret < 0) | ||
498 | return ret; | ||
499 | |||
500 | /* Write the second keycode to enable C2 Flash programming */ | ||
501 | ret = c2port_write_dr(dev, 0x01); | ||
502 | if (ret < 0) | ||
503 | return ret; | ||
504 | |||
505 | /* Delay for at least 20ms to ensure the target is ready for | ||
506 | * C2 flash programming */ | ||
507 | mdelay(25); | ||
508 | |||
509 | return 0; | ||
510 | } | ||
511 | |||
512 | static ssize_t c2port_store_flash_access(struct device *dev, | ||
513 | struct device_attribute *attr, | ||
514 | const char *buf, size_t count) | ||
515 | { | ||
516 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
517 | int status; | ||
518 | ssize_t ret; | ||
519 | |||
520 | ret = sscanf(buf, "%d", &status); | ||
521 | if (ret != 1) | ||
522 | return -EINVAL; | ||
523 | |||
524 | mutex_lock(&c2dev->mutex); | ||
525 | ret = __c2port_store_flash_access(c2dev, status); | ||
526 | mutex_unlock(&c2dev->mutex); | ||
527 | |||
528 | if (ret < 0) { | ||
529 | dev_err(c2dev->dev, "cannot enable %s flash programming\n", | ||
530 | c2dev->name); | ||
531 | return ret; | ||
532 | } | ||
533 | |||
534 | return count; | ||
535 | } | ||
536 | |||
537 | static ssize_t __c2port_write_flash_erase(struct c2port_device *dev) | ||
538 | { | ||
539 | u8 status; | ||
540 | int ret; | ||
541 | |||
542 | /* Target the C2 flash programming data register for C2 data register | ||
543 | * access. | ||
544 | */ | ||
545 | c2port_write_ar(dev, C2PORT_FPDAT); | ||
546 | |||
547 | /* Send device erase command */ | ||
548 | c2port_write_dr(dev, C2PORT_DEVICE_ERASE); | ||
549 | |||
550 | /* Wait for input acknowledge */ | ||
551 | ret = c2port_poll_in_busy(dev); | ||
552 | if (ret < 0) | ||
553 | return ret; | ||
554 | |||
555 | /* Should check status before starting FLASH access sequence */ | ||
556 | |||
557 | /* Wait for status information */ | ||
558 | ret = c2port_poll_out_ready(dev); | ||
559 | if (ret < 0) | ||
560 | return ret; | ||
561 | |||
562 | /* Read flash programming interface status */ | ||
563 | ret = c2port_read_dr(dev, &status); | ||
564 | if (ret < 0) | ||
565 | return ret; | ||
566 | if (status != C2PORT_COMMAND_OK) | ||
567 | return -EBUSY; | ||
568 | |||
569 | /* Send a three-byte arming sequence to enable the device erase. | ||
570 | * If the sequence is not received correctly, the command will be | ||
571 | * ignored. | ||
572 | * Sequence is: 0xde, 0xad, 0xa5. | ||
573 | */ | ||
574 | c2port_write_dr(dev, 0xde); | ||
575 | ret = c2port_poll_in_busy(dev); | ||
576 | if (ret < 0) | ||
577 | return ret; | ||
578 | c2port_write_dr(dev, 0xad); | ||
579 | ret = c2port_poll_in_busy(dev); | ||
580 | if (ret < 0) | ||
581 | return ret; | ||
582 | c2port_write_dr(dev, 0xa5); | ||
583 | ret = c2port_poll_in_busy(dev); | ||
584 | if (ret < 0) | ||
585 | return ret; | ||
586 | |||
587 | ret = c2port_poll_out_ready(dev); | ||
588 | if (ret < 0) | ||
589 | return ret; | ||
590 | |||
591 | return 0; | ||
592 | } | ||
593 | |||
594 | static ssize_t c2port_store_flash_erase(struct device *dev, | ||
595 | struct device_attribute *attr, | ||
596 | const char *buf, size_t count) | ||
597 | { | ||
598 | struct c2port_device *c2dev = dev_get_drvdata(dev); | ||
599 | int ret; | ||
600 | |||
601 | /* Check the device and flash access status */ | ||
602 | if (!c2dev->access || !c2dev->flash_access) | ||
603 | return -EBUSY; | ||
604 | |||
605 | mutex_lock(&c2dev->mutex); | ||
606 | ret = __c2port_write_flash_erase(c2dev); | ||
607 | mutex_unlock(&c2dev->mutex); | ||
608 | |||
609 | if (ret < 0) { | ||
610 | dev_err(c2dev->dev, "cannot erase %s flash\n", c2dev->name); | ||
611 | return ret; | ||
612 | } | ||
613 | |||
614 | return count; | ||
615 | } | ||
616 | |||
617 | static ssize_t __c2port_read_flash_data(struct c2port_device *dev, | ||
618 | char *buffer, loff_t offset, size_t count) | ||
619 | { | ||
620 | struct c2port_ops *ops = dev->ops; | ||
621 | u8 status, nread = 128; | ||
622 | int i, ret; | ||
623 | |||
624 | /* Check for flash end */ | ||
625 | if (offset >= ops->block_size * ops->blocks_num) | ||
626 | return 0; | ||
627 | |||
628 | if (ops->block_size * ops->blocks_num - offset < nread) | ||
629 | nread = ops->block_size * ops->blocks_num - offset; | ||
630 | if (count < nread) | ||
631 | nread = count; | ||
632 | if (nread == 0) | ||
633 | return nread; | ||
634 | |||
635 | /* Target the C2 flash programming data register for C2 data register | ||
636 | * access */ | ||
637 | c2port_write_ar(dev, C2PORT_FPDAT); | ||
638 | |||
639 | /* Send flash block read command */ | ||
640 | c2port_write_dr(dev, C2PORT_BLOCK_READ); | ||
641 | |||
642 | /* Wait for input acknowledge */ | ||
643 | ret = c2port_poll_in_busy(dev); | ||
644 | if (ret < 0) | ||
645 | return ret; | ||
646 | |||
647 | /* Should check status before starting FLASH access sequence */ | ||
648 | |||
649 | /* Wait for status information */ | ||
650 | ret = c2port_poll_out_ready(dev); | ||
651 | if (ret < 0) | ||
652 | return ret; | ||
653 | |||
654 | /* Read flash programming interface status */ | ||
655 | ret = c2port_read_dr(dev, &status); | ||
656 | if (ret < 0) | ||
657 | return ret; | ||
658 | if (status != C2PORT_COMMAND_OK) | ||
659 | return -EBUSY; | ||
660 | |||
661 | /* Send address high byte */ | ||
662 | c2port_write_dr(dev, offset >> 8); | ||
663 | ret = c2port_poll_in_busy(dev); | ||
664 | if (ret < 0) | ||
665 | return ret; | ||
666 | |||
667 | /* Send address low byte */ | ||
668 | c2port_write_dr(dev, offset & 0x00ff); | ||
669 | ret = c2port_poll_in_busy(dev); | ||
670 | if (ret < 0) | ||
671 | return ret; | ||
672 | |||
673 | /* Send address block size */ | ||
674 | c2port_write_dr(dev, nread); | ||
675 | ret = c2port_poll_in_busy(dev); | ||
676 | if (ret < 0) | ||
677 | return ret; | ||
678 | |||
679 | /* Should check status before reading FLASH block */ | ||
680 | |||
681 | /* Wait for status information */ | ||
682 | ret = c2port_poll_out_ready(dev); | ||
683 | if (ret < 0) | ||
684 | return ret; | ||
685 | |||
686 | /* Read flash programming interface status */ | ||
687 | ret = c2port_read_dr(dev, &status); | ||
688 | if (ret < 0) | ||
689 | return ret; | ||
690 | if (status != C2PORT_COMMAND_OK) | ||
691 | return -EBUSY; | ||
692 | |||
693 | /* Read flash block */ | ||
694 | for (i = 0; i < nread; i++) { | ||
695 | ret = c2port_poll_out_ready(dev); | ||
696 | if (ret < 0) | ||
697 | return ret; | ||
698 | |||
699 | ret = c2port_read_dr(dev, buffer+i); | ||
700 | if (ret < 0) | ||
701 | return ret; | ||
702 | } | ||
703 | |||
704 | return nread; | ||
705 | } | ||
706 | |||
707 | static ssize_t c2port_read_flash_data(struct kobject *kobj, | ||
708 | struct bin_attribute *attr, | ||
709 | char *buffer, loff_t offset, size_t count) | ||
710 | { | ||
711 | struct c2port_device *c2dev = | ||
712 | dev_get_drvdata(container_of(kobj, | ||
713 | struct device, kobj)); | ||
714 | ssize_t ret; | ||
715 | |||
716 | /* Check the device and flash access status */ | ||
717 | if (!c2dev->access || !c2dev->flash_access) | ||
718 | return -EBUSY; | ||
719 | |||
720 | mutex_lock(&c2dev->mutex); | ||
721 | ret = __c2port_read_flash_data(c2dev, buffer, offset, count); | ||
722 | mutex_unlock(&c2dev->mutex); | ||
723 | |||
724 | if (ret < 0) | ||
725 | dev_err(c2dev->dev, "cannot read %s flash\n", c2dev->name); | ||
726 | |||
727 | return ret; | ||
728 | } | ||
729 | |||
730 | static ssize_t __c2port_write_flash_data(struct c2port_device *dev, | ||
731 | char *buffer, loff_t offset, size_t count) | ||
732 | { | ||
733 | struct c2port_ops *ops = dev->ops; | ||
734 | u8 status, nwrite = 128; | ||
735 | int i, ret; | ||
736 | |||
737 | if (nwrite > count) | ||
738 | nwrite = count; | ||
739 | if (ops->block_size * ops->blocks_num - offset < nwrite) | ||
740 | nwrite = ops->block_size * ops->blocks_num - offset; | ||
741 | |||
742 | /* Check for flash end */ | ||
743 | if (offset >= ops->block_size * ops->blocks_num) | ||
744 | return -EINVAL; | ||
745 | |||
746 | /* Target the C2 flash programming data register for C2 data register | ||
747 | * access */ | ||
748 | c2port_write_ar(dev, C2PORT_FPDAT); | ||
749 | |||
750 | /* Send flash block write command */ | ||
751 | c2port_write_dr(dev, C2PORT_BLOCK_WRITE); | ||
752 | |||
753 | /* Wait for input acknowledge */ | ||
754 | ret = c2port_poll_in_busy(dev); | ||
755 | if (ret < 0) | ||
756 | return ret; | ||
757 | |||
758 | /* Should check status before starting FLASH access sequence */ | ||
759 | |||
760 | /* Wait for status information */ | ||
761 | ret = c2port_poll_out_ready(dev); | ||
762 | if (ret < 0) | ||
763 | return ret; | ||
764 | |||
765 | /* Read flash programming interface status */ | ||
766 | ret = c2port_read_dr(dev, &status); | ||
767 | if (ret < 0) | ||
768 | return ret; | ||
769 | if (status != C2PORT_COMMAND_OK) | ||
770 | return -EBUSY; | ||
771 | |||
772 | /* Send address high byte */ | ||
773 | c2port_write_dr(dev, offset >> 8); | ||
774 | ret = c2port_poll_in_busy(dev); | ||
775 | if (ret < 0) | ||
776 | return ret; | ||
777 | |||
778 | /* Send address low byte */ | ||
779 | c2port_write_dr(dev, offset & 0x00ff); | ||
780 | ret = c2port_poll_in_busy(dev); | ||
781 | if (ret < 0) | ||
782 | return ret; | ||
783 | |||
784 | /* Send address block size */ | ||
785 | c2port_write_dr(dev, nwrite); | ||
786 | ret = c2port_poll_in_busy(dev); | ||
787 | if (ret < 0) | ||
788 | return ret; | ||
789 | |||
790 | /* Should check status before writing FLASH block */ | ||
791 | |||
792 | /* Wait for status information */ | ||
793 | ret = c2port_poll_out_ready(dev); | ||
794 | if (ret < 0) | ||
795 | return ret; | ||
796 | |||
797 | /* Read flash programming interface status */ | ||
798 | ret = c2port_read_dr(dev, &status); | ||
799 | if (ret < 0) | ||
800 | return ret; | ||
801 | if (status != C2PORT_COMMAND_OK) | ||
802 | return -EBUSY; | ||
803 | |||
804 | /* Write flash block */ | ||
805 | for (i = 0; i < nwrite; i++) { | ||
806 | ret = c2port_write_dr(dev, *(buffer+i)); | ||
807 | if (ret < 0) | ||
808 | return ret; | ||
809 | |||
810 | ret = c2port_poll_in_busy(dev); | ||
811 | if (ret < 0) | ||
812 | return ret; | ||
813 | |||
814 | } | ||
815 | |||
816 | /* Wait for last flash write to complete */ | ||
817 | ret = c2port_poll_out_ready(dev); | ||
818 | if (ret < 0) | ||
819 | return ret; | ||
820 | |||
821 | return nwrite; | ||
822 | } | ||
823 | |||
824 | static ssize_t c2port_write_flash_data(struct kobject *kobj, | ||
825 | struct bin_attribute *attr, | ||
826 | char *buffer, loff_t offset, size_t count) | ||
827 | { | ||
828 | struct c2port_device *c2dev = | ||
829 | dev_get_drvdata(container_of(kobj, | ||
830 | struct device, kobj)); | ||
831 | int ret; | ||
832 | |||
833 | /* Check the device access status */ | ||
834 | if (!c2dev->access || !c2dev->flash_access) | ||
835 | return -EBUSY; | ||
836 | |||
837 | mutex_lock(&c2dev->mutex); | ||
838 | ret = __c2port_write_flash_data(c2dev, buffer, offset, count); | ||
839 | mutex_unlock(&c2dev->mutex); | ||
840 | |||
841 | if (ret < 0) | ||
842 | dev_err(c2dev->dev, "cannot write %s flash\n", c2dev->name); | ||
843 | |||
844 | return ret; | ||
845 | } | ||
846 | |||
847 | /* | ||
848 | * Class attributes | ||
849 | */ | ||
850 | |||
851 | static struct device_attribute c2port_attrs[] = { | ||
852 | __ATTR(name, 0444, c2port_show_name, NULL), | ||
853 | __ATTR(flash_blocks_num, 0444, c2port_show_flash_blocks_num, NULL), | ||
854 | __ATTR(flash_block_size, 0444, c2port_show_flash_block_size, NULL), | ||
855 | __ATTR(flash_size, 0444, c2port_show_flash_size, NULL), | ||
856 | __ATTR(access, 0644, c2port_show_access, c2port_store_access), | ||
857 | __ATTR(reset, 0200, NULL, c2port_store_reset), | ||
858 | __ATTR(dev_id, 0444, c2port_show_dev_id, NULL), | ||
859 | __ATTR(rev_id, 0444, c2port_show_rev_id, NULL), | ||
860 | |||
861 | __ATTR(flash_access, 0644, c2port_show_flash_access, | ||
862 | c2port_store_flash_access), | ||
863 | __ATTR(flash_erase, 0200, NULL, c2port_store_flash_erase), | ||
864 | __ATTR_NULL, | ||
865 | }; | ||
866 | |||
867 | static struct bin_attribute c2port_bin_attrs = { | ||
868 | .attr = { | ||
869 | .name = "flash_data", | ||
870 | .mode = 0644 | ||
871 | }, | ||
872 | .read = c2port_read_flash_data, | ||
873 | .write = c2port_write_flash_data, | ||
874 | /* .size is computed at run-time */ | ||
875 | }; | ||
876 | |||
877 | /* | ||
878 | * Exported functions | ||
879 | */ | ||
880 | |||
881 | struct c2port_device *c2port_device_register(char *name, | ||
882 | struct c2port_ops *ops, void *devdata) | ||
883 | { | ||
884 | struct c2port_device *c2dev; | ||
885 | int id, ret; | ||
886 | |||
887 | if (unlikely(!ops) || unlikely(!ops->access) || \ | ||
888 | unlikely(!ops->c2d_dir) || unlikely(!ops->c2ck_set) || \ | ||
889 | unlikely(!ops->c2d_get) || unlikely(!ops->c2d_set)) | ||
890 | return ERR_PTR(-EINVAL); | ||
891 | |||
892 | c2dev = kmalloc(sizeof(struct c2port_device), GFP_KERNEL); | ||
893 | if (unlikely(!c2dev)) | ||
894 | return ERR_PTR(-ENOMEM); | ||
895 | |||
896 | ret = idr_pre_get(&c2port_idr, GFP_KERNEL); | ||
897 | if (!ret) { | ||
898 | ret = -ENOMEM; | ||
899 | goto error_idr_get_new; | ||
900 | } | ||
901 | |||
902 | spin_lock_irq(&c2port_idr_lock); | ||
903 | ret = idr_get_new(&c2port_idr, c2dev, &id); | ||
904 | spin_unlock_irq(&c2port_idr_lock); | ||
905 | |||
906 | if (ret < 0) | ||
907 | goto error_idr_get_new; | ||
908 | c2dev->id = id; | ||
909 | |||
910 | c2dev->dev = device_create(c2port_class, NULL, 0, c2dev, | ||
911 | "c2port%d", id); | ||
912 | if (unlikely(!c2dev->dev)) { | ||
913 | ret = -ENOMEM; | ||
914 | goto error_device_create; | ||
915 | } | ||
916 | dev_set_drvdata(c2dev->dev, c2dev); | ||
917 | |||
918 | strncpy(c2dev->name, name, C2PORT_NAME_LEN); | ||
919 | c2dev->ops = ops; | ||
920 | mutex_init(&c2dev->mutex); | ||
921 | |||
922 | /* Create binary file */ | ||
923 | c2port_bin_attrs.size = ops->blocks_num * ops->block_size; | ||
924 | ret = device_create_bin_file(c2dev->dev, &c2port_bin_attrs); | ||
925 | if (unlikely(ret)) | ||
926 | goto error_device_create_bin_file; | ||
927 | |||
928 | /* By default C2 port access is off */ | ||
929 | c2dev->access = c2dev->flash_access = 0; | ||
930 | ops->access(c2dev, 0); | ||
931 | |||
932 | dev_info(c2dev->dev, "C2 port %s added\n", name); | ||
933 | dev_info(c2dev->dev, "%s flash has %d blocks x %d bytes " | ||
934 | "(%d bytes total)\n", | ||
935 | name, ops->blocks_num, ops->block_size, | ||
936 | ops->blocks_num * ops->block_size); | ||
937 | |||
938 | return c2dev; | ||
939 | |||
940 | error_device_create_bin_file: | ||
941 | device_destroy(c2port_class, 0); | ||
942 | |||
943 | error_device_create: | ||
944 | spin_lock_irq(&c2port_idr_lock); | ||
945 | idr_remove(&c2port_idr, id); | ||
946 | spin_unlock_irq(&c2port_idr_lock); | ||
947 | |||
948 | error_idr_get_new: | ||
949 | kfree(c2dev); | ||
950 | |||
951 | return ERR_PTR(ret); | ||
952 | } | ||
953 | EXPORT_SYMBOL(c2port_device_register); | ||
954 | |||
955 | void c2port_device_unregister(struct c2port_device *c2dev) | ||
956 | { | ||
957 | if (!c2dev) | ||
958 | return; | ||
959 | |||
960 | dev_info(c2dev->dev, "C2 port %s removed\n", c2dev->name); | ||
961 | |||
962 | device_remove_bin_file(c2dev->dev, &c2port_bin_attrs); | ||
963 | spin_lock_irq(&c2port_idr_lock); | ||
964 | idr_remove(&c2port_idr, c2dev->id); | ||
965 | spin_unlock_irq(&c2port_idr_lock); | ||
966 | |||
967 | device_destroy(c2port_class, c2dev->id); | ||
968 | |||
969 | kfree(c2dev); | ||
970 | } | ||
971 | EXPORT_SYMBOL(c2port_device_unregister); | ||
972 | |||
973 | /* | ||
974 | * Module stuff | ||
975 | */ | ||
976 | |||
977 | static int __init c2port_init(void) | ||
978 | { | ||
979 | printk(KERN_INFO "Silicon Labs C2 port support v. " DRIVER_VERSION | ||
980 | " - (C) 2007 Rodolfo Giometti\n"); | ||
981 | |||
982 | c2port_class = class_create(THIS_MODULE, "c2port"); | ||
983 | if (!c2port_class) { | ||
984 | printk(KERN_ERR "c2port: failed to allocate class\n"); | ||
985 | return -ENOMEM; | ||
986 | } | ||
987 | c2port_class->dev_attrs = c2port_attrs; | ||
988 | |||
989 | return 0; | ||
990 | } | ||
991 | |||
992 | static void __exit c2port_exit(void) | ||
993 | { | ||
994 | class_destroy(c2port_class); | ||
995 | } | ||
996 | |||
997 | module_init(c2port_init); | ||
998 | module_exit(c2port_exit); | ||
999 | |||
1000 | MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); | ||
1001 | MODULE_DESCRIPTION("Silicon Labs C2 port support v. " DRIVER_VERSION); | ||
1002 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/misc/compal-laptop.c b/drivers/misc/compal-laptop.c index 344b790a6253..11003bba10d3 100644 --- a/drivers/misc/compal-laptop.c +++ b/drivers/misc/compal-laptop.c | |||
@@ -326,12 +326,14 @@ static int __init compal_init(void) | |||
326 | 326 | ||
327 | /* Register backlight stuff */ | 327 | /* Register backlight stuff */ |
328 | 328 | ||
329 | compalbl_device = backlight_device_register("compal-laptop", NULL, NULL, | 329 | if (!acpi_video_backlight_support()) { |
330 | &compalbl_ops); | 330 | compalbl_device = backlight_device_register("compal-laptop", NULL, NULL, |
331 | if (IS_ERR(compalbl_device)) | 331 | &compalbl_ops); |
332 | return PTR_ERR(compalbl_device); | 332 | if (IS_ERR(compalbl_device)) |
333 | return PTR_ERR(compalbl_device); | ||
333 | 334 | ||
334 | compalbl_device->props.max_brightness = COMPAL_LCD_LEVEL_MAX-1; | 335 | compalbl_device->props.max_brightness = COMPAL_LCD_LEVEL_MAX-1; |
336 | } | ||
335 | 337 | ||
336 | ret = platform_driver_register(&compal_driver); | 338 | ret = platform_driver_register(&compal_driver); |
337 | if (ret) | 339 | if (ret) |
diff --git a/drivers/misc/eeepc-laptop.c b/drivers/misc/eeepc-laptop.c index 9ef98b2d5039..02fe2b8b8939 100644 --- a/drivers/misc/eeepc-laptop.c +++ b/drivers/misc/eeepc-laptop.c | |||
@@ -825,9 +825,15 @@ static int __init eeepc_laptop_init(void) | |||
825 | return -ENODEV; | 825 | return -ENODEV; |
826 | } | 826 | } |
827 | dev = acpi_get_physical_device(ehotk->device->handle); | 827 | dev = acpi_get_physical_device(ehotk->device->handle); |
828 | result = eeepc_backlight_init(dev); | 828 | |
829 | if (result) | 829 | if (!acpi_video_backlight_support()) { |
830 | goto fail_backlight; | 830 | result = eeepc_backlight_init(dev); |
831 | if (result) | ||
832 | goto fail_backlight; | ||
833 | } else | ||
834 | printk(EEEPC_INFO "Backlight controlled by ACPI video " | ||
835 | "driver\n"); | ||
836 | |||
831 | result = eeepc_hwmon_init(dev); | 837 | result = eeepc_hwmon_init(dev); |
832 | if (result) | 838 | if (result) |
833 | goto fail_hwmon; | 839 | goto fail_hwmon; |
diff --git a/drivers/misc/fujitsu-laptop.c b/drivers/misc/fujitsu-laptop.c index d2cf0bfe3163..a7dd3e9fb79d 100644 --- a/drivers/misc/fujitsu-laptop.c +++ b/drivers/misc/fujitsu-laptop.c | |||
@@ -464,6 +464,14 @@ static int dmi_check_cb_s6410(const struct dmi_system_id *id) | |||
464 | return 0; | 464 | return 0; |
465 | } | 465 | } |
466 | 466 | ||
467 | static int dmi_check_cb_s6420(const struct dmi_system_id *id) | ||
468 | { | ||
469 | dmi_check_cb_common(id); | ||
470 | fujitsu->keycode1 = KEY_SCREENLOCK; /* "Lock" */ | ||
471 | fujitsu->keycode2 = KEY_HELP; /* "Mobility Center" */ | ||
472 | return 0; | ||
473 | } | ||
474 | |||
467 | static int dmi_check_cb_p8010(const struct dmi_system_id *id) | 475 | static int dmi_check_cb_p8010(const struct dmi_system_id *id) |
468 | { | 476 | { |
469 | dmi_check_cb_common(id); | 477 | dmi_check_cb_common(id); |
@@ -473,7 +481,7 @@ static int dmi_check_cb_p8010(const struct dmi_system_id *id) | |||
473 | return 0; | 481 | return 0; |
474 | } | 482 | } |
475 | 483 | ||
476 | static struct dmi_system_id __initdata fujitsu_dmi_table[] = { | 484 | static struct dmi_system_id fujitsu_dmi_table[] = { |
477 | { | 485 | { |
478 | .ident = "Fujitsu Siemens S6410", | 486 | .ident = "Fujitsu Siemens S6410", |
479 | .matches = { | 487 | .matches = { |
@@ -482,6 +490,13 @@ static struct dmi_system_id __initdata fujitsu_dmi_table[] = { | |||
482 | }, | 490 | }, |
483 | .callback = dmi_check_cb_s6410}, | 491 | .callback = dmi_check_cb_s6410}, |
484 | { | 492 | { |
493 | .ident = "Fujitsu Siemens S6420", | ||
494 | .matches = { | ||
495 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
496 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK S6420"), | ||
497 | }, | ||
498 | .callback = dmi_check_cb_s6420}, | ||
499 | { | ||
485 | .ident = "Fujitsu LifeBook P8010", | 500 | .ident = "Fujitsu LifeBook P8010", |
486 | .matches = { | 501 | .matches = { |
487 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | 502 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), |
@@ -990,16 +1005,16 @@ static int __init fujitsu_init(void) | |||
990 | 1005 | ||
991 | /* Register backlight stuff */ | 1006 | /* Register backlight stuff */ |
992 | 1007 | ||
993 | fujitsu->bl_device = | 1008 | if (!acpi_video_backlight_support()) { |
994 | backlight_device_register("fujitsu-laptop", NULL, NULL, | 1009 | fujitsu->bl_device = |
995 | &fujitsubl_ops); | 1010 | backlight_device_register("fujitsu-laptop", NULL, NULL, |
996 | if (IS_ERR(fujitsu->bl_device)) | 1011 | &fujitsubl_ops); |
997 | return PTR_ERR(fujitsu->bl_device); | 1012 | if (IS_ERR(fujitsu->bl_device)) |
998 | 1013 | return PTR_ERR(fujitsu->bl_device); | |
999 | max_brightness = fujitsu->max_brightness; | 1014 | max_brightness = fujitsu->max_brightness; |
1000 | 1015 | fujitsu->bl_device->props.max_brightness = max_brightness - 1; | |
1001 | fujitsu->bl_device->props.max_brightness = max_brightness - 1; | 1016 | fujitsu->bl_device->props.brightness = fujitsu->brightness_level; |
1002 | fujitsu->bl_device->props.brightness = fujitsu->brightness_level; | 1017 | } |
1003 | 1018 | ||
1004 | ret = platform_driver_register(&fujitsupf_driver); | 1019 | ret = platform_driver_register(&fujitsupf_driver); |
1005 | if (ret) | 1020 | if (ret) |
@@ -1035,7 +1050,8 @@ fail_hotkey: | |||
1035 | 1050 | ||
1036 | fail_backlight: | 1051 | fail_backlight: |
1037 | 1052 | ||
1038 | backlight_device_unregister(fujitsu->bl_device); | 1053 | if (fujitsu->bl_device) |
1054 | backlight_device_unregister(fujitsu->bl_device); | ||
1039 | 1055 | ||
1040 | fail_platform_device2: | 1056 | fail_platform_device2: |
1041 | 1057 | ||
@@ -1062,7 +1078,8 @@ static void __exit fujitsu_cleanup(void) | |||
1062 | &fujitsupf_attribute_group); | 1078 | &fujitsupf_attribute_group); |
1063 | platform_device_unregister(fujitsu->pf_device); | 1079 | platform_device_unregister(fujitsu->pf_device); |
1064 | platform_driver_unregister(&fujitsupf_driver); | 1080 | platform_driver_unregister(&fujitsupf_driver); |
1065 | backlight_device_unregister(fujitsu->bl_device); | 1081 | if (fujitsu->bl_device) |
1082 | backlight_device_unregister(fujitsu->bl_device); | ||
1066 | 1083 | ||
1067 | acpi_bus_unregister_driver(&acpi_fujitsu_driver); | 1084 | acpi_bus_unregister_driver(&acpi_fujitsu_driver); |
1068 | 1085 | ||
diff --git a/drivers/misc/ics932s401.c b/drivers/misc/ics932s401.c new file mode 100644 index 000000000000..6e43ab4231ae --- /dev/null +++ b/drivers/misc/ics932s401.c | |||
@@ -0,0 +1,515 @@ | |||
1 | /* | ||
2 | * A driver for the Integrated Circuits ICS932S401 | ||
3 | * Copyright (C) 2008 IBM | ||
4 | * | ||
5 | * Author: Darrick J. Wong <djwong@us.ibm.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/jiffies.h> | ||
24 | #include <linux/i2c.h> | ||
25 | #include <linux/err.h> | ||
26 | #include <linux/mutex.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/log2.h> | ||
29 | |||
30 | /* Addresses to scan */ | ||
31 | static const unsigned short normal_i2c[] = { 0x69, I2C_CLIENT_END }; | ||
32 | |||
33 | /* Insmod parameters */ | ||
34 | I2C_CLIENT_INSMOD_1(ics932s401); | ||
35 | |||
36 | /* ICS932S401 registers */ | ||
37 | #define ICS932S401_REG_CFG2 0x01 | ||
38 | #define ICS932S401_CFG1_SPREAD 0x01 | ||
39 | #define ICS932S401_REG_CFG7 0x06 | ||
40 | #define ICS932S401_FS_MASK 0x07 | ||
41 | #define ICS932S401_REG_VENDOR_REV 0x07 | ||
42 | #define ICS932S401_VENDOR 1 | ||
43 | #define ICS932S401_VENDOR_MASK 0x0F | ||
44 | #define ICS932S401_REV 4 | ||
45 | #define ICS932S401_REV_SHIFT 4 | ||
46 | #define ICS932S401_REG_DEVICE 0x09 | ||
47 | #define ICS932S401_DEVICE 11 | ||
48 | #define ICS932S401_REG_CTRL 0x0A | ||
49 | #define ICS932S401_MN_ENABLED 0x80 | ||
50 | #define ICS932S401_CPU_ALT 0x04 | ||
51 | #define ICS932S401_SRC_ALT 0x08 | ||
52 | #define ICS932S401_REG_CPU_M_CTRL 0x0B | ||
53 | #define ICS932S401_M_MASK 0x3F | ||
54 | #define ICS932S401_REG_CPU_N_CTRL 0x0C | ||
55 | #define ICS932S401_REG_CPU_SPREAD1 0x0D | ||
56 | #define ICS932S401_REG_CPU_SPREAD2 0x0E | ||
57 | #define ICS932S401_SPREAD_MASK 0x7FFF | ||
58 | #define ICS932S401_REG_SRC_M_CTRL 0x0F | ||
59 | #define ICS932S401_REG_SRC_N_CTRL 0x10 | ||
60 | #define ICS932S401_REG_SRC_SPREAD1 0x11 | ||
61 | #define ICS932S401_REG_SRC_SPREAD2 0x12 | ||
62 | #define ICS932S401_REG_CPU_DIVISOR 0x13 | ||
63 | #define ICS932S401_CPU_DIVISOR_SHIFT 4 | ||
64 | #define ICS932S401_REG_PCISRC_DIVISOR 0x14 | ||
65 | #define ICS932S401_SRC_DIVISOR_MASK 0x0F | ||
66 | #define ICS932S401_PCI_DIVISOR_SHIFT 4 | ||
67 | |||
68 | /* Base clock is 14.318MHz */ | ||
69 | #define BASE_CLOCK 14318 | ||
70 | |||
71 | #define NUM_REGS 21 | ||
72 | #define NUM_MIRRORED_REGS 15 | ||
73 | |||
74 | static int regs_to_copy[NUM_MIRRORED_REGS] = { | ||
75 | ICS932S401_REG_CFG2, | ||
76 | ICS932S401_REG_CFG7, | ||
77 | ICS932S401_REG_VENDOR_REV, | ||
78 | ICS932S401_REG_DEVICE, | ||
79 | ICS932S401_REG_CTRL, | ||
80 | ICS932S401_REG_CPU_M_CTRL, | ||
81 | ICS932S401_REG_CPU_N_CTRL, | ||
82 | ICS932S401_REG_CPU_SPREAD1, | ||
83 | ICS932S401_REG_CPU_SPREAD2, | ||
84 | ICS932S401_REG_SRC_M_CTRL, | ||
85 | ICS932S401_REG_SRC_N_CTRL, | ||
86 | ICS932S401_REG_SRC_SPREAD1, | ||
87 | ICS932S401_REG_SRC_SPREAD2, | ||
88 | ICS932S401_REG_CPU_DIVISOR, | ||
89 | ICS932S401_REG_PCISRC_DIVISOR, | ||
90 | }; | ||
91 | |||
92 | /* How often do we reread sensors values? (In jiffies) */ | ||
93 | #define SENSOR_REFRESH_INTERVAL (2 * HZ) | ||
94 | |||
95 | /* How often do we reread sensor limit values? (In jiffies) */ | ||
96 | #define LIMIT_REFRESH_INTERVAL (60 * HZ) | ||
97 | |||
98 | struct ics932s401_data { | ||
99 | struct attribute_group attrs; | ||
100 | struct mutex lock; | ||
101 | char sensors_valid; | ||
102 | unsigned long sensors_last_updated; /* In jiffies */ | ||
103 | |||
104 | u8 regs[NUM_REGS]; | ||
105 | }; | ||
106 | |||
107 | static int ics932s401_probe(struct i2c_client *client, | ||
108 | const struct i2c_device_id *id); | ||
109 | static int ics932s401_detect(struct i2c_client *client, int kind, | ||
110 | struct i2c_board_info *info); | ||
111 | static int ics932s401_remove(struct i2c_client *client); | ||
112 | |||
113 | static const struct i2c_device_id ics932s401_id[] = { | ||
114 | { "ics932s401", ics932s401 }, | ||
115 | { } | ||
116 | }; | ||
117 | MODULE_DEVICE_TABLE(i2c, ics932s401_id); | ||
118 | |||
119 | static struct i2c_driver ics932s401_driver = { | ||
120 | .class = I2C_CLASS_HWMON, | ||
121 | .driver = { | ||
122 | .name = "ics932s401", | ||
123 | }, | ||
124 | .probe = ics932s401_probe, | ||
125 | .remove = ics932s401_remove, | ||
126 | .id_table = ics932s401_id, | ||
127 | .detect = ics932s401_detect, | ||
128 | .address_data = &addr_data, | ||
129 | }; | ||
130 | |||
131 | static struct ics932s401_data *ics932s401_update_device(struct device *dev) | ||
132 | { | ||
133 | struct i2c_client *client = to_i2c_client(dev); | ||
134 | struct ics932s401_data *data = i2c_get_clientdata(client); | ||
135 | unsigned long local_jiffies = jiffies; | ||
136 | int i, temp; | ||
137 | |||
138 | mutex_lock(&data->lock); | ||
139 | if (time_before(local_jiffies, data->sensors_last_updated + | ||
140 | SENSOR_REFRESH_INTERVAL) | ||
141 | && data->sensors_valid) | ||
142 | goto out; | ||
143 | |||
144 | /* | ||
145 | * Each register must be read as a word and then right shifted 8 bits. | ||
146 | * Not really sure why this is; setting the "byte count programming" | ||
147 | * register to 1 does not fix this problem. | ||
148 | */ | ||
149 | for (i = 0; i < NUM_MIRRORED_REGS; i++) { | ||
150 | temp = i2c_smbus_read_word_data(client, regs_to_copy[i]); | ||
151 | data->regs[regs_to_copy[i]] = temp >> 8; | ||
152 | } | ||
153 | |||
154 | data->sensors_last_updated = local_jiffies; | ||
155 | data->sensors_valid = 1; | ||
156 | |||
157 | out: | ||
158 | mutex_unlock(&data->lock); | ||
159 | return data; | ||
160 | } | ||
161 | |||
162 | static ssize_t show_spread_enabled(struct device *dev, | ||
163 | struct device_attribute *devattr, | ||
164 | char *buf) | ||
165 | { | ||
166 | struct ics932s401_data *data = ics932s401_update_device(dev); | ||
167 | |||
168 | if (data->regs[ICS932S401_REG_CFG2] & ICS932S401_CFG1_SPREAD) | ||
169 | return sprintf(buf, "1\n"); | ||
170 | |||
171 | return sprintf(buf, "0\n"); | ||
172 | } | ||
173 | |||
174 | /* bit to cpu khz map */ | ||
175 | static const int fs_speeds[] = { | ||
176 | 266666, | ||
177 | 133333, | ||
178 | 200000, | ||
179 | 166666, | ||
180 | 333333, | ||
181 | 100000, | ||
182 | 400000, | ||
183 | 0, | ||
184 | }; | ||
185 | |||
186 | /* clock divisor map */ | ||
187 | static const int divisors[] = {2, 3, 5, 15, 4, 6, 10, 30, 8, 12, 20, 60, 16, | ||
188 | 24, 40, 120}; | ||
189 | |||
190 | /* Calculate CPU frequency from the M/N registers. */ | ||
191 | static int calculate_cpu_freq(struct ics932s401_data *data) | ||
192 | { | ||
193 | int m, n, freq; | ||
194 | |||
195 | m = data->regs[ICS932S401_REG_CPU_M_CTRL] & ICS932S401_M_MASK; | ||
196 | n = data->regs[ICS932S401_REG_CPU_N_CTRL]; | ||
197 | |||
198 | /* Pull in bits 8 & 9 from the M register */ | ||
199 | n |= ((int)data->regs[ICS932S401_REG_CPU_M_CTRL] & 0x80) << 1; | ||
200 | n |= ((int)data->regs[ICS932S401_REG_CPU_M_CTRL] & 0x40) << 3; | ||
201 | |||
202 | freq = BASE_CLOCK * (n + 8) / (m + 2); | ||
203 | freq /= divisors[data->regs[ICS932S401_REG_CPU_DIVISOR] >> | ||
204 | ICS932S401_CPU_DIVISOR_SHIFT]; | ||
205 | |||
206 | return freq; | ||
207 | } | ||
208 | |||
209 | static ssize_t show_cpu_clock(struct device *dev, | ||
210 | struct device_attribute *devattr, | ||
211 | char *buf) | ||
212 | { | ||
213 | struct ics932s401_data *data = ics932s401_update_device(dev); | ||
214 | |||
215 | return sprintf(buf, "%d\n", calculate_cpu_freq(data)); | ||
216 | } | ||
217 | |||
218 | static ssize_t show_cpu_clock_sel(struct device *dev, | ||
219 | struct device_attribute *devattr, | ||
220 | char *buf) | ||
221 | { | ||
222 | struct ics932s401_data *data = ics932s401_update_device(dev); | ||
223 | int freq; | ||
224 | |||
225 | if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_MN_ENABLED) | ||
226 | freq = calculate_cpu_freq(data); | ||
227 | else { | ||
228 | /* Freq is neatly wrapped up for us */ | ||
229 | int fid = data->regs[ICS932S401_REG_CFG7] & ICS932S401_FS_MASK; | ||
230 | freq = fs_speeds[fid]; | ||
231 | if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_CPU_ALT) { | ||
232 | switch (freq) { | ||
233 | case 166666: | ||
234 | freq = 160000; | ||
235 | break; | ||
236 | case 333333: | ||
237 | freq = 320000; | ||
238 | break; | ||
239 | } | ||
240 | } | ||
241 | } | ||
242 | |||
243 | return sprintf(buf, "%d\n", freq); | ||
244 | } | ||
245 | |||
246 | /* Calculate SRC frequency from the M/N registers. */ | ||
247 | static int calculate_src_freq(struct ics932s401_data *data) | ||
248 | { | ||
249 | int m, n, freq; | ||
250 | |||
251 | m = data->regs[ICS932S401_REG_SRC_M_CTRL] & ICS932S401_M_MASK; | ||
252 | n = data->regs[ICS932S401_REG_SRC_N_CTRL]; | ||
253 | |||
254 | /* Pull in bits 8 & 9 from the M register */ | ||
255 | n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x80) << 1; | ||
256 | n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x40) << 3; | ||
257 | |||
258 | freq = BASE_CLOCK * (n + 8) / (m + 2); | ||
259 | freq /= divisors[data->regs[ICS932S401_REG_PCISRC_DIVISOR] & | ||
260 | ICS932S401_SRC_DIVISOR_MASK]; | ||
261 | |||
262 | return freq; | ||
263 | } | ||
264 | |||
265 | static ssize_t show_src_clock(struct device *dev, | ||
266 | struct device_attribute *devattr, | ||
267 | char *buf) | ||
268 | { | ||
269 | struct ics932s401_data *data = ics932s401_update_device(dev); | ||
270 | |||
271 | return sprintf(buf, "%d\n", calculate_src_freq(data)); | ||
272 | } | ||
273 | |||
274 | static ssize_t show_src_clock_sel(struct device *dev, | ||
275 | struct device_attribute *devattr, | ||
276 | char *buf) | ||
277 | { | ||
278 | struct ics932s401_data *data = ics932s401_update_device(dev); | ||
279 | int freq; | ||
280 | |||
281 | if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_MN_ENABLED) | ||
282 | freq = calculate_src_freq(data); | ||
283 | else | ||
284 | /* Freq is neatly wrapped up for us */ | ||
285 | if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_CPU_ALT && | ||
286 | data->regs[ICS932S401_REG_CTRL] & ICS932S401_SRC_ALT) | ||
287 | freq = 96000; | ||
288 | else | ||
289 | freq = 100000; | ||
290 | |||
291 | return sprintf(buf, "%d\n", freq); | ||
292 | } | ||
293 | |||
294 | /* Calculate PCI frequency from the SRC M/N registers. */ | ||
295 | static int calculate_pci_freq(struct ics932s401_data *data) | ||
296 | { | ||
297 | int m, n, freq; | ||
298 | |||
299 | m = data->regs[ICS932S401_REG_SRC_M_CTRL] & ICS932S401_M_MASK; | ||
300 | n = data->regs[ICS932S401_REG_SRC_N_CTRL]; | ||
301 | |||
302 | /* Pull in bits 8 & 9 from the M register */ | ||
303 | n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x80) << 1; | ||
304 | n |= ((int)data->regs[ICS932S401_REG_SRC_M_CTRL] & 0x40) << 3; | ||
305 | |||
306 | freq = BASE_CLOCK * (n + 8) / (m + 2); | ||
307 | freq /= divisors[data->regs[ICS932S401_REG_PCISRC_DIVISOR] >> | ||
308 | ICS932S401_PCI_DIVISOR_SHIFT]; | ||
309 | |||
310 | return freq; | ||
311 | } | ||
312 | |||
313 | static ssize_t show_pci_clock(struct device *dev, | ||
314 | struct device_attribute *devattr, | ||
315 | char *buf) | ||
316 | { | ||
317 | struct ics932s401_data *data = ics932s401_update_device(dev); | ||
318 | |||
319 | return sprintf(buf, "%d\n", calculate_pci_freq(data)); | ||
320 | } | ||
321 | |||
322 | static ssize_t show_pci_clock_sel(struct device *dev, | ||
323 | struct device_attribute *devattr, | ||
324 | char *buf) | ||
325 | { | ||
326 | struct ics932s401_data *data = ics932s401_update_device(dev); | ||
327 | int freq; | ||
328 | |||
329 | if (data->regs[ICS932S401_REG_CTRL] & ICS932S401_MN_ENABLED) | ||
330 | freq = calculate_pci_freq(data); | ||
331 | else | ||
332 | freq = 33333; | ||
333 | |||
334 | return sprintf(buf, "%d\n", freq); | ||
335 | } | ||
336 | |||
337 | static ssize_t show_value(struct device *dev, | ||
338 | struct device_attribute *devattr, | ||
339 | char *buf); | ||
340 | |||
341 | static ssize_t show_spread(struct device *dev, | ||
342 | struct device_attribute *devattr, | ||
343 | char *buf); | ||
344 | |||
345 | static DEVICE_ATTR(spread_enabled, S_IRUGO, show_spread_enabled, NULL); | ||
346 | static DEVICE_ATTR(cpu_clock_selection, S_IRUGO, show_cpu_clock_sel, NULL); | ||
347 | static DEVICE_ATTR(cpu_clock, S_IRUGO, show_cpu_clock, NULL); | ||
348 | static DEVICE_ATTR(src_clock_selection, S_IRUGO, show_src_clock_sel, NULL); | ||
349 | static DEVICE_ATTR(src_clock, S_IRUGO, show_src_clock, NULL); | ||
350 | static DEVICE_ATTR(pci_clock_selection, S_IRUGO, show_pci_clock_sel, NULL); | ||
351 | static DEVICE_ATTR(pci_clock, S_IRUGO, show_pci_clock, NULL); | ||
352 | static DEVICE_ATTR(usb_clock, S_IRUGO, show_value, NULL); | ||
353 | static DEVICE_ATTR(ref_clock, S_IRUGO, show_value, NULL); | ||
354 | static DEVICE_ATTR(cpu_spread, S_IRUGO, show_spread, NULL); | ||
355 | static DEVICE_ATTR(src_spread, S_IRUGO, show_spread, NULL); | ||
356 | |||
357 | static struct attribute *ics932s401_attr[] = | ||
358 | { | ||
359 | &dev_attr_spread_enabled.attr, | ||
360 | &dev_attr_cpu_clock_selection.attr, | ||
361 | &dev_attr_cpu_clock.attr, | ||
362 | &dev_attr_src_clock_selection.attr, | ||
363 | &dev_attr_src_clock.attr, | ||
364 | &dev_attr_pci_clock_selection.attr, | ||
365 | &dev_attr_pci_clock.attr, | ||
366 | &dev_attr_usb_clock.attr, | ||
367 | &dev_attr_ref_clock.attr, | ||
368 | &dev_attr_cpu_spread.attr, | ||
369 | &dev_attr_src_spread.attr, | ||
370 | NULL | ||
371 | }; | ||
372 | |||
373 | static ssize_t show_value(struct device *dev, | ||
374 | struct device_attribute *devattr, | ||
375 | char *buf) | ||
376 | { | ||
377 | int x; | ||
378 | |||
379 | if (devattr == &dev_attr_usb_clock) | ||
380 | x = 48000; | ||
381 | else if (devattr == &dev_attr_ref_clock) | ||
382 | x = BASE_CLOCK; | ||
383 | else | ||
384 | BUG(); | ||
385 | |||
386 | return sprintf(buf, "%d\n", x); | ||
387 | } | ||
388 | |||
389 | static ssize_t show_spread(struct device *dev, | ||
390 | struct device_attribute *devattr, | ||
391 | char *buf) | ||
392 | { | ||
393 | struct ics932s401_data *data = ics932s401_update_device(dev); | ||
394 | int reg; | ||
395 | unsigned long val; | ||
396 | |||
397 | if (!(data->regs[ICS932S401_REG_CFG2] & ICS932S401_CFG1_SPREAD)) | ||
398 | return sprintf(buf, "0%%\n"); | ||
399 | |||
400 | if (devattr == &dev_attr_src_spread) | ||
401 | reg = ICS932S401_REG_SRC_SPREAD1; | ||
402 | else if (devattr == &dev_attr_cpu_spread) | ||
403 | reg = ICS932S401_REG_CPU_SPREAD1; | ||
404 | else | ||
405 | BUG(); | ||
406 | |||
407 | val = data->regs[reg] | (data->regs[reg + 1] << 8); | ||
408 | val &= ICS932S401_SPREAD_MASK; | ||
409 | |||
410 | /* Scale 0..2^14 to -0.5. */ | ||
411 | val = 500000 * val / 16384; | ||
412 | return sprintf(buf, "-0.%lu%%\n", val); | ||
413 | } | ||
414 | |||
415 | /* Return 0 if detection is successful, -ENODEV otherwise */ | ||
416 | static int ics932s401_detect(struct i2c_client *client, int kind, | ||
417 | struct i2c_board_info *info) | ||
418 | { | ||
419 | struct i2c_adapter *adapter = client->adapter; | ||
420 | |||
421 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
422 | return -ENODEV; | ||
423 | |||
424 | if (kind <= 0) { | ||
425 | int vendor, device, revision; | ||
426 | |||
427 | vendor = i2c_smbus_read_word_data(client, | ||
428 | ICS932S401_REG_VENDOR_REV); | ||
429 | vendor >>= 8; | ||
430 | revision = vendor >> ICS932S401_REV_SHIFT; | ||
431 | vendor &= ICS932S401_VENDOR_MASK; | ||
432 | if (vendor != ICS932S401_VENDOR) | ||
433 | return -ENODEV; | ||
434 | |||
435 | device = i2c_smbus_read_word_data(client, | ||
436 | ICS932S401_REG_DEVICE); | ||
437 | device >>= 8; | ||
438 | if (device != ICS932S401_DEVICE) | ||
439 | return -ENODEV; | ||
440 | |||
441 | if (revision != ICS932S401_REV) | ||
442 | dev_info(&adapter->dev, "Unknown revision %d\n", | ||
443 | revision); | ||
444 | } else | ||
445 | dev_dbg(&adapter->dev, "detection forced\n"); | ||
446 | |||
447 | strlcpy(info->type, "ics932s401", I2C_NAME_SIZE); | ||
448 | |||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | static int ics932s401_probe(struct i2c_client *client, | ||
453 | const struct i2c_device_id *id) | ||
454 | { | ||
455 | struct ics932s401_data *data; | ||
456 | int err; | ||
457 | |||
458 | data = kzalloc(sizeof(struct ics932s401_data), GFP_KERNEL); | ||
459 | if (!data) { | ||
460 | err = -ENOMEM; | ||
461 | goto exit; | ||
462 | } | ||
463 | |||
464 | i2c_set_clientdata(client, data); | ||
465 | mutex_init(&data->lock); | ||
466 | |||
467 | dev_info(&client->dev, "%s chip found\n", client->name); | ||
468 | |||
469 | /* Register sysfs hooks */ | ||
470 | data->attrs.attrs = ics932s401_attr; | ||
471 | err = sysfs_create_group(&client->dev.kobj, &data->attrs); | ||
472 | if (err) | ||
473 | goto exit_free; | ||
474 | |||
475 | return 0; | ||
476 | |||
477 | exit_free: | ||
478 | kfree(data); | ||
479 | exit: | ||
480 | return err; | ||
481 | } | ||
482 | |||
483 | static int ics932s401_remove(struct i2c_client *client) | ||
484 | { | ||
485 | struct ics932s401_data *data = i2c_get_clientdata(client); | ||
486 | |||
487 | sysfs_remove_group(&client->dev.kobj, &data->attrs); | ||
488 | kfree(data); | ||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | static int __init ics932s401_init(void) | ||
493 | { | ||
494 | return i2c_add_driver(&ics932s401_driver); | ||
495 | } | ||
496 | |||
497 | static void __exit ics932s401_exit(void) | ||
498 | { | ||
499 | i2c_del_driver(&ics932s401_driver); | ||
500 | } | ||
501 | |||
502 | MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); | ||
503 | MODULE_DESCRIPTION("ICS932S401 driver"); | ||
504 | MODULE_LICENSE("GPL"); | ||
505 | |||
506 | module_init(ics932s401_init); | ||
507 | module_exit(ics932s401_exit); | ||
508 | |||
509 | /* IBM IntelliStation Z30 */ | ||
510 | MODULE_ALIAS("dmi:bvnIBM:*:rn9228:*"); | ||
511 | MODULE_ALIAS("dmi:bvnIBM:*:rn9232:*"); | ||
512 | |||
513 | /* IBM x3650/x3550 */ | ||
514 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3650*"); | ||
515 | MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3550*"); | ||
diff --git a/drivers/misc/intel_menlow.c b/drivers/misc/intel_menlow.c index e00a2756e97e..27b7662955bb 100644 --- a/drivers/misc/intel_menlow.c +++ b/drivers/misc/intel_menlow.c | |||
@@ -52,6 +52,11 @@ MODULE_LICENSE("GPL"); | |||
52 | #define MEMORY_ARG_CUR_BANDWIDTH 1 | 52 | #define MEMORY_ARG_CUR_BANDWIDTH 1 |
53 | #define MEMORY_ARG_MAX_BANDWIDTH 0 | 53 | #define MEMORY_ARG_MAX_BANDWIDTH 0 |
54 | 54 | ||
55 | /* | ||
56 | * GTHS returning 'n' would mean that [0,n-1] states are supported | ||
57 | * In that case max_cstate would be n-1 | ||
58 | * GTHS returning '0' would mean that no bandwidth control states are supported | ||
59 | */ | ||
55 | static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev, | 60 | static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev, |
56 | unsigned long *max_state) | 61 | unsigned long *max_state) |
57 | { | 62 | { |
@@ -71,6 +76,9 @@ static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev, | |||
71 | if (ACPI_FAILURE(status)) | 76 | if (ACPI_FAILURE(status)) |
72 | return -EFAULT; | 77 | return -EFAULT; |
73 | 78 | ||
79 | if (!value) | ||
80 | return -EINVAL; | ||
81 | |||
74 | *max_state = value - 1; | 82 | *max_state = value - 1; |
75 | return 0; | 83 | return 0; |
76 | } | 84 | } |
@@ -121,7 +129,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev, | |||
121 | if (memory_get_int_max_bandwidth(cdev, &max_state)) | 129 | if (memory_get_int_max_bandwidth(cdev, &max_state)) |
122 | return -EFAULT; | 130 | return -EFAULT; |
123 | 131 | ||
124 | if (max_state < 0 || state > max_state) | 132 | if (state > max_state) |
125 | return -EINVAL; | 133 | return -EINVAL; |
126 | 134 | ||
127 | arg_list.count = 1; | 135 | arg_list.count = 1; |
diff --git a/drivers/misc/msi-laptop.c b/drivers/misc/msi-laptop.c index de898c6938f3..759763d18e4c 100644 --- a/drivers/misc/msi-laptop.c +++ b/drivers/misc/msi-laptop.c | |||
@@ -347,12 +347,16 @@ static int __init msi_init(void) | |||
347 | 347 | ||
348 | /* Register backlight stuff */ | 348 | /* Register backlight stuff */ |
349 | 349 | ||
350 | msibl_device = backlight_device_register("msi-laptop-bl", NULL, NULL, | 350 | if (acpi_video_backlight_support()) { |
351 | &msibl_ops); | 351 | printk(KERN_INFO "MSI: Brightness ignored, must be controlled " |
352 | if (IS_ERR(msibl_device)) | 352 | "by ACPI video driver\n"); |
353 | return PTR_ERR(msibl_device); | 353 | } else { |
354 | 354 | msibl_device = backlight_device_register("msi-laptop-bl", NULL, | |
355 | msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1; | 355 | NULL, &msibl_ops); |
356 | if (IS_ERR(msibl_device)) | ||
357 | return PTR_ERR(msibl_device); | ||
358 | msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1; | ||
359 | } | ||
356 | 360 | ||
357 | ret = platform_driver_register(&msipf_driver); | 361 | ret = platform_driver_register(&msipf_driver); |
358 | if (ret) | 362 | if (ret) |
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c index 06f07e19dc70..7bcb81002dcf 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c | |||
@@ -1038,7 +1038,11 @@ static int sony_nc_add(struct acpi_device *device) | |||
1038 | goto outinput; | 1038 | goto outinput; |
1039 | } | 1039 | } |
1040 | 1040 | ||
1041 | if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", &handle))) { | 1041 | if (!acpi_video_backlight_support()) { |
1042 | printk(KERN_INFO DRV_PFX "Sony: Brightness ignored, must be " | ||
1043 | "controlled by ACPI video driver\n"); | ||
1044 | } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", | ||
1045 | &handle))) { | ||
1042 | sony_backlight_device = backlight_device_register("sony", NULL, | 1046 | sony_backlight_device = backlight_device_register("sony", NULL, |
1043 | NULL, | 1047 | NULL, |
1044 | &sony_backlight_ops); | 1048 | &sony_backlight_ops); |
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 4db1cf9078d9..7a4a26b0edd2 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c | |||
@@ -4932,16 +4932,25 @@ static int __init brightness_init(struct ibm_init_struct *iibm) | |||
4932 | */ | 4932 | */ |
4933 | b = tpacpi_check_std_acpi_brightness_support(); | 4933 | b = tpacpi_check_std_acpi_brightness_support(); |
4934 | if (b > 0) { | 4934 | if (b > 0) { |
4935 | if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { | 4935 | |
4936 | printk(TPACPI_NOTICE | 4936 | if (acpi_video_backlight_support()) { |
4937 | "Lenovo BIOS switched to ACPI backlight " | 4937 | if (brightness_enable > 1) { |
4938 | "control mode\n"); | 4938 | printk(TPACPI_NOTICE |
4939 | } | 4939 | "Standard ACPI backlight interface " |
4940 | if (brightness_enable > 1) { | 4940 | "available, not loading native one.\n"); |
4941 | printk(TPACPI_NOTICE | 4941 | return 1; |
4942 | "standard ACPI backlight interface " | 4942 | } else if (brightness_enable == 1) { |
4943 | "available, not loading native one...\n"); | 4943 | printk(TPACPI_NOTICE |
4944 | return 1; | 4944 | "Backlight control force enabled, even if standard " |
4945 | "ACPI backlight interface is available\n"); | ||
4946 | } | ||
4947 | } else { | ||
4948 | if (brightness_enable > 1) { | ||
4949 | printk(TPACPI_NOTICE | ||
4950 | "Standard ACPI backlight interface not " | ||
4951 | "available, thinkpad_acpi native " | ||
4952 | "brightness control enabled\n"); | ||
4953 | } | ||
4945 | } | 4954 | } |
4946 | } | 4955 | } |
4947 | 4956 | ||
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 0d9b2d6f9ebf..f210a8ee6861 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c | |||
@@ -216,8 +216,7 @@ int mmc_add_card(struct mmc_card *card) | |||
216 | int ret; | 216 | int ret; |
217 | const char *type; | 217 | const char *type; |
218 | 218 | ||
219 | snprintf(card->dev.bus_id, sizeof(card->dev.bus_id), | 219 | dev_set_name(&card->dev, "%s:%04x", mmc_hostname(card->host), card->rca); |
220 | "%s:%04x", mmc_hostname(card->host), card->rca); | ||
221 | 220 | ||
222 | switch (card->type) { | 221 | switch (card->type) { |
223 | case MMC_TYPE_MMC: | 222 | case MMC_TYPE_MMC: |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 044d84eeed7c..f7284b905eb3 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -280,7 +280,11 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card) | |||
280 | (card->host->ios.clock / 1000); | 280 | (card->host->ios.clock / 1000); |
281 | 281 | ||
282 | if (data->flags & MMC_DATA_WRITE) | 282 | if (data->flags & MMC_DATA_WRITE) |
283 | limit_us = 250000; | 283 | /* |
284 | * The limit is really 250 ms, but that is | ||
285 | * insufficient for some crappy cards. | ||
286 | */ | ||
287 | limit_us = 300000; | ||
284 | else | 288 | else |
285 | limit_us = 100000; | 289 | limit_us = 100000; |
286 | 290 | ||
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 6da80fd4d974..5e945e64ead7 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
@@ -73,8 +73,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | |||
73 | if (err) | 73 | if (err) |
74 | goto free; | 74 | goto free; |
75 | 75 | ||
76 | snprintf(host->class_dev.bus_id, BUS_ID_SIZE, | 76 | dev_set_name(&host->class_dev, "mmc%d", host->index); |
77 | "mmc%d", host->index); | ||
78 | 77 | ||
79 | host->parent = dev; | 78 | host->parent = dev; |
80 | host->class_dev.parent = dev; | 79 | host->class_dev.parent = dev; |
@@ -121,7 +120,7 @@ int mmc_add_host(struct mmc_host *host) | |||
121 | WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) && | 120 | WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) && |
122 | !host->ops->enable_sdio_irq); | 121 | !host->ops->enable_sdio_irq); |
123 | 122 | ||
124 | led_trigger_register_simple(host->class_dev.bus_id, &host->led); | 123 | led_trigger_register_simple(dev_name(&host->class_dev), &host->led); |
125 | 124 | ||
126 | err = device_add(&host->class_dev); | 125 | err = device_add(&host->class_dev); |
127 | if (err) | 126 | if (err) |
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 233d0f9b3c4b..46284b527397 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c | |||
@@ -239,8 +239,7 @@ int sdio_add_func(struct sdio_func *func) | |||
239 | { | 239 | { |
240 | int ret; | 240 | int ret; |
241 | 241 | ||
242 | snprintf(func->dev.bus_id, sizeof(func->dev.bus_id), | 242 | dev_set_name(&func->dev, "%s:%d", mmc_card_id(func->card), func->num); |
243 | "%s:%d", mmc_card_id(func->card), func->num); | ||
244 | 243 | ||
245 | ret = device_add(&func->dev); | 244 | ret = device_add(&func->dev); |
246 | if (ret == 0) | 245 | if (ret == 0) |
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 07faf5412a1f..ad00e1632317 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c | |||
@@ -1348,7 +1348,7 @@ static int mmc_spi_probe(struct spi_device *spi) | |||
1348 | goto fail_add_host; | 1348 | goto fail_add_host; |
1349 | 1349 | ||
1350 | dev_info(&spi->dev, "SD/MMC host %s%s%s%s%s\n", | 1350 | dev_info(&spi->dev, "SD/MMC host %s%s%s%s%s\n", |
1351 | mmc->class_dev.bus_id, | 1351 | dev_name(&mmc->class_dev), |
1352 | host->dma_dev ? "" : ", no DMA", | 1352 | host->dma_dev ? "" : ", no DMA", |
1353 | (host->pdata && host->pdata->get_ro) | 1353 | (host->pdata && host->pdata->get_ro) |
1354 | ? "" : ", no WP", | 1354 | ? "" : ", no WP", |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 30f64b1f2354..4d010a984bed 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -1733,7 +1733,7 @@ int sdhci_add_host(struct sdhci_host *host) | |||
1733 | mmc_add_host(mmc); | 1733 | mmc_add_host(mmc); |
1734 | 1734 | ||
1735 | printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s%s\n", | 1735 | printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s%s\n", |
1736 | mmc_hostname(mmc), host->hw_name, mmc_dev(mmc)->bus_id, | 1736 | mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)), |
1737 | (host->flags & SDHCI_USE_ADMA)?"A":"", | 1737 | (host->flags & SDHCI_USE_ADMA)?"A":"", |
1738 | (host->flags & SDHCI_USE_DMA)?"DMA":"PIO"); | 1738 | (host->flags & SDHCI_USE_DMA)?"DMA":"PIO"); |
1739 | 1739 | ||
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c index 13844843e8de..82554ddec6b3 100644 --- a/drivers/mmc/host/tifm_sd.c +++ b/drivers/mmc/host/tifm_sd.c | |||
@@ -632,7 +632,7 @@ static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
632 | 632 | ||
633 | if (host->req) { | 633 | if (host->req) { |
634 | printk(KERN_ERR "%s : unfinished request detected\n", | 634 | printk(KERN_ERR "%s : unfinished request detected\n", |
635 | sock->dev.bus_id); | 635 | dev_name(&sock->dev)); |
636 | mrq->cmd->error = -ETIMEDOUT; | 636 | mrq->cmd->error = -ETIMEDOUT; |
637 | goto err_out; | 637 | goto err_out; |
638 | } | 638 | } |
@@ -672,7 +672,7 @@ static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
672 | ? PCI_DMA_TODEVICE | 672 | ? PCI_DMA_TODEVICE |
673 | : PCI_DMA_FROMDEVICE)) { | 673 | : PCI_DMA_FROMDEVICE)) { |
674 | printk(KERN_ERR "%s : scatterlist map failed\n", | 674 | printk(KERN_ERR "%s : scatterlist map failed\n", |
675 | sock->dev.bus_id); | 675 | dev_name(&sock->dev)); |
676 | mrq->cmd->error = -ENOMEM; | 676 | mrq->cmd->error = -ENOMEM; |
677 | goto err_out; | 677 | goto err_out; |
678 | } | 678 | } |
@@ -684,7 +684,7 @@ static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
684 | : PCI_DMA_FROMDEVICE); | 684 | : PCI_DMA_FROMDEVICE); |
685 | if (host->sg_len < 1) { | 685 | if (host->sg_len < 1) { |
686 | printk(KERN_ERR "%s : scatterlist map failed\n", | 686 | printk(KERN_ERR "%s : scatterlist map failed\n", |
687 | sock->dev.bus_id); | 687 | dev_name(&sock->dev)); |
688 | tifm_unmap_sg(sock, &host->bounce_buf, 1, | 688 | tifm_unmap_sg(sock, &host->bounce_buf, 1, |
689 | r_data->flags & MMC_DATA_WRITE | 689 | r_data->flags & MMC_DATA_WRITE |
690 | ? PCI_DMA_TODEVICE | 690 | ? PCI_DMA_TODEVICE |
@@ -748,7 +748,7 @@ static void tifm_sd_end_cmd(unsigned long data) | |||
748 | 748 | ||
749 | if (!mrq) { | 749 | if (!mrq) { |
750 | printk(KERN_ERR " %s : no request to complete?\n", | 750 | printk(KERN_ERR " %s : no request to complete?\n", |
751 | sock->dev.bus_id); | 751 | dev_name(&sock->dev)); |
752 | spin_unlock_irqrestore(&sock->lock, flags); | 752 | spin_unlock_irqrestore(&sock->lock, flags); |
753 | return; | 753 | return; |
754 | } | 754 | } |
@@ -789,7 +789,7 @@ static void tifm_sd_abort(unsigned long data) | |||
789 | printk(KERN_ERR | 789 | printk(KERN_ERR |
790 | "%s : card failed to respond for a long period of time " | 790 | "%s : card failed to respond for a long period of time " |
791 | "(%x, %x)\n", | 791 | "(%x, %x)\n", |
792 | host->dev->dev.bus_id, host->req->cmd->opcode, host->cmd_flags); | 792 | dev_name(&host->dev->dev), host->req->cmd->opcode, host->cmd_flags); |
793 | 793 | ||
794 | tifm_eject(host->dev); | 794 | tifm_eject(host->dev); |
795 | } | 795 | } |
@@ -906,7 +906,7 @@ static int tifm_sd_initialize_host(struct tifm_sd *host) | |||
906 | 906 | ||
907 | if (rc) { | 907 | if (rc) { |
908 | printk(KERN_ERR "%s : controller failed to reset\n", | 908 | printk(KERN_ERR "%s : controller failed to reset\n", |
909 | sock->dev.bus_id); | 909 | dev_name(&sock->dev)); |
910 | return -ENODEV; | 910 | return -ENODEV; |
911 | } | 911 | } |
912 | 912 | ||
@@ -933,7 +933,7 @@ static int tifm_sd_initialize_host(struct tifm_sd *host) | |||
933 | if (rc) { | 933 | if (rc) { |
934 | printk(KERN_ERR | 934 | printk(KERN_ERR |
935 | "%s : card not ready - probe failed on initialization\n", | 935 | "%s : card not ready - probe failed on initialization\n", |
936 | sock->dev.bus_id); | 936 | dev_name(&sock->dev)); |
937 | return -ENODEV; | 937 | return -ENODEV; |
938 | } | 938 | } |
939 | 939 | ||
@@ -954,7 +954,7 @@ static int tifm_sd_probe(struct tifm_dev *sock) | |||
954 | if (!(TIFM_SOCK_STATE_OCCUPIED | 954 | if (!(TIFM_SOCK_STATE_OCCUPIED |
955 | & readl(sock->addr + SOCK_PRESENT_STATE))) { | 955 | & readl(sock->addr + SOCK_PRESENT_STATE))) { |
956 | printk(KERN_WARNING "%s : card gone, unexpectedly\n", | 956 | printk(KERN_WARNING "%s : card gone, unexpectedly\n", |
957 | sock->dev.bus_id); | 957 | dev_name(&sock->dev)); |
958 | return rc; | 958 | return rc; |
959 | } | 959 | } |
960 | 960 | ||
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 3e6f5d8609e8..d74ec46aa032 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c | |||
@@ -406,19 +406,6 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) | |||
406 | /* Set the default CFI lock/unlock addresses */ | 406 | /* Set the default CFI lock/unlock addresses */ |
407 | cfi->addr_unlock1 = 0x555; | 407 | cfi->addr_unlock1 = 0x555; |
408 | cfi->addr_unlock2 = 0x2aa; | 408 | cfi->addr_unlock2 = 0x2aa; |
409 | /* Modify the unlock address if we are in compatibility mode */ | ||
410 | if ( /* x16 in x8 mode */ | ||
411 | ((cfi->device_type == CFI_DEVICETYPE_X8) && | ||
412 | (cfi->cfiq->InterfaceDesc == | ||
413 | CFI_INTERFACE_X8_BY_X16_ASYNC)) || | ||
414 | /* x32 in x16 mode */ | ||
415 | ((cfi->device_type == CFI_DEVICETYPE_X16) && | ||
416 | (cfi->cfiq->InterfaceDesc == | ||
417 | CFI_INTERFACE_X16_BY_X32_ASYNC))) | ||
418 | { | ||
419 | cfi->addr_unlock1 = 0xaaa; | ||
420 | cfi->addr_unlock2 = 0x555; | ||
421 | } | ||
422 | 409 | ||
423 | } /* CFI mode */ | 410 | } /* CFI mode */ |
424 | else if (cfi->cfi_mode == CFI_MODE_JEDEC) { | 411 | else if (cfi->cfi_mode == CFI_MODE_JEDEC) { |
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index f84ab6182148..2f3f2f719ba4 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c | |||
@@ -1808,9 +1808,7 @@ static inline u32 jedec_read_mfr(struct map_info *map, uint32_t base, | |||
1808 | * several first banks can contain 0x7f instead of actual ID | 1808 | * several first banks can contain 0x7f instead of actual ID |
1809 | */ | 1809 | */ |
1810 | do { | 1810 | do { |
1811 | uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8), | 1811 | uint32_t ofs = cfi_build_cmd_addr(0 + (bank << 8), map, cfi); |
1812 | cfi_interleave(cfi), | ||
1813 | cfi->device_type); | ||
1814 | mask = (1 << (cfi->device_type * 8)) - 1; | 1812 | mask = (1 << (cfi->device_type * 8)) - 1; |
1815 | result = map_read(map, base + ofs); | 1813 | result = map_read(map, base + ofs); |
1816 | bank++; | 1814 | bank++; |
@@ -1824,7 +1822,7 @@ static inline u32 jedec_read_id(struct map_info *map, uint32_t base, | |||
1824 | { | 1822 | { |
1825 | map_word result; | 1823 | map_word result; |
1826 | unsigned long mask; | 1824 | unsigned long mask; |
1827 | u32 ofs = cfi_build_cmd_addr(1, cfi_interleave(cfi), cfi->device_type); | 1825 | u32 ofs = cfi_build_cmd_addr(1, map, cfi); |
1828 | mask = (1 << (cfi->device_type * 8)) -1; | 1826 | mask = (1 << (cfi->device_type * 8)) -1; |
1829 | result = map_read(map, base + ofs); | 1827 | result = map_read(map, base + ofs); |
1830 | return result.x[0] & mask; | 1828 | return result.x[0] & mask; |
@@ -2067,8 +2065,8 @@ static int jedec_probe_chip(struct map_info *map, __u32 base, | |||
2067 | 2065 | ||
2068 | } | 2066 | } |
2069 | /* Ensure the unlock addresses we try stay inside the map */ | 2067 | /* Ensure the unlock addresses we try stay inside the map */ |
2070 | probe_offset1 = cfi_build_cmd_addr(cfi->addr_unlock1, cfi_interleave(cfi), cfi->device_type); | 2068 | probe_offset1 = cfi_build_cmd_addr(cfi->addr_unlock1, map, cfi); |
2071 | probe_offset2 = cfi_build_cmd_addr(cfi->addr_unlock2, cfi_interleave(cfi), cfi->device_type); | 2069 | probe_offset2 = cfi_build_cmd_addr(cfi->addr_unlock2, map, cfi); |
2072 | if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) || | 2070 | if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) || |
2073 | ((base + probe_offset2 + map_bankwidth(map)) >= map->size)) | 2071 | ((base + probe_offset2 + map_bankwidth(map)) >= map->size)) |
2074 | goto retry; | 2072 | goto retry; |
diff --git a/drivers/mtd/maps/cdb89712.c b/drivers/mtd/maps/cdb89712.c index e5059aa3c724..8d92d8db9a98 100644 --- a/drivers/mtd/maps/cdb89712.c +++ b/drivers/mtd/maps/cdb89712.c | |||
@@ -14,7 +14,18 @@ | |||
14 | #include <linux/mtd/map.h> | 14 | #include <linux/mtd/map.h> |
15 | #include <linux/mtd/partitions.h> | 15 | #include <linux/mtd/partitions.h> |
16 | 16 | ||
17 | 17 | /* dynamic ioremap() areas */ | |
18 | #define FLASH_START 0x00000000 | ||
19 | #define FLASH_SIZE 0x800000 | ||
20 | #define FLASH_WIDTH 4 | ||
21 | |||
22 | #define SRAM_START 0x60000000 | ||
23 | #define SRAM_SIZE 0xc000 | ||
24 | #define SRAM_WIDTH 4 | ||
25 | |||
26 | #define BOOTROM_START 0x70000000 | ||
27 | #define BOOTROM_SIZE 0x80 | ||
28 | #define BOOTROM_WIDTH 4 | ||
18 | 29 | ||
19 | 30 | ||
20 | static struct mtd_info *flash_mtd; | 31 | static struct mtd_info *flash_mtd; |
diff --git a/drivers/mtd/maps/h720x-flash.c b/drivers/mtd/maps/h720x-flash.c index 35fef655ccc4..3b959fad1c4e 100644 --- a/drivers/mtd/maps/h720x-flash.c +++ b/drivers/mtd/maps/h720x-flash.c | |||
@@ -24,8 +24,8 @@ static struct mtd_info *mymtd; | |||
24 | static struct map_info h720x_map = { | 24 | static struct map_info h720x_map = { |
25 | .name = "H720X", | 25 | .name = "H720X", |
26 | .bankwidth = 4, | 26 | .bankwidth = 4, |
27 | .size = FLASH_SIZE, | 27 | .size = H720X_FLASH_SIZE, |
28 | .phys = FLASH_PHYS, | 28 | .phys = H720X_FLASH_PHYS, |
29 | }; | 29 | }; |
30 | 30 | ||
31 | static struct mtd_partition h720x_partitions[] = { | 31 | static struct mtd_partition h720x_partitions[] = { |
@@ -70,7 +70,7 @@ int __init h720x_mtd_init(void) | |||
70 | 70 | ||
71 | char *part_type = NULL; | 71 | char *part_type = NULL; |
72 | 72 | ||
73 | h720x_map.virt = ioremap(FLASH_PHYS, FLASH_SIZE); | 73 | h720x_map.virt = ioremap(h720x_map.phys, h720x_map.size); |
74 | 74 | ||
75 | if (!h720x_map.virt) { | 75 | if (!h720x_map.virt) { |
76 | printk(KERN_ERR "H720x-MTD: ioremap failed\n"); | 76 | printk(KERN_ERR "H720x-MTD: ioremap failed\n"); |
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 430d430bce29..d07e3f148951 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -7204,10 +7204,13 @@ static void | |||
7204 | poll_bnx2(struct net_device *dev) | 7204 | poll_bnx2(struct net_device *dev) |
7205 | { | 7205 | { |
7206 | struct bnx2 *bp = netdev_priv(dev); | 7206 | struct bnx2 *bp = netdev_priv(dev); |
7207 | int i; | ||
7207 | 7208 | ||
7208 | disable_irq(bp->pdev->irq); | 7209 | for (i = 0; i < bp->irq_nvecs; i++) { |
7209 | bnx2_interrupt(bp->pdev->irq, dev); | 7210 | disable_irq(bp->irq_tbl[i].vector); |
7210 | enable_irq(bp->pdev->irq); | 7211 | bnx2_interrupt(bp->irq_tbl[i].vector, &bp->bnx2_napi[i]); |
7212 | enable_irq(bp->irq_tbl[i].vector); | ||
7213 | } | ||
7211 | } | 7214 | } |
7212 | #endif | 7215 | #endif |
7213 | 7216 | ||
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 1ace41a13ac3..2c341f83d327 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c | |||
@@ -1307,8 +1307,10 @@ static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | |||
1307 | u32 fw_vers = 0; | 1307 | u32 fw_vers = 0; |
1308 | u32 tp_vers = 0; | 1308 | u32 tp_vers = 0; |
1309 | 1309 | ||
1310 | spin_lock(&adapter->stats_lock); | ||
1310 | t3_get_fw_version(adapter, &fw_vers); | 1311 | t3_get_fw_version(adapter, &fw_vers); |
1311 | t3_get_tp_version(adapter, &tp_vers); | 1312 | t3_get_tp_version(adapter, &tp_vers); |
1313 | spin_unlock(&adapter->stats_lock); | ||
1312 | 1314 | ||
1313 | strcpy(info->driver, DRV_NAME); | 1315 | strcpy(info->driver, DRV_NAME); |
1314 | strcpy(info->version, DRV_VERSION); | 1316 | strcpy(info->version, DRV_VERSION); |
@@ -2699,7 +2701,7 @@ static void set_nqsets(struct adapter *adap) | |||
2699 | int hwports = adap->params.nports; | 2701 | int hwports = adap->params.nports; |
2700 | int nqsets = SGE_QSETS; | 2702 | int nqsets = SGE_QSETS; |
2701 | 2703 | ||
2702 | if (adap->params.rev > 0) { | 2704 | if (adap->params.rev > 0 && adap->flags & USING_MSIX) { |
2703 | if (hwports == 2 && | 2705 | if (hwports == 2 && |
2704 | (hwports * nqsets > SGE_QSETS || | 2706 | (hwports * nqsets > SGE_QSETS || |
2705 | num_cpus >= nqsets / hwports)) | 2707 | num_cpus >= nqsets / hwports)) |
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index 968f64be3743..9a0898b0dbce 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c | |||
@@ -572,7 +572,7 @@ struct t3_vpd { | |||
572 | u32 pad; /* for multiple-of-4 sizing and alignment */ | 572 | u32 pad; /* for multiple-of-4 sizing and alignment */ |
573 | }; | 573 | }; |
574 | 574 | ||
575 | #define EEPROM_MAX_POLL 4 | 575 | #define EEPROM_MAX_POLL 40 |
576 | #define EEPROM_STAT_ADDR 0x4000 | 576 | #define EEPROM_STAT_ADDR 0x4000 |
577 | #define VPD_BASE 0xc00 | 577 | #define VPD_BASE 0xc00 |
578 | 578 | ||
@@ -3690,6 +3690,12 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai, | |||
3690 | ; | 3690 | ; |
3691 | 3691 | ||
3692 | pti = &port_types[adapter->params.vpd.port_type[j]]; | 3692 | pti = &port_types[adapter->params.vpd.port_type[j]]; |
3693 | if (!pti->phy_prep) { | ||
3694 | CH_ALERT(adapter, "Invalid port type index %d\n", | ||
3695 | adapter->params.vpd.port_type[j]); | ||
3696 | return -EINVAL; | ||
3697 | } | ||
3698 | |||
3693 | ret = pti->phy_prep(&p->phy, adapter, ai->phy_base_addr + j, | 3699 | ret = pti->phy_prep(&p->phy, adapter, ai->phy_base_addr + j, |
3694 | ai->mdio_ops); | 3700 | ai->mdio_ops); |
3695 | if (ret) | 3701 | if (ret) |
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index a339afbeed38..a3f732418c49 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c | |||
@@ -706,7 +706,7 @@ tx_err: | |||
706 | mlx4_en_release_rss_steer(priv); | 706 | mlx4_en_release_rss_steer(priv); |
707 | rx_err: | 707 | rx_err: |
708 | for (i = 0; i < priv->rx_ring_num; i++) | 708 | for (i = 0; i < priv->rx_ring_num; i++) |
709 | mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[rx_index]); | 709 | mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]); |
710 | cq_err: | 710 | cq_err: |
711 | while (rx_index--) | 711 | while (rx_index--) |
712 | mlx4_en_deactivate_cq(priv, &priv->rx_cq[rx_index]); | 712 | mlx4_en_deactivate_cq(priv, &priv->rx_cq[rx_index]); |
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h index fa431fad0eec..56a2e213fe62 100644 --- a/drivers/net/mlx4/mlx4.h +++ b/drivers/net/mlx4/mlx4.h | |||
@@ -87,6 +87,9 @@ enum { | |||
87 | 87 | ||
88 | #ifdef CONFIG_MLX4_DEBUG | 88 | #ifdef CONFIG_MLX4_DEBUG |
89 | extern int mlx4_debug_level; | 89 | extern int mlx4_debug_level; |
90 | #else /* CONFIG_MLX4_DEBUG */ | ||
91 | #define mlx4_debug_level (0) | ||
92 | #endif /* CONFIG_MLX4_DEBUG */ | ||
90 | 93 | ||
91 | #define mlx4_dbg(mdev, format, arg...) \ | 94 | #define mlx4_dbg(mdev, format, arg...) \ |
92 | do { \ | 95 | do { \ |
@@ -94,12 +97,6 @@ extern int mlx4_debug_level; | |||
94 | dev_printk(KERN_DEBUG, &mdev->pdev->dev, format, ## arg); \ | 97 | dev_printk(KERN_DEBUG, &mdev->pdev->dev, format, ## arg); \ |
95 | } while (0) | 98 | } while (0) |
96 | 99 | ||
97 | #else /* CONFIG_MLX4_DEBUG */ | ||
98 | |||
99 | #define mlx4_dbg(mdev, format, arg...) do { (void) mdev; } while (0) | ||
100 | |||
101 | #endif /* CONFIG_MLX4_DEBUG */ | ||
102 | |||
103 | #define mlx4_err(mdev, format, arg...) \ | 100 | #define mlx4_err(mdev, format, arg...) \ |
104 | dev_err(&mdev->pdev->dev, format, ## arg) | 101 | dev_err(&mdev->pdev->dev, format, ## arg) |
105 | #define mlx4_info(mdev, format, arg...) \ | 102 | #define mlx4_info(mdev, format, arg...) \ |
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index a5f428bcc0eb..b37867097308 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
@@ -75,7 +75,7 @@ | |||
75 | #include "myri10ge_mcp.h" | 75 | #include "myri10ge_mcp.h" |
76 | #include "myri10ge_mcp_gen_header.h" | 76 | #include "myri10ge_mcp_gen_header.h" |
77 | 77 | ||
78 | #define MYRI10GE_VERSION_STR "1.4.3-1.375" | 78 | #define MYRI10GE_VERSION_STR "1.4.3-1.378" |
79 | 79 | ||
80 | MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); | 80 | MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); |
81 | MODULE_AUTHOR("Maintainer: help@myri.com"); | 81 | MODULE_AUTHOR("Maintainer: help@myri.com"); |
@@ -1393,6 +1393,7 @@ myri10ge_tx_done(struct myri10ge_slice_state *ss, int mcp_index) | |||
1393 | if (tx->req == tx->done) { | 1393 | if (tx->req == tx->done) { |
1394 | tx->queue_active = 0; | 1394 | tx->queue_active = 0; |
1395 | put_be32(htonl(1), tx->send_stop); | 1395 | put_be32(htonl(1), tx->send_stop); |
1396 | mb(); | ||
1396 | mmiowb(); | 1397 | mmiowb(); |
1397 | } | 1398 | } |
1398 | __netif_tx_unlock(dev_queue); | 1399 | __netif_tx_unlock(dev_queue); |
@@ -2865,6 +2866,7 @@ again: | |||
2865 | if ((mgp->dev->real_num_tx_queues > 1) && tx->queue_active == 0) { | 2866 | if ((mgp->dev->real_num_tx_queues > 1) && tx->queue_active == 0) { |
2866 | tx->queue_active = 1; | 2867 | tx->queue_active = 1; |
2867 | put_be32(htonl(1), tx->send_go); | 2868 | put_be32(htonl(1), tx->send_go); |
2869 | mb(); | ||
2868 | mmiowb(); | 2870 | mmiowb(); |
2869 | } | 2871 | } |
2870 | tx->pkt_start++; | 2872 | tx->pkt_start++; |
diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 9acb5d70a3ae..d8463b1c3df3 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c | |||
@@ -51,8 +51,7 @@ MODULE_VERSION(DRV_MODULE_VERSION); | |||
51 | #ifndef readq | 51 | #ifndef readq |
52 | static u64 readq(void __iomem *reg) | 52 | static u64 readq(void __iomem *reg) |
53 | { | 53 | { |
54 | return (((u64)readl(reg + 0x4UL) << 32) | | 54 | return ((u64) readl(reg)) | (((u64) readl(reg + 4UL)) << 32); |
55 | (u64)readl(reg)); | ||
56 | } | 55 | } |
57 | 56 | ||
58 | static void writeq(u64 val, void __iomem *reg) | 57 | static void writeq(u64 val, void __iomem *reg) |
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index fa98af58223e..cd0d0873d978 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c | |||
@@ -174,8 +174,8 @@ static struct efx_ethtool_stat efx_ethtool_stats[] = { | |||
174 | 174 | ||
175 | /* EEPROM range with gPXE configuration */ | 175 | /* EEPROM range with gPXE configuration */ |
176 | #define EFX_ETHTOOL_EEPROM_MAGIC 0xEFAB | 176 | #define EFX_ETHTOOL_EEPROM_MAGIC 0xEFAB |
177 | #define EFX_ETHTOOL_EEPROM_MIN 0x100U | 177 | #define EFX_ETHTOOL_EEPROM_MIN 0x800U |
178 | #define EFX_ETHTOOL_EEPROM_MAX 0x400U | 178 | #define EFX_ETHTOOL_EEPROM_MAX 0x1800U |
179 | 179 | ||
180 | /************************************************************************** | 180 | /************************************************************************** |
181 | * | 181 | * |
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 5051554ff05b..1f26ab0e7986 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c | |||
@@ -2050,7 +2050,9 @@ err_out: | |||
2050 | */ | 2050 | */ |
2051 | static int smc911x_drv_probe(struct platform_device *pdev) | 2051 | static int smc911x_drv_probe(struct platform_device *pdev) |
2052 | { | 2052 | { |
2053 | #ifdef SMC_DYNAMIC_BUS_CONFIG | ||
2053 | struct smc911x_platdata *pd = pdev->dev.platform_data; | 2054 | struct smc911x_platdata *pd = pdev->dev.platform_data; |
2055 | #endif | ||
2054 | struct net_device *ndev; | 2056 | struct net_device *ndev; |
2055 | struct resource *res; | 2057 | struct resource *res; |
2056 | struct smc911x_local *lp; | 2058 | struct smc911x_local *lp; |
@@ -2182,9 +2184,9 @@ static int smc911x_drv_resume(struct platform_device *dev) | |||
2182 | 2184 | ||
2183 | if (netif_running(ndev)) { | 2185 | if (netif_running(ndev)) { |
2184 | smc911x_reset(ndev); | 2186 | smc911x_reset(ndev); |
2185 | smc911x_enable(ndev); | ||
2186 | if (lp->phy_type != 0) | 2187 | if (lp->phy_type != 0) |
2187 | smc911x_phy_configure(&lp->phy_configure); | 2188 | smc911x_phy_configure(&lp->phy_configure); |
2189 | smc911x_enable(ndev); | ||
2188 | netif_device_attach(ndev); | 2190 | netif_device_attach(ndev); |
2189 | } | 2191 | } |
2190 | } | 2192 | } |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 1164c52e2c0a..8e90891f0e42 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -2184,19 +2184,20 @@ static void hso_create_rfkill(struct hso_device *hso_dev, | |||
2184 | struct usb_interface *interface) | 2184 | struct usb_interface *interface) |
2185 | { | 2185 | { |
2186 | struct hso_net *hso_net = dev2net(hso_dev); | 2186 | struct hso_net *hso_net = dev2net(hso_dev); |
2187 | struct device *dev = hso_dev->dev; | 2187 | struct device *dev = &hso_net->net->dev; |
2188 | char *rfkn; | 2188 | char *rfkn; |
2189 | 2189 | ||
2190 | hso_net->rfkill = rfkill_allocate(&interface_to_usbdev(interface)->dev, | 2190 | hso_net->rfkill = rfkill_allocate(&interface_to_usbdev(interface)->dev, |
2191 | RFKILL_TYPE_WLAN); | 2191 | RFKILL_TYPE_WWAN); |
2192 | if (!hso_net->rfkill) { | 2192 | if (!hso_net->rfkill) { |
2193 | dev_err(dev, "%s - Out of memory", __func__); | 2193 | dev_err(dev, "%s - Out of memory\n", __func__); |
2194 | return; | 2194 | return; |
2195 | } | 2195 | } |
2196 | rfkn = kzalloc(20, GFP_KERNEL); | 2196 | rfkn = kzalloc(20, GFP_KERNEL); |
2197 | if (!rfkn) { | 2197 | if (!rfkn) { |
2198 | rfkill_free(hso_net->rfkill); | 2198 | rfkill_free(hso_net->rfkill); |
2199 | dev_err(dev, "%s - Out of memory", __func__); | 2199 | hso_net->rfkill = NULL; |
2200 | dev_err(dev, "%s - Out of memory\n", __func__); | ||
2200 | return; | 2201 | return; |
2201 | } | 2202 | } |
2202 | snprintf(rfkn, 20, "hso-%d", | 2203 | snprintf(rfkn, 20, "hso-%d", |
@@ -2209,7 +2210,8 @@ static void hso_create_rfkill(struct hso_device *hso_dev, | |||
2209 | kfree(rfkn); | 2210 | kfree(rfkn); |
2210 | hso_net->rfkill->name = NULL; | 2211 | hso_net->rfkill->name = NULL; |
2211 | rfkill_free(hso_net->rfkill); | 2212 | rfkill_free(hso_net->rfkill); |
2212 | dev_err(dev, "%s - Failed to register rfkill", __func__); | 2213 | hso_net->rfkill = NULL; |
2214 | dev_err(dev, "%s - Failed to register rfkill\n", __func__); | ||
2213 | return; | 2215 | return; |
2214 | } | 2216 | } |
2215 | } | 2217 | } |
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 9e47d727e220..cfd4d052d666 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
@@ -2942,8 +2942,10 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, | |||
2942 | sc->opmode != NL80211_IFTYPE_MESH_POINT && | 2942 | sc->opmode != NL80211_IFTYPE_MESH_POINT && |
2943 | test_bit(ATH_STAT_PROMISC, sc->status)) | 2943 | test_bit(ATH_STAT_PROMISC, sc->status)) |
2944 | rfilt |= AR5K_RX_FILTER_PROM; | 2944 | rfilt |= AR5K_RX_FILTER_PROM; |
2945 | if (sc->opmode == NL80211_IFTYPE_ADHOC) | 2945 | if (sc->opmode == NL80211_IFTYPE_STATION || |
2946 | sc->opmode == NL80211_IFTYPE_ADHOC) { | ||
2946 | rfilt |= AR5K_RX_FILTER_BEACON; | 2947 | rfilt |= AR5K_RX_FILTER_BEACON; |
2948 | } | ||
2947 | 2949 | ||
2948 | /* Set filters */ | 2950 | /* Set filters */ |
2949 | ath5k_hw_set_rx_filter(ah,rfilt); | 2951 | ath5k_hw_set_rx_filter(ah,rfilt); |
diff --git a/drivers/net/wireless/ath5k/desc.c b/drivers/net/wireless/ath5k/desc.c index dd1374052ba9..5e362a7a3620 100644 --- a/drivers/net/wireless/ath5k/desc.c +++ b/drivers/net/wireless/ath5k/desc.c | |||
@@ -531,10 +531,10 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, | |||
531 | AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL); | 531 | AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL); |
532 | rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, | 532 | rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, |
533 | AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE); | 533 | AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE); |
534 | rs->rs_antenna = rx_status->rx_status_0 & | 534 | rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, |
535 | AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA; | 535 | AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA); |
536 | rs->rs_more = rx_status->rx_status_0 & | 536 | rs->rs_more = !!(rx_status->rx_status_0 & |
537 | AR5K_5210_RX_DESC_STATUS0_MORE; | 537 | AR5K_5210_RX_DESC_STATUS0_MORE); |
538 | /* TODO: this timestamp is 13 bit, later on we assume 15 bit */ | 538 | /* TODO: this timestamp is 13 bit, later on we assume 15 bit */ |
539 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, | 539 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, |
540 | AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); | 540 | AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); |
@@ -607,10 +607,10 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, | |||
607 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); | 607 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); |
608 | rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, | 608 | rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, |
609 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); | 609 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); |
610 | rs->rs_antenna = rx_status->rx_status_0 & | 610 | rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, |
611 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA; | 611 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA); |
612 | rs->rs_more = rx_status->rx_status_0 & | 612 | rs->rs_more = !!(rx_status->rx_status_0 & |
613 | AR5K_5212_RX_DESC_STATUS0_MORE; | 613 | AR5K_5212_RX_DESC_STATUS0_MORE); |
614 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, | 614 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, |
615 | AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); | 615 | AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); |
616 | rs->rs_status = 0; | 616 | rs->rs_status = 0; |
diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h index ffdf4876121b..a68f97c39359 100644 --- a/drivers/net/wireless/hostap/hostap_wlan.h +++ b/drivers/net/wireless/hostap/hostap_wlan.h | |||
@@ -918,9 +918,12 @@ struct hostap_interface { | |||
918 | 918 | ||
919 | /* | 919 | /* |
920 | * TX meta data - stored in skb->cb buffer, so this must not be increased over | 920 | * TX meta data - stored in skb->cb buffer, so this must not be increased over |
921 | * the 40-byte limit | 921 | * the 48-byte limit. |
922 | * THE PADDING THIS STARTS WITH IS A HORRIBLE HACK THAT SHOULD NOT LIVE | ||
923 | * TO SEE THE DAY. | ||
922 | */ | 924 | */ |
923 | struct hostap_skb_tx_data { | 925 | struct hostap_skb_tx_data { |
926 | unsigned int __padding_for_default_qdiscs; | ||
924 | u32 magic; /* HOSTAP_SKB_TX_DATA_MAGIC */ | 927 | u32 magic; /* HOSTAP_SKB_TX_DATA_MAGIC */ |
925 | u8 rate; /* transmit rate */ | 928 | u8 rate; /* transmit rate */ |
926 | #define HOSTAP_TX_FLAGS_WDS BIT(0) | 929 | #define HOSTAP_TX_FLAGS_WDS BIT(0) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 321dbc8c034a..8d690a0eb1a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -3252,7 +3252,11 @@ static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw, | |||
3252 | return; | 3252 | return; |
3253 | } | 3253 | } |
3254 | 3254 | ||
3255 | iwl_scan_cancel_timeout(priv, 100); | 3255 | if (iwl_scan_cancel(priv)) { |
3256 | /* cancel scan failed, just live w/ bad key and rely | ||
3257 | briefly on SW decryption */ | ||
3258 | return; | ||
3259 | } | ||
3256 | 3260 | ||
3257 | key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK); | 3261 | key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK); |
3258 | key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); | 3262 | key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 3b0bee331a33..c89365e2ca58 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -896,6 +896,13 @@ static void iwl_bg_request_scan(struct work_struct *data) | |||
896 | return; | 896 | return; |
897 | 897 | ||
898 | done: | 898 | done: |
899 | /* Cannot perform scan. Make sure we clear scanning | ||
900 | * bits from status so next scan request can be performed. | ||
901 | * If we don't clear scanning status bit here all next scan | ||
902 | * will fail | ||
903 | */ | ||
904 | clear_bit(STATUS_SCAN_HW, &priv->status); | ||
905 | clear_bit(STATUS_SCANNING, &priv->status); | ||
899 | /* inform mac80211 scan aborted */ | 906 | /* inform mac80211 scan aborted */ |
900 | queue_work(priv->workqueue, &priv->scan_completed); | 907 | queue_work(priv->workqueue, &priv->scan_completed); |
901 | mutex_unlock(&priv->mutex); | 908 | mutex_unlock(&priv->mutex); |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index d15a2c997954..285b53e7e261 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -5768,7 +5768,6 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv) | |||
5768 | if (priv->error_recovering) | 5768 | if (priv->error_recovering) |
5769 | iwl3945_error_recovery(priv); | 5769 | iwl3945_error_recovery(priv); |
5770 | 5770 | ||
5771 | ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC); | ||
5772 | return; | 5771 | return; |
5773 | 5772 | ||
5774 | restart: | 5773 | restart: |
@@ -6013,6 +6012,7 @@ static void iwl3945_bg_alive_start(struct work_struct *data) | |||
6013 | mutex_lock(&priv->mutex); | 6012 | mutex_lock(&priv->mutex); |
6014 | iwl3945_alive_start(priv); | 6013 | iwl3945_alive_start(priv); |
6015 | mutex_unlock(&priv->mutex); | 6014 | mutex_unlock(&priv->mutex); |
6015 | ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC); | ||
6016 | } | 6016 | } |
6017 | 6017 | ||
6018 | static void iwl3945_bg_rf_kill(struct work_struct *work) | 6018 | static void iwl3945_bg_rf_kill(struct work_struct *work) |
@@ -6256,6 +6256,11 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6256 | n_probes, | 6256 | n_probes, |
6257 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | 6257 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); |
6258 | 6258 | ||
6259 | if (scan->channel_count == 0) { | ||
6260 | IWL_DEBUG_SCAN("channel count %d\n", scan->channel_count); | ||
6261 | goto done; | ||
6262 | } | ||
6263 | |||
6259 | cmd.len += le16_to_cpu(scan->tx_cmd.len) + | 6264 | cmd.len += le16_to_cpu(scan->tx_cmd.len) + |
6260 | scan->channel_count * sizeof(struct iwl3945_scan_channel); | 6265 | scan->channel_count * sizeof(struct iwl3945_scan_channel); |
6261 | cmd.data = scan; | 6266 | cmd.data = scan; |
@@ -6273,6 +6278,14 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6273 | return; | 6278 | return; |
6274 | 6279 | ||
6275 | done: | 6280 | done: |
6281 | /* can not perform scan make sure we clear scanning | ||
6282 | * bits from status so next scan request can be performed. | ||
6283 | * if we dont clear scanning status bit here all next scan | ||
6284 | * will fail | ||
6285 | */ | ||
6286 | clear_bit(STATUS_SCAN_HW, &priv->status); | ||
6287 | clear_bit(STATUS_SCANNING, &priv->status); | ||
6288 | |||
6276 | /* inform mac80211 scan aborted */ | 6289 | /* inform mac80211 scan aborted */ |
6277 | queue_work(priv->workqueue, &priv->scan_completed); | 6290 | queue_work(priv->workqueue, &priv->scan_completed); |
6278 | mutex_unlock(&priv->mutex); | 6291 | mutex_unlock(&priv->mutex); |
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index 431e3c78bf27..69eb0132593b 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c | |||
@@ -48,6 +48,9 @@ static struct usb_device_id rtl8187_table[] __devinitdata = { | |||
48 | {USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187}, | 48 | {USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187}, |
49 | /* Sitecom */ | 49 | /* Sitecom */ |
50 | {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187}, | 50 | {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187}, |
51 | {USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B}, | ||
52 | /* Abocom */ | ||
53 | {USB_DEVICE(0x13d1, 0xabe6), .driver_info = DEVICE_RTL8187}, | ||
51 | {} | 54 | {} |
52 | }; | 55 | }; |
53 | 56 | ||
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index a60ae86bd5c9..a3ccd8c1c716 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
@@ -61,6 +61,7 @@ static struct usb_device_id usb_ids[] = { | |||
61 | { USB_DEVICE(0x0105, 0x145f), .driver_info = DEVICE_ZD1211 }, | 61 | { USB_DEVICE(0x0105, 0x145f), .driver_info = DEVICE_ZD1211 }, |
62 | /* ZD1211B */ | 62 | /* ZD1211B */ |
63 | { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, | 63 | { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, |
64 | { USB_DEVICE(0x0ace, 0xb215), .driver_info = DEVICE_ZD1211B }, | ||
64 | { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, | 65 | { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, |
65 | { USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B }, | 66 | { USB_DEVICE(0x079b, 0x0062), .driver_info = DEVICE_ZD1211B }, |
66 | { USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B }, | 67 | { USB_DEVICE(0x1582, 0x6003), .driver_info = DEVICE_ZD1211B }, |
@@ -82,6 +83,7 @@ static struct usb_device_id usb_ids[] = { | |||
82 | { USB_DEVICE(0x0cde, 0x001a), .driver_info = DEVICE_ZD1211B }, | 83 | { USB_DEVICE(0x0cde, 0x001a), .driver_info = DEVICE_ZD1211B }, |
83 | { USB_DEVICE(0x0586, 0x340a), .driver_info = DEVICE_ZD1211B }, | 84 | { USB_DEVICE(0x0586, 0x340a), .driver_info = DEVICE_ZD1211B }, |
84 | { USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B }, | 85 | { USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B }, |
86 | { USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B }, | ||
85 | /* "Driverless" devices that need ejecting */ | 87 | /* "Driverless" devices that need ejecting */ |
86 | { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, | 88 | { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, |
87 | { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER }, | 89 | { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER }, |
diff --git a/drivers/oprofile/event_buffer.c b/drivers/oprofile/event_buffer.c index d962ba0dd87a..191a3202cecc 100644 --- a/drivers/oprofile/event_buffer.c +++ b/drivers/oprofile/event_buffer.c | |||
@@ -105,7 +105,7 @@ static int event_buffer_open(struct inode *inode, struct file *file) | |||
105 | if (!capable(CAP_SYS_ADMIN)) | 105 | if (!capable(CAP_SYS_ADMIN)) |
106 | return -EPERM; | 106 | return -EPERM; |
107 | 107 | ||
108 | if (test_and_set_bit(0, &buffer_opened)) | 108 | if (test_and_set_bit_lock(0, &buffer_opened)) |
109 | return -EBUSY; | 109 | return -EBUSY; |
110 | 110 | ||
111 | /* Register as a user of dcookies | 111 | /* Register as a user of dcookies |
@@ -129,7 +129,7 @@ static int event_buffer_open(struct inode *inode, struct file *file) | |||
129 | fail: | 129 | fail: |
130 | dcookie_unregister(file->private_data); | 130 | dcookie_unregister(file->private_data); |
131 | out: | 131 | out: |
132 | clear_bit(0, &buffer_opened); | 132 | __clear_bit_unlock(0, &buffer_opened); |
133 | return err; | 133 | return err; |
134 | } | 134 | } |
135 | 135 | ||
@@ -141,7 +141,7 @@ static int event_buffer_release(struct inode *inode, struct file *file) | |||
141 | dcookie_unregister(file->private_data); | 141 | dcookie_unregister(file->private_data); |
142 | buffer_pos = 0; | 142 | buffer_pos = 0; |
143 | atomic_set(&buffer_ready, 0); | 143 | atomic_set(&buffer_ready, 0); |
144 | clear_bit(0, &buffer_opened); | 144 | __clear_bit_unlock(0, &buffer_opened); |
145 | return 0; | 145 | return 0; |
146 | } | 146 | } |
147 | 147 | ||
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index b3a63edb6901..ae5ec76dca77 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -63,7 +63,7 @@ static acpi_status acpi_run_osc(acpi_handle handle, | |||
63 | union acpi_object in_params[4]; | 63 | union acpi_object in_params[4]; |
64 | struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; | 64 | struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; |
65 | union acpi_object *out_obj; | 65 | union acpi_object *out_obj; |
66 | u32 osc_dw0, flags = osc_args->capbuf[OSC_QUERY_TYPE]; | 66 | u32 errors, flags = osc_args->capbuf[OSC_QUERY_TYPE]; |
67 | 67 | ||
68 | /* Setting up input parameters */ | 68 | /* Setting up input parameters */ |
69 | input.count = 4; | 69 | input.count = 4; |
@@ -92,15 +92,16 @@ static acpi_status acpi_run_osc(acpi_handle handle, | |||
92 | status = AE_TYPE; | 92 | status = AE_TYPE; |
93 | goto out_kfree; | 93 | goto out_kfree; |
94 | } | 94 | } |
95 | osc_dw0 = *((u32 *)out_obj->buffer.pointer); | 95 | /* Need to ignore the bit0 in result code */ |
96 | if (osc_dw0) { | 96 | errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0); |
97 | if (osc_dw0 & OSC_REQUEST_ERROR) | 97 | if (errors) { |
98 | if (errors & OSC_REQUEST_ERROR) | ||
98 | printk(KERN_DEBUG "_OSC request fails\n"); | 99 | printk(KERN_DEBUG "_OSC request fails\n"); |
99 | if (osc_dw0 & OSC_INVALID_UUID_ERROR) | 100 | if (errors & OSC_INVALID_UUID_ERROR) |
100 | printk(KERN_DEBUG "_OSC invalid UUID\n"); | 101 | printk(KERN_DEBUG "_OSC invalid UUID\n"); |
101 | if (osc_dw0 & OSC_INVALID_REVISION_ERROR) | 102 | if (errors & OSC_INVALID_REVISION_ERROR) |
102 | printk(KERN_DEBUG "_OSC invalid revision\n"); | 103 | printk(KERN_DEBUG "_OSC invalid revision\n"); |
103 | if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) { | 104 | if (errors & OSC_CAPABILITIES_MASK_ERROR) { |
104 | if (flags & OSC_QUERY_ENABLE) | 105 | if (flags & OSC_QUERY_ENABLE) |
105 | goto out_success; | 106 | goto out_success; |
106 | printk(KERN_DEBUG "_OSC FW not grant req. control\n"); | 107 | printk(KERN_DEBUG "_OSC FW not grant req. control\n"); |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 110022d78689..5d72866897a8 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -575,7 +575,7 @@ static int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct | |||
575 | 575 | ||
576 | nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; | 576 | nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; |
577 | start = vma->vm_pgoff; | 577 | start = vma->vm_pgoff; |
578 | size = pci_resource_len(pdev, resno) >> PAGE_SHIFT; | 578 | size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1; |
579 | if (start < size && size - start >= nr) | 579 | if (start < size && size - start >= nr) |
580 | return 1; | 580 | return 1; |
581 | WARN(1, "process \"%s\" tried to map 0x%08lx-0x%08lx on %s BAR %d (size 0x%08lx)\n", | 581 | WARN(1, "process \"%s\" tried to map 0x%08lx-0x%08lx on %s BAR %d (size 0x%08lx)\n", |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index bbf66ea8fd87..5049a47030ac 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -1692,24 +1692,24 @@ static void __devinit quirk_brcm_570x_limit_vpd(struct pci_dev *dev) | |||
1692 | } | 1692 | } |
1693 | } | 1693 | } |
1694 | 1694 | ||
1695 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, | 1695 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, |
1696 | PCI_DEVICE_ID_NX2_5706, | 1696 | PCI_DEVICE_ID_NX2_5706, |
1697 | quirk_brcm_570x_limit_vpd); | 1697 | quirk_brcm_570x_limit_vpd); |
1698 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, | 1698 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, |
1699 | PCI_DEVICE_ID_NX2_5706S, | 1699 | PCI_DEVICE_ID_NX2_5706S, |
1700 | quirk_brcm_570x_limit_vpd); | 1700 | quirk_brcm_570x_limit_vpd); |
1701 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, | 1701 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, |
1702 | PCI_DEVICE_ID_NX2_5708, | 1702 | PCI_DEVICE_ID_NX2_5708, |
1703 | quirk_brcm_570x_limit_vpd); | 1703 | quirk_brcm_570x_limit_vpd); |
1704 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, | 1704 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, |
1705 | PCI_DEVICE_ID_NX2_5708S, | 1705 | PCI_DEVICE_ID_NX2_5708S, |
1706 | quirk_brcm_570x_limit_vpd); | 1706 | quirk_brcm_570x_limit_vpd); |
1707 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, | 1707 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, |
1708 | PCI_DEVICE_ID_NX2_5709, | 1708 | PCI_DEVICE_ID_NX2_5709, |
1709 | quirk_brcm_570x_limit_vpd); | 1709 | quirk_brcm_570x_limit_vpd); |
1710 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, | 1710 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM, |
1711 | PCI_DEVICE_ID_NX2_5709S, | 1711 | PCI_DEVICE_ID_NX2_5709S, |
1712 | quirk_brcm_570x_limit_vpd); | 1712 | quirk_brcm_570x_limit_vpd); |
1713 | 1713 | ||
1714 | #ifdef CONFIG_PCI_MSI | 1714 | #ifdef CONFIG_PCI_MSI |
1715 | /* Some chipsets do not support MSI. We cannot easily rely on setting | 1715 | /* Some chipsets do not support MSI. We cannot easily rely on setting |
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index 1f5f6143f35c..132a78159b60 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
@@ -100,7 +100,8 @@ size_t pci_get_rom_size(void __iomem *rom, size_t size) | |||
100 | * pci_map_rom - map a PCI ROM to kernel space | 100 | * pci_map_rom - map a PCI ROM to kernel space |
101 | * @pdev: pointer to pci device struct | 101 | * @pdev: pointer to pci device struct |
102 | * @size: pointer to receive size of pci window over ROM | 102 | * @size: pointer to receive size of pci window over ROM |
103 | * @return: kernel virtual pointer to image of ROM | 103 | * |
104 | * Return: kernel virtual pointer to image of ROM | ||
104 | * | 105 | * |
105 | * Map a PCI ROM into kernel space. If ROM is boot video ROM, | 106 | * Map a PCI ROM into kernel space. If ROM is boot video ROM, |
106 | * the shadow BIOS copy will be returned instead of the | 107 | * the shadow BIOS copy will be returned instead of the |
@@ -167,7 +168,8 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) | |||
167 | * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy | 168 | * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy |
168 | * @pdev: pointer to pci device struct | 169 | * @pdev: pointer to pci device struct |
169 | * @size: pointer to receive size of pci window over ROM | 170 | * @size: pointer to receive size of pci window over ROM |
170 | * @return: kernel virtual pointer to image of ROM | 171 | * |
172 | * Return: kernel virtual pointer to image of ROM | ||
171 | * | 173 | * |
172 | * Map a PCI ROM into kernel space. If ROM is boot video ROM, | 174 | * Map a PCI ROM into kernel space. If ROM is boot video ROM, |
173 | * the shadow BIOS copy will be returned instead of the | 175 | * the shadow BIOS copy will be returned instead of the |
diff --git a/drivers/ps3/ps3-lpm.c b/drivers/ps3/ps3-lpm.c index 85edf945ab86..204158cf7a55 100644 --- a/drivers/ps3/ps3-lpm.c +++ b/drivers/ps3/ps3-lpm.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/uaccess.h> | 24 | #include <linux/uaccess.h> |
25 | #include <asm/smp.h> | ||
25 | #include <asm/time.h> | 26 | #include <asm/time.h> |
26 | #include <asm/ps3.h> | 27 | #include <asm/ps3.h> |
27 | #include <asm/lv1call.h> | 28 | #include <asm/lv1call.h> |
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 4dada6ee1119..39360e2a4540 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
@@ -1,6 +1,4 @@ | |||
1 | menu "Voltage and Current regulators" | 1 | menuconfig REGULATOR |
2 | |||
3 | config REGULATOR | ||
4 | bool "Voltage and Current Regulator Support" | 2 | bool "Voltage and Current Regulator Support" |
5 | default n | 3 | default n |
6 | help | 4 | help |
@@ -23,21 +21,20 @@ config REGULATOR | |||
23 | 21 | ||
24 | If unsure, say no. | 22 | If unsure, say no. |
25 | 23 | ||
24 | if REGULATOR | ||
25 | |||
26 | config REGULATOR_DEBUG | 26 | config REGULATOR_DEBUG |
27 | bool "Regulator debug support" | 27 | bool "Regulator debug support" |
28 | depends on REGULATOR | ||
29 | help | 28 | help |
30 | Say yes here to enable debugging support. | 29 | Say yes here to enable debugging support. |
31 | 30 | ||
32 | config REGULATOR_FIXED_VOLTAGE | 31 | config REGULATOR_FIXED_VOLTAGE |
33 | tristate | 32 | tristate |
34 | default n | 33 | default n |
35 | select REGULATOR | ||
36 | 34 | ||
37 | config REGULATOR_VIRTUAL_CONSUMER | 35 | config REGULATOR_VIRTUAL_CONSUMER |
38 | tristate "Virtual regulator consumer support" | 36 | tristate "Virtual regulator consumer support" |
39 | default n | 37 | default n |
40 | select REGULATOR | ||
41 | help | 38 | help |
42 | This driver provides a virtual consumer for the voltage and | 39 | This driver provides a virtual consumer for the voltage and |
43 | current regulator API which provides sysfs controls for | 40 | current regulator API which provides sysfs controls for |
@@ -49,7 +46,6 @@ config REGULATOR_VIRTUAL_CONSUMER | |||
49 | config REGULATOR_BQ24022 | 46 | config REGULATOR_BQ24022 |
50 | tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC" | 47 | tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC" |
51 | default n | 48 | default n |
52 | select REGULATOR | ||
53 | help | 49 | help |
54 | This driver controls a TI bq24022 Charger attached via | 50 | This driver controls a TI bq24022 Charger attached via |
55 | GPIOs. The provided current regulator can enable/disable | 51 | GPIOs. The provided current regulator can enable/disable |
@@ -59,7 +55,6 @@ config REGULATOR_BQ24022 | |||
59 | config REGULATOR_WM8350 | 55 | config REGULATOR_WM8350 |
60 | tristate "Wolfson Microelectroncis WM8350 AudioPlus PMIC" | 56 | tristate "Wolfson Microelectroncis WM8350 AudioPlus PMIC" |
61 | depends on MFD_WM8350 | 57 | depends on MFD_WM8350 |
62 | select REGULATOR | ||
63 | help | 58 | help |
64 | This driver provides support for the voltage and current regulators | 59 | This driver provides support for the voltage and current regulators |
65 | of the WM8350 AudioPlus PMIC. | 60 | of the WM8350 AudioPlus PMIC. |
@@ -67,7 +62,6 @@ config REGULATOR_WM8350 | |||
67 | config REGULATOR_WM8400 | 62 | config REGULATOR_WM8400 |
68 | tristate "Wolfson Microelectroncis WM8400 AudioPlus PMIC" | 63 | tristate "Wolfson Microelectroncis WM8400 AudioPlus PMIC" |
69 | depends on MFD_WM8400 | 64 | depends on MFD_WM8400 |
70 | select REGULATOR | ||
71 | help | 65 | help |
72 | This driver provides support for the voltage regulators of the | 66 | This driver provides support for the voltage regulators of the |
73 | WM8400 AudioPlus PMIC. | 67 | WM8400 AudioPlus PMIC. |
@@ -75,9 +69,8 @@ config REGULATOR_WM8400 | |||
75 | config REGULATOR_DA903X | 69 | config REGULATOR_DA903X |
76 | tristate "Support regulators on Dialog Semiconductor DA9030/DA9034 PMIC" | 70 | tristate "Support regulators on Dialog Semiconductor DA9030/DA9034 PMIC" |
77 | depends on PMIC_DA903X | 71 | depends on PMIC_DA903X |
78 | select REGULATOR | ||
79 | help | 72 | help |
80 | Say y here to support the BUCKs and LDOs regulators found on | 73 | Say y here to support the BUCKs and LDOs regulators found on |
81 | Dialog Semiconductor DA9030/DA9034 PMIC. | 74 | Dialog Semiconductor DA9030/DA9034 PMIC. |
82 | 75 | ||
83 | endmenu | 76 | endif |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 8abbb2020af9..123092d8a984 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -277,6 +277,14 @@ config RTC_DRV_FM3130 | |||
277 | This driver can also be built as a module. If so the module | 277 | This driver can also be built as a module. If so the module |
278 | will be called rtc-fm3130. | 278 | will be called rtc-fm3130. |
279 | 279 | ||
280 | config RTC_DRV_RX8581 | ||
281 | tristate "Epson RX-8581" | ||
282 | help | ||
283 | If you say yes here you will get support for the Epson RX-8581. | ||
284 | |||
285 | This driver can also be built as a module. If so the module | ||
286 | will be called rtc-rx8581. | ||
287 | |||
280 | endif # I2C | 288 | endif # I2C |
281 | 289 | ||
282 | comment "SPI RTC drivers" | 290 | comment "SPI RTC drivers" |
@@ -302,6 +310,17 @@ config RTC_DRV_DS1305 | |||
302 | This driver can also be built as a module. If so, the module | 310 | This driver can also be built as a module. If so, the module |
303 | will be called rtc-ds1305. | 311 | will be called rtc-ds1305. |
304 | 312 | ||
313 | config RTC_DRV_DS1390 | ||
314 | tristate "Dallas/Maxim DS1390/93/94" | ||
315 | help | ||
316 | If you say yes here you get support for the DS1390/93/94 chips. | ||
317 | |||
318 | This driver only supports the RTC feature, and not other chip | ||
319 | features such as alarms and trickle charging. | ||
320 | |||
321 | This driver can also be built as a module. If so, the module | ||
322 | will be called rtc-ds1390. | ||
323 | |||
305 | config RTC_DRV_MAX6902 | 324 | config RTC_DRV_MAX6902 |
306 | tristate "Maxim MAX6902" | 325 | tristate "Maxim MAX6902" |
307 | help | 326 | help |
@@ -468,6 +487,16 @@ config RTC_DRV_V3020 | |||
468 | This driver can also be built as a module. If so, the module | 487 | This driver can also be built as a module. If so, the module |
469 | will be called rtc-v3020. | 488 | will be called rtc-v3020. |
470 | 489 | ||
490 | config RTC_DRV_WM8350 | ||
491 | tristate "Wolfson Microelectronics WM8350 RTC" | ||
492 | depends on MFD_WM8350 | ||
493 | help | ||
494 | If you say yes here you will get support for the RTC subsystem | ||
495 | of the Wolfson Microelectronics WM8350. | ||
496 | |||
497 | This driver can also be built as a module. If so, the module | ||
498 | will be called "rtc-wm8350". | ||
499 | |||
471 | comment "on-CPU RTC drivers" | 500 | comment "on-CPU RTC drivers" |
472 | 501 | ||
473 | config RTC_DRV_OMAP | 502 | config RTC_DRV_OMAP |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index e9e8474cc8fe..6e79c912bf9e 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -28,6 +28,7 @@ obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o | |||
28 | obj-$(CONFIG_RTC_DRV_DS1305) += rtc-ds1305.o | 28 | obj-$(CONFIG_RTC_DRV_DS1305) += rtc-ds1305.o |
29 | obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o | 29 | obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o |
30 | obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o | 30 | obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o |
31 | obj-$(CONFIG_RTC_DRV_DS1390) += rtc-ds1390.o | ||
31 | obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o | 32 | obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o |
32 | obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o | 33 | obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o |
33 | obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o | 34 | obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o |
@@ -57,6 +58,7 @@ obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o | |||
57 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o | 58 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o |
58 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o | 59 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o |
59 | obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o | 60 | obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o |
61 | obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o | ||
60 | obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o | 62 | obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o |
61 | obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o | 63 | obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o |
62 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o | 64 | obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o |
@@ -66,4 +68,5 @@ obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o | |||
66 | obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl4030.o | 68 | obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl4030.o |
67 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o | 69 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o |
68 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o | 70 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o |
71 | obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o | ||
69 | obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o | 72 | obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o |
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 7af60b98d8a4..a04c1b6b1575 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
@@ -271,7 +271,7 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | |||
271 | dev_dbg(&rtc->dev, "alarm rollover: %s\n", "year"); | 271 | dev_dbg(&rtc->dev, "alarm rollover: %s\n", "year"); |
272 | do { | 272 | do { |
273 | alarm->time.tm_year++; | 273 | alarm->time.tm_year++; |
274 | } while (!rtc_valid_tm(&alarm->time)); | 274 | } while (rtc_valid_tm(&alarm->time) != 0); |
275 | break; | 275 | break; |
276 | 276 | ||
277 | default: | 277 | default: |
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 5549231179a2..6cf8e282338f 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -794,7 +794,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
794 | goto cleanup2; | 794 | goto cleanup2; |
795 | } | 795 | } |
796 | 796 | ||
797 | pr_info("%s: alarms up to one %s%s, %zd bytes nvram, %s irqs\n", | 797 | pr_info("%s: alarms up to one %s%s, %zd bytes nvram%s\n", |
798 | cmos_rtc.rtc->dev.bus_id, | 798 | cmos_rtc.rtc->dev.bus_id, |
799 | is_valid_irq(rtc_irq) | 799 | is_valid_irq(rtc_irq) |
800 | ? (cmos_rtc.mon_alrm | 800 | ? (cmos_rtc.mon_alrm |
diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c new file mode 100644 index 000000000000..599e976bf014 --- /dev/null +++ b/drivers/rtc/rtc-ds1390.c | |||
@@ -0,0 +1,220 @@ | |||
1 | /* | ||
2 | * rtc-ds1390.c -- driver for DS1390/93/94 | ||
3 | * | ||
4 | * Copyright (C) 2008 Mercury IMC Ltd | ||
5 | * Written by Mark Jackson <mpfj@mimc.co.uk> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * NOTE : Currently this driver only supports the bare minimum for read | ||
12 | * and write the RTC. The extra features provided by the chip family | ||
13 | * (alarms, trickle charger, different control registers) are unavailable. | ||
14 | */ | ||
15 | |||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/rtc.h> | ||
18 | #include <linux/spi/spi.h> | ||
19 | #include <linux/bcd.h> | ||
20 | |||
21 | #define DS1390_REG_100THS 0x00 | ||
22 | #define DS1390_REG_SECONDS 0x01 | ||
23 | #define DS1390_REG_MINUTES 0x02 | ||
24 | #define DS1390_REG_HOURS 0x03 | ||
25 | #define DS1390_REG_DAY 0x04 | ||
26 | #define DS1390_REG_DATE 0x05 | ||
27 | #define DS1390_REG_MONTH_CENT 0x06 | ||
28 | #define DS1390_REG_YEAR 0x07 | ||
29 | |||
30 | #define DS1390_REG_ALARM_100THS 0x08 | ||
31 | #define DS1390_REG_ALARM_SECONDS 0x09 | ||
32 | #define DS1390_REG_ALARM_MINUTES 0x0A | ||
33 | #define DS1390_REG_ALARM_HOURS 0x0B | ||
34 | #define DS1390_REG_ALARM_DAY_DATE 0x0C | ||
35 | |||
36 | #define DS1390_REG_CONTROL 0x0D | ||
37 | #define DS1390_REG_STATUS 0x0E | ||
38 | #define DS1390_REG_TRICKLE 0x0F | ||
39 | |||
40 | struct ds1390 { | ||
41 | struct rtc_device *rtc; | ||
42 | u8 txrx_buf[9]; /* cmd + 8 registers */ | ||
43 | }; | ||
44 | |||
45 | static void ds1390_set_reg(struct device *dev, unsigned char address, | ||
46 | unsigned char data) | ||
47 | { | ||
48 | struct spi_device *spi = to_spi_device(dev); | ||
49 | struct ds1390 *chip = dev_get_drvdata(dev); | ||
50 | |||
51 | /* Set MSB to indicate write */ | ||
52 | chip->txrx_buf[0] = address | 0x80; | ||
53 | chip->txrx_buf[1] = data; | ||
54 | |||
55 | /* do the i/o */ | ||
56 | spi_write_then_read(spi, chip->txrx_buf, 2, NULL, 0); | ||
57 | } | ||
58 | |||
59 | static int ds1390_get_reg(struct device *dev, unsigned char address, | ||
60 | unsigned char *data) | ||
61 | { | ||
62 | struct spi_device *spi = to_spi_device(dev); | ||
63 | struct ds1390 *chip = dev_get_drvdata(dev); | ||
64 | int status; | ||
65 | |||
66 | if (!data) | ||
67 | return -EINVAL; | ||
68 | |||
69 | /* Clear MSB to indicate read */ | ||
70 | chip->txrx_buf[0] = address & 0x7f; | ||
71 | /* do the i/o */ | ||
72 | status = spi_write_then_read(spi, chip->txrx_buf, 1, chip->txrx_buf, 1); | ||
73 | if (status != 0) | ||
74 | return status; | ||
75 | |||
76 | *data = chip->txrx_buf[1]; | ||
77 | |||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | static int ds1390_get_datetime(struct device *dev, struct rtc_time *dt) | ||
82 | { | ||
83 | struct spi_device *spi = to_spi_device(dev); | ||
84 | struct ds1390 *chip = dev_get_drvdata(dev); | ||
85 | int status; | ||
86 | |||
87 | /* build the message */ | ||
88 | chip->txrx_buf[0] = DS1390_REG_SECONDS; | ||
89 | |||
90 | /* do the i/o */ | ||
91 | status = spi_write_then_read(spi, chip->txrx_buf, 1, chip->txrx_buf, 8); | ||
92 | if (status != 0) | ||
93 | return status; | ||
94 | |||
95 | /* The chip sends data in this order: | ||
96 | * Seconds, Minutes, Hours, Day, Date, Month / Century, Year */ | ||
97 | dt->tm_sec = bcd2bin(chip->txrx_buf[0]); | ||
98 | dt->tm_min = bcd2bin(chip->txrx_buf[1]); | ||
99 | dt->tm_hour = bcd2bin(chip->txrx_buf[2]); | ||
100 | dt->tm_wday = bcd2bin(chip->txrx_buf[3]); | ||
101 | dt->tm_mday = bcd2bin(chip->txrx_buf[4]); | ||
102 | /* mask off century bit */ | ||
103 | dt->tm_mon = bcd2bin(chip->txrx_buf[5] & 0x7f) - 1; | ||
104 | /* adjust for century bit */ | ||
105 | dt->tm_year = bcd2bin(chip->txrx_buf[6]) + ((chip->txrx_buf[5] & 0x80) ? 100 : 0); | ||
106 | |||
107 | return rtc_valid_tm(dt); | ||
108 | } | ||
109 | |||
110 | static int ds1390_set_datetime(struct device *dev, struct rtc_time *dt) | ||
111 | { | ||
112 | struct spi_device *spi = to_spi_device(dev); | ||
113 | struct ds1390 *chip = dev_get_drvdata(dev); | ||
114 | |||
115 | /* build the message */ | ||
116 | chip->txrx_buf[0] = DS1390_REG_SECONDS | 0x80; | ||
117 | chip->txrx_buf[1] = bin2bcd(dt->tm_sec); | ||
118 | chip->txrx_buf[2] = bin2bcd(dt->tm_min); | ||
119 | chip->txrx_buf[3] = bin2bcd(dt->tm_hour); | ||
120 | chip->txrx_buf[4] = bin2bcd(dt->tm_wday); | ||
121 | chip->txrx_buf[5] = bin2bcd(dt->tm_mday); | ||
122 | chip->txrx_buf[6] = bin2bcd(dt->tm_mon + 1) | | ||
123 | ((dt->tm_year > 99) ? 0x80 : 0x00); | ||
124 | chip->txrx_buf[7] = bin2bcd(dt->tm_year % 100); | ||
125 | |||
126 | /* do the i/o */ | ||
127 | return spi_write_then_read(spi, chip->txrx_buf, 8, NULL, 0); | ||
128 | } | ||
129 | |||
130 | static int ds1390_read_time(struct device *dev, struct rtc_time *tm) | ||
131 | { | ||
132 | return ds1390_get_datetime(dev, tm); | ||
133 | } | ||
134 | |||
135 | static int ds1390_set_time(struct device *dev, struct rtc_time *tm) | ||
136 | { | ||
137 | return ds1390_set_datetime(dev, tm); | ||
138 | } | ||
139 | |||
140 | static const struct rtc_class_ops ds1390_rtc_ops = { | ||
141 | .read_time = ds1390_read_time, | ||
142 | .set_time = ds1390_set_time, | ||
143 | }; | ||
144 | |||
145 | static int __devinit ds1390_probe(struct spi_device *spi) | ||
146 | { | ||
147 | struct rtc_device *rtc; | ||
148 | unsigned char tmp; | ||
149 | struct ds1390 *chip; | ||
150 | int res; | ||
151 | |||
152 | printk(KERN_DEBUG "DS1390 SPI RTC driver\n"); | ||
153 | |||
154 | rtc = rtc_device_register("ds1390", | ||
155 | &spi->dev, &ds1390_rtc_ops, THIS_MODULE); | ||
156 | if (IS_ERR(rtc)) { | ||
157 | printk(KERN_ALERT "RTC : unable to register device\n"); | ||
158 | return PTR_ERR(rtc); | ||
159 | } | ||
160 | |||
161 | spi->mode = SPI_MODE_3; | ||
162 | spi->bits_per_word = 8; | ||
163 | spi_setup(spi); | ||
164 | |||
165 | chip = kzalloc(sizeof *chip, GFP_KERNEL); | ||
166 | if (!chip) { | ||
167 | printk(KERN_ALERT "RTC : unable to allocate device memory\n"); | ||
168 | rtc_device_unregister(rtc); | ||
169 | return -ENOMEM; | ||
170 | } | ||
171 | chip->rtc = rtc; | ||
172 | dev_set_drvdata(&spi->dev, chip); | ||
173 | |||
174 | res = ds1390_get_reg(&spi->dev, DS1390_REG_SECONDS, &tmp); | ||
175 | if (res) { | ||
176 | printk(KERN_ALERT "RTC : unable to read device\n"); | ||
177 | rtc_device_unregister(rtc); | ||
178 | return res; | ||
179 | } | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static int __devexit ds1390_remove(struct spi_device *spi) | ||
185 | { | ||
186 | struct ds1390 *chip = platform_get_drvdata(spi); | ||
187 | struct rtc_device *rtc = chip->rtc; | ||
188 | |||
189 | if (rtc) | ||
190 | rtc_device_unregister(rtc); | ||
191 | |||
192 | kfree(chip); | ||
193 | |||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | static struct spi_driver ds1390_driver = { | ||
198 | .driver = { | ||
199 | .name = "rtc-ds1390", | ||
200 | .owner = THIS_MODULE, | ||
201 | }, | ||
202 | .probe = ds1390_probe, | ||
203 | .remove = __devexit_p(ds1390_remove), | ||
204 | }; | ||
205 | |||
206 | static __init int ds1390_init(void) | ||
207 | { | ||
208 | return spi_register_driver(&ds1390_driver); | ||
209 | } | ||
210 | module_init(ds1390_init); | ||
211 | |||
212 | static __exit void ds1390_exit(void) | ||
213 | { | ||
214 | spi_unregister_driver(&ds1390_driver); | ||
215 | } | ||
216 | module_exit(ds1390_exit); | ||
217 | |||
218 | MODULE_DESCRIPTION("DS1390/93/94 SPI RTC driver"); | ||
219 | MODULE_AUTHOR("Mark Jackson <mpfj@mimc.co.uk>"); | ||
220 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-rx8581.c b/drivers/rtc/rtc-rx8581.c new file mode 100644 index 000000000000..c9522f3bc21c --- /dev/null +++ b/drivers/rtc/rtc-rx8581.c | |||
@@ -0,0 +1,281 @@ | |||
1 | /* | ||
2 | * An I2C driver for the Epson RX8581 RTC | ||
3 | * | ||
4 | * Author: Martyn Welch <martyn.welch@gefanuc.com> | ||
5 | * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * Based on: rtc-pcf8563.c (An I2C driver for the Philips PCF8563 RTC) | ||
12 | * Copyright 2005-06 Tower Technologies | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/i2c.h> | ||
17 | #include <linux/bcd.h> | ||
18 | #include <linux/rtc.h> | ||
19 | #include <linux/log2.h> | ||
20 | |||
21 | #define DRV_VERSION "0.1" | ||
22 | |||
23 | #define RX8581_REG_SC 0x00 /* Second in BCD */ | ||
24 | #define RX8581_REG_MN 0x01 /* Minute in BCD */ | ||
25 | #define RX8581_REG_HR 0x02 /* Hour in BCD */ | ||
26 | #define RX8581_REG_DW 0x03 /* Day of Week */ | ||
27 | #define RX8581_REG_DM 0x04 /* Day of Month in BCD */ | ||
28 | #define RX8581_REG_MO 0x05 /* Month in BCD */ | ||
29 | #define RX8581_REG_YR 0x06 /* Year in BCD */ | ||
30 | #define RX8581_REG_RAM 0x07 /* RAM */ | ||
31 | #define RX8581_REG_AMN 0x08 /* Alarm Min in BCD*/ | ||
32 | #define RX8581_REG_AHR 0x09 /* Alarm Hour in BCD */ | ||
33 | #define RX8581_REG_ADM 0x0A | ||
34 | #define RX8581_REG_ADW 0x0A | ||
35 | #define RX8581_REG_TMR0 0x0B | ||
36 | #define RX8581_REG_TMR1 0x0C | ||
37 | #define RX8581_REG_EXT 0x0D /* Extension Register */ | ||
38 | #define RX8581_REG_FLAG 0x0E /* Flag Register */ | ||
39 | #define RX8581_REG_CTRL 0x0F /* Control Register */ | ||
40 | |||
41 | |||
42 | /* Flag Register bit definitions */ | ||
43 | #define RX8581_FLAG_UF 0x20 /* Update */ | ||
44 | #define RX8581_FLAG_TF 0x10 /* Timer */ | ||
45 | #define RX8581_FLAG_AF 0x08 /* Alarm */ | ||
46 | #define RX8581_FLAG_VLF 0x02 /* Voltage Low */ | ||
47 | |||
48 | /* Control Register bit definitions */ | ||
49 | #define RX8581_CTRL_UIE 0x20 /* Update Interrupt Enable */ | ||
50 | #define RX8581_CTRL_TIE 0x10 /* Timer Interrupt Enable */ | ||
51 | #define RX8581_CTRL_AIE 0x08 /* Alarm Interrupt Enable */ | ||
52 | #define RX8581_CTRL_STOP 0x02 /* STOP bit */ | ||
53 | #define RX8581_CTRL_RESET 0x01 /* RESET bit */ | ||
54 | |||
55 | static struct i2c_driver rx8581_driver; | ||
56 | |||
57 | /* | ||
58 | * In the routines that deal directly with the rx8581 hardware, we use | ||
59 | * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. | ||
60 | */ | ||
61 | static int rx8581_get_datetime(struct i2c_client *client, struct rtc_time *tm) | ||
62 | { | ||
63 | unsigned char date[7]; | ||
64 | int data, err; | ||
65 | |||
66 | /* First we ensure that the "update flag" is not set, we read the | ||
67 | * time and date then re-read the "update flag". If the update flag | ||
68 | * has been set, we know that the time has changed during the read so | ||
69 | * we repeat the whole process again. | ||
70 | */ | ||
71 | data = i2c_smbus_read_byte_data(client, RX8581_REG_FLAG); | ||
72 | if (data < 0) { | ||
73 | dev_err(&client->dev, "Unable to read device flags\n"); | ||
74 | return -EIO; | ||
75 | } | ||
76 | |||
77 | do { | ||
78 | /* If update flag set, clear it */ | ||
79 | if (data & RX8581_FLAG_UF) { | ||
80 | err = i2c_smbus_write_byte_data(client, | ||
81 | RX8581_REG_FLAG, (data & ~RX8581_FLAG_UF)); | ||
82 | if (err != 0) { | ||
83 | dev_err(&client->dev, "Unable to write device " | ||
84 | "flags\n"); | ||
85 | return -EIO; | ||
86 | } | ||
87 | } | ||
88 | |||
89 | /* Now read time and date */ | ||
90 | err = i2c_smbus_read_i2c_block_data(client, RX8581_REG_SC, | ||
91 | 7, date); | ||
92 | if (err < 0) { | ||
93 | dev_err(&client->dev, "Unable to read date\n"); | ||
94 | return -EIO; | ||
95 | } | ||
96 | |||
97 | /* Check flag register */ | ||
98 | data = i2c_smbus_read_byte_data(client, RX8581_REG_FLAG); | ||
99 | if (data < 0) { | ||
100 | dev_err(&client->dev, "Unable to read device flags\n"); | ||
101 | return -EIO; | ||
102 | } | ||
103 | } while (data & RX8581_FLAG_UF); | ||
104 | |||
105 | if (data & RX8581_FLAG_VLF) | ||
106 | dev_info(&client->dev, | ||
107 | "low voltage detected, date/time is not reliable.\n"); | ||
108 | |||
109 | dev_dbg(&client->dev, | ||
110 | "%s: raw data is sec=%02x, min=%02x, hr=%02x, " | ||
111 | "wday=%02x, mday=%02x, mon=%02x, year=%02x\n", | ||
112 | __func__, | ||
113 | date[0], date[1], date[2], date[3], date[4], date[5], date[6]); | ||
114 | |||
115 | tm->tm_sec = bcd2bin(date[RX8581_REG_SC] & 0x7F); | ||
116 | tm->tm_min = bcd2bin(date[RX8581_REG_MN] & 0x7F); | ||
117 | tm->tm_hour = bcd2bin(date[RX8581_REG_HR] & 0x3F); /* rtc hr 0-23 */ | ||
118 | tm->tm_wday = ilog2(date[RX8581_REG_DW] & 0x7F); | ||
119 | tm->tm_mday = bcd2bin(date[RX8581_REG_DM] & 0x3F); | ||
120 | tm->tm_mon = bcd2bin(date[RX8581_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */ | ||
121 | tm->tm_year = bcd2bin(date[RX8581_REG_YR]); | ||
122 | if (tm->tm_year < 70) | ||
123 | tm->tm_year += 100; /* assume we are in 1970...2069 */ | ||
124 | |||
125 | |||
126 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " | ||
127 | "mday=%d, mon=%d, year=%d, wday=%d\n", | ||
128 | __func__, | ||
129 | tm->tm_sec, tm->tm_min, tm->tm_hour, | ||
130 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | ||
131 | |||
132 | err = rtc_valid_tm(tm); | ||
133 | if (err < 0) | ||
134 | dev_err(&client->dev, "retrieved date/time is not valid.\n"); | ||
135 | |||
136 | return err; | ||
137 | } | ||
138 | |||
139 | static int rx8581_set_datetime(struct i2c_client *client, struct rtc_time *tm) | ||
140 | { | ||
141 | int data, err; | ||
142 | unsigned char buf[7]; | ||
143 | |||
144 | dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, " | ||
145 | "mday=%d, mon=%d, year=%d, wday=%d\n", | ||
146 | __func__, | ||
147 | tm->tm_sec, tm->tm_min, tm->tm_hour, | ||
148 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | ||
149 | |||
150 | /* hours, minutes and seconds */ | ||
151 | buf[RX8581_REG_SC] = bin2bcd(tm->tm_sec); | ||
152 | buf[RX8581_REG_MN] = bin2bcd(tm->tm_min); | ||
153 | buf[RX8581_REG_HR] = bin2bcd(tm->tm_hour); | ||
154 | |||
155 | buf[RX8581_REG_DM] = bin2bcd(tm->tm_mday); | ||
156 | |||
157 | /* month, 1 - 12 */ | ||
158 | buf[RX8581_REG_MO] = bin2bcd(tm->tm_mon + 1); | ||
159 | |||
160 | /* year and century */ | ||
161 | buf[RX8581_REG_YR] = bin2bcd(tm->tm_year % 100); | ||
162 | buf[RX8581_REG_DW] = (0x1 << tm->tm_wday); | ||
163 | |||
164 | /* Stop the clock */ | ||
165 | data = i2c_smbus_read_byte_data(client, RX8581_REG_CTRL); | ||
166 | if (data < 0) { | ||
167 | dev_err(&client->dev, "Unable to read control register\n"); | ||
168 | return -EIO; | ||
169 | } | ||
170 | |||
171 | err = i2c_smbus_write_byte_data(client, RX8581_REG_FLAG, | ||
172 | (data | RX8581_CTRL_STOP)); | ||
173 | if (err < 0) { | ||
174 | dev_err(&client->dev, "Unable to write control register\n"); | ||
175 | return -EIO; | ||
176 | } | ||
177 | |||
178 | /* write register's data */ | ||
179 | err = i2c_smbus_write_i2c_block_data(client, RX8581_REG_SC, 7, buf); | ||
180 | if (err < 0) { | ||
181 | dev_err(&client->dev, "Unable to write to date registers\n"); | ||
182 | return -EIO; | ||
183 | } | ||
184 | |||
185 | /* Restart the clock */ | ||
186 | data = i2c_smbus_read_byte_data(client, RX8581_REG_CTRL); | ||
187 | if (data < 0) { | ||
188 | dev_err(&client->dev, "Unable to read control register\n"); | ||
189 | return -EIO; | ||
190 | } | ||
191 | |||
192 | err = i2c_smbus_write_byte_data(client, RX8581_REG_FLAG, | ||
193 | (data | ~(RX8581_CTRL_STOP))); | ||
194 | if (err != 0) { | ||
195 | dev_err(&client->dev, "Unable to write control register\n"); | ||
196 | return -EIO; | ||
197 | } | ||
198 | |||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | static int rx8581_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
203 | { | ||
204 | return rx8581_get_datetime(to_i2c_client(dev), tm); | ||
205 | } | ||
206 | |||
207 | static int rx8581_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
208 | { | ||
209 | return rx8581_set_datetime(to_i2c_client(dev), tm); | ||
210 | } | ||
211 | |||
212 | static const struct rtc_class_ops rx8581_rtc_ops = { | ||
213 | .read_time = rx8581_rtc_read_time, | ||
214 | .set_time = rx8581_rtc_set_time, | ||
215 | }; | ||
216 | |||
217 | static int __devinit rx8581_probe(struct i2c_client *client, | ||
218 | const struct i2c_device_id *id) | ||
219 | { | ||
220 | struct rtc_device *rtc; | ||
221 | |||
222 | dev_dbg(&client->dev, "%s\n", __func__); | ||
223 | |||
224 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) | ||
225 | return -ENODEV; | ||
226 | |||
227 | dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n"); | ||
228 | |||
229 | rtc = rtc_device_register(rx8581_driver.driver.name, | ||
230 | &client->dev, &rx8581_rtc_ops, THIS_MODULE); | ||
231 | |||
232 | if (IS_ERR(rtc)) | ||
233 | return PTR_ERR(rtc); | ||
234 | |||
235 | i2c_set_clientdata(client, rtc); | ||
236 | |||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | static int __devexit rx8581_remove(struct i2c_client *client) | ||
241 | { | ||
242 | struct rtc_device *rtc = i2c_get_clientdata(client); | ||
243 | |||
244 | rtc_device_unregister(rtc); | ||
245 | |||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | static const struct i2c_device_id rx8581_id[] = { | ||
250 | { "rx8581", 0 }, | ||
251 | { } | ||
252 | }; | ||
253 | MODULE_DEVICE_TABLE(i2c, rx8581_id); | ||
254 | |||
255 | static struct i2c_driver rx8581_driver = { | ||
256 | .driver = { | ||
257 | .name = "rtc-rx8581", | ||
258 | .owner = THIS_MODULE, | ||
259 | }, | ||
260 | .probe = rx8581_probe, | ||
261 | .remove = __devexit_p(rx8581_remove), | ||
262 | .id_table = rx8581_id, | ||
263 | }; | ||
264 | |||
265 | static int __init rx8581_init(void) | ||
266 | { | ||
267 | return i2c_add_driver(&rx8581_driver); | ||
268 | } | ||
269 | |||
270 | static void __exit rx8581_exit(void) | ||
271 | { | ||
272 | i2c_del_driver(&rx8581_driver); | ||
273 | } | ||
274 | |||
275 | MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com>"); | ||
276 | MODULE_DESCRIPTION("Epson RX-8581 RTC driver"); | ||
277 | MODULE_LICENSE("GPL"); | ||
278 | MODULE_VERSION(DRV_VERSION); | ||
279 | |||
280 | module_init(rx8581_init); | ||
281 | module_exit(rx8581_exit); | ||
diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c new file mode 100644 index 000000000000..5c5e3aa91385 --- /dev/null +++ b/drivers/rtc/rtc-wm8350.c | |||
@@ -0,0 +1,514 @@ | |||
1 | /* | ||
2 | * Real Time Clock driver for Wolfson Microelectronics WM8350 | ||
3 | * | ||
4 | * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC. | ||
5 | * | ||
6 | * Author: Liam Girdwood | ||
7 | * linux@wolfsonmicro.com | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/time.h> | ||
19 | #include <linux/rtc.h> | ||
20 | #include <linux/bcd.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/ioctl.h> | ||
23 | #include <linux/completion.h> | ||
24 | #include <linux/mfd/wm8350/rtc.h> | ||
25 | #include <linux/mfd/wm8350/core.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | |||
29 | #define WM8350_SET_ALM_RETRIES 5 | ||
30 | #define WM8350_SET_TIME_RETRIES 5 | ||
31 | #define WM8350_GET_TIME_RETRIES 5 | ||
32 | |||
33 | #define to_wm8350_from_rtc_dev(d) container_of(d, struct wm8350, rtc.pdev.dev) | ||
34 | |||
35 | /* | ||
36 | * Read current time and date in RTC | ||
37 | */ | ||
38 | static int wm8350_rtc_readtime(struct device *dev, struct rtc_time *tm) | ||
39 | { | ||
40 | struct wm8350 *wm8350 = dev_get_drvdata(dev); | ||
41 | u16 time1[4], time2[4]; | ||
42 | int retries = WM8350_GET_TIME_RETRIES, ret; | ||
43 | |||
44 | /* | ||
45 | * Read the time twice and compare. | ||
46 | * If time1 == time2, then time is valid else retry. | ||
47 | */ | ||
48 | do { | ||
49 | ret = wm8350_block_read(wm8350, WM8350_RTC_SECONDS_MINUTES, | ||
50 | 4, time1); | ||
51 | if (ret < 0) | ||
52 | return ret; | ||
53 | ret = wm8350_block_read(wm8350, WM8350_RTC_SECONDS_MINUTES, | ||
54 | 4, time2); | ||
55 | if (ret < 0) | ||
56 | return ret; | ||
57 | |||
58 | if (memcmp(time1, time2, sizeof(time1)) == 0) { | ||
59 | tm->tm_sec = time1[0] & WM8350_RTC_SECS_MASK; | ||
60 | |||
61 | tm->tm_min = (time1[0] & WM8350_RTC_MINS_MASK) | ||
62 | >> WM8350_RTC_MINS_SHIFT; | ||
63 | |||
64 | tm->tm_hour = time1[1] & WM8350_RTC_HRS_MASK; | ||
65 | |||
66 | tm->tm_wday = ((time1[1] >> WM8350_RTC_DAY_SHIFT) | ||
67 | & 0x7) - 1; | ||
68 | |||
69 | tm->tm_mon = ((time1[2] & WM8350_RTC_MTH_MASK) | ||
70 | >> WM8350_RTC_MTH_SHIFT) - 1; | ||
71 | |||
72 | tm->tm_mday = (time1[2] & WM8350_RTC_DATE_MASK); | ||
73 | |||
74 | tm->tm_year = ((time1[3] & WM8350_RTC_YHUNDREDS_MASK) | ||
75 | >> WM8350_RTC_YHUNDREDS_SHIFT) * 100; | ||
76 | tm->tm_year += time1[3] & WM8350_RTC_YUNITS_MASK; | ||
77 | |||
78 | tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, | ||
79 | tm->tm_year); | ||
80 | tm->tm_year -= 1900; | ||
81 | |||
82 | dev_dbg(dev, "Read (%d left): %04x %04x %04x %04x\n", | ||
83 | retries, | ||
84 | time1[0], time1[1], time1[2], time1[3]); | ||
85 | |||
86 | return 0; | ||
87 | } | ||
88 | } while (retries--); | ||
89 | |||
90 | dev_err(dev, "timed out reading RTC time\n"); | ||
91 | return -EIO; | ||
92 | } | ||
93 | |||
94 | /* | ||
95 | * Set current time and date in RTC | ||
96 | */ | ||
97 | static int wm8350_rtc_settime(struct device *dev, struct rtc_time *tm) | ||
98 | { | ||
99 | struct wm8350 *wm8350 = dev_get_drvdata(dev); | ||
100 | u16 time[4]; | ||
101 | u16 rtc_ctrl; | ||
102 | int ret, retries = WM8350_SET_TIME_RETRIES; | ||
103 | |||
104 | time[0] = tm->tm_sec; | ||
105 | time[0] |= tm->tm_min << WM8350_RTC_MINS_SHIFT; | ||
106 | time[1] = tm->tm_hour; | ||
107 | time[1] |= (tm->tm_wday + 1) << WM8350_RTC_DAY_SHIFT; | ||
108 | time[2] = tm->tm_mday; | ||
109 | time[2] |= (tm->tm_mon + 1) << WM8350_RTC_MTH_SHIFT; | ||
110 | time[3] = ((tm->tm_year + 1900) / 100) << WM8350_RTC_YHUNDREDS_SHIFT; | ||
111 | time[3] |= (tm->tm_year + 1900) % 100; | ||
112 | |||
113 | dev_dbg(dev, "Setting: %04x %04x %04x %04x\n", | ||
114 | time[0], time[1], time[2], time[3]); | ||
115 | |||
116 | /* Set RTC_SET to stop the clock */ | ||
117 | ret = wm8350_set_bits(wm8350, WM8350_RTC_TIME_CONTROL, WM8350_RTC_SET); | ||
118 | if (ret < 0) | ||
119 | return ret; | ||
120 | |||
121 | /* Wait until confirmation of stopping */ | ||
122 | do { | ||
123 | rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); | ||
124 | schedule_timeout_uninterruptible(msecs_to_jiffies(1)); | ||
125 | } while (retries-- && !(rtc_ctrl & WM8350_RTC_STS)); | ||
126 | |||
127 | if (!retries) { | ||
128 | dev_err(dev, "timed out on set confirmation\n"); | ||
129 | return -EIO; | ||
130 | } | ||
131 | |||
132 | /* Write time to RTC */ | ||
133 | ret = wm8350_block_write(wm8350, WM8350_RTC_SECONDS_MINUTES, 4, time); | ||
134 | if (ret < 0) | ||
135 | return ret; | ||
136 | |||
137 | /* Clear RTC_SET to start the clock */ | ||
138 | ret = wm8350_clear_bits(wm8350, WM8350_RTC_TIME_CONTROL, | ||
139 | WM8350_RTC_SET); | ||
140 | return ret; | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * Read alarm time and date in RTC | ||
145 | */ | ||
146 | static int wm8350_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
147 | { | ||
148 | struct wm8350 *wm8350 = dev_get_drvdata(dev); | ||
149 | struct rtc_time *tm = &alrm->time; | ||
150 | u16 time[4]; | ||
151 | int ret; | ||
152 | |||
153 | ret = wm8350_block_read(wm8350, WM8350_ALARM_SECONDS_MINUTES, 4, time); | ||
154 | if (ret < 0) | ||
155 | return ret; | ||
156 | |||
157 | tm->tm_sec = time[0] & WM8350_RTC_ALMSECS_MASK; | ||
158 | if (tm->tm_sec == WM8350_RTC_ALMSECS_MASK) | ||
159 | tm->tm_sec = -1; | ||
160 | |||
161 | tm->tm_min = time[0] & WM8350_RTC_ALMMINS_MASK; | ||
162 | if (tm->tm_min == WM8350_RTC_ALMMINS_MASK) | ||
163 | tm->tm_min = -1; | ||
164 | else | ||
165 | tm->tm_min >>= WM8350_RTC_ALMMINS_SHIFT; | ||
166 | |||
167 | tm->tm_hour = time[1] & WM8350_RTC_ALMHRS_MASK; | ||
168 | if (tm->tm_hour == WM8350_RTC_ALMHRS_MASK) | ||
169 | tm->tm_hour = -1; | ||
170 | |||
171 | tm->tm_wday = ((time[1] >> WM8350_RTC_ALMDAY_SHIFT) & 0x7) - 1; | ||
172 | if (tm->tm_wday > 7) | ||
173 | tm->tm_wday = -1; | ||
174 | |||
175 | tm->tm_mon = time[2] & WM8350_RTC_ALMMTH_MASK; | ||
176 | if (tm->tm_mon == WM8350_RTC_ALMMTH_MASK) | ||
177 | tm->tm_mon = -1; | ||
178 | else | ||
179 | tm->tm_mon = (tm->tm_mon >> WM8350_RTC_ALMMTH_SHIFT) - 1; | ||
180 | |||
181 | tm->tm_mday = (time[2] & WM8350_RTC_ALMDATE_MASK); | ||
182 | if (tm->tm_mday == WM8350_RTC_ALMDATE_MASK) | ||
183 | tm->tm_mday = -1; | ||
184 | |||
185 | tm->tm_year = -1; | ||
186 | |||
187 | alrm->enabled = !(time[3] & WM8350_RTC_ALMSTS); | ||
188 | |||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static int wm8350_rtc_stop_alarm(struct wm8350 *wm8350) | ||
193 | { | ||
194 | int retries = WM8350_SET_ALM_RETRIES; | ||
195 | u16 rtc_ctrl; | ||
196 | int ret; | ||
197 | |||
198 | /* Set RTC_SET to stop the clock */ | ||
199 | ret = wm8350_set_bits(wm8350, WM8350_RTC_TIME_CONTROL, | ||
200 | WM8350_RTC_ALMSET); | ||
201 | if (ret < 0) | ||
202 | return ret; | ||
203 | |||
204 | /* Wait until confirmation of stopping */ | ||
205 | do { | ||
206 | rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); | ||
207 | schedule_timeout_uninterruptible(msecs_to_jiffies(1)); | ||
208 | } while (retries-- && !(rtc_ctrl & WM8350_RTC_ALMSTS)); | ||
209 | |||
210 | if (!(rtc_ctrl & WM8350_RTC_ALMSTS)) | ||
211 | return -ETIMEDOUT; | ||
212 | |||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | static int wm8350_rtc_start_alarm(struct wm8350 *wm8350) | ||
217 | { | ||
218 | int ret; | ||
219 | int retries = WM8350_SET_ALM_RETRIES; | ||
220 | u16 rtc_ctrl; | ||
221 | |||
222 | ret = wm8350_clear_bits(wm8350, WM8350_RTC_TIME_CONTROL, | ||
223 | WM8350_RTC_ALMSET); | ||
224 | if (ret < 0) | ||
225 | return ret; | ||
226 | |||
227 | /* Wait until confirmation */ | ||
228 | do { | ||
229 | rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); | ||
230 | schedule_timeout_uninterruptible(msecs_to_jiffies(1)); | ||
231 | } while (retries-- && rtc_ctrl & WM8350_RTC_ALMSTS); | ||
232 | |||
233 | if (rtc_ctrl & WM8350_RTC_ALMSTS) | ||
234 | return -ETIMEDOUT; | ||
235 | |||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | static int wm8350_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
240 | { | ||
241 | struct wm8350 *wm8350 = dev_get_drvdata(dev); | ||
242 | struct rtc_time *tm = &alrm->time; | ||
243 | u16 time[3]; | ||
244 | int ret; | ||
245 | |||
246 | memset(time, 0, sizeof(time)); | ||
247 | |||
248 | if (tm->tm_sec != -1) | ||
249 | time[0] |= tm->tm_sec; | ||
250 | else | ||
251 | time[0] |= WM8350_RTC_ALMSECS_MASK; | ||
252 | |||
253 | if (tm->tm_min != -1) | ||
254 | time[0] |= tm->tm_min << WM8350_RTC_ALMMINS_SHIFT; | ||
255 | else | ||
256 | time[0] |= WM8350_RTC_ALMMINS_MASK; | ||
257 | |||
258 | if (tm->tm_hour != -1) | ||
259 | time[1] |= tm->tm_hour; | ||
260 | else | ||
261 | time[1] |= WM8350_RTC_ALMHRS_MASK; | ||
262 | |||
263 | if (tm->tm_wday != -1) | ||
264 | time[1] |= (tm->tm_wday + 1) << WM8350_RTC_ALMDAY_SHIFT; | ||
265 | else | ||
266 | time[1] |= WM8350_RTC_ALMDAY_MASK; | ||
267 | |||
268 | if (tm->tm_mday != -1) | ||
269 | time[2] |= tm->tm_mday; | ||
270 | else | ||
271 | time[2] |= WM8350_RTC_ALMDATE_MASK; | ||
272 | |||
273 | if (tm->tm_mon != -1) | ||
274 | time[2] |= (tm->tm_mon + 1) << WM8350_RTC_ALMMTH_SHIFT; | ||
275 | else | ||
276 | time[2] |= WM8350_RTC_ALMMTH_MASK; | ||
277 | |||
278 | ret = wm8350_rtc_stop_alarm(wm8350); | ||
279 | if (ret < 0) | ||
280 | return ret; | ||
281 | |||
282 | /* Write time to RTC */ | ||
283 | ret = wm8350_block_write(wm8350, WM8350_ALARM_SECONDS_MINUTES, | ||
284 | 3, time); | ||
285 | if (ret < 0) | ||
286 | return ret; | ||
287 | |||
288 | if (alrm->enabled) | ||
289 | ret = wm8350_rtc_start_alarm(wm8350); | ||
290 | |||
291 | return ret; | ||
292 | } | ||
293 | |||
294 | /* | ||
295 | * Handle commands from user-space | ||
296 | */ | ||
297 | static int wm8350_rtc_ioctl(struct device *dev, unsigned int cmd, | ||
298 | unsigned long arg) | ||
299 | { | ||
300 | struct wm8350 *wm8350 = dev_get_drvdata(dev); | ||
301 | |||
302 | switch (cmd) { | ||
303 | case RTC_AIE_OFF: | ||
304 | return wm8350_rtc_stop_alarm(wm8350); | ||
305 | case RTC_AIE_ON: | ||
306 | return wm8350_rtc_start_alarm(wm8350); | ||
307 | |||
308 | case RTC_UIE_OFF: | ||
309 | wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); | ||
310 | break; | ||
311 | case RTC_UIE_ON: | ||
312 | wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC); | ||
313 | break; | ||
314 | |||
315 | default: | ||
316 | return -ENOIOCTLCMD; | ||
317 | } | ||
318 | |||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | static void wm8350_rtc_alarm_handler(struct wm8350 *wm8350, int irq, | ||
323 | void *data) | ||
324 | { | ||
325 | struct rtc_device *rtc = wm8350->rtc.rtc; | ||
326 | int ret; | ||
327 | |||
328 | rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF); | ||
329 | |||
330 | /* Make it one shot */ | ||
331 | ret = wm8350_set_bits(wm8350, WM8350_RTC_TIME_CONTROL, | ||
332 | WM8350_RTC_ALMSET); | ||
333 | if (ret != 0) { | ||
334 | dev_err(&(wm8350->rtc.pdev->dev), | ||
335 | "Failed to disable alarm: %d\n", ret); | ||
336 | } | ||
337 | } | ||
338 | |||
339 | static void wm8350_rtc_update_handler(struct wm8350 *wm8350, int irq, | ||
340 | void *data) | ||
341 | { | ||
342 | struct rtc_device *rtc = wm8350->rtc.rtc; | ||
343 | |||
344 | rtc_update_irq(rtc, 1, RTC_IRQF | RTC_UF); | ||
345 | } | ||
346 | |||
347 | static const struct rtc_class_ops wm8350_rtc_ops = { | ||
348 | .ioctl = wm8350_rtc_ioctl, | ||
349 | .read_time = wm8350_rtc_readtime, | ||
350 | .set_time = wm8350_rtc_settime, | ||
351 | .read_alarm = wm8350_rtc_readalarm, | ||
352 | .set_alarm = wm8350_rtc_setalarm, | ||
353 | }; | ||
354 | |||
355 | #ifdef CONFIG_PM | ||
356 | static int wm8350_rtc_suspend(struct platform_device *pdev, pm_message_t state) | ||
357 | { | ||
358 | struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev); | ||
359 | int ret = 0; | ||
360 | u16 reg; | ||
361 | |||
362 | reg = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); | ||
363 | |||
364 | if (device_may_wakeup(&wm8350->rtc.pdev->dev) && | ||
365 | reg & WM8350_RTC_ALMSTS) { | ||
366 | ret = wm8350_rtc_stop_alarm(wm8350); | ||
367 | if (ret != 0) | ||
368 | dev_err(&pdev->dev, "Failed to stop RTC alarm: %d\n", | ||
369 | ret); | ||
370 | } | ||
371 | |||
372 | return ret; | ||
373 | } | ||
374 | |||
375 | static int wm8350_rtc_resume(struct platform_device *pdev) | ||
376 | { | ||
377 | struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev); | ||
378 | int ret; | ||
379 | |||
380 | if (wm8350->rtc.alarm_enabled) { | ||
381 | ret = wm8350_rtc_start_alarm(wm8350); | ||
382 | if (ret != 0) | ||
383 | dev_err(&pdev->dev, | ||
384 | "Failed to restart RTC alarm: %d\n", ret); | ||
385 | } | ||
386 | |||
387 | return 0; | ||
388 | } | ||
389 | |||
390 | #else | ||
391 | #define wm8350_rtc_suspend NULL | ||
392 | #define wm8350_rtc_resume NULL | ||
393 | #endif | ||
394 | |||
395 | static int wm8350_rtc_probe(struct platform_device *pdev) | ||
396 | { | ||
397 | struct wm8350 *wm8350 = platform_get_drvdata(pdev); | ||
398 | struct wm8350_rtc *wm_rtc = &wm8350->rtc; | ||
399 | int ret = 0; | ||
400 | u16 timectl, power5; | ||
401 | |||
402 | timectl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); | ||
403 | if (timectl & WM8350_RTC_BCD) { | ||
404 | dev_err(&pdev->dev, "RTC BCD mode not supported\n"); | ||
405 | return -EINVAL; | ||
406 | } | ||
407 | if (timectl & WM8350_RTC_12HR) { | ||
408 | dev_err(&pdev->dev, "RTC 12 hour mode not supported\n"); | ||
409 | return -EINVAL; | ||
410 | } | ||
411 | |||
412 | /* enable the RTC if it's not already enabled */ | ||
413 | power5 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_5); | ||
414 | if (!(power5 & WM8350_RTC_TICK_ENA)) { | ||
415 | dev_info(wm8350->dev, "Starting RTC\n"); | ||
416 | |||
417 | wm8350_reg_unlock(wm8350); | ||
418 | |||
419 | ret = wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, | ||
420 | WM8350_RTC_TICK_ENA); | ||
421 | if (ret < 0) { | ||
422 | dev_err(&pdev->dev, "failed to enable RTC: %d\n", ret); | ||
423 | return ret; | ||
424 | } | ||
425 | |||
426 | wm8350_reg_lock(wm8350); | ||
427 | } | ||
428 | |||
429 | if (timectl & WM8350_RTC_STS) { | ||
430 | int retries; | ||
431 | |||
432 | ret = wm8350_clear_bits(wm8350, WM8350_RTC_TIME_CONTROL, | ||
433 | WM8350_RTC_SET); | ||
434 | if (ret < 0) { | ||
435 | dev_err(&pdev->dev, "failed to start: %d\n", ret); | ||
436 | return ret; | ||
437 | } | ||
438 | |||
439 | retries = WM8350_SET_TIME_RETRIES; | ||
440 | do { | ||
441 | timectl = wm8350_reg_read(wm8350, | ||
442 | WM8350_RTC_TIME_CONTROL); | ||
443 | } while (timectl & WM8350_RTC_STS && retries--); | ||
444 | |||
445 | if (retries == 0) { | ||
446 | dev_err(&pdev->dev, "failed to start: timeout\n"); | ||
447 | return -ENODEV; | ||
448 | } | ||
449 | } | ||
450 | |||
451 | device_init_wakeup(&pdev->dev, 1); | ||
452 | |||
453 | wm_rtc->rtc = rtc_device_register("wm8350", &pdev->dev, | ||
454 | &wm8350_rtc_ops, THIS_MODULE); | ||
455 | if (IS_ERR(wm_rtc->rtc)) { | ||
456 | ret = PTR_ERR(wm_rtc->rtc); | ||
457 | dev_err(&pdev->dev, "failed to register RTC: %d\n", ret); | ||
458 | return ret; | ||
459 | } | ||
460 | |||
461 | wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); | ||
462 | wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_PER); | ||
463 | |||
464 | wm8350_register_irq(wm8350, WM8350_IRQ_RTC_SEC, | ||
465 | wm8350_rtc_update_handler, NULL); | ||
466 | |||
467 | wm8350_register_irq(wm8350, WM8350_IRQ_RTC_ALM, | ||
468 | wm8350_rtc_alarm_handler, NULL); | ||
469 | wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_ALM); | ||
470 | |||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | static int __devexit wm8350_rtc_remove(struct platform_device *pdev) | ||
475 | { | ||
476 | struct wm8350 *wm8350 = platform_get_drvdata(pdev); | ||
477 | struct wm8350_rtc *wm_rtc = &wm8350->rtc; | ||
478 | |||
479 | wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); | ||
480 | |||
481 | wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC); | ||
482 | wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM); | ||
483 | |||
484 | rtc_device_unregister(wm_rtc->rtc); | ||
485 | |||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | static struct platform_driver wm8350_rtc_driver = { | ||
490 | .probe = wm8350_rtc_probe, | ||
491 | .remove = __devexit_p(wm8350_rtc_remove), | ||
492 | .suspend = wm8350_rtc_suspend, | ||
493 | .resume = wm8350_rtc_resume, | ||
494 | .driver = { | ||
495 | .name = "wm8350-rtc", | ||
496 | }, | ||
497 | }; | ||
498 | |||
499 | static int __init wm8350_rtc_init(void) | ||
500 | { | ||
501 | return platform_driver_register(&wm8350_rtc_driver); | ||
502 | } | ||
503 | module_init(wm8350_rtc_init); | ||
504 | |||
505 | static void __exit wm8350_rtc_exit(void) | ||
506 | { | ||
507 | platform_driver_unregister(&wm8350_rtc_driver); | ||
508 | } | ||
509 | module_exit(wm8350_rtc_exit); | ||
510 | |||
511 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | ||
512 | MODULE_DESCRIPTION("RTC driver for the WM8350"); | ||
513 | MODULE_LICENSE("GPL"); | ||
514 | MODULE_ALIAS("platform:wm8350-rtc"); | ||
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index 61fb8b6d19af..d5efd6c77904 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c | |||
@@ -1258,6 +1258,8 @@ static void __devinit atmel_init_port(struct atmel_uart_port *atmel_port, | |||
1258 | atmel_port->clk = clk_get(&pdev->dev, "usart"); | 1258 | atmel_port->clk = clk_get(&pdev->dev, "usart"); |
1259 | clk_enable(atmel_port->clk); | 1259 | clk_enable(atmel_port->clk); |
1260 | port->uartclk = clk_get_rate(atmel_port->clk); | 1260 | port->uartclk = clk_get_rate(atmel_port->clk); |
1261 | clk_disable(atmel_port->clk); | ||
1262 | /* only enable clock when USART is in use */ | ||
1261 | } | 1263 | } |
1262 | 1264 | ||
1263 | atmel_port->use_dma_rx = data->use_dma_rx; | 1265 | atmel_port->use_dma_rx = data->use_dma_rx; |
@@ -1379,6 +1381,8 @@ static int __init atmel_console_setup(struct console *co, char *options) | |||
1379 | return -ENODEV; | 1381 | return -ENODEV; |
1380 | } | 1382 | } |
1381 | 1383 | ||
1384 | clk_enable(atmel_ports[co->index].clk); | ||
1385 | |||
1382 | UART_PUT_IDR(port, -1); | 1386 | UART_PUT_IDR(port, -1); |
1383 | UART_PUT_CR(port, ATMEL_US_RSTSTA | ATMEL_US_RSTRX); | 1387 | UART_PUT_CR(port, ATMEL_US_RSTSTA | ATMEL_US_RSTRX); |
1384 | UART_PUT_CR(port, ATMEL_US_TXEN | ATMEL_US_RXEN); | 1388 | UART_PUT_CR(port, ATMEL_US_TXEN | ATMEL_US_RXEN); |
@@ -1403,7 +1407,7 @@ static struct console atmel_console = { | |||
1403 | .data = &atmel_uart, | 1407 | .data = &atmel_uart, |
1404 | }; | 1408 | }; |
1405 | 1409 | ||
1406 | #define ATMEL_CONSOLE_DEVICE &atmel_console | 1410 | #define ATMEL_CONSOLE_DEVICE (&atmel_console) |
1407 | 1411 | ||
1408 | /* | 1412 | /* |
1409 | * Early console initialization (before VM subsystem initialized). | 1413 | * Early console initialization (before VM subsystem initialized). |
@@ -1534,6 +1538,15 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev) | |||
1534 | if (ret) | 1538 | if (ret) |
1535 | goto err_add_port; | 1539 | goto err_add_port; |
1536 | 1540 | ||
1541 | if (atmel_is_console_port(&port->uart) | ||
1542 | && ATMEL_CONSOLE_DEVICE->flags & CON_ENABLED) { | ||
1543 | /* | ||
1544 | * The serial core enabled the clock for us, so undo | ||
1545 | * the clk_enable() in atmel_console_setup() | ||
1546 | */ | ||
1547 | clk_disable(port->clk); | ||
1548 | } | ||
1549 | |||
1537 | device_init_wakeup(&pdev->dev, 1); | 1550 | device_init_wakeup(&pdev->dev, 1); |
1538 | platform_set_drvdata(pdev, port); | 1551 | platform_set_drvdata(pdev, port); |
1539 | 1552 | ||
@@ -1544,7 +1557,6 @@ err_add_port: | |||
1544 | port->rx_ring.buf = NULL; | 1557 | port->rx_ring.buf = NULL; |
1545 | err_alloc_ring: | 1558 | err_alloc_ring: |
1546 | if (!atmel_is_console_port(&port->uart)) { | 1559 | if (!atmel_is_console_port(&port->uart)) { |
1547 | clk_disable(port->clk); | ||
1548 | clk_put(port->clk); | 1560 | clk_put(port->clk); |
1549 | port->clk = NULL; | 1561 | port->clk = NULL; |
1550 | } | 1562 | } |
@@ -1568,7 +1580,6 @@ static int __devexit atmel_serial_remove(struct platform_device *pdev) | |||
1568 | 1580 | ||
1569 | /* "port" is allocated statically, so we shouldn't free it */ | 1581 | /* "port" is allocated statically, so we shouldn't free it */ |
1570 | 1582 | ||
1571 | clk_disable(atmel_port->clk); | ||
1572 | clk_put(atmel_port->clk); | 1583 | clk_put(atmel_port->clk); |
1573 | 1584 | ||
1574 | return ret; | 1585 | return ret; |
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index 02f9320f3efc..8abae4ad0fa5 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c | |||
@@ -766,6 +766,7 @@ static int __init atmel_spi_probe(struct platform_device *pdev) | |||
766 | /* Initialize the hardware */ | 766 | /* Initialize the hardware */ |
767 | clk_enable(clk); | 767 | clk_enable(clk); |
768 | spi_writel(as, CR, SPI_BIT(SWRST)); | 768 | spi_writel(as, CR, SPI_BIT(SWRST)); |
769 | spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ | ||
769 | spi_writel(as, MR, SPI_BIT(MSTR) | SPI_BIT(MODFDIS)); | 770 | spi_writel(as, MR, SPI_BIT(MSTR) | SPI_BIT(MODFDIS)); |
770 | spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS)); | 771 | spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS)); |
771 | spi_writel(as, CR, SPI_BIT(SPIEN)); | 772 | spi_writel(as, CR, SPI_BIT(SPIEN)); |
@@ -782,6 +783,7 @@ static int __init atmel_spi_probe(struct platform_device *pdev) | |||
782 | 783 | ||
783 | out_reset_hw: | 784 | out_reset_hw: |
784 | spi_writel(as, CR, SPI_BIT(SWRST)); | 785 | spi_writel(as, CR, SPI_BIT(SWRST)); |
786 | spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ | ||
785 | clk_disable(clk); | 787 | clk_disable(clk); |
786 | free_irq(irq, master); | 788 | free_irq(irq, master); |
787 | out_unmap_regs: | 789 | out_unmap_regs: |
@@ -805,6 +807,7 @@ static int __exit atmel_spi_remove(struct platform_device *pdev) | |||
805 | spin_lock_irq(&as->lock); | 807 | spin_lock_irq(&as->lock); |
806 | as->stopping = 1; | 808 | as->stopping = 1; |
807 | spi_writel(as, CR, SPI_BIT(SWRST)); | 809 | spi_writel(as, CR, SPI_BIT(SWRST)); |
810 | spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ | ||
808 | spi_readl(as, SR); | 811 | spi_readl(as, SR); |
809 | spin_unlock_irq(&as->lock); | 812 | spin_unlock_irq(&as->lock); |
810 | 813 | ||
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig index 307b1f62d949..b1b947edcf01 100644 --- a/drivers/ssb/Kconfig +++ b/drivers/ssb/Kconfig | |||
@@ -1,10 +1,11 @@ | |||
1 | menu "Sonics Silicon Backplane" | ||
2 | |||
3 | config SSB_POSSIBLE | 1 | config SSB_POSSIBLE |
4 | bool | 2 | bool |
5 | depends on HAS_IOMEM && HAS_DMA | 3 | depends on HAS_IOMEM && HAS_DMA |
6 | default y | 4 | default y |
7 | 5 | ||
6 | menu "Sonics Silicon Backplane" | ||
7 | depends on SSB_POSSIBLE | ||
8 | |||
8 | config SSB | 9 | config SSB |
9 | tristate "Sonics Silicon Backplane support" | 10 | tristate "Sonics Silicon Backplane support" |
10 | depends on SSB_POSSIBLE | 11 | depends on SSB_POSSIBLE |
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index e1654f59eb70..c95b286a1239 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig | |||
@@ -21,7 +21,23 @@ menuconfig STAGING | |||
21 | 21 | ||
22 | If in doubt, say N here. | 22 | If in doubt, say N here. |
23 | 23 | ||
24 | if STAGING | 24 | |
25 | config STAGING_EXCLUDE_BUILD | ||
26 | bool "Exclude Staging drivers from being built" if STAGING | ||
27 | default y | ||
28 | ---help--- | ||
29 | Are you sure you really want to build the staging drivers? | ||
30 | They taint your kernel, don't live up to the normal Linux | ||
31 | kernel quality standards, are a bit crufty around the edges, | ||
32 | and might go off and kick your dog when you aren't paying | ||
33 | attention. | ||
34 | |||
35 | Say N here to be able to select and build the Staging drivers. | ||
36 | This option is primarily here to prevent them from being built | ||
37 | when selecting 'make allyesconfg' and 'make allmodconfig' so | ||
38 | don't be all that put off, your dog will be just fine. | ||
39 | |||
40 | if !STAGING_EXCLUDE_BUILD | ||
25 | 41 | ||
26 | source "drivers/staging/et131x/Kconfig" | 42 | source "drivers/staging/et131x/Kconfig" |
27 | 43 | ||
@@ -45,4 +61,4 @@ source "drivers/staging/at76_usb/Kconfig" | |||
45 | 61 | ||
46 | source "drivers/staging/poch/Kconfig" | 62 | source "drivers/staging/poch/Kconfig" |
47 | 63 | ||
48 | endif # STAGING | 64 | endif # !STAGING_EXCLUDE_BUILD |
diff --git a/drivers/staging/usbip/Kconfig b/drivers/staging/usbip/Kconfig index 7426235ccc44..217fb7e62c2f 100644 --- a/drivers/staging/usbip/Kconfig +++ b/drivers/staging/usbip/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config USB_IP_COMMON | 1 | config USB_IP_COMMON |
2 | tristate "USB IP support (EXPERIMENTAL)" | 2 | tristate "USB IP support (EXPERIMENTAL)" |
3 | depends on USB && EXPERIMENTAL | 3 | depends on USB && NET && EXPERIMENTAL |
4 | default N | 4 | default N |
5 | ---help--- | 5 | ---help--- |
6 | This enables pushing USB packets over IP to allow remote | 6 | This enables pushing USB packets over IP to allow remote |
diff --git a/drivers/telephony/phonedev.c b/drivers/telephony/phonedev.c index 37caf4d69037..b52cc830c0b4 100644 --- a/drivers/telephony/phonedev.c +++ b/drivers/telephony/phonedev.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * as published by the Free Software Foundation; either version | 8 | * as published by the Free Software Foundation; either version |
9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
10 | * | 10 | * |
11 | * Author: Alan Cox, <alan@redhat.com> | 11 | * Author: Alan Cox, <alan@lxorguk.ukuu.org.uk> |
12 | * | 12 | * |
13 | * Fixes: Mar 01 2000 Thomas Sparr, <thomas.l.sparr@telia.com> | 13 | * Fixes: Mar 01 2000 Thomas Sparr, <thomas.l.sparr@telia.com> |
14 | * phone_register_device now works with unit!=PHONE_UNIT_ANY | 14 | * phone_register_device now works with unit!=PHONE_UNIT_ANY |
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index b679a556b98d..4e2cda93da59 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c | |||
@@ -26,7 +26,7 @@ | |||
26 | * Introduced common header to be used also in USB Gadget Framework. | 26 | * Introduced common header to be used also in USB Gadget Framework. |
27 | * Still needs some other style fixes. | 27 | * Still needs some other style fixes. |
28 | * | 28 | * |
29 | * 2007_Jun_21 Alan Cox <alan@redhat.com> | 29 | * 2007_Jun_21 Alan Cox <alan@lxorguk.ukuu.org.uk> |
30 | * Minimal cleanups for some of the driver problens and tty layer abuse. | 30 | * Minimal cleanups for some of the driver problens and tty layer abuse. |
31 | * Still needs fixing to allow multiple dongles. | 31 | * Still needs fixing to allow multiple dongles. |
32 | * | 32 | * |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 0f13448c6f79..3f3ce13fef43 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -2083,6 +2083,38 @@ config FB_METRONOME | |||
2083 | controller. The pre-release name for this device was 8track | 2083 | controller. The pre-release name for this device was 8track |
2084 | and could also have been called by some vendors as PVI-nnnn. | 2084 | and could also have been called by some vendors as PVI-nnnn. |
2085 | 2085 | ||
2086 | config FB_MB862XX | ||
2087 | tristate "Fujitsu MB862xx GDC support" | ||
2088 | depends on FB | ||
2089 | select FB_CFB_FILLRECT | ||
2090 | select FB_CFB_COPYAREA | ||
2091 | select FB_CFB_IMAGEBLIT | ||
2092 | ---help--- | ||
2093 | Frame buffer driver for Fujitsu Carmine/Coral-P(A)/Lime controllers. | ||
2094 | |||
2095 | config FB_MB862XX_PCI_GDC | ||
2096 | bool "Carmine/Coral-P(A) GDC" | ||
2097 | depends on PCI && FB_MB862XX | ||
2098 | ---help--- | ||
2099 | This enables framebuffer support for Fujitsu Carmine/Coral-P(A) | ||
2100 | PCI graphics controller devices. | ||
2101 | |||
2102 | config FB_MB862XX_LIME | ||
2103 | bool "Lime GDC" | ||
2104 | depends on FB_MB862XX | ||
2105 | depends on OF && !FB_MB862XX_PCI_GDC | ||
2106 | select FB_FOREIGN_ENDIAN | ||
2107 | select FB_LITTLE_ENDIAN | ||
2108 | ---help--- | ||
2109 | Framebuffer support for Fujitsu Lime GDC on host CPU bus. | ||
2110 | |||
2111 | config FB_PRE_INIT_FB | ||
2112 | bool "Don't reinitialize, use bootloader's GDC/Display configuration" | ||
2113 | depends on FB_MB862XX_LIME | ||
2114 | ---help--- | ||
2115 | Select this option if display contents should be inherited as set by | ||
2116 | the bootloader. | ||
2117 | |||
2086 | source "drivers/video/omap/Kconfig" | 2118 | source "drivers/video/omap/Kconfig" |
2087 | 2119 | ||
2088 | source "drivers/video/backlight/Kconfig" | 2120 | source "drivers/video/backlight/Kconfig" |
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 248bddc8d0b0..e39e33e797da 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
@@ -122,6 +122,7 @@ obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o | |||
122 | obj-$(CONFIG_FB_OMAP) += omap/ | 122 | obj-$(CONFIG_FB_OMAP) += omap/ |
123 | obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o | 123 | obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o |
124 | obj-$(CONFIG_FB_CARMINE) += carminefb.o | 124 | obj-$(CONFIG_FB_CARMINE) += carminefb.o |
125 | obj-$(CONFIG_FB_MB862XX) += mb862xx/ | ||
125 | 126 | ||
126 | # Platform or fallback drivers go here | 127 | # Platform or fallback drivers go here |
127 | obj-$(CONFIG_FB_UVESA) += uvesafb.o | 128 | obj-$(CONFIG_FB_UVESA) += uvesafb.o |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 6048b55f2878..1d5ae39cb271 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -1002,13 +1002,9 @@ fb_blank(struct fb_info *info, int blank) | |||
1002 | return ret; | 1002 | return ret; |
1003 | } | 1003 | } |
1004 | 1004 | ||
1005 | static long | 1005 | static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, |
1006 | fb_ioctl(struct file *file, unsigned int cmd, | 1006 | unsigned long arg) |
1007 | unsigned long arg) | ||
1008 | { | 1007 | { |
1009 | struct inode *inode = file->f_path.dentry->d_inode; | ||
1010 | int fbidx = iminor(inode); | ||
1011 | struct fb_info *info; | ||
1012 | struct fb_ops *fb; | 1008 | struct fb_ops *fb; |
1013 | struct fb_var_screeninfo var; | 1009 | struct fb_var_screeninfo var; |
1014 | struct fb_fix_screeninfo fix; | 1010 | struct fb_fix_screeninfo fix; |
@@ -1018,14 +1014,10 @@ fb_ioctl(struct file *file, unsigned int cmd, | |||
1018 | void __user *argp = (void __user *)arg; | 1014 | void __user *argp = (void __user *)arg; |
1019 | long ret = 0; | 1015 | long ret = 0; |
1020 | 1016 | ||
1021 | info = registered_fb[fbidx]; | ||
1022 | mutex_lock(&info->lock); | ||
1023 | fb = info->fbops; | 1017 | fb = info->fbops; |
1024 | 1018 | if (!fb) | |
1025 | if (!fb) { | ||
1026 | mutex_unlock(&info->lock); | ||
1027 | return -ENODEV; | 1019 | return -ENODEV; |
1028 | } | 1020 | |
1029 | switch (cmd) { | 1021 | switch (cmd) { |
1030 | case FBIOGET_VSCREENINFO: | 1022 | case FBIOGET_VSCREENINFO: |
1031 | ret = copy_to_user(argp, &info->var, | 1023 | ret = copy_to_user(argp, &info->var, |
@@ -1126,6 +1118,21 @@ fb_ioctl(struct file *file, unsigned int cmd, | |||
1126 | else | 1118 | else |
1127 | ret = fb->fb_ioctl(info, cmd, arg); | 1119 | ret = fb->fb_ioctl(info, cmd, arg); |
1128 | } | 1120 | } |
1121 | return ret; | ||
1122 | } | ||
1123 | |||
1124 | static long fb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
1125 | __acquires(&info->lock) | ||
1126 | __releases(&info->lock) | ||
1127 | { | ||
1128 | struct inode *inode = file->f_path.dentry->d_inode; | ||
1129 | int fbidx = iminor(inode); | ||
1130 | struct fb_info *info; | ||
1131 | long ret; | ||
1132 | |||
1133 | info = registered_fb[fbidx]; | ||
1134 | mutex_lock(&info->lock); | ||
1135 | ret = do_fb_ioctl(info, cmd, arg); | ||
1129 | mutex_unlock(&info->lock); | 1136 | mutex_unlock(&info->lock); |
1130 | return ret; | 1137 | return ret; |
1131 | } | 1138 | } |
@@ -1157,8 +1164,8 @@ struct fb_cmap32 { | |||
1157 | compat_caddr_t transp; | 1164 | compat_caddr_t transp; |
1158 | }; | 1165 | }; |
1159 | 1166 | ||
1160 | static int fb_getput_cmap(struct inode *inode, struct file *file, | 1167 | static int fb_getput_cmap(struct fb_info *info, unsigned int cmd, |
1161 | unsigned int cmd, unsigned long arg) | 1168 | unsigned long arg) |
1162 | { | 1169 | { |
1163 | struct fb_cmap_user __user *cmap; | 1170 | struct fb_cmap_user __user *cmap; |
1164 | struct fb_cmap32 __user *cmap32; | 1171 | struct fb_cmap32 __user *cmap32; |
@@ -1181,7 +1188,7 @@ static int fb_getput_cmap(struct inode *inode, struct file *file, | |||
1181 | put_user(compat_ptr(data), &cmap->transp)) | 1188 | put_user(compat_ptr(data), &cmap->transp)) |
1182 | return -EFAULT; | 1189 | return -EFAULT; |
1183 | 1190 | ||
1184 | err = fb_ioctl(file, cmd, (unsigned long) cmap); | 1191 | err = do_fb_ioctl(info, cmd, (unsigned long) cmap); |
1185 | 1192 | ||
1186 | if (!err) { | 1193 | if (!err) { |
1187 | if (copy_in_user(&cmap32->start, | 1194 | if (copy_in_user(&cmap32->start, |
@@ -1223,8 +1230,8 @@ static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix, | |||
1223 | return err; | 1230 | return err; |
1224 | } | 1231 | } |
1225 | 1232 | ||
1226 | static int fb_get_fscreeninfo(struct inode *inode, struct file *file, | 1233 | static int fb_get_fscreeninfo(struct fb_info *info, unsigned int cmd, |
1227 | unsigned int cmd, unsigned long arg) | 1234 | unsigned long arg) |
1228 | { | 1235 | { |
1229 | mm_segment_t old_fs; | 1236 | mm_segment_t old_fs; |
1230 | struct fb_fix_screeninfo fix; | 1237 | struct fb_fix_screeninfo fix; |
@@ -1235,7 +1242,7 @@ static int fb_get_fscreeninfo(struct inode *inode, struct file *file, | |||
1235 | 1242 | ||
1236 | old_fs = get_fs(); | 1243 | old_fs = get_fs(); |
1237 | set_fs(KERNEL_DS); | 1244 | set_fs(KERNEL_DS); |
1238 | err = fb_ioctl(file, cmd, (unsigned long) &fix); | 1245 | err = do_fb_ioctl(info, cmd, (unsigned long) &fix); |
1239 | set_fs(old_fs); | 1246 | set_fs(old_fs); |
1240 | 1247 | ||
1241 | if (!err) | 1248 | if (!err) |
@@ -1244,8 +1251,10 @@ static int fb_get_fscreeninfo(struct inode *inode, struct file *file, | |||
1244 | return err; | 1251 | return err; |
1245 | } | 1252 | } |
1246 | 1253 | ||
1247 | static long | 1254 | static long fb_compat_ioctl(struct file *file, unsigned int cmd, |
1248 | fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 1255 | unsigned long arg) |
1256 | __acquires(&info->lock) | ||
1257 | __releases(&info->lock) | ||
1249 | { | 1258 | { |
1250 | struct inode *inode = file->f_path.dentry->d_inode; | 1259 | struct inode *inode = file->f_path.dentry->d_inode; |
1251 | int fbidx = iminor(inode); | 1260 | int fbidx = iminor(inode); |
@@ -1262,16 +1271,16 @@ fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1262 | case FBIOPUT_CON2FBMAP: | 1271 | case FBIOPUT_CON2FBMAP: |
1263 | arg = (unsigned long) compat_ptr(arg); | 1272 | arg = (unsigned long) compat_ptr(arg); |
1264 | case FBIOBLANK: | 1273 | case FBIOBLANK: |
1265 | mutex_unlock(&info->lock); | 1274 | ret = do_fb_ioctl(info, cmd, arg); |
1266 | return fb_ioctl(file, cmd, arg); | 1275 | break; |
1267 | 1276 | ||
1268 | case FBIOGET_FSCREENINFO: | 1277 | case FBIOGET_FSCREENINFO: |
1269 | ret = fb_get_fscreeninfo(inode, file, cmd, arg); | 1278 | ret = fb_get_fscreeninfo(info, cmd, arg); |
1270 | break; | 1279 | break; |
1271 | 1280 | ||
1272 | case FBIOGETCMAP: | 1281 | case FBIOGETCMAP: |
1273 | case FBIOPUTCMAP: | 1282 | case FBIOPUTCMAP: |
1274 | ret = fb_getput_cmap(inode, file, cmd, arg); | 1283 | ret = fb_getput_cmap(info, cmd, arg); |
1275 | break; | 1284 | break; |
1276 | 1285 | ||
1277 | default: | 1286 | default: |
@@ -1286,6 +1295,8 @@ fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1286 | 1295 | ||
1287 | static int | 1296 | static int |
1288 | fb_mmap(struct file *file, struct vm_area_struct * vma) | 1297 | fb_mmap(struct file *file, struct vm_area_struct * vma) |
1298 | __acquires(&info->lock) | ||
1299 | __releases(&info->lock) | ||
1289 | { | 1300 | { |
1290 | int fbidx = iminor(file->f_path.dentry->d_inode); | 1301 | int fbidx = iminor(file->f_path.dentry->d_inode); |
1291 | struct fb_info *info = registered_fb[fbidx]; | 1302 | struct fb_info *info = registered_fb[fbidx]; |
@@ -1339,6 +1350,8 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) | |||
1339 | 1350 | ||
1340 | static int | 1351 | static int |
1341 | fb_open(struct inode *inode, struct file *file) | 1352 | fb_open(struct inode *inode, struct file *file) |
1353 | __acquires(&info->lock) | ||
1354 | __releases(&info->lock) | ||
1342 | { | 1355 | { |
1343 | int fbidx = iminor(inode); | 1356 | int fbidx = iminor(inode); |
1344 | struct fb_info *info; | 1357 | struct fb_info *info; |
@@ -1374,6 +1387,8 @@ out: | |||
1374 | 1387 | ||
1375 | static int | 1388 | static int |
1376 | fb_release(struct inode *inode, struct file *file) | 1389 | fb_release(struct inode *inode, struct file *file) |
1390 | __acquires(&info->lock) | ||
1391 | __releases(&info->lock) | ||
1377 | { | 1392 | { |
1378 | struct fb_info * const info = file->private_data; | 1393 | struct fb_info * const info = file->private_data; |
1379 | 1394 | ||
diff --git a/drivers/video/mb862xx/Makefile b/drivers/video/mb862xx/Makefile new file mode 100644 index 000000000000..07664814bb1d --- /dev/null +++ b/drivers/video/mb862xx/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | # | ||
2 | # Makefile for the MB862xx framebuffer driver | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_FB_MB862XX) := mb862xxfb.o | ||
diff --git a/drivers/video/mb862xx/mb862xx_reg.h b/drivers/video/mb862xx/mb862xx_reg.h new file mode 100644 index 000000000000..2ba65e118500 --- /dev/null +++ b/drivers/video/mb862xx/mb862xx_reg.h | |||
@@ -0,0 +1,138 @@ | |||
1 | /* | ||
2 | * Fujitsu MB862xx Graphics Controller Registers/Bits | ||
3 | */ | ||
4 | |||
5 | #ifndef _MB862XX_REG_H | ||
6 | #define _MB862XX_REG_H | ||
7 | |||
8 | #ifdef MB862XX_MMIO_BOTTOM | ||
9 | #define MB862XX_MMIO_BASE 0x03fc0000 | ||
10 | #else | ||
11 | #define MB862XX_MMIO_BASE 0x01fc0000 | ||
12 | #endif | ||
13 | #define MB862XX_I2C_BASE 0x0000c000 | ||
14 | #define MB862XX_DISP_BASE 0x00010000 | ||
15 | #define MB862XX_CAP_BASE 0x00018000 | ||
16 | #define MB862XX_DRAW_BASE 0x00030000 | ||
17 | #define MB862XX_GEO_BASE 0x00038000 | ||
18 | #define MB862XX_PIO_BASE 0x00038000 | ||
19 | #define MB862XX_MMIO_SIZE 0x40000 | ||
20 | |||
21 | /* Host interface/pio registers */ | ||
22 | #define GC_IST 0x00000020 | ||
23 | #define GC_IMASK 0x00000024 | ||
24 | #define GC_SRST 0x0000002c | ||
25 | #define GC_CCF 0x00000038 | ||
26 | #define GC_CID 0x000000f0 | ||
27 | #define GC_REVISION 0x00000084 | ||
28 | |||
29 | #define GC_CCF_CGE_100 0x00000000 | ||
30 | #define GC_CCF_CGE_133 0x00040000 | ||
31 | #define GC_CCF_CGE_166 0x00080000 | ||
32 | #define GC_CCF_COT_100 0x00000000 | ||
33 | #define GC_CCF_COT_133 0x00010000 | ||
34 | #define GC_CID_CNAME_MSK 0x0000ff00 | ||
35 | #define GC_CID_VERSION_MSK 0x000000ff | ||
36 | |||
37 | /* define enabled interrupts hereby */ | ||
38 | #define GC_INT_EN 0x00000000 | ||
39 | |||
40 | /* Memory interface mode register */ | ||
41 | #define GC_MMR 0x0000fffc | ||
42 | |||
43 | /* Display Controller registers */ | ||
44 | #define GC_DCM0 0x00000000 | ||
45 | #define GC_HTP 0x00000004 | ||
46 | #define GC_HDB_HDP 0x00000008 | ||
47 | #define GC_VSW_HSW_HSP 0x0000000c | ||
48 | #define GC_VTR 0x00000010 | ||
49 | #define GC_VDP_VSP 0x00000014 | ||
50 | #define GC_WY_WX 0x00000018 | ||
51 | #define GC_WH_WW 0x0000001c | ||
52 | #define GC_L0M 0x00000020 | ||
53 | #define GC_L0OA0 0x00000024 | ||
54 | #define GC_L0DA0 0x00000028 | ||
55 | #define GC_L0DY_L0DX 0x0000002c | ||
56 | #define GC_DCM1 0x00000100 | ||
57 | #define GC_L0EM 0x00000110 | ||
58 | #define GC_L0WY_L0WX 0x00000114 | ||
59 | #define GC_L0WH_L0WW 0x00000118 | ||
60 | #define GC_DCM2 0x00000104 | ||
61 | #define GC_DCM3 0x00000108 | ||
62 | #define GC_CPM_CUTC 0x000000a0 | ||
63 | #define GC_CUOA0 0x000000a4 | ||
64 | #define GC_CUY0_CUX0 0x000000a8 | ||
65 | #define GC_CUOA1 0x000000ac | ||
66 | #define GC_CUY1_CUX1 0x000000b0 | ||
67 | #define GC_L0PAL0 0x00000400 | ||
68 | |||
69 | #define GC_CPM_CEN0 0x00100000 | ||
70 | #define GC_CPM_CEN1 0x00200000 | ||
71 | |||
72 | #define GC_DCM01_ESY 0x00000004 | ||
73 | #define GC_DCM01_SC 0x00003f00 | ||
74 | #define GC_DCM01_RESV 0x00004000 | ||
75 | #define GC_DCM01_CKS 0x00008000 | ||
76 | #define GC_DCM01_L0E 0x00010000 | ||
77 | #define GC_DCM01_DEN 0x80000000 | ||
78 | #define GC_L0M_L0C_8 0x00000000 | ||
79 | #define GC_L0M_L0C_16 0x80000000 | ||
80 | #define GC_L0EM_L0EC_24 0x40000000 | ||
81 | #define GC_L0M_L0W_UNIT 64 | ||
82 | |||
83 | #define GC_DISP_REFCLK_400 400 | ||
84 | |||
85 | /* Carmine specific */ | ||
86 | #define MB86297_DRAW_BASE 0x00020000 | ||
87 | #define MB86297_DISP0_BASE 0x00100000 | ||
88 | #define MB86297_DISP1_BASE 0x00140000 | ||
89 | #define MB86297_WRBACK_BASE 0x00180000 | ||
90 | #define MB86297_CAP0_BASE 0x00200000 | ||
91 | #define MB86297_CAP1_BASE 0x00280000 | ||
92 | #define MB86297_DRAMCTRL_BASE 0x00300000 | ||
93 | #define MB86297_CTRL_BASE 0x00400000 | ||
94 | #define MB86297_I2C_BASE 0x00500000 | ||
95 | |||
96 | #define GC_CTRL_STATUS 0x00000000 | ||
97 | #define GC_CTRL_INT_MASK 0x00000004 | ||
98 | #define GC_CTRL_CLK_ENABLE 0x0000000c | ||
99 | #define GC_CTRL_SOFT_RST 0x00000010 | ||
100 | |||
101 | #define GC_CTRL_CLK_EN_DRAM 0x00000001 | ||
102 | #define GC_CTRL_CLK_EN_2D3D 0x00000002 | ||
103 | #define GC_CTRL_CLK_EN_DISP0 0x00000020 | ||
104 | #define GC_CTRL_CLK_EN_DISP1 0x00000040 | ||
105 | |||
106 | #define GC_2D3D_REV 0x000004b4 | ||
107 | #define GC_RE_REVISION 0x24240200 | ||
108 | |||
109 | /* define enabled interrupts hereby */ | ||
110 | #define GC_CARMINE_INT_EN 0x00000004 | ||
111 | |||
112 | /* DRAM controller */ | ||
113 | #define GC_DCTL_MODE_ADD 0x00000000 | ||
114 | #define GC_DCTL_SETTIME1_EMODE 0x00000004 | ||
115 | #define GC_DCTL_REFRESH_SETTIME2 0x00000008 | ||
116 | #define GC_DCTL_RSV0_STATES 0x0000000C | ||
117 | #define GC_DCTL_RSV2_RSV1 0x00000010 | ||
118 | #define GC_DCTL_DDRIF2_DDRIF1 0x00000014 | ||
119 | #define GC_DCTL_IOCONT1_IOCONT0 0x00000024 | ||
120 | |||
121 | #define GC_DCTL_STATES_MSK 0x0000000f | ||
122 | #define GC_DCTL_INIT_WAIT_CNT 3000 | ||
123 | #define GC_DCTL_INIT_WAIT_INTERVAL 1 | ||
124 | |||
125 | /* DRAM ctrl values for Carmine PCI Eval. board */ | ||
126 | #define GC_EVB_DCTL_MODE_ADD 0x012105c3 | ||
127 | #define GC_EVB_DCTL_MODE_ADD_AFT_RST 0x002105c3 | ||
128 | #define GC_EVB_DCTL_SETTIME1_EMODE 0x47498000 | ||
129 | #define GC_EVB_DCTL_REFRESH_SETTIME2 0x00422a22 | ||
130 | #define GC_EVB_DCTL_RSV0_STATES 0x00200003 | ||
131 | #define GC_EVB_DCTL_RSV0_STATES_AFT_RST 0x00200002 | ||
132 | #define GC_EVB_DCTL_RSV2_RSV1 0x0000000f | ||
133 | #define GC_EVB_DCTL_DDRIF2_DDRIF1 0x00556646 | ||
134 | #define GC_EVB_DCTL_IOCONT1_IOCONT0 0x05550555 | ||
135 | |||
136 | #define GC_DISP_REFCLK_533 533 | ||
137 | |||
138 | #endif | ||
diff --git a/drivers/video/mb862xx/mb862xxfb.c b/drivers/video/mb862xx/mb862xxfb.c new file mode 100644 index 000000000000..38718d95fbb9 --- /dev/null +++ b/drivers/video/mb862xx/mb862xxfb.c | |||
@@ -0,0 +1,1061 @@ | |||
1 | /* | ||
2 | * drivers/mb862xx/mb862xxfb.c | ||
3 | * | ||
4 | * Fujitsu Carmine/Coral-P(A)/Lime framebuffer driver | ||
5 | * | ||
6 | * (C) 2008 Anatolij Gustschin <agust@denx.de> | ||
7 | * DENX Software Engineering | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #undef DEBUG | ||
16 | |||
17 | #include <linux/fb.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/pci.h> | ||
22 | #if defined(CONFIG_PPC_OF) | ||
23 | #include <linux/of_platform.h> | ||
24 | #endif | ||
25 | #include "mb862xxfb.h" | ||
26 | #include "mb862xx_reg.h" | ||
27 | |||
28 | #define NR_PALETTE 256 | ||
29 | #define MB862XX_MEM_SIZE 0x1000000 | ||
30 | #define CORALP_MEM_SIZE 0x4000000 | ||
31 | #define CARMINE_MEM_SIZE 0x8000000 | ||
32 | #define DRV_NAME "mb862xxfb" | ||
33 | |||
34 | #if defined(CONFIG_LWMON5) | ||
35 | static struct mb862xx_gc_mode lwmon5_gc_mode = { | ||
36 | /* Mode for Sharp LQ104V1DG61 TFT LCD Panel */ | ||
37 | { "640x480", 60, 640, 480, 40000, 48, 16, 32, 11, 96, 2, 0, 0, 0 }, | ||
38 | /* 16 bits/pixel, 32MB, 100MHz, SDRAM memory mode value */ | ||
39 | 16, 0x2000000, GC_CCF_COT_100, 0x414fb7f2 | ||
40 | }; | ||
41 | #endif | ||
42 | |||
43 | #if defined(CONFIG_SOCRATES) | ||
44 | static struct mb862xx_gc_mode socrates_gc_mode = { | ||
45 | /* Mode for Prime View PM070WL4 TFT LCD Panel */ | ||
46 | { "800x480", 45, 800, 480, 40000, 86, 42, 33, 10, 128, 2, 0, 0, 0 }, | ||
47 | /* 16 bits/pixel, 16MB, 133MHz, SDRAM memory mode value */ | ||
48 | 16, 0x1000000, GC_CCF_COT_133, 0x4157ba63 | ||
49 | }; | ||
50 | #endif | ||
51 | |||
52 | /* Helpers */ | ||
53 | static inline int h_total(struct fb_var_screeninfo *var) | ||
54 | { | ||
55 | return var->xres + var->left_margin + | ||
56 | var->right_margin + var->hsync_len; | ||
57 | } | ||
58 | |||
59 | static inline int v_total(struct fb_var_screeninfo *var) | ||
60 | { | ||
61 | return var->yres + var->upper_margin + | ||
62 | var->lower_margin + var->vsync_len; | ||
63 | } | ||
64 | |||
65 | static inline int hsp(struct fb_var_screeninfo *var) | ||
66 | { | ||
67 | return var->xres + var->right_margin - 1; | ||
68 | } | ||
69 | |||
70 | static inline int vsp(struct fb_var_screeninfo *var) | ||
71 | { | ||
72 | return var->yres + var->lower_margin - 1; | ||
73 | } | ||
74 | |||
75 | static inline int d_pitch(struct fb_var_screeninfo *var) | ||
76 | { | ||
77 | return var->xres * var->bits_per_pixel / 8; | ||
78 | } | ||
79 | |||
80 | static inline unsigned int chan_to_field(unsigned int chan, | ||
81 | struct fb_bitfield *bf) | ||
82 | { | ||
83 | chan &= 0xffff; | ||
84 | chan >>= 16 - bf->length; | ||
85 | return chan << bf->offset; | ||
86 | } | ||
87 | |||
88 | static int mb862xxfb_setcolreg(unsigned regno, | ||
89 | unsigned red, unsigned green, unsigned blue, | ||
90 | unsigned transp, struct fb_info *info) | ||
91 | { | ||
92 | struct mb862xxfb_par *par = info->par; | ||
93 | unsigned int val; | ||
94 | |||
95 | switch (info->fix.visual) { | ||
96 | case FB_VISUAL_TRUECOLOR: | ||
97 | if (regno < 16) { | ||
98 | val = chan_to_field(red, &info->var.red); | ||
99 | val |= chan_to_field(green, &info->var.green); | ||
100 | val |= chan_to_field(blue, &info->var.blue); | ||
101 | par->pseudo_palette[regno] = val; | ||
102 | } | ||
103 | break; | ||
104 | case FB_VISUAL_PSEUDOCOLOR: | ||
105 | if (regno < 256) { | ||
106 | val = (red >> 8) << 16; | ||
107 | val |= (green >> 8) << 8; | ||
108 | val |= blue >> 8; | ||
109 | outreg(disp, GC_L0PAL0 + (regno * 4), val); | ||
110 | } | ||
111 | break; | ||
112 | default: | ||
113 | return 1; /* unsupported type */ | ||
114 | } | ||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static int mb862xxfb_check_var(struct fb_var_screeninfo *var, | ||
119 | struct fb_info *fbi) | ||
120 | { | ||
121 | unsigned long tmp; | ||
122 | |||
123 | if (fbi->dev) | ||
124 | dev_dbg(fbi->dev, "%s\n", __func__); | ||
125 | |||
126 | /* check if these values fit into the registers */ | ||
127 | if (var->hsync_len > 255 || var->vsync_len > 255) | ||
128 | return -EINVAL; | ||
129 | |||
130 | if ((var->xres + var->right_margin) >= 4096) | ||
131 | return -EINVAL; | ||
132 | |||
133 | if ((var->yres + var->lower_margin) > 4096) | ||
134 | return -EINVAL; | ||
135 | |||
136 | if (h_total(var) > 4096 || v_total(var) > 4096) | ||
137 | return -EINVAL; | ||
138 | |||
139 | if (var->xres_virtual > 4096 || var->yres_virtual > 4096) | ||
140 | return -EINVAL; | ||
141 | |||
142 | if (var->bits_per_pixel <= 8) | ||
143 | var->bits_per_pixel = 8; | ||
144 | else if (var->bits_per_pixel <= 16) | ||
145 | var->bits_per_pixel = 16; | ||
146 | else if (var->bits_per_pixel <= 32) | ||
147 | var->bits_per_pixel = 32; | ||
148 | |||
149 | /* | ||
150 | * can cope with 8,16 or 24/32bpp if resulting | ||
151 | * pitch is divisible by 64 without remainder | ||
152 | */ | ||
153 | if (d_pitch(&fbi->var) % GC_L0M_L0W_UNIT) { | ||
154 | int r; | ||
155 | |||
156 | var->bits_per_pixel = 0; | ||
157 | do { | ||
158 | var->bits_per_pixel += 8; | ||
159 | r = d_pitch(&fbi->var) % GC_L0M_L0W_UNIT; | ||
160 | } while (r && var->bits_per_pixel <= 32); | ||
161 | |||
162 | if (d_pitch(&fbi->var) % GC_L0M_L0W_UNIT) | ||
163 | return -EINVAL; | ||
164 | } | ||
165 | |||
166 | /* line length is going to be 128 bit aligned */ | ||
167 | tmp = (var->xres * var->bits_per_pixel) / 8; | ||
168 | if ((tmp & 15) != 0) | ||
169 | return -EINVAL; | ||
170 | |||
171 | /* set r/g/b positions and validate bpp */ | ||
172 | switch (var->bits_per_pixel) { | ||
173 | case 8: | ||
174 | var->red.length = var->bits_per_pixel; | ||
175 | var->green.length = var->bits_per_pixel; | ||
176 | var->blue.length = var->bits_per_pixel; | ||
177 | var->red.offset = 0; | ||
178 | var->green.offset = 0; | ||
179 | var->blue.offset = 0; | ||
180 | var->transp.length = 0; | ||
181 | break; | ||
182 | case 16: | ||
183 | var->red.length = 5; | ||
184 | var->green.length = 5; | ||
185 | var->blue.length = 5; | ||
186 | var->red.offset = 10; | ||
187 | var->green.offset = 5; | ||
188 | var->blue.offset = 0; | ||
189 | var->transp.length = 0; | ||
190 | break; | ||
191 | case 24: | ||
192 | case 32: | ||
193 | var->transp.length = 8; | ||
194 | var->red.length = 8; | ||
195 | var->green.length = 8; | ||
196 | var->blue.length = 8; | ||
197 | var->transp.offset = 24; | ||
198 | var->red.offset = 16; | ||
199 | var->green.offset = 8; | ||
200 | var->blue.offset = 0; | ||
201 | break; | ||
202 | default: | ||
203 | return -EINVAL; | ||
204 | } | ||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | /* | ||
209 | * set display parameters | ||
210 | */ | ||
211 | static int mb862xxfb_set_par(struct fb_info *fbi) | ||
212 | { | ||
213 | struct mb862xxfb_par *par = fbi->par; | ||
214 | unsigned long reg, sc; | ||
215 | |||
216 | dev_dbg(par->dev, "%s\n", __func__); | ||
217 | |||
218 | if (par->pre_init) | ||
219 | return 0; | ||
220 | |||
221 | /* disp off */ | ||
222 | reg = inreg(disp, GC_DCM1); | ||
223 | reg &= ~GC_DCM01_DEN; | ||
224 | outreg(disp, GC_DCM1, reg); | ||
225 | |||
226 | /* set display reference clock div. */ | ||
227 | sc = par->refclk / (1000000 / fbi->var.pixclock) - 1; | ||
228 | reg = inreg(disp, GC_DCM1); | ||
229 | reg &= ~(GC_DCM01_CKS | GC_DCM01_RESV | GC_DCM01_SC); | ||
230 | reg |= sc << 8; | ||
231 | outreg(disp, GC_DCM1, reg); | ||
232 | dev_dbg(par->dev, "SC 0x%lx\n", sc); | ||
233 | |||
234 | /* disp dimension, format */ | ||
235 | reg = pack(d_pitch(&fbi->var) / GC_L0M_L0W_UNIT, | ||
236 | (fbi->var.yres - 1)); | ||
237 | if (fbi->var.bits_per_pixel == 16) | ||
238 | reg |= GC_L0M_L0C_16; | ||
239 | outreg(disp, GC_L0M, reg); | ||
240 | |||
241 | if (fbi->var.bits_per_pixel == 32) { | ||
242 | reg = inreg(disp, GC_L0EM); | ||
243 | outreg(disp, GC_L0EM, reg | GC_L0EM_L0EC_24); | ||
244 | } | ||
245 | outreg(disp, GC_WY_WX, 0); | ||
246 | reg = pack(fbi->var.yres - 1, fbi->var.xres); | ||
247 | outreg(disp, GC_WH_WW, reg); | ||
248 | outreg(disp, GC_L0OA0, 0); | ||
249 | outreg(disp, GC_L0DA0, 0); | ||
250 | outreg(disp, GC_L0DY_L0DX, 0); | ||
251 | outreg(disp, GC_L0WY_L0WX, 0); | ||
252 | outreg(disp, GC_L0WH_L0WW, reg); | ||
253 | |||
254 | /* both HW-cursors off */ | ||
255 | reg = inreg(disp, GC_CPM_CUTC); | ||
256 | reg &= ~(GC_CPM_CEN0 | GC_CPM_CEN1); | ||
257 | outreg(disp, GC_CPM_CUTC, reg); | ||
258 | |||
259 | /* timings */ | ||
260 | reg = pack(fbi->var.xres - 1, fbi->var.xres - 1); | ||
261 | outreg(disp, GC_HDB_HDP, reg); | ||
262 | reg = pack((fbi->var.yres - 1), vsp(&fbi->var)); | ||
263 | outreg(disp, GC_VDP_VSP, reg); | ||
264 | reg = ((fbi->var.vsync_len - 1) << 24) | | ||
265 | pack((fbi->var.hsync_len - 1), hsp(&fbi->var)); | ||
266 | outreg(disp, GC_VSW_HSW_HSP, reg); | ||
267 | outreg(disp, GC_HTP, pack(h_total(&fbi->var) - 1, 0)); | ||
268 | outreg(disp, GC_VTR, pack(v_total(&fbi->var) - 1, 0)); | ||
269 | |||
270 | /* display on */ | ||
271 | reg = inreg(disp, GC_DCM1); | ||
272 | reg |= GC_DCM01_DEN | GC_DCM01_L0E; | ||
273 | reg &= ~GC_DCM01_ESY; | ||
274 | outreg(disp, GC_DCM1, reg); | ||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | static int mb862xxfb_pan(struct fb_var_screeninfo *var, | ||
279 | struct fb_info *info) | ||
280 | { | ||
281 | struct mb862xxfb_par *par = info->par; | ||
282 | unsigned long reg; | ||
283 | |||
284 | reg = pack(var->yoffset, var->xoffset); | ||
285 | outreg(disp, GC_L0WY_L0WX, reg); | ||
286 | |||
287 | reg = pack(var->yres_virtual, var->xres_virtual); | ||
288 | outreg(disp, GC_L0WH_L0WW, reg); | ||
289 | return 0; | ||
290 | } | ||
291 | |||
292 | static int mb862xxfb_blank(int mode, struct fb_info *fbi) | ||
293 | { | ||
294 | struct mb862xxfb_par *par = fbi->par; | ||
295 | unsigned long reg; | ||
296 | |||
297 | dev_dbg(fbi->dev, "blank mode=%d\n", mode); | ||
298 | |||
299 | switch (mode) { | ||
300 | case FB_BLANK_POWERDOWN: | ||
301 | reg = inreg(disp, GC_DCM1); | ||
302 | reg &= ~GC_DCM01_DEN; | ||
303 | outreg(disp, GC_DCM1, reg); | ||
304 | break; | ||
305 | case FB_BLANK_UNBLANK: | ||
306 | reg = inreg(disp, GC_DCM1); | ||
307 | reg |= GC_DCM01_DEN; | ||
308 | outreg(disp, GC_DCM1, reg); | ||
309 | break; | ||
310 | case FB_BLANK_NORMAL: | ||
311 | case FB_BLANK_VSYNC_SUSPEND: | ||
312 | case FB_BLANK_HSYNC_SUSPEND: | ||
313 | default: | ||
314 | return 1; | ||
315 | } | ||
316 | return 0; | ||
317 | } | ||
318 | |||
319 | /* framebuffer ops */ | ||
320 | static struct fb_ops mb862xxfb_ops = { | ||
321 | .owner = THIS_MODULE, | ||
322 | .fb_check_var = mb862xxfb_check_var, | ||
323 | .fb_set_par = mb862xxfb_set_par, | ||
324 | .fb_setcolreg = mb862xxfb_setcolreg, | ||
325 | .fb_blank = mb862xxfb_blank, | ||
326 | .fb_pan_display = mb862xxfb_pan, | ||
327 | .fb_fillrect = cfb_fillrect, | ||
328 | .fb_copyarea = cfb_copyarea, | ||
329 | .fb_imageblit = cfb_imageblit, | ||
330 | }; | ||
331 | |||
332 | /* initialize fb_info data */ | ||
333 | static int mb862xxfb_init_fbinfo(struct fb_info *fbi) | ||
334 | { | ||
335 | struct mb862xxfb_par *par = fbi->par; | ||
336 | struct mb862xx_gc_mode *mode = par->gc_mode; | ||
337 | unsigned long reg; | ||
338 | |||
339 | fbi->fbops = &mb862xxfb_ops; | ||
340 | fbi->pseudo_palette = par->pseudo_palette; | ||
341 | fbi->screen_base = par->fb_base; | ||
342 | fbi->screen_size = par->mapped_vram; | ||
343 | |||
344 | strcpy(fbi->fix.id, DRV_NAME); | ||
345 | fbi->fix.smem_start = (unsigned long)par->fb_base_phys; | ||
346 | fbi->fix.smem_len = par->mapped_vram; | ||
347 | fbi->fix.mmio_start = (unsigned long)par->mmio_base_phys; | ||
348 | fbi->fix.mmio_len = par->mmio_len; | ||
349 | fbi->fix.accel = FB_ACCEL_NONE; | ||
350 | fbi->fix.type = FB_TYPE_PACKED_PIXELS; | ||
351 | fbi->fix.type_aux = 0; | ||
352 | fbi->fix.xpanstep = 1; | ||
353 | fbi->fix.ypanstep = 1; | ||
354 | fbi->fix.ywrapstep = 0; | ||
355 | |||
356 | reg = inreg(disp, GC_DCM1); | ||
357 | if (reg & GC_DCM01_DEN && reg & GC_DCM01_L0E) { | ||
358 | /* get the disp mode from active display cfg */ | ||
359 | unsigned long sc = ((reg & GC_DCM01_SC) >> 8) + 1; | ||
360 | unsigned long hsp, vsp, ht, vt; | ||
361 | |||
362 | dev_dbg(par->dev, "using bootloader's disp. mode\n"); | ||
363 | fbi->var.pixclock = (sc * 1000000) / par->refclk; | ||
364 | fbi->var.xres = (inreg(disp, GC_HDB_HDP) & 0x0fff) + 1; | ||
365 | reg = inreg(disp, GC_VDP_VSP); | ||
366 | fbi->var.yres = ((reg >> 16) & 0x0fff) + 1; | ||
367 | vsp = (reg & 0x0fff) + 1; | ||
368 | fbi->var.xres_virtual = fbi->var.xres; | ||
369 | fbi->var.yres_virtual = fbi->var.yres; | ||
370 | reg = inreg(disp, GC_L0EM); | ||
371 | if (reg & GC_L0EM_L0EC_24) { | ||
372 | fbi->var.bits_per_pixel = 32; | ||
373 | } else { | ||
374 | reg = inreg(disp, GC_L0M); | ||
375 | if (reg & GC_L0M_L0C_16) | ||
376 | fbi->var.bits_per_pixel = 16; | ||
377 | else | ||
378 | fbi->var.bits_per_pixel = 8; | ||
379 | } | ||
380 | reg = inreg(disp, GC_VSW_HSW_HSP); | ||
381 | fbi->var.hsync_len = ((reg & 0xff0000) >> 16) + 1; | ||
382 | fbi->var.vsync_len = ((reg & 0x3f000000) >> 24) + 1; | ||
383 | hsp = (reg & 0xffff) + 1; | ||
384 | ht = ((inreg(disp, GC_HTP) & 0xfff0000) >> 16) + 1; | ||
385 | fbi->var.right_margin = hsp - fbi->var.xres; | ||
386 | fbi->var.left_margin = ht - hsp - fbi->var.hsync_len; | ||
387 | vt = ((inreg(disp, GC_VTR) & 0xfff0000) >> 16) + 1; | ||
388 | fbi->var.lower_margin = vsp - fbi->var.yres; | ||
389 | fbi->var.upper_margin = vt - vsp - fbi->var.vsync_len; | ||
390 | } else if (mode) { | ||
391 | dev_dbg(par->dev, "using supplied mode\n"); | ||
392 | fb_videomode_to_var(&fbi->var, (struct fb_videomode *)mode); | ||
393 | fbi->var.bits_per_pixel = mode->def_bpp ? mode->def_bpp : 8; | ||
394 | } else { | ||
395 | int ret; | ||
396 | |||
397 | ret = fb_find_mode(&fbi->var, fbi, "640x480-16@60", | ||
398 | NULL, 0, NULL, 16); | ||
399 | if (ret == 0 || ret == 4) { | ||
400 | dev_err(par->dev, | ||
401 | "failed to get initial mode\n"); | ||
402 | return -EINVAL; | ||
403 | } | ||
404 | } | ||
405 | |||
406 | fbi->var.xoffset = 0; | ||
407 | fbi->var.yoffset = 0; | ||
408 | fbi->var.grayscale = 0; | ||
409 | fbi->var.nonstd = 0; | ||
410 | fbi->var.height = -1; | ||
411 | fbi->var.width = -1; | ||
412 | fbi->var.accel_flags = 0; | ||
413 | fbi->var.vmode = FB_VMODE_NONINTERLACED; | ||
414 | fbi->var.activate = FB_ACTIVATE_NOW; | ||
415 | fbi->flags = FBINFO_DEFAULT | | ||
416 | #ifdef __BIG_ENDIAN | ||
417 | FBINFO_FOREIGN_ENDIAN | | ||
418 | #endif | ||
419 | FBINFO_HWACCEL_XPAN | | ||
420 | FBINFO_HWACCEL_YPAN; | ||
421 | |||
422 | /* check and possibly fix bpp */ | ||
423 | if ((fbi->fbops->fb_check_var)(&fbi->var, fbi)) | ||
424 | dev_err(par->dev, "check_var() failed on initial setup?\n"); | ||
425 | |||
426 | fbi->fix.visual = fbi->var.bits_per_pixel == 8 ? | ||
427 | FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; | ||
428 | fbi->fix.line_length = (fbi->var.xres_virtual * | ||
429 | fbi->var.bits_per_pixel) / 8; | ||
430 | return 0; | ||
431 | } | ||
432 | |||
433 | /* | ||
434 | * show some display controller and cursor registers | ||
435 | */ | ||
436 | static ssize_t mb862xxfb_show_dispregs(struct device *dev, | ||
437 | struct device_attribute *attr, char *buf) | ||
438 | { | ||
439 | struct fb_info *fbi = dev_get_drvdata(dev); | ||
440 | struct mb862xxfb_par *par = fbi->par; | ||
441 | char *ptr = buf; | ||
442 | unsigned int reg; | ||
443 | |||
444 | for (reg = GC_DCM0; reg <= GC_L0DY_L0DX; reg += 4) | ||
445 | ptr += sprintf(ptr, "%08x = %08x\n", | ||
446 | reg, inreg(disp, reg)); | ||
447 | |||
448 | for (reg = GC_CPM_CUTC; reg <= GC_CUY1_CUX1; reg += 4) | ||
449 | ptr += sprintf(ptr, "%08x = %08x\n", | ||
450 | reg, inreg(disp, reg)); | ||
451 | |||
452 | for (reg = GC_DCM1; reg <= GC_L0WH_L0WW; reg += 4) | ||
453 | ptr += sprintf(ptr, "%08x = %08x\n", | ||
454 | reg, inreg(disp, reg)); | ||
455 | |||
456 | return ptr - buf; | ||
457 | } | ||
458 | |||
459 | static DEVICE_ATTR(dispregs, 0444, mb862xxfb_show_dispregs, NULL); | ||
460 | |||
461 | irqreturn_t mb862xx_intr(int irq, void *dev_id) | ||
462 | { | ||
463 | struct mb862xxfb_par *par = (struct mb862xxfb_par *) dev_id; | ||
464 | unsigned long reg_ist, mask; | ||
465 | |||
466 | if (!par) | ||
467 | return IRQ_NONE; | ||
468 | |||
469 | if (par->type == BT_CARMINE) { | ||
470 | /* Get Interrupt Status */ | ||
471 | reg_ist = inreg(ctrl, GC_CTRL_STATUS); | ||
472 | mask = inreg(ctrl, GC_CTRL_INT_MASK); | ||
473 | if (reg_ist == 0) | ||
474 | return IRQ_HANDLED; | ||
475 | |||
476 | reg_ist &= mask; | ||
477 | if (reg_ist == 0) | ||
478 | return IRQ_HANDLED; | ||
479 | |||
480 | /* Clear interrupt status */ | ||
481 | outreg(ctrl, 0x0, reg_ist); | ||
482 | } else { | ||
483 | /* Get status */ | ||
484 | reg_ist = inreg(host, GC_IST); | ||
485 | mask = inreg(host, GC_IMASK); | ||
486 | |||
487 | reg_ist &= mask; | ||
488 | if (reg_ist == 0) | ||
489 | return IRQ_HANDLED; | ||
490 | |||
491 | /* Clear status */ | ||
492 | outreg(host, GC_IST, ~reg_ist); | ||
493 | } | ||
494 | return IRQ_HANDLED; | ||
495 | } | ||
496 | |||
497 | #if defined(CONFIG_FB_MB862XX_LIME) | ||
498 | /* | ||
499 | * GDC (Lime, Coral(B/Q), Mint, ...) on host bus | ||
500 | */ | ||
501 | static int mb862xx_gdc_init(struct mb862xxfb_par *par) | ||
502 | { | ||
503 | unsigned long ccf, mmr; | ||
504 | unsigned long ver, rev; | ||
505 | |||
506 | if (!par) | ||
507 | return -ENODEV; | ||
508 | |||
509 | #if defined(CONFIG_FB_PRE_INIT_FB) | ||
510 | par->pre_init = 1; | ||
511 | #endif | ||
512 | par->host = par->mmio_base; | ||
513 | par->i2c = par->mmio_base + MB862XX_I2C_BASE; | ||
514 | par->disp = par->mmio_base + MB862XX_DISP_BASE; | ||
515 | par->cap = par->mmio_base + MB862XX_CAP_BASE; | ||
516 | par->draw = par->mmio_base + MB862XX_DRAW_BASE; | ||
517 | par->geo = par->mmio_base + MB862XX_GEO_BASE; | ||
518 | par->pio = par->mmio_base + MB862XX_PIO_BASE; | ||
519 | |||
520 | par->refclk = GC_DISP_REFCLK_400; | ||
521 | |||
522 | ver = inreg(host, GC_CID); | ||
523 | rev = inreg(pio, GC_REVISION); | ||
524 | if ((ver == 0x303) && (rev & 0xffffff00) == 0x20050100) { | ||
525 | dev_info(par->dev, "Fujitsu Lime v1.%d found\n", | ||
526 | (int)rev & 0xff); | ||
527 | par->type = BT_LIME; | ||
528 | ccf = par->gc_mode ? par->gc_mode->ccf : GC_CCF_COT_100; | ||
529 | mmr = par->gc_mode ? par->gc_mode->mmr : 0x414fb7f2; | ||
530 | } else { | ||
531 | dev_info(par->dev, "? GDC, CID/Rev.: 0x%lx/0x%lx \n", ver, rev); | ||
532 | return -ENODEV; | ||
533 | } | ||
534 | |||
535 | if (!par->pre_init) { | ||
536 | outreg(host, GC_CCF, ccf); | ||
537 | udelay(200); | ||
538 | outreg(host, GC_MMR, mmr); | ||
539 | udelay(10); | ||
540 | } | ||
541 | |||
542 | /* interrupt status */ | ||
543 | outreg(host, GC_IST, 0); | ||
544 | outreg(host, GC_IMASK, GC_INT_EN); | ||
545 | return 0; | ||
546 | } | ||
547 | |||
548 | static int __devinit of_platform_mb862xx_probe(struct of_device *ofdev, | ||
549 | const struct of_device_id *id) | ||
550 | { | ||
551 | struct device_node *np = ofdev->node; | ||
552 | struct device *dev = &ofdev->dev; | ||
553 | struct mb862xxfb_par *par; | ||
554 | struct fb_info *info; | ||
555 | struct resource res; | ||
556 | resource_size_t res_size; | ||
557 | unsigned long ret = -ENODEV; | ||
558 | |||
559 | if (of_address_to_resource(np, 0, &res)) { | ||
560 | dev_err(dev, "Invalid address\n"); | ||
561 | return -ENXIO; | ||
562 | } | ||
563 | |||
564 | info = framebuffer_alloc(sizeof(struct mb862xxfb_par), dev); | ||
565 | if (info == NULL) { | ||
566 | dev_err(dev, "cannot allocate framebuffer\n"); | ||
567 | return -ENOMEM; | ||
568 | } | ||
569 | |||
570 | par = info->par; | ||
571 | par->info = info; | ||
572 | par->dev = dev; | ||
573 | |||
574 | par->irq = irq_of_parse_and_map(np, 0); | ||
575 | if (par->irq == NO_IRQ) { | ||
576 | dev_err(dev, "failed to map irq\n"); | ||
577 | ret = -ENODEV; | ||
578 | goto fbrel; | ||
579 | } | ||
580 | |||
581 | res_size = 1 + res.end - res.start; | ||
582 | par->res = request_mem_region(res.start, res_size, DRV_NAME); | ||
583 | if (par->res == NULL) { | ||
584 | dev_err(dev, "Cannot claim framebuffer/mmio\n"); | ||
585 | ret = -ENXIO; | ||
586 | goto irqdisp; | ||
587 | } | ||
588 | |||
589 | #if defined(CONFIG_LWMON5) | ||
590 | par->gc_mode = &lwmon5_gc_mode; | ||
591 | #endif | ||
592 | |||
593 | #if defined(CONFIG_SOCRATES) | ||
594 | par->gc_mode = &socrates_gc_mode; | ||
595 | #endif | ||
596 | |||
597 | par->fb_base_phys = res.start; | ||
598 | par->mmio_base_phys = res.start + MB862XX_MMIO_BASE; | ||
599 | par->mmio_len = MB862XX_MMIO_SIZE; | ||
600 | if (par->gc_mode) | ||
601 | par->mapped_vram = par->gc_mode->max_vram; | ||
602 | else | ||
603 | par->mapped_vram = MB862XX_MEM_SIZE; | ||
604 | |||
605 | par->fb_base = ioremap(par->fb_base_phys, par->mapped_vram); | ||
606 | if (par->fb_base == NULL) { | ||
607 | dev_err(dev, "Cannot map framebuffer\n"); | ||
608 | goto rel_reg; | ||
609 | } | ||
610 | |||
611 | par->mmio_base = ioremap(par->mmio_base_phys, par->mmio_len); | ||
612 | if (par->mmio_base == NULL) { | ||
613 | dev_err(dev, "Cannot map registers\n"); | ||
614 | goto fb_unmap; | ||
615 | } | ||
616 | |||
617 | dev_dbg(dev, "fb phys 0x%llx 0x%lx\n", | ||
618 | (u64)par->fb_base_phys, (ulong)par->mapped_vram); | ||
619 | dev_dbg(dev, "mmio phys 0x%llx 0x%lx, (irq = %d)\n", | ||
620 | (u64)par->mmio_base_phys, (ulong)par->mmio_len, par->irq); | ||
621 | |||
622 | if (mb862xx_gdc_init(par)) | ||
623 | goto io_unmap; | ||
624 | |||
625 | if (request_irq(par->irq, mb862xx_intr, IRQF_DISABLED, | ||
626 | DRV_NAME, (void *)par)) { | ||
627 | dev_err(dev, "Cannot request irq\n"); | ||
628 | goto io_unmap; | ||
629 | } | ||
630 | |||
631 | mb862xxfb_init_fbinfo(info); | ||
632 | |||
633 | if (fb_alloc_cmap(&info->cmap, NR_PALETTE, 0) < 0) { | ||
634 | dev_err(dev, "Could not allocate cmap for fb_info.\n"); | ||
635 | goto free_irq; | ||
636 | } | ||
637 | |||
638 | if ((info->fbops->fb_set_par)(info)) | ||
639 | dev_err(dev, "set_var() failed on initial setup?\n"); | ||
640 | |||
641 | if (register_framebuffer(info)) { | ||
642 | dev_err(dev, "failed to register framebuffer\n"); | ||
643 | goto rel_cmap; | ||
644 | } | ||
645 | |||
646 | dev_set_drvdata(dev, info); | ||
647 | |||
648 | if (device_create_file(dev, &dev_attr_dispregs)) | ||
649 | dev_err(dev, "Can't create sysfs regdump file\n"); | ||
650 | return 0; | ||
651 | |||
652 | rel_cmap: | ||
653 | fb_dealloc_cmap(&info->cmap); | ||
654 | free_irq: | ||
655 | outreg(host, GC_IMASK, 0); | ||
656 | free_irq(par->irq, (void *)par); | ||
657 | io_unmap: | ||
658 | iounmap(par->mmio_base); | ||
659 | fb_unmap: | ||
660 | iounmap(par->fb_base); | ||
661 | rel_reg: | ||
662 | release_mem_region(res.start, res_size); | ||
663 | irqdisp: | ||
664 | irq_dispose_mapping(par->irq); | ||
665 | fbrel: | ||
666 | dev_set_drvdata(dev, NULL); | ||
667 | framebuffer_release(info); | ||
668 | return ret; | ||
669 | } | ||
670 | |||
671 | static int __devexit of_platform_mb862xx_remove(struct of_device *ofdev) | ||
672 | { | ||
673 | struct fb_info *fbi = dev_get_drvdata(&ofdev->dev); | ||
674 | struct mb862xxfb_par *par = fbi->par; | ||
675 | resource_size_t res_size = 1 + par->res->end - par->res->start; | ||
676 | unsigned long reg; | ||
677 | |||
678 | dev_dbg(fbi->dev, "%s release\n", fbi->fix.id); | ||
679 | |||
680 | /* display off */ | ||
681 | reg = inreg(disp, GC_DCM1); | ||
682 | reg &= ~(GC_DCM01_DEN | GC_DCM01_L0E); | ||
683 | outreg(disp, GC_DCM1, reg); | ||
684 | |||
685 | /* disable interrupts */ | ||
686 | outreg(host, GC_IMASK, 0); | ||
687 | |||
688 | free_irq(par->irq, (void *)par); | ||
689 | irq_dispose_mapping(par->irq); | ||
690 | |||
691 | device_remove_file(&ofdev->dev, &dev_attr_dispregs); | ||
692 | |||
693 | unregister_framebuffer(fbi); | ||
694 | fb_dealloc_cmap(&fbi->cmap); | ||
695 | |||
696 | iounmap(par->mmio_base); | ||
697 | iounmap(par->fb_base); | ||
698 | |||
699 | dev_set_drvdata(&ofdev->dev, NULL); | ||
700 | release_mem_region(par->res->start, res_size); | ||
701 | framebuffer_release(fbi); | ||
702 | return 0; | ||
703 | } | ||
704 | |||
705 | /* | ||
706 | * common types | ||
707 | */ | ||
708 | static struct of_device_id __devinitdata of_platform_mb862xx_tbl[] = { | ||
709 | { .compatible = "fujitsu,MB86276", }, | ||
710 | { .compatible = "fujitsu,lime", }, | ||
711 | { .compatible = "fujitsu,MB86277", }, | ||
712 | { .compatible = "fujitsu,mint", }, | ||
713 | { .compatible = "fujitsu,MB86293", }, | ||
714 | { .compatible = "fujitsu,MB86294", }, | ||
715 | { .compatible = "fujitsu,coral", }, | ||
716 | { /* end */ } | ||
717 | }; | ||
718 | |||
719 | static struct of_platform_driver of_platform_mb862xxfb_driver = { | ||
720 | .owner = THIS_MODULE, | ||
721 | .name = DRV_NAME, | ||
722 | .match_table = of_platform_mb862xx_tbl, | ||
723 | .probe = of_platform_mb862xx_probe, | ||
724 | .remove = __devexit_p(of_platform_mb862xx_remove), | ||
725 | }; | ||
726 | #endif | ||
727 | |||
728 | #if defined(CONFIG_FB_MB862XX_PCI_GDC) | ||
729 | static int coralp_init(struct mb862xxfb_par *par) | ||
730 | { | ||
731 | int cn, ver; | ||
732 | |||
733 | par->host = par->mmio_base; | ||
734 | par->i2c = par->mmio_base + MB862XX_I2C_BASE; | ||
735 | par->disp = par->mmio_base + MB862XX_DISP_BASE; | ||
736 | par->cap = par->mmio_base + MB862XX_CAP_BASE; | ||
737 | par->draw = par->mmio_base + MB862XX_DRAW_BASE; | ||
738 | par->geo = par->mmio_base + MB862XX_GEO_BASE; | ||
739 | par->pio = par->mmio_base + MB862XX_PIO_BASE; | ||
740 | |||
741 | par->refclk = GC_DISP_REFCLK_400; | ||
742 | |||
743 | ver = inreg(host, GC_CID); | ||
744 | cn = (ver & GC_CID_CNAME_MSK) >> 8; | ||
745 | ver = ver & GC_CID_VERSION_MSK; | ||
746 | if (cn == 3) { | ||
747 | dev_info(par->dev, "Fujitsu Coral-%s GDC Rev.%d found\n",\ | ||
748 | (ver == 6) ? "P" : (ver == 8) ? "PA" : "?", | ||
749 | par->pdev->revision); | ||
750 | outreg(host, GC_CCF, GC_CCF_CGE_166 | GC_CCF_COT_133); | ||
751 | udelay(200); | ||
752 | outreg(host, GC_MMR, GC_MMR_CORALP_EVB_VAL); | ||
753 | udelay(10); | ||
754 | /* Clear interrupt status */ | ||
755 | outreg(host, GC_IST, 0); | ||
756 | } else { | ||
757 | return -ENODEV; | ||
758 | } | ||
759 | return 0; | ||
760 | } | ||
761 | |||
762 | static int init_dram_ctrl(struct mb862xxfb_par *par) | ||
763 | { | ||
764 | unsigned long i = 0; | ||
765 | |||
766 | /* | ||
767 | * Set io mode first! Spec. says IC may be destroyed | ||
768 | * if not set to SSTL2/LVCMOS before init. | ||
769 | */ | ||
770 | outreg(dram_ctrl, GC_DCTL_IOCONT1_IOCONT0, GC_EVB_DCTL_IOCONT1_IOCONT0); | ||
771 | |||
772 | /* DRAM init */ | ||
773 | outreg(dram_ctrl, GC_DCTL_MODE_ADD, GC_EVB_DCTL_MODE_ADD); | ||
774 | outreg(dram_ctrl, GC_DCTL_SETTIME1_EMODE, GC_EVB_DCTL_SETTIME1_EMODE); | ||
775 | outreg(dram_ctrl, GC_DCTL_REFRESH_SETTIME2, | ||
776 | GC_EVB_DCTL_REFRESH_SETTIME2); | ||
777 | outreg(dram_ctrl, GC_DCTL_RSV2_RSV1, GC_EVB_DCTL_RSV2_RSV1); | ||
778 | outreg(dram_ctrl, GC_DCTL_DDRIF2_DDRIF1, GC_EVB_DCTL_DDRIF2_DDRIF1); | ||
779 | outreg(dram_ctrl, GC_DCTL_RSV0_STATES, GC_EVB_DCTL_RSV0_STATES); | ||
780 | |||
781 | /* DLL reset done? */ | ||
782 | while ((inreg(dram_ctrl, GC_DCTL_RSV0_STATES) & GC_DCTL_STATES_MSK)) { | ||
783 | udelay(GC_DCTL_INIT_WAIT_INTERVAL); | ||
784 | if (i++ > GC_DCTL_INIT_WAIT_CNT) { | ||
785 | dev_err(par->dev, "VRAM init failed.\n"); | ||
786 | return -EINVAL; | ||
787 | } | ||
788 | } | ||
789 | outreg(dram_ctrl, GC_DCTL_MODE_ADD, GC_EVB_DCTL_MODE_ADD_AFT_RST); | ||
790 | outreg(dram_ctrl, GC_DCTL_RSV0_STATES, GC_EVB_DCTL_RSV0_STATES_AFT_RST); | ||
791 | return 0; | ||
792 | } | ||
793 | |||
794 | static int carmine_init(struct mb862xxfb_par *par) | ||
795 | { | ||
796 | unsigned long reg; | ||
797 | |||
798 | par->ctrl = par->mmio_base + MB86297_CTRL_BASE; | ||
799 | par->i2c = par->mmio_base + MB86297_I2C_BASE; | ||
800 | par->disp = par->mmio_base + MB86297_DISP0_BASE; | ||
801 | par->disp1 = par->mmio_base + MB86297_DISP1_BASE; | ||
802 | par->cap = par->mmio_base + MB86297_CAP0_BASE; | ||
803 | par->cap1 = par->mmio_base + MB86297_CAP1_BASE; | ||
804 | par->draw = par->mmio_base + MB86297_DRAW_BASE; | ||
805 | par->dram_ctrl = par->mmio_base + MB86297_DRAMCTRL_BASE; | ||
806 | par->wrback = par->mmio_base + MB86297_WRBACK_BASE; | ||
807 | |||
808 | par->refclk = GC_DISP_REFCLK_533; | ||
809 | |||
810 | /* warm up */ | ||
811 | reg = GC_CTRL_CLK_EN_DRAM | GC_CTRL_CLK_EN_2D3D | GC_CTRL_CLK_EN_DISP0; | ||
812 | outreg(ctrl, GC_CTRL_CLK_ENABLE, reg); | ||
813 | |||
814 | /* check for engine module revision */ | ||
815 | if (inreg(draw, GC_2D3D_REV) == GC_RE_REVISION) | ||
816 | dev_info(par->dev, "Fujitsu Carmine GDC Rev.%d found\n", | ||
817 | par->pdev->revision); | ||
818 | else | ||
819 | goto err_init; | ||
820 | |||
821 | reg &= ~GC_CTRL_CLK_EN_2D3D; | ||
822 | outreg(ctrl, GC_CTRL_CLK_ENABLE, reg); | ||
823 | |||
824 | /* set up vram */ | ||
825 | if (init_dram_ctrl(par) < 0) | ||
826 | goto err_init; | ||
827 | |||
828 | outreg(ctrl, GC_CTRL_INT_MASK, 0); | ||
829 | return 0; | ||
830 | |||
831 | err_init: | ||
832 | outreg(ctrl, GC_CTRL_CLK_ENABLE, 0); | ||
833 | return -EINVAL; | ||
834 | } | ||
835 | |||
836 | static inline int mb862xx_pci_gdc_init(struct mb862xxfb_par *par) | ||
837 | { | ||
838 | switch (par->type) { | ||
839 | case BT_CORALP: | ||
840 | return coralp_init(par); | ||
841 | case BT_CARMINE: | ||
842 | return carmine_init(par); | ||
843 | default: | ||
844 | return -ENODEV; | ||
845 | } | ||
846 | } | ||
847 | |||
848 | #define CHIP_ID(id) \ | ||
849 | { PCI_DEVICE(PCI_VENDOR_ID_FUJITSU_LIMITED, id) } | ||
850 | |||
851 | static struct pci_device_id mb862xx_pci_tbl[] __devinitdata = { | ||
852 | /* MB86295/MB86296 */ | ||
853 | CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALP), | ||
854 | CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALPA), | ||
855 | /* MB86297 */ | ||
856 | CHIP_ID(PCI_DEVICE_ID_FUJITSU_CARMINE), | ||
857 | { 0, } | ||
858 | }; | ||
859 | |||
860 | MODULE_DEVICE_TABLE(pci, mb862xx_pci_tbl); | ||
861 | |||
862 | static int __devinit mb862xx_pci_probe(struct pci_dev *pdev, | ||
863 | const struct pci_device_id *ent) | ||
864 | { | ||
865 | struct mb862xxfb_par *par; | ||
866 | struct fb_info *info; | ||
867 | struct device *dev = &pdev->dev; | ||
868 | int ret; | ||
869 | |||
870 | ret = pci_enable_device(pdev); | ||
871 | if (ret < 0) { | ||
872 | dev_err(dev, "Cannot enable PCI device\n"); | ||
873 | goto out; | ||
874 | } | ||
875 | |||
876 | info = framebuffer_alloc(sizeof(struct mb862xxfb_par), dev); | ||
877 | if (!info) { | ||
878 | dev_err(dev, "framebuffer alloc failed\n"); | ||
879 | ret = -ENOMEM; | ||
880 | goto dis_dev; | ||
881 | } | ||
882 | |||
883 | par = info->par; | ||
884 | par->info = info; | ||
885 | par->dev = dev; | ||
886 | par->pdev = pdev; | ||
887 | par->irq = pdev->irq; | ||
888 | |||
889 | ret = pci_request_regions(pdev, DRV_NAME); | ||
890 | if (ret < 0) { | ||
891 | dev_err(dev, "Cannot reserve region(s) for PCI device\n"); | ||
892 | goto rel_fb; | ||
893 | } | ||
894 | |||
895 | switch (pdev->device) { | ||
896 | case PCI_DEVICE_ID_FUJITSU_CORALP: | ||
897 | case PCI_DEVICE_ID_FUJITSU_CORALPA: | ||
898 | par->fb_base_phys = pci_resource_start(par->pdev, 0); | ||
899 | par->mapped_vram = CORALP_MEM_SIZE; | ||
900 | par->mmio_base_phys = par->fb_base_phys + MB862XX_MMIO_BASE; | ||
901 | par->mmio_len = MB862XX_MMIO_SIZE; | ||
902 | par->type = BT_CORALP; | ||
903 | break; | ||
904 | case PCI_DEVICE_ID_FUJITSU_CARMINE: | ||
905 | par->fb_base_phys = pci_resource_start(par->pdev, 2); | ||
906 | par->mmio_base_phys = pci_resource_start(par->pdev, 3); | ||
907 | par->mmio_len = pci_resource_len(par->pdev, 3); | ||
908 | par->mapped_vram = CARMINE_MEM_SIZE; | ||
909 | par->type = BT_CARMINE; | ||
910 | break; | ||
911 | default: | ||
912 | /* should never occur */ | ||
913 | goto rel_reg; | ||
914 | } | ||
915 | |||
916 | par->fb_base = ioremap(par->fb_base_phys, par->mapped_vram); | ||
917 | if (par->fb_base == NULL) { | ||
918 | dev_err(dev, "Cannot map framebuffer\n"); | ||
919 | goto rel_reg; | ||
920 | } | ||
921 | |||
922 | par->mmio_base = ioremap(par->mmio_base_phys, par->mmio_len); | ||
923 | if (par->mmio_base == NULL) { | ||
924 | dev_err(dev, "Cannot map registers\n"); | ||
925 | ret = -EIO; | ||
926 | goto fb_unmap; | ||
927 | } | ||
928 | |||
929 | dev_dbg(dev, "fb phys 0x%llx 0x%lx\n", | ||
930 | (u64)par->fb_base_phys, (ulong)par->mapped_vram); | ||
931 | dev_dbg(dev, "mmio phys 0x%llx 0x%lx\n", | ||
932 | (u64)par->mmio_base_phys, (ulong)par->mmio_len); | ||
933 | |||
934 | if (mb862xx_pci_gdc_init(par)) | ||
935 | goto io_unmap; | ||
936 | |||
937 | if (request_irq(par->irq, mb862xx_intr, IRQF_DISABLED | IRQF_SHARED, | ||
938 | DRV_NAME, (void *)par)) { | ||
939 | dev_err(dev, "Cannot request irq\n"); | ||
940 | goto io_unmap; | ||
941 | } | ||
942 | |||
943 | mb862xxfb_init_fbinfo(info); | ||
944 | |||
945 | if (fb_alloc_cmap(&info->cmap, NR_PALETTE, 0) < 0) { | ||
946 | dev_err(dev, "Could not allocate cmap for fb_info.\n"); | ||
947 | ret = -ENOMEM; | ||
948 | goto free_irq; | ||
949 | } | ||
950 | |||
951 | if ((info->fbops->fb_set_par)(info)) | ||
952 | dev_err(dev, "set_var() failed on initial setup?\n"); | ||
953 | |||
954 | ret = register_framebuffer(info); | ||
955 | if (ret < 0) { | ||
956 | dev_err(dev, "failed to register framebuffer\n"); | ||
957 | goto rel_cmap; | ||
958 | } | ||
959 | |||
960 | pci_set_drvdata(pdev, info); | ||
961 | |||
962 | if (device_create_file(dev, &dev_attr_dispregs)) | ||
963 | dev_err(dev, "Can't create sysfs regdump file\n"); | ||
964 | |||
965 | if (par->type == BT_CARMINE) | ||
966 | outreg(ctrl, GC_CTRL_INT_MASK, GC_CARMINE_INT_EN); | ||
967 | else | ||
968 | outreg(host, GC_IMASK, GC_INT_EN); | ||
969 | |||
970 | return 0; | ||
971 | |||
972 | rel_cmap: | ||
973 | fb_dealloc_cmap(&info->cmap); | ||
974 | free_irq: | ||
975 | free_irq(par->irq, (void *)par); | ||
976 | io_unmap: | ||
977 | iounmap(par->mmio_base); | ||
978 | fb_unmap: | ||
979 | iounmap(par->fb_base); | ||
980 | rel_reg: | ||
981 | pci_release_regions(pdev); | ||
982 | rel_fb: | ||
983 | framebuffer_release(info); | ||
984 | dis_dev: | ||
985 | pci_disable_device(pdev); | ||
986 | out: | ||
987 | return ret; | ||
988 | } | ||
989 | |||
990 | static void __devexit mb862xx_pci_remove(struct pci_dev *pdev) | ||
991 | { | ||
992 | struct fb_info *fbi = pci_get_drvdata(pdev); | ||
993 | struct mb862xxfb_par *par = fbi->par; | ||
994 | unsigned long reg; | ||
995 | |||
996 | dev_dbg(fbi->dev, "%s release\n", fbi->fix.id); | ||
997 | |||
998 | /* display off */ | ||
999 | reg = inreg(disp, GC_DCM1); | ||
1000 | reg &= ~(GC_DCM01_DEN | GC_DCM01_L0E); | ||
1001 | outreg(disp, GC_DCM1, reg); | ||
1002 | |||
1003 | if (par->type == BT_CARMINE) { | ||
1004 | outreg(ctrl, GC_CTRL_INT_MASK, 0); | ||
1005 | outreg(ctrl, GC_CTRL_CLK_ENABLE, 0); | ||
1006 | } else { | ||
1007 | outreg(host, GC_IMASK, 0); | ||
1008 | } | ||
1009 | |||
1010 | device_remove_file(&pdev->dev, &dev_attr_dispregs); | ||
1011 | |||
1012 | pci_set_drvdata(pdev, NULL); | ||
1013 | unregister_framebuffer(fbi); | ||
1014 | fb_dealloc_cmap(&fbi->cmap); | ||
1015 | |||
1016 | free_irq(par->irq, (void *)par); | ||
1017 | iounmap(par->mmio_base); | ||
1018 | iounmap(par->fb_base); | ||
1019 | |||
1020 | pci_release_regions(pdev); | ||
1021 | framebuffer_release(fbi); | ||
1022 | pci_disable_device(pdev); | ||
1023 | } | ||
1024 | |||
1025 | static struct pci_driver mb862xxfb_pci_driver = { | ||
1026 | .name = DRV_NAME, | ||
1027 | .id_table = mb862xx_pci_tbl, | ||
1028 | .probe = mb862xx_pci_probe, | ||
1029 | .remove = __devexit_p(mb862xx_pci_remove), | ||
1030 | }; | ||
1031 | #endif | ||
1032 | |||
1033 | static int __devinit mb862xxfb_init(void) | ||
1034 | { | ||
1035 | int ret = -ENODEV; | ||
1036 | |||
1037 | #if defined(CONFIG_FB_MB862XX_LIME) | ||
1038 | ret = of_register_platform_driver(&of_platform_mb862xxfb_driver); | ||
1039 | #endif | ||
1040 | #if defined(CONFIG_FB_MB862XX_PCI_GDC) | ||
1041 | ret = pci_register_driver(&mb862xxfb_pci_driver); | ||
1042 | #endif | ||
1043 | return ret; | ||
1044 | } | ||
1045 | |||
1046 | static void __exit mb862xxfb_exit(void) | ||
1047 | { | ||
1048 | #if defined(CONFIG_FB_MB862XX_LIME) | ||
1049 | of_unregister_platform_driver(&of_platform_mb862xxfb_driver); | ||
1050 | #endif | ||
1051 | #if defined(CONFIG_FB_MB862XX_PCI_GDC) | ||
1052 | pci_unregister_driver(&mb862xxfb_pci_driver); | ||
1053 | #endif | ||
1054 | } | ||
1055 | |||
1056 | module_init(mb862xxfb_init); | ||
1057 | module_exit(mb862xxfb_exit); | ||
1058 | |||
1059 | MODULE_DESCRIPTION("Fujitsu MB862xx Framebuffer driver"); | ||
1060 | MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>"); | ||
1061 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/video/mb862xx/mb862xxfb.h b/drivers/video/mb862xx/mb862xxfb.h new file mode 100644 index 000000000000..c4c8f4dd2217 --- /dev/null +++ b/drivers/video/mb862xx/mb862xxfb.h | |||
@@ -0,0 +1,83 @@ | |||
1 | #ifndef __MB862XX_H__ | ||
2 | #define __MB862XX_H__ | ||
3 | |||
4 | #define PCI_VENDOR_ID_FUJITSU_LIMITED 0x10cf | ||
5 | #define PCI_DEVICE_ID_FUJITSU_CORALP 0x2019 | ||
6 | #define PCI_DEVICE_ID_FUJITSU_CORALPA 0x201e | ||
7 | #define PCI_DEVICE_ID_FUJITSU_CARMINE 0x202b | ||
8 | |||
9 | #define GC_MMR_CORALP_EVB_VAL 0x11d7fa13 | ||
10 | |||
11 | enum gdctype { | ||
12 | BT_NONE, | ||
13 | BT_LIME, | ||
14 | BT_MINT, | ||
15 | BT_CORAL, | ||
16 | BT_CORALP, | ||
17 | BT_CARMINE, | ||
18 | }; | ||
19 | |||
20 | struct mb862xx_gc_mode { | ||
21 | struct fb_videomode def_mode; /* mode of connected display */ | ||
22 | unsigned int def_bpp; /* default depth */ | ||
23 | unsigned long max_vram; /* connected SDRAM size */ | ||
24 | unsigned long ccf; /* gdc clk */ | ||
25 | unsigned long mmr; /* memory mode for SDRAM */ | ||
26 | }; | ||
27 | |||
28 | /* private data */ | ||
29 | struct mb862xxfb_par { | ||
30 | struct fb_info *info; /* fb info head */ | ||
31 | struct device *dev; | ||
32 | struct pci_dev *pdev; | ||
33 | struct resource *res; /* framebuffer/mmio resource */ | ||
34 | |||
35 | resource_size_t fb_base_phys; /* fb base, 36-bit PPC440EPx */ | ||
36 | resource_size_t mmio_base_phys; /* io base addr */ | ||
37 | void __iomem *fb_base; /* remapped framebuffer */ | ||
38 | void __iomem *mmio_base; /* remapped registers */ | ||
39 | size_t mapped_vram; /* length of remapped vram */ | ||
40 | size_t mmio_len; /* length of register region */ | ||
41 | |||
42 | void __iomem *host; /* relocatable reg. bases */ | ||
43 | void __iomem *i2c; | ||
44 | void __iomem *disp; | ||
45 | void __iomem *disp1; | ||
46 | void __iomem *cap; | ||
47 | void __iomem *cap1; | ||
48 | void __iomem *draw; | ||
49 | void __iomem *geo; | ||
50 | void __iomem *pio; | ||
51 | void __iomem *ctrl; | ||
52 | void __iomem *dram_ctrl; | ||
53 | void __iomem *wrback; | ||
54 | |||
55 | unsigned int irq; | ||
56 | unsigned int type; /* GDC type */ | ||
57 | unsigned int refclk; /* disp. reference clock */ | ||
58 | struct mb862xx_gc_mode *gc_mode; /* GDC mode init data */ | ||
59 | int pre_init; /* don't init display if 1 */ | ||
60 | |||
61 | u32 pseudo_palette[16]; | ||
62 | }; | ||
63 | |||
64 | #if defined(CONFIG_FB_MB862XX_LIME) && defined(CONFIG_FB_MB862XX_PCI_GDC) | ||
65 | #error "Select Lime GDC or CoralP/Carmine support, but not both together" | ||
66 | #endif | ||
67 | #if defined(CONFIG_FB_MB862XX_LIME) | ||
68 | #define gdc_read __raw_readl | ||
69 | #define gdc_write __raw_writel | ||
70 | #else | ||
71 | #define gdc_read readl | ||
72 | #define gdc_write writel | ||
73 | #endif | ||
74 | |||
75 | #define inreg(type, off) \ | ||
76 | gdc_read((par->type + (off))) | ||
77 | |||
78 | #define outreg(type, off, val) \ | ||
79 | gdc_write((val), (par->type + (off))) | ||
80 | |||
81 | #define pack(a, b) (((a) << 16) | (b)) | ||
82 | |||
83 | #endif | ||
diff --git a/drivers/w1/masters/Kconfig b/drivers/w1/masters/Kconfig index c4493091c655..a14d5b6e4c7c 100644 --- a/drivers/w1/masters/Kconfig +++ b/drivers/w1/masters/Kconfig | |||
@@ -52,5 +52,12 @@ config W1_MASTER_GPIO | |||
52 | This support is also available as a module. If so, the module | 52 | This support is also available as a module. If so, the module |
53 | will be called w1-gpio.ko. | 53 | will be called w1-gpio.ko. |
54 | 54 | ||
55 | config HDQ_MASTER_OMAP | ||
56 | tristate "OMAP HDQ driver" | ||
57 | depends on ARCH_OMAP2430 || ARCH_OMAP34XX | ||
58 | help | ||
59 | Say Y here if you want support for the 1-wire or HDQ Interface | ||
60 | on an OMAP processor. | ||
61 | |||
55 | endmenu | 62 | endmenu |
56 | 63 | ||
diff --git a/drivers/w1/masters/Makefile b/drivers/w1/masters/Makefile index 1420b5bbdda8..bc4714a75f3a 100644 --- a/drivers/w1/masters/Makefile +++ b/drivers/w1/masters/Makefile | |||
@@ -7,3 +7,4 @@ obj-$(CONFIG_W1_MASTER_DS2490) += ds2490.o | |||
7 | obj-$(CONFIG_W1_MASTER_DS2482) += ds2482.o | 7 | obj-$(CONFIG_W1_MASTER_DS2482) += ds2482.o |
8 | obj-$(CONFIG_W1_MASTER_DS1WM) += ds1wm.o | 8 | obj-$(CONFIG_W1_MASTER_DS1WM) += ds1wm.o |
9 | obj-$(CONFIG_W1_MASTER_GPIO) += w1-gpio.o | 9 | obj-$(CONFIG_W1_MASTER_GPIO) += w1-gpio.o |
10 | obj-$(CONFIG_HDQ_MASTER_OMAP) += omap_hdq.o | ||
diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c new file mode 100644 index 000000000000..1295625c4825 --- /dev/null +++ b/drivers/w1/masters/omap_hdq.c | |||
@@ -0,0 +1,725 @@ | |||
1 | /* | ||
2 | * drivers/w1/masters/omap_hdq.c | ||
3 | * | ||
4 | * Copyright (C) 2007 Texas Instruments, Inc. | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public License | ||
7 | * version 2. This program is licensed "as is" without any warranty of any | ||
8 | * kind, whether express or implied. | ||
9 | * | ||
10 | */ | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/clk.h> | ||
17 | #include <linux/io.h> | ||
18 | |||
19 | #include <asm/irq.h> | ||
20 | #include <mach/hardware.h> | ||
21 | |||
22 | #include "../w1.h" | ||
23 | #include "../w1_int.h" | ||
24 | |||
25 | #define MOD_NAME "OMAP_HDQ:" | ||
26 | |||
27 | #define OMAP_HDQ_REVISION 0x00 | ||
28 | #define OMAP_HDQ_TX_DATA 0x04 | ||
29 | #define OMAP_HDQ_RX_DATA 0x08 | ||
30 | #define OMAP_HDQ_CTRL_STATUS 0x0c | ||
31 | #define OMAP_HDQ_CTRL_STATUS_INTERRUPTMASK (1<<6) | ||
32 | #define OMAP_HDQ_CTRL_STATUS_CLOCKENABLE (1<<5) | ||
33 | #define OMAP_HDQ_CTRL_STATUS_GO (1<<4) | ||
34 | #define OMAP_HDQ_CTRL_STATUS_INITIALIZATION (1<<2) | ||
35 | #define OMAP_HDQ_CTRL_STATUS_DIR (1<<1) | ||
36 | #define OMAP_HDQ_CTRL_STATUS_MODE (1<<0) | ||
37 | #define OMAP_HDQ_INT_STATUS 0x10 | ||
38 | #define OMAP_HDQ_INT_STATUS_TXCOMPLETE (1<<2) | ||
39 | #define OMAP_HDQ_INT_STATUS_RXCOMPLETE (1<<1) | ||
40 | #define OMAP_HDQ_INT_STATUS_TIMEOUT (1<<0) | ||
41 | #define OMAP_HDQ_SYSCONFIG 0x14 | ||
42 | #define OMAP_HDQ_SYSCONFIG_SOFTRESET (1<<1) | ||
43 | #define OMAP_HDQ_SYSCONFIG_AUTOIDLE (1<<0) | ||
44 | #define OMAP_HDQ_SYSSTATUS 0x18 | ||
45 | #define OMAP_HDQ_SYSSTATUS_RESETDONE (1<<0) | ||
46 | |||
47 | #define OMAP_HDQ_FLAG_CLEAR 0 | ||
48 | #define OMAP_HDQ_FLAG_SET 1 | ||
49 | #define OMAP_HDQ_TIMEOUT (HZ/5) | ||
50 | |||
51 | #define OMAP_HDQ_MAX_USER 4 | ||
52 | |||
53 | static DECLARE_WAIT_QUEUE_HEAD(hdq_wait_queue); | ||
54 | static int w1_id; | ||
55 | |||
56 | struct hdq_data { | ||
57 | struct device *dev; | ||
58 | void __iomem *hdq_base; | ||
59 | /* lock status update */ | ||
60 | struct mutex hdq_mutex; | ||
61 | int hdq_usecount; | ||
62 | struct clk *hdq_ick; | ||
63 | struct clk *hdq_fck; | ||
64 | u8 hdq_irqstatus; | ||
65 | /* device lock */ | ||
66 | spinlock_t hdq_spinlock; | ||
67 | /* | ||
68 | * Used to control the call to omap_hdq_get and omap_hdq_put. | ||
69 | * HDQ Protocol: Write the CMD|REG_address first, followed by | ||
70 | * the data wrire or read. | ||
71 | */ | ||
72 | int init_trans; | ||
73 | }; | ||
74 | |||
75 | static int __init omap_hdq_probe(struct platform_device *pdev); | ||
76 | static int omap_hdq_remove(struct platform_device *pdev); | ||
77 | |||
78 | static struct platform_driver omap_hdq_driver = { | ||
79 | .probe = omap_hdq_probe, | ||
80 | .remove = omap_hdq_remove, | ||
81 | .driver = { | ||
82 | .name = "omap_hdq", | ||
83 | }, | ||
84 | }; | ||
85 | |||
86 | static u8 omap_w1_read_byte(void *_hdq); | ||
87 | static void omap_w1_write_byte(void *_hdq, u8 byte); | ||
88 | static u8 omap_w1_reset_bus(void *_hdq); | ||
89 | static void omap_w1_search_bus(void *_hdq, u8 search_type, | ||
90 | w1_slave_found_callback slave_found); | ||
91 | |||
92 | |||
93 | static struct w1_bus_master omap_w1_master = { | ||
94 | .read_byte = omap_w1_read_byte, | ||
95 | .write_byte = omap_w1_write_byte, | ||
96 | .reset_bus = omap_w1_reset_bus, | ||
97 | .search = omap_w1_search_bus, | ||
98 | }; | ||
99 | |||
100 | /* HDQ register I/O routines */ | ||
101 | static inline u8 hdq_reg_in(struct hdq_data *hdq_data, u32 offset) | ||
102 | { | ||
103 | return __raw_readb(hdq_data->hdq_base + offset); | ||
104 | } | ||
105 | |||
106 | static inline void hdq_reg_out(struct hdq_data *hdq_data, u32 offset, u8 val) | ||
107 | { | ||
108 | __raw_writeb(val, hdq_data->hdq_base + offset); | ||
109 | } | ||
110 | |||
111 | static inline u8 hdq_reg_merge(struct hdq_data *hdq_data, u32 offset, | ||
112 | u8 val, u8 mask) | ||
113 | { | ||
114 | u8 new_val = (__raw_readb(hdq_data->hdq_base + offset) & ~mask) | ||
115 | | (val & mask); | ||
116 | __raw_writeb(new_val, hdq_data->hdq_base + offset); | ||
117 | |||
118 | return new_val; | ||
119 | } | ||
120 | |||
121 | /* | ||
122 | * Wait for one or more bits in flag change. | ||
123 | * HDQ_FLAG_SET: wait until any bit in the flag is set. | ||
124 | * HDQ_FLAG_CLEAR: wait until all bits in the flag are cleared. | ||
125 | * return 0 on success and -ETIMEDOUT in the case of timeout. | ||
126 | */ | ||
127 | static int hdq_wait_for_flag(struct hdq_data *hdq_data, u32 offset, | ||
128 | u8 flag, u8 flag_set, u8 *status) | ||
129 | { | ||
130 | int ret = 0; | ||
131 | unsigned long timeout = jiffies + OMAP_HDQ_TIMEOUT; | ||
132 | |||
133 | if (flag_set == OMAP_HDQ_FLAG_CLEAR) { | ||
134 | /* wait for the flag clear */ | ||
135 | while (((*status = hdq_reg_in(hdq_data, offset)) & flag) | ||
136 | && time_before(jiffies, timeout)) { | ||
137 | schedule_timeout_uninterruptible(1); | ||
138 | } | ||
139 | if (*status & flag) | ||
140 | ret = -ETIMEDOUT; | ||
141 | } else if (flag_set == OMAP_HDQ_FLAG_SET) { | ||
142 | /* wait for the flag set */ | ||
143 | while (!((*status = hdq_reg_in(hdq_data, offset)) & flag) | ||
144 | && time_before(jiffies, timeout)) { | ||
145 | schedule_timeout_uninterruptible(1); | ||
146 | } | ||
147 | if (!(*status & flag)) | ||
148 | ret = -ETIMEDOUT; | ||
149 | } else | ||
150 | return -EINVAL; | ||
151 | |||
152 | return ret; | ||
153 | } | ||
154 | |||
155 | /* write out a byte and fill *status with HDQ_INT_STATUS */ | ||
156 | static int hdq_write_byte(struct hdq_data *hdq_data, u8 val, u8 *status) | ||
157 | { | ||
158 | int ret; | ||
159 | u8 tmp_status; | ||
160 | unsigned long irqflags; | ||
161 | |||
162 | *status = 0; | ||
163 | |||
164 | spin_lock_irqsave(&hdq_data->hdq_spinlock, irqflags); | ||
165 | /* clear interrupt flags via a dummy read */ | ||
166 | hdq_reg_in(hdq_data, OMAP_HDQ_INT_STATUS); | ||
167 | /* ISR loads it with new INT_STATUS */ | ||
168 | hdq_data->hdq_irqstatus = 0; | ||
169 | spin_unlock_irqrestore(&hdq_data->hdq_spinlock, irqflags); | ||
170 | |||
171 | hdq_reg_out(hdq_data, OMAP_HDQ_TX_DATA, val); | ||
172 | |||
173 | /* set the GO bit */ | ||
174 | hdq_reg_merge(hdq_data, OMAP_HDQ_CTRL_STATUS, OMAP_HDQ_CTRL_STATUS_GO, | ||
175 | OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO); | ||
176 | /* wait for the TXCOMPLETE bit */ | ||
177 | ret = wait_event_timeout(hdq_wait_queue, | ||
178 | hdq_data->hdq_irqstatus, OMAP_HDQ_TIMEOUT); | ||
179 | if (ret == 0) { | ||
180 | dev_dbg(hdq_data->dev, "TX wait elapsed\n"); | ||
181 | goto out; | ||
182 | } | ||
183 | |||
184 | *status = hdq_data->hdq_irqstatus; | ||
185 | /* check irqstatus */ | ||
186 | if (!(*status & OMAP_HDQ_INT_STATUS_TXCOMPLETE)) { | ||
187 | dev_dbg(hdq_data->dev, "timeout waiting for" | ||
188 | "TXCOMPLETE/RXCOMPLETE, %x", *status); | ||
189 | ret = -ETIMEDOUT; | ||
190 | goto out; | ||
191 | } | ||
192 | |||
193 | /* wait for the GO bit return to zero */ | ||
194 | ret = hdq_wait_for_flag(hdq_data, OMAP_HDQ_CTRL_STATUS, | ||
195 | OMAP_HDQ_CTRL_STATUS_GO, | ||
196 | OMAP_HDQ_FLAG_CLEAR, &tmp_status); | ||
197 | if (ret) { | ||
198 | dev_dbg(hdq_data->dev, "timeout waiting GO bit" | ||
199 | "return to zero, %x", tmp_status); | ||
200 | } | ||
201 | |||
202 | out: | ||
203 | return ret; | ||
204 | } | ||
205 | |||
206 | /* HDQ Interrupt service routine */ | ||
207 | static irqreturn_t hdq_isr(int irq, void *_hdq) | ||
208 | { | ||
209 | struct hdq_data *hdq_data = _hdq; | ||
210 | unsigned long irqflags; | ||
211 | |||
212 | spin_lock_irqsave(&hdq_data->hdq_spinlock, irqflags); | ||
213 | hdq_data->hdq_irqstatus = hdq_reg_in(hdq_data, OMAP_HDQ_INT_STATUS); | ||
214 | spin_unlock_irqrestore(&hdq_data->hdq_spinlock, irqflags); | ||
215 | dev_dbg(hdq_data->dev, "hdq_isr: %x", hdq_data->hdq_irqstatus); | ||
216 | |||
217 | if (hdq_data->hdq_irqstatus & | ||
218 | (OMAP_HDQ_INT_STATUS_TXCOMPLETE | OMAP_HDQ_INT_STATUS_RXCOMPLETE | ||
219 | | OMAP_HDQ_INT_STATUS_TIMEOUT)) { | ||
220 | /* wake up sleeping process */ | ||
221 | wake_up(&hdq_wait_queue); | ||
222 | } | ||
223 | |||
224 | return IRQ_HANDLED; | ||
225 | } | ||
226 | |||
227 | /* HDQ Mode: always return success */ | ||
228 | static u8 omap_w1_reset_bus(void *_hdq) | ||
229 | { | ||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | /* W1 search callback function */ | ||
234 | static void omap_w1_search_bus(void *_hdq, u8 search_type, | ||
235 | w1_slave_found_callback slave_found) | ||
236 | { | ||
237 | u64 module_id, rn_le, cs, id; | ||
238 | |||
239 | if (w1_id) | ||
240 | module_id = w1_id; | ||
241 | else | ||
242 | module_id = 0x1; | ||
243 | |||
244 | rn_le = cpu_to_le64(module_id); | ||
245 | /* | ||
246 | * HDQ might not obey truly the 1-wire spec. | ||
247 | * So calculate CRC based on module parameter. | ||
248 | */ | ||
249 | cs = w1_calc_crc8((u8 *)&rn_le, 7); | ||
250 | id = (cs << 56) | module_id; | ||
251 | |||
252 | slave_found(_hdq, id); | ||
253 | } | ||
254 | |||
255 | static int _omap_hdq_reset(struct hdq_data *hdq_data) | ||
256 | { | ||
257 | int ret; | ||
258 | u8 tmp_status; | ||
259 | |||
260 | hdq_reg_out(hdq_data, OMAP_HDQ_SYSCONFIG, OMAP_HDQ_SYSCONFIG_SOFTRESET); | ||
261 | /* | ||
262 | * Select HDQ mode & enable clocks. | ||
263 | * It is observed that INT flags can't be cleared via a read and GO/INIT | ||
264 | * won't return to zero if interrupt is disabled. So we always enable | ||
265 | * interrupt. | ||
266 | */ | ||
267 | hdq_reg_out(hdq_data, OMAP_HDQ_CTRL_STATUS, | ||
268 | OMAP_HDQ_CTRL_STATUS_CLOCKENABLE | | ||
269 | OMAP_HDQ_CTRL_STATUS_INTERRUPTMASK); | ||
270 | |||
271 | /* wait for reset to complete */ | ||
272 | ret = hdq_wait_for_flag(hdq_data, OMAP_HDQ_SYSSTATUS, | ||
273 | OMAP_HDQ_SYSSTATUS_RESETDONE, OMAP_HDQ_FLAG_SET, &tmp_status); | ||
274 | if (ret) | ||
275 | dev_dbg(hdq_data->dev, "timeout waiting HDQ reset, %x", | ||
276 | tmp_status); | ||
277 | else { | ||
278 | hdq_reg_out(hdq_data, OMAP_HDQ_CTRL_STATUS, | ||
279 | OMAP_HDQ_CTRL_STATUS_CLOCKENABLE | | ||
280 | OMAP_HDQ_CTRL_STATUS_INTERRUPTMASK); | ||
281 | hdq_reg_out(hdq_data, OMAP_HDQ_SYSCONFIG, | ||
282 | OMAP_HDQ_SYSCONFIG_AUTOIDLE); | ||
283 | } | ||
284 | |||
285 | return ret; | ||
286 | } | ||
287 | |||
288 | /* Issue break pulse to the device */ | ||
289 | static int omap_hdq_break(struct hdq_data *hdq_data) | ||
290 | { | ||
291 | int ret = 0; | ||
292 | u8 tmp_status; | ||
293 | unsigned long irqflags; | ||
294 | |||
295 | ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); | ||
296 | if (ret < 0) { | ||
297 | dev_dbg(hdq_data->dev, "Could not acquire mutex\n"); | ||
298 | ret = -EINTR; | ||
299 | goto rtn; | ||
300 | } | ||
301 | |||
302 | spin_lock_irqsave(&hdq_data->hdq_spinlock, irqflags); | ||
303 | /* clear interrupt flags via a dummy read */ | ||
304 | hdq_reg_in(hdq_data, OMAP_HDQ_INT_STATUS); | ||
305 | /* ISR loads it with new INT_STATUS */ | ||
306 | hdq_data->hdq_irqstatus = 0; | ||
307 | spin_unlock_irqrestore(&hdq_data->hdq_spinlock, irqflags); | ||
308 | |||
309 | /* set the INIT and GO bit */ | ||
310 | hdq_reg_merge(hdq_data, OMAP_HDQ_CTRL_STATUS, | ||
311 | OMAP_HDQ_CTRL_STATUS_INITIALIZATION | OMAP_HDQ_CTRL_STATUS_GO, | ||
312 | OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_INITIALIZATION | | ||
313 | OMAP_HDQ_CTRL_STATUS_GO); | ||
314 | |||
315 | /* wait for the TIMEOUT bit */ | ||
316 | ret = wait_event_timeout(hdq_wait_queue, | ||
317 | hdq_data->hdq_irqstatus, OMAP_HDQ_TIMEOUT); | ||
318 | if (ret == 0) { | ||
319 | dev_dbg(hdq_data->dev, "break wait elapsed\n"); | ||
320 | ret = -EINTR; | ||
321 | goto out; | ||
322 | } | ||
323 | |||
324 | tmp_status = hdq_data->hdq_irqstatus; | ||
325 | /* check irqstatus */ | ||
326 | if (!(tmp_status & OMAP_HDQ_INT_STATUS_TIMEOUT)) { | ||
327 | dev_dbg(hdq_data->dev, "timeout waiting for TIMEOUT, %x", | ||
328 | tmp_status); | ||
329 | ret = -ETIMEDOUT; | ||
330 | goto out; | ||
331 | } | ||
332 | /* | ||
333 | * wait for both INIT and GO bits rerurn to zero. | ||
334 | * zero wait time expected for interrupt mode. | ||
335 | */ | ||
336 | ret = hdq_wait_for_flag(hdq_data, OMAP_HDQ_CTRL_STATUS, | ||
337 | OMAP_HDQ_CTRL_STATUS_INITIALIZATION | | ||
338 | OMAP_HDQ_CTRL_STATUS_GO, OMAP_HDQ_FLAG_CLEAR, | ||
339 | &tmp_status); | ||
340 | if (ret) | ||
341 | dev_dbg(hdq_data->dev, "timeout waiting INIT&GO bits" | ||
342 | "return to zero, %x", tmp_status); | ||
343 | |||
344 | out: | ||
345 | mutex_unlock(&hdq_data->hdq_mutex); | ||
346 | rtn: | ||
347 | return ret; | ||
348 | } | ||
349 | |||
350 | static int hdq_read_byte(struct hdq_data *hdq_data, u8 *val) | ||
351 | { | ||
352 | int ret = 0; | ||
353 | u8 status; | ||
354 | unsigned long timeout = jiffies + OMAP_HDQ_TIMEOUT; | ||
355 | |||
356 | ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); | ||
357 | if (ret < 0) { | ||
358 | ret = -EINTR; | ||
359 | goto rtn; | ||
360 | } | ||
361 | |||
362 | if (!hdq_data->hdq_usecount) { | ||
363 | ret = -EINVAL; | ||
364 | goto out; | ||
365 | } | ||
366 | |||
367 | if (!(hdq_data->hdq_irqstatus & OMAP_HDQ_INT_STATUS_RXCOMPLETE)) { | ||
368 | hdq_reg_merge(hdq_data, OMAP_HDQ_CTRL_STATUS, | ||
369 | OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO, | ||
370 | OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO); | ||
371 | /* | ||
372 | * The RX comes immediately after TX. It | ||
373 | * triggers another interrupt before we | ||
374 | * sleep. So we have to wait for RXCOMPLETE bit. | ||
375 | */ | ||
376 | while (!(hdq_data->hdq_irqstatus | ||
377 | & OMAP_HDQ_INT_STATUS_RXCOMPLETE) | ||
378 | && time_before(jiffies, timeout)) { | ||
379 | schedule_timeout_uninterruptible(1); | ||
380 | } | ||
381 | hdq_reg_merge(hdq_data, OMAP_HDQ_CTRL_STATUS, 0, | ||
382 | OMAP_HDQ_CTRL_STATUS_DIR); | ||
383 | status = hdq_data->hdq_irqstatus; | ||
384 | /* check irqstatus */ | ||
385 | if (!(status & OMAP_HDQ_INT_STATUS_RXCOMPLETE)) { | ||
386 | dev_dbg(hdq_data->dev, "timeout waiting for" | ||
387 | "RXCOMPLETE, %x", status); | ||
388 | ret = -ETIMEDOUT; | ||
389 | goto out; | ||
390 | } | ||
391 | } | ||
392 | /* the data is ready. Read it in! */ | ||
393 | *val = hdq_reg_in(hdq_data, OMAP_HDQ_RX_DATA); | ||
394 | out: | ||
395 | mutex_unlock(&hdq_data->hdq_mutex); | ||
396 | rtn: | ||
397 | return 0; | ||
398 | |||
399 | } | ||
400 | |||
401 | /* Enable clocks and set the controller to HDQ mode */ | ||
402 | static int omap_hdq_get(struct hdq_data *hdq_data) | ||
403 | { | ||
404 | int ret = 0; | ||
405 | |||
406 | ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); | ||
407 | if (ret < 0) { | ||
408 | ret = -EINTR; | ||
409 | goto rtn; | ||
410 | } | ||
411 | |||
412 | if (OMAP_HDQ_MAX_USER == hdq_data->hdq_usecount) { | ||
413 | dev_dbg(hdq_data->dev, "attempt to exceed the max use count"); | ||
414 | ret = -EINVAL; | ||
415 | goto out; | ||
416 | } else { | ||
417 | hdq_data->hdq_usecount++; | ||
418 | try_module_get(THIS_MODULE); | ||
419 | if (1 == hdq_data->hdq_usecount) { | ||
420 | if (clk_enable(hdq_data->hdq_ick)) { | ||
421 | dev_dbg(hdq_data->dev, "Can not enable ick\n"); | ||
422 | ret = -ENODEV; | ||
423 | goto clk_err; | ||
424 | } | ||
425 | if (clk_enable(hdq_data->hdq_fck)) { | ||
426 | dev_dbg(hdq_data->dev, "Can not enable fck\n"); | ||
427 | clk_disable(hdq_data->hdq_ick); | ||
428 | ret = -ENODEV; | ||
429 | goto clk_err; | ||
430 | } | ||
431 | |||
432 | /* make sure HDQ is out of reset */ | ||
433 | if (!(hdq_reg_in(hdq_data, OMAP_HDQ_SYSSTATUS) & | ||
434 | OMAP_HDQ_SYSSTATUS_RESETDONE)) { | ||
435 | ret = _omap_hdq_reset(hdq_data); | ||
436 | if (ret) | ||
437 | /* back up the count */ | ||
438 | hdq_data->hdq_usecount--; | ||
439 | } else { | ||
440 | /* select HDQ mode & enable clocks */ | ||
441 | hdq_reg_out(hdq_data, OMAP_HDQ_CTRL_STATUS, | ||
442 | OMAP_HDQ_CTRL_STATUS_CLOCKENABLE | | ||
443 | OMAP_HDQ_CTRL_STATUS_INTERRUPTMASK); | ||
444 | hdq_reg_out(hdq_data, OMAP_HDQ_SYSCONFIG, | ||
445 | OMAP_HDQ_SYSCONFIG_AUTOIDLE); | ||
446 | hdq_reg_in(hdq_data, OMAP_HDQ_INT_STATUS); | ||
447 | } | ||
448 | } | ||
449 | } | ||
450 | |||
451 | clk_err: | ||
452 | clk_put(hdq_data->hdq_ick); | ||
453 | clk_put(hdq_data->hdq_fck); | ||
454 | out: | ||
455 | mutex_unlock(&hdq_data->hdq_mutex); | ||
456 | rtn: | ||
457 | return ret; | ||
458 | } | ||
459 | |||
460 | /* Disable clocks to the module */ | ||
461 | static int omap_hdq_put(struct hdq_data *hdq_data) | ||
462 | { | ||
463 | int ret = 0; | ||
464 | |||
465 | ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); | ||
466 | if (ret < 0) | ||
467 | return -EINTR; | ||
468 | |||
469 | if (0 == hdq_data->hdq_usecount) { | ||
470 | dev_dbg(hdq_data->dev, "attempt to decrement use count" | ||
471 | "when it is zero"); | ||
472 | ret = -EINVAL; | ||
473 | } else { | ||
474 | hdq_data->hdq_usecount--; | ||
475 | module_put(THIS_MODULE); | ||
476 | if (0 == hdq_data->hdq_usecount) { | ||
477 | clk_disable(hdq_data->hdq_ick); | ||
478 | clk_disable(hdq_data->hdq_fck); | ||
479 | } | ||
480 | } | ||
481 | mutex_unlock(&hdq_data->hdq_mutex); | ||
482 | |||
483 | return ret; | ||
484 | } | ||
485 | |||
486 | /* Read a byte of data from the device */ | ||
487 | static u8 omap_w1_read_byte(void *_hdq) | ||
488 | { | ||
489 | struct hdq_data *hdq_data = _hdq; | ||
490 | u8 val = 0; | ||
491 | int ret; | ||
492 | |||
493 | ret = hdq_read_byte(hdq_data, &val); | ||
494 | if (ret) { | ||
495 | ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); | ||
496 | if (ret < 0) { | ||
497 | dev_dbg(hdq_data->dev, "Could not acquire mutex\n"); | ||
498 | return -EINTR; | ||
499 | } | ||
500 | hdq_data->init_trans = 0; | ||
501 | mutex_unlock(&hdq_data->hdq_mutex); | ||
502 | omap_hdq_put(hdq_data); | ||
503 | return -1; | ||
504 | } | ||
505 | |||
506 | /* Write followed by a read, release the module */ | ||
507 | if (hdq_data->init_trans) { | ||
508 | ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); | ||
509 | if (ret < 0) { | ||
510 | dev_dbg(hdq_data->dev, "Could not acquire mutex\n"); | ||
511 | return -EINTR; | ||
512 | } | ||
513 | hdq_data->init_trans = 0; | ||
514 | mutex_unlock(&hdq_data->hdq_mutex); | ||
515 | omap_hdq_put(hdq_data); | ||
516 | } | ||
517 | |||
518 | return val; | ||
519 | } | ||
520 | |||
521 | /* Write a byte of data to the device */ | ||
522 | static void omap_w1_write_byte(void *_hdq, u8 byte) | ||
523 | { | ||
524 | struct hdq_data *hdq_data = _hdq; | ||
525 | int ret; | ||
526 | u8 status; | ||
527 | |||
528 | /* First write to initialize the transfer */ | ||
529 | if (hdq_data->init_trans == 0) | ||
530 | omap_hdq_get(hdq_data); | ||
531 | |||
532 | ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); | ||
533 | if (ret < 0) { | ||
534 | dev_dbg(hdq_data->dev, "Could not acquire mutex\n"); | ||
535 | return; | ||
536 | } | ||
537 | hdq_data->init_trans++; | ||
538 | mutex_unlock(&hdq_data->hdq_mutex); | ||
539 | |||
540 | ret = hdq_write_byte(hdq_data, byte, &status); | ||
541 | if (ret == 0) { | ||
542 | dev_dbg(hdq_data->dev, "TX failure:Ctrl status %x\n", status); | ||
543 | return; | ||
544 | } | ||
545 | |||
546 | /* Second write, data transfered. Release the module */ | ||
547 | if (hdq_data->init_trans > 1) { | ||
548 | omap_hdq_put(hdq_data); | ||
549 | ret = mutex_lock_interruptible(&hdq_data->hdq_mutex); | ||
550 | if (ret < 0) { | ||
551 | dev_dbg(hdq_data->dev, "Could not acquire mutex\n"); | ||
552 | return; | ||
553 | } | ||
554 | hdq_data->init_trans = 0; | ||
555 | mutex_unlock(&hdq_data->hdq_mutex); | ||
556 | } | ||
557 | |||
558 | return; | ||
559 | } | ||
560 | |||
561 | static int __init omap_hdq_probe(struct platform_device *pdev) | ||
562 | { | ||
563 | struct hdq_data *hdq_data; | ||
564 | struct resource *res; | ||
565 | int ret, irq; | ||
566 | u8 rev; | ||
567 | |||
568 | hdq_data = kmalloc(sizeof(*hdq_data), GFP_KERNEL); | ||
569 | if (!hdq_data) { | ||
570 | dev_dbg(&pdev->dev, "unable to allocate memory\n"); | ||
571 | ret = -ENOMEM; | ||
572 | goto err_kmalloc; | ||
573 | } | ||
574 | |||
575 | hdq_data->dev = &pdev->dev; | ||
576 | platform_set_drvdata(pdev, hdq_data); | ||
577 | |||
578 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
579 | if (!res) { | ||
580 | dev_dbg(&pdev->dev, "unable to get resource\n"); | ||
581 | ret = -ENXIO; | ||
582 | goto err_resource; | ||
583 | } | ||
584 | |||
585 | hdq_data->hdq_base = ioremap(res->start, SZ_4K); | ||
586 | if (!hdq_data->hdq_base) { | ||
587 | dev_dbg(&pdev->dev, "ioremap failed\n"); | ||
588 | ret = -EINVAL; | ||
589 | goto err_ioremap; | ||
590 | } | ||
591 | |||
592 | /* get interface & functional clock objects */ | ||
593 | hdq_data->hdq_ick = clk_get(&pdev->dev, "hdq_ick"); | ||
594 | hdq_data->hdq_fck = clk_get(&pdev->dev, "hdq_fck"); | ||
595 | |||
596 | if (IS_ERR(hdq_data->hdq_ick) || IS_ERR(hdq_data->hdq_fck)) { | ||
597 | dev_dbg(&pdev->dev, "Can't get HDQ clock objects\n"); | ||
598 | if (IS_ERR(hdq_data->hdq_ick)) { | ||
599 | ret = PTR_ERR(hdq_data->hdq_ick); | ||
600 | goto err_clk; | ||
601 | } | ||
602 | if (IS_ERR(hdq_data->hdq_fck)) { | ||
603 | ret = PTR_ERR(hdq_data->hdq_fck); | ||
604 | clk_put(hdq_data->hdq_ick); | ||
605 | goto err_clk; | ||
606 | } | ||
607 | } | ||
608 | |||
609 | hdq_data->hdq_usecount = 0; | ||
610 | mutex_init(&hdq_data->hdq_mutex); | ||
611 | |||
612 | if (clk_enable(hdq_data->hdq_ick)) { | ||
613 | dev_dbg(&pdev->dev, "Can not enable ick\n"); | ||
614 | ret = -ENODEV; | ||
615 | goto err_intfclk; | ||
616 | } | ||
617 | |||
618 | if (clk_enable(hdq_data->hdq_fck)) { | ||
619 | dev_dbg(&pdev->dev, "Can not enable fck\n"); | ||
620 | ret = -ENODEV; | ||
621 | goto err_fnclk; | ||
622 | } | ||
623 | |||
624 | rev = hdq_reg_in(hdq_data, OMAP_HDQ_REVISION); | ||
625 | dev_info(&pdev->dev, "OMAP HDQ Hardware Rev %c.%c. Driver in %s mode\n", | ||
626 | (rev >> 4) + '0', (rev & 0x0f) + '0', "Interrupt"); | ||
627 | |||
628 | spin_lock_init(&hdq_data->hdq_spinlock); | ||
629 | |||
630 | irq = platform_get_irq(pdev, 0); | ||
631 | if (irq < 0) { | ||
632 | ret = -ENXIO; | ||
633 | goto err_irq; | ||
634 | } | ||
635 | |||
636 | ret = request_irq(irq, hdq_isr, IRQF_DISABLED, "omap_hdq", hdq_data); | ||
637 | if (ret < 0) { | ||
638 | dev_dbg(&pdev->dev, "could not request irq\n"); | ||
639 | goto err_irq; | ||
640 | } | ||
641 | |||
642 | omap_hdq_break(hdq_data); | ||
643 | |||
644 | /* don't clock the HDQ until it is needed */ | ||
645 | clk_disable(hdq_data->hdq_ick); | ||
646 | clk_disable(hdq_data->hdq_fck); | ||
647 | |||
648 | omap_w1_master.data = hdq_data; | ||
649 | |||
650 | ret = w1_add_master_device(&omap_w1_master); | ||
651 | if (ret) { | ||
652 | dev_dbg(&pdev->dev, "Failure in registering w1 master\n"); | ||
653 | goto err_w1; | ||
654 | } | ||
655 | |||
656 | return 0; | ||
657 | |||
658 | err_w1: | ||
659 | err_irq: | ||
660 | clk_disable(hdq_data->hdq_fck); | ||
661 | |||
662 | err_fnclk: | ||
663 | clk_disable(hdq_data->hdq_ick); | ||
664 | |||
665 | err_intfclk: | ||
666 | clk_put(hdq_data->hdq_ick); | ||
667 | clk_put(hdq_data->hdq_fck); | ||
668 | |||
669 | err_clk: | ||
670 | iounmap(hdq_data->hdq_base); | ||
671 | |||
672 | err_ioremap: | ||
673 | err_resource: | ||
674 | platform_set_drvdata(pdev, NULL); | ||
675 | kfree(hdq_data); | ||
676 | |||
677 | err_kmalloc: | ||
678 | return ret; | ||
679 | |||
680 | } | ||
681 | |||
682 | static int omap_hdq_remove(struct platform_device *pdev) | ||
683 | { | ||
684 | struct hdq_data *hdq_data = platform_get_drvdata(pdev); | ||
685 | |||
686 | mutex_lock(&hdq_data->hdq_mutex); | ||
687 | |||
688 | if (hdq_data->hdq_usecount) { | ||
689 | dev_dbg(&pdev->dev, "removed when use count is not zero\n"); | ||
690 | return -EBUSY; | ||
691 | } | ||
692 | |||
693 | mutex_unlock(&hdq_data->hdq_mutex); | ||
694 | |||
695 | /* remove module dependency */ | ||
696 | clk_put(hdq_data->hdq_ick); | ||
697 | clk_put(hdq_data->hdq_fck); | ||
698 | free_irq(INT_24XX_HDQ_IRQ, hdq_data); | ||
699 | platform_set_drvdata(pdev, NULL); | ||
700 | iounmap(hdq_data->hdq_base); | ||
701 | kfree(hdq_data); | ||
702 | |||
703 | return 0; | ||
704 | } | ||
705 | |||
706 | static int __init | ||
707 | omap_hdq_init(void) | ||
708 | { | ||
709 | return platform_driver_register(&omap_hdq_driver); | ||
710 | } | ||
711 | module_init(omap_hdq_init); | ||
712 | |||
713 | static void __exit | ||
714 | omap_hdq_exit(void) | ||
715 | { | ||
716 | platform_driver_unregister(&omap_hdq_driver); | ||
717 | } | ||
718 | module_exit(omap_hdq_exit); | ||
719 | |||
720 | module_param(w1_id, int, S_IRUSR); | ||
721 | MODULE_PARM_DESC(w1_id, "1-wire id for the slave detection"); | ||
722 | |||
723 | MODULE_AUTHOR("Texas Instruments"); | ||
724 | MODULE_DESCRIPTION("HDQ driver Library"); | ||
725 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig index 3df29a122f84..8d0b1fb1e52e 100644 --- a/drivers/w1/slaves/Kconfig +++ b/drivers/w1/slaves/Kconfig | |||
@@ -44,4 +44,11 @@ config W1_SLAVE_DS2760 | |||
44 | 44 | ||
45 | If you are unsure, say N. | 45 | If you are unsure, say N. |
46 | 46 | ||
47 | config W1_SLAVE_BQ27000 | ||
48 | tristate "BQ27000 slave support" | ||
49 | depends on W1 | ||
50 | help | ||
51 | Say Y here if you want to use a hdq | ||
52 | bq27000 slave support. | ||
53 | |||
47 | endmenu | 54 | endmenu |
diff --git a/drivers/w1/slaves/Makefile b/drivers/w1/slaves/Makefile index a8eb7524df1d..990f400b6d22 100644 --- a/drivers/w1/slaves/Makefile +++ b/drivers/w1/slaves/Makefile | |||
@@ -6,4 +6,4 @@ obj-$(CONFIG_W1_SLAVE_THERM) += w1_therm.o | |||
6 | obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o | 6 | obj-$(CONFIG_W1_SLAVE_SMEM) += w1_smem.o |
7 | obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o | 7 | obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o |
8 | obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o | 8 | obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o |
9 | 9 | obj-$(CONFIG_W1_SLAVE_BQ27000) += w1_bq27000.o | |
diff --git a/drivers/w1/slaves/w1_bq27000.c b/drivers/w1/slaves/w1_bq27000.c new file mode 100644 index 000000000000..8f4c91f6c680 --- /dev/null +++ b/drivers/w1/slaves/w1_bq27000.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * drivers/w1/slaves/w1_bq27000.c | ||
3 | * | ||
4 | * Copyright (C) 2007 Texas Instruments, Inc. | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public License | ||
7 | * version 2. This program is licensed "as is" without any warranty of any | ||
8 | * kind, whether express or implied. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/mutex.h> | ||
18 | |||
19 | #include "../w1.h" | ||
20 | #include "../w1_int.h" | ||
21 | #include "../w1_family.h" | ||
22 | |||
23 | #define HDQ_CMD_READ (0) | ||
24 | #define HDQ_CMD_WRITE (1<<7) | ||
25 | |||
26 | static int F_ID; | ||
27 | |||
28 | void w1_bq27000_write(struct device *dev, u8 buf, u8 reg) | ||
29 | { | ||
30 | struct w1_slave *sl = container_of(dev, struct w1_slave, dev); | ||
31 | |||
32 | if (!dev) { | ||
33 | pr_info("Could not obtain slave dev ptr\n"); | ||
34 | return; | ||
35 | } | ||
36 | |||
37 | w1_write_8(sl->master, HDQ_CMD_WRITE | reg); | ||
38 | w1_write_8(sl->master, buf); | ||
39 | } | ||
40 | EXPORT_SYMBOL(w1_bq27000_write); | ||
41 | |||
42 | int w1_bq27000_read(struct device *dev, u8 reg) | ||
43 | { | ||
44 | u8 val; | ||
45 | struct w1_slave *sl = container_of(dev, struct w1_slave, dev); | ||
46 | |||
47 | if (!dev) | ||
48 | return 0; | ||
49 | |||
50 | w1_write_8(sl->master, HDQ_CMD_READ | reg); | ||
51 | val = w1_read_8(sl->master); | ||
52 | |||
53 | return val; | ||
54 | } | ||
55 | EXPORT_SYMBOL(w1_bq27000_read); | ||
56 | |||
57 | static int w1_bq27000_add_slave(struct w1_slave *sl) | ||
58 | { | ||
59 | int ret; | ||
60 | int id = 1; | ||
61 | struct platform_device *pdev; | ||
62 | |||
63 | pdev = platform_device_alloc("bq27000-battery", id); | ||
64 | if (!pdev) { | ||
65 | ret = -ENOMEM; | ||
66 | return ret; | ||
67 | } | ||
68 | pdev->dev.parent = &sl->dev; | ||
69 | |||
70 | ret = platform_device_add(pdev); | ||
71 | if (ret) | ||
72 | goto pdev_add_failed; | ||
73 | |||
74 | dev_set_drvdata(&sl->dev, pdev); | ||
75 | |||
76 | goto success; | ||
77 | |||
78 | pdev_add_failed: | ||
79 | platform_device_unregister(pdev); | ||
80 | success: | ||
81 | return ret; | ||
82 | } | ||
83 | |||
84 | static void w1_bq27000_remove_slave(struct w1_slave *sl) | ||
85 | { | ||
86 | struct platform_device *pdev = dev_get_drvdata(&sl->dev); | ||
87 | |||
88 | platform_device_unregister(pdev); | ||
89 | } | ||
90 | |||
91 | static struct w1_family_ops w1_bq27000_fops = { | ||
92 | .add_slave = w1_bq27000_add_slave, | ||
93 | .remove_slave = w1_bq27000_remove_slave, | ||
94 | }; | ||
95 | |||
96 | static struct w1_family w1_bq27000_family = { | ||
97 | .fid = 1, | ||
98 | .fops = &w1_bq27000_fops, | ||
99 | }; | ||
100 | |||
101 | static int __init w1_bq27000_init(void) | ||
102 | { | ||
103 | if (F_ID) | ||
104 | w1_bq27000_family.fid = F_ID; | ||
105 | |||
106 | return w1_register_family(&w1_bq27000_family); | ||
107 | } | ||
108 | |||
109 | static void __exit w1_bq27000_exit(void) | ||
110 | { | ||
111 | w1_unregister_family(&w1_bq27000_family); | ||
112 | } | ||
113 | |||
114 | |||
115 | module_init(w1_bq27000_init); | ||
116 | module_exit(w1_bq27000_exit); | ||
117 | |||
118 | module_param(F_ID, int, S_IRUSR); | ||
119 | MODULE_PARM_DESC(F_ID, "1-wire slave FID for BQ device"); | ||
120 | |||
121 | MODULE_LICENSE("GPL"); | ||
122 | MODULE_AUTHOR("Texas Instruments Ltd"); | ||
123 | MODULE_DESCRIPTION("HDQ/1-wire slave driver bq27000 battery monitor chip"); | ||
diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h index cdaa6fffbfc7..97304bd83ec9 100644 --- a/drivers/w1/w1.h +++ b/drivers/w1/w1.h | |||
@@ -206,6 +206,7 @@ void w1_slave_detach(struct w1_slave *sl); | |||
206 | 206 | ||
207 | u8 w1_triplet(struct w1_master *dev, int bdir); | 207 | u8 w1_triplet(struct w1_master *dev, int bdir); |
208 | void w1_write_8(struct w1_master *, u8); | 208 | void w1_write_8(struct w1_master *, u8); |
209 | u8 w1_read_8(struct w1_master *); | ||
209 | int w1_reset_bus(struct w1_master *); | 210 | int w1_reset_bus(struct w1_master *); |
210 | u8 w1_calc_crc8(u8 *, int); | 211 | u8 w1_calc_crc8(u8 *, int); |
211 | void w1_write_block(struct w1_master *, const u8 *, int); | 212 | void w1_write_block(struct w1_master *, const u8 *, int); |
diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c index f4f82f1f486e..0d15b0eaf79a 100644 --- a/drivers/w1/w1_io.c +++ b/drivers/w1/w1_io.c | |||
@@ -217,7 +217,7 @@ u8 w1_triplet(struct w1_master *dev, int bdir) | |||
217 | * @param dev the master device | 217 | * @param dev the master device |
218 | * @return the byte read | 218 | * @return the byte read |
219 | */ | 219 | */ |
220 | static u8 w1_read_8(struct w1_master * dev) | 220 | u8 w1_read_8(struct w1_master *dev) |
221 | { | 221 | { |
222 | int i; | 222 | int i; |
223 | u8 res = 0; | 223 | u8 res = 0; |
@@ -230,6 +230,7 @@ static u8 w1_read_8(struct w1_master * dev) | |||
230 | 230 | ||
231 | return res; | 231 | return res; |
232 | } | 232 | } |
233 | EXPORT_SYMBOL_GPL(w1_read_8); | ||
233 | 234 | ||
234 | /** | 235 | /** |
235 | * Writes a series of bytes. | 236 | * Writes a series of bytes. |
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 1a22fe782a27..4fd3fa5546b1 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -67,11 +67,11 @@ config AT91RM9200_WATCHDOG | |||
67 | system when the timeout is reached. | 67 | system when the timeout is reached. |
68 | 68 | ||
69 | config AT91SAM9X_WATCHDOG | 69 | config AT91SAM9X_WATCHDOG |
70 | tristate "AT91SAM9X watchdog" | 70 | tristate "AT91SAM9X / AT91CAP9 watchdog" |
71 | depends on WATCHDOG && (ARCH_AT91SAM9260 || ARCH_AT91SAM9261) | 71 | depends on ARCH_AT91 && !ARCH_AT91RM9200 |
72 | help | 72 | help |
73 | Watchdog timer embedded into AT91SAM9X chips. This will reboot your | 73 | Watchdog timer embedded into AT91SAM9X and AT91CAP9 chips. This will |
74 | system when the timeout is reached. | 74 | reboot your system when the timeout is reached. |
75 | 75 | ||
76 | config 21285_WATCHDOG | 76 | config 21285_WATCHDOG |
77 | tristate "DC21285 watchdog" | 77 | tristate "DC21285 watchdog" |
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index b4babfc31586..b1da287f90ec 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <linux/bitops.h> | 30 | #include <linux/bitops.h> |
31 | #include <linux/uaccess.h> | 31 | #include <linux/uaccess.h> |
32 | 32 | ||
33 | #include <asm/arch/at91_wdt.h> | 33 | #include <mach/at91_wdt.h> |
34 | 34 | ||
35 | #define DRV_NAME "AT91SAM9 Watchdog" | 35 | #define DRV_NAME "AT91SAM9 Watchdog" |
36 | 36 | ||
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c index c3b78a76f173..225398fd5049 100644 --- a/drivers/watchdog/booke_wdt.c +++ b/drivers/watchdog/booke_wdt.c | |||
@@ -42,8 +42,10 @@ u32 booke_wdt_period = WDT_PERIOD_DEFAULT; | |||
42 | 42 | ||
43 | #ifdef CONFIG_FSL_BOOKE | 43 | #ifdef CONFIG_FSL_BOOKE |
44 | #define WDTP(x) ((((63-x)&0x3)<<30)|(((63-x)&0x3c)<<15)) | 44 | #define WDTP(x) ((((63-x)&0x3)<<30)|(((63-x)&0x3c)<<15)) |
45 | #define WDTP_MASK (WDTP(0)) | ||
45 | #else | 46 | #else |
46 | #define WDTP(x) (TCR_WP(x)) | 47 | #define WDTP(x) (TCR_WP(x)) |
48 | #define WDTP_MASK (TCR_WP_MASK) | ||
47 | #endif | 49 | #endif |
48 | 50 | ||
49 | static DEFINE_SPINLOCK(booke_wdt_lock); | 51 | static DEFINE_SPINLOCK(booke_wdt_lock); |
@@ -65,6 +67,7 @@ static void __booke_wdt_enable(void *data) | |||
65 | /* clear status before enabling watchdog */ | 67 | /* clear status before enabling watchdog */ |
66 | __booke_wdt_ping(NULL); | 68 | __booke_wdt_ping(NULL); |
67 | val = mfspr(SPRN_TCR); | 69 | val = mfspr(SPRN_TCR); |
70 | val &= ~WDTP_MASK; | ||
68 | val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period)); | 71 | val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period)); |
69 | 72 | ||
70 | mtspr(SPRN_TCR, val); | 73 | mtspr(SPRN_TCR, val); |
@@ -114,7 +117,7 @@ static long booke_wdt_ioctl(struct file *file, | |||
114 | case WDIOC_SETTIMEOUT: | 117 | case WDIOC_SETTIMEOUT: |
115 | if (get_user(booke_wdt_period, p)) | 118 | if (get_user(booke_wdt_period, p)) |
116 | return -EFAULT; | 119 | return -EFAULT; |
117 | mtspr(SPRN_TCR, (mfspr(SPRN_TCR) & ~WDTP(0)) | | 120 | mtspr(SPRN_TCR, (mfspr(SPRN_TCR) & ~WDTP_MASK) | |
118 | WDTP(booke_wdt_period)); | 121 | WDTP(booke_wdt_period)); |
119 | return 0; | 122 | return 0; |
120 | case WDIOC_GETTIMEOUT: | 123 | case WDIOC_GETTIMEOUT: |