diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2008-10-22 14:34:09 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-10-22 14:34:09 -0400 |
commit | f20e3b5fe7ead0615309433260b9784d8da0bbbd (patch) | |
tree | eabb2e47a0355ac4e8024b7087b4e7cb9f324358 /drivers | |
parent | bcbfe664e7af019e698cef2feb85ac2b4f1ac11d (diff) | |
parent | f030d7b65e4e6399f23de2a41a58d1b607b6bd89 (diff) |
Merge branch 'for-rmk' of git://git.android.com/kernel into devel
Diffstat (limited to 'drivers')
271 files changed, 11158 insertions, 4476 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index b1c723f9f58d..70f7f60929ca 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -431,7 +431,7 @@ static ssize_t acpi_battery_alarm_store(struct device *dev, | |||
431 | } | 431 | } |
432 | 432 | ||
433 | static struct device_attribute alarm_attr = { | 433 | static struct device_attribute alarm_attr = { |
434 | .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE}, | 434 | .attr = {.name = "alarm", .mode = 0644}, |
435 | .show = acpi_battery_alarm_show, | 435 | .show = acpi_battery_alarm_show, |
436 | .store = acpi_battery_alarm_store, | 436 | .store = acpi_battery_alarm_store, |
437 | }; | 437 | }; |
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 10a36512647c..7b011e7e29fe 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
@@ -463,7 +463,7 @@ static ssize_t acpi_battery_alarm_store(struct device *dev, | |||
463 | } | 463 | } |
464 | 464 | ||
465 | static struct device_attribute alarm_attr = { | 465 | static struct device_attribute alarm_attr = { |
466 | .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE}, | 466 | .attr = {.name = "alarm", .mode = 0644}, |
467 | .show = acpi_battery_alarm_show, | 467 | .show = acpi_battery_alarm_show, |
468 | .store = acpi_battery_alarm_store, | 468 | .store = acpi_battery_alarm_store, |
469 | }; | 469 | }; |
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c index bf5b04de02d1..631ee2ee2ca0 100644 --- a/drivers/acpi/sleep/proc.c +++ b/drivers/acpi/sleep/proc.c | |||
@@ -120,13 +120,13 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) | |||
120 | spin_unlock_irqrestore(&rtc_lock, flags); | 120 | spin_unlock_irqrestore(&rtc_lock, flags); |
121 | 121 | ||
122 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { | 122 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { |
123 | BCD_TO_BIN(sec); | 123 | sec = bcd2bin(sec); |
124 | BCD_TO_BIN(min); | 124 | min = bcd2bin(min); |
125 | BCD_TO_BIN(hr); | 125 | hr = bcd2bin(hr); |
126 | BCD_TO_BIN(day); | 126 | day = bcd2bin(day); |
127 | BCD_TO_BIN(mo); | 127 | mo = bcd2bin(mo); |
128 | BCD_TO_BIN(yr); | 128 | yr = bcd2bin(yr); |
129 | BCD_TO_BIN(cent); | 129 | cent = bcd2bin(cent); |
130 | } | 130 | } |
131 | 131 | ||
132 | /* we're trusting the FADT (see above) */ | 132 | /* we're trusting the FADT (see above) */ |
@@ -204,7 +204,7 @@ static u32 cmos_bcd_read(int offset, int rtc_control) | |||
204 | { | 204 | { |
205 | u32 val = CMOS_READ(offset); | 205 | u32 val = CMOS_READ(offset); |
206 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) | 206 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) |
207 | BCD_TO_BIN(val); | 207 | val = bcd2bin(val); |
208 | return val; | 208 | return val; |
209 | } | 209 | } |
210 | 210 | ||
@@ -212,7 +212,7 @@ static u32 cmos_bcd_read(int offset, int rtc_control) | |||
212 | static void cmos_bcd_write(u32 val, int offset, int rtc_control) | 212 | static void cmos_bcd_write(u32 val, int offset, int rtc_control) |
213 | { | 213 | { |
214 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) | 214 | if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) |
215 | BIN_TO_BCD(val); | 215 | val = bin2bcd(val); |
216 | CMOS_WRITE(val, offset); | 216 | CMOS_WRITE(val, offset); |
217 | } | 217 | } |
218 | 218 | ||
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 91dec448b3ed..24e80fd927e2 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c | |||
@@ -115,7 +115,6 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr, | |||
115 | table_attr->attr.read = acpi_table_show; | 115 | table_attr->attr.read = acpi_table_show; |
116 | table_attr->attr.attr.name = table_attr->name; | 116 | table_attr->attr.attr.name = table_attr->name; |
117 | table_attr->attr.attr.mode = 0444; | 117 | table_attr->attr.attr.mode = 0444; |
118 | table_attr->attr.attr.owner = THIS_MODULE; | ||
119 | 118 | ||
120 | return; | 119 | return; |
121 | } | 120 | } |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index af0d175c025d..5260e9e0df48 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <linux/memory_hotplug.h> | 21 | #include <linux/memory_hotplug.h> |
22 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
23 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
24 | #include <linux/stat.h> | ||
25 | |||
24 | #include <asm/atomic.h> | 26 | #include <asm/atomic.h> |
25 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
26 | 28 | ||
@@ -325,7 +327,7 @@ memory_probe_store(struct class *class, const char *buf, size_t count) | |||
325 | 327 | ||
326 | return count; | 328 | return count; |
327 | } | 329 | } |
328 | static CLASS_ATTR(probe, 0700, NULL, memory_probe_store); | 330 | static CLASS_ATTR(probe, S_IWUSR, NULL, memory_probe_store); |
329 | 331 | ||
330 | static int memory_probe_init(void) | 332 | static int memory_probe_init(void) |
331 | { | 333 | { |
diff --git a/drivers/base/node.c b/drivers/base/node.c index 5116b78c6325..f5207090885a 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/nodemask.h> | 13 | #include <linux/nodemask.h> |
14 | #include <linux/cpu.h> | 14 | #include <linux/cpu.h> |
15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
16 | #include <linux/swap.h> | ||
16 | 17 | ||
17 | static struct sysdev_class node_class = { | 18 | static struct sysdev_class node_class = { |
18 | .name = "node", | 19 | .name = "node", |
@@ -61,34 +62,52 @@ static ssize_t node_read_meminfo(struct sys_device * dev, | |||
61 | si_meminfo_node(&i, nid); | 62 | si_meminfo_node(&i, nid); |
62 | 63 | ||
63 | n = sprintf(buf, "\n" | 64 | n = sprintf(buf, "\n" |
64 | "Node %d MemTotal: %8lu kB\n" | 65 | "Node %d MemTotal: %8lu kB\n" |
65 | "Node %d MemFree: %8lu kB\n" | 66 | "Node %d MemFree: %8lu kB\n" |
66 | "Node %d MemUsed: %8lu kB\n" | 67 | "Node %d MemUsed: %8lu kB\n" |
67 | "Node %d Active: %8lu kB\n" | 68 | "Node %d Active: %8lu kB\n" |
68 | "Node %d Inactive: %8lu kB\n" | 69 | "Node %d Inactive: %8lu kB\n" |
70 | "Node %d Active(anon): %8lu kB\n" | ||
71 | "Node %d Inactive(anon): %8lu kB\n" | ||
72 | "Node %d Active(file): %8lu kB\n" | ||
73 | "Node %d Inactive(file): %8lu kB\n" | ||
74 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
75 | "Node %d Unevictable: %8lu kB\n" | ||
76 | "Node %d Mlocked: %8lu kB\n" | ||
77 | #endif | ||
69 | #ifdef CONFIG_HIGHMEM | 78 | #ifdef CONFIG_HIGHMEM |
70 | "Node %d HighTotal: %8lu kB\n" | 79 | "Node %d HighTotal: %8lu kB\n" |
71 | "Node %d HighFree: %8lu kB\n" | 80 | "Node %d HighFree: %8lu kB\n" |
72 | "Node %d LowTotal: %8lu kB\n" | 81 | "Node %d LowTotal: %8lu kB\n" |
73 | "Node %d LowFree: %8lu kB\n" | 82 | "Node %d LowFree: %8lu kB\n" |
74 | #endif | 83 | #endif |
75 | "Node %d Dirty: %8lu kB\n" | 84 | "Node %d Dirty: %8lu kB\n" |
76 | "Node %d Writeback: %8lu kB\n" | 85 | "Node %d Writeback: %8lu kB\n" |
77 | "Node %d FilePages: %8lu kB\n" | 86 | "Node %d FilePages: %8lu kB\n" |
78 | "Node %d Mapped: %8lu kB\n" | 87 | "Node %d Mapped: %8lu kB\n" |
79 | "Node %d AnonPages: %8lu kB\n" | 88 | "Node %d AnonPages: %8lu kB\n" |
80 | "Node %d PageTables: %8lu kB\n" | 89 | "Node %d PageTables: %8lu kB\n" |
81 | "Node %d NFS_Unstable: %8lu kB\n" | 90 | "Node %d NFS_Unstable: %8lu kB\n" |
82 | "Node %d Bounce: %8lu kB\n" | 91 | "Node %d Bounce: %8lu kB\n" |
83 | "Node %d WritebackTmp: %8lu kB\n" | 92 | "Node %d WritebackTmp: %8lu kB\n" |
84 | "Node %d Slab: %8lu kB\n" | 93 | "Node %d Slab: %8lu kB\n" |
85 | "Node %d SReclaimable: %8lu kB\n" | 94 | "Node %d SReclaimable: %8lu kB\n" |
86 | "Node %d SUnreclaim: %8lu kB\n", | 95 | "Node %d SUnreclaim: %8lu kB\n", |
87 | nid, K(i.totalram), | 96 | nid, K(i.totalram), |
88 | nid, K(i.freeram), | 97 | nid, K(i.freeram), |
89 | nid, K(i.totalram - i.freeram), | 98 | nid, K(i.totalram - i.freeram), |
90 | nid, K(node_page_state(nid, NR_ACTIVE)), | 99 | nid, K(node_page_state(nid, NR_ACTIVE_ANON) + |
91 | nid, K(node_page_state(nid, NR_INACTIVE)), | 100 | node_page_state(nid, NR_ACTIVE_FILE)), |
101 | nid, K(node_page_state(nid, NR_INACTIVE_ANON) + | ||
102 | node_page_state(nid, NR_INACTIVE_FILE)), | ||
103 | nid, K(node_page_state(nid, NR_ACTIVE_ANON)), | ||
104 | nid, K(node_page_state(nid, NR_INACTIVE_ANON)), | ||
105 | nid, K(node_page_state(nid, NR_ACTIVE_FILE)), | ||
106 | nid, K(node_page_state(nid, NR_INACTIVE_FILE)), | ||
107 | #ifdef CONFIG_UNEVICTABLE_LRU | ||
108 | nid, K(node_page_state(nid, NR_UNEVICTABLE)), | ||
109 | nid, K(node_page_state(nid, NR_MLOCK)), | ||
110 | #endif | ||
92 | #ifdef CONFIG_HIGHMEM | 111 | #ifdef CONFIG_HIGHMEM |
93 | nid, K(i.totalhigh), | 112 | nid, K(i.totalhigh), |
94 | nid, K(i.freehigh), | 113 | nid, K(i.freehigh), |
@@ -173,6 +192,8 @@ int register_node(struct node *node, int num, struct node *parent) | |||
173 | sysdev_create_file(&node->sysdev, &attr_meminfo); | 192 | sysdev_create_file(&node->sysdev, &attr_meminfo); |
174 | sysdev_create_file(&node->sysdev, &attr_numastat); | 193 | sysdev_create_file(&node->sysdev, &attr_numastat); |
175 | sysdev_create_file(&node->sysdev, &attr_distance); | 194 | sysdev_create_file(&node->sysdev, &attr_distance); |
195 | |||
196 | scan_unevictable_register_node(node); | ||
176 | } | 197 | } |
177 | return error; | 198 | return error; |
178 | } | 199 | } |
@@ -192,6 +213,8 @@ void unregister_node(struct node *node) | |||
192 | sysdev_remove_file(&node->sysdev, &attr_numastat); | 213 | sysdev_remove_file(&node->sysdev, &attr_numastat); |
193 | sysdev_remove_file(&node->sysdev, &attr_distance); | 214 | sysdev_remove_file(&node->sysdev, &attr_distance); |
194 | 215 | ||
216 | scan_unevictable_unregister_node(node); | ||
217 | |||
195 | sysdev_unregister(&node->sysdev); | 218 | sysdev_unregister(&node->sysdev); |
196 | } | 219 | } |
197 | 220 | ||
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index b82654e883a7..d876ad861237 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c | |||
@@ -90,7 +90,7 @@ static DEVICE_ATTR(state, S_IRUGO, aoedisk_show_state, NULL); | |||
90 | static DEVICE_ATTR(mac, S_IRUGO, aoedisk_show_mac, NULL); | 90 | static DEVICE_ATTR(mac, S_IRUGO, aoedisk_show_mac, NULL); |
91 | static DEVICE_ATTR(netif, S_IRUGO, aoedisk_show_netif, NULL); | 91 | static DEVICE_ATTR(netif, S_IRUGO, aoedisk_show_netif, NULL); |
92 | static struct device_attribute dev_attr_firmware_version = { | 92 | static struct device_attribute dev_attr_firmware_version = { |
93 | .attr = { .name = "firmware-version", .mode = S_IRUGO, .owner = THIS_MODULE }, | 93 | .attr = { .name = "firmware-version", .mode = S_IRUGO }, |
94 | .show = aoedisk_show_fwver, | 94 | .show = aoedisk_show_fwver, |
95 | }; | 95 | }; |
96 | 96 | ||
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 7b3351260d56..9034ca585afd 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c | |||
@@ -391,7 +391,7 @@ static ssize_t pid_show(struct device *dev, | |||
391 | } | 391 | } |
392 | 392 | ||
393 | static struct device_attribute pid_attr = { | 393 | static struct device_attribute pid_attr = { |
394 | .attr = { .name = "pid", .mode = S_IRUGO, .owner = THIS_MODULE }, | 394 | .attr = { .name = "pid", .mode = S_IRUGO}, |
395 | .show = pid_show, | 395 | .show = pid_show, |
396 | }; | 396 | }; |
397 | 397 | ||
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index 31dcd9142d54..dc8d1a90971f 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c | |||
@@ -417,6 +417,6 @@ static void __exit agp_ali_cleanup(void) | |||
417 | module_init(agp_ali_init); | 417 | module_init(agp_ali_init); |
418 | module_exit(agp_ali_cleanup); | 418 | module_exit(agp_ali_cleanup); |
419 | 419 | ||
420 | MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>"); | 420 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); |
421 | MODULE_LICENSE("GPL and additional rights"); | 421 | MODULE_LICENSE("GPL and additional rights"); |
422 | 422 | ||
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 2812ee2b165a..52f4361eb6e4 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -772,6 +772,6 @@ module_init(agp_amd64_init); | |||
772 | module_exit(agp_amd64_cleanup); | 772 | module_exit(agp_amd64_cleanup); |
773 | #endif | 773 | #endif |
774 | 774 | ||
775 | MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>, Andi Kleen"); | 775 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>, Andi Kleen"); |
776 | module_param(agp_try_unsupported, bool, 0); | 776 | module_param(agp_try_unsupported, bool, 0); |
777 | MODULE_LICENSE("GPL"); | 777 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index ae2791b926b9..f1537eece07f 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c | |||
@@ -561,6 +561,6 @@ static void __exit agp_ati_cleanup(void) | |||
561 | module_init(agp_ati_init); | 561 | module_init(agp_ati_init); |
562 | module_exit(agp_ati_cleanup); | 562 | module_exit(agp_ati_cleanup); |
563 | 563 | ||
564 | MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>"); | 564 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); |
565 | MODULE_LICENSE("GPL and additional rights"); | 565 | MODULE_LICENSE("GPL and additional rights"); |
566 | 566 | ||
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index 3a3cc03d401c..8c617ad7497f 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c | |||
@@ -349,7 +349,7 @@ static __init int agp_setup(char *s) | |||
349 | __setup("agp=", agp_setup); | 349 | __setup("agp=", agp_setup); |
350 | #endif | 350 | #endif |
351 | 351 | ||
352 | MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>"); | 352 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); |
353 | MODULE_DESCRIPTION("AGP GART driver"); | 353 | MODULE_DESCRIPTION("AGP GART driver"); |
354 | MODULE_LICENSE("GPL and additional rights"); | 354 | MODULE_LICENSE("GPL and additional rights"); |
355 | MODULE_ALIAS_MISCDEV(AGPGART_MINOR); | 355 | MODULE_ALIAS_MISCDEV(AGPGART_MINOR); |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 1108665913e2..9cf6e9bb017e 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -2390,5 +2390,5 @@ static void __exit agp_intel_cleanup(void) | |||
2390 | module_init(agp_intel_init); | 2390 | module_init(agp_intel_init); |
2391 | module_exit(agp_intel_cleanup); | 2391 | module_exit(agp_intel_cleanup); |
2392 | 2392 | ||
2393 | MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>"); | 2393 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); |
2394 | MODULE_LICENSE("GPL and additional rights"); | 2394 | MODULE_LICENSE("GPL and additional rights"); |
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index 5bbed3d79db9..16acee2de117 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Nvidia AGPGART routines. | 2 | * Nvidia AGPGART routines. |
3 | * Based upon a 2.4 agpgart diff by the folks from NVIDIA, and hacked up | 3 | * Based upon a 2.4 agpgart diff by the folks from NVIDIA, and hacked up |
4 | * to work in 2.5 by Dave Jones <davej@codemonkey.org.uk> | 4 | * to work in 2.5 by Dave Jones <davej@redhat.com> |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c index f2492ecf0824..db60539bf67a 100644 --- a/drivers/char/agp/parisc-agp.c +++ b/drivers/char/agp/parisc-agp.c | |||
@@ -20,8 +20,8 @@ | |||
20 | #include <linux/agp_backend.h> | 20 | #include <linux/agp_backend.h> |
21 | #include <linux/log2.h> | 21 | #include <linux/log2.h> |
22 | 22 | ||
23 | #include <asm-parisc/parisc-device.h> | 23 | #include <asm/parisc-device.h> |
24 | #include <asm-parisc/ropes.h> | 24 | #include <asm/ropes.h> |
25 | 25 | ||
26 | #include "agp.h" | 26 | #include "agp.h" |
27 | 27 | ||
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c index 9f4d49e1b59a..d3bd243867fc 100644 --- a/drivers/char/agp/via-agp.c +++ b/drivers/char/agp/via-agp.c | |||
@@ -595,4 +595,4 @@ module_init(agp_via_init); | |||
595 | module_exit(agp_via_cleanup); | 595 | module_exit(agp_via_cleanup); |
596 | 596 | ||
597 | MODULE_LICENSE("GPL"); | 597 | MODULE_LICENSE("GPL"); |
598 | MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>"); | 598 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); |
diff --git a/drivers/char/ds1286.c b/drivers/char/ds1286.c index 5329d482b582..0a826d7be10e 100644 --- a/drivers/char/ds1286.c +++ b/drivers/char/ds1286.c | |||
@@ -210,8 +210,8 @@ static int ds1286_ioctl(struct inode *inode, struct file *file, | |||
210 | if (sec != 0) | 210 | if (sec != 0) |
211 | return -EINVAL; | 211 | return -EINVAL; |
212 | 212 | ||
213 | min = BIN2BCD(min); | 213 | min = bin2bcd(min); |
214 | min = BIN2BCD(hrs); | 214 | min = bin2bcd(hrs); |
215 | 215 | ||
216 | spin_lock(&ds1286_lock); | 216 | spin_lock(&ds1286_lock); |
217 | rtc_write(hrs, RTC_HOURS_ALARM); | 217 | rtc_write(hrs, RTC_HOURS_ALARM); |
@@ -353,7 +353,7 @@ static int ds1286_proc_output(char *buf) | |||
353 | 353 | ||
354 | ds1286_get_time(&tm); | 354 | ds1286_get_time(&tm); |
355 | hundredth = rtc_read(RTC_HUNDREDTH_SECOND); | 355 | hundredth = rtc_read(RTC_HUNDREDTH_SECOND); |
356 | BCD_TO_BIN(hundredth); | 356 | hundredth = bcd2bin(hundredth); |
357 | 357 | ||
358 | p += sprintf(p, | 358 | p += sprintf(p, |
359 | "rtc_time\t: %02d:%02d:%02d.%02d\n" | 359 | "rtc_time\t: %02d:%02d:%02d.%02d\n" |
@@ -477,12 +477,12 @@ static void ds1286_get_time(struct rtc_time *rtc_tm) | |||
477 | rtc_write(save_control, RTC_CMD); | 477 | rtc_write(save_control, RTC_CMD); |
478 | spin_unlock_irqrestore(&ds1286_lock, flags); | 478 | spin_unlock_irqrestore(&ds1286_lock, flags); |
479 | 479 | ||
480 | BCD_TO_BIN(rtc_tm->tm_sec); | 480 | rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec); |
481 | BCD_TO_BIN(rtc_tm->tm_min); | 481 | rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min); |
482 | BCD_TO_BIN(rtc_tm->tm_hour); | 482 | rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour); |
483 | BCD_TO_BIN(rtc_tm->tm_mday); | 483 | rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday); |
484 | BCD_TO_BIN(rtc_tm->tm_mon); | 484 | rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon); |
485 | BCD_TO_BIN(rtc_tm->tm_year); | 485 | rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year); |
486 | 486 | ||
487 | /* | 487 | /* |
488 | * Account for differences between how the RTC uses the values | 488 | * Account for differences between how the RTC uses the values |
@@ -531,12 +531,12 @@ static int ds1286_set_time(struct rtc_time *rtc_tm) | |||
531 | if (yrs >= 100) | 531 | if (yrs >= 100) |
532 | yrs -= 100; | 532 | yrs -= 100; |
533 | 533 | ||
534 | BIN_TO_BCD(sec); | 534 | sec = bin2bcd(sec); |
535 | BIN_TO_BCD(min); | 535 | min = bin2bcd(min); |
536 | BIN_TO_BCD(hrs); | 536 | hrs = bin2bcd(hrs); |
537 | BIN_TO_BCD(day); | 537 | day = bin2bcd(day); |
538 | BIN_TO_BCD(mon); | 538 | mon = bin2bcd(mon); |
539 | BIN_TO_BCD(yrs); | 539 | yrs = bin2bcd(yrs); |
540 | 540 | ||
541 | spin_lock_irqsave(&ds1286_lock, flags); | 541 | spin_lock_irqsave(&ds1286_lock, flags); |
542 | save_control = rtc_read(RTC_CMD); | 542 | save_control = rtc_read(RTC_CMD); |
@@ -572,8 +572,8 @@ static void ds1286_get_alm_time(struct rtc_time *alm_tm) | |||
572 | cmd = rtc_read(RTC_CMD); | 572 | cmd = rtc_read(RTC_CMD); |
573 | spin_unlock_irqrestore(&ds1286_lock, flags); | 573 | spin_unlock_irqrestore(&ds1286_lock, flags); |
574 | 574 | ||
575 | BCD_TO_BIN(alm_tm->tm_min); | 575 | alm_tm->tm_min = bcd2bin(alm_tm->tm_min); |
576 | BCD_TO_BIN(alm_tm->tm_hour); | 576 | alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour); |
577 | alm_tm->tm_sec = 0; | 577 | alm_tm->tm_sec = 0; |
578 | } | 578 | } |
579 | 579 | ||
diff --git a/drivers/char/ds1302.c b/drivers/char/ds1302.c index c5e67a623951..170693c93c73 100644 --- a/drivers/char/ds1302.c +++ b/drivers/char/ds1302.c | |||
@@ -131,12 +131,12 @@ get_rtc_time(struct rtc_time *rtc_tm) | |||
131 | 131 | ||
132 | local_irq_restore(flags); | 132 | local_irq_restore(flags); |
133 | 133 | ||
134 | BCD_TO_BIN(rtc_tm->tm_sec); | 134 | rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec); |
135 | BCD_TO_BIN(rtc_tm->tm_min); | 135 | rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min); |
136 | BCD_TO_BIN(rtc_tm->tm_hour); | 136 | rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour); |
137 | BCD_TO_BIN(rtc_tm->tm_mday); | 137 | rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday); |
138 | BCD_TO_BIN(rtc_tm->tm_mon); | 138 | rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon); |
139 | BCD_TO_BIN(rtc_tm->tm_year); | 139 | rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year); |
140 | 140 | ||
141 | /* | 141 | /* |
142 | * Account for differences between how the RTC uses the values | 142 | * Account for differences between how the RTC uses the values |
@@ -211,12 +211,12 @@ static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
211 | else | 211 | else |
212 | yrs -= 1900; /* RTC (70, 71, ... 99) */ | 212 | yrs -= 1900; /* RTC (70, 71, ... 99) */ |
213 | 213 | ||
214 | BIN_TO_BCD(sec); | 214 | sec = bin2bcd(sec); |
215 | BIN_TO_BCD(min); | 215 | min = bin2bcd(min); |
216 | BIN_TO_BCD(hrs); | 216 | hrs = bin2bcd(hrs); |
217 | BIN_TO_BCD(day); | 217 | day = bin2bcd(day); |
218 | BIN_TO_BCD(mon); | 218 | mon = bin2bcd(mon); |
219 | BIN_TO_BCD(yrs); | 219 | yrs = bin2bcd(yrs); |
220 | 220 | ||
221 | lock_kernel(); | 221 | lock_kernel(); |
222 | local_irq_save(flags); | 222 | local_irq_save(flags); |
diff --git a/drivers/char/epca.c b/drivers/char/epca.c index 4998b2761e8f..cf2461d34e5f 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c | |||
@@ -2477,7 +2477,11 @@ static int pc_send_break(struct tty_struct *tty, int msec) | |||
2477 | unsigned long flags; | 2477 | unsigned long flags; |
2478 | 2478 | ||
2479 | if (msec == -1) | 2479 | if (msec == -1) |
2480 | return -EOPNOTSUPP; | 2480 | msec = 0xFFFF; |
2481 | else if (msec > 0xFFFE) | ||
2482 | msec = 0xFFFE; | ||
2483 | else if (msec < 1) | ||
2484 | msec = 1; | ||
2481 | 2485 | ||
2482 | spin_lock_irqsave(&epca_lock, flags); | 2486 | spin_lock_irqsave(&epca_lock, flags); |
2483 | globalwinon(ch); | 2487 | globalwinon(ch); |
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index f3cfb4c76125..408f5f92cb4e 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -219,7 +219,7 @@ static void hpet_timer_set_irq(struct hpet_dev *devp) | |||
219 | for (irq = find_first_bit(&v, HPET_MAX_IRQ); irq < HPET_MAX_IRQ; | 219 | for (irq = find_first_bit(&v, HPET_MAX_IRQ); irq < HPET_MAX_IRQ; |
220 | irq = find_next_bit(&v, HPET_MAX_IRQ, 1 + irq)) { | 220 | irq = find_next_bit(&v, HPET_MAX_IRQ, 1 + irq)) { |
221 | 221 | ||
222 | if (irq >= NR_IRQS) { | 222 | if (irq >= nr_irqs) { |
223 | irq = HPET_MAX_IRQ; | 223 | irq = HPET_MAX_IRQ; |
224 | break; | 224 | break; |
225 | } | 225 | } |
diff --git a/drivers/char/ip27-rtc.c b/drivers/char/ip27-rtc.c index ec9d0443d92c..2abd881b4cbc 100644 --- a/drivers/char/ip27-rtc.c +++ b/drivers/char/ip27-rtc.c | |||
@@ -130,12 +130,12 @@ static long rtc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
130 | if (yrs >= 100) | 130 | if (yrs >= 100) |
131 | yrs -= 100; | 131 | yrs -= 100; |
132 | 132 | ||
133 | sec = BIN2BCD(sec); | 133 | sec = bin2bcd(sec); |
134 | min = BIN2BCD(min); | 134 | min = bin2bcd(min); |
135 | hrs = BIN2BCD(hrs); | 135 | hrs = bin2bcd(hrs); |
136 | day = BIN2BCD(day); | 136 | day = bin2bcd(day); |
137 | mon = BIN2BCD(mon); | 137 | mon = bin2bcd(mon); |
138 | yrs = BIN2BCD(yrs); | 138 | yrs = bin2bcd(yrs); |
139 | 139 | ||
140 | spin_lock_irq(&rtc_lock); | 140 | spin_lock_irq(&rtc_lock); |
141 | rtc->control |= M48T35_RTC_SET; | 141 | rtc->control |= M48T35_RTC_SET; |
@@ -311,12 +311,12 @@ static void get_rtc_time(struct rtc_time *rtc_tm) | |||
311 | rtc->control &= ~M48T35_RTC_READ; | 311 | rtc->control &= ~M48T35_RTC_READ; |
312 | spin_unlock_irq(&rtc_lock); | 312 | spin_unlock_irq(&rtc_lock); |
313 | 313 | ||
314 | rtc_tm->tm_sec = BCD2BIN(rtc_tm->tm_sec); | 314 | rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec); |
315 | rtc_tm->tm_min = BCD2BIN(rtc_tm->tm_min); | 315 | rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min); |
316 | rtc_tm->tm_hour = BCD2BIN(rtc_tm->tm_hour); | 316 | rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour); |
317 | rtc_tm->tm_mday = BCD2BIN(rtc_tm->tm_mday); | 317 | rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday); |
318 | rtc_tm->tm_mon = BCD2BIN(rtc_tm->tm_mon); | 318 | rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon); |
319 | rtc_tm->tm_year = BCD2BIN(rtc_tm->tm_year); | 319 | rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year); |
320 | 320 | ||
321 | /* | 321 | /* |
322 | * Account for differences between how the RTC uses the values | 322 | * Account for differences between how the RTC uses the values |
diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c index b930de50407a..3f7da8cf3a80 100644 --- a/drivers/char/pc8736x_gpio.c +++ b/drivers/char/pc8736x_gpio.c | |||
@@ -41,7 +41,8 @@ static u8 pc8736x_gpio_shadow[4]; | |||
41 | #define SIO_BASE2 0x4E /* alt command-reg to check */ | 41 | #define SIO_BASE2 0x4E /* alt command-reg to check */ |
42 | 42 | ||
43 | #define SIO_SID 0x20 /* SuperI/O ID Register */ | 43 | #define SIO_SID 0x20 /* SuperI/O ID Register */ |
44 | #define SIO_SID_VALUE 0xe9 /* Expected value in SuperI/O ID Register */ | 44 | #define SIO_SID_PC87365 0xe5 /* Expected value in ID Register for PC87365 */ |
45 | #define SIO_SID_PC87366 0xe9 /* Expected value in ID Register for PC87366 */ | ||
45 | 46 | ||
46 | #define SIO_CF1 0x21 /* chip config, bit0 is chip enable */ | 47 | #define SIO_CF1 0x21 /* chip config, bit0 is chip enable */ |
47 | 48 | ||
@@ -91,13 +92,17 @@ static inline int superio_inb(int addr) | |||
91 | 92 | ||
92 | static int pc8736x_superio_present(void) | 93 | static int pc8736x_superio_present(void) |
93 | { | 94 | { |
95 | int id; | ||
96 | |||
94 | /* try the 2 possible values, read a hardware reg to verify */ | 97 | /* try the 2 possible values, read a hardware reg to verify */ |
95 | superio_cmd = SIO_BASE1; | 98 | superio_cmd = SIO_BASE1; |
96 | if (superio_inb(SIO_SID) == SIO_SID_VALUE) | 99 | id = superio_inb(SIO_SID); |
100 | if (id == SIO_SID_PC87365 || id == SIO_SID_PC87366) | ||
97 | return superio_cmd; | 101 | return superio_cmd; |
98 | 102 | ||
99 | superio_cmd = SIO_BASE2; | 103 | superio_cmd = SIO_BASE2; |
100 | if (superio_inb(SIO_SID) == SIO_SID_VALUE) | 104 | id = superio_inb(SIO_SID); |
105 | if (id == SIO_SID_PC87365 || id == SIO_SID_PC87366) | ||
101 | return superio_cmd; | 106 | return superio_cmd; |
102 | 107 | ||
103 | return 0; | 108 | return 0; |
diff --git a/drivers/char/random.c b/drivers/char/random.c index c8752eaad483..705a839f1796 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -558,9 +558,26 @@ struct timer_rand_state { | |||
558 | unsigned dont_count_entropy:1; | 558 | unsigned dont_count_entropy:1; |
559 | }; | 559 | }; |
560 | 560 | ||
561 | static struct timer_rand_state input_timer_state; | ||
562 | static struct timer_rand_state *irq_timer_state[NR_IRQS]; | 561 | static struct timer_rand_state *irq_timer_state[NR_IRQS]; |
563 | 562 | ||
563 | static struct timer_rand_state *get_timer_rand_state(unsigned int irq) | ||
564 | { | ||
565 | if (irq >= nr_irqs) | ||
566 | return NULL; | ||
567 | |||
568 | return irq_timer_state[irq]; | ||
569 | } | ||
570 | |||
571 | static void set_timer_rand_state(unsigned int irq, struct timer_rand_state *state) | ||
572 | { | ||
573 | if (irq >= nr_irqs) | ||
574 | return; | ||
575 | |||
576 | irq_timer_state[irq] = state; | ||
577 | } | ||
578 | |||
579 | static struct timer_rand_state input_timer_state; | ||
580 | |||
564 | /* | 581 | /* |
565 | * This function adds entropy to the entropy "pool" by using timing | 582 | * This function adds entropy to the entropy "pool" by using timing |
566 | * delays. It uses the timer_rand_state structure to make an estimate | 583 | * delays. It uses the timer_rand_state structure to make an estimate |
@@ -648,11 +665,15 @@ EXPORT_SYMBOL_GPL(add_input_randomness); | |||
648 | 665 | ||
649 | void add_interrupt_randomness(int irq) | 666 | void add_interrupt_randomness(int irq) |
650 | { | 667 | { |
651 | if (irq >= NR_IRQS || irq_timer_state[irq] == NULL) | 668 | struct timer_rand_state *state; |
669 | |||
670 | state = get_timer_rand_state(irq); | ||
671 | |||
672 | if (state == NULL) | ||
652 | return; | 673 | return; |
653 | 674 | ||
654 | DEBUG_ENT("irq event %d\n", irq); | 675 | DEBUG_ENT("irq event %d\n", irq); |
655 | add_timer_randomness(irq_timer_state[irq], 0x100 + irq); | 676 | add_timer_randomness(state, 0x100 + irq); |
656 | } | 677 | } |
657 | 678 | ||
658 | #ifdef CONFIG_BLOCK | 679 | #ifdef CONFIG_BLOCK |
@@ -912,7 +933,12 @@ void rand_initialize_irq(int irq) | |||
912 | { | 933 | { |
913 | struct timer_rand_state *state; | 934 | struct timer_rand_state *state; |
914 | 935 | ||
915 | if (irq >= NR_IRQS || irq_timer_state[irq]) | 936 | if (irq >= nr_irqs) |
937 | return; | ||
938 | |||
939 | state = get_timer_rand_state(irq); | ||
940 | |||
941 | if (state) | ||
916 | return; | 942 | return; |
917 | 943 | ||
918 | /* | 944 | /* |
@@ -921,7 +947,7 @@ void rand_initialize_irq(int irq) | |||
921 | */ | 947 | */ |
922 | state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL); | 948 | state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL); |
923 | if (state) | 949 | if (state) |
924 | irq_timer_state[irq] = state; | 950 | set_timer_rand_state(irq, state); |
925 | } | 951 | } |
926 | 952 | ||
927 | #ifdef CONFIG_BLOCK | 953 | #ifdef CONFIG_BLOCK |
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index 17683de95717..32dc89720d58 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c | |||
@@ -518,17 +518,17 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
518 | if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || | 518 | if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || |
519 | RTC_ALWAYS_BCD) { | 519 | RTC_ALWAYS_BCD) { |
520 | if (sec < 60) | 520 | if (sec < 60) |
521 | BIN_TO_BCD(sec); | 521 | sec = bin2bcd(sec); |
522 | else | 522 | else |
523 | sec = 0xff; | 523 | sec = 0xff; |
524 | 524 | ||
525 | if (min < 60) | 525 | if (min < 60) |
526 | BIN_TO_BCD(min); | 526 | min = bin2bcd(min); |
527 | else | 527 | else |
528 | min = 0xff; | 528 | min = 0xff; |
529 | 529 | ||
530 | if (hrs < 24) | 530 | if (hrs < 24) |
531 | BIN_TO_BCD(hrs); | 531 | hrs = bin2bcd(hrs); |
532 | else | 532 | else |
533 | hrs = 0xff; | 533 | hrs = 0xff; |
534 | } | 534 | } |
@@ -614,12 +614,12 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) | |||
614 | 614 | ||
615 | if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) | 615 | if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) |
616 | || RTC_ALWAYS_BCD) { | 616 | || RTC_ALWAYS_BCD) { |
617 | BIN_TO_BCD(sec); | 617 | sec = bin2bcd(sec); |
618 | BIN_TO_BCD(min); | 618 | min = bin2bcd(min); |
619 | BIN_TO_BCD(hrs); | 619 | hrs = bin2bcd(hrs); |
620 | BIN_TO_BCD(day); | 620 | day = bin2bcd(day); |
621 | BIN_TO_BCD(mon); | 621 | mon = bin2bcd(mon); |
622 | BIN_TO_BCD(yrs); | 622 | yrs = bin2bcd(yrs); |
623 | } | 623 | } |
624 | 624 | ||
625 | save_control = CMOS_READ(RTC_CONTROL); | 625 | save_control = CMOS_READ(RTC_CONTROL); |
@@ -1099,7 +1099,7 @@ no_irq: | |||
1099 | spin_unlock_irq(&rtc_lock); | 1099 | spin_unlock_irq(&rtc_lock); |
1100 | 1100 | ||
1101 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) | 1101 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) |
1102 | BCD_TO_BIN(year); /* This should never happen... */ | 1102 | year = bcd2bin(year); /* This should never happen... */ |
1103 | 1103 | ||
1104 | if (year < 20) { | 1104 | if (year < 20) { |
1105 | epoch = 2000; | 1105 | epoch = 2000; |
@@ -1352,13 +1352,13 @@ static void rtc_get_rtc_time(struct rtc_time *rtc_tm) | |||
1352 | spin_unlock_irqrestore(&rtc_lock, flags); | 1352 | spin_unlock_irqrestore(&rtc_lock, flags); |
1353 | 1353 | ||
1354 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { | 1354 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { |
1355 | BCD_TO_BIN(rtc_tm->tm_sec); | 1355 | rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec); |
1356 | BCD_TO_BIN(rtc_tm->tm_min); | 1356 | rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min); |
1357 | BCD_TO_BIN(rtc_tm->tm_hour); | 1357 | rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour); |
1358 | BCD_TO_BIN(rtc_tm->tm_mday); | 1358 | rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday); |
1359 | BCD_TO_BIN(rtc_tm->tm_mon); | 1359 | rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon); |
1360 | BCD_TO_BIN(rtc_tm->tm_year); | 1360 | rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year); |
1361 | BCD_TO_BIN(rtc_tm->tm_wday); | 1361 | rtc_tm->tm_wday = bcd2bin(rtc_tm->tm_wday); |
1362 | } | 1362 | } |
1363 | 1363 | ||
1364 | #ifdef CONFIG_MACH_DECSTATION | 1364 | #ifdef CONFIG_MACH_DECSTATION |
@@ -1392,9 +1392,9 @@ static void get_rtc_alm_time(struct rtc_time *alm_tm) | |||
1392 | spin_unlock_irq(&rtc_lock); | 1392 | spin_unlock_irq(&rtc_lock); |
1393 | 1393 | ||
1394 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { | 1394 | if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { |
1395 | BCD_TO_BIN(alm_tm->tm_sec); | 1395 | alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec); |
1396 | BCD_TO_BIN(alm_tm->tm_min); | 1396 | alm_tm->tm_min = bcd2bin(alm_tm->tm_min); |
1397 | BCD_TO_BIN(alm_tm->tm_hour); | 1397 | alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour); |
1398 | } | 1398 | } |
1399 | } | 1399 | } |
1400 | 1400 | ||
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index 5b8d7a1aa3e6..ba4e86281fbf 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c | |||
@@ -2504,7 +2504,7 @@ static void __devexit sx_remove_card(struct sx_board *board, | |||
2504 | del_timer(&board->timer); | 2504 | del_timer(&board->timer); |
2505 | if (pdev) { | 2505 | if (pdev) { |
2506 | #ifdef CONFIG_PCI | 2506 | #ifdef CONFIG_PCI |
2507 | pci_iounmap(pdev, board->base2); | 2507 | iounmap(board->base2); |
2508 | pci_release_region(pdev, IS_CF_BOARD(board) ? 3 : 2); | 2508 | pci_release_region(pdev, IS_CF_BOARD(board) ? 3 : 2); |
2509 | #endif | 2509 | #endif |
2510 | } else { | 2510 | } else { |
@@ -2677,7 +2677,7 @@ static int __devinit sx_pci_probe(struct pci_dev *pdev, | |||
2677 | } | 2677 | } |
2678 | board->hw_base = pci_resource_start(pdev, reg); | 2678 | board->hw_base = pci_resource_start(pdev, reg); |
2679 | board->base2 = | 2679 | board->base2 = |
2680 | board->base = pci_iomap(pdev, reg, WINDOW_LEN(board)); | 2680 | board->base = ioremap_nocache(board->hw_base, WINDOW_LEN(board)); |
2681 | if (!board->base) { | 2681 | if (!board->base) { |
2682 | dev_err(&pdev->dev, "ioremap failed\n"); | 2682 | dev_err(&pdev->dev, "ioremap failed\n"); |
2683 | goto err_reg; | 2683 | goto err_reg; |
@@ -2703,7 +2703,7 @@ static int __devinit sx_pci_probe(struct pci_dev *pdev, | |||
2703 | 2703 | ||
2704 | return 0; | 2704 | return 0; |
2705 | err_unmap: | 2705 | err_unmap: |
2706 | pci_iounmap(pdev, board->base2); | 2706 | iounmap(board->base2); |
2707 | err_reg: | 2707 | err_reg: |
2708 | pci_release_region(pdev, reg); | 2708 | pci_release_region(pdev, reg); |
2709 | err_flag: | 2709 | err_flag: |
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index dce4cc0e6953..ce0d9da52a8a 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -168,7 +168,7 @@ static void sysrq_handle_show_timers(int key, struct tty_struct *tty) | |||
168 | static struct sysrq_key_op sysrq_show_timers_op = { | 168 | static struct sysrq_key_op sysrq_show_timers_op = { |
169 | .handler = sysrq_handle_show_timers, | 169 | .handler = sysrq_handle_show_timers, |
170 | .help_msg = "show-all-timers(Q)", | 170 | .help_msg = "show-all-timers(Q)", |
171 | .action_msg = "Show Pending Timers", | 171 | .action_msg = "Show clockevent devices & pending hrtimers (no others)", |
172 | }; | 172 | }; |
173 | 173 | ||
174 | static void sysrq_handle_mountro(int key, struct tty_struct *tty) | 174 | static void sysrq_handle_mountro(int key, struct tty_struct *tty) |
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index e70d13defde4..9c47dc48c9fd 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -1157,7 +1157,7 @@ EXPORT_SYMBOL_GPL(tpm_dev_vendor_release); | |||
1157 | * Once all references to platform device are down to 0, | 1157 | * Once all references to platform device are down to 0, |
1158 | * release all allocated structures. | 1158 | * release all allocated structures. |
1159 | */ | 1159 | */ |
1160 | static void tpm_dev_release(struct device *dev) | 1160 | void tpm_dev_release(struct device *dev) |
1161 | { | 1161 | { |
1162 | struct tpm_chip *chip = dev_get_drvdata(dev); | 1162 | struct tpm_chip *chip = dev_get_drvdata(dev); |
1163 | 1163 | ||
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c index ffe9b4e3072e..54c837288d19 100644 --- a/drivers/char/vr41xx_giu.c +++ b/drivers/char/vr41xx_giu.c | |||
@@ -641,7 +641,7 @@ static int __devinit giu_probe(struct platform_device *dev) | |||
641 | } | 641 | } |
642 | 642 | ||
643 | irq = platform_get_irq(dev, 0); | 643 | irq = platform_get_irq(dev, 0); |
644 | if (irq < 0 || irq >= NR_IRQS) | 644 | if (irq < 0 || irq >= nr_irqs) |
645 | return -EBUSY; | 645 | return -EBUSY; |
646 | 646 | ||
647 | return cascade_irq(irq, giu_get_irq); | 647 | return cascade_irq(irq, giu_get_irq); |
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index 71d2ac4e3f46..c20171078d1d 100644 --- a/drivers/clocksource/acpi_pm.c +++ b/drivers/clocksource/acpi_pm.c | |||
@@ -237,9 +237,12 @@ static int __init parse_pmtmr(char *arg) | |||
237 | 237 | ||
238 | if (strict_strtoul(arg, 16, &base)) | 238 | if (strict_strtoul(arg, 16, &base)) |
239 | return -EINVAL; | 239 | return -EINVAL; |
240 | 240 | #ifdef CONFIG_X86_64 | |
241 | if (base > UINT_MAX) | ||
242 | return -ERANGE; | ||
243 | #endif | ||
241 | printk(KERN_INFO "PMTMR IOPort override: 0x%04x -> 0x%04lx\n", | 244 | printk(KERN_INFO "PMTMR IOPort override: 0x%04x -> 0x%04lx\n", |
242 | (unsigned int)pmtmr_ioport, base); | 245 | pmtmr_ioport, base); |
243 | pmtmr_ioport = base; | 246 | pmtmr_ioport = base; |
244 | 247 | ||
245 | return 1; | 248 | return 1; |
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index cd303901eb5b..904e57558bb5 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig | |||
@@ -48,13 +48,13 @@ config DW_DMAC | |||
48 | can be integrated in chips such as the Atmel AT32ap7000. | 48 | can be integrated in chips such as the Atmel AT32ap7000. |
49 | 49 | ||
50 | config FSL_DMA | 50 | config FSL_DMA |
51 | bool "Freescale MPC85xx/MPC83xx DMA support" | 51 | tristate "Freescale Elo and Elo Plus DMA support" |
52 | depends on PPC | 52 | depends on FSL_SOC |
53 | select DMA_ENGINE | 53 | select DMA_ENGINE |
54 | ---help--- | 54 | ---help--- |
55 | Enable support for the Freescale DMA engine. Now, it support | 55 | Enable support for the Freescale Elo and Elo Plus DMA controllers. |
56 | MPC8560/40, MPC8555, MPC8548 and MPC8641 processors. | 56 | The Elo is the DMA controller on some 82xx and 83xx parts, and the |
57 | The MPC8349, MPC8360 is also supported. | 57 | Elo Plus is the DMA controller on 85xx and 86xx parts. |
58 | 58 | ||
59 | config MV_XOR | 59 | config MV_XOR |
60 | bool "Marvell XOR engine support" | 60 | bool "Marvell XOR engine support" |
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index a08d19704743..d1e381e35a9e 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c | |||
@@ -325,7 +325,12 @@ static enum dma_state_client dmatest_add_channel(struct dma_chan *chan) | |||
325 | struct dmatest_thread *thread; | 325 | struct dmatest_thread *thread; |
326 | unsigned int i; | 326 | unsigned int i; |
327 | 327 | ||
328 | dtc = kmalloc(sizeof(struct dmatest_chan), GFP_ATOMIC); | 328 | /* Have we already been told about this channel? */ |
329 | list_for_each_entry(dtc, &dmatest_channels, node) | ||
330 | if (dtc->chan == chan) | ||
331 | return DMA_DUP; | ||
332 | |||
333 | dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL); | ||
329 | if (!dtc) { | 334 | if (!dtc) { |
330 | pr_warning("dmatest: No memory for %s\n", chan->dev.bus_id); | 335 | pr_warning("dmatest: No memory for %s\n", chan->dev.bus_id); |
331 | return DMA_NAK; | 336 | return DMA_NAK; |
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index c0059ca58340..0b95dcce447e 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c | |||
@@ -370,7 +370,10 @@ static int fsl_dma_alloc_chan_resources(struct dma_chan *chan, | |||
370 | struct dma_client *client) | 370 | struct dma_client *client) |
371 | { | 371 | { |
372 | struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan); | 372 | struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan); |
373 | LIST_HEAD(tmp_list); | 373 | |
374 | /* Has this channel already been allocated? */ | ||
375 | if (fsl_chan->desc_pool) | ||
376 | return 1; | ||
374 | 377 | ||
375 | /* We need the descriptor to be aligned to 32bytes | 378 | /* We need the descriptor to be aligned to 32bytes |
376 | * for meeting FSL DMA specification requirement. | 379 | * for meeting FSL DMA specification requirement. |
@@ -410,6 +413,8 @@ static void fsl_dma_free_chan_resources(struct dma_chan *chan) | |||
410 | } | 413 | } |
411 | spin_unlock_irqrestore(&fsl_chan->desc_lock, flags); | 414 | spin_unlock_irqrestore(&fsl_chan->desc_lock, flags); |
412 | dma_pool_destroy(fsl_chan->desc_pool); | 415 | dma_pool_destroy(fsl_chan->desc_pool); |
416 | |||
417 | fsl_chan->desc_pool = NULL; | ||
413 | } | 418 | } |
414 | 419 | ||
415 | static struct dma_async_tx_descriptor * | 420 | static struct dma_async_tx_descriptor * |
@@ -786,159 +791,29 @@ static void dma_do_tasklet(unsigned long data) | |||
786 | fsl_chan_ld_cleanup(fsl_chan); | 791 | fsl_chan_ld_cleanup(fsl_chan); |
787 | } | 792 | } |
788 | 793 | ||
789 | static void fsl_dma_callback_test(void *param) | 794 | static int __devinit fsl_dma_chan_probe(struct fsl_dma_device *fdev, |
790 | { | 795 | struct device_node *node, u32 feature, const char *compatible) |
791 | struct fsl_dma_chan *fsl_chan = param; | ||
792 | if (fsl_chan) | ||
793 | dev_dbg(fsl_chan->dev, "selftest: callback is ok!\n"); | ||
794 | } | ||
795 | |||
796 | static int fsl_dma_self_test(struct fsl_dma_chan *fsl_chan) | ||
797 | { | ||
798 | struct dma_chan *chan; | ||
799 | int err = 0; | ||
800 | dma_addr_t dma_dest, dma_src; | ||
801 | dma_cookie_t cookie; | ||
802 | u8 *src, *dest; | ||
803 | int i; | ||
804 | size_t test_size; | ||
805 | struct dma_async_tx_descriptor *tx1, *tx2, *tx3; | ||
806 | |||
807 | test_size = 4096; | ||
808 | |||
809 | src = kmalloc(test_size * 2, GFP_KERNEL); | ||
810 | if (!src) { | ||
811 | dev_err(fsl_chan->dev, | ||
812 | "selftest: Cannot alloc memory for test!\n"); | ||
813 | return -ENOMEM; | ||
814 | } | ||
815 | |||
816 | dest = src + test_size; | ||
817 | |||
818 | for (i = 0; i < test_size; i++) | ||
819 | src[i] = (u8) i; | ||
820 | |||
821 | chan = &fsl_chan->common; | ||
822 | |||
823 | if (fsl_dma_alloc_chan_resources(chan, NULL) < 1) { | ||
824 | dev_err(fsl_chan->dev, | ||
825 | "selftest: Cannot alloc resources for DMA\n"); | ||
826 | err = -ENODEV; | ||
827 | goto out; | ||
828 | } | ||
829 | |||
830 | /* TX 1 */ | ||
831 | dma_src = dma_map_single(fsl_chan->dev, src, test_size / 2, | ||
832 | DMA_TO_DEVICE); | ||
833 | dma_dest = dma_map_single(fsl_chan->dev, dest, test_size / 2, | ||
834 | DMA_FROM_DEVICE); | ||
835 | tx1 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 2, 0); | ||
836 | async_tx_ack(tx1); | ||
837 | |||
838 | cookie = fsl_dma_tx_submit(tx1); | ||
839 | fsl_dma_memcpy_issue_pending(chan); | ||
840 | msleep(2); | ||
841 | |||
842 | if (fsl_dma_is_complete(chan, cookie, NULL, NULL) != DMA_SUCCESS) { | ||
843 | dev_err(fsl_chan->dev, "selftest: Time out!\n"); | ||
844 | err = -ENODEV; | ||
845 | goto free_resources; | ||
846 | } | ||
847 | |||
848 | /* Test free and re-alloc channel resources */ | ||
849 | fsl_dma_free_chan_resources(chan); | ||
850 | |||
851 | if (fsl_dma_alloc_chan_resources(chan, NULL) < 1) { | ||
852 | dev_err(fsl_chan->dev, | ||
853 | "selftest: Cannot alloc resources for DMA\n"); | ||
854 | err = -ENODEV; | ||
855 | goto free_resources; | ||
856 | } | ||
857 | |||
858 | /* Continue to test | ||
859 | * TX 2 | ||
860 | */ | ||
861 | dma_src = dma_map_single(fsl_chan->dev, src + test_size / 2, | ||
862 | test_size / 4, DMA_TO_DEVICE); | ||
863 | dma_dest = dma_map_single(fsl_chan->dev, dest + test_size / 2, | ||
864 | test_size / 4, DMA_FROM_DEVICE); | ||
865 | tx2 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 4, 0); | ||
866 | async_tx_ack(tx2); | ||
867 | |||
868 | /* TX 3 */ | ||
869 | dma_src = dma_map_single(fsl_chan->dev, src + test_size * 3 / 4, | ||
870 | test_size / 4, DMA_TO_DEVICE); | ||
871 | dma_dest = dma_map_single(fsl_chan->dev, dest + test_size * 3 / 4, | ||
872 | test_size / 4, DMA_FROM_DEVICE); | ||
873 | tx3 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 4, 0); | ||
874 | async_tx_ack(tx3); | ||
875 | |||
876 | /* Interrupt tx test */ | ||
877 | tx1 = fsl_dma_prep_interrupt(chan, 0); | ||
878 | async_tx_ack(tx1); | ||
879 | cookie = fsl_dma_tx_submit(tx1); | ||
880 | |||
881 | /* Test exchanging the prepared tx sort */ | ||
882 | cookie = fsl_dma_tx_submit(tx3); | ||
883 | cookie = fsl_dma_tx_submit(tx2); | ||
884 | |||
885 | if (dma_has_cap(DMA_INTERRUPT, ((struct fsl_dma_device *) | ||
886 | dev_get_drvdata(fsl_chan->dev->parent))->common.cap_mask)) { | ||
887 | tx3->callback = fsl_dma_callback_test; | ||
888 | tx3->callback_param = fsl_chan; | ||
889 | } | ||
890 | fsl_dma_memcpy_issue_pending(chan); | ||
891 | msleep(2); | ||
892 | |||
893 | if (fsl_dma_is_complete(chan, cookie, NULL, NULL) != DMA_SUCCESS) { | ||
894 | dev_err(fsl_chan->dev, "selftest: Time out!\n"); | ||
895 | err = -ENODEV; | ||
896 | goto free_resources; | ||
897 | } | ||
898 | |||
899 | err = memcmp(src, dest, test_size); | ||
900 | if (err) { | ||
901 | for (i = 0; (*(src + i) == *(dest + i)) && (i < test_size); | ||
902 | i++); | ||
903 | dev_err(fsl_chan->dev, "selftest: Test failed, data %d/%ld is " | ||
904 | "error! src 0x%x, dest 0x%x\n", | ||
905 | i, (long)test_size, *(src + i), *(dest + i)); | ||
906 | } | ||
907 | |||
908 | free_resources: | ||
909 | fsl_dma_free_chan_resources(chan); | ||
910 | out: | ||
911 | kfree(src); | ||
912 | return err; | ||
913 | } | ||
914 | |||
915 | static int __devinit of_fsl_dma_chan_probe(struct of_device *dev, | ||
916 | const struct of_device_id *match) | ||
917 | { | 796 | { |
918 | struct fsl_dma_device *fdev; | ||
919 | struct fsl_dma_chan *new_fsl_chan; | 797 | struct fsl_dma_chan *new_fsl_chan; |
920 | int err; | 798 | int err; |
921 | 799 | ||
922 | fdev = dev_get_drvdata(dev->dev.parent); | ||
923 | BUG_ON(!fdev); | ||
924 | |||
925 | /* alloc channel */ | 800 | /* alloc channel */ |
926 | new_fsl_chan = kzalloc(sizeof(struct fsl_dma_chan), GFP_KERNEL); | 801 | new_fsl_chan = kzalloc(sizeof(struct fsl_dma_chan), GFP_KERNEL); |
927 | if (!new_fsl_chan) { | 802 | if (!new_fsl_chan) { |
928 | dev_err(&dev->dev, "No free memory for allocating " | 803 | dev_err(fdev->dev, "No free memory for allocating " |
929 | "dma channels!\n"); | 804 | "dma channels!\n"); |
930 | return -ENOMEM; | 805 | return -ENOMEM; |
931 | } | 806 | } |
932 | 807 | ||
933 | /* get dma channel register base */ | 808 | /* get dma channel register base */ |
934 | err = of_address_to_resource(dev->node, 0, &new_fsl_chan->reg); | 809 | err = of_address_to_resource(node, 0, &new_fsl_chan->reg); |
935 | if (err) { | 810 | if (err) { |
936 | dev_err(&dev->dev, "Can't get %s property 'reg'\n", | 811 | dev_err(fdev->dev, "Can't get %s property 'reg'\n", |
937 | dev->node->full_name); | 812 | node->full_name); |
938 | goto err_no_reg; | 813 | goto err_no_reg; |
939 | } | 814 | } |
940 | 815 | ||
941 | new_fsl_chan->feature = *(u32 *)match->data; | 816 | new_fsl_chan->feature = feature; |
942 | 817 | ||
943 | if (!fdev->feature) | 818 | if (!fdev->feature) |
944 | fdev->feature = new_fsl_chan->feature; | 819 | fdev->feature = new_fsl_chan->feature; |
@@ -948,13 +823,13 @@ static int __devinit of_fsl_dma_chan_probe(struct of_device *dev, | |||
948 | */ | 823 | */ |
949 | WARN_ON(fdev->feature != new_fsl_chan->feature); | 824 | WARN_ON(fdev->feature != new_fsl_chan->feature); |
950 | 825 | ||
951 | new_fsl_chan->dev = &dev->dev; | 826 | new_fsl_chan->dev = &new_fsl_chan->common.dev; |
952 | new_fsl_chan->reg_base = ioremap(new_fsl_chan->reg.start, | 827 | new_fsl_chan->reg_base = ioremap(new_fsl_chan->reg.start, |
953 | new_fsl_chan->reg.end - new_fsl_chan->reg.start + 1); | 828 | new_fsl_chan->reg.end - new_fsl_chan->reg.start + 1); |
954 | 829 | ||
955 | new_fsl_chan->id = ((new_fsl_chan->reg.start - 0x100) & 0xfff) >> 7; | 830 | new_fsl_chan->id = ((new_fsl_chan->reg.start - 0x100) & 0xfff) >> 7; |
956 | if (new_fsl_chan->id > FSL_DMA_MAX_CHANS_PER_DEVICE) { | 831 | if (new_fsl_chan->id > FSL_DMA_MAX_CHANS_PER_DEVICE) { |
957 | dev_err(&dev->dev, "There is no %d channel!\n", | 832 | dev_err(fdev->dev, "There is no %d channel!\n", |
958 | new_fsl_chan->id); | 833 | new_fsl_chan->id); |
959 | err = -EINVAL; | 834 | err = -EINVAL; |
960 | goto err_no_chan; | 835 | goto err_no_chan; |
@@ -988,29 +863,23 @@ static int __devinit of_fsl_dma_chan_probe(struct of_device *dev, | |||
988 | &fdev->common.channels); | 863 | &fdev->common.channels); |
989 | fdev->common.chancnt++; | 864 | fdev->common.chancnt++; |
990 | 865 | ||
991 | new_fsl_chan->irq = irq_of_parse_and_map(dev->node, 0); | 866 | new_fsl_chan->irq = irq_of_parse_and_map(node, 0); |
992 | if (new_fsl_chan->irq != NO_IRQ) { | 867 | if (new_fsl_chan->irq != NO_IRQ) { |
993 | err = request_irq(new_fsl_chan->irq, | 868 | err = request_irq(new_fsl_chan->irq, |
994 | &fsl_dma_chan_do_interrupt, IRQF_SHARED, | 869 | &fsl_dma_chan_do_interrupt, IRQF_SHARED, |
995 | "fsldma-channel", new_fsl_chan); | 870 | "fsldma-channel", new_fsl_chan); |
996 | if (err) { | 871 | if (err) { |
997 | dev_err(&dev->dev, "DMA channel %s request_irq error " | 872 | dev_err(fdev->dev, "DMA channel %s request_irq error " |
998 | "with return %d\n", dev->node->full_name, err); | 873 | "with return %d\n", node->full_name, err); |
999 | goto err_no_irq; | 874 | goto err_no_irq; |
1000 | } | 875 | } |
1001 | } | 876 | } |
1002 | 877 | ||
1003 | err = fsl_dma_self_test(new_fsl_chan); | 878 | dev_info(fdev->dev, "#%d (%s), irq %d\n", new_fsl_chan->id, |
1004 | if (err) | 879 | compatible, new_fsl_chan->irq); |
1005 | goto err_self_test; | ||
1006 | |||
1007 | dev_info(&dev->dev, "#%d (%s), irq %d\n", new_fsl_chan->id, | ||
1008 | match->compatible, new_fsl_chan->irq); | ||
1009 | 880 | ||
1010 | return 0; | 881 | return 0; |
1011 | 882 | ||
1012 | err_self_test: | ||
1013 | free_irq(new_fsl_chan->irq, new_fsl_chan); | ||
1014 | err_no_irq: | 883 | err_no_irq: |
1015 | list_del(&new_fsl_chan->common.device_node); | 884 | list_del(&new_fsl_chan->common.device_node); |
1016 | err_no_chan: | 885 | err_no_chan: |
@@ -1020,38 +889,20 @@ err_no_reg: | |||
1020 | return err; | 889 | return err; |
1021 | } | 890 | } |
1022 | 891 | ||
1023 | const u32 mpc8540_dma_ip_feature = FSL_DMA_IP_85XX | FSL_DMA_BIG_ENDIAN; | 892 | static void fsl_dma_chan_remove(struct fsl_dma_chan *fchan) |
1024 | const u32 mpc8349_dma_ip_feature = FSL_DMA_IP_83XX | FSL_DMA_LITTLE_ENDIAN; | ||
1025 | |||
1026 | static struct of_device_id of_fsl_dma_chan_ids[] = { | ||
1027 | { | ||
1028 | .compatible = "fsl,eloplus-dma-channel", | ||
1029 | .data = (void *)&mpc8540_dma_ip_feature, | ||
1030 | }, | ||
1031 | { | ||
1032 | .compatible = "fsl,elo-dma-channel", | ||
1033 | .data = (void *)&mpc8349_dma_ip_feature, | ||
1034 | }, | ||
1035 | {} | ||
1036 | }; | ||
1037 | |||
1038 | static struct of_platform_driver of_fsl_dma_chan_driver = { | ||
1039 | .name = "of-fsl-dma-channel", | ||
1040 | .match_table = of_fsl_dma_chan_ids, | ||
1041 | .probe = of_fsl_dma_chan_probe, | ||
1042 | }; | ||
1043 | |||
1044 | static __init int of_fsl_dma_chan_init(void) | ||
1045 | { | 893 | { |
1046 | return of_register_platform_driver(&of_fsl_dma_chan_driver); | 894 | free_irq(fchan->irq, fchan); |
895 | list_del(&fchan->common.device_node); | ||
896 | iounmap(fchan->reg_base); | ||
897 | kfree(fchan); | ||
1047 | } | 898 | } |
1048 | 899 | ||
1049 | static int __devinit of_fsl_dma_probe(struct of_device *dev, | 900 | static int __devinit of_fsl_dma_probe(struct of_device *dev, |
1050 | const struct of_device_id *match) | 901 | const struct of_device_id *match) |
1051 | { | 902 | { |
1052 | int err; | 903 | int err; |
1053 | unsigned int irq; | ||
1054 | struct fsl_dma_device *fdev; | 904 | struct fsl_dma_device *fdev; |
905 | struct device_node *child; | ||
1055 | 906 | ||
1056 | fdev = kzalloc(sizeof(struct fsl_dma_device), GFP_KERNEL); | 907 | fdev = kzalloc(sizeof(struct fsl_dma_device), GFP_KERNEL); |
1057 | if (!fdev) { | 908 | if (!fdev) { |
@@ -1085,9 +936,9 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev, | |||
1085 | fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending; | 936 | fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending; |
1086 | fdev->common.dev = &dev->dev; | 937 | fdev->common.dev = &dev->dev; |
1087 | 938 | ||
1088 | irq = irq_of_parse_and_map(dev->node, 0); | 939 | fdev->irq = irq_of_parse_and_map(dev->node, 0); |
1089 | if (irq != NO_IRQ) { | 940 | if (fdev->irq != NO_IRQ) { |
1090 | err = request_irq(irq, &fsl_dma_do_interrupt, IRQF_SHARED, | 941 | err = request_irq(fdev->irq, &fsl_dma_do_interrupt, IRQF_SHARED, |
1091 | "fsldma-device", fdev); | 942 | "fsldma-device", fdev); |
1092 | if (err) { | 943 | if (err) { |
1093 | dev_err(&dev->dev, "DMA device request_irq error " | 944 | dev_err(&dev->dev, "DMA device request_irq error " |
@@ -1097,7 +948,21 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev, | |||
1097 | } | 948 | } |
1098 | 949 | ||
1099 | dev_set_drvdata(&(dev->dev), fdev); | 950 | dev_set_drvdata(&(dev->dev), fdev); |
1100 | of_platform_bus_probe(dev->node, of_fsl_dma_chan_ids, &dev->dev); | 951 | |
952 | /* We cannot use of_platform_bus_probe() because there is no | ||
953 | * of_platform_bus_remove. Instead, we manually instantiate every DMA | ||
954 | * channel object. | ||
955 | */ | ||
956 | for_each_child_of_node(dev->node, child) { | ||
957 | if (of_device_is_compatible(child, "fsl,eloplus-dma-channel")) | ||
958 | fsl_dma_chan_probe(fdev, child, | ||
959 | FSL_DMA_IP_85XX | FSL_DMA_BIG_ENDIAN, | ||
960 | "fsl,eloplus-dma-channel"); | ||
961 | if (of_device_is_compatible(child, "fsl,elo-dma-channel")) | ||
962 | fsl_dma_chan_probe(fdev, child, | ||
963 | FSL_DMA_IP_83XX | FSL_DMA_LITTLE_ENDIAN, | ||
964 | "fsl,elo-dma-channel"); | ||
965 | } | ||
1101 | 966 | ||
1102 | dma_async_device_register(&fdev->common); | 967 | dma_async_device_register(&fdev->common); |
1103 | return 0; | 968 | return 0; |
@@ -1109,6 +974,30 @@ err_no_reg: | |||
1109 | return err; | 974 | return err; |
1110 | } | 975 | } |
1111 | 976 | ||
977 | static int of_fsl_dma_remove(struct of_device *of_dev) | ||
978 | { | ||
979 | struct fsl_dma_device *fdev; | ||
980 | unsigned int i; | ||
981 | |||
982 | fdev = dev_get_drvdata(&of_dev->dev); | ||
983 | |||
984 | dma_async_device_unregister(&fdev->common); | ||
985 | |||
986 | for (i = 0; i < FSL_DMA_MAX_CHANS_PER_DEVICE; i++) | ||
987 | if (fdev->chan[i]) | ||
988 | fsl_dma_chan_remove(fdev->chan[i]); | ||
989 | |||
990 | if (fdev->irq != NO_IRQ) | ||
991 | free_irq(fdev->irq, fdev); | ||
992 | |||
993 | iounmap(fdev->reg_base); | ||
994 | |||
995 | kfree(fdev); | ||
996 | dev_set_drvdata(&of_dev->dev, NULL); | ||
997 | |||
998 | return 0; | ||
999 | } | ||
1000 | |||
1112 | static struct of_device_id of_fsl_dma_ids[] = { | 1001 | static struct of_device_id of_fsl_dma_ids[] = { |
1113 | { .compatible = "fsl,eloplus-dma", }, | 1002 | { .compatible = "fsl,eloplus-dma", }, |
1114 | { .compatible = "fsl,elo-dma", }, | 1003 | { .compatible = "fsl,elo-dma", }, |
@@ -1116,15 +1005,32 @@ static struct of_device_id of_fsl_dma_ids[] = { | |||
1116 | }; | 1005 | }; |
1117 | 1006 | ||
1118 | static struct of_platform_driver of_fsl_dma_driver = { | 1007 | static struct of_platform_driver of_fsl_dma_driver = { |
1119 | .name = "of-fsl-dma", | 1008 | .name = "fsl-elo-dma", |
1120 | .match_table = of_fsl_dma_ids, | 1009 | .match_table = of_fsl_dma_ids, |
1121 | .probe = of_fsl_dma_probe, | 1010 | .probe = of_fsl_dma_probe, |
1011 | .remove = of_fsl_dma_remove, | ||
1122 | }; | 1012 | }; |
1123 | 1013 | ||
1124 | static __init int of_fsl_dma_init(void) | 1014 | static __init int of_fsl_dma_init(void) |
1125 | { | 1015 | { |
1126 | return of_register_platform_driver(&of_fsl_dma_driver); | 1016 | int ret; |
1017 | |||
1018 | pr_info("Freescale Elo / Elo Plus DMA driver\n"); | ||
1019 | |||
1020 | ret = of_register_platform_driver(&of_fsl_dma_driver); | ||
1021 | if (ret) | ||
1022 | pr_err("fsldma: failed to register platform driver\n"); | ||
1023 | |||
1024 | return ret; | ||
1025 | } | ||
1026 | |||
1027 | static void __exit of_fsl_dma_exit(void) | ||
1028 | { | ||
1029 | of_unregister_platform_driver(&of_fsl_dma_driver); | ||
1127 | } | 1030 | } |
1128 | 1031 | ||
1129 | subsys_initcall(of_fsl_dma_chan_init); | ||
1130 | subsys_initcall(of_fsl_dma_init); | 1032 | subsys_initcall(of_fsl_dma_init); |
1033 | module_exit(of_fsl_dma_exit); | ||
1034 | |||
1035 | MODULE_DESCRIPTION("Freescale Elo / Elo Plus DMA driver"); | ||
1036 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h index 6faf07ba0d0e..4f21a512d848 100644 --- a/drivers/dma/fsldma.h +++ b/drivers/dma/fsldma.h | |||
@@ -114,6 +114,7 @@ struct fsl_dma_device { | |||
114 | struct dma_device common; | 114 | struct dma_device common; |
115 | struct fsl_dma_chan *chan[FSL_DMA_MAX_CHANS_PER_DEVICE]; | 115 | struct fsl_dma_chan *chan[FSL_DMA_MAX_CHANS_PER_DEVICE]; |
116 | u32 feature; /* The same as DMA channels */ | 116 | u32 feature; /* The same as DMA channels */ |
117 | int irq; /* Channel IRQ */ | ||
117 | }; | 118 | }; |
118 | 119 | ||
119 | /* Define macros for fsl_dma_chan->feature property */ | 120 | /* Define macros for fsl_dma_chan->feature property */ |
diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c index bc8c6e3470ca..1ef68b315657 100644 --- a/drivers/dma/ioat_dma.c +++ b/drivers/dma/ioat_dma.c | |||
@@ -971,11 +971,9 @@ static struct ioat_desc_sw *ioat_dma_get_next_descriptor( | |||
971 | switch (ioat_chan->device->version) { | 971 | switch (ioat_chan->device->version) { |
972 | case IOAT_VER_1_2: | 972 | case IOAT_VER_1_2: |
973 | return ioat1_dma_get_next_descriptor(ioat_chan); | 973 | return ioat1_dma_get_next_descriptor(ioat_chan); |
974 | break; | ||
975 | case IOAT_VER_2_0: | 974 | case IOAT_VER_2_0: |
976 | case IOAT_VER_3_0: | 975 | case IOAT_VER_3_0: |
977 | return ioat2_dma_get_next_descriptor(ioat_chan); | 976 | return ioat2_dma_get_next_descriptor(ioat_chan); |
978 | break; | ||
979 | } | 977 | } |
980 | return NULL; | 978 | return NULL; |
981 | } | 979 | } |
diff --git a/drivers/edac/cell_edac.c b/drivers/edac/cell_edac.c index 0e024fe2d8c4..887072f5dc8b 100644 --- a/drivers/edac/cell_edac.c +++ b/drivers/edac/cell_edac.c | |||
@@ -142,7 +142,7 @@ static void __devinit cell_edac_init_csrows(struct mem_ctl_info *mci) | |||
142 | csrow->nr_pages = (r.end - r.start + 1) >> PAGE_SHIFT; | 142 | csrow->nr_pages = (r.end - r.start + 1) >> PAGE_SHIFT; |
143 | csrow->last_page = csrow->first_page + csrow->nr_pages - 1; | 143 | csrow->last_page = csrow->first_page + csrow->nr_pages - 1; |
144 | csrow->mtype = MEM_XDR; | 144 | csrow->mtype = MEM_XDR; |
145 | csrow->edac_mode = EDAC_FLAG_EC | EDAC_FLAG_SECDED; | 145 | csrow->edac_mode = EDAC_SECDED; |
146 | dev_dbg(mci->dev, | 146 | dev_dbg(mci->dev, |
147 | "Initialized on node %d, chanmask=0x%x," | 147 | "Initialized on node %d, chanmask=0x%x," |
148 | " first_page=0x%lx, nr_pages=0x%x\n", | 148 | " first_page=0x%lx, nr_pages=0x%x\n", |
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c index deb154aa47c4..4353414a0b77 100644 --- a/drivers/firmware/iscsi_ibft.c +++ b/drivers/firmware/iscsi_ibft.c | |||
@@ -732,7 +732,6 @@ static int __init ibft_create_attribute(struct ibft_kobject *kobj_data, | |||
732 | 732 | ||
733 | attr->attr.name = name; | 733 | attr->attr.name = name; |
734 | attr->attr.mode = S_IRUSR; | 734 | attr->attr.mode = S_IRUSR; |
735 | attr->attr.owner = THIS_MODULE; | ||
736 | 735 | ||
737 | attr->hdr = hdr; | 736 | attr->hdr = hdr; |
738 | attr->show = show; | 737 | attr->show = show; |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 9112830107a5..faa1cc66e9cf 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -248,7 +248,7 @@ static ssize_t gpio_value_show(struct device *dev, | |||
248 | if (!test_bit(FLAG_EXPORT, &desc->flags)) | 248 | if (!test_bit(FLAG_EXPORT, &desc->flags)) |
249 | status = -EIO; | 249 | status = -EIO; |
250 | else | 250 | else |
251 | status = sprintf(buf, "%d\n", gpio_get_value_cansleep(gpio)); | 251 | status = sprintf(buf, "%d\n", !!gpio_get_value_cansleep(gpio)); |
252 | 252 | ||
253 | mutex_unlock(&sysfs_lock); | 253 | mutex_unlock(&sysfs_lock); |
254 | return status; | 254 | return status; |
@@ -1105,7 +1105,7 @@ int gpio_get_value_cansleep(unsigned gpio) | |||
1105 | 1105 | ||
1106 | might_sleep_if(extra_checks); | 1106 | might_sleep_if(extra_checks); |
1107 | chip = gpio_to_chip(gpio); | 1107 | chip = gpio_to_chip(gpio); |
1108 | return chip->get(chip, gpio - chip->base); | 1108 | return chip->get ? chip->get(chip, gpio - chip->base) : 0; |
1109 | } | 1109 | } |
1110 | EXPORT_SYMBOL_GPL(gpio_get_value_cansleep); | 1110 | EXPORT_SYMBOL_GPL(gpio_get_value_cansleep); |
1111 | 1111 | ||
@@ -1143,7 +1143,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
1143 | 1143 | ||
1144 | if (!is_out) { | 1144 | if (!is_out) { |
1145 | int irq = gpio_to_irq(gpio); | 1145 | int irq = gpio_to_irq(gpio); |
1146 | struct irq_desc *desc = irq_desc + irq; | 1146 | struct irq_desc *desc = irq_to_desc(irq); |
1147 | 1147 | ||
1148 | /* This races with request_irq(), set_irq_type(), | 1148 | /* This races with request_irq(), set_irq_type(), |
1149 | * and set_irq_wake() ... but those are "rare". | 1149 | * and set_irq_wake() ... but those are "rare". |
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 9097500de5f4..a8b33c2ec8d2 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig | |||
@@ -6,7 +6,7 @@ | |||
6 | # | 6 | # |
7 | menuconfig DRM | 7 | menuconfig DRM |
8 | tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" | 8 | tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" |
9 | depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG && SHMEM | 9 | depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG && MMU |
10 | help | 10 | help |
11 | Kernel-level support for the Direct Rendering Infrastructure (DRI) | 11 | Kernel-level support for the Direct Rendering Infrastructure (DRI) |
12 | introduced in XFree86 4.0. If you say Y here, you need to select | 12 | introduced in XFree86 4.0. If you say Y here, you need to select |
diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c index d490db4c0de0..ae73b7f7249a 100644 --- a/drivers/gpu/drm/drm_proc.c +++ b/drivers/gpu/drm/drm_proc.c | |||
@@ -522,12 +522,12 @@ static int drm_gem_one_name_info(int id, void *ptr, void *data) | |||
522 | struct drm_gem_object *obj = ptr; | 522 | struct drm_gem_object *obj = ptr; |
523 | struct drm_gem_name_info_data *nid = data; | 523 | struct drm_gem_name_info_data *nid = data; |
524 | 524 | ||
525 | DRM_INFO("name %d size %d\n", obj->name, obj->size); | 525 | DRM_INFO("name %d size %zd\n", obj->name, obj->size); |
526 | if (nid->eof) | 526 | if (nid->eof) |
527 | return 0; | 527 | return 0; |
528 | 528 | ||
529 | nid->len += sprintf(&nid->buf[nid->len], | 529 | nid->len += sprintf(&nid->buf[nid->len], |
530 | "%6d%9d%8d%9d\n", | 530 | "%6d %8zd %7d %8d\n", |
531 | obj->name, obj->size, | 531 | obj->name, obj->size, |
532 | atomic_read(&obj->handlecount.refcount), | 532 | atomic_read(&obj->handlecount.refcount), |
533 | atomic_read(&obj->refcount.refcount)); | 533 | atomic_read(&obj->refcount.refcount)); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 9ac73dd1b422..dc2e6fdb6ca3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -171,6 +171,37 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, | |||
171 | return 0; | 171 | return 0; |
172 | } | 172 | } |
173 | 173 | ||
174 | /* | ||
175 | * Try to write quickly with an atomic kmap. Return true on success. | ||
176 | * | ||
177 | * If this fails (which includes a partial write), we'll redo the whole | ||
178 | * thing with the slow version. | ||
179 | * | ||
180 | * This is a workaround for the low performance of iounmap (approximate | ||
181 | * 10% cpu cost on normal 3D workloads). kmap_atomic on HIGHMEM kernels | ||
182 | * happens to let us map card memory without taking IPIs. When the vmap | ||
183 | * rework lands we should be able to dump this hack. | ||
184 | */ | ||
185 | static inline int fast_user_write(unsigned long pfn, char __user *user_data, | ||
186 | int l, int o) | ||
187 | { | ||
188 | #ifdef CONFIG_HIGHMEM | ||
189 | unsigned long unwritten; | ||
190 | char *vaddr_atomic; | ||
191 | |||
192 | vaddr_atomic = kmap_atomic_pfn(pfn, KM_USER0); | ||
193 | #if WATCH_PWRITE | ||
194 | DRM_INFO("pwrite i %d o %d l %d pfn %ld vaddr %p\n", | ||
195 | i, o, l, pfn, vaddr_atomic); | ||
196 | #endif | ||
197 | unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + o, user_data, l); | ||
198 | kunmap_atomic(vaddr_atomic, KM_USER0); | ||
199 | return !unwritten; | ||
200 | #else | ||
201 | return 0; | ||
202 | #endif | ||
203 | } | ||
204 | |||
174 | static int | 205 | static int |
175 | i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | 206 | i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj, |
176 | struct drm_i915_gem_pwrite *args, | 207 | struct drm_i915_gem_pwrite *args, |
@@ -180,12 +211,7 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | |||
180 | ssize_t remain; | 211 | ssize_t remain; |
181 | loff_t offset; | 212 | loff_t offset; |
182 | char __user *user_data; | 213 | char __user *user_data; |
183 | char __iomem *vaddr; | ||
184 | char *vaddr_atomic; | ||
185 | int i, o, l; | ||
186 | int ret = 0; | 214 | int ret = 0; |
187 | unsigned long pfn; | ||
188 | unsigned long unwritten; | ||
189 | 215 | ||
190 | user_data = (char __user *) (uintptr_t) args->data_ptr; | 216 | user_data = (char __user *) (uintptr_t) args->data_ptr; |
191 | remain = args->size; | 217 | remain = args->size; |
@@ -209,6 +235,9 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | |||
209 | obj_priv->dirty = 1; | 235 | obj_priv->dirty = 1; |
210 | 236 | ||
211 | while (remain > 0) { | 237 | while (remain > 0) { |
238 | unsigned long pfn; | ||
239 | int i, o, l; | ||
240 | |||
212 | /* Operation in this page | 241 | /* Operation in this page |
213 | * | 242 | * |
214 | * i = page number | 243 | * i = page number |
@@ -223,25 +252,10 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | |||
223 | 252 | ||
224 | pfn = (dev->agp->base >> PAGE_SHIFT) + i; | 253 | pfn = (dev->agp->base >> PAGE_SHIFT) + i; |
225 | 254 | ||
226 | #ifdef CONFIG_HIGHMEM | 255 | if (!fast_user_write(pfn, user_data, l, o)) { |
227 | /* This is a workaround for the low performance of iounmap | 256 | unsigned long unwritten; |
228 | * (approximate 10% cpu cost on normal 3D workloads). | 257 | char __iomem *vaddr; |
229 | * kmap_atomic on HIGHMEM kernels happens to let us map card | ||
230 | * memory without taking IPIs. When the vmap rework lands | ||
231 | * we should be able to dump this hack. | ||
232 | */ | ||
233 | vaddr_atomic = kmap_atomic_pfn(pfn, KM_USER0); | ||
234 | #if WATCH_PWRITE | ||
235 | DRM_INFO("pwrite i %d o %d l %d pfn %ld vaddr %p\n", | ||
236 | i, o, l, pfn, vaddr_atomic); | ||
237 | #endif | ||
238 | unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + o, | ||
239 | user_data, l); | ||
240 | kunmap_atomic(vaddr_atomic, KM_USER0); | ||
241 | 258 | ||
242 | if (unwritten) | ||
243 | #endif /* CONFIG_HIGHMEM */ | ||
244 | { | ||
245 | vaddr = ioremap_wc(pfn << PAGE_SHIFT, PAGE_SIZE); | 259 | vaddr = ioremap_wc(pfn << PAGE_SHIFT, PAGE_SIZE); |
246 | #if WATCH_PWRITE | 260 | #if WATCH_PWRITE |
247 | DRM_INFO("pwrite slow i %d o %d l %d " | 261 | DRM_INFO("pwrite slow i %d o %d l %d " |
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index b06b8e090a27..bc011da79e14 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c | |||
@@ -49,6 +49,9 @@ | |||
49 | 49 | ||
50 | #define APPLESMC_MAX_DATA_LENGTH 32 | 50 | #define APPLESMC_MAX_DATA_LENGTH 32 |
51 | 51 | ||
52 | #define APPLESMC_MIN_WAIT 0x0040 | ||
53 | #define APPLESMC_MAX_WAIT 0x8000 | ||
54 | |||
52 | #define APPLESMC_STATUS_MASK 0x0f | 55 | #define APPLESMC_STATUS_MASK 0x0f |
53 | #define APPLESMC_READ_CMD 0x10 | 56 | #define APPLESMC_READ_CMD 0x10 |
54 | #define APPLESMC_WRITE_CMD 0x11 | 57 | #define APPLESMC_WRITE_CMD 0x11 |
@@ -57,8 +60,8 @@ | |||
57 | 60 | ||
58 | #define KEY_COUNT_KEY "#KEY" /* r-o ui32 */ | 61 | #define KEY_COUNT_KEY "#KEY" /* r-o ui32 */ |
59 | 62 | ||
60 | #define LIGHT_SENSOR_LEFT_KEY "ALV0" /* r-o {alv (6 bytes) */ | 63 | #define LIGHT_SENSOR_LEFT_KEY "ALV0" /* r-o {alv (6-10 bytes) */ |
61 | #define LIGHT_SENSOR_RIGHT_KEY "ALV1" /* r-o {alv (6 bytes) */ | 64 | #define LIGHT_SENSOR_RIGHT_KEY "ALV1" /* r-o {alv (6-10 bytes) */ |
62 | #define BACKLIGHT_KEY "LKSB" /* w-o {lkb (2 bytes) */ | 65 | #define BACKLIGHT_KEY "LKSB" /* w-o {lkb (2 bytes) */ |
63 | 66 | ||
64 | #define CLAMSHELL_KEY "MSLD" /* r-o ui8 (unused) */ | 67 | #define CLAMSHELL_KEY "MSLD" /* r-o ui8 (unused) */ |
@@ -104,6 +107,15 @@ static const char* temperature_sensors_sets[][36] = { | |||
104 | /* Set 6: Macbook3 set */ | 107 | /* Set 6: Macbook3 set */ |
105 | { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TTF0", "TW0P", "Th0H", | 108 | { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TTF0", "TW0P", "Th0H", |
106 | "Th0S", "Th1H", NULL }, | 109 | "Th0S", "Th1H", NULL }, |
110 | /* Set 7: Macbook Air */ | ||
111 | { "TB0T", "TB1S", "TB1T", "TB2S", "TB2T", "TC0D", "TC0P", "TCFP", | ||
112 | "TTF0", "TW0P", "Th0H", "Tp0P", "TpFP", "Ts0P", "Ts0S", NULL }, | ||
113 | /* Set 8: Macbook Pro 4,1 (Penryn) */ | ||
114 | { "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P", "Th0H", | ||
115 | "Th1H", "Th2H", "Tm0P", "Ts0P", NULL }, | ||
116 | /* Set 9: Macbook Pro 3,1 (Santa Rosa) */ | ||
117 | { "TALP", "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P", | ||
118 | "Th0H", "Th1H", "Th2H", "Tm0P", "Ts0P", NULL }, | ||
107 | }; | 119 | }; |
108 | 120 | ||
109 | /* List of keys used to read/write fan speeds */ | 121 | /* List of keys used to read/write fan speeds */ |
@@ -163,25 +175,25 @@ static unsigned int key_at_index; | |||
163 | static struct workqueue_struct *applesmc_led_wq; | 175 | static struct workqueue_struct *applesmc_led_wq; |
164 | 176 | ||
165 | /* | 177 | /* |
166 | * __wait_status - Wait up to 2ms for the status port to get a certain value | 178 | * __wait_status - Wait up to 32ms for the status port to get a certain value |
167 | * (masked with 0x0f), returning zero if the value is obtained. Callers must | 179 | * (masked with 0x0f), returning zero if the value is obtained. Callers must |
168 | * hold applesmc_lock. | 180 | * hold applesmc_lock. |
169 | */ | 181 | */ |
170 | static int __wait_status(u8 val) | 182 | static int __wait_status(u8 val) |
171 | { | 183 | { |
172 | unsigned int i; | 184 | int us; |
173 | 185 | ||
174 | val = val & APPLESMC_STATUS_MASK; | 186 | val = val & APPLESMC_STATUS_MASK; |
175 | 187 | ||
176 | for (i = 0; i < 200; i++) { | 188 | for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) { |
189 | udelay(us); | ||
177 | if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) { | 190 | if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) { |
178 | if (debug) | 191 | if (debug) |
179 | printk(KERN_DEBUG | 192 | printk(KERN_DEBUG |
180 | "Waited %d us for status %x\n", | 193 | "Waited %d us for status %x\n", |
181 | i*10, val); | 194 | 2 * us - APPLESMC_MIN_WAIT, val); |
182 | return 0; | 195 | return 0; |
183 | } | 196 | } |
184 | udelay(10); | ||
185 | } | 197 | } |
186 | 198 | ||
187 | printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n", | 199 | printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n", |
@@ -191,6 +203,25 @@ static int __wait_status(u8 val) | |||
191 | } | 203 | } |
192 | 204 | ||
193 | /* | 205 | /* |
206 | * special treatment of command port - on newer macbooks, it seems necessary | ||
207 | * to resend the command byte before polling the status again. Callers must | ||
208 | * hold applesmc_lock. | ||
209 | */ | ||
210 | static int send_command(u8 cmd) | ||
211 | { | ||
212 | int us; | ||
213 | for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) { | ||
214 | outb(cmd, APPLESMC_CMD_PORT); | ||
215 | udelay(us); | ||
216 | if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c) | ||
217 | return 0; | ||
218 | } | ||
219 | printk(KERN_WARNING "applesmc: command failed: %x -> %x\n", | ||
220 | cmd, inb(APPLESMC_CMD_PORT)); | ||
221 | return -EIO; | ||
222 | } | ||
223 | |||
224 | /* | ||
194 | * applesmc_read_key - reads len bytes from a given key, and put them in buffer. | 225 | * applesmc_read_key - reads len bytes from a given key, and put them in buffer. |
195 | * Returns zero on success or a negative error on failure. Callers must | 226 | * Returns zero on success or a negative error on failure. Callers must |
196 | * hold applesmc_lock. | 227 | * hold applesmc_lock. |
@@ -205,8 +236,7 @@ static int applesmc_read_key(const char* key, u8* buffer, u8 len) | |||
205 | return -EINVAL; | 236 | return -EINVAL; |
206 | } | 237 | } |
207 | 238 | ||
208 | outb(APPLESMC_READ_CMD, APPLESMC_CMD_PORT); | 239 | if (send_command(APPLESMC_READ_CMD)) |
209 | if (__wait_status(0x0c)) | ||
210 | return -EIO; | 240 | return -EIO; |
211 | 241 | ||
212 | for (i = 0; i < 4; i++) { | 242 | for (i = 0; i < 4; i++) { |
@@ -249,8 +279,7 @@ static int applesmc_write_key(const char* key, u8* buffer, u8 len) | |||
249 | return -EINVAL; | 279 | return -EINVAL; |
250 | } | 280 | } |
251 | 281 | ||
252 | outb(APPLESMC_WRITE_CMD, APPLESMC_CMD_PORT); | 282 | if (send_command(APPLESMC_WRITE_CMD)) |
253 | if (__wait_status(0x0c)) | ||
254 | return -EIO; | 283 | return -EIO; |
255 | 284 | ||
256 | for (i = 0; i < 4; i++) { | 285 | for (i = 0; i < 4; i++) { |
@@ -284,8 +313,7 @@ static int applesmc_get_key_at_index(int index, char* key) | |||
284 | readkey[2] = index >> 8; | 313 | readkey[2] = index >> 8; |
285 | readkey[3] = index; | 314 | readkey[3] = index; |
286 | 315 | ||
287 | outb(APPLESMC_GET_KEY_BY_INDEX_CMD, APPLESMC_CMD_PORT); | 316 | if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD)) |
288 | if (__wait_status(0x0c)) | ||
289 | return -EIO; | 317 | return -EIO; |
290 | 318 | ||
291 | for (i = 0; i < 4; i++) { | 319 | for (i = 0; i < 4; i++) { |
@@ -315,8 +343,7 @@ static int applesmc_get_key_type(char* key, char* type) | |||
315 | { | 343 | { |
316 | int i; | 344 | int i; |
317 | 345 | ||
318 | outb(APPLESMC_GET_KEY_TYPE_CMD, APPLESMC_CMD_PORT); | 346 | if (send_command(APPLESMC_GET_KEY_TYPE_CMD)) |
319 | if (__wait_status(0x0c)) | ||
320 | return -EIO; | 347 | return -EIO; |
321 | 348 | ||
322 | for (i = 0; i < 4; i++) { | 349 | for (i = 0; i < 4; i++) { |
@@ -325,7 +352,7 @@ static int applesmc_get_key_type(char* key, char* type) | |||
325 | return -EIO; | 352 | return -EIO; |
326 | } | 353 | } |
327 | 354 | ||
328 | outb(5, APPLESMC_DATA_PORT); | 355 | outb(6, APPLESMC_DATA_PORT); |
329 | 356 | ||
330 | for (i = 0; i < 6; i++) { | 357 | for (i = 0; i < 6; i++) { |
331 | if (__wait_status(0x05)) | 358 | if (__wait_status(0x05)) |
@@ -527,17 +554,27 @@ out: | |||
527 | static ssize_t applesmc_light_show(struct device *dev, | 554 | static ssize_t applesmc_light_show(struct device *dev, |
528 | struct device_attribute *attr, char *sysfsbuf) | 555 | struct device_attribute *attr, char *sysfsbuf) |
529 | { | 556 | { |
557 | static int data_length; | ||
530 | int ret; | 558 | int ret; |
531 | u8 left = 0, right = 0; | 559 | u8 left = 0, right = 0; |
532 | u8 buffer[6]; | 560 | u8 buffer[10], query[6]; |
533 | 561 | ||
534 | mutex_lock(&applesmc_lock); | 562 | mutex_lock(&applesmc_lock); |
535 | 563 | ||
536 | ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, 6); | 564 | if (!data_length) { |
565 | ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query); | ||
566 | if (ret) | ||
567 | goto out; | ||
568 | data_length = clamp_val(query[0], 0, 10); | ||
569 | printk(KERN_INFO "applesmc: light sensor data length set to " | ||
570 | "%d\n", data_length); | ||
571 | } | ||
572 | |||
573 | ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length); | ||
537 | left = buffer[2]; | 574 | left = buffer[2]; |
538 | if (ret) | 575 | if (ret) |
539 | goto out; | 576 | goto out; |
540 | ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, 6); | 577 | ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length); |
541 | right = buffer[2]; | 578 | right = buffer[2]; |
542 | 579 | ||
543 | out: | 580 | out: |
@@ -1233,39 +1270,57 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = { | |||
1233 | { .accelerometer = 0, .light = 0, .temperature_set = 5 }, | 1270 | { .accelerometer = 0, .light = 0, .temperature_set = 5 }, |
1234 | /* MacBook3: accelerometer and temperature set 6 */ | 1271 | /* MacBook3: accelerometer and temperature set 6 */ |
1235 | { .accelerometer = 1, .light = 0, .temperature_set = 6 }, | 1272 | { .accelerometer = 1, .light = 0, .temperature_set = 6 }, |
1273 | /* MacBook Air: accelerometer, backlight and temperature set 7 */ | ||
1274 | { .accelerometer = 1, .light = 1, .temperature_set = 7 }, | ||
1275 | /* MacBook Pro 4: accelerometer, backlight and temperature set 8 */ | ||
1276 | { .accelerometer = 1, .light = 1, .temperature_set = 8 }, | ||
1277 | /* MacBook Pro 3: accelerometer, backlight and temperature set 9 */ | ||
1278 | { .accelerometer = 1, .light = 1, .temperature_set = 9 }, | ||
1236 | }; | 1279 | }; |
1237 | 1280 | ||
1238 | /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". | 1281 | /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". |
1239 | * So we need to put "Apple MacBook Pro" before "Apple MacBook". */ | 1282 | * So we need to put "Apple MacBook Pro" before "Apple MacBook". */ |
1240 | static __initdata struct dmi_system_id applesmc_whitelist[] = { | 1283 | static __initdata struct dmi_system_id applesmc_whitelist[] = { |
1284 | { applesmc_dmi_match, "Apple MacBook Air", { | ||
1285 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
1286 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") }, | ||
1287 | &applesmc_dmi_data[7]}, | ||
1288 | { applesmc_dmi_match, "Apple MacBook Pro 4", { | ||
1289 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
1290 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") }, | ||
1291 | &applesmc_dmi_data[8]}, | ||
1292 | { applesmc_dmi_match, "Apple MacBook Pro 3", { | ||
1293 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
1294 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") }, | ||
1295 | &applesmc_dmi_data[9]}, | ||
1241 | { applesmc_dmi_match, "Apple MacBook Pro", { | 1296 | { applesmc_dmi_match, "Apple MacBook Pro", { |
1242 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1297 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
1243 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") }, | 1298 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") }, |
1244 | (void*)&applesmc_dmi_data[0]}, | 1299 | &applesmc_dmi_data[0]}, |
1245 | { applesmc_dmi_match, "Apple MacBook (v2)", { | 1300 | { applesmc_dmi_match, "Apple MacBook (v2)", { |
1246 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1301 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
1247 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") }, | 1302 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") }, |
1248 | (void*)&applesmc_dmi_data[1]}, | 1303 | &applesmc_dmi_data[1]}, |
1249 | { applesmc_dmi_match, "Apple MacBook (v3)", { | 1304 | { applesmc_dmi_match, "Apple MacBook (v3)", { |
1250 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1305 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
1251 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") }, | 1306 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") }, |
1252 | (void*)&applesmc_dmi_data[6]}, | 1307 | &applesmc_dmi_data[6]}, |
1253 | { applesmc_dmi_match, "Apple MacBook", { | 1308 | { applesmc_dmi_match, "Apple MacBook", { |
1254 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1309 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
1255 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") }, | 1310 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") }, |
1256 | (void*)&applesmc_dmi_data[2]}, | 1311 | &applesmc_dmi_data[2]}, |
1257 | { applesmc_dmi_match, "Apple Macmini", { | 1312 | { applesmc_dmi_match, "Apple Macmini", { |
1258 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1313 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
1259 | DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") }, | 1314 | DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") }, |
1260 | (void*)&applesmc_dmi_data[3]}, | 1315 | &applesmc_dmi_data[3]}, |
1261 | { applesmc_dmi_match, "Apple MacPro2", { | 1316 | { applesmc_dmi_match, "Apple MacPro2", { |
1262 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1317 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
1263 | DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") }, | 1318 | DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") }, |
1264 | (void*)&applesmc_dmi_data[4]}, | 1319 | &applesmc_dmi_data[4]}, |
1265 | { applesmc_dmi_match, "Apple iMac", { | 1320 | { applesmc_dmi_match, "Apple iMac", { |
1266 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1321 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
1267 | DMI_MATCH(DMI_PRODUCT_NAME,"iMac") }, | 1322 | DMI_MATCH(DMI_PRODUCT_NAME,"iMac") }, |
1268 | (void*)&applesmc_dmi_data[5]}, | 1323 | &applesmc_dmi_data[5]}, |
1269 | { .ident = NULL } | 1324 | { .ident = NULL } |
1270 | }; | 1325 | }; |
1271 | 1326 | ||
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index 9b462bb13fa3..5fbfa34c110e 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c | |||
@@ -75,7 +75,8 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID"); | |||
75 | #define FSCM 0x09 /* Logical device: fans */ | 75 | #define FSCM 0x09 /* Logical device: fans */ |
76 | #define VLM 0x0d /* Logical device: voltages */ | 76 | #define VLM 0x0d /* Logical device: voltages */ |
77 | #define TMS 0x0e /* Logical device: temperatures */ | 77 | #define TMS 0x0e /* Logical device: temperatures */ |
78 | static const u8 logdev[3] = { FSCM, VLM, TMS }; | 78 | #define LDNI_MAX 3 |
79 | static const u8 logdev[LDNI_MAX] = { FSCM, VLM, TMS }; | ||
79 | 80 | ||
80 | #define LD_FAN 0 | 81 | #define LD_FAN 0 |
81 | #define LD_IN 1 | 82 | #define LD_IN 1 |
@@ -489,11 +490,66 @@ static struct sensor_device_attribute in_max[] = { | |||
489 | SENSOR_ATTR(in10_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 10), | 490 | SENSOR_ATTR(in10_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 10), |
490 | }; | 491 | }; |
491 | 492 | ||
493 | /* (temp & vin) channel status register alarm bits (pdf sec.11.5.12) */ | ||
494 | #define CHAN_ALM_MIN 0x02 /* min limit crossed */ | ||
495 | #define CHAN_ALM_MAX 0x04 /* max limit exceeded */ | ||
496 | #define TEMP_ALM_CRIT 0x08 /* temp crit exceeded (temp only) */ | ||
497 | |||
498 | /* show_in_min/max_alarm() reads data from the per-channel status | ||
499 | register (sec 11.5.12), not the vin event status registers (sec | ||
500 | 11.5.2) that (legacy) show_in_alarm() resds (via data->in_alarms) */ | ||
501 | |||
502 | static ssize_t show_in_min_alarm(struct device *dev, | ||
503 | struct device_attribute *devattr, char *buf) | ||
504 | { | ||
505 | struct pc87360_data *data = pc87360_update_device(dev); | ||
506 | unsigned nr = to_sensor_dev_attr(devattr)->index; | ||
507 | |||
508 | return sprintf(buf, "%u\n", !!(data->in_status[nr] & CHAN_ALM_MIN)); | ||
509 | } | ||
510 | static ssize_t show_in_max_alarm(struct device *dev, | ||
511 | struct device_attribute *devattr, char *buf) | ||
512 | { | ||
513 | struct pc87360_data *data = pc87360_update_device(dev); | ||
514 | unsigned nr = to_sensor_dev_attr(devattr)->index; | ||
515 | |||
516 | return sprintf(buf, "%u\n", !!(data->in_status[nr] & CHAN_ALM_MAX)); | ||
517 | } | ||
518 | |||
519 | static struct sensor_device_attribute in_min_alarm[] = { | ||
520 | SENSOR_ATTR(in0_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 0), | ||
521 | SENSOR_ATTR(in1_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 1), | ||
522 | SENSOR_ATTR(in2_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 2), | ||
523 | SENSOR_ATTR(in3_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 3), | ||
524 | SENSOR_ATTR(in4_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 4), | ||
525 | SENSOR_ATTR(in5_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 5), | ||
526 | SENSOR_ATTR(in6_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 6), | ||
527 | SENSOR_ATTR(in7_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 7), | ||
528 | SENSOR_ATTR(in8_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 8), | ||
529 | SENSOR_ATTR(in9_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 9), | ||
530 | SENSOR_ATTR(in10_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 10), | ||
531 | }; | ||
532 | static struct sensor_device_attribute in_max_alarm[] = { | ||
533 | SENSOR_ATTR(in0_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 0), | ||
534 | SENSOR_ATTR(in1_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 1), | ||
535 | SENSOR_ATTR(in2_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 2), | ||
536 | SENSOR_ATTR(in3_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 3), | ||
537 | SENSOR_ATTR(in4_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 4), | ||
538 | SENSOR_ATTR(in5_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 5), | ||
539 | SENSOR_ATTR(in6_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 6), | ||
540 | SENSOR_ATTR(in7_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 7), | ||
541 | SENSOR_ATTR(in8_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 8), | ||
542 | SENSOR_ATTR(in9_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 9), | ||
543 | SENSOR_ATTR(in10_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 10), | ||
544 | }; | ||
545 | |||
492 | #define VIN_UNIT_ATTRS(X) \ | 546 | #define VIN_UNIT_ATTRS(X) \ |
493 | &in_input[X].dev_attr.attr, \ | 547 | &in_input[X].dev_attr.attr, \ |
494 | &in_status[X].dev_attr.attr, \ | 548 | &in_status[X].dev_attr.attr, \ |
495 | &in_min[X].dev_attr.attr, \ | 549 | &in_min[X].dev_attr.attr, \ |
496 | &in_max[X].dev_attr.attr | 550 | &in_max[X].dev_attr.attr, \ |
551 | &in_min_alarm[X].dev_attr.attr, \ | ||
552 | &in_max_alarm[X].dev_attr.attr | ||
497 | 553 | ||
498 | static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf) | 554 | static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf) |
499 | { | 555 | { |
@@ -658,12 +714,68 @@ static struct sensor_device_attribute therm_crit[] = { | |||
658 | show_therm_crit, set_therm_crit, 2+11), | 714 | show_therm_crit, set_therm_crit, 2+11), |
659 | }; | 715 | }; |
660 | 716 | ||
717 | /* show_therm_min/max_alarm() reads data from the per-channel voltage | ||
718 | status register (sec 11.5.12) */ | ||
719 | |||
720 | static ssize_t show_therm_min_alarm(struct device *dev, | ||
721 | struct device_attribute *devattr, char *buf) | ||
722 | { | ||
723 | struct pc87360_data *data = pc87360_update_device(dev); | ||
724 | unsigned nr = to_sensor_dev_attr(devattr)->index; | ||
725 | |||
726 | return sprintf(buf, "%u\n", !!(data->in_status[nr] & CHAN_ALM_MIN)); | ||
727 | } | ||
728 | static ssize_t show_therm_max_alarm(struct device *dev, | ||
729 | struct device_attribute *devattr, char *buf) | ||
730 | { | ||
731 | struct pc87360_data *data = pc87360_update_device(dev); | ||
732 | unsigned nr = to_sensor_dev_attr(devattr)->index; | ||
733 | |||
734 | return sprintf(buf, "%u\n", !!(data->in_status[nr] & CHAN_ALM_MAX)); | ||
735 | } | ||
736 | static ssize_t show_therm_crit_alarm(struct device *dev, | ||
737 | struct device_attribute *devattr, char *buf) | ||
738 | { | ||
739 | struct pc87360_data *data = pc87360_update_device(dev); | ||
740 | unsigned nr = to_sensor_dev_attr(devattr)->index; | ||
741 | |||
742 | return sprintf(buf, "%u\n", !!(data->in_status[nr] & TEMP_ALM_CRIT)); | ||
743 | } | ||
744 | |||
745 | static struct sensor_device_attribute therm_min_alarm[] = { | ||
746 | SENSOR_ATTR(temp4_min_alarm, S_IRUGO, | ||
747 | show_therm_min_alarm, NULL, 0+11), | ||
748 | SENSOR_ATTR(temp5_min_alarm, S_IRUGO, | ||
749 | show_therm_min_alarm, NULL, 1+11), | ||
750 | SENSOR_ATTR(temp6_min_alarm, S_IRUGO, | ||
751 | show_therm_min_alarm, NULL, 2+11), | ||
752 | }; | ||
753 | static struct sensor_device_attribute therm_max_alarm[] = { | ||
754 | SENSOR_ATTR(temp4_max_alarm, S_IRUGO, | ||
755 | show_therm_max_alarm, NULL, 0+11), | ||
756 | SENSOR_ATTR(temp5_max_alarm, S_IRUGO, | ||
757 | show_therm_max_alarm, NULL, 1+11), | ||
758 | SENSOR_ATTR(temp6_max_alarm, S_IRUGO, | ||
759 | show_therm_max_alarm, NULL, 2+11), | ||
760 | }; | ||
761 | static struct sensor_device_attribute therm_crit_alarm[] = { | ||
762 | SENSOR_ATTR(temp4_crit_alarm, S_IRUGO, | ||
763 | show_therm_crit_alarm, NULL, 0+11), | ||
764 | SENSOR_ATTR(temp5_crit_alarm, S_IRUGO, | ||
765 | show_therm_crit_alarm, NULL, 1+11), | ||
766 | SENSOR_ATTR(temp6_crit_alarm, S_IRUGO, | ||
767 | show_therm_crit_alarm, NULL, 2+11), | ||
768 | }; | ||
769 | |||
661 | #define THERM_UNIT_ATTRS(X) \ | 770 | #define THERM_UNIT_ATTRS(X) \ |
662 | &therm_input[X].dev_attr.attr, \ | 771 | &therm_input[X].dev_attr.attr, \ |
663 | &therm_status[X].dev_attr.attr, \ | 772 | &therm_status[X].dev_attr.attr, \ |
664 | &therm_min[X].dev_attr.attr, \ | 773 | &therm_min[X].dev_attr.attr, \ |
665 | &therm_max[X].dev_attr.attr, \ | 774 | &therm_max[X].dev_attr.attr, \ |
666 | &therm_crit[X].dev_attr.attr | 775 | &therm_crit[X].dev_attr.attr, \ |
776 | &therm_min_alarm[X].dev_attr.attr, \ | ||
777 | &therm_max_alarm[X].dev_attr.attr, \ | ||
778 | &therm_crit_alarm[X].dev_attr.attr | ||
667 | 779 | ||
668 | static struct attribute * pc8736x_therm_attr_array[] = { | 780 | static struct attribute * pc8736x_therm_attr_array[] = { |
669 | THERM_UNIT_ATTRS(0), | 781 | THERM_UNIT_ATTRS(0), |
@@ -790,12 +902,76 @@ static ssize_t show_temp_alarms(struct device *dev, struct device_attribute *att | |||
790 | } | 902 | } |
791 | static DEVICE_ATTR(alarms_temp, S_IRUGO, show_temp_alarms, NULL); | 903 | static DEVICE_ATTR(alarms_temp, S_IRUGO, show_temp_alarms, NULL); |
792 | 904 | ||
905 | /* show_temp_min/max_alarm() reads data from the per-channel status | ||
906 | register (sec 12.3.7), not the temp event status registers (sec | ||
907 | 12.3.2) that show_temp_alarm() reads (via data->temp_alarms) */ | ||
908 | |||
909 | static ssize_t show_temp_min_alarm(struct device *dev, | ||
910 | struct device_attribute *devattr, char *buf) | ||
911 | { | ||
912 | struct pc87360_data *data = pc87360_update_device(dev); | ||
913 | unsigned nr = to_sensor_dev_attr(devattr)->index; | ||
914 | |||
915 | return sprintf(buf, "%u\n", !!(data->temp_status[nr] & CHAN_ALM_MIN)); | ||
916 | } | ||
917 | static ssize_t show_temp_max_alarm(struct device *dev, | ||
918 | struct device_attribute *devattr, char *buf) | ||
919 | { | ||
920 | struct pc87360_data *data = pc87360_update_device(dev); | ||
921 | unsigned nr = to_sensor_dev_attr(devattr)->index; | ||
922 | |||
923 | return sprintf(buf, "%u\n", !!(data->temp_status[nr] & CHAN_ALM_MAX)); | ||
924 | } | ||
925 | static ssize_t show_temp_crit_alarm(struct device *dev, | ||
926 | struct device_attribute *devattr, char *buf) | ||
927 | { | ||
928 | struct pc87360_data *data = pc87360_update_device(dev); | ||
929 | unsigned nr = to_sensor_dev_attr(devattr)->index; | ||
930 | |||
931 | return sprintf(buf, "%u\n", !!(data->temp_status[nr] & TEMP_ALM_CRIT)); | ||
932 | } | ||
933 | |||
934 | static struct sensor_device_attribute temp_min_alarm[] = { | ||
935 | SENSOR_ATTR(temp1_min_alarm, S_IRUGO, show_temp_min_alarm, NULL, 0), | ||
936 | SENSOR_ATTR(temp2_min_alarm, S_IRUGO, show_temp_min_alarm, NULL, 1), | ||
937 | SENSOR_ATTR(temp3_min_alarm, S_IRUGO, show_temp_min_alarm, NULL, 2), | ||
938 | }; | ||
939 | static struct sensor_device_attribute temp_max_alarm[] = { | ||
940 | SENSOR_ATTR(temp1_max_alarm, S_IRUGO, show_temp_max_alarm, NULL, 0), | ||
941 | SENSOR_ATTR(temp2_max_alarm, S_IRUGO, show_temp_max_alarm, NULL, 1), | ||
942 | SENSOR_ATTR(temp3_max_alarm, S_IRUGO, show_temp_max_alarm, NULL, 2), | ||
943 | }; | ||
944 | static struct sensor_device_attribute temp_crit_alarm[] = { | ||
945 | SENSOR_ATTR(temp1_crit_alarm, S_IRUGO, show_temp_crit_alarm, NULL, 0), | ||
946 | SENSOR_ATTR(temp2_crit_alarm, S_IRUGO, show_temp_crit_alarm, NULL, 1), | ||
947 | SENSOR_ATTR(temp3_crit_alarm, S_IRUGO, show_temp_crit_alarm, NULL, 2), | ||
948 | }; | ||
949 | |||
950 | #define TEMP_FAULT 0x40 /* open diode */ | ||
951 | static ssize_t show_temp_fault(struct device *dev, | ||
952 | struct device_attribute *devattr, char *buf) | ||
953 | { | ||
954 | struct pc87360_data *data = pc87360_update_device(dev); | ||
955 | unsigned nr = to_sensor_dev_attr(devattr)->index; | ||
956 | |||
957 | return sprintf(buf, "%u\n", !!(data->temp_status[nr] & TEMP_FAULT)); | ||
958 | } | ||
959 | static struct sensor_device_attribute temp_fault[] = { | ||
960 | SENSOR_ATTR(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0), | ||
961 | SENSOR_ATTR(temp2_fault, S_IRUGO, show_temp_fault, NULL, 1), | ||
962 | SENSOR_ATTR(temp3_fault, S_IRUGO, show_temp_fault, NULL, 2), | ||
963 | }; | ||
964 | |||
793 | #define TEMP_UNIT_ATTRS(X) \ | 965 | #define TEMP_UNIT_ATTRS(X) \ |
794 | &temp_input[X].dev_attr.attr, \ | 966 | &temp_input[X].dev_attr.attr, \ |
795 | &temp_status[X].dev_attr.attr, \ | 967 | &temp_status[X].dev_attr.attr, \ |
796 | &temp_min[X].dev_attr.attr, \ | 968 | &temp_min[X].dev_attr.attr, \ |
797 | &temp_max[X].dev_attr.attr, \ | 969 | &temp_max[X].dev_attr.attr, \ |
798 | &temp_crit[X].dev_attr.attr | 970 | &temp_crit[X].dev_attr.attr, \ |
971 | &temp_min_alarm[X].dev_attr.attr, \ | ||
972 | &temp_max_alarm[X].dev_attr.attr, \ | ||
973 | &temp_crit_alarm[X].dev_attr.attr, \ | ||
974 | &temp_fault[X].dev_attr.attr | ||
799 | 975 | ||
800 | static struct attribute * pc8736x_temp_attr_array[] = { | 976 | static struct attribute * pc8736x_temp_attr_array[] = { |
801 | TEMP_UNIT_ATTRS(0), | 977 | TEMP_UNIT_ATTRS(0), |
@@ -809,8 +985,8 @@ static const struct attribute_group pc8736x_temp_group = { | |||
809 | .attrs = pc8736x_temp_attr_array, | 985 | .attrs = pc8736x_temp_attr_array, |
810 | }; | 986 | }; |
811 | 987 | ||
812 | static ssize_t show_name(struct device *dev, struct device_attribute | 988 | static ssize_t show_name(struct device *dev, |
813 | *devattr, char *buf) | 989 | struct device_attribute *devattr, char *buf) |
814 | { | 990 | { |
815 | struct pc87360_data *data = dev_get_drvdata(dev); | 991 | struct pc87360_data *data = dev_get_drvdata(dev); |
816 | return sprintf(buf, "%s\n", data->name); | 992 | return sprintf(buf, "%s\n", data->name); |
@@ -955,7 +1131,7 @@ static int __devinit pc87360_probe(struct platform_device *pdev) | |||
955 | mutex_init(&data->update_lock); | 1131 | mutex_init(&data->update_lock); |
956 | platform_set_drvdata(pdev, data); | 1132 | platform_set_drvdata(pdev, data); |
957 | 1133 | ||
958 | for (i = 0; i < 3; i++) { | 1134 | for (i = 0; i < LDNI_MAX; i++) { |
959 | if (((data->address[i] = extra_isa[i])) | 1135 | if (((data->address[i] = extra_isa[i])) |
960 | && !request_region(extra_isa[i], PC87360_EXTENT, | 1136 | && !request_region(extra_isa[i], PC87360_EXTENT, |
961 | pc87360_driver.driver.name)) { | 1137 | pc87360_driver.driver.name)) { |
@@ -1031,7 +1207,15 @@ static int __devinit pc87360_probe(struct platform_device *pdev) | |||
1031 | || (err = device_create_file(dev, | 1207 | || (err = device_create_file(dev, |
1032 | &temp_crit[i].dev_attr)) | 1208 | &temp_crit[i].dev_attr)) |
1033 | || (err = device_create_file(dev, | 1209 | || (err = device_create_file(dev, |
1034 | &temp_status[i].dev_attr))) | 1210 | &temp_status[i].dev_attr)) |
1211 | || (err = device_create_file(dev, | ||
1212 | &temp_min_alarm[i].dev_attr)) | ||
1213 | || (err = device_create_file(dev, | ||
1214 | &temp_max_alarm[i].dev_attr)) | ||
1215 | || (err = device_create_file(dev, | ||
1216 | &temp_crit_alarm[i].dev_attr)) | ||
1217 | || (err = device_create_file(dev, | ||
1218 | &temp_fault[i].dev_attr))) | ||
1035 | goto ERROR3; | 1219 | goto ERROR3; |
1036 | } | 1220 | } |
1037 | if ((err = device_create_file(dev, &dev_attr_alarms_temp))) | 1221 | if ((err = device_create_file(dev, &dev_attr_alarms_temp))) |
@@ -1131,6 +1315,16 @@ static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank, | |||
1131 | mutex_unlock(&(data->lock)); | 1315 | mutex_unlock(&(data->lock)); |
1132 | } | 1316 | } |
1133 | 1317 | ||
1318 | /* (temp & vin) channel conversion status register flags (pdf sec.11.5.12) */ | ||
1319 | #define CHAN_CNVRTD 0x80 /* new data ready */ | ||
1320 | #define CHAN_ENA 0x01 /* enabled channel (temp or vin) */ | ||
1321 | #define CHAN_ALM_ENA 0x10 /* propagate to alarms-reg ?? (chk val!) */ | ||
1322 | #define CHAN_READY (CHAN_ENA|CHAN_CNVRTD) /* sample ready mask */ | ||
1323 | |||
1324 | #define TEMP_OTS_OE 0x20 /* OTS Output Enable */ | ||
1325 | #define VIN_RW1C_MASK (CHAN_READY|CHAN_ALM_MAX|CHAN_ALM_MIN) /* 0x87 */ | ||
1326 | #define TEMP_RW1C_MASK (VIN_RW1C_MASK|TEMP_ALM_CRIT|TEMP_FAULT) /* 0xCF */ | ||
1327 | |||
1134 | static void pc87360_init_device(struct platform_device *pdev, | 1328 | static void pc87360_init_device(struct platform_device *pdev, |
1135 | int use_thermistors) | 1329 | int use_thermistors) |
1136 | { | 1330 | { |
@@ -1152,11 +1346,12 @@ static void pc87360_init_device(struct platform_device *pdev, | |||
1152 | 1346 | ||
1153 | nr = data->innr < 11 ? data->innr : 11; | 1347 | nr = data->innr < 11 ? data->innr : 11; |
1154 | for (i = 0; i < nr; i++) { | 1348 | for (i = 0; i < nr; i++) { |
1349 | reg = pc87360_read_value(data, LD_IN, i, | ||
1350 | PC87365_REG_IN_STATUS); | ||
1351 | dev_dbg(&pdev->dev, "bios in%d status:0x%02x\n", i, reg); | ||
1155 | if (init >= init_in[i]) { | 1352 | if (init >= init_in[i]) { |
1156 | /* Forcibly enable voltage channel */ | 1353 | /* Forcibly enable voltage channel */ |
1157 | reg = pc87360_read_value(data, LD_IN, i, | 1354 | if (!(reg & CHAN_ENA)) { |
1158 | PC87365_REG_IN_STATUS); | ||
1159 | if (!(reg & 0x01)) { | ||
1160 | dev_dbg(&pdev->dev, "Forcibly " | 1355 | dev_dbg(&pdev->dev, "Forcibly " |
1161 | "enabling in%d\n", i); | 1356 | "enabling in%d\n", i); |
1162 | pc87360_write_value(data, LD_IN, i, | 1357 | pc87360_write_value(data, LD_IN, i, |
@@ -1168,19 +1363,24 @@ static void pc87360_init_device(struct platform_device *pdev, | |||
1168 | 1363 | ||
1169 | /* We can't blindly trust the Super-I/O space configuration bit, | 1364 | /* We can't blindly trust the Super-I/O space configuration bit, |
1170 | most BIOS won't set it properly */ | 1365 | most BIOS won't set it properly */ |
1366 | dev_dbg(&pdev->dev, "bios thermistors:%d\n", use_thermistors); | ||
1171 | for (i = 11; i < data->innr; i++) { | 1367 | for (i = 11; i < data->innr; i++) { |
1172 | reg = pc87360_read_value(data, LD_IN, i, | 1368 | reg = pc87360_read_value(data, LD_IN, i, |
1173 | PC87365_REG_TEMP_STATUS); | 1369 | PC87365_REG_TEMP_STATUS); |
1174 | use_thermistors = use_thermistors || (reg & 0x01); | 1370 | use_thermistors = use_thermistors || (reg & CHAN_ENA); |
1371 | /* thermistors are temp[4-6], measured on vin[11-14] */ | ||
1372 | dev_dbg(&pdev->dev, "bios temp%d_status:0x%02x\n", i-7, reg); | ||
1175 | } | 1373 | } |
1374 | dev_dbg(&pdev->dev, "using thermistors:%d\n", use_thermistors); | ||
1176 | 1375 | ||
1177 | i = use_thermistors ? 2 : 0; | 1376 | i = use_thermistors ? 2 : 0; |
1178 | for (; i < data->tempnr; i++) { | 1377 | for (; i < data->tempnr; i++) { |
1378 | reg = pc87360_read_value(data, LD_TEMP, i, | ||
1379 | PC87365_REG_TEMP_STATUS); | ||
1380 | dev_dbg(&pdev->dev, "bios temp%d_status:0x%02x\n", i+1, reg); | ||
1179 | if (init >= init_temp[i]) { | 1381 | if (init >= init_temp[i]) { |
1180 | /* Forcibly enable temperature channel */ | 1382 | /* Forcibly enable temperature channel */ |
1181 | reg = pc87360_read_value(data, LD_TEMP, i, | 1383 | if (!(reg & CHAN_ENA)) { |
1182 | PC87365_REG_TEMP_STATUS); | ||
1183 | if (!(reg & 0x01)) { | ||
1184 | dev_dbg(&pdev->dev, "Forcibly " | 1384 | dev_dbg(&pdev->dev, "Forcibly " |
1185 | "enabling temp%d\n", i+1); | 1385 | "enabling temp%d\n", i+1); |
1186 | pc87360_write_value(data, LD_TEMP, i, | 1386 | pc87360_write_value(data, LD_TEMP, i, |
@@ -1197,7 +1397,7 @@ static void pc87360_init_device(struct platform_device *pdev, | |||
1197 | diodes */ | 1397 | diodes */ |
1198 | reg = pc87360_read_value(data, LD_TEMP, | 1398 | reg = pc87360_read_value(data, LD_TEMP, |
1199 | (i-11)/2, PC87365_REG_TEMP_STATUS); | 1399 | (i-11)/2, PC87365_REG_TEMP_STATUS); |
1200 | if (reg & 0x01) { | 1400 | if (reg & CHAN_ENA) { |
1201 | dev_dbg(&pdev->dev, "Skipping " | 1401 | dev_dbg(&pdev->dev, "Skipping " |
1202 | "temp%d, pin already in use " | 1402 | "temp%d, pin already in use " |
1203 | "by temp%d\n", i-7, (i-11)/2); | 1403 | "by temp%d\n", i-7, (i-11)/2); |
@@ -1207,7 +1407,7 @@ static void pc87360_init_device(struct platform_device *pdev, | |||
1207 | /* Forcibly enable thermistor channel */ | 1407 | /* Forcibly enable thermistor channel */ |
1208 | reg = pc87360_read_value(data, LD_IN, i, | 1408 | reg = pc87360_read_value(data, LD_IN, i, |
1209 | PC87365_REG_IN_STATUS); | 1409 | PC87365_REG_IN_STATUS); |
1210 | if (!(reg & 0x01)) { | 1410 | if (!(reg & CHAN_ENA)) { |
1211 | dev_dbg(&pdev->dev, "Forcibly " | 1411 | dev_dbg(&pdev->dev, "Forcibly " |
1212 | "enabling temp%d\n", i-7); | 1412 | "enabling temp%d\n", i-7); |
1213 | pc87360_write_value(data, LD_IN, i, | 1413 | pc87360_write_value(data, LD_IN, i, |
@@ -1221,7 +1421,8 @@ static void pc87360_init_device(struct platform_device *pdev, | |||
1221 | if (data->innr) { | 1421 | if (data->innr) { |
1222 | reg = pc87360_read_value(data, LD_IN, NO_BANK, | 1422 | reg = pc87360_read_value(data, LD_IN, NO_BANK, |
1223 | PC87365_REG_IN_CONFIG); | 1423 | PC87365_REG_IN_CONFIG); |
1224 | if (reg & 0x01) { | 1424 | dev_dbg(&pdev->dev, "bios vin-cfg:0x%02x\n", reg); |
1425 | if (reg & CHAN_ENA) { | ||
1225 | dev_dbg(&pdev->dev, "Forcibly " | 1426 | dev_dbg(&pdev->dev, "Forcibly " |
1226 | "enabling monitoring (VLM)\n"); | 1427 | "enabling monitoring (VLM)\n"); |
1227 | pc87360_write_value(data, LD_IN, NO_BANK, | 1428 | pc87360_write_value(data, LD_IN, NO_BANK, |
@@ -1233,7 +1434,8 @@ static void pc87360_init_device(struct platform_device *pdev, | |||
1233 | if (data->tempnr) { | 1434 | if (data->tempnr) { |
1234 | reg = pc87360_read_value(data, LD_TEMP, NO_BANK, | 1435 | reg = pc87360_read_value(data, LD_TEMP, NO_BANK, |
1235 | PC87365_REG_TEMP_CONFIG); | 1436 | PC87365_REG_TEMP_CONFIG); |
1236 | if (reg & 0x01) { | 1437 | dev_dbg(&pdev->dev, "bios temp-cfg:0x%02x\n", reg); |
1438 | if (reg & CHAN_ENA) { | ||
1237 | dev_dbg(&pdev->dev, "Forcibly enabling " | 1439 | dev_dbg(&pdev->dev, "Forcibly enabling " |
1238 | "monitoring (TMS)\n"); | 1440 | "monitoring (TMS)\n"); |
1239 | pc87360_write_value(data, LD_TEMP, NO_BANK, | 1441 | pc87360_write_value(data, LD_TEMP, NO_BANK, |
@@ -1336,11 +1538,11 @@ static struct pc87360_data *pc87360_update_device(struct device *dev) | |||
1336 | pc87360_write_value(data, LD_IN, i, | 1538 | pc87360_write_value(data, LD_IN, i, |
1337 | PC87365_REG_IN_STATUS, | 1539 | PC87365_REG_IN_STATUS, |
1338 | data->in_status[i]); | 1540 | data->in_status[i]); |
1339 | if ((data->in_status[i] & 0x81) == 0x81) { | 1541 | if ((data->in_status[i] & CHAN_READY) == CHAN_READY) { |
1340 | data->in[i] = pc87360_read_value(data, LD_IN, | 1542 | data->in[i] = pc87360_read_value(data, LD_IN, |
1341 | i, PC87365_REG_IN); | 1543 | i, PC87365_REG_IN); |
1342 | } | 1544 | } |
1343 | if (data->in_status[i] & 0x01) { | 1545 | if (data->in_status[i] & CHAN_ENA) { |
1344 | data->in_min[i] = pc87360_read_value(data, | 1546 | data->in_min[i] = pc87360_read_value(data, |
1345 | LD_IN, i, | 1547 | LD_IN, i, |
1346 | PC87365_REG_IN_MIN); | 1548 | PC87365_REG_IN_MIN); |
@@ -1373,12 +1575,12 @@ static struct pc87360_data *pc87360_update_device(struct device *dev) | |||
1373 | pc87360_write_value(data, LD_TEMP, i, | 1575 | pc87360_write_value(data, LD_TEMP, i, |
1374 | PC87365_REG_TEMP_STATUS, | 1576 | PC87365_REG_TEMP_STATUS, |
1375 | data->temp_status[i]); | 1577 | data->temp_status[i]); |
1376 | if ((data->temp_status[i] & 0x81) == 0x81) { | 1578 | if ((data->temp_status[i] & CHAN_READY) == CHAN_READY) { |
1377 | data->temp[i] = pc87360_read_value(data, | 1579 | data->temp[i] = pc87360_read_value(data, |
1378 | LD_TEMP, i, | 1580 | LD_TEMP, i, |
1379 | PC87365_REG_TEMP); | 1581 | PC87365_REG_TEMP); |
1380 | } | 1582 | } |
1381 | if (data->temp_status[i] & 0x01) { | 1583 | if (data->temp_status[i] & CHAN_ENA) { |
1382 | data->temp_min[i] = pc87360_read_value(data, | 1584 | data->temp_min[i] = pc87360_read_value(data, |
1383 | LD_TEMP, i, | 1585 | LD_TEMP, i, |
1384 | PC87365_REG_TEMP_MIN); | 1586 | PC87365_REG_TEMP_MIN); |
diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c index 1ea39254dac6..424dad6f18d8 100644 --- a/drivers/i2c/busses/i2c-amd756.c +++ b/drivers/i2c/busses/i2c-amd756.c | |||
@@ -332,10 +332,6 @@ static int __devinit amd756_probe(struct pci_dev *pdev, | |||
332 | int error; | 332 | int error; |
333 | u8 temp; | 333 | u8 temp; |
334 | 334 | ||
335 | /* driver_data might come from user-space, so check it */ | ||
336 | if (id->driver_data >= ARRAY_SIZE(chipname)) | ||
337 | return -EINVAL; | ||
338 | |||
339 | if (amd756_ioport) { | 335 | if (amd756_ioport) { |
340 | dev_err(&pdev->dev, "Only one device supported " | 336 | dev_err(&pdev->dev, "Only one device supported " |
341 | "(you have a strange motherboard, btw)\n"); | 337 | "(you have a strange motherboard, btw)\n"); |
@@ -412,7 +408,6 @@ static struct pci_driver amd756_driver = { | |||
412 | .id_table = amd756_ids, | 408 | .id_table = amd756_ids, |
413 | .probe = amd756_probe, | 409 | .probe = amd756_probe, |
414 | .remove = __devexit_p(amd756_remove), | 410 | .remove = __devexit_p(amd756_remove), |
415 | .dynids.use_driver_data = 1, | ||
416 | }; | 411 | }; |
417 | 412 | ||
418 | static int __init amd756_init(void) | 413 | static int __init amd756_init(void) |
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index 73dc52e114eb..9f194d9efd91 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c | |||
@@ -332,10 +332,6 @@ static int __devinit vt596_probe(struct pci_dev *pdev, | |||
332 | unsigned char temp; | 332 | unsigned char temp; |
333 | int error = -ENODEV; | 333 | int error = -ENODEV; |
334 | 334 | ||
335 | /* driver_data might come from user-space, so check it */ | ||
336 | if (id->driver_data & 1 || id->driver_data > 0xff) | ||
337 | return -EINVAL; | ||
338 | |||
339 | /* Determine the address of the SMBus areas */ | 335 | /* Determine the address of the SMBus areas */ |
340 | if (force_addr) { | 336 | if (force_addr) { |
341 | vt596_smba = force_addr & 0xfff0; | 337 | vt596_smba = force_addr & 0xfff0; |
@@ -483,7 +479,6 @@ static struct pci_driver vt596_driver = { | |||
483 | .name = "vt596_smbus", | 479 | .name = "vt596_smbus", |
484 | .id_table = vt596_ids, | 480 | .id_table = vt596_ids, |
485 | .probe = vt596_probe, | 481 | .probe = vt596_probe, |
486 | .dynids.use_driver_data = 1, | ||
487 | }; | 482 | }; |
488 | 483 | ||
489 | static int __init i2c_vt596_init(void) | 484 | static int __init i2c_vt596_init(void) |
diff --git a/drivers/i2c/chips/at24.c b/drivers/i2c/chips/at24.c index 2a4acb269569..d4775528abc6 100644 --- a/drivers/i2c/chips/at24.c +++ b/drivers/i2c/chips/at24.c | |||
@@ -460,7 +460,6 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
460 | */ | 460 | */ |
461 | at24->bin.attr.name = "eeprom"; | 461 | at24->bin.attr.name = "eeprom"; |
462 | at24->bin.attr.mode = chip.flags & AT24_FLAG_IRUGO ? S_IRUGO : S_IRUSR; | 462 | at24->bin.attr.mode = chip.flags & AT24_FLAG_IRUGO ? S_IRUGO : S_IRUSR; |
463 | at24->bin.attr.owner = THIS_MODULE; | ||
464 | at24->bin.read = at24_bin_read; | 463 | at24->bin.read = at24_bin_read; |
465 | at24->bin.size = chip.byte_len; | 464 | at24->bin.size = chip.byte_len; |
466 | 465 | ||
diff --git a/drivers/i2c/chips/ds1682.c b/drivers/i2c/chips/ds1682.c index 23be4d42cb02..f3ee4a1abb77 100644 --- a/drivers/i2c/chips/ds1682.c +++ b/drivers/i2c/chips/ds1682.c | |||
@@ -190,7 +190,6 @@ static struct bin_attribute ds1682_eeprom_attr = { | |||
190 | .attr = { | 190 | .attr = { |
191 | .name = "eeprom", | 191 | .name = "eeprom", |
192 | .mode = S_IRUGO | S_IWUSR, | 192 | .mode = S_IRUGO | S_IWUSR, |
193 | .owner = THIS_MODULE, | ||
194 | }, | 193 | }, |
195 | .size = DS1682_EEPROM_SIZE, | 194 | .size = DS1682_EEPROM_SIZE, |
196 | .read = ds1682_eeprom_read, | 195 | .read = ds1682_eeprom_read, |
diff --git a/drivers/i2c/chips/menelaus.c b/drivers/i2c/chips/menelaus.c index 176126d3a01d..4b364bae6b3e 100644 --- a/drivers/i2c/chips/menelaus.c +++ b/drivers/i2c/chips/menelaus.c | |||
@@ -832,52 +832,52 @@ static irqreturn_t menelaus_irq(int irq, void *_menelaus) | |||
832 | 832 | ||
833 | static void menelaus_to_time(char *regs, struct rtc_time *t) | 833 | static void menelaus_to_time(char *regs, struct rtc_time *t) |
834 | { | 834 | { |
835 | t->tm_sec = BCD2BIN(regs[0]); | 835 | t->tm_sec = bcd2bin(regs[0]); |
836 | t->tm_min = BCD2BIN(regs[1]); | 836 | t->tm_min = bcd2bin(regs[1]); |
837 | if (the_menelaus->rtc_control & RTC_CTRL_MODE12) { | 837 | if (the_menelaus->rtc_control & RTC_CTRL_MODE12) { |
838 | t->tm_hour = BCD2BIN(regs[2] & 0x1f) - 1; | 838 | t->tm_hour = bcd2bin(regs[2] & 0x1f) - 1; |
839 | if (regs[2] & RTC_HR_PM) | 839 | if (regs[2] & RTC_HR_PM) |
840 | t->tm_hour += 12; | 840 | t->tm_hour += 12; |
841 | } else | 841 | } else |
842 | t->tm_hour = BCD2BIN(regs[2] & 0x3f); | 842 | t->tm_hour = bcd2bin(regs[2] & 0x3f); |
843 | t->tm_mday = BCD2BIN(regs[3]); | 843 | t->tm_mday = bcd2bin(regs[3]); |
844 | t->tm_mon = BCD2BIN(regs[4]) - 1; | 844 | t->tm_mon = bcd2bin(regs[4]) - 1; |
845 | t->tm_year = BCD2BIN(regs[5]) + 100; | 845 | t->tm_year = bcd2bin(regs[5]) + 100; |
846 | } | 846 | } |
847 | 847 | ||
848 | static int time_to_menelaus(struct rtc_time *t, int regnum) | 848 | static int time_to_menelaus(struct rtc_time *t, int regnum) |
849 | { | 849 | { |
850 | int hour, status; | 850 | int hour, status; |
851 | 851 | ||
852 | status = menelaus_write_reg(regnum++, BIN2BCD(t->tm_sec)); | 852 | status = menelaus_write_reg(regnum++, bin2bcd(t->tm_sec)); |
853 | if (status < 0) | 853 | if (status < 0) |
854 | goto fail; | 854 | goto fail; |
855 | 855 | ||
856 | status = menelaus_write_reg(regnum++, BIN2BCD(t->tm_min)); | 856 | status = menelaus_write_reg(regnum++, bin2bcd(t->tm_min)); |
857 | if (status < 0) | 857 | if (status < 0) |
858 | goto fail; | 858 | goto fail; |
859 | 859 | ||
860 | if (the_menelaus->rtc_control & RTC_CTRL_MODE12) { | 860 | if (the_menelaus->rtc_control & RTC_CTRL_MODE12) { |
861 | hour = t->tm_hour + 1; | 861 | hour = t->tm_hour + 1; |
862 | if (hour > 12) | 862 | if (hour > 12) |
863 | hour = RTC_HR_PM | BIN2BCD(hour - 12); | 863 | hour = RTC_HR_PM | bin2bcd(hour - 12); |
864 | else | 864 | else |
865 | hour = BIN2BCD(hour); | 865 | hour = bin2bcd(hour); |
866 | } else | 866 | } else |
867 | hour = BIN2BCD(t->tm_hour); | 867 | hour = bin2bcd(t->tm_hour); |
868 | status = menelaus_write_reg(regnum++, hour); | 868 | status = menelaus_write_reg(regnum++, hour); |
869 | if (status < 0) | 869 | if (status < 0) |
870 | goto fail; | 870 | goto fail; |
871 | 871 | ||
872 | status = menelaus_write_reg(regnum++, BIN2BCD(t->tm_mday)); | 872 | status = menelaus_write_reg(regnum++, bin2bcd(t->tm_mday)); |
873 | if (status < 0) | 873 | if (status < 0) |
874 | goto fail; | 874 | goto fail; |
875 | 875 | ||
876 | status = menelaus_write_reg(regnum++, BIN2BCD(t->tm_mon + 1)); | 876 | status = menelaus_write_reg(regnum++, bin2bcd(t->tm_mon + 1)); |
877 | if (status < 0) | 877 | if (status < 0) |
878 | goto fail; | 878 | goto fail; |
879 | 879 | ||
880 | status = menelaus_write_reg(regnum++, BIN2BCD(t->tm_year - 100)); | 880 | status = menelaus_write_reg(regnum++, bin2bcd(t->tm_year - 100)); |
881 | if (status < 0) | 881 | if (status < 0) |
882 | goto fail; | 882 | goto fail; |
883 | 883 | ||
@@ -914,7 +914,7 @@ static int menelaus_read_time(struct device *dev, struct rtc_time *t) | |||
914 | } | 914 | } |
915 | 915 | ||
916 | menelaus_to_time(regs, t); | 916 | menelaus_to_time(regs, t); |
917 | t->tm_wday = BCD2BIN(regs[6]); | 917 | t->tm_wday = bcd2bin(regs[6]); |
918 | 918 | ||
919 | return 0; | 919 | return 0; |
920 | } | 920 | } |
@@ -927,7 +927,7 @@ static int menelaus_set_time(struct device *dev, struct rtc_time *t) | |||
927 | status = time_to_menelaus(t, MENELAUS_RTC_SEC); | 927 | status = time_to_menelaus(t, MENELAUS_RTC_SEC); |
928 | if (status < 0) | 928 | if (status < 0) |
929 | return status; | 929 | return status; |
930 | status = menelaus_write_reg(MENELAUS_RTC_WKDAY, BIN2BCD(t->tm_wday)); | 930 | status = menelaus_write_reg(MENELAUS_RTC_WKDAY, bin2bcd(t->tm_wday)); |
931 | if (status < 0) { | 931 | if (status < 0) { |
932 | dev_err(&the_menelaus->client->dev, "rtc write reg %02x " | 932 | dev_err(&the_menelaus->client->dev, "rtc write reg %02x " |
933 | "err %d\n", MENELAUS_RTC_WKDAY, status); | 933 | "err %d\n", MENELAUS_RTC_WKDAY, status); |
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 74a369a6116f..a820ca6fc327 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
@@ -84,21 +84,40 @@ config BLK_DEV_IDE_SATA | |||
84 | 84 | ||
85 | If unsure, say N. | 85 | If unsure, say N. |
86 | 86 | ||
87 | config BLK_DEV_IDEDISK | 87 | config IDE_GD |
88 | tristate "Include IDE/ATA-2 DISK support" | 88 | tristate "generic ATA/ATAPI disk support" |
89 | ---help--- | 89 | default y |
90 | This will include enhanced support for MFM/RLL/IDE hard disks. If | 90 | help |
91 | you have a MFM/RLL/IDE disk, and there is no special reason to use | 91 | Support for ATA/ATAPI disks (including ATAPI floppy drives). |
92 | the old hard disk driver instead, say Y. If you have an SCSI-only | ||
93 | system, you can say N here. | ||
94 | 92 | ||
95 | To compile this driver as a module, choose M here: the | 93 | To compile this driver as a module, choose M here. |
96 | module will be called ide-disk. | 94 | The module will be called ide-gd_mod. |
97 | Do not compile this driver as a module if your root file system | 95 | |
98 | (the one containing the directory /) is located on the IDE disk. | 96 | If unsure, say Y. |
97 | |||
98 | config IDE_GD_ATA | ||
99 | bool "ATA disk support" | ||
100 | depends on IDE_GD | ||
101 | default y | ||
102 | help | ||
103 | This will include support for ATA hard disks. | ||
99 | 104 | ||
100 | If unsure, say Y. | 105 | If unsure, say Y. |
101 | 106 | ||
107 | config IDE_GD_ATAPI | ||
108 | bool "ATAPI floppy support" | ||
109 | depends on IDE_GD | ||
110 | select IDE_ATAPI | ||
111 | help | ||
112 | This will include support for ATAPI floppy drives | ||
113 | (i.e. Iomega ZIP or MKE LS-120). | ||
114 | |||
115 | For information about jumper settings and the question | ||
116 | of when a ZIP drive uses a partition table, see | ||
117 | <http://www.win.tue.nl/~aeb/linux/zip/zip-1.html>. | ||
118 | |||
119 | If unsure, say N. | ||
120 | |||
102 | config BLK_DEV_IDECS | 121 | config BLK_DEV_IDECS |
103 | tristate "PCMCIA IDE support" | 122 | tristate "PCMCIA IDE support" |
104 | depends on PCMCIA | 123 | depends on PCMCIA |
@@ -163,29 +182,6 @@ config BLK_DEV_IDETAPE | |||
163 | To compile this driver as a module, choose M here: the | 182 | To compile this driver as a module, choose M here: the |
164 | module will be called ide-tape. | 183 | module will be called ide-tape. |
165 | 184 | ||
166 | config BLK_DEV_IDEFLOPPY | ||
167 | tristate "Include IDE/ATAPI FLOPPY support" | ||
168 | select IDE_ATAPI | ||
169 | ---help--- | ||
170 | If you have an IDE floppy drive which uses the ATAPI protocol, | ||
171 | answer Y. ATAPI is a newer protocol used by IDE CD-ROM/tape/floppy | ||
172 | drives, similar to the SCSI protocol. | ||
173 | |||
174 | The LS-120 and the IDE/ATAPI Iomega ZIP drive are also supported by | ||
175 | this driver. For information about jumper settings and the question | ||
176 | of when a ZIP drive uses a partition table, see | ||
177 | <http://www.win.tue.nl/~aeb/linux/zip/zip-1.html>. | ||
178 | (ATAPI PD-CD/CDR drives are not supported by this driver; support | ||
179 | for PD-CD/CDR drives is available if you answer Y to | ||
180 | "SCSI emulation support", below). | ||
181 | |||
182 | If you say Y here, the FLOPPY drive will be identified along with | ||
183 | other IDE devices, as "hdb" or "hdc", or something similar (check | ||
184 | the boot messages with dmesg). | ||
185 | |||
186 | To compile this driver as a module, choose M here: the | ||
187 | module will be called ide-floppy. | ||
188 | |||
189 | config BLK_DEV_IDESCSI | 185 | config BLK_DEV_IDESCSI |
190 | tristate "SCSI emulation support (DEPRECATED)" | 186 | tristate "SCSI emulation support (DEPRECATED)" |
191 | depends on SCSI | 187 | depends on SCSI |
@@ -332,7 +328,7 @@ config IDEPCI_PCIBUS_ORDER | |||
332 | # TODO: split it on per host driver config options (or module parameters) | 328 | # TODO: split it on per host driver config options (or module parameters) |
333 | config BLK_DEV_OFFBOARD | 329 | config BLK_DEV_OFFBOARD |
334 | bool "Boot off-board chipsets first support (DEPRECATED)" | 330 | bool "Boot off-board chipsets first support (DEPRECATED)" |
335 | depends on BLK_DEV_IDEPCI && (BLK_DEV_AEC62XX || BLK_DEV_GENERIC || BLK_DEV_HPT34X || BLK_DEV_HPT366 || BLK_DEV_PDC202XX_NEW || BLK_DEV_PDC202XX_OLD || BLK_DEV_TC86C001) | 331 | depends on BLK_DEV_IDEPCI && (BLK_DEV_AEC62XX || BLK_DEV_GENERIC || BLK_DEV_HPT366 || BLK_DEV_PDC202XX_NEW || BLK_DEV_PDC202XX_OLD || BLK_DEV_TC86C001) |
336 | help | 332 | help |
337 | Normally, IDE controllers built into the motherboard (on-board | 333 | Normally, IDE controllers built into the motherboard (on-board |
338 | controllers) are assigned to ide0 and ide1 while those on add-in PCI | 334 | controllers) are assigned to ide0 and ide1 while those on add-in PCI |
@@ -482,28 +478,6 @@ config BLK_DEV_CS5535 | |||
482 | 478 | ||
483 | It is safe to say Y to this question. | 479 | It is safe to say Y to this question. |
484 | 480 | ||
485 | config BLK_DEV_HPT34X | ||
486 | tristate "HPT34X chipset support" | ||
487 | depends on BROKEN | ||
488 | select BLK_DEV_IDEDMA_PCI | ||
489 | help | ||
490 | This driver adds up to 4 more EIDE devices sharing a single | ||
491 | interrupt. The HPT343 chipset in its current form is a non-bootable | ||
492 | controller; the HPT345/HPT363 chipset is a bootable (needs BIOS FIX) | ||
493 | PCI UDMA controllers. This driver requires dynamic tuning of the | ||
494 | chipset during the ide-probe at boot time. It is reported to support | ||
495 | DVD II drives, by the manufacturer. | ||
496 | |||
497 | config HPT34X_AUTODMA | ||
498 | bool "HPT34X AUTODMA support (EXPERIMENTAL)" | ||
499 | depends on BLK_DEV_HPT34X && EXPERIMENTAL | ||
500 | help | ||
501 | This is a dangerous thing to attempt currently! Please read the | ||
502 | comments at the top of <file:drivers/ide/pci/hpt34x.c>. If you say Y | ||
503 | here, then say Y to "Use DMA by default when available" as well. | ||
504 | |||
505 | If unsure, say N. | ||
506 | |||
507 | config BLK_DEV_HPT366 | 481 | config BLK_DEV_HPT366 |
508 | tristate "HPT36X/37X chipset support" | 482 | tristate "HPT36X/37X chipset support" |
509 | select BLK_DEV_IDEDMA_PCI | 483 | select BLK_DEV_IDEDMA_PCI |
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index ceaf779054ea..093d3248ca89 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile | |||
@@ -37,18 +37,25 @@ obj-$(CONFIG_IDE_H8300) += h8300/ | |||
37 | obj-$(CONFIG_IDE_GENERIC) += ide-generic.o | 37 | obj-$(CONFIG_IDE_GENERIC) += ide-generic.o |
38 | obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o | 38 | obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o |
39 | 39 | ||
40 | ide-disk_mod-y += ide-disk.o ide-disk_ioctl.o | 40 | ide-gd_mod-y += ide-gd.o |
41 | ide-cd_mod-y += ide-cd.o ide-cd_ioctl.o ide-cd_verbose.o | 41 | ide-cd_mod-y += ide-cd.o ide-cd_ioctl.o ide-cd_verbose.o |
42 | ide-floppy_mod-y += ide-floppy.o ide-floppy_ioctl.o | ||
43 | 42 | ||
43 | ifeq ($(CONFIG_IDE_GD_ATA), y) | ||
44 | ide-gd_mod-y += ide-disk.o ide-disk_ioctl.o | ||
44 | ifeq ($(CONFIG_IDE_PROC_FS), y) | 45 | ifeq ($(CONFIG_IDE_PROC_FS), y) |
45 | ide-disk_mod-y += ide-disk_proc.o | 46 | ide-gd_mod-y += ide-disk_proc.o |
46 | ide-floppy_mod-y += ide-floppy_proc.o | 47 | endif |
48 | endif | ||
49 | |||
50 | ifeq ($(CONFIG_IDE_GD_ATAPI), y) | ||
51 | ide-gd_mod-y += ide-floppy.o ide-floppy_ioctl.o | ||
52 | ifeq ($(CONFIG_IDE_PROC_FS), y) | ||
53 | ide-gd_mod-y += ide-floppy_proc.o | ||
54 | endif | ||
47 | endif | 55 | endif |
48 | 56 | ||
49 | obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk_mod.o | 57 | obj-$(CONFIG_IDE_GD) += ide-gd_mod.o |
50 | obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd_mod.o | 58 | obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd_mod.o |
51 | obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy_mod.o | ||
52 | obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o | 59 | obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o |
53 | 60 | ||
54 | ifeq ($(CONFIG_BLK_DEV_IDECS), y) | 61 | ifeq ($(CONFIG_BLK_DEV_IDECS), y) |
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 2e305714c209..4e58b9e7a58a 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c | |||
@@ -191,7 +191,7 @@ int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on) | |||
191 | { | 191 | { |
192 | struct ide_atapi_pc pc; | 192 | struct ide_atapi_pc pc; |
193 | 193 | ||
194 | if (drive->atapi_flags & IDE_AFLAG_NO_DOORLOCK) | 194 | if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) |
195 | return 0; | 195 | return 0; |
196 | 196 | ||
197 | ide_init_pc(&pc); | 197 | ide_init_pc(&pc); |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 3308b1cd3a33..13265a8827da 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -99,7 +99,7 @@ static void ide_cd_put(struct cdrom_info *cd) | |||
99 | /* Mark that we've seen a media change and invalidate our internal buffers. */ | 99 | /* Mark that we've seen a media change and invalidate our internal buffers. */ |
100 | static void cdrom_saw_media_change(ide_drive_t *drive) | 100 | static void cdrom_saw_media_change(ide_drive_t *drive) |
101 | { | 101 | { |
102 | drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED; | 102 | drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; |
103 | drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID; | 103 | drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID; |
104 | } | 104 | } |
105 | 105 | ||
@@ -340,8 +340,8 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) | |||
340 | } | 340 | } |
341 | 341 | ||
342 | ide_debug_log(IDE_DBG_RQ, "%s: stat: 0x%x, good_stat: 0x%x, " | 342 | ide_debug_log(IDE_DBG_RQ, "%s: stat: 0x%x, good_stat: 0x%x, " |
343 | "rq->cmd_type: 0x%x, err: 0x%x\n", __func__, stat, | 343 | "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x, err: 0x%x\n", |
344 | good_stat, rq->cmd_type, err); | 344 | __func__, stat, good_stat, rq->cmd[0], rq->cmd_type, err); |
345 | 345 | ||
346 | if (blk_sense_request(rq)) { | 346 | if (blk_sense_request(rq)) { |
347 | /* | 347 | /* |
@@ -843,13 +843,10 @@ static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq) | |||
843 | rq->q->prep_rq_fn(rq->q, rq); | 843 | rq->q->prep_rq_fn(rq->q, rq); |
844 | } | 844 | } |
845 | 845 | ||
846 | /* | ||
847 | * All other packet commands. | ||
848 | */ | ||
849 | static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq) | 846 | static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq) |
850 | { | 847 | { |
851 | 848 | ide_debug_log(IDE_DBG_FUNC, "Call %s, rq->cmd[0]: 0x%x\n", | |
852 | ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); | 849 | __func__, rq->cmd[0]); |
853 | 850 | ||
854 | /* | 851 | /* |
855 | * Some of the trailing request sense fields are optional, | 852 | * Some of the trailing request sense fields are optional, |
@@ -876,7 +873,7 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, | |||
876 | if (!sense) | 873 | if (!sense) |
877 | sense = &local_sense; | 874 | sense = &local_sense; |
878 | 875 | ||
879 | ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x, " | 876 | ide_debug_log(IDE_DBG_PC, "Call %s, cmd[0]: 0x%x, write: 0x%x, " |
880 | "timeout: %d, cmd_flags: 0x%x\n", __func__, cmd[0], write, | 877 | "timeout: %d, cmd_flags: 0x%x\n", __func__, cmd[0], write, |
881 | timeout, cmd_flags); | 878 | timeout, cmd_flags); |
882 | 879 | ||
@@ -1177,8 +1174,9 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) | |||
1177 | unsigned short sectors_per_frame = | 1174 | unsigned short sectors_per_frame = |
1178 | queue_hardsect_size(drive->queue) >> SECTOR_BITS; | 1175 | queue_hardsect_size(drive->queue) >> SECTOR_BITS; |
1179 | 1176 | ||
1180 | ide_debug_log(IDE_DBG_RQ, "Call %s, write: 0x%x, secs_per_frame: %u\n", | 1177 | ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x, " |
1181 | __func__, write, sectors_per_frame); | 1178 | "secs_per_frame: %u\n", |
1179 | __func__, rq->cmd[0], write, sectors_per_frame); | ||
1182 | 1180 | ||
1183 | if (write) { | 1181 | if (write) { |
1184 | /* disk has become write protected */ | 1182 | /* disk has become write protected */ |
@@ -1221,7 +1219,8 @@ static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive) | |||
1221 | static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) | 1219 | static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) |
1222 | { | 1220 | { |
1223 | 1221 | ||
1224 | ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd_type: 0x%x\n", __func__, | 1222 | ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, " |
1223 | "rq->cmd_type: 0x%x\n", __func__, rq->cmd[0], | ||
1225 | rq->cmd_type); | 1224 | rq->cmd_type); |
1226 | 1225 | ||
1227 | if (blk_pc_request(rq)) | 1226 | if (blk_pc_request(rq)) |
@@ -1257,9 +1256,6 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) | |||
1257 | } | 1256 | } |
1258 | } | 1257 | } |
1259 | 1258 | ||
1260 | /* | ||
1261 | * cdrom driver request routine. | ||
1262 | */ | ||
1263 | static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, | 1259 | static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, |
1264 | sector_t block) | 1260 | sector_t block) |
1265 | { | 1261 | { |
@@ -1267,8 +1263,10 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, | |||
1267 | ide_handler_t *fn; | 1263 | ide_handler_t *fn; |
1268 | int xferlen; | 1264 | int xferlen; |
1269 | 1265 | ||
1270 | ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd_type: 0x%x, block: %llu\n", | 1266 | ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, " |
1271 | __func__, rq->cmd_type, (unsigned long long)block); | 1267 | "rq->cmd_type: 0x%x, block: %llu\n", |
1268 | __func__, rq->cmd[0], rq->cmd_type, | ||
1269 | (unsigned long long)block); | ||
1272 | 1270 | ||
1273 | if (blk_fs_request(rq)) { | 1271 | if (blk_fs_request(rq)) { |
1274 | if (drive->atapi_flags & IDE_AFLAG_SEEKING) { | 1272 | if (drive->atapi_flags & IDE_AFLAG_SEEKING) { |
@@ -1412,6 +1410,10 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, | |||
1412 | 1410 | ||
1413 | *capacity = 1 + be32_to_cpu(capbuf.lba); | 1411 | *capacity = 1 + be32_to_cpu(capbuf.lba); |
1414 | *sectors_per_frame = blocklen >> SECTOR_BITS; | 1412 | *sectors_per_frame = blocklen >> SECTOR_BITS; |
1413 | |||
1414 | ide_debug_log(IDE_DBG_PROBE, "%s: cap: %lu, sectors_per_frame: %lu\n", | ||
1415 | __func__, *capacity, *sectors_per_frame); | ||
1416 | |||
1415 | return 0; | 1417 | return 0; |
1416 | } | 1418 | } |
1417 | 1419 | ||
@@ -1643,6 +1645,9 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf) | |||
1643 | maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]); | 1645 | maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]); |
1644 | } | 1646 | } |
1645 | 1647 | ||
1648 | ide_debug_log(IDE_DBG_PROBE, "%s: curspeed: %u, maxspeed: %u\n", | ||
1649 | __func__, curspeed, maxspeed); | ||
1650 | |||
1646 | cd->current_speed = (curspeed + (176/2)) / 176; | 1651 | cd->current_speed = (curspeed + (176/2)) / 176; |
1647 | cd->max_speed = (maxspeed + (176/2)) / 176; | 1652 | cd->max_speed = (maxspeed + (176/2)) / 176; |
1648 | } | 1653 | } |
@@ -1732,7 +1737,7 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive) | |||
1732 | return 0; | 1737 | return 0; |
1733 | 1738 | ||
1734 | if ((buf[8 + 6] & 0x01) == 0) | 1739 | if ((buf[8 + 6] & 0x01) == 0) |
1735 | drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK; | 1740 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; |
1736 | if (buf[8 + 6] & 0x08) | 1741 | if (buf[8 + 6] & 0x08) |
1737 | drive->atapi_flags &= ~IDE_AFLAG_NO_EJECT; | 1742 | drive->atapi_flags &= ~IDE_AFLAG_NO_EJECT; |
1738 | if (buf[8 + 3] & 0x01) | 1743 | if (buf[8 + 3] & 0x01) |
@@ -1777,7 +1782,7 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive) | |||
1777 | if ((cdi->mask & CDC_DVD_R) == 0 || (cdi->mask & CDC_DVD_RAM) == 0) | 1782 | if ((cdi->mask & CDC_DVD_R) == 0 || (cdi->mask & CDC_DVD_RAM) == 0) |
1778 | printk(KERN_CONT " DVD%s%s", | 1783 | printk(KERN_CONT " DVD%s%s", |
1779 | (cdi->mask & CDC_DVD_R) ? "" : "-R", | 1784 | (cdi->mask & CDC_DVD_R) ? "" : "-R", |
1780 | (cdi->mask & CDC_DVD_RAM) ? "" : "-RAM"); | 1785 | (cdi->mask & CDC_DVD_RAM) ? "" : "/RAM"); |
1781 | 1786 | ||
1782 | if ((cdi->mask & CDC_CD_R) == 0 || (cdi->mask & CDC_CD_RW) == 0) | 1787 | if ((cdi->mask & CDC_CD_R) == 0 || (cdi->mask & CDC_CD_RW) == 0) |
1783 | printk(KERN_CONT " CD%s%s", | 1788 | printk(KERN_CONT " CD%s%s", |
@@ -1908,6 +1913,16 @@ static const struct ide_proc_devset idecd_settings[] = { | |||
1908 | IDE_PROC_DEVSET(dsc_overlap, 0, 1), | 1913 | IDE_PROC_DEVSET(dsc_overlap, 0, 1), |
1909 | { 0 }, | 1914 | { 0 }, |
1910 | }; | 1915 | }; |
1916 | |||
1917 | static ide_proc_entry_t *ide_cd_proc_entries(ide_drive_t *drive) | ||
1918 | { | ||
1919 | return idecd_proc; | ||
1920 | } | ||
1921 | |||
1922 | static const struct ide_proc_devset *ide_cd_proc_devsets(ide_drive_t *drive) | ||
1923 | { | ||
1924 | return idecd_settings; | ||
1925 | } | ||
1911 | #endif | 1926 | #endif |
1912 | 1927 | ||
1913 | static const struct cd_list_entry ide_cd_quirks_list[] = { | 1928 | static const struct cd_list_entry ide_cd_quirks_list[] = { |
@@ -1986,8 +2001,8 @@ static int ide_cdrom_setup(ide_drive_t *drive) | |||
1986 | if (!drive->queue->unplug_delay) | 2001 | if (!drive->queue->unplug_delay) |
1987 | drive->queue->unplug_delay = 1; | 2002 | drive->queue->unplug_delay = 1; |
1988 | 2003 | ||
1989 | drive->atapi_flags = IDE_AFLAG_MEDIA_CHANGED | IDE_AFLAG_NO_EJECT | | 2004 | drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; |
1990 | ide_cd_flags(id); | 2005 | drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id); |
1991 | 2006 | ||
1992 | if ((drive->atapi_flags & IDE_AFLAG_VERTOS_300_SSD) && | 2007 | if ((drive->atapi_flags & IDE_AFLAG_VERTOS_300_SSD) && |
1993 | fw_rev[4] == '1' && fw_rev[6] <= '2') | 2008 | fw_rev[4] == '1' && fw_rev[6] <= '2') |
@@ -2069,8 +2084,8 @@ static ide_driver_t ide_cdrom_driver = { | |||
2069 | .end_request = ide_end_request, | 2084 | .end_request = ide_end_request, |
2070 | .error = __ide_error, | 2085 | .error = __ide_error, |
2071 | #ifdef CONFIG_IDE_PROC_FS | 2086 | #ifdef CONFIG_IDE_PROC_FS |
2072 | .proc = idecd_proc, | 2087 | .proc_entries = ide_cd_proc_entries, |
2073 | .settings = idecd_settings, | 2088 | .proc_devsets = ide_cd_proc_devsets, |
2074 | #endif | 2089 | #endif |
2075 | }; | 2090 | }; |
2076 | 2091 | ||
diff --git a/drivers/ide/ide-cd_ioctl.c b/drivers/ide/ide-cd_ioctl.c index 74231b41f611..df3df0041eb6 100644 --- a/drivers/ide/ide-cd_ioctl.c +++ b/drivers/ide/ide-cd_ioctl.c | |||
@@ -86,8 +86,8 @@ int ide_cdrom_check_media_change_real(struct cdrom_device_info *cdi, | |||
86 | 86 | ||
87 | if (slot_nr == CDSL_CURRENT) { | 87 | if (slot_nr == CDSL_CURRENT) { |
88 | (void) cdrom_check_status(drive, NULL); | 88 | (void) cdrom_check_status(drive, NULL); |
89 | retval = (drive->atapi_flags & IDE_AFLAG_MEDIA_CHANGED) ? 1 : 0; | 89 | retval = (drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED) ? 1 : 0; |
90 | drive->atapi_flags &= ~IDE_AFLAG_MEDIA_CHANGED; | 90 | drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; |
91 | return retval; | 91 | return retval; |
92 | } else { | 92 | } else { |
93 | return -EINVAL; | 93 | return -EINVAL; |
@@ -136,7 +136,7 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag, | |||
136 | sense = &my_sense; | 136 | sense = &my_sense; |
137 | 137 | ||
138 | /* If the drive cannot lock the door, just pretend. */ | 138 | /* If the drive cannot lock the door, just pretend. */ |
139 | if (drive->atapi_flags & IDE_AFLAG_NO_DOORLOCK) { | 139 | if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) { |
140 | stat = 0; | 140 | stat = 0; |
141 | } else { | 141 | } else { |
142 | unsigned char cmd[BLK_MAX_CDB]; | 142 | unsigned char cmd[BLK_MAX_CDB]; |
@@ -157,7 +157,7 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag, | |||
157 | (sense->asc == 0x24 || sense->asc == 0x20)) { | 157 | (sense->asc == 0x24 || sense->asc == 0x20)) { |
158 | printk(KERN_ERR "%s: door locking not supported\n", | 158 | printk(KERN_ERR "%s: door locking not supported\n", |
159 | drive->name); | 159 | drive->name); |
160 | drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK; | 160 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; |
161 | stat = 0; | 161 | stat = 0; |
162 | } | 162 | } |
163 | 163 | ||
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 3853bde8eedc..223750c1b5a6 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -14,9 +14,6 @@ | |||
14 | * This is the IDE/ATA disk driver, as evolved from hd.c and ide.c. | 14 | * This is the IDE/ATA disk driver, as evolved from hd.c and ide.c. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #define IDEDISK_VERSION "1.18" | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/types.h> | 17 | #include <linux/types.h> |
21 | #include <linux/string.h> | 18 | #include <linux/string.h> |
22 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
@@ -39,46 +36,8 @@ | |||
39 | #include <asm/io.h> | 36 | #include <asm/io.h> |
40 | #include <asm/div64.h> | 37 | #include <asm/div64.h> |
41 | 38 | ||
42 | #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT) | ||
43 | #define IDE_DISK_MINORS (1 << PARTN_BITS) | ||
44 | #else | ||
45 | #define IDE_DISK_MINORS 0 | ||
46 | #endif | ||
47 | |||
48 | #include "ide-disk.h" | 39 | #include "ide-disk.h" |
49 | 40 | ||
50 | static DEFINE_MUTEX(idedisk_ref_mutex); | ||
51 | |||
52 | #define to_ide_disk(obj) container_of(obj, struct ide_disk_obj, kref) | ||
53 | |||
54 | static void ide_disk_release(struct kref *); | ||
55 | |||
56 | static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) | ||
57 | { | ||
58 | struct ide_disk_obj *idkp = NULL; | ||
59 | |||
60 | mutex_lock(&idedisk_ref_mutex); | ||
61 | idkp = ide_disk_g(disk); | ||
62 | if (idkp) { | ||
63 | if (ide_device_get(idkp->drive)) | ||
64 | idkp = NULL; | ||
65 | else | ||
66 | kref_get(&idkp->kref); | ||
67 | } | ||
68 | mutex_unlock(&idedisk_ref_mutex); | ||
69 | return idkp; | ||
70 | } | ||
71 | |||
72 | static void ide_disk_put(struct ide_disk_obj *idkp) | ||
73 | { | ||
74 | ide_drive_t *drive = idkp->drive; | ||
75 | |||
76 | mutex_lock(&idedisk_ref_mutex); | ||
77 | kref_put(&idkp->kref, ide_disk_release); | ||
78 | ide_device_put(drive); | ||
79 | mutex_unlock(&idedisk_ref_mutex); | ||
80 | } | ||
81 | |||
82 | static const u8 ide_rw_cmds[] = { | 41 | static const u8 ide_rw_cmds[] = { |
83 | ATA_CMD_READ_MULTI, | 42 | ATA_CMD_READ_MULTI, |
84 | ATA_CMD_WRITE_MULTI, | 43 | ATA_CMD_WRITE_MULTI, |
@@ -374,7 +333,7 @@ static void idedisk_check_hpa(ide_drive_t *drive) | |||
374 | } | 333 | } |
375 | } | 334 | } |
376 | 335 | ||
377 | static void init_idedisk_capacity(ide_drive_t *drive) | 336 | static int ide_disk_get_capacity(ide_drive_t *drive) |
378 | { | 337 | { |
379 | u16 *id = drive->id; | 338 | u16 *id = drive->id; |
380 | int lba; | 339 | int lba; |
@@ -403,11 +362,28 @@ static void init_idedisk_capacity(ide_drive_t *drive) | |||
403 | if (ata_id_hpa_enabled(id)) | 362 | if (ata_id_hpa_enabled(id)) |
404 | idedisk_check_hpa(drive); | 363 | idedisk_check_hpa(drive); |
405 | } | 364 | } |
406 | } | ||
407 | 365 | ||
408 | sector_t ide_disk_capacity(ide_drive_t *drive) | 366 | /* limit drive capacity to 137GB if LBA48 cannot be used */ |
409 | { | 367 | if ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 && |
410 | return drive->capacity64; | 368 | drive->capacity64 > 1ULL << 28) { |
369 | printk(KERN_WARNING "%s: cannot use LBA48 - full capacity " | ||
370 | "%llu sectors (%llu MB)\n", | ||
371 | drive->name, (unsigned long long)drive->capacity64, | ||
372 | sectors_to_MB(drive->capacity64)); | ||
373 | drive->capacity64 = 1ULL << 28; | ||
374 | } | ||
375 | |||
376 | if ((drive->hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && | ||
377 | (drive->dev_flags & IDE_DFLAG_LBA48)) { | ||
378 | if (drive->capacity64 > 1ULL << 28) { | ||
379 | printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode" | ||
380 | " will be used for accessing sectors " | ||
381 | "> %u\n", drive->name, 1 << 28); | ||
382 | } else | ||
383 | drive->dev_flags &= ~IDE_DFLAG_LBA48; | ||
384 | } | ||
385 | |||
386 | return 0; | ||
411 | } | 387 | } |
412 | 388 | ||
413 | static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) | 389 | static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) |
@@ -508,7 +484,7 @@ static void update_ordered(ide_drive_t *drive) | |||
508 | * time we have trimmed the drive capacity if LBA48 is | 484 | * time we have trimmed the drive capacity if LBA48 is |
509 | * not available so we don't need to recheck that. | 485 | * not available so we don't need to recheck that. |
510 | */ | 486 | */ |
511 | capacity = ide_disk_capacity(drive); | 487 | capacity = ide_gd_capacity(drive); |
512 | barrier = ata_id_flush_enabled(id) && | 488 | barrier = ata_id_flush_enabled(id) && |
513 | (drive->dev_flags & IDE_DFLAG_NOFLUSH) == 0 && | 489 | (drive->dev_flags & IDE_DFLAG_NOFLUSH) == 0 && |
514 | ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 || | 490 | ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 || |
@@ -616,7 +592,12 @@ ide_ext_devset_rw(wcache, wcache); | |||
616 | 592 | ||
617 | ide_ext_devset_rw_sync(nowerr, nowerr); | 593 | ide_ext_devset_rw_sync(nowerr, nowerr); |
618 | 594 | ||
619 | static void idedisk_setup(ide_drive_t *drive) | 595 | static int ide_disk_check(ide_drive_t *drive, const char *s) |
596 | { | ||
597 | return 1; | ||
598 | } | ||
599 | |||
600 | static void ide_disk_setup(ide_drive_t *drive) | ||
620 | { | 601 | { |
621 | struct ide_disk_obj *idkp = drive->driver_data; | 602 | struct ide_disk_obj *idkp = drive->driver_data; |
622 | ide_hwif_t *hwif = drive->hwif; | 603 | ide_hwif_t *hwif = drive->hwif; |
@@ -652,33 +633,13 @@ static void idedisk_setup(ide_drive_t *drive) | |||
652 | drive->queue->max_sectors / 2); | 633 | drive->queue->max_sectors / 2); |
653 | 634 | ||
654 | /* calculate drive capacity, and select LBA if possible */ | 635 | /* calculate drive capacity, and select LBA if possible */ |
655 | init_idedisk_capacity(drive); | 636 | ide_disk_get_capacity(drive); |
656 | |||
657 | /* limit drive capacity to 137GB if LBA48 cannot be used */ | ||
658 | if ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 && | ||
659 | drive->capacity64 > 1ULL << 28) { | ||
660 | printk(KERN_WARNING "%s: cannot use LBA48 - full capacity " | ||
661 | "%llu sectors (%llu MB)\n", | ||
662 | drive->name, (unsigned long long)drive->capacity64, | ||
663 | sectors_to_MB(drive->capacity64)); | ||
664 | drive->capacity64 = 1ULL << 28; | ||
665 | } | ||
666 | |||
667 | if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && | ||
668 | (drive->dev_flags & IDE_DFLAG_LBA48)) { | ||
669 | if (drive->capacity64 > 1ULL << 28) { | ||
670 | printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode" | ||
671 | " will be used for accessing sectors " | ||
672 | "> %u\n", drive->name, 1 << 28); | ||
673 | } else | ||
674 | drive->dev_flags &= ~IDE_DFLAG_LBA48; | ||
675 | } | ||
676 | 637 | ||
677 | /* | 638 | /* |
678 | * if possible, give fdisk access to more of the drive, | 639 | * if possible, give fdisk access to more of the drive, |
679 | * by correcting bios_cyls: | 640 | * by correcting bios_cyls: |
680 | */ | 641 | */ |
681 | capacity = ide_disk_capacity(drive); | 642 | capacity = ide_gd_capacity(drive); |
682 | 643 | ||
683 | if ((drive->dev_flags & IDE_DFLAG_FORCED_GEOM) == 0) { | 644 | if ((drive->dev_flags & IDE_DFLAG_FORCED_GEOM) == 0) { |
684 | if (ata_id_lba48_enabled(drive->id)) { | 645 | if (ata_id_lba48_enabled(drive->id)) { |
@@ -718,9 +679,17 @@ static void idedisk_setup(ide_drive_t *drive) | |||
718 | drive->dev_flags |= IDE_DFLAG_WCACHE; | 679 | drive->dev_flags |= IDE_DFLAG_WCACHE; |
719 | 680 | ||
720 | set_wcache(drive, 1); | 681 | set_wcache(drive, 1); |
682 | |||
683 | if ((drive->dev_flags & IDE_DFLAG_LBA) == 0 && | ||
684 | (drive->head == 0 || drive->head > 16)) { | ||
685 | printk(KERN_ERR "%s: invalid geometry: %d physical heads?\n", | ||
686 | drive->name, drive->head); | ||
687 | drive->dev_flags &= ~IDE_DFLAG_ATTACH; | ||
688 | } else | ||
689 | drive->dev_flags |= IDE_DFLAG_ATTACH; | ||
721 | } | 690 | } |
722 | 691 | ||
723 | static void ide_cacheflush_p(ide_drive_t *drive) | 692 | static void ide_disk_flush(ide_drive_t *drive) |
724 | { | 693 | { |
725 | if (ata_id_flush_enabled(drive->id) == 0 || | 694 | if (ata_id_flush_enabled(drive->id) == 0 || |
726 | (drive->dev_flags & IDE_DFLAG_WCACHE) == 0) | 695 | (drive->dev_flags & IDE_DFLAG_WCACHE) == 0) |
@@ -730,267 +699,40 @@ static void ide_cacheflush_p(ide_drive_t *drive) | |||
730 | printk(KERN_INFO "%s: wcache flush failed!\n", drive->name); | 699 | printk(KERN_INFO "%s: wcache flush failed!\n", drive->name); |
731 | } | 700 | } |
732 | 701 | ||
733 | static void ide_disk_remove(ide_drive_t *drive) | 702 | static int ide_disk_init_media(ide_drive_t *drive, struct gendisk *disk) |
734 | { | ||
735 | struct ide_disk_obj *idkp = drive->driver_data; | ||
736 | struct gendisk *g = idkp->disk; | ||
737 | |||
738 | ide_proc_unregister_driver(drive, idkp->driver); | ||
739 | |||
740 | del_gendisk(g); | ||
741 | |||
742 | ide_cacheflush_p(drive); | ||
743 | |||
744 | ide_disk_put(idkp); | ||
745 | } | ||
746 | |||
747 | static void ide_disk_release(struct kref *kref) | ||
748 | { | ||
749 | struct ide_disk_obj *idkp = to_ide_disk(kref); | ||
750 | ide_drive_t *drive = idkp->drive; | ||
751 | struct gendisk *g = idkp->disk; | ||
752 | |||
753 | drive->driver_data = NULL; | ||
754 | g->private_data = NULL; | ||
755 | put_disk(g); | ||
756 | kfree(idkp); | ||
757 | } | ||
758 | |||
759 | static int ide_disk_probe(ide_drive_t *drive); | ||
760 | |||
761 | /* | ||
762 | * On HPA drives the capacity needs to be | ||
763 | * reinitilized on resume otherwise the disk | ||
764 | * can not be used and a hard reset is required | ||
765 | */ | ||
766 | static void ide_disk_resume(ide_drive_t *drive) | ||
767 | { | 703 | { |
768 | if (ata_id_hpa_enabled(drive->id)) | 704 | return 0; |
769 | init_idedisk_capacity(drive); | ||
770 | } | ||
771 | |||
772 | static void ide_device_shutdown(ide_drive_t *drive) | ||
773 | { | ||
774 | #ifdef CONFIG_ALPHA | ||
775 | /* On Alpha, halt(8) doesn't actually turn the machine off, | ||
776 | it puts you into the sort of firmware monitor. Typically, | ||
777 | it's used to boot another kernel image, so it's not much | ||
778 | different from reboot(8). Therefore, we don't need to | ||
779 | spin down the disk in this case, especially since Alpha | ||
780 | firmware doesn't handle disks in standby mode properly. | ||
781 | On the other hand, it's reasonably safe to turn the power | ||
782 | off when the shutdown process reaches the firmware prompt, | ||
783 | as the firmware initialization takes rather long time - | ||
784 | at least 10 seconds, which should be sufficient for | ||
785 | the disk to expire its write cache. */ | ||
786 | if (system_state != SYSTEM_POWER_OFF) { | ||
787 | #else | ||
788 | if (system_state == SYSTEM_RESTART) { | ||
789 | #endif | ||
790 | ide_cacheflush_p(drive); | ||
791 | return; | ||
792 | } | ||
793 | |||
794 | printk(KERN_INFO "Shutdown: %s\n", drive->name); | ||
795 | |||
796 | drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND); | ||
797 | } | 705 | } |
798 | 706 | ||
799 | static ide_driver_t idedisk_driver = { | 707 | static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk, |
800 | .gen_driver = { | 708 | int on) |
801 | .owner = THIS_MODULE, | ||
802 | .name = "ide-disk", | ||
803 | .bus = &ide_bus_type, | ||
804 | }, | ||
805 | .probe = ide_disk_probe, | ||
806 | .remove = ide_disk_remove, | ||
807 | .resume = ide_disk_resume, | ||
808 | .shutdown = ide_device_shutdown, | ||
809 | .version = IDEDISK_VERSION, | ||
810 | .do_request = ide_do_rw_disk, | ||
811 | .end_request = ide_end_request, | ||
812 | .error = __ide_error, | ||
813 | #ifdef CONFIG_IDE_PROC_FS | ||
814 | .proc = ide_disk_proc, | ||
815 | .settings = ide_disk_settings, | ||
816 | #endif | ||
817 | }; | ||
818 | |||
819 | static int idedisk_set_doorlock(ide_drive_t *drive, int on) | ||
820 | { | 709 | { |
821 | ide_task_t task; | 710 | ide_task_t task; |
711 | int ret; | ||
712 | |||
713 | if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) | ||
714 | return 0; | ||
822 | 715 | ||
823 | memset(&task, 0, sizeof(task)); | 716 | memset(&task, 0, sizeof(task)); |
824 | task.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK; | 717 | task.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK; |
825 | task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 718 | task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
826 | 719 | ||
827 | return ide_no_data_taskfile(drive, &task); | 720 | ret = ide_no_data_taskfile(drive, &task); |
828 | } | ||
829 | |||
830 | static int idedisk_open(struct inode *inode, struct file *filp) | ||
831 | { | ||
832 | struct gendisk *disk = inode->i_bdev->bd_disk; | ||
833 | struct ide_disk_obj *idkp; | ||
834 | ide_drive_t *drive; | ||
835 | |||
836 | idkp = ide_disk_get(disk); | ||
837 | if (idkp == NULL) | ||
838 | return -ENXIO; | ||
839 | |||
840 | drive = idkp->drive; | ||
841 | |||
842 | idkp->openers++; | ||
843 | |||
844 | if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) { | ||
845 | check_disk_change(inode->i_bdev); | ||
846 | /* | ||
847 | * Ignore the return code from door_lock, | ||
848 | * since the open() has already succeeded, | ||
849 | * and the door_lock is irrelevant at this point. | ||
850 | */ | ||
851 | if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) && | ||
852 | idedisk_set_doorlock(drive, 1)) | ||
853 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; | ||
854 | } | ||
855 | return 0; | ||
856 | } | ||
857 | |||
858 | static int idedisk_release(struct inode *inode, struct file *filp) | ||
859 | { | ||
860 | struct gendisk *disk = inode->i_bdev->bd_disk; | ||
861 | struct ide_disk_obj *idkp = ide_disk_g(disk); | ||
862 | ide_drive_t *drive = idkp->drive; | ||
863 | |||
864 | if (idkp->openers == 1) | ||
865 | ide_cacheflush_p(drive); | ||
866 | |||
867 | if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) { | ||
868 | if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) && | ||
869 | idedisk_set_doorlock(drive, 0)) | ||
870 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; | ||
871 | } | ||
872 | 721 | ||
873 | idkp->openers--; | 722 | if (ret) |
723 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; | ||
874 | 724 | ||
875 | ide_disk_put(idkp); | 725 | return ret; |
876 | |||
877 | return 0; | ||
878 | } | ||
879 | |||
880 | static int idedisk_getgeo(struct block_device *bdev, struct hd_geometry *geo) | ||
881 | { | ||
882 | struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk); | ||
883 | ide_drive_t *drive = idkp->drive; | ||
884 | |||
885 | geo->heads = drive->bios_head; | ||
886 | geo->sectors = drive->bios_sect; | ||
887 | geo->cylinders = (u16)drive->bios_cyl; /* truncate */ | ||
888 | return 0; | ||
889 | } | 726 | } |
890 | 727 | ||
891 | static int idedisk_media_changed(struct gendisk *disk) | 728 | const struct ide_disk_ops ide_ata_disk_ops = { |
892 | { | 729 | .check = ide_disk_check, |
893 | struct ide_disk_obj *idkp = ide_disk_g(disk); | 730 | .get_capacity = ide_disk_get_capacity, |
894 | ide_drive_t *drive = idkp->drive; | 731 | .setup = ide_disk_setup, |
895 | 732 | .flush = ide_disk_flush, | |
896 | /* do not scan partitions twice if this is a removable device */ | 733 | .init_media = ide_disk_init_media, |
897 | if (drive->dev_flags & IDE_DFLAG_ATTACH) { | 734 | .set_doorlock = ide_disk_set_doorlock, |
898 | drive->dev_flags &= ~IDE_DFLAG_ATTACH; | 735 | .do_request = ide_do_rw_disk, |
899 | return 0; | 736 | .end_request = ide_end_request, |
900 | } | 737 | .ioctl = ide_disk_ioctl, |
901 | |||
902 | /* if removable, always assume it was changed */ | ||
903 | return !!(drive->dev_flags & IDE_DFLAG_REMOVABLE); | ||
904 | } | ||
905 | |||
906 | static int idedisk_revalidate_disk(struct gendisk *disk) | ||
907 | { | ||
908 | struct ide_disk_obj *idkp = ide_disk_g(disk); | ||
909 | set_capacity(disk, ide_disk_capacity(idkp->drive)); | ||
910 | return 0; | ||
911 | } | ||
912 | |||
913 | static struct block_device_operations idedisk_ops = { | ||
914 | .owner = THIS_MODULE, | ||
915 | .open = idedisk_open, | ||
916 | .release = idedisk_release, | ||
917 | .ioctl = ide_disk_ioctl, | ||
918 | .getgeo = idedisk_getgeo, | ||
919 | .media_changed = idedisk_media_changed, | ||
920 | .revalidate_disk = idedisk_revalidate_disk | ||
921 | }; | 738 | }; |
922 | |||
923 | MODULE_DESCRIPTION("ATA DISK Driver"); | ||
924 | |||
925 | static int ide_disk_probe(ide_drive_t *drive) | ||
926 | { | ||
927 | struct ide_disk_obj *idkp; | ||
928 | struct gendisk *g; | ||
929 | |||
930 | /* strstr("foo", "") is non-NULL */ | ||
931 | if (!strstr("ide-disk", drive->driver_req)) | ||
932 | goto failed; | ||
933 | |||
934 | if (drive->media != ide_disk) | ||
935 | goto failed; | ||
936 | |||
937 | idkp = kzalloc(sizeof(*idkp), GFP_KERNEL); | ||
938 | if (!idkp) | ||
939 | goto failed; | ||
940 | |||
941 | g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif)); | ||
942 | if (!g) | ||
943 | goto out_free_idkp; | ||
944 | |||
945 | ide_init_disk(g, drive); | ||
946 | |||
947 | kref_init(&idkp->kref); | ||
948 | |||
949 | idkp->drive = drive; | ||
950 | idkp->driver = &idedisk_driver; | ||
951 | idkp->disk = g; | ||
952 | |||
953 | g->private_data = &idkp->driver; | ||
954 | |||
955 | drive->driver_data = idkp; | ||
956 | |||
957 | idedisk_setup(drive); | ||
958 | if ((drive->dev_flags & IDE_DFLAG_LBA) == 0 && | ||
959 | (drive->head == 0 || drive->head > 16)) { | ||
960 | printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", | ||
961 | drive->name, drive->head); | ||
962 | drive->dev_flags &= ~IDE_DFLAG_ATTACH; | ||
963 | } else | ||
964 | drive->dev_flags |= IDE_DFLAG_ATTACH; | ||
965 | |||
966 | g->minors = IDE_DISK_MINORS; | ||
967 | g->driverfs_dev = &drive->gendev; | ||
968 | g->flags |= GENHD_FL_EXT_DEVT; | ||
969 | if (drive->dev_flags & IDE_DFLAG_REMOVABLE) | ||
970 | g->flags = GENHD_FL_REMOVABLE; | ||
971 | set_capacity(g, ide_disk_capacity(drive)); | ||
972 | g->fops = &idedisk_ops; | ||
973 | add_disk(g); | ||
974 | return 0; | ||
975 | |||
976 | out_free_idkp: | ||
977 | kfree(idkp); | ||
978 | failed: | ||
979 | return -ENODEV; | ||
980 | } | ||
981 | |||
982 | static void __exit idedisk_exit(void) | ||
983 | { | ||
984 | driver_unregister(&idedisk_driver.gen_driver); | ||
985 | } | ||
986 | |||
987 | static int __init idedisk_init(void) | ||
988 | { | ||
989 | return driver_register(&idedisk_driver.gen_driver); | ||
990 | } | ||
991 | |||
992 | MODULE_ALIAS("ide:*m-disk*"); | ||
993 | MODULE_ALIAS("ide-disk"); | ||
994 | module_init(idedisk_init); | ||
995 | module_exit(idedisk_exit); | ||
996 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ide/ide-disk.h b/drivers/ide/ide-disk.h index a82fa4355665..b234b0feaf7b 100644 --- a/drivers/ide/ide-disk.h +++ b/drivers/ide/ide-disk.h | |||
@@ -1,19 +1,11 @@ | |||
1 | #ifndef __IDE_DISK_H | 1 | #ifndef __IDE_DISK_H |
2 | #define __IDE_DISK_H | 2 | #define __IDE_DISK_H |
3 | 3 | ||
4 | struct ide_disk_obj { | 4 | #include "ide-gd.h" |
5 | ide_drive_t *drive; | ||
6 | ide_driver_t *driver; | ||
7 | struct gendisk *disk; | ||
8 | struct kref kref; | ||
9 | unsigned int openers; /* protected by BKL for now */ | ||
10 | }; | ||
11 | |||
12 | #define ide_disk_g(disk) \ | ||
13 | container_of((disk)->private_data, struct ide_disk_obj, driver) | ||
14 | 5 | ||
6 | #ifdef CONFIG_IDE_GD_ATA | ||
15 | /* ide-disk.c */ | 7 | /* ide-disk.c */ |
16 | sector_t ide_disk_capacity(ide_drive_t *); | 8 | extern const struct ide_disk_ops ide_ata_disk_ops; |
17 | ide_decl_devset(address); | 9 | ide_decl_devset(address); |
18 | ide_decl_devset(multcount); | 10 | ide_decl_devset(multcount); |
19 | ide_decl_devset(nowerr); | 11 | ide_decl_devset(nowerr); |
@@ -21,12 +13,17 @@ ide_decl_devset(wcache); | |||
21 | ide_decl_devset(acoustic); | 13 | ide_decl_devset(acoustic); |
22 | 14 | ||
23 | /* ide-disk_ioctl.c */ | 15 | /* ide-disk_ioctl.c */ |
24 | int ide_disk_ioctl(struct inode *, struct file *, unsigned int, unsigned long); | 16 | int ide_disk_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int, |
17 | unsigned long); | ||
25 | 18 | ||
26 | #ifdef CONFIG_IDE_PROC_FS | 19 | #ifdef CONFIG_IDE_PROC_FS |
27 | /* ide-disk_proc.c */ | 20 | /* ide-disk_proc.c */ |
28 | extern ide_proc_entry_t ide_disk_proc[]; | 21 | extern ide_proc_entry_t ide_disk_proc[]; |
29 | extern const struct ide_proc_devset ide_disk_settings[]; | 22 | extern const struct ide_proc_devset ide_disk_settings[]; |
30 | #endif | 23 | #endif |
24 | #else | ||
25 | #define ide_disk_proc NULL | ||
26 | #define ide_disk_settings NULL | ||
27 | #endif | ||
31 | 28 | ||
32 | #endif /* __IDE_DISK_H */ | 29 | #endif /* __IDE_DISK_H */ |
diff --git a/drivers/ide/ide-disk_ioctl.c b/drivers/ide/ide-disk_ioctl.c index a6cf1a03a806..a49698bcf966 100644 --- a/drivers/ide/ide-disk_ioctl.c +++ b/drivers/ide/ide-disk_ioctl.c | |||
@@ -13,12 +13,10 @@ static const struct ide_ioctl_devset ide_disk_ioctl_settings[] = { | |||
13 | { 0 } | 13 | { 0 } |
14 | }; | 14 | }; |
15 | 15 | ||
16 | int ide_disk_ioctl(struct inode *inode, struct file *file, | 16 | int ide_disk_ioctl(ide_drive_t *drive, struct inode *inode, struct file *file, |
17 | unsigned int cmd, unsigned long arg) | 17 | unsigned int cmd, unsigned long arg) |
18 | { | 18 | { |
19 | struct block_device *bdev = inode->i_bdev; | 19 | struct block_device *bdev = inode->i_bdev; |
20 | struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk); | ||
21 | ide_drive_t *drive = idkp->drive; | ||
22 | int err; | 20 | int err; |
23 | 21 | ||
24 | err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings); | 22 | err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings); |
diff --git a/drivers/ide/ide-disk_proc.c b/drivers/ide/ide-disk_proc.c index 4724976afe71..1146f4204c6e 100644 --- a/drivers/ide/ide-disk_proc.c +++ b/drivers/ide/ide-disk_proc.c | |||
@@ -56,7 +56,7 @@ static int proc_idedisk_read_capacity | |||
56 | ide_drive_t*drive = (ide_drive_t *)data; | 56 | ide_drive_t*drive = (ide_drive_t *)data; |
57 | int len; | 57 | int len; |
58 | 58 | ||
59 | len = sprintf(page, "%llu\n", (long long)ide_disk_capacity(drive)); | 59 | len = sprintf(page, "%llu\n", (long long)ide_gd_capacity(drive)); |
60 | 60 | ||
61 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); | 61 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); |
62 | } | 62 | } |
diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c index 0903782689e9..cac431f0df17 100644 --- a/drivers/ide/ide-dma-sff.c +++ b/drivers/ide/ide-dma-sff.c | |||
@@ -130,7 +130,7 @@ int ide_build_dmatable(ide_drive_t *drive, struct request *rq) | |||
130 | xcount = bcount & 0xffff; | 130 | xcount = bcount & 0xffff; |
131 | if (is_trm290) | 131 | if (is_trm290) |
132 | xcount = ((xcount >> 2) - 1) << 16; | 132 | xcount = ((xcount >> 2) - 1) << 16; |
133 | if (xcount == 0x0000) { | 133 | else if (xcount == 0x0000) { |
134 | if (count++ >= PRD_ENTRIES) | 134 | if (count++ >= PRD_ENTRIES) |
135 | goto use_pio_instead; | 135 | goto use_pio_instead; |
136 | *table++ = cpu_to_le32(0x8000); | 136 | *table++ = cpu_to_le32(0x8000); |
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index cf0aa25470ee..aeb1ad782f54 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
@@ -15,12 +15,6 @@ | |||
15 | * Documentation/ide/ChangeLog.ide-floppy.1996-2002 | 15 | * Documentation/ide/ChangeLog.ide-floppy.1996-2002 |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #define DRV_NAME "ide-floppy" | ||
19 | #define PFX DRV_NAME ": " | ||
20 | |||
21 | #define IDEFLOPPY_VERSION "1.00" | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/types.h> | 18 | #include <linux/types.h> |
25 | #include <linux/string.h> | 19 | #include <linux/string.h> |
26 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
@@ -49,19 +43,6 @@ | |||
49 | 43 | ||
50 | #include "ide-floppy.h" | 44 | #include "ide-floppy.h" |
51 | 45 | ||
52 | /* module parameters */ | ||
53 | static unsigned long debug_mask; | ||
54 | module_param(debug_mask, ulong, 0644); | ||
55 | |||
56 | /* define to see debug info */ | ||
57 | #define IDEFLOPPY_DEBUG_LOG 0 | ||
58 | |||
59 | #if IDEFLOPPY_DEBUG_LOG | ||
60 | #define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args) | ||
61 | #else | ||
62 | #define ide_debug_log(lvl, fmt, args...) do {} while (0) | ||
63 | #endif | ||
64 | |||
65 | /* | 46 | /* |
66 | * After each failed packet command we issue a request sense command and retry | 47 | * After each failed packet command we issue a request sense command and retry |
67 | * the packet command IDEFLOPPY_MAX_PC_RETRIES times. | 48 | * the packet command IDEFLOPPY_MAX_PC_RETRIES times. |
@@ -83,43 +64,13 @@ module_param(debug_mask, ulong, 0644); | |||
83 | /* Error code returned in rq->errors to the higher part of the driver. */ | 64 | /* Error code returned in rq->errors to the higher part of the driver. */ |
84 | #define IDEFLOPPY_ERROR_GENERAL 101 | 65 | #define IDEFLOPPY_ERROR_GENERAL 101 |
85 | 66 | ||
86 | static DEFINE_MUTEX(idefloppy_ref_mutex); | ||
87 | |||
88 | static void idefloppy_cleanup_obj(struct kref *); | ||
89 | |||
90 | static struct ide_floppy_obj *ide_floppy_get(struct gendisk *disk) | ||
91 | { | ||
92 | struct ide_floppy_obj *floppy = NULL; | ||
93 | |||
94 | mutex_lock(&idefloppy_ref_mutex); | ||
95 | floppy = ide_drv_g(disk, ide_floppy_obj); | ||
96 | if (floppy) { | ||
97 | if (ide_device_get(floppy->drive)) | ||
98 | floppy = NULL; | ||
99 | else | ||
100 | kref_get(&floppy->kref); | ||
101 | } | ||
102 | mutex_unlock(&idefloppy_ref_mutex); | ||
103 | return floppy; | ||
104 | } | ||
105 | |||
106 | static void ide_floppy_put(struct ide_floppy_obj *floppy) | ||
107 | { | ||
108 | ide_drive_t *drive = floppy->drive; | ||
109 | |||
110 | mutex_lock(&idefloppy_ref_mutex); | ||
111 | kref_put(&floppy->kref, idefloppy_cleanup_obj); | ||
112 | ide_device_put(drive); | ||
113 | mutex_unlock(&idefloppy_ref_mutex); | ||
114 | } | ||
115 | |||
116 | /* | 67 | /* |
117 | * Used to finish servicing a request. For read/write requests, we will call | 68 | * Used to finish servicing a request. For read/write requests, we will call |
118 | * ide_end_request to pass to the next buffer. | 69 | * ide_end_request to pass to the next buffer. |
119 | */ | 70 | */ |
120 | static int idefloppy_end_request(ide_drive_t *drive, int uptodate, int nsecs) | 71 | static int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs) |
121 | { | 72 | { |
122 | idefloppy_floppy_t *floppy = drive->driver_data; | 73 | struct ide_disk_obj *floppy = drive->driver_data; |
123 | struct request *rq = HWGROUP(drive)->rq; | 74 | struct request *rq = HWGROUP(drive)->rq; |
124 | int error; | 75 | int error; |
125 | 76 | ||
@@ -161,12 +112,12 @@ static void idefloppy_update_buffers(ide_drive_t *drive, | |||
161 | struct bio *bio = rq->bio; | 112 | struct bio *bio = rq->bio; |
162 | 113 | ||
163 | while ((bio = rq->bio) != NULL) | 114 | while ((bio = rq->bio) != NULL) |
164 | idefloppy_end_request(drive, 1, 0); | 115 | ide_floppy_end_request(drive, 1, 0); |
165 | } | 116 | } |
166 | 117 | ||
167 | static void ide_floppy_callback(ide_drive_t *drive, int dsc) | 118 | static void ide_floppy_callback(ide_drive_t *drive, int dsc) |
168 | { | 119 | { |
169 | idefloppy_floppy_t *floppy = drive->driver_data; | 120 | struct ide_disk_obj *floppy = drive->driver_data; |
170 | struct ide_atapi_pc *pc = drive->pc; | 121 | struct ide_atapi_pc *pc = drive->pc; |
171 | int uptodate = pc->error ? 0 : 1; | 122 | int uptodate = pc->error ? 0 : 1; |
172 | 123 | ||
@@ -200,10 +151,10 @@ static void ide_floppy_callback(ide_drive_t *drive, int dsc) | |||
200 | "Aborting request!\n"); | 151 | "Aborting request!\n"); |
201 | } | 152 | } |
202 | 153 | ||
203 | idefloppy_end_request(drive, uptodate, 0); | 154 | ide_floppy_end_request(drive, uptodate, 0); |
204 | } | 155 | } |
205 | 156 | ||
206 | static void ide_floppy_report_error(idefloppy_floppy_t *floppy, | 157 | static void ide_floppy_report_error(struct ide_disk_obj *floppy, |
207 | struct ide_atapi_pc *pc) | 158 | struct ide_atapi_pc *pc) |
208 | { | 159 | { |
209 | /* supress error messages resulting from Medium not present */ | 160 | /* supress error messages resulting from Medium not present */ |
@@ -222,7 +173,7 @@ static void ide_floppy_report_error(idefloppy_floppy_t *floppy, | |||
222 | static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, | 173 | static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, |
223 | struct ide_atapi_pc *pc) | 174 | struct ide_atapi_pc *pc) |
224 | { | 175 | { |
225 | idefloppy_floppy_t *floppy = drive->driver_data; | 176 | struct ide_disk_obj *floppy = drive->driver_data; |
226 | 177 | ||
227 | if (floppy->failed_pc == NULL && | 178 | if (floppy->failed_pc == NULL && |
228 | pc->c[0] != GPCMD_REQUEST_SENSE) | 179 | pc->c[0] != GPCMD_REQUEST_SENSE) |
@@ -286,7 +237,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive, | |||
286 | struct ide_atapi_pc *pc, struct request *rq, | 237 | struct ide_atapi_pc *pc, struct request *rq, |
287 | unsigned long sector) | 238 | unsigned long sector) |
288 | { | 239 | { |
289 | idefloppy_floppy_t *floppy = drive->driver_data; | 240 | struct ide_disk_obj *floppy = drive->driver_data; |
290 | int block = sector / floppy->bs_factor; | 241 | int block = sector / floppy->bs_factor; |
291 | int blocks = rq->nr_sectors / floppy->bs_factor; | 242 | int blocks = rq->nr_sectors / floppy->bs_factor; |
292 | int cmd = rq_data_dir(rq); | 243 | int cmd = rq_data_dir(rq); |
@@ -310,7 +261,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive, | |||
310 | pc->flags |= PC_FLAG_DMA_OK; | 261 | pc->flags |= PC_FLAG_DMA_OK; |
311 | } | 262 | } |
312 | 263 | ||
313 | static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, | 264 | static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy, |
314 | struct ide_atapi_pc *pc, struct request *rq) | 265 | struct ide_atapi_pc *pc, struct request *rq) |
315 | { | 266 | { |
316 | ide_init_pc(pc); | 267 | ide_init_pc(pc); |
@@ -329,13 +280,12 @@ static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, | |||
329 | pc->req_xfer = pc->buf_size = rq->data_len; | 280 | pc->req_xfer = pc->buf_size = rq->data_len; |
330 | } | 281 | } |
331 | 282 | ||
332 | static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, | 283 | static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, |
333 | struct request *rq, sector_t block_s) | 284 | struct request *rq, sector_t block) |
334 | { | 285 | { |
335 | idefloppy_floppy_t *floppy = drive->driver_data; | 286 | struct ide_disk_obj *floppy = drive->driver_data; |
336 | ide_hwif_t *hwif = drive->hwif; | 287 | ide_hwif_t *hwif = drive->hwif; |
337 | struct ide_atapi_pc *pc; | 288 | struct ide_atapi_pc *pc; |
338 | unsigned long block = (unsigned long)block_s; | ||
339 | 289 | ||
340 | ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, " | 290 | ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, " |
341 | "errors: %d\n", | 291 | "errors: %d\n", |
@@ -353,7 +303,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, | |||
353 | else | 303 | else |
354 | printk(KERN_ERR PFX "%s: I/O error\n", drive->name); | 304 | printk(KERN_ERR PFX "%s: I/O error\n", drive->name); |
355 | 305 | ||
356 | idefloppy_end_request(drive, 0, 0); | 306 | ide_floppy_end_request(drive, 0, 0); |
357 | return ide_stopped; | 307 | return ide_stopped; |
358 | } | 308 | } |
359 | if (blk_fs_request(rq)) { | 309 | if (blk_fs_request(rq)) { |
@@ -361,11 +311,11 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, | |||
361 | (rq->nr_sectors % floppy->bs_factor)) { | 311 | (rq->nr_sectors % floppy->bs_factor)) { |
362 | printk(KERN_ERR PFX "%s: unsupported r/w rq size\n", | 312 | printk(KERN_ERR PFX "%s: unsupported r/w rq size\n", |
363 | drive->name); | 313 | drive->name); |
364 | idefloppy_end_request(drive, 0, 0); | 314 | ide_floppy_end_request(drive, 0, 0); |
365 | return ide_stopped; | 315 | return ide_stopped; |
366 | } | 316 | } |
367 | pc = &floppy->queued_pc; | 317 | pc = &floppy->queued_pc; |
368 | idefloppy_create_rw_cmd(drive, pc, rq, block); | 318 | idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block); |
369 | } else if (blk_special_request(rq)) { | 319 | } else if (blk_special_request(rq)) { |
370 | pc = (struct ide_atapi_pc *) rq->buffer; | 320 | pc = (struct ide_atapi_pc *) rq->buffer; |
371 | } else if (blk_pc_request(rq)) { | 321 | } else if (blk_pc_request(rq)) { |
@@ -373,7 +323,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, | |||
373 | idefloppy_blockpc_cmd(floppy, pc, rq); | 323 | idefloppy_blockpc_cmd(floppy, pc, rq); |
374 | } else { | 324 | } else { |
375 | blk_dump_rq_flags(rq, PFX "unsupported command in queue"); | 325 | blk_dump_rq_flags(rq, PFX "unsupported command in queue"); |
376 | idefloppy_end_request(drive, 0, 0); | 326 | ide_floppy_end_request(drive, 0, 0); |
377 | return ide_stopped; | 327 | return ide_stopped; |
378 | } | 328 | } |
379 | 329 | ||
@@ -394,7 +344,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, | |||
394 | */ | 344 | */ |
395 | static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) | 345 | static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) |
396 | { | 346 | { |
397 | idefloppy_floppy_t *floppy = drive->driver_data; | 347 | struct ide_disk_obj *floppy = drive->driver_data; |
398 | struct gendisk *disk = floppy->disk; | 348 | struct gendisk *disk = floppy->disk; |
399 | struct ide_atapi_pc pc; | 349 | struct ide_atapi_pc pc; |
400 | u8 *page; | 350 | u8 *page; |
@@ -410,11 +360,11 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) | |||
410 | } | 360 | } |
411 | 361 | ||
412 | if (pc.buf[3] & 0x80) | 362 | if (pc.buf[3] & 0x80) |
413 | drive->atapi_flags |= IDE_AFLAG_WP; | 363 | drive->dev_flags |= IDE_DFLAG_WP; |
414 | else | 364 | else |
415 | drive->atapi_flags &= ~IDE_AFLAG_WP; | 365 | drive->dev_flags &= ~IDE_DFLAG_WP; |
416 | 366 | ||
417 | set_disk_ro(disk, !!(drive->atapi_flags & IDE_AFLAG_WP)); | 367 | set_disk_ro(disk, !!(drive->dev_flags & IDE_DFLAG_WP)); |
418 | 368 | ||
419 | page = &pc.buf[8]; | 369 | page = &pc.buf[8]; |
420 | 370 | ||
@@ -445,7 +395,9 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) | |||
445 | drive->name, lba_capacity, capacity); | 395 | drive->name, lba_capacity, capacity); |
446 | floppy->blocks = floppy->block_size ? | 396 | floppy->blocks = floppy->block_size ? |
447 | capacity / floppy->block_size : 0; | 397 | capacity / floppy->block_size : 0; |
398 | drive->capacity64 = floppy->blocks * floppy->bs_factor; | ||
448 | } | 399 | } |
400 | |||
449 | return 0; | 401 | return 0; |
450 | } | 402 | } |
451 | 403 | ||
@@ -455,7 +407,7 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) | |||
455 | */ | 407 | */ |
456 | static int ide_floppy_get_capacity(ide_drive_t *drive) | 408 | static int ide_floppy_get_capacity(ide_drive_t *drive) |
457 | { | 409 | { |
458 | idefloppy_floppy_t *floppy = drive->driver_data; | 410 | struct ide_disk_obj *floppy = drive->driver_data; |
459 | struct gendisk *disk = floppy->disk; | 411 | struct gendisk *disk = floppy->disk; |
460 | struct ide_atapi_pc pc; | 412 | struct ide_atapi_pc pc; |
461 | u8 *cap_desc; | 413 | u8 *cap_desc; |
@@ -466,7 +418,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) | |||
466 | drive->bios_head = drive->bios_sect = 0; | 418 | drive->bios_head = drive->bios_sect = 0; |
467 | floppy->blocks = 0; | 419 | floppy->blocks = 0; |
468 | floppy->bs_factor = 1; | 420 | floppy->bs_factor = 1; |
469 | set_capacity(floppy->disk, 0); | 421 | drive->capacity64 = 0; |
470 | 422 | ||
471 | ide_floppy_create_read_capacity_cmd(&pc); | 423 | ide_floppy_create_read_capacity_cmd(&pc); |
472 | if (ide_queue_pc_tail(drive, disk, &pc)) { | 424 | if (ide_queue_pc_tail(drive, disk, &pc)) { |
@@ -523,6 +475,8 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) | |||
523 | "non 512 bytes block size not " | 475 | "non 512 bytes block size not " |
524 | "fully supported\n", | 476 | "fully supported\n", |
525 | drive->name); | 477 | drive->name); |
478 | drive->capacity64 = | ||
479 | floppy->blocks * floppy->bs_factor; | ||
526 | rc = 0; | 480 | rc = 0; |
527 | } | 481 | } |
528 | break; | 482 | break; |
@@ -547,21 +501,12 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) | |||
547 | if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) | 501 | if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) |
548 | (void) ide_floppy_get_flexible_disk_page(drive); | 502 | (void) ide_floppy_get_flexible_disk_page(drive); |
549 | 503 | ||
550 | set_capacity(disk, floppy->blocks * floppy->bs_factor); | ||
551 | |||
552 | return rc; | 504 | return rc; |
553 | } | 505 | } |
554 | 506 | ||
555 | sector_t ide_floppy_capacity(ide_drive_t *drive) | 507 | static void ide_floppy_setup(ide_drive_t *drive) |
556 | { | ||
557 | idefloppy_floppy_t *floppy = drive->driver_data; | ||
558 | unsigned long capacity = floppy->blocks * floppy->bs_factor; | ||
559 | |||
560 | return capacity; | ||
561 | } | ||
562 | |||
563 | static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy) | ||
564 | { | 508 | { |
509 | struct ide_disk_obj *floppy = drive->driver_data; | ||
565 | u16 *id = drive->id; | 510 | u16 *id = drive->id; |
566 | 511 | ||
567 | drive->pc_callback = ide_floppy_callback; | 512 | drive->pc_callback = ide_floppy_callback; |
@@ -592,252 +537,42 @@ static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy) | |||
592 | blk_queue_max_sectors(drive->queue, 64); | 537 | blk_queue_max_sectors(drive->queue, 64); |
593 | drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE; | 538 | drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE; |
594 | /* IOMEGA Clik! drives do not support lock/unlock commands */ | 539 | /* IOMEGA Clik! drives do not support lock/unlock commands */ |
595 | drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK; | 540 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; |
596 | } | 541 | } |
597 | 542 | ||
598 | (void) ide_floppy_get_capacity(drive); | 543 | (void) ide_floppy_get_capacity(drive); |
599 | 544 | ||
600 | ide_proc_register_driver(drive, floppy->driver); | 545 | ide_proc_register_driver(drive, floppy->driver); |
601 | } | ||
602 | 546 | ||
603 | static void ide_floppy_remove(ide_drive_t *drive) | 547 | drive->dev_flags |= IDE_DFLAG_ATTACH; |
604 | { | ||
605 | idefloppy_floppy_t *floppy = drive->driver_data; | ||
606 | struct gendisk *g = floppy->disk; | ||
607 | |||
608 | ide_proc_unregister_driver(drive, floppy->driver); | ||
609 | |||
610 | del_gendisk(g); | ||
611 | |||
612 | ide_floppy_put(floppy); | ||
613 | } | 548 | } |
614 | 549 | ||
615 | static void idefloppy_cleanup_obj(struct kref *kref) | 550 | static void ide_floppy_flush(ide_drive_t *drive) |
616 | { | 551 | { |
617 | struct ide_floppy_obj *floppy = to_ide_drv(kref, ide_floppy_obj); | ||
618 | ide_drive_t *drive = floppy->drive; | ||
619 | struct gendisk *g = floppy->disk; | ||
620 | |||
621 | drive->driver_data = NULL; | ||
622 | g->private_data = NULL; | ||
623 | put_disk(g); | ||
624 | kfree(floppy); | ||
625 | } | 552 | } |
626 | 553 | ||
627 | static int ide_floppy_probe(ide_drive_t *); | 554 | static int ide_floppy_init_media(ide_drive_t *drive, struct gendisk *disk) |
628 | |||
629 | static ide_driver_t idefloppy_driver = { | ||
630 | .gen_driver = { | ||
631 | .owner = THIS_MODULE, | ||
632 | .name = "ide-floppy", | ||
633 | .bus = &ide_bus_type, | ||
634 | }, | ||
635 | .probe = ide_floppy_probe, | ||
636 | .remove = ide_floppy_remove, | ||
637 | .version = IDEFLOPPY_VERSION, | ||
638 | .do_request = idefloppy_do_request, | ||
639 | .end_request = idefloppy_end_request, | ||
640 | .error = __ide_error, | ||
641 | #ifdef CONFIG_IDE_PROC_FS | ||
642 | .proc = ide_floppy_proc, | ||
643 | .settings = ide_floppy_settings, | ||
644 | #endif | ||
645 | }; | ||
646 | |||
647 | static int idefloppy_open(struct inode *inode, struct file *filp) | ||
648 | { | 555 | { |
649 | struct gendisk *disk = inode->i_bdev->bd_disk; | ||
650 | struct ide_floppy_obj *floppy; | ||
651 | ide_drive_t *drive; | ||
652 | int ret = 0; | 556 | int ret = 0; |
653 | 557 | ||
654 | floppy = ide_floppy_get(disk); | 558 | if (ide_do_test_unit_ready(drive, disk)) |
655 | if (!floppy) | 559 | ide_do_start_stop(drive, disk, 1); |
656 | return -ENXIO; | ||
657 | |||
658 | drive = floppy->drive; | ||
659 | |||
660 | ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); | ||
661 | |||
662 | floppy->openers++; | ||
663 | |||
664 | if (floppy->openers == 1) { | ||
665 | drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS; | ||
666 | /* Just in case */ | ||
667 | |||
668 | if (ide_do_test_unit_ready(drive, disk)) | ||
669 | ide_do_start_stop(drive, disk, 1); | ||
670 | |||
671 | if (ide_floppy_get_capacity(drive) | ||
672 | && (filp->f_flags & O_NDELAY) == 0 | ||
673 | /* | ||
674 | * Allow O_NDELAY to open a drive without a disk, or with an | ||
675 | * unreadable disk, so that we can get the format capacity | ||
676 | * of the drive or begin the format - Sam | ||
677 | */ | ||
678 | ) { | ||
679 | ret = -EIO; | ||
680 | goto out_put_floppy; | ||
681 | } | ||
682 | |||
683 | if ((drive->atapi_flags & IDE_AFLAG_WP) && (filp->f_mode & 2)) { | ||
684 | ret = -EROFS; | ||
685 | goto out_put_floppy; | ||
686 | } | ||
687 | |||
688 | drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED; | ||
689 | ide_set_media_lock(drive, disk, 1); | ||
690 | check_disk_change(inode->i_bdev); | ||
691 | } else if (drive->atapi_flags & IDE_AFLAG_FORMAT_IN_PROGRESS) { | ||
692 | ret = -EBUSY; | ||
693 | goto out_put_floppy; | ||
694 | } | ||
695 | return 0; | ||
696 | |||
697 | out_put_floppy: | ||
698 | floppy->openers--; | ||
699 | ide_floppy_put(floppy); | ||
700 | return ret; | ||
701 | } | ||
702 | |||
703 | static int idefloppy_release(struct inode *inode, struct file *filp) | ||
704 | { | ||
705 | struct gendisk *disk = inode->i_bdev->bd_disk; | ||
706 | struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj); | ||
707 | ide_drive_t *drive = floppy->drive; | ||
708 | |||
709 | ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); | ||
710 | |||
711 | if (floppy->openers == 1) { | ||
712 | ide_set_media_lock(drive, disk, 0); | ||
713 | drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS; | ||
714 | } | ||
715 | |||
716 | floppy->openers--; | ||
717 | |||
718 | ide_floppy_put(floppy); | ||
719 | |||
720 | return 0; | ||
721 | } | ||
722 | |||
723 | static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo) | ||
724 | { | ||
725 | struct ide_floppy_obj *floppy = ide_drv_g(bdev->bd_disk, | ||
726 | ide_floppy_obj); | ||
727 | ide_drive_t *drive = floppy->drive; | ||
728 | 560 | ||
729 | geo->heads = drive->bios_head; | 561 | ret = ide_floppy_get_capacity(drive); |
730 | geo->sectors = drive->bios_sect; | ||
731 | geo->cylinders = (u16)drive->bios_cyl; /* truncate */ | ||
732 | return 0; | ||
733 | } | ||
734 | 562 | ||
735 | static int idefloppy_media_changed(struct gendisk *disk) | 563 | set_capacity(disk, ide_gd_capacity(drive)); |
736 | { | ||
737 | struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj); | ||
738 | ide_drive_t *drive = floppy->drive; | ||
739 | int ret; | ||
740 | 564 | ||
741 | /* do not scan partitions twice if this is a removable device */ | ||
742 | if (drive->dev_flags & IDE_DFLAG_ATTACH) { | ||
743 | drive->dev_flags &= ~IDE_DFLAG_ATTACH; | ||
744 | return 0; | ||
745 | } | ||
746 | ret = !!(drive->atapi_flags & IDE_AFLAG_MEDIA_CHANGED); | ||
747 | drive->atapi_flags &= ~IDE_AFLAG_MEDIA_CHANGED; | ||
748 | return ret; | 565 | return ret; |
749 | } | 566 | } |
750 | 567 | ||
751 | static int idefloppy_revalidate_disk(struct gendisk *disk) | 568 | const struct ide_disk_ops ide_atapi_disk_ops = { |
752 | { | 569 | .check = ide_check_atapi_device, |
753 | struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj); | 570 | .get_capacity = ide_floppy_get_capacity, |
754 | set_capacity(disk, ide_floppy_capacity(floppy->drive)); | 571 | .setup = ide_floppy_setup, |
755 | return 0; | 572 | .flush = ide_floppy_flush, |
756 | } | 573 | .init_media = ide_floppy_init_media, |
757 | 574 | .set_doorlock = ide_set_media_lock, | |
758 | static struct block_device_operations idefloppy_ops = { | 575 | .do_request = ide_floppy_do_request, |
759 | .owner = THIS_MODULE, | 576 | .end_request = ide_floppy_end_request, |
760 | .open = idefloppy_open, | 577 | .ioctl = ide_floppy_ioctl, |
761 | .release = idefloppy_release, | ||
762 | .ioctl = ide_floppy_ioctl, | ||
763 | .getgeo = idefloppy_getgeo, | ||
764 | .media_changed = idefloppy_media_changed, | ||
765 | .revalidate_disk = idefloppy_revalidate_disk | ||
766 | }; | 578 | }; |
767 | |||
768 | static int ide_floppy_probe(ide_drive_t *drive) | ||
769 | { | ||
770 | idefloppy_floppy_t *floppy; | ||
771 | struct gendisk *g; | ||
772 | |||
773 | if (!strstr("ide-floppy", drive->driver_req)) | ||
774 | goto failed; | ||
775 | |||
776 | if (drive->media != ide_floppy) | ||
777 | goto failed; | ||
778 | |||
779 | if (!ide_check_atapi_device(drive, DRV_NAME)) { | ||
780 | printk(KERN_ERR PFX "%s: not supported by this version of " | ||
781 | DRV_NAME "\n", drive->name); | ||
782 | goto failed; | ||
783 | } | ||
784 | floppy = kzalloc(sizeof(idefloppy_floppy_t), GFP_KERNEL); | ||
785 | if (!floppy) { | ||
786 | printk(KERN_ERR PFX "%s: Can't allocate a floppy structure\n", | ||
787 | drive->name); | ||
788 | goto failed; | ||
789 | } | ||
790 | |||
791 | g = alloc_disk(1 << PARTN_BITS); | ||
792 | if (!g) | ||
793 | goto out_free_floppy; | ||
794 | |||
795 | ide_init_disk(g, drive); | ||
796 | |||
797 | kref_init(&floppy->kref); | ||
798 | |||
799 | floppy->drive = drive; | ||
800 | floppy->driver = &idefloppy_driver; | ||
801 | floppy->disk = g; | ||
802 | |||
803 | g->private_data = &floppy->driver; | ||
804 | |||
805 | drive->driver_data = floppy; | ||
806 | |||
807 | drive->debug_mask = debug_mask; | ||
808 | |||
809 | idefloppy_setup(drive, floppy); | ||
810 | drive->dev_flags |= IDE_DFLAG_ATTACH; | ||
811 | |||
812 | g->minors = 1 << PARTN_BITS; | ||
813 | g->driverfs_dev = &drive->gendev; | ||
814 | if (drive->dev_flags & IDE_DFLAG_REMOVABLE) | ||
815 | g->flags = GENHD_FL_REMOVABLE; | ||
816 | g->fops = &idefloppy_ops; | ||
817 | add_disk(g); | ||
818 | return 0; | ||
819 | |||
820 | out_free_floppy: | ||
821 | kfree(floppy); | ||
822 | failed: | ||
823 | return -ENODEV; | ||
824 | } | ||
825 | |||
826 | static void __exit idefloppy_exit(void) | ||
827 | { | ||
828 | driver_unregister(&idefloppy_driver.gen_driver); | ||
829 | } | ||
830 | |||
831 | static int __init idefloppy_init(void) | ||
832 | { | ||
833 | printk(KERN_INFO DRV_NAME " driver " IDEFLOPPY_VERSION "\n"); | ||
834 | return driver_register(&idefloppy_driver.gen_driver); | ||
835 | } | ||
836 | |||
837 | MODULE_ALIAS("ide:*m-floppy*"); | ||
838 | MODULE_ALIAS("ide-floppy"); | ||
839 | module_init(idefloppy_init); | ||
840 | module_exit(idefloppy_exit); | ||
841 | MODULE_LICENSE("GPL"); | ||
842 | MODULE_DESCRIPTION("ATAPI FLOPPY Driver"); | ||
843 | |||
diff --git a/drivers/ide/ide-floppy.h b/drivers/ide/ide-floppy.h index 17cf865e583d..c17124dd6079 100644 --- a/drivers/ide/ide-floppy.h +++ b/drivers/ide/ide-floppy.h | |||
@@ -1,37 +1,9 @@ | |||
1 | #ifndef __IDE_FLOPPY_H | 1 | #ifndef __IDE_FLOPPY_H |
2 | #define __IDE_FLOPPY_H | 2 | #define __IDE_FLOPPY_H |
3 | 3 | ||
4 | /* | 4 | #include "ide-gd.h" |
5 | * Most of our global data which we need to save even as we leave the driver | ||
6 | * due to an interrupt or a timer event is stored in a variable of type | ||
7 | * idefloppy_floppy_t, defined below. | ||
8 | */ | ||
9 | typedef struct ide_floppy_obj { | ||
10 | ide_drive_t *drive; | ||
11 | ide_driver_t *driver; | ||
12 | struct gendisk *disk; | ||
13 | struct kref kref; | ||
14 | unsigned int openers; /* protected by BKL for now */ | ||
15 | |||
16 | /* Last failed packet command */ | ||
17 | struct ide_atapi_pc *failed_pc; | ||
18 | /* used for blk_{fs,pc}_request() requests */ | ||
19 | struct ide_atapi_pc queued_pc; | ||
20 | |||
21 | /* Last error information */ | ||
22 | u8 sense_key, asc, ascq; | ||
23 | |||
24 | int progress_indication; | ||
25 | |||
26 | /* Device information */ | ||
27 | /* Current format */ | ||
28 | int blocks, block_size, bs_factor; | ||
29 | /* Last format capacity descriptor */ | ||
30 | u8 cap_desc[8]; | ||
31 | /* Copy of the flexible disk page */ | ||
32 | u8 flexible_disk_page[32]; | ||
33 | } idefloppy_floppy_t; | ||
34 | 5 | ||
6 | #ifdef CONFIG_IDE_GD_ATAPI | ||
35 | /* | 7 | /* |
36 | * Pages of the SELECT SENSE / MODE SENSE packet commands. | 8 | * Pages of the SELECT SENSE / MODE SENSE packet commands. |
37 | * See SFF-8070i spec. | 9 | * See SFF-8070i spec. |
@@ -46,17 +18,22 @@ typedef struct ide_floppy_obj { | |||
46 | #define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS 0x4603 | 18 | #define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS 0x4603 |
47 | 19 | ||
48 | /* ide-floppy.c */ | 20 | /* ide-floppy.c */ |
21 | extern const struct ide_disk_ops ide_atapi_disk_ops; | ||
49 | void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *, u8); | 22 | void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *, u8); |
50 | void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *); | 23 | void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *); |
51 | sector_t ide_floppy_capacity(ide_drive_t *); | ||
52 | 24 | ||
53 | /* ide-floppy_ioctl.c */ | 25 | /* ide-floppy_ioctl.c */ |
54 | int ide_floppy_ioctl(struct inode *, struct file *, unsigned, unsigned long); | 26 | int ide_floppy_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int, |
27 | unsigned long); | ||
55 | 28 | ||
56 | #ifdef CONFIG_IDE_PROC_FS | 29 | #ifdef CONFIG_IDE_PROC_FS |
57 | /* ide-floppy_proc.c */ | 30 | /* ide-floppy_proc.c */ |
58 | extern ide_proc_entry_t ide_floppy_proc[]; | 31 | extern ide_proc_entry_t ide_floppy_proc[]; |
59 | extern const struct ide_proc_devset ide_floppy_settings[]; | 32 | extern const struct ide_proc_devset ide_floppy_settings[]; |
60 | #endif | 33 | #endif |
34 | #else | ||
35 | #define ide_floppy_proc NULL | ||
36 | #define ide_floppy_settings NULL | ||
37 | #endif | ||
61 | 38 | ||
62 | #endif /*__IDE_FLOPPY_H */ | 39 | #endif /*__IDE_FLOPPY_H */ |
diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c index a3a7a0809e2b..409e4c15f9b7 100644 --- a/drivers/ide/ide-floppy_ioctl.c +++ b/drivers/ide/ide-floppy_ioctl.c | |||
@@ -33,7 +33,7 @@ | |||
33 | 33 | ||
34 | static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) | 34 | static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) |
35 | { | 35 | { |
36 | struct ide_floppy_obj *floppy = drive->driver_data; | 36 | struct ide_disk_obj *floppy = drive->driver_data; |
37 | struct ide_atapi_pc pc; | 37 | struct ide_atapi_pc pc; |
38 | u8 header_len, desc_cnt; | 38 | u8 header_len, desc_cnt; |
39 | int i, blocks, length, u_array_size, u_index; | 39 | int i, blocks, length, u_array_size, u_index; |
@@ -113,7 +113,7 @@ static void ide_floppy_create_format_unit_cmd(struct ide_atapi_pc *pc, int b, | |||
113 | 113 | ||
114 | static int ide_floppy_get_sfrp_bit(ide_drive_t *drive) | 114 | static int ide_floppy_get_sfrp_bit(ide_drive_t *drive) |
115 | { | 115 | { |
116 | idefloppy_floppy_t *floppy = drive->driver_data; | 116 | struct ide_disk_obj *floppy = drive->driver_data; |
117 | struct ide_atapi_pc pc; | 117 | struct ide_atapi_pc pc; |
118 | 118 | ||
119 | drive->atapi_flags &= ~IDE_AFLAG_SRFP; | 119 | drive->atapi_flags &= ~IDE_AFLAG_SRFP; |
@@ -132,17 +132,17 @@ static int ide_floppy_get_sfrp_bit(ide_drive_t *drive) | |||
132 | 132 | ||
133 | static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg) | 133 | static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg) |
134 | { | 134 | { |
135 | idefloppy_floppy_t *floppy = drive->driver_data; | 135 | struct ide_disk_obj *floppy = drive->driver_data; |
136 | struct ide_atapi_pc pc; | 136 | struct ide_atapi_pc pc; |
137 | int blocks, length, flags, err = 0; | 137 | int blocks, length, flags, err = 0; |
138 | 138 | ||
139 | if (floppy->openers > 1) { | 139 | if (floppy->openers > 1) { |
140 | /* Don't format if someone is using the disk */ | 140 | /* Don't format if someone is using the disk */ |
141 | drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS; | 141 | drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS; |
142 | return -EBUSY; | 142 | return -EBUSY; |
143 | } | 143 | } |
144 | 144 | ||
145 | drive->atapi_flags |= IDE_AFLAG_FORMAT_IN_PROGRESS; | 145 | drive->dev_flags |= IDE_DFLAG_FORMAT_IN_PROGRESS; |
146 | 146 | ||
147 | /* | 147 | /* |
148 | * Send ATAPI_FORMAT_UNIT to the drive. | 148 | * Send ATAPI_FORMAT_UNIT to the drive. |
@@ -174,7 +174,7 @@ static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg) | |||
174 | 174 | ||
175 | out: | 175 | out: |
176 | if (err) | 176 | if (err) |
177 | drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS; | 177 | drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS; |
178 | return err; | 178 | return err; |
179 | } | 179 | } |
180 | 180 | ||
@@ -190,7 +190,7 @@ out: | |||
190 | 190 | ||
191 | static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg) | 191 | static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg) |
192 | { | 192 | { |
193 | idefloppy_floppy_t *floppy = drive->driver_data; | 193 | struct ide_disk_obj *floppy = drive->driver_data; |
194 | struct ide_atapi_pc pc; | 194 | struct ide_atapi_pc pc; |
195 | int progress_indication = 0x10000; | 195 | int progress_indication = 0x10000; |
196 | 196 | ||
@@ -226,7 +226,7 @@ static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg) | |||
226 | static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc, | 226 | static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc, |
227 | unsigned long arg, unsigned int cmd) | 227 | unsigned long arg, unsigned int cmd) |
228 | { | 228 | { |
229 | idefloppy_floppy_t *floppy = drive->driver_data; | 229 | struct ide_disk_obj *floppy = drive->driver_data; |
230 | struct gendisk *disk = floppy->disk; | 230 | struct gendisk *disk = floppy->disk; |
231 | int prevent = (arg && cmd != CDROMEJECT) ? 1 : 0; | 231 | int prevent = (arg && cmd != CDROMEJECT) ? 1 : 0; |
232 | 232 | ||
@@ -260,13 +260,10 @@ static int ide_floppy_format_ioctl(ide_drive_t *drive, struct file *file, | |||
260 | } | 260 | } |
261 | } | 261 | } |
262 | 262 | ||
263 | int ide_floppy_ioctl(struct inode *inode, struct file *file, | 263 | int ide_floppy_ioctl(ide_drive_t *drive, struct inode *inode, |
264 | unsigned int cmd, unsigned long arg) | 264 | struct file *file, unsigned int cmd, unsigned long arg) |
265 | { | 265 | { |
266 | struct block_device *bdev = inode->i_bdev; | 266 | struct block_device *bdev = inode->i_bdev; |
267 | struct ide_floppy_obj *floppy = ide_drv_g(bdev->bd_disk, | ||
268 | ide_floppy_obj); | ||
269 | ide_drive_t *drive = floppy->drive; | ||
270 | struct ide_atapi_pc pc; | 267 | struct ide_atapi_pc pc; |
271 | void __user *argp = (void __user *)arg; | 268 | void __user *argp = (void __user *)arg; |
272 | int err; | 269 | int err; |
diff --git a/drivers/ide/ide-floppy_proc.c b/drivers/ide/ide-floppy_proc.c index 76f0c6c4eca3..3ec762cb60ab 100644 --- a/drivers/ide/ide-floppy_proc.c +++ b/drivers/ide/ide-floppy_proc.c | |||
@@ -9,7 +9,7 @@ static int proc_idefloppy_read_capacity(char *page, char **start, off_t off, | |||
9 | ide_drive_t*drive = (ide_drive_t *)data; | 9 | ide_drive_t*drive = (ide_drive_t *)data; |
10 | int len; | 10 | int len; |
11 | 11 | ||
12 | len = sprintf(page, "%llu\n", (long long)ide_floppy_capacity(drive)); | 12 | len = sprintf(page, "%llu\n", (long long)ide_gd_capacity(drive)); |
13 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); | 13 | PROC_IDE_READ_RETURN(page, start, off, count, eof, len); |
14 | } | 14 | } |
15 | 15 | ||
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c new file mode 100644 index 000000000000..d44898f46c33 --- /dev/null +++ b/drivers/ide/ide-gd.c | |||
@@ -0,0 +1,398 @@ | |||
1 | #include <linux/module.h> | ||
2 | #include <linux/types.h> | ||
3 | #include <linux/string.h> | ||
4 | #include <linux/kernel.h> | ||
5 | #include <linux/errno.h> | ||
6 | #include <linux/genhd.h> | ||
7 | #include <linux/mutex.h> | ||
8 | #include <linux/ide.h> | ||
9 | #include <linux/hdreg.h> | ||
10 | |||
11 | #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT) | ||
12 | #define IDE_DISK_MINORS (1 << PARTN_BITS) | ||
13 | #else | ||
14 | #define IDE_DISK_MINORS 0 | ||
15 | #endif | ||
16 | |||
17 | #include "ide-disk.h" | ||
18 | #include "ide-floppy.h" | ||
19 | |||
20 | #define IDE_GD_VERSION "1.18" | ||
21 | |||
22 | /* module parameters */ | ||
23 | static unsigned long debug_mask; | ||
24 | module_param(debug_mask, ulong, 0644); | ||
25 | |||
26 | static DEFINE_MUTEX(ide_disk_ref_mutex); | ||
27 | |||
28 | static void ide_disk_release(struct kref *); | ||
29 | |||
30 | static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) | ||
31 | { | ||
32 | struct ide_disk_obj *idkp = NULL; | ||
33 | |||
34 | mutex_lock(&ide_disk_ref_mutex); | ||
35 | idkp = ide_drv_g(disk, ide_disk_obj); | ||
36 | if (idkp) { | ||
37 | if (ide_device_get(idkp->drive)) | ||
38 | idkp = NULL; | ||
39 | else | ||
40 | kref_get(&idkp->kref); | ||
41 | } | ||
42 | mutex_unlock(&ide_disk_ref_mutex); | ||
43 | return idkp; | ||
44 | } | ||
45 | |||
46 | static void ide_disk_put(struct ide_disk_obj *idkp) | ||
47 | { | ||
48 | ide_drive_t *drive = idkp->drive; | ||
49 | |||
50 | mutex_lock(&ide_disk_ref_mutex); | ||
51 | kref_put(&idkp->kref, ide_disk_release); | ||
52 | ide_device_put(drive); | ||
53 | mutex_unlock(&ide_disk_ref_mutex); | ||
54 | } | ||
55 | |||
56 | sector_t ide_gd_capacity(ide_drive_t *drive) | ||
57 | { | ||
58 | return drive->capacity64; | ||
59 | } | ||
60 | |||
61 | static int ide_gd_probe(ide_drive_t *); | ||
62 | |||
63 | static void ide_gd_remove(ide_drive_t *drive) | ||
64 | { | ||
65 | struct ide_disk_obj *idkp = drive->driver_data; | ||
66 | struct gendisk *g = idkp->disk; | ||
67 | |||
68 | ide_proc_unregister_driver(drive, idkp->driver); | ||
69 | |||
70 | del_gendisk(g); | ||
71 | |||
72 | drive->disk_ops->flush(drive); | ||
73 | |||
74 | ide_disk_put(idkp); | ||
75 | } | ||
76 | |||
77 | static void ide_disk_release(struct kref *kref) | ||
78 | { | ||
79 | struct ide_disk_obj *idkp = to_ide_drv(kref, ide_disk_obj); | ||
80 | ide_drive_t *drive = idkp->drive; | ||
81 | struct gendisk *g = idkp->disk; | ||
82 | |||
83 | drive->disk_ops = NULL; | ||
84 | drive->driver_data = NULL; | ||
85 | g->private_data = NULL; | ||
86 | put_disk(g); | ||
87 | kfree(idkp); | ||
88 | } | ||
89 | |||
90 | /* | ||
91 | * On HPA drives the capacity needs to be | ||
92 | * reinitilized on resume otherwise the disk | ||
93 | * can not be used and a hard reset is required | ||
94 | */ | ||
95 | static void ide_gd_resume(ide_drive_t *drive) | ||
96 | { | ||
97 | if (ata_id_hpa_enabled(drive->id)) | ||
98 | (void)drive->disk_ops->get_capacity(drive); | ||
99 | } | ||
100 | |||
101 | static void ide_gd_shutdown(ide_drive_t *drive) | ||
102 | { | ||
103 | #ifdef CONFIG_ALPHA | ||
104 | /* On Alpha, halt(8) doesn't actually turn the machine off, | ||
105 | it puts you into the sort of firmware monitor. Typically, | ||
106 | it's used to boot another kernel image, so it's not much | ||
107 | different from reboot(8). Therefore, we don't need to | ||
108 | spin down the disk in this case, especially since Alpha | ||
109 | firmware doesn't handle disks in standby mode properly. | ||
110 | On the other hand, it's reasonably safe to turn the power | ||
111 | off when the shutdown process reaches the firmware prompt, | ||
112 | as the firmware initialization takes rather long time - | ||
113 | at least 10 seconds, which should be sufficient for | ||
114 | the disk to expire its write cache. */ | ||
115 | if (system_state != SYSTEM_POWER_OFF) { | ||
116 | #else | ||
117 | if (system_state == SYSTEM_RESTART) { | ||
118 | #endif | ||
119 | drive->disk_ops->flush(drive); | ||
120 | return; | ||
121 | } | ||
122 | |||
123 | printk(KERN_INFO "Shutdown: %s\n", drive->name); | ||
124 | |||
125 | drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND); | ||
126 | } | ||
127 | |||
128 | #ifdef CONFIG_IDE_PROC_FS | ||
129 | static ide_proc_entry_t *ide_disk_proc_entries(ide_drive_t *drive) | ||
130 | { | ||
131 | return (drive->media == ide_disk) ? ide_disk_proc : ide_floppy_proc; | ||
132 | } | ||
133 | |||
134 | static const struct ide_proc_devset *ide_disk_proc_devsets(ide_drive_t *drive) | ||
135 | { | ||
136 | return (drive->media == ide_disk) ? ide_disk_settings | ||
137 | : ide_floppy_settings; | ||
138 | } | ||
139 | #endif | ||
140 | |||
141 | static ide_startstop_t ide_gd_do_request(ide_drive_t *drive, | ||
142 | struct request *rq, sector_t sector) | ||
143 | { | ||
144 | return drive->disk_ops->do_request(drive, rq, sector); | ||
145 | } | ||
146 | |||
147 | static int ide_gd_end_request(ide_drive_t *drive, int uptodate, int nrsecs) | ||
148 | { | ||
149 | return drive->disk_ops->end_request(drive, uptodate, nrsecs); | ||
150 | } | ||
151 | |||
152 | static ide_driver_t ide_gd_driver = { | ||
153 | .gen_driver = { | ||
154 | .owner = THIS_MODULE, | ||
155 | .name = "ide-gd", | ||
156 | .bus = &ide_bus_type, | ||
157 | }, | ||
158 | .probe = ide_gd_probe, | ||
159 | .remove = ide_gd_remove, | ||
160 | .resume = ide_gd_resume, | ||
161 | .shutdown = ide_gd_shutdown, | ||
162 | .version = IDE_GD_VERSION, | ||
163 | .do_request = ide_gd_do_request, | ||
164 | .end_request = ide_gd_end_request, | ||
165 | .error = __ide_error, | ||
166 | #ifdef CONFIG_IDE_PROC_FS | ||
167 | .proc_entries = ide_disk_proc_entries, | ||
168 | .proc_devsets = ide_disk_proc_devsets, | ||
169 | #endif | ||
170 | }; | ||
171 | |||
172 | static int ide_gd_open(struct inode *inode, struct file *filp) | ||
173 | { | ||
174 | struct gendisk *disk = inode->i_bdev->bd_disk; | ||
175 | struct ide_disk_obj *idkp; | ||
176 | ide_drive_t *drive; | ||
177 | int ret = 0; | ||
178 | |||
179 | idkp = ide_disk_get(disk); | ||
180 | if (idkp == NULL) | ||
181 | return -ENXIO; | ||
182 | |||
183 | drive = idkp->drive; | ||
184 | |||
185 | ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); | ||
186 | |||
187 | idkp->openers++; | ||
188 | |||
189 | if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) { | ||
190 | drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS; | ||
191 | /* Just in case */ | ||
192 | |||
193 | ret = drive->disk_ops->init_media(drive, disk); | ||
194 | |||
195 | /* | ||
196 | * Allow O_NDELAY to open a drive without a disk, or with an | ||
197 | * unreadable disk, so that we can get the format capacity | ||
198 | * of the drive or begin the format - Sam | ||
199 | */ | ||
200 | if (ret && (filp->f_flags & O_NDELAY) == 0) { | ||
201 | ret = -EIO; | ||
202 | goto out_put_idkp; | ||
203 | } | ||
204 | |||
205 | if ((drive->dev_flags & IDE_DFLAG_WP) && (filp->f_mode & 2)) { | ||
206 | ret = -EROFS; | ||
207 | goto out_put_idkp; | ||
208 | } | ||
209 | |||
210 | /* | ||
211 | * Ignore the return code from door_lock, | ||
212 | * since the open() has already succeeded, | ||
213 | * and the door_lock is irrelevant at this point. | ||
214 | */ | ||
215 | drive->disk_ops->set_doorlock(drive, disk, 1); | ||
216 | drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; | ||
217 | check_disk_change(inode->i_bdev); | ||
218 | } else if (drive->dev_flags & IDE_DFLAG_FORMAT_IN_PROGRESS) { | ||
219 | ret = -EBUSY; | ||
220 | goto out_put_idkp; | ||
221 | } | ||
222 | return 0; | ||
223 | |||
224 | out_put_idkp: | ||
225 | idkp->openers--; | ||
226 | ide_disk_put(idkp); | ||
227 | return ret; | ||
228 | } | ||
229 | |||
230 | static int ide_gd_release(struct inode *inode, struct file *filp) | ||
231 | { | ||
232 | struct gendisk *disk = inode->i_bdev->bd_disk; | ||
233 | struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); | ||
234 | ide_drive_t *drive = idkp->drive; | ||
235 | |||
236 | ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); | ||
237 | |||
238 | if (idkp->openers == 1) | ||
239 | drive->disk_ops->flush(drive); | ||
240 | |||
241 | if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) { | ||
242 | drive->disk_ops->set_doorlock(drive, disk, 0); | ||
243 | drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS; | ||
244 | } | ||
245 | |||
246 | idkp->openers--; | ||
247 | |||
248 | ide_disk_put(idkp); | ||
249 | |||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | static int ide_gd_getgeo(struct block_device *bdev, struct hd_geometry *geo) | ||
254 | { | ||
255 | struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj); | ||
256 | ide_drive_t *drive = idkp->drive; | ||
257 | |||
258 | geo->heads = drive->bios_head; | ||
259 | geo->sectors = drive->bios_sect; | ||
260 | geo->cylinders = (u16)drive->bios_cyl; /* truncate */ | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | static int ide_gd_media_changed(struct gendisk *disk) | ||
265 | { | ||
266 | struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); | ||
267 | ide_drive_t *drive = idkp->drive; | ||
268 | int ret; | ||
269 | |||
270 | /* do not scan partitions twice if this is a removable device */ | ||
271 | if (drive->dev_flags & IDE_DFLAG_ATTACH) { | ||
272 | drive->dev_flags &= ~IDE_DFLAG_ATTACH; | ||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | ret = !!(drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED); | ||
277 | drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; | ||
278 | |||
279 | return ret; | ||
280 | } | ||
281 | |||
282 | static int ide_gd_revalidate_disk(struct gendisk *disk) | ||
283 | { | ||
284 | struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); | ||
285 | set_capacity(disk, ide_gd_capacity(idkp->drive)); | ||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static int ide_gd_ioctl(struct inode *inode, struct file *file, | ||
290 | unsigned int cmd, unsigned long arg) | ||
291 | { | ||
292 | struct block_device *bdev = inode->i_bdev; | ||
293 | struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj); | ||
294 | ide_drive_t *drive = idkp->drive; | ||
295 | |||
296 | return drive->disk_ops->ioctl(drive, inode, file, cmd, arg); | ||
297 | } | ||
298 | |||
299 | static struct block_device_operations ide_gd_ops = { | ||
300 | .owner = THIS_MODULE, | ||
301 | .open = ide_gd_open, | ||
302 | .release = ide_gd_release, | ||
303 | .ioctl = ide_gd_ioctl, | ||
304 | .getgeo = ide_gd_getgeo, | ||
305 | .media_changed = ide_gd_media_changed, | ||
306 | .revalidate_disk = ide_gd_revalidate_disk | ||
307 | }; | ||
308 | |||
309 | static int ide_gd_probe(ide_drive_t *drive) | ||
310 | { | ||
311 | const struct ide_disk_ops *disk_ops = NULL; | ||
312 | struct ide_disk_obj *idkp; | ||
313 | struct gendisk *g; | ||
314 | |||
315 | /* strstr("foo", "") is non-NULL */ | ||
316 | if (!strstr("ide-gd", drive->driver_req)) | ||
317 | goto failed; | ||
318 | |||
319 | #ifdef CONFIG_IDE_GD_ATA | ||
320 | if (drive->media == ide_disk) | ||
321 | disk_ops = &ide_ata_disk_ops; | ||
322 | #endif | ||
323 | #ifdef CONFIG_IDE_GD_ATAPI | ||
324 | if (drive->media == ide_floppy) | ||
325 | disk_ops = &ide_atapi_disk_ops; | ||
326 | #endif | ||
327 | if (disk_ops == NULL) | ||
328 | goto failed; | ||
329 | |||
330 | if (disk_ops->check(drive, DRV_NAME) == 0) { | ||
331 | printk(KERN_ERR PFX "%s: not supported by this driver\n", | ||
332 | drive->name); | ||
333 | goto failed; | ||
334 | } | ||
335 | |||
336 | idkp = kzalloc(sizeof(*idkp), GFP_KERNEL); | ||
337 | if (!idkp) { | ||
338 | printk(KERN_ERR PFX "%s: can't allocate a disk structure\n", | ||
339 | drive->name); | ||
340 | goto failed; | ||
341 | } | ||
342 | |||
343 | g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif)); | ||
344 | if (!g) | ||
345 | goto out_free_idkp; | ||
346 | |||
347 | ide_init_disk(g, drive); | ||
348 | |||
349 | kref_init(&idkp->kref); | ||
350 | |||
351 | idkp->drive = drive; | ||
352 | idkp->driver = &ide_gd_driver; | ||
353 | idkp->disk = g; | ||
354 | |||
355 | g->private_data = &idkp->driver; | ||
356 | |||
357 | drive->driver_data = idkp; | ||
358 | drive->debug_mask = debug_mask; | ||
359 | drive->disk_ops = disk_ops; | ||
360 | |||
361 | disk_ops->setup(drive); | ||
362 | |||
363 | set_capacity(g, ide_gd_capacity(drive)); | ||
364 | |||
365 | g->minors = IDE_DISK_MINORS; | ||
366 | g->driverfs_dev = &drive->gendev; | ||
367 | g->flags |= GENHD_FL_EXT_DEVT; | ||
368 | if (drive->dev_flags & IDE_DFLAG_REMOVABLE) | ||
369 | g->flags = GENHD_FL_REMOVABLE; | ||
370 | g->fops = &ide_gd_ops; | ||
371 | add_disk(g); | ||
372 | return 0; | ||
373 | |||
374 | out_free_idkp: | ||
375 | kfree(idkp); | ||
376 | failed: | ||
377 | return -ENODEV; | ||
378 | } | ||
379 | |||
380 | static int __init ide_gd_init(void) | ||
381 | { | ||
382 | printk(KERN_INFO DRV_NAME " driver " IDE_GD_VERSION "\n"); | ||
383 | return driver_register(&ide_gd_driver.gen_driver); | ||
384 | } | ||
385 | |||
386 | static void __exit ide_gd_exit(void) | ||
387 | { | ||
388 | driver_unregister(&ide_gd_driver.gen_driver); | ||
389 | } | ||
390 | |||
391 | MODULE_ALIAS("ide:*m-disk*"); | ||
392 | MODULE_ALIAS("ide-disk"); | ||
393 | MODULE_ALIAS("ide:*m-floppy*"); | ||
394 | MODULE_ALIAS("ide-floppy"); | ||
395 | module_init(ide_gd_init); | ||
396 | module_exit(ide_gd_exit); | ||
397 | MODULE_LICENSE("GPL"); | ||
398 | MODULE_DESCRIPTION("generic ATA/ATAPI disk driver"); | ||
diff --git a/drivers/ide/ide-gd.h b/drivers/ide/ide-gd.h new file mode 100644 index 000000000000..7d3d101713e0 --- /dev/null +++ b/drivers/ide/ide-gd.h | |||
@@ -0,0 +1,44 @@ | |||
1 | #ifndef __IDE_GD_H | ||
2 | #define __IDE_GD_H | ||
3 | |||
4 | #define DRV_NAME "ide-gd" | ||
5 | #define PFX DRV_NAME ": " | ||
6 | |||
7 | /* define to see debug info */ | ||
8 | #define IDE_GD_DEBUG_LOG 0 | ||
9 | |||
10 | #if IDE_GD_DEBUG_LOG | ||
11 | #define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args) | ||
12 | #else | ||
13 | #define ide_debug_log(lvl, fmt, args...) do {} while (0) | ||
14 | #endif | ||
15 | |||
16 | struct ide_disk_obj { | ||
17 | ide_drive_t *drive; | ||
18 | ide_driver_t *driver; | ||
19 | struct gendisk *disk; | ||
20 | struct kref kref; | ||
21 | unsigned int openers; /* protected by BKL for now */ | ||
22 | |||
23 | /* Last failed packet command */ | ||
24 | struct ide_atapi_pc *failed_pc; | ||
25 | /* used for blk_{fs,pc}_request() requests */ | ||
26 | struct ide_atapi_pc queued_pc; | ||
27 | |||
28 | /* Last error information */ | ||
29 | u8 sense_key, asc, ascq; | ||
30 | |||
31 | int progress_indication; | ||
32 | |||
33 | /* Device information */ | ||
34 | /* Current format */ | ||
35 | int blocks, block_size, bs_factor; | ||
36 | /* Last format capacity descriptor */ | ||
37 | u8 cap_desc[8]; | ||
38 | /* Copy of the flexible disk page */ | ||
39 | u8 flexible_disk_page[32]; | ||
40 | }; | ||
41 | |||
42 | sector_t ide_gd_capacity(ide_drive_t *); | ||
43 | |||
44 | #endif /* __IDE_GD_H */ | ||
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index b762deb2dacb..bb7a1ed8094e 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -755,7 +755,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) | |||
755 | 755 | ||
756 | udelay(1); | 756 | udelay(1); |
757 | SELECT_DRIVE(drive); | 757 | SELECT_DRIVE(drive); |
758 | SELECT_MASK(drive, 0); | 758 | SELECT_MASK(drive, 1); |
759 | udelay(1); | 759 | udelay(1); |
760 | tp_ops->set_irq(hwif, 0); | 760 | tp_ops->set_irq(hwif, 0); |
761 | 761 | ||
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 19f8c7770a25..1649ea54f76c 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -208,6 +208,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) | |||
208 | drive->ready_stat = 0; | 208 | drive->ready_stat = 0; |
209 | if (ata_id_cdb_intr(id)) | 209 | if (ata_id_cdb_intr(id)) |
210 | drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT; | 210 | drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT; |
211 | drive->dev_flags |= IDE_DFLAG_DOORLOCKING; | ||
211 | /* we don't do head unloading on ATAPI devices */ | 212 | /* we don't do head unloading on ATAPI devices */ |
212 | drive->dev_flags |= IDE_DFLAG_NO_UNLOAD; | 213 | drive->dev_flags |= IDE_DFLAG_NO_UNLOAD; |
213 | return; | 214 | return; |
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index b26926487cc0..c31d0dd7a532 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c | |||
@@ -567,10 +567,10 @@ static void ide_remove_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t | |||
567 | void ide_proc_register_driver(ide_drive_t *drive, ide_driver_t *driver) | 567 | void ide_proc_register_driver(ide_drive_t *drive, ide_driver_t *driver) |
568 | { | 568 | { |
569 | mutex_lock(&ide_setting_mtx); | 569 | mutex_lock(&ide_setting_mtx); |
570 | drive->settings = driver->settings; | 570 | drive->settings = driver->proc_devsets(drive); |
571 | mutex_unlock(&ide_setting_mtx); | 571 | mutex_unlock(&ide_setting_mtx); |
572 | 572 | ||
573 | ide_add_proc_entries(drive->proc, driver->proc, drive); | 573 | ide_add_proc_entries(drive->proc, driver->proc_entries(drive), drive); |
574 | } | 574 | } |
575 | 575 | ||
576 | EXPORT_SYMBOL(ide_proc_register_driver); | 576 | EXPORT_SYMBOL(ide_proc_register_driver); |
@@ -591,7 +591,7 @@ void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver) | |||
591 | { | 591 | { |
592 | unsigned long flags; | 592 | unsigned long flags; |
593 | 593 | ||
594 | ide_remove_proc_entries(drive->proc, driver->proc); | 594 | ide_remove_proc_entries(drive->proc, driver->proc_entries(drive)); |
595 | 595 | ||
596 | mutex_lock(&ide_setting_mtx); | 596 | mutex_lock(&ide_setting_mtx); |
597 | spin_lock_irqsave(&ide_lock, flags); | 597 | spin_lock_irqsave(&ide_lock, flags); |
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index d879c7797cde..b2b2e5e8d38e 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -2108,7 +2108,7 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive) | |||
2108 | 2108 | ||
2109 | /* device lacks locking support according to capabilities page */ | 2109 | /* device lacks locking support according to capabilities page */ |
2110 | if ((caps[6] & 1) == 0) | 2110 | if ((caps[6] & 1) == 0) |
2111 | drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK; | 2111 | drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; |
2112 | 2112 | ||
2113 | if (caps[7] & 0x02) | 2113 | if (caps[7] & 0x02) |
2114 | tape->blk_size = 512; | 2114 | tape->blk_size = 512; |
@@ -2298,6 +2298,16 @@ static ide_proc_entry_t idetape_proc[] = { | |||
2298 | { "name", S_IFREG|S_IRUGO, proc_idetape_read_name, NULL }, | 2298 | { "name", S_IFREG|S_IRUGO, proc_idetape_read_name, NULL }, |
2299 | { NULL, 0, NULL, NULL } | 2299 | { NULL, 0, NULL, NULL } |
2300 | }; | 2300 | }; |
2301 | |||
2302 | static ide_proc_entry_t *ide_tape_proc_entries(ide_drive_t *drive) | ||
2303 | { | ||
2304 | return idetape_proc; | ||
2305 | } | ||
2306 | |||
2307 | static const struct ide_proc_devset *ide_tape_proc_devsets(ide_drive_t *drive) | ||
2308 | { | ||
2309 | return idetape_settings; | ||
2310 | } | ||
2301 | #endif | 2311 | #endif |
2302 | 2312 | ||
2303 | static int ide_tape_probe(ide_drive_t *); | 2313 | static int ide_tape_probe(ide_drive_t *); |
@@ -2315,8 +2325,8 @@ static ide_driver_t idetape_driver = { | |||
2315 | .end_request = idetape_end_request, | 2325 | .end_request = idetape_end_request, |
2316 | .error = __ide_error, | 2326 | .error = __ide_error, |
2317 | #ifdef CONFIG_IDE_PROC_FS | 2327 | #ifdef CONFIG_IDE_PROC_FS |
2318 | .proc = idetape_proc, | 2328 | .proc_entries = ide_tape_proc_entries, |
2319 | .settings = idetape_settings, | 2329 | .proc_devsets = ide_tape_proc_devsets, |
2320 | #endif | 2330 | #endif |
2321 | }; | 2331 | }; |
2322 | 2332 | ||
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile index 02e6ee7d751d..ab44a1f5f5a9 100644 --- a/drivers/ide/pci/Makefile +++ b/drivers/ide/pci/Makefile | |||
@@ -11,7 +11,6 @@ obj-$(CONFIG_BLK_DEV_CS5535) += cs5535.o | |||
11 | obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o | 11 | obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o |
12 | obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o | 12 | obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o |
13 | obj-$(CONFIG_BLK_DEV_DELKIN) += delkin_cb.o | 13 | obj-$(CONFIG_BLK_DEV_DELKIN) += delkin_cb.o |
14 | obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o | ||
15 | obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o | 14 | obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o |
16 | obj-$(CONFIG_BLK_DEV_IT8213) += it8213.o | 15 | obj-$(CONFIG_BLK_DEV_IT8213) += it8213.o |
17 | obj-$(CONFIG_BLK_DEV_IT821X) += it821x.o | 16 | obj-$(CONFIG_BLK_DEV_IT821X) += it821x.o |
diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/pci/delkin_cb.c index 8689a706f537..8f1b2d9f0513 100644 --- a/drivers/ide/pci/delkin_cb.c +++ b/drivers/ide/pci/delkin_cb.c | |||
@@ -46,10 +46,27 @@ static const struct ide_port_ops delkin_cb_port_ops = { | |||
46 | .quirkproc = ide_undecoded_slave, | 46 | .quirkproc = ide_undecoded_slave, |
47 | }; | 47 | }; |
48 | 48 | ||
49 | static unsigned int delkin_cb_init_chipset(struct pci_dev *dev) | ||
50 | { | ||
51 | unsigned long base = pci_resource_start(dev, 0); | ||
52 | int i; | ||
53 | |||
54 | outb(0x02, base + 0x1e); /* set nIEN to block interrupts */ | ||
55 | inb(base + 0x17); /* read status to clear interrupts */ | ||
56 | |||
57 | for (i = 0; i < sizeof(setup); ++i) { | ||
58 | if (setup[i]) | ||
59 | outb(setup[i], base + i); | ||
60 | } | ||
61 | |||
62 | return 0; | ||
63 | } | ||
64 | |||
49 | static const struct ide_port_info delkin_cb_port_info = { | 65 | static const struct ide_port_info delkin_cb_port_info = { |
50 | .port_ops = &delkin_cb_port_ops, | 66 | .port_ops = &delkin_cb_port_ops, |
51 | .host_flags = IDE_HFLAG_IO_32BIT | IDE_HFLAG_UNMASK_IRQS | | 67 | .host_flags = IDE_HFLAG_IO_32BIT | IDE_HFLAG_UNMASK_IRQS | |
52 | IDE_HFLAG_NO_DMA, | 68 | IDE_HFLAG_NO_DMA, |
69 | .init_chipset = delkin_cb_init_chipset, | ||
53 | }; | 70 | }; |
54 | 71 | ||
55 | static int __devinit | 72 | static int __devinit |
@@ -57,7 +74,7 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) | |||
57 | { | 74 | { |
58 | struct ide_host *host; | 75 | struct ide_host *host; |
59 | unsigned long base; | 76 | unsigned long base; |
60 | int i, rc; | 77 | int rc; |
61 | hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; | 78 | hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; |
62 | 79 | ||
63 | rc = pci_enable_device(dev); | 80 | rc = pci_enable_device(dev); |
@@ -72,12 +89,8 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) | |||
72 | return rc; | 89 | return rc; |
73 | } | 90 | } |
74 | base = pci_resource_start(dev, 0); | 91 | base = pci_resource_start(dev, 0); |
75 | outb(0x02, base + 0x1e); /* set nIEN to block interrupts */ | 92 | |
76 | inb(base + 0x17); /* read status to clear interrupts */ | 93 | delkin_cb_init_chipset(dev); |
77 | for (i = 0; i < sizeof(setup); ++i) { | ||
78 | if (setup[i]) | ||
79 | outb(setup[i], base + i); | ||
80 | } | ||
81 | 94 | ||
82 | memset(&hw, 0, sizeof(hw)); | 95 | memset(&hw, 0, sizeof(hw)); |
83 | ide_std_init_ports(&hw, base + 0x10, base + 0x1e); | 96 | ide_std_init_ports(&hw, base + 0x10, base + 0x1e); |
@@ -110,6 +123,40 @@ delkin_cb_remove (struct pci_dev *dev) | |||
110 | pci_disable_device(dev); | 123 | pci_disable_device(dev); |
111 | } | 124 | } |
112 | 125 | ||
126 | #ifdef CONFIG_PM | ||
127 | static int delkin_cb_suspend(struct pci_dev *dev, pm_message_t state) | ||
128 | { | ||
129 | pci_save_state(dev); | ||
130 | pci_disable_device(dev); | ||
131 | pci_set_power_state(dev, pci_choose_state(dev, state)); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static int delkin_cb_resume(struct pci_dev *dev) | ||
137 | { | ||
138 | struct ide_host *host = pci_get_drvdata(dev); | ||
139 | int rc; | ||
140 | |||
141 | pci_set_power_state(dev, PCI_D0); | ||
142 | |||
143 | rc = pci_enable_device(dev); | ||
144 | if (rc) | ||
145 | return rc; | ||
146 | |||
147 | pci_restore_state(dev); | ||
148 | pci_set_master(dev); | ||
149 | |||
150 | if (host->init_chipset) | ||
151 | host->init_chipset(dev); | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | #else | ||
156 | #define delkin_cb_suspend NULL | ||
157 | #define delkin_cb_resume NULL | ||
158 | #endif | ||
159 | |||
113 | static struct pci_device_id delkin_cb_pci_tbl[] __devinitdata = { | 160 | static struct pci_device_id delkin_cb_pci_tbl[] __devinitdata = { |
114 | { 0x1145, 0xf021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 161 | { 0x1145, 0xf021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
115 | { 0x1145, 0xf024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 162 | { 0x1145, 0xf024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
@@ -122,6 +169,8 @@ static struct pci_driver delkin_cb_pci_driver = { | |||
122 | .id_table = delkin_cb_pci_tbl, | 169 | .id_table = delkin_cb_pci_tbl, |
123 | .probe = delkin_cb_probe, | 170 | .probe = delkin_cb_probe, |
124 | .remove = delkin_cb_remove, | 171 | .remove = delkin_cb_remove, |
172 | .suspend = delkin_cb_suspend, | ||
173 | .resume = delkin_cb_resume, | ||
125 | }; | 174 | }; |
126 | 175 | ||
127 | static int __init delkin_cb_init(void) | 176 | static int __init delkin_cb_init(void) |
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c deleted file mode 100644 index fb1a3aa57f07..000000000000 --- a/drivers/ide/pci/hpt34x.c +++ /dev/null | |||
@@ -1,193 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> | ||
3 | * | ||
4 | * May be copied or modified under the terms of the GNU General Public License | ||
5 | * | ||
6 | * | ||
7 | * 00:12.0 Unknown mass storage controller: | ||
8 | * Triones Technologies, Inc. | ||
9 | * Unknown device 0003 (rev 01) | ||
10 | * | ||
11 | * hde: UDMA 2 (0x0000 0x0002) (0x0000 0x0010) | ||
12 | * hdf: UDMA 2 (0x0002 0x0012) (0x0010 0x0030) | ||
13 | * hde: DMA 2 (0x0000 0x0002) (0x0000 0x0010) | ||
14 | * hdf: DMA 2 (0x0002 0x0012) (0x0010 0x0030) | ||
15 | * hdg: DMA 1 (0x0012 0x0052) (0x0030 0x0070) | ||
16 | * hdh: DMA 1 (0x0052 0x0252) (0x0070 0x00f0) | ||
17 | * | ||
18 | * ide-pci.c reference | ||
19 | * | ||
20 | * Since there are two cards that report almost identically, | ||
21 | * the only discernable difference is the values reported in pcicmd. | ||
22 | * Booting-BIOS card or HPT363 :: pcicmd == 0x07 | ||
23 | * Non-bootable card or HPT343 :: pcicmd == 0x05 | ||
24 | */ | ||
25 | |||
26 | #include <linux/module.h> | ||
27 | #include <linux/types.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/ioport.h> | ||
30 | #include <linux/interrupt.h> | ||
31 | #include <linux/pci.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/ide.h> | ||
34 | |||
35 | #define DRV_NAME "hpt34x" | ||
36 | |||
37 | #define HPT343_DEBUG_DRIVE_INFO 0 | ||
38 | |||
39 | static void hpt34x_set_mode(ide_drive_t *drive, const u8 speed) | ||
40 | { | ||
41 | struct pci_dev *dev = to_pci_dev(drive->hwif->dev); | ||
42 | u32 reg1= 0, tmp1 = 0, reg2 = 0, tmp2 = 0; | ||
43 | u8 hi_speed, lo_speed; | ||
44 | |||
45 | hi_speed = speed >> 4; | ||
46 | lo_speed = speed & 0x0f; | ||
47 | |||
48 | if (hi_speed & 7) { | ||
49 | hi_speed = (hi_speed & 4) ? 0x01 : 0x10; | ||
50 | } else { | ||
51 | lo_speed <<= 5; | ||
52 | lo_speed >>= 5; | ||
53 | } | ||
54 | |||
55 | pci_read_config_dword(dev, 0x44, ®1); | ||
56 | pci_read_config_dword(dev, 0x48, ®2); | ||
57 | tmp1 = ((lo_speed << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn)))); | ||
58 | tmp2 = ((hi_speed << drive->dn) | (reg2 & ~(0x11 << drive->dn))); | ||
59 | pci_write_config_dword(dev, 0x44, tmp1); | ||
60 | pci_write_config_dword(dev, 0x48, tmp2); | ||
61 | |||
62 | #if HPT343_DEBUG_DRIVE_INFO | ||
63 | printk("%s: %s drive%d (0x%04x 0x%04x) (0x%04x 0x%04x)" \ | ||
64 | " (0x%02x 0x%02x)\n", | ||
65 | drive->name, ide_xfer_verbose(speed), | ||
66 | drive->dn, reg1, tmp1, reg2, tmp2, | ||
67 | hi_speed, lo_speed); | ||
68 | #endif /* HPT343_DEBUG_DRIVE_INFO */ | ||
69 | } | ||
70 | |||
71 | static void hpt34x_set_pio_mode(ide_drive_t *drive, const u8 pio) | ||
72 | { | ||
73 | hpt34x_set_mode(drive, XFER_PIO_0 + pio); | ||
74 | } | ||
75 | |||
76 | /* | ||
77 | * If the BIOS does not set the IO base addaress to XX00, 343 will fail. | ||
78 | */ | ||
79 | #define HPT34X_PCI_INIT_REG 0x80 | ||
80 | |||
81 | static unsigned int init_chipset_hpt34x(struct pci_dev *dev) | ||
82 | { | ||
83 | int i = 0; | ||
84 | unsigned long hpt34xIoBase = pci_resource_start(dev, 4); | ||
85 | unsigned long hpt_addr[4] = { 0x20, 0x34, 0x28, 0x3c }; | ||
86 | unsigned long hpt_addr_len[4] = { 7, 3, 7, 3 }; | ||
87 | u16 cmd; | ||
88 | unsigned long flags; | ||
89 | |||
90 | local_irq_save(flags); | ||
91 | |||
92 | pci_write_config_byte(dev, HPT34X_PCI_INIT_REG, 0x00); | ||
93 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
94 | |||
95 | if (cmd & PCI_COMMAND_MEMORY) | ||
96 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0); | ||
97 | else | ||
98 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20); | ||
99 | |||
100 | /* | ||
101 | * Since 20-23 can be assigned and are R/W, we correct them. | ||
102 | */ | ||
103 | pci_write_config_word(dev, PCI_COMMAND, cmd & ~PCI_COMMAND_IO); | ||
104 | for(i=0; i<4; i++) { | ||
105 | dev->resource[i].start = (hpt34xIoBase + hpt_addr[i]); | ||
106 | dev->resource[i].end = dev->resource[i].start + hpt_addr_len[i]; | ||
107 | dev->resource[i].flags = IORESOURCE_IO; | ||
108 | pci_write_config_dword(dev, | ||
109 | (PCI_BASE_ADDRESS_0 + (i * 4)), | ||
110 | dev->resource[i].start); | ||
111 | } | ||
112 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
113 | |||
114 | local_irq_restore(flags); | ||
115 | |||
116 | return dev->irq; | ||
117 | } | ||
118 | |||
119 | static const struct ide_port_ops hpt34x_port_ops = { | ||
120 | .set_pio_mode = hpt34x_set_pio_mode, | ||
121 | .set_dma_mode = hpt34x_set_mode, | ||
122 | }; | ||
123 | |||
124 | #define IDE_HFLAGS_HPT34X \ | ||
125 | (IDE_HFLAG_NO_ATAPI_DMA | \ | ||
126 | IDE_HFLAG_NO_DSC | \ | ||
127 | IDE_HFLAG_NO_AUTODMA) | ||
128 | |||
129 | static const struct ide_port_info hpt34x_chipsets[] __devinitdata = { | ||
130 | { /* 0: HPT343 */ | ||
131 | .name = DRV_NAME, | ||
132 | .init_chipset = init_chipset_hpt34x, | ||
133 | .port_ops = &hpt34x_port_ops, | ||
134 | .host_flags = IDE_HFLAGS_HPT34X | IDE_HFLAG_NON_BOOTABLE, | ||
135 | .pio_mask = ATA_PIO5, | ||
136 | }, | ||
137 | { /* 1: HPT345 */ | ||
138 | .name = DRV_NAME, | ||
139 | .init_chipset = init_chipset_hpt34x, | ||
140 | .port_ops = &hpt34x_port_ops, | ||
141 | .host_flags = IDE_HFLAGS_HPT34X | IDE_HFLAG_OFF_BOARD, | ||
142 | .pio_mask = ATA_PIO5, | ||
143 | #ifdef CONFIG_HPT34X_AUTODMA | ||
144 | .swdma_mask = ATA_SWDMA2, | ||
145 | .mwdma_mask = ATA_MWDMA2, | ||
146 | .udma_mask = ATA_UDMA2, | ||
147 | #endif | ||
148 | } | ||
149 | }; | ||
150 | |||
151 | static int __devinit hpt34x_init_one(struct pci_dev *dev, const struct pci_device_id *id) | ||
152 | { | ||
153 | const struct ide_port_info *d; | ||
154 | u16 pcicmd = 0; | ||
155 | |||
156 | pci_read_config_word(dev, PCI_COMMAND, &pcicmd); | ||
157 | |||
158 | d = &hpt34x_chipsets[(pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0]; | ||
159 | |||
160 | return ide_pci_init_one(dev, d, NULL); | ||
161 | } | ||
162 | |||
163 | static const struct pci_device_id hpt34x_pci_tbl[] = { | ||
164 | { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT343), 0 }, | ||
165 | { 0, }, | ||
166 | }; | ||
167 | MODULE_DEVICE_TABLE(pci, hpt34x_pci_tbl); | ||
168 | |||
169 | static struct pci_driver hpt34x_pci_driver = { | ||
170 | .name = "HPT34x_IDE", | ||
171 | .id_table = hpt34x_pci_tbl, | ||
172 | .probe = hpt34x_init_one, | ||
173 | .remove = ide_pci_remove, | ||
174 | .suspend = ide_pci_suspend, | ||
175 | .resume = ide_pci_resume, | ||
176 | }; | ||
177 | |||
178 | static int __init hpt34x_ide_init(void) | ||
179 | { | ||
180 | return ide_pci_register_driver(&hpt34x_pci_driver); | ||
181 | } | ||
182 | |||
183 | static void __exit hpt34x_ide_exit(void) | ||
184 | { | ||
185 | pci_unregister_driver(&hpt34x_pci_driver); | ||
186 | } | ||
187 | |||
188 | module_init(hpt34x_ide_init); | ||
189 | module_exit(hpt34x_ide_exit); | ||
190 | |||
191 | MODULE_AUTHOR("Andre Hedrick"); | ||
192 | MODULE_DESCRIPTION("PCI driver module for Highpoint 34x IDE"); | ||
193 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 9cf171cb9376..a7909e9c720e 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. | 3 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. |
4 | * Portions Copyright (C) 2003 Red Hat Inc | 4 | * Portions Copyright (C) 2003 Red Hat Inc |
5 | * Portions Copyright (C) 2007 Bartlomiej Zolnierkiewicz | 5 | * Portions Copyright (C) 2007 Bartlomiej Zolnierkiewicz |
6 | * Portions Copyright (C) 2005-2007 MontaVista Software, Inc. | 6 | * Portions Copyright (C) 2005-2008 MontaVista Software, Inc. |
7 | * | 7 | * |
8 | * Thanks to HighPoint Technologies for their assistance, and hardware. | 8 | * Thanks to HighPoint Technologies for their assistance, and hardware. |
9 | * Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his | 9 | * Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his |
@@ -748,26 +748,24 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask) | |||
748 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 748 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
749 | struct hpt_info *info = hpt3xx_get_info(hwif->dev); | 749 | struct hpt_info *info = hpt3xx_get_info(hwif->dev); |
750 | 750 | ||
751 | if (drive->quirk_list) { | 751 | if (drive->quirk_list == 0) |
752 | if (info->chip_type >= HPT370) { | 752 | return; |
753 | u8 scr1 = 0; | 753 | |
754 | 754 | if (info->chip_type >= HPT370) { | |
755 | pci_read_config_byte(dev, 0x5a, &scr1); | 755 | u8 scr1 = 0; |
756 | if (((scr1 & 0x10) >> 4) != mask) { | 756 | |
757 | if (mask) | 757 | pci_read_config_byte(dev, 0x5a, &scr1); |
758 | scr1 |= 0x10; | 758 | if (((scr1 & 0x10) >> 4) != mask) { |
759 | else | ||
760 | scr1 &= ~0x10; | ||
761 | pci_write_config_byte(dev, 0x5a, scr1); | ||
762 | } | ||
763 | } else { | ||
764 | if (mask) | 759 | if (mask) |
765 | disable_irq(hwif->irq); | 760 | scr1 |= 0x10; |
766 | else | 761 | else |
767 | enable_irq (hwif->irq); | 762 | scr1 &= ~0x10; |
763 | pci_write_config_byte(dev, 0x5a, scr1); | ||
768 | } | 764 | } |
769 | } else | 765 | } else if (mask) |
770 | outb(ATA_DEVCTL_OBS | (mask ? 2 : 0), hwif->io_ports.ctl_addr); | 766 | disable_irq(hwif->irq); |
767 | else | ||
768 | enable_irq(hwif->irq); | ||
771 | } | 769 | } |
772 | 770 | ||
773 | /* | 771 | /* |
@@ -1289,7 +1287,6 @@ static u8 hpt3xx_cable_detect(ide_hwif_t *hwif) | |||
1289 | 1287 | ||
1290 | static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) | 1288 | static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) |
1291 | { | 1289 | { |
1292 | struct pci_dev *dev = to_pci_dev(hwif->dev); | ||
1293 | struct hpt_info *info = hpt3xx_get_info(hwif->dev); | 1290 | struct hpt_info *info = hpt3xx_get_info(hwif->dev); |
1294 | int serialize = HPT_SERIALIZE_IO; | 1291 | int serialize = HPT_SERIALIZE_IO; |
1295 | u8 chip_type = info->chip_type; | 1292 | u8 chip_type = info->chip_type; |
diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c index 9ce1d8059921..49f163aa51e3 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c | |||
@@ -617,7 +617,6 @@ static int __devinit init_setup_scc(struct pci_dev *dev, | |||
617 | unsigned long intmask_port; | 617 | unsigned long intmask_port; |
618 | unsigned long mode_port; | 618 | unsigned long mode_port; |
619 | unsigned long ecmode_port; | 619 | unsigned long ecmode_port; |
620 | unsigned long dma_status_port; | ||
621 | u32 reg = 0; | 620 | u32 reg = 0; |
622 | struct scc_ports *ports; | 621 | struct scc_ports *ports; |
623 | int rc; | 622 | int rc; |
@@ -637,7 +636,6 @@ static int __devinit init_setup_scc(struct pci_dev *dev, | |||
637 | intmask_port = dma_base + 0x010; | 636 | intmask_port = dma_base + 0x010; |
638 | mode_port = ctl_base + 0x024; | 637 | mode_port = ctl_base + 0x024; |
639 | ecmode_port = ctl_base + 0xf00; | 638 | ecmode_port = ctl_base + 0xf00; |
640 | dma_status_port = dma_base + 0x004; | ||
641 | 639 | ||
642 | /* controller initialization */ | 640 | /* controller initialization */ |
643 | reg = 0; | 641 | reg = 0; |
@@ -843,8 +841,6 @@ static u8 scc_cable_detect(ide_hwif_t *hwif) | |||
843 | 841 | ||
844 | static void __devinit init_hwif_scc(ide_hwif_t *hwif) | 842 | static void __devinit init_hwif_scc(ide_hwif_t *hwif) |
845 | { | 843 | { |
846 | struct scc_ports *ports = ide_get_hwifdata(hwif); | ||
847 | |||
848 | /* PTERADD */ | 844 | /* PTERADD */ |
849 | out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma); | 845 | out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma); |
850 | 846 | ||
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index dd634541ce36..8af9b23499fd 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c | |||
@@ -101,18 +101,8 @@ sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port, | |||
101 | for (i = 0; i <= 7; i++) | 101 | for (i = 0; i <= 7; i++) |
102 | hw->io_ports_array[i] = reg + i * 4; | 102 | hw->io_ports_array[i] = reg + i * 4; |
103 | 103 | ||
104 | if (ctrl_port) | 104 | hw->io_ports.ctl_addr = ctrl_port; |
105 | hw->io_ports.ctl_addr = ctrl_port; | 105 | hw->io_ports.irq_addr = irq_port; |
106 | |||
107 | if (irq_port) | ||
108 | hw->io_ports.irq_addr = irq_port; | ||
109 | } | ||
110 | |||
111 | static void | ||
112 | sgiioc4_maskproc(ide_drive_t * drive, int mask) | ||
113 | { | ||
114 | writeb(ATA_DEVCTL_OBS | (mask ? 2 : 0), | ||
115 | (void __iomem *)drive->hwif->io_ports.ctl_addr); | ||
116 | } | 106 | } |
117 | 107 | ||
118 | static int | 108 | static int |
@@ -310,16 +300,14 @@ static u8 sgiioc4_read_status(ide_hwif_t *hwif) | |||
310 | unsigned long port = hwif->io_ports.status_addr; | 300 | unsigned long port = hwif->io_ports.status_addr; |
311 | u8 reg = (u8) readb((void __iomem *) port); | 301 | u8 reg = (u8) readb((void __iomem *) port); |
312 | 302 | ||
313 | if ((port & 0xFFF) == 0x11C) { /* Status register of IOC4 */ | 303 | if (!(reg & ATA_BUSY)) { /* Not busy... check for interrupt */ |
314 | if (!(reg & ATA_BUSY)) { /* Not busy... check for interrupt */ | 304 | unsigned long other_ir = port - 0x110; |
315 | unsigned long other_ir = port - 0x110; | 305 | unsigned int intr_reg = (u32) readl((void __iomem *) other_ir); |
316 | unsigned int intr_reg = (u32) readl((void __iomem *) other_ir); | ||
317 | 306 | ||
318 | /* Clear the Interrupt, Error bits on the IOC4 */ | 307 | /* Clear the Interrupt, Error bits on the IOC4 */ |
319 | if (intr_reg & 0x03) { | 308 | if (intr_reg & 0x03) { |
320 | writel(0x03, (void __iomem *) other_ir); | 309 | writel(0x03, (void __iomem *) other_ir); |
321 | intr_reg = (u32) readl((void __iomem *) other_ir); | 310 | intr_reg = (u32) readl((void __iomem *) other_ir); |
322 | } | ||
323 | } | 311 | } |
324 | } | 312 | } |
325 | 313 | ||
@@ -332,13 +320,9 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d) | |||
332 | { | 320 | { |
333 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 321 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
334 | unsigned long dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET; | 322 | unsigned long dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET; |
335 | void __iomem *virt_dma_base; | ||
336 | int num_ports = sizeof (ioc4_dma_regs_t); | 323 | int num_ports = sizeof (ioc4_dma_regs_t); |
337 | void *pad; | 324 | void *pad; |
338 | 325 | ||
339 | if (dma_base == 0) | ||
340 | return -1; | ||
341 | |||
342 | printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name); | 326 | printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name); |
343 | 327 | ||
344 | if (request_mem_region(dma_base, num_ports, hwif->name) == NULL) { | 328 | if (request_mem_region(dma_base, num_ports, hwif->name) == NULL) { |
@@ -348,14 +332,8 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d) | |||
348 | return -1; | 332 | return -1; |
349 | } | 333 | } |
350 | 334 | ||
351 | virt_dma_base = ioremap(dma_base, num_ports); | 335 | hwif->dma_base = (unsigned long)hwif->io_ports.irq_addr + |
352 | if (virt_dma_base == NULL) { | 336 | IOC4_DMA_OFFSET; |
353 | printk(KERN_ERR "%s(%s) -- ERROR: unable to map addresses " | ||
354 | "0x%lx to 0x%lx\n", __func__, hwif->name, | ||
355 | dma_base, dma_base + num_ports - 1); | ||
356 | goto dma_remap_failure; | ||
357 | } | ||
358 | hwif->dma_base = (unsigned long) virt_dma_base; | ||
359 | 337 | ||
360 | hwif->sg_max_nents = IOC4_PRD_ENTRIES; | 338 | hwif->sg_max_nents = IOC4_PRD_ENTRIES; |
361 | 339 | ||
@@ -379,9 +357,6 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d) | |||
379 | printk(KERN_INFO "%s: changing from DMA to PIO mode", hwif->name); | 357 | printk(KERN_INFO "%s: changing from DMA to PIO mode", hwif->name); |
380 | 358 | ||
381 | dma_pci_alloc_failure: | 359 | dma_pci_alloc_failure: |
382 | iounmap(virt_dma_base); | ||
383 | |||
384 | dma_remap_failure: | ||
385 | release_mem_region(dma_base, num_ports); | 360 | release_mem_region(dma_base, num_ports); |
386 | 361 | ||
387 | return -1; | 362 | return -1; |
@@ -563,8 +538,6 @@ static const struct ide_port_ops sgiioc4_port_ops = { | |||
563 | .set_dma_mode = sgiioc4_set_dma_mode, | 538 | .set_dma_mode = sgiioc4_set_dma_mode, |
564 | /* reset DMA engine, clear IRQs */ | 539 | /* reset DMA engine, clear IRQs */ |
565 | .resetproc = sgiioc4_resetproc, | 540 | .resetproc = sgiioc4_resetproc, |
566 | /* mask on/off NIEN register */ | ||
567 | .maskproc = sgiioc4_maskproc, | ||
568 | }; | 541 | }; |
569 | 542 | ||
570 | static const struct ide_dma_ops sgiioc4_dma_ops = { | 543 | static const struct ide_dma_ops sgiioc4_dma_ops = { |
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index a78d35aecee3..f1e82a92e61e 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c | |||
@@ -122,7 +122,7 @@ struct cm_counter_attribute { | |||
122 | 122 | ||
123 | #define CM_COUNTER_ATTR(_name, _index) \ | 123 | #define CM_COUNTER_ATTR(_name, _index) \ |
124 | struct cm_counter_attribute cm_##_name##_counter_attr = { \ | 124 | struct cm_counter_attribute cm_##_name##_counter_attr = { \ |
125 | .attr = { .name = __stringify(_name), .mode = 0444, .owner = THIS_MODULE }, \ | 125 | .attr = { .name = __stringify(_name), .mode = 0444 }, \ |
126 | .index = _index \ | 126 | .index = _index \ |
127 | } | 127 | } |
128 | 128 | ||
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index dff4adca6475..3d1ab8fa9acc 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -223,7 +223,7 @@ config TOUCHSCREEN_ATMEL_TSADCC | |||
223 | 223 | ||
224 | config TOUCHSCREEN_UCB1400 | 224 | config TOUCHSCREEN_UCB1400 |
225 | tristate "Philips UCB1400 touchscreen" | 225 | tristate "Philips UCB1400 touchscreen" |
226 | select AC97_BUS | 226 | depends on AC97_BUS |
227 | depends on UCB1400_CORE | 227 | depends on UCB1400_CORE |
228 | help | 228 | help |
229 | This enables support for the Philips UCB1400 touchscreen interface. | 229 | This enables support for the Philips UCB1400 touchscreen interface. |
diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c index c38d4e0f95c6..a89700e7ace4 100644 --- a/drivers/input/touchscreen/hp680_ts_input.c +++ b/drivers/input/touchscreen/hp680_ts_input.c | |||
@@ -5,7 +5,7 @@ | |||
5 | #include <asm/io.h> | 5 | #include <asm/io.h> |
6 | #include <asm/delay.h> | 6 | #include <asm/delay.h> |
7 | #include <asm/adc.h> | 7 | #include <asm/adc.h> |
8 | #include <asm/hp6xx.h> | 8 | #include <mach/hp6xx.h> |
9 | 9 | ||
10 | #define MODNAME "hp680_ts_input" | 10 | #define MODNAME "hp680_ts_input" |
11 | 11 | ||
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index e3e40427e00e..c7ff1e11ea85 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
@@ -179,7 +179,7 @@ config LEDS_TRIGGER_TIMER | |||
179 | 179 | ||
180 | config LEDS_TRIGGER_IDE_DISK | 180 | config LEDS_TRIGGER_IDE_DISK |
181 | bool "LED IDE Disk Trigger" | 181 | bool "LED IDE Disk Trigger" |
182 | depends on LEDS_TRIGGERS && BLK_DEV_IDEDISK | 182 | depends on LEDS_TRIGGERS && IDE_GD_ATA |
183 | help | 183 | help |
184 | This allows LEDs to be controlled by IDE disk activity. | 184 | This allows LEDs to be controlled by IDE disk activity. |
185 | If unsure, say Y. | 185 | If unsure, say Y. |
diff --git a/drivers/leds/leds-hp6xx.c b/drivers/leds/leds-hp6xx.c index 844d5979c904..e8fb1baf8a50 100644 --- a/drivers/leds/leds-hp6xx.c +++ b/drivers/leds/leds-hp6xx.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | #include <linux/leds.h> | 16 | #include <linux/leds.h> |
17 | #include <asm/hd64461.h> | 17 | #include <asm/hd64461.h> |
18 | #include <asm/hp6xx.h> | 18 | #include <mach/hp6xx.h> |
19 | 19 | ||
20 | static void hp6xxled_green_set(struct led_classdev *led_cdev, | 20 | static void hp6xxled_green_set(struct led_classdev *led_cdev, |
21 | enum led_brightness value) | 21 | enum led_brightness value) |
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index c7c770c28988..aa1ff524256e 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/fs.h> | 36 | #include <linux/fs.h> |
37 | #include <linux/timer.h> | 37 | #include <linux/timer.h> |
38 | #include <linux/poll.h> | 38 | #include <linux/poll.h> |
39 | #include <linux/byteorder/swabb.h> | ||
40 | #include <linux/smp_lock.h> | 39 | #include <linux/smp_lock.h> |
41 | 40 | ||
42 | #include <linux/kernel.h> | 41 | #include <linux/kernel.h> |
@@ -52,6 +51,7 @@ | |||
52 | #include <linux/i2c.h> | 51 | #include <linux/i2c.h> |
53 | #include <linux/kthread.h> | 52 | #include <linux/kthread.h> |
54 | #include <asm/unaligned.h> | 53 | #include <asm/unaligned.h> |
54 | #include <asm/byteorder.h> | ||
55 | 55 | ||
56 | #include <asm/system.h> | 56 | #include <asm/system.h> |
57 | 57 | ||
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index fa8be0731a3f..a4b1708fafe7 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/pagemap.h> | 41 | #include <linux/pagemap.h> |
42 | #include <linux/workqueue.h> | 42 | #include <linux/workqueue.h> |
43 | #include <linux/mutex.h> | 43 | #include <linux/mutex.h> |
44 | #include <asm/byteorder.h> | ||
44 | 45 | ||
45 | #include <linux/dvb/video.h> | 46 | #include <linux/dvb/video.h> |
46 | #include <linux/dvb/audio.h> | 47 | #include <linux/dvb/audio.h> |
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index bc29436e8a3c..3733b2afec5f 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h | |||
@@ -55,6 +55,7 @@ | |||
55 | #include <linux/mutex.h> | 55 | #include <linux/mutex.h> |
56 | #include <asm/uaccess.h> | 56 | #include <asm/uaccess.h> |
57 | #include <asm/system.h> | 57 | #include <asm/system.h> |
58 | #include <asm/byteorder.h> | ||
58 | 59 | ||
59 | #include <linux/dvb/video.h> | 60 | #include <linux/dvb/video.h> |
60 | #include <linux/dvb/audio.h> | 61 | #include <linux/dvb/audio.h> |
diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c index 6e291bf8237a..5263913e0c69 100644 --- a/drivers/memstick/core/mspro_block.c +++ b/drivers/memstick/core/mspro_block.c | |||
@@ -1044,7 +1044,6 @@ static int mspro_block_read_attributes(struct memstick_dev *card) | |||
1044 | 1044 | ||
1045 | s_attr->dev_attr.attr.name = s_attr->name; | 1045 | s_attr->dev_attr.attr.name = s_attr->name; |
1046 | s_attr->dev_attr.attr.mode = S_IRUGO; | 1046 | s_attr->dev_attr.attr.mode = S_IRUGO; |
1047 | s_attr->dev_attr.attr.owner = THIS_MODULE; | ||
1048 | s_attr->dev_attr.show = mspro_block_attr_show(s_attr->id); | 1047 | s_attr->dev_attr.show = mspro_block_attr_show(s_attr->id); |
1049 | 1048 | ||
1050 | if (!rc) | 1049 | if (!rc) |
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 5eff8ad834d6..5a79d2d4cdae 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -52,6 +52,8 @@ config HTC_PASIC3 | |||
52 | 52 | ||
53 | config UCB1400_CORE | 53 | config UCB1400_CORE |
54 | tristate "Philips UCB1400 Core driver" | 54 | tristate "Philips UCB1400 Core driver" |
55 | depends on AC97_BUS | ||
56 | depends on GPIOLIB | ||
55 | help | 57 | help |
56 | This enables support for the Philips UCB1400 core functions. | 58 | This enables support for the Philips UCB1400 core functions. |
57 | The UCB1400 is an AC97 audio codec. | 59 | The UCB1400 is an AC97 audio codec. |
@@ -59,6 +61,20 @@ config UCB1400_CORE | |||
59 | To compile this driver as a module, choose M here: the | 61 | To compile this driver as a module, choose M here: the |
60 | module will be called ucb1400_core. | 62 | module will be called ucb1400_core. |
61 | 63 | ||
64 | config TWL4030_CORE | ||
65 | bool "Texas Instruments TWL4030/TPS659x0 Support" | ||
66 | depends on I2C=y && GENERIC_HARDIRQS && (ARCH_OMAP2 || ARCH_OMAP3) | ||
67 | help | ||
68 | Say yes here if you have TWL4030 family chip on your board. | ||
69 | This core driver provides register access and IRQ handling | ||
70 | facilities, and registers devices for the various functions | ||
71 | so that function-specific drivers can bind to them. | ||
72 | |||
73 | These multi-function chips are found on many OMAP2 and OMAP3 | ||
74 | boards, providing power management, RTC, GPIO, keypad, a | ||
75 | high speed USB OTG transceiver, an audio codec (on most | ||
76 | versions) and many other features. | ||
77 | |||
62 | config MFD_TMIO | 78 | config MFD_TMIO |
63 | bool | 79 | bool |
64 | default n | 80 | default n |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 759b1fe1c891..68e237b830ad 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -17,6 +17,8 @@ wm8350-objs := wm8350-core.o wm8350-regmap.o wm8350-gpio.o | |||
17 | obj-$(CONFIG_MFD_WM8350) += wm8350.o | 17 | obj-$(CONFIG_MFD_WM8350) += wm8350.o |
18 | obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o | 18 | obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o |
19 | 19 | ||
20 | obj-$(CONFIG_TWL4030_CORE) += twl4030-core.o | ||
21 | |||
20 | obj-$(CONFIG_MFD_CORE) += mfd-core.o | 22 | obj-$(CONFIG_MFD_CORE) += mfd-core.o |
21 | 23 | ||
22 | obj-$(CONFIG_MCP) += mcp-core.o | 24 | obj-$(CONFIG_MCP) += mcp-core.o |
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index ba5aa2008273..e4c0db4dc7b1 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c | |||
@@ -123,7 +123,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
123 | irqnr = asic->irq_base + | 123 | irqnr = asic->irq_base + |
124 | (ASIC3_GPIOS_PER_BANK * bank) | 124 | (ASIC3_GPIOS_PER_BANK * bank) |
125 | + i; | 125 | + i; |
126 | desc = irq_desc + irqnr; | 126 | desc = irq_to_desc(irqnr); |
127 | desc->handle_irq(irqnr, desc); | 127 | desc->handle_irq(irqnr, desc); |
128 | if (asic->irq_bothedge[bank] & bit) | 128 | if (asic->irq_bothedge[bank] & bit) |
129 | asic3_irq_flip_edge(asic, base, | 129 | asic3_irq_flip_edge(asic, base, |
@@ -136,7 +136,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc) | |||
136 | for (i = ASIC3_NUM_GPIOS; i < ASIC3_NR_IRQS; i++) { | 136 | for (i = ASIC3_NUM_GPIOS; i < ASIC3_NR_IRQS; i++) { |
137 | /* They start at bit 4 and go up */ | 137 | /* They start at bit 4 and go up */ |
138 | if (status & (1 << (i - ASIC3_NUM_GPIOS + 4))) { | 138 | if (status & (1 << (i - ASIC3_NUM_GPIOS + 4))) { |
139 | desc = irq_desc + asic->irq_base + i; | 139 | desc = irq_to_desc(asic->irq_base + i); |
140 | desc->handle_irq(asic->irq_base + i, | 140 | desc->handle_irq(asic->irq_base + i, |
141 | desc); | 141 | desc); |
142 | } | 142 | } |
diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c new file mode 100644 index 000000000000..b57326ae464d --- /dev/null +++ b/drivers/mfd/da903x.c | |||
@@ -0,0 +1,563 @@ | |||
1 | /* | ||
2 | * Base driver for Dialog Semiconductor DA9030/DA9034 | ||
3 | * | ||
4 | * Copyright (C) 2008 Compulab, Ltd. | ||
5 | * Mike Rapoport <mike@compulab.co.il> | ||
6 | * | ||
7 | * Copyright (C) 2006-2008 Marvell International Ltd. | ||
8 | * Eric Miao <eric.miao@marvell.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/mfd/da903x.h> | ||
21 | |||
22 | #define DA9030_CHIP_ID 0x00 | ||
23 | #define DA9030_EVENT_A 0x01 | ||
24 | #define DA9030_EVENT_B 0x02 | ||
25 | #define DA9030_EVENT_C 0x03 | ||
26 | #define DA9030_STATUS 0x04 | ||
27 | #define DA9030_IRQ_MASK_A 0x05 | ||
28 | #define DA9030_IRQ_MASK_B 0x06 | ||
29 | #define DA9030_IRQ_MASK_C 0x07 | ||
30 | #define DA9030_SYS_CTRL_A 0x08 | ||
31 | #define DA9030_SYS_CTRL_B 0x09 | ||
32 | #define DA9030_FAULT_LOG 0x0a | ||
33 | |||
34 | #define DA9034_CHIP_ID 0x00 | ||
35 | #define DA9034_EVENT_A 0x01 | ||
36 | #define DA9034_EVENT_B 0x02 | ||
37 | #define DA9034_EVENT_C 0x03 | ||
38 | #define DA9034_EVENT_D 0x04 | ||
39 | #define DA9034_STATUS_A 0x05 | ||
40 | #define DA9034_STATUS_B 0x06 | ||
41 | #define DA9034_IRQ_MASK_A 0x07 | ||
42 | #define DA9034_IRQ_MASK_B 0x08 | ||
43 | #define DA9034_IRQ_MASK_C 0x09 | ||
44 | #define DA9034_IRQ_MASK_D 0x0a | ||
45 | #define DA9034_SYS_CTRL_A 0x0b | ||
46 | #define DA9034_SYS_CTRL_B 0x0c | ||
47 | #define DA9034_FAULT_LOG 0x0d | ||
48 | |||
49 | struct da903x_chip; | ||
50 | |||
51 | struct da903x_chip_ops { | ||
52 | int (*init_chip)(struct da903x_chip *); | ||
53 | int (*unmask_events)(struct da903x_chip *, unsigned int events); | ||
54 | int (*mask_events)(struct da903x_chip *, unsigned int events); | ||
55 | int (*read_events)(struct da903x_chip *, unsigned int *events); | ||
56 | int (*read_status)(struct da903x_chip *, unsigned int *status); | ||
57 | }; | ||
58 | |||
59 | struct da903x_chip { | ||
60 | struct i2c_client *client; | ||
61 | struct device *dev; | ||
62 | struct da903x_chip_ops *ops; | ||
63 | |||
64 | int type; | ||
65 | uint32_t events_mask; | ||
66 | |||
67 | struct mutex lock; | ||
68 | struct work_struct irq_work; | ||
69 | |||
70 | struct blocking_notifier_head notifier_list; | ||
71 | }; | ||
72 | |||
73 | static inline int __da903x_read(struct i2c_client *client, | ||
74 | int reg, uint8_t *val) | ||
75 | { | ||
76 | int ret; | ||
77 | |||
78 | ret = i2c_smbus_read_byte_data(client, reg); | ||
79 | if (ret < 0) { | ||
80 | dev_err(&client->dev, "failed reading at 0x%02x\n", reg); | ||
81 | return ret; | ||
82 | } | ||
83 | |||
84 | *val = (uint8_t)ret; | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static inline int __da903x_reads(struct i2c_client *client, int reg, | ||
89 | int len, uint8_t *val) | ||
90 | { | ||
91 | int ret; | ||
92 | |||
93 | ret = i2c_smbus_read_i2c_block_data(client, reg, len, val); | ||
94 | if (ret < 0) { | ||
95 | dev_err(&client->dev, "failed reading from 0x%02x\n", reg); | ||
96 | return ret; | ||
97 | } | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static inline int __da903x_write(struct i2c_client *client, | ||
102 | int reg, uint8_t val) | ||
103 | { | ||
104 | int ret; | ||
105 | |||
106 | ret = i2c_smbus_write_byte_data(client, reg, val); | ||
107 | if (ret < 0) { | ||
108 | dev_err(&client->dev, "failed writing 0x%02x to 0x%02x\n", | ||
109 | val, reg); | ||
110 | return ret; | ||
111 | } | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static inline int __da903x_writes(struct i2c_client *client, int reg, | ||
116 | int len, uint8_t *val) | ||
117 | { | ||
118 | int ret; | ||
119 | |||
120 | ret = i2c_smbus_write_i2c_block_data(client, reg, len, val); | ||
121 | if (ret < 0) { | ||
122 | dev_err(&client->dev, "failed writings to 0x%02x\n", reg); | ||
123 | return ret; | ||
124 | } | ||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | int da903x_register_notifier(struct device *dev, struct notifier_block *nb, | ||
129 | unsigned int events) | ||
130 | { | ||
131 | struct da903x_chip *chip = dev_get_drvdata(dev); | ||
132 | |||
133 | chip->ops->unmask_events(chip, events); | ||
134 | return blocking_notifier_chain_register(&chip->notifier_list, nb); | ||
135 | } | ||
136 | EXPORT_SYMBOL_GPL(da903x_register_notifier); | ||
137 | |||
138 | int da903x_unregister_notifier(struct device *dev, struct notifier_block *nb, | ||
139 | unsigned int events) | ||
140 | { | ||
141 | struct da903x_chip *chip = dev_get_drvdata(dev); | ||
142 | |||
143 | chip->ops->mask_events(chip, events); | ||
144 | return blocking_notifier_chain_unregister(&chip->notifier_list, nb); | ||
145 | } | ||
146 | EXPORT_SYMBOL_GPL(da903x_unregister_notifier); | ||
147 | |||
148 | int da903x_write(struct device *dev, int reg, uint8_t val) | ||
149 | { | ||
150 | return __da903x_write(to_i2c_client(dev), reg, val); | ||
151 | } | ||
152 | EXPORT_SYMBOL_GPL(da903x_write); | ||
153 | |||
154 | int da903x_read(struct device *dev, int reg, uint8_t *val) | ||
155 | { | ||
156 | return __da903x_read(to_i2c_client(dev), reg, val); | ||
157 | } | ||
158 | EXPORT_SYMBOL_GPL(da903x_read); | ||
159 | |||
160 | int da903x_set_bits(struct device *dev, int reg, uint8_t bit_mask) | ||
161 | { | ||
162 | struct da903x_chip *chip = dev_get_drvdata(dev); | ||
163 | uint8_t reg_val; | ||
164 | int ret = 0; | ||
165 | |||
166 | mutex_lock(&chip->lock); | ||
167 | |||
168 | ret = __da903x_read(chip->client, reg, ®_val); | ||
169 | if (ret) | ||
170 | goto out; | ||
171 | |||
172 | if ((reg_val & bit_mask) == 0) { | ||
173 | reg_val |= bit_mask; | ||
174 | ret = __da903x_write(chip->client, reg, reg_val); | ||
175 | } | ||
176 | out: | ||
177 | mutex_unlock(&chip->lock); | ||
178 | return ret; | ||
179 | } | ||
180 | EXPORT_SYMBOL_GPL(da903x_set_bits); | ||
181 | |||
182 | int da903x_clr_bits(struct device *dev, int reg, uint8_t bit_mask) | ||
183 | { | ||
184 | struct da903x_chip *chip = dev_get_drvdata(dev); | ||
185 | uint8_t reg_val; | ||
186 | int ret = 0; | ||
187 | |||
188 | mutex_lock(&chip->lock); | ||
189 | |||
190 | ret = __da903x_read(chip->client, reg, ®_val); | ||
191 | if (ret) | ||
192 | goto out; | ||
193 | |||
194 | if (reg_val & bit_mask) { | ||
195 | reg_val &= ~bit_mask; | ||
196 | ret = __da903x_write(chip->client, reg, reg_val); | ||
197 | } | ||
198 | out: | ||
199 | mutex_unlock(&chip->lock); | ||
200 | return ret; | ||
201 | } | ||
202 | EXPORT_SYMBOL_GPL(da903x_clr_bits); | ||
203 | |||
204 | int da903x_update(struct device *dev, int reg, uint8_t val, uint8_t mask) | ||
205 | { | ||
206 | struct da903x_chip *chip = dev_get_drvdata(dev); | ||
207 | uint8_t reg_val; | ||
208 | int ret = 0; | ||
209 | |||
210 | mutex_lock(&chip->lock); | ||
211 | |||
212 | ret = __da903x_read(chip->client, reg, ®_val); | ||
213 | if (ret) | ||
214 | goto out; | ||
215 | |||
216 | if ((reg_val & mask) != val) { | ||
217 | reg_val = (reg_val & ~mask) | val; | ||
218 | ret = __da903x_write(chip->client, reg, reg_val); | ||
219 | } | ||
220 | out: | ||
221 | mutex_unlock(&chip->lock); | ||
222 | return ret; | ||
223 | } | ||
224 | EXPORT_SYMBOL_GPL(da903x_update); | ||
225 | |||
226 | int da903x_query_status(struct device *dev, unsigned int sbits) | ||
227 | { | ||
228 | struct da903x_chip *chip = dev_get_drvdata(dev); | ||
229 | unsigned int status = 0; | ||
230 | |||
231 | chip->ops->read_status(chip, &status); | ||
232 | return ((status & sbits) == sbits); | ||
233 | } | ||
234 | EXPORT_SYMBOL(da903x_query_status); | ||
235 | |||
236 | static int __devinit da9030_init_chip(struct da903x_chip *chip) | ||
237 | { | ||
238 | uint8_t chip_id; | ||
239 | int err; | ||
240 | |||
241 | err = __da903x_read(chip->client, DA9030_CHIP_ID, &chip_id); | ||
242 | if (err) | ||
243 | return err; | ||
244 | |||
245 | err = __da903x_write(chip->client, DA9030_SYS_CTRL_A, 0xE8); | ||
246 | if (err) | ||
247 | return err; | ||
248 | |||
249 | dev_info(chip->dev, "DA9030 (CHIP ID: 0x%02x) detected\n", chip_id); | ||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | static int da9030_unmask_events(struct da903x_chip *chip, unsigned int events) | ||
254 | { | ||
255 | uint8_t v[3]; | ||
256 | |||
257 | chip->events_mask &= ~events; | ||
258 | |||
259 | v[0] = (chip->events_mask & 0xff); | ||
260 | v[1] = (chip->events_mask >> 8) & 0xff; | ||
261 | v[2] = (chip->events_mask >> 16) & 0xff; | ||
262 | |||
263 | return __da903x_writes(chip->client, DA9030_IRQ_MASK_A, 3, v); | ||
264 | } | ||
265 | |||
266 | static int da9030_mask_events(struct da903x_chip *chip, unsigned int events) | ||
267 | { | ||
268 | uint8_t v[3]; | ||
269 | |||
270 | chip->events_mask &= ~events; | ||
271 | |||
272 | v[0] = (chip->events_mask & 0xff); | ||
273 | v[1] = (chip->events_mask >> 8) & 0xff; | ||
274 | v[2] = (chip->events_mask >> 16) & 0xff; | ||
275 | |||
276 | return __da903x_writes(chip->client, DA9030_IRQ_MASK_A, 3, v); | ||
277 | } | ||
278 | |||
279 | static int da9030_read_events(struct da903x_chip *chip, unsigned int *events) | ||
280 | { | ||
281 | uint8_t v[3] = {0, 0, 0}; | ||
282 | int ret; | ||
283 | |||
284 | ret = __da903x_reads(chip->client, DA9030_EVENT_A, 3, v); | ||
285 | if (ret < 0) | ||
286 | return ret; | ||
287 | |||
288 | *events = (v[2] << 16) | (v[1] << 8) | v[0]; | ||
289 | return 0; | ||
290 | } | ||
291 | |||
292 | static int da9030_read_status(struct da903x_chip *chip, unsigned int *status) | ||
293 | { | ||
294 | return __da903x_read(chip->client, DA9030_STATUS, (uint8_t *)status); | ||
295 | } | ||
296 | |||
297 | static int da9034_init_chip(struct da903x_chip *chip) | ||
298 | { | ||
299 | uint8_t chip_id; | ||
300 | int err; | ||
301 | |||
302 | err = __da903x_read(chip->client, DA9034_CHIP_ID, &chip_id); | ||
303 | if (err) | ||
304 | return err; | ||
305 | |||
306 | err = __da903x_write(chip->client, DA9034_SYS_CTRL_A, 0xE8); | ||
307 | if (err) | ||
308 | return err; | ||
309 | |||
310 | /* avoid SRAM power off during sleep*/ | ||
311 | __da903x_write(chip->client, 0x10, 0x07); | ||
312 | __da903x_write(chip->client, 0x11, 0xff); | ||
313 | __da903x_write(chip->client, 0x12, 0xff); | ||
314 | |||
315 | /* Enable the ONKEY power down functionality */ | ||
316 | __da903x_write(chip->client, DA9034_SYS_CTRL_B, 0x20); | ||
317 | __da903x_write(chip->client, DA9034_SYS_CTRL_A, 0x60); | ||
318 | |||
319 | /* workaround to make LEDs work */ | ||
320 | __da903x_write(chip->client, 0x90, 0x01); | ||
321 | __da903x_write(chip->client, 0xB0, 0x08); | ||
322 | |||
323 | /* make ADTV1 and SDTV1 effective */ | ||
324 | __da903x_write(chip->client, 0x20, 0x00); | ||
325 | |||
326 | dev_info(chip->dev, "DA9034 (CHIP ID: 0x%02x) detected\n", chip_id); | ||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | static int da9034_unmask_events(struct da903x_chip *chip, unsigned int events) | ||
331 | { | ||
332 | uint8_t v[4]; | ||
333 | |||
334 | chip->events_mask &= ~events; | ||
335 | |||
336 | v[0] = (chip->events_mask & 0xff); | ||
337 | v[1] = (chip->events_mask >> 8) & 0xff; | ||
338 | v[2] = (chip->events_mask >> 16) & 0xff; | ||
339 | v[3] = (chip->events_mask >> 24) & 0xff; | ||
340 | |||
341 | return __da903x_writes(chip->client, DA9034_IRQ_MASK_A, 4, v); | ||
342 | } | ||
343 | |||
344 | static int da9034_mask_events(struct da903x_chip *chip, unsigned int events) | ||
345 | { | ||
346 | uint8_t v[4]; | ||
347 | |||
348 | chip->events_mask |= events; | ||
349 | |||
350 | v[0] = (chip->events_mask & 0xff); | ||
351 | v[1] = (chip->events_mask >> 8) & 0xff; | ||
352 | v[2] = (chip->events_mask >> 16) & 0xff; | ||
353 | v[3] = (chip->events_mask >> 24) & 0xff; | ||
354 | |||
355 | return __da903x_writes(chip->client, DA9034_IRQ_MASK_A, 4, v); | ||
356 | } | ||
357 | |||
358 | static int da9034_read_events(struct da903x_chip *chip, unsigned int *events) | ||
359 | { | ||
360 | uint8_t v[4] = {0, 0, 0, 0}; | ||
361 | int ret; | ||
362 | |||
363 | ret = __da903x_reads(chip->client, DA9034_EVENT_A, 4, v); | ||
364 | if (ret < 0) | ||
365 | return ret; | ||
366 | |||
367 | *events = (v[3] << 24) | (v[2] << 16) | (v[1] << 8) | v[0]; | ||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | static int da9034_read_status(struct da903x_chip *chip, unsigned int *status) | ||
372 | { | ||
373 | uint8_t v[2] = {0, 0}; | ||
374 | int ret = 0; | ||
375 | |||
376 | ret = __da903x_reads(chip->client, DA9034_STATUS_A, 2, v); | ||
377 | if (ret) | ||
378 | return ret; | ||
379 | |||
380 | *status = (v[1] << 8) | v[0]; | ||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | static void da903x_irq_work(struct work_struct *work) | ||
385 | { | ||
386 | struct da903x_chip *chip = | ||
387 | container_of(work, struct da903x_chip, irq_work); | ||
388 | unsigned int events = 0; | ||
389 | |||
390 | while (1) { | ||
391 | if (chip->ops->read_events(chip, &events)) | ||
392 | break; | ||
393 | |||
394 | events &= ~chip->events_mask; | ||
395 | if (events == 0) | ||
396 | break; | ||
397 | |||
398 | blocking_notifier_call_chain( | ||
399 | &chip->notifier_list, events, NULL); | ||
400 | } | ||
401 | enable_irq(chip->client->irq); | ||
402 | } | ||
403 | |||
404 | static int da903x_irq_handler(int irq, void *data) | ||
405 | { | ||
406 | struct da903x_chip *chip = data; | ||
407 | |||
408 | disable_irq_nosync(irq); | ||
409 | (void)schedule_work(&chip->irq_work); | ||
410 | |||
411 | return IRQ_HANDLED; | ||
412 | } | ||
413 | |||
414 | static struct da903x_chip_ops da903x_ops[] = { | ||
415 | [0] = { | ||
416 | .init_chip = da9030_init_chip, | ||
417 | .unmask_events = da9030_unmask_events, | ||
418 | .mask_events = da9030_mask_events, | ||
419 | .read_events = da9030_read_events, | ||
420 | .read_status = da9030_read_status, | ||
421 | }, | ||
422 | [1] = { | ||
423 | .init_chip = da9034_init_chip, | ||
424 | .unmask_events = da9034_unmask_events, | ||
425 | .mask_events = da9034_mask_events, | ||
426 | .read_events = da9034_read_events, | ||
427 | .read_status = da9034_read_status, | ||
428 | } | ||
429 | }; | ||
430 | |||
431 | static const struct i2c_device_id da903x_id_table[] = { | ||
432 | { "da9030", 0 }, | ||
433 | { "da9034", 1 }, | ||
434 | { }, | ||
435 | }; | ||
436 | MODULE_DEVICE_TABLE(i2c, da903x_id_table); | ||
437 | |||
438 | static int __devexit __remove_subdev(struct device *dev, void *unused) | ||
439 | { | ||
440 | platform_device_unregister(to_platform_device(dev)); | ||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | static int __devexit da903x_remove_subdevs(struct da903x_chip *chip) | ||
445 | { | ||
446 | return device_for_each_child(chip->dev, NULL, __remove_subdev); | ||
447 | } | ||
448 | |||
449 | static int __devinit da903x_add_subdevs(struct da903x_chip *chip, | ||
450 | struct da903x_platform_data *pdata) | ||
451 | { | ||
452 | struct da903x_subdev_info *subdev; | ||
453 | struct platform_device *pdev; | ||
454 | int i, ret = 0; | ||
455 | |||
456 | for (i = 0; i < pdata->num_subdevs; i++) { | ||
457 | subdev = &pdata->subdevs[i]; | ||
458 | |||
459 | pdev = platform_device_alloc(subdev->name, subdev->id); | ||
460 | |||
461 | pdev->dev.parent = chip->dev; | ||
462 | pdev->dev.platform_data = subdev->platform_data; | ||
463 | |||
464 | ret = platform_device_add(pdev); | ||
465 | if (ret) | ||
466 | goto failed; | ||
467 | } | ||
468 | return 0; | ||
469 | |||
470 | failed: | ||
471 | da903x_remove_subdevs(chip); | ||
472 | return ret; | ||
473 | } | ||
474 | |||
475 | static int __devinit da903x_probe(struct i2c_client *client, | ||
476 | const struct i2c_device_id *id) | ||
477 | { | ||
478 | struct da903x_platform_data *pdata = client->dev.platform_data; | ||
479 | struct da903x_chip *chip; | ||
480 | unsigned int tmp; | ||
481 | int ret; | ||
482 | |||
483 | chip = kzalloc(sizeof(struct da903x_chip), GFP_KERNEL); | ||
484 | if (chip == NULL) | ||
485 | return -ENOMEM; | ||
486 | |||
487 | chip->client = client; | ||
488 | chip->dev = &client->dev; | ||
489 | chip->ops = &da903x_ops[id->driver_data]; | ||
490 | |||
491 | mutex_init(&chip->lock); | ||
492 | INIT_WORK(&chip->irq_work, da903x_irq_work); | ||
493 | BLOCKING_INIT_NOTIFIER_HEAD(&chip->notifier_list); | ||
494 | |||
495 | i2c_set_clientdata(client, chip); | ||
496 | |||
497 | ret = chip->ops->init_chip(chip); | ||
498 | if (ret) | ||
499 | goto out_free_chip; | ||
500 | |||
501 | /* mask and clear all IRQs */ | ||
502 | chip->events_mask = 0xffffffff; | ||
503 | chip->ops->mask_events(chip, chip->events_mask); | ||
504 | chip->ops->read_events(chip, &tmp); | ||
505 | |||
506 | ret = request_irq(client->irq, da903x_irq_handler, | ||
507 | IRQF_DISABLED | IRQF_TRIGGER_FALLING, | ||
508 | "da903x", chip); | ||
509 | if (ret) { | ||
510 | dev_err(&client->dev, "failed to request irq %d\n", | ||
511 | client->irq); | ||
512 | goto out_free_chip; | ||
513 | } | ||
514 | |||
515 | ret = da903x_add_subdevs(chip, pdata); | ||
516 | if (ret) | ||
517 | goto out_free_irq; | ||
518 | |||
519 | return 0; | ||
520 | |||
521 | out_free_irq: | ||
522 | free_irq(client->irq, chip); | ||
523 | out_free_chip: | ||
524 | i2c_set_clientdata(client, NULL); | ||
525 | kfree(chip); | ||
526 | return ret; | ||
527 | } | ||
528 | |||
529 | static int __devexit da903x_remove(struct i2c_client *client) | ||
530 | { | ||
531 | struct da903x_chip *chip = i2c_get_clientdata(client); | ||
532 | |||
533 | da903x_remove_subdevs(chip); | ||
534 | kfree(chip); | ||
535 | return 0; | ||
536 | } | ||
537 | |||
538 | static struct i2c_driver da903x_driver = { | ||
539 | .driver = { | ||
540 | .name = "da903x", | ||
541 | .owner = THIS_MODULE, | ||
542 | }, | ||
543 | .probe = da903x_probe, | ||
544 | .remove = __devexit_p(da903x_remove), | ||
545 | .id_table = da903x_id_table, | ||
546 | }; | ||
547 | |||
548 | static int __init da903x_init(void) | ||
549 | { | ||
550 | return i2c_add_driver(&da903x_driver); | ||
551 | } | ||
552 | module_init(da903x_init); | ||
553 | |||
554 | static void __exit da903x_exit(void) | ||
555 | { | ||
556 | i2c_del_driver(&da903x_driver); | ||
557 | } | ||
558 | module_exit(da903x_exit); | ||
559 | |||
560 | MODULE_DESCRIPTION("PMIC Driver for Dialog Semiconductor DA9034"); | ||
561 | MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>" | ||
562 | "Mike Rapoport <mike@compulab.co.il>"); | ||
563 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mfd/htc-egpio.c b/drivers/mfd/htc-egpio.c index 6be43172dc65..1a4d04664d6d 100644 --- a/drivers/mfd/htc-egpio.c +++ b/drivers/mfd/htc-egpio.c | |||
@@ -112,7 +112,7 @@ static void egpio_handler(unsigned int irq, struct irq_desc *desc) | |||
112 | /* Run irq handler */ | 112 | /* Run irq handler */ |
113 | pr_debug("got IRQ %d\n", irqpin); | 113 | pr_debug("got IRQ %d\n", irqpin); |
114 | irq = ei->irq_start + irqpin; | 114 | irq = ei->irq_start + irqpin; |
115 | desc = &irq_desc[irq]; | 115 | desc = irq_to_desc(irq); |
116 | desc->handle_irq(irq, desc); | 116 | desc->handle_irq(irq, desc); |
117 | } | 117 | } |
118 | } | 118 | } |
@@ -289,7 +289,7 @@ static int __init egpio_probe(struct platform_device *pdev) | |||
289 | ei->base_addr = ioremap_nocache(res->start, res->end - res->start); | 289 | ei->base_addr = ioremap_nocache(res->start, res->end - res->start); |
290 | if (!ei->base_addr) | 290 | if (!ei->base_addr) |
291 | goto fail; | 291 | goto fail; |
292 | pr_debug("EGPIO phys=%08x virt=%p\n", res->start, ei->base_addr); | 292 | pr_debug("EGPIO phys=%08x virt=%p\n", (u32)res->start, ei->base_addr); |
293 | 293 | ||
294 | if ((pdata->bus_width != 16) && (pdata->bus_width != 32)) | 294 | if ((pdata->bus_width != 16) && (pdata->bus_width != 32)) |
295 | goto fail; | 295 | goto fail; |
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 9c9c126ed334..6c0d1bec4b76 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c | |||
@@ -20,7 +20,7 @@ static int mfd_add_device(struct device *parent, int id, | |||
20 | struct resource *mem_base, | 20 | struct resource *mem_base, |
21 | int irq_base) | 21 | int irq_base) |
22 | { | 22 | { |
23 | struct resource res[cell->num_resources]; | 23 | struct resource *res; |
24 | struct platform_device *pdev; | 24 | struct platform_device *pdev; |
25 | int ret = -ENOMEM; | 25 | int ret = -ENOMEM; |
26 | int r; | 26 | int r; |
@@ -29,14 +29,17 @@ static int mfd_add_device(struct device *parent, int id, | |||
29 | if (!pdev) | 29 | if (!pdev) |
30 | goto fail_alloc; | 30 | goto fail_alloc; |
31 | 31 | ||
32 | res = kzalloc(sizeof(*res) * cell->num_resources, GFP_KERNEL); | ||
33 | if (!res) | ||
34 | goto fail_device; | ||
35 | |||
32 | pdev->dev.parent = parent; | 36 | pdev->dev.parent = parent; |
33 | 37 | ||
34 | ret = platform_device_add_data(pdev, | 38 | ret = platform_device_add_data(pdev, |
35 | cell->platform_data, cell->data_size); | 39 | cell->platform_data, cell->data_size); |
36 | if (ret) | 40 | if (ret) |
37 | goto fail_device; | 41 | goto fail_res; |
38 | 42 | ||
39 | memset(res, 0, sizeof(res)); | ||
40 | for (r = 0; r < cell->num_resources; r++) { | 43 | for (r = 0; r < cell->num_resources; r++) { |
41 | res[r].name = cell->resources[r].name; | 44 | res[r].name = cell->resources[r].name; |
42 | res[r].flags = cell->resources[r].flags; | 45 | res[r].flags = cell->resources[r].flags; |
@@ -64,11 +67,15 @@ static int mfd_add_device(struct device *parent, int id, | |||
64 | 67 | ||
65 | ret = platform_device_add(pdev); | 68 | ret = platform_device_add(pdev); |
66 | if (ret) | 69 | if (ret) |
67 | goto fail_device; | 70 | goto fail_res; |
71 | |||
72 | kfree(res); | ||
68 | 73 | ||
69 | return 0; | 74 | return 0; |
70 | 75 | ||
71 | /* platform_device_del(pdev); */ | 76 | /* platform_device_del(pdev); */ |
77 | fail_res: | ||
78 | kfree(res); | ||
72 | fail_device: | 79 | fail_device: |
73 | platform_device_put(pdev); | 80 | platform_device_put(pdev); |
74 | fail_alloc: | 81 | fail_alloc: |
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index 7aebad4c06ff..220e4371266b 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c | |||
@@ -623,8 +623,8 @@ unsigned long sm501_set_clock(struct device *dev, | |||
623 | 623 | ||
624 | sm501_sync_regs(sm); | 624 | sm501_sync_regs(sm); |
625 | 625 | ||
626 | dev_info(sm->dev, "gate %08lx, clock %08lx, mode %08lx\n", | 626 | dev_dbg(sm->dev, "gate %08lx, clock %08lx, mode %08lx\n", |
627 | gate, clock, mode); | 627 | gate, clock, mode); |
628 | 628 | ||
629 | sm501_mdelay(sm, 16); | 629 | sm501_mdelay(sm, 16); |
630 | mutex_unlock(&sm->clock_lock); | 630 | mutex_unlock(&sm->clock_lock); |
@@ -742,7 +742,7 @@ static int sm501_register_device(struct sm501_devdata *sm, | |||
742 | int ret; | 742 | int ret; |
743 | 743 | ||
744 | for (ptr = 0; ptr < pdev->num_resources; ptr++) { | 744 | for (ptr = 0; ptr < pdev->num_resources; ptr++) { |
745 | printk("%s[%d] flags %08lx: %08llx..%08llx\n", | 745 | printk(KERN_DEBUG "%s[%d] flags %08lx: %08llx..%08llx\n", |
746 | pdev->name, ptr, | 746 | pdev->name, ptr, |
747 | pdev->resource[ptr].flags, | 747 | pdev->resource[ptr].flags, |
748 | (unsigned long long)pdev->resource[ptr].start, | 748 | (unsigned long long)pdev->resource[ptr].start, |
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c index 49a0fffc02af..9f7024c0f8ec 100644 --- a/drivers/mfd/t7l66xb.c +++ b/drivers/mfd/t7l66xb.c | |||
@@ -24,8 +24,10 @@ | |||
24 | 24 | ||
25 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/err.h> | ||
27 | #include <linux/io.h> | 28 | #include <linux/io.h> |
28 | #include <linux/irq.h> | 29 | #include <linux/irq.h> |
30 | #include <linux/clk.h> | ||
29 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
30 | #include <linux/mfd/core.h> | 32 | #include <linux/mfd/core.h> |
31 | #include <linux/mfd/tmio.h> | 33 | #include <linux/mfd/tmio.h> |
@@ -56,6 +58,8 @@ struct t7l66xb { | |||
56 | spinlock_t lock; | 58 | spinlock_t lock; |
57 | 59 | ||
58 | struct resource rscr; | 60 | struct resource rscr; |
61 | struct clk *clk48m; | ||
62 | struct clk *clk32k; | ||
59 | int irq; | 63 | int irq; |
60 | int irq_base; | 64 | int irq_base; |
61 | }; | 65 | }; |
@@ -65,13 +69,11 @@ struct t7l66xb { | |||
65 | static int t7l66xb_mmc_enable(struct platform_device *mmc) | 69 | static int t7l66xb_mmc_enable(struct platform_device *mmc) |
66 | { | 70 | { |
67 | struct platform_device *dev = to_platform_device(mmc->dev.parent); | 71 | struct platform_device *dev = to_platform_device(mmc->dev.parent); |
68 | struct t7l66xb_platform_data *pdata = dev->dev.platform_data; | ||
69 | struct t7l66xb *t7l66xb = platform_get_drvdata(dev); | 72 | struct t7l66xb *t7l66xb = platform_get_drvdata(dev); |
70 | unsigned long flags; | 73 | unsigned long flags; |
71 | u8 dev_ctl; | 74 | u8 dev_ctl; |
72 | 75 | ||
73 | if (pdata->enable_clk32k) | 76 | clk_enable(t7l66xb->clk32k); |
74 | pdata->enable_clk32k(dev); | ||
75 | 77 | ||
76 | spin_lock_irqsave(&t7l66xb->lock, flags); | 78 | spin_lock_irqsave(&t7l66xb->lock, flags); |
77 | 79 | ||
@@ -87,7 +89,6 @@ static int t7l66xb_mmc_enable(struct platform_device *mmc) | |||
87 | static int t7l66xb_mmc_disable(struct platform_device *mmc) | 89 | static int t7l66xb_mmc_disable(struct platform_device *mmc) |
88 | { | 90 | { |
89 | struct platform_device *dev = to_platform_device(mmc->dev.parent); | 91 | struct platform_device *dev = to_platform_device(mmc->dev.parent); |
90 | struct t7l66xb_platform_data *pdata = dev->dev.platform_data; | ||
91 | struct t7l66xb *t7l66xb = platform_get_drvdata(dev); | 92 | struct t7l66xb *t7l66xb = platform_get_drvdata(dev); |
92 | unsigned long flags; | 93 | unsigned long flags; |
93 | u8 dev_ctl; | 94 | u8 dev_ctl; |
@@ -100,8 +101,7 @@ static int t7l66xb_mmc_disable(struct platform_device *mmc) | |||
100 | 101 | ||
101 | spin_unlock_irqrestore(&t7l66xb->lock, flags); | 102 | spin_unlock_irqrestore(&t7l66xb->lock, flags); |
102 | 103 | ||
103 | if (pdata->disable_clk32k) | 104 | clk_disable(t7l66xb->clk32k); |
104 | pdata->disable_clk32k(dev); | ||
105 | 105 | ||
106 | return 0; | 106 | return 0; |
107 | } | 107 | } |
@@ -258,18 +258,22 @@ static void t7l66xb_detach_irq(struct platform_device *dev) | |||
258 | #ifdef CONFIG_PM | 258 | #ifdef CONFIG_PM |
259 | static int t7l66xb_suspend(struct platform_device *dev, pm_message_t state) | 259 | static int t7l66xb_suspend(struct platform_device *dev, pm_message_t state) |
260 | { | 260 | { |
261 | struct t7l66xb *t7l66xb = platform_get_drvdata(dev); | ||
261 | struct t7l66xb_platform_data *pdata = dev->dev.platform_data; | 262 | struct t7l66xb_platform_data *pdata = dev->dev.platform_data; |
262 | 263 | ||
263 | if (pdata && pdata->suspend) | 264 | if (pdata && pdata->suspend) |
264 | pdata->suspend(dev); | 265 | pdata->suspend(dev); |
266 | clk_disable(t7l66xb->clk48m); | ||
265 | 267 | ||
266 | return 0; | 268 | return 0; |
267 | } | 269 | } |
268 | 270 | ||
269 | static int t7l66xb_resume(struct platform_device *dev) | 271 | static int t7l66xb_resume(struct platform_device *dev) |
270 | { | 272 | { |
273 | struct t7l66xb *t7l66xb = platform_get_drvdata(dev); | ||
271 | struct t7l66xb_platform_data *pdata = dev->dev.platform_data; | 274 | struct t7l66xb_platform_data *pdata = dev->dev.platform_data; |
272 | 275 | ||
276 | clk_enable(t7l66xb->clk48m); | ||
273 | if (pdata && pdata->resume) | 277 | if (pdata && pdata->resume) |
274 | pdata->resume(dev); | 278 | pdata->resume(dev); |
275 | 279 | ||
@@ -309,6 +313,19 @@ static int t7l66xb_probe(struct platform_device *dev) | |||
309 | 313 | ||
310 | t7l66xb->irq_base = pdata->irq_base; | 314 | t7l66xb->irq_base = pdata->irq_base; |
311 | 315 | ||
316 | t7l66xb->clk32k = clk_get(&dev->dev, "CLK_CK32K"); | ||
317 | if (IS_ERR(t7l66xb->clk32k)) { | ||
318 | ret = PTR_ERR(t7l66xb->clk32k); | ||
319 | goto err_clk32k_get; | ||
320 | } | ||
321 | |||
322 | t7l66xb->clk48m = clk_get(&dev->dev, "CLK_CK48M"); | ||
323 | if (IS_ERR(t7l66xb->clk48m)) { | ||
324 | ret = PTR_ERR(t7l66xb->clk48m); | ||
325 | clk_put(t7l66xb->clk32k); | ||
326 | goto err_clk48m_get; | ||
327 | } | ||
328 | |||
312 | rscr = &t7l66xb->rscr; | 329 | rscr = &t7l66xb->rscr; |
313 | rscr->name = "t7l66xb-core"; | 330 | rscr->name = "t7l66xb-core"; |
314 | rscr->start = iomem->start; | 331 | rscr->start = iomem->start; |
@@ -325,6 +342,8 @@ static int t7l66xb_probe(struct platform_device *dev) | |||
325 | goto err_ioremap; | 342 | goto err_ioremap; |
326 | } | 343 | } |
327 | 344 | ||
345 | clk_enable(t7l66xb->clk48m); | ||
346 | |||
328 | if (pdata && pdata->enable) | 347 | if (pdata && pdata->enable) |
329 | pdata->enable(dev); | 348 | pdata->enable(dev); |
330 | 349 | ||
@@ -359,9 +378,13 @@ static int t7l66xb_probe(struct platform_device *dev) | |||
359 | iounmap(t7l66xb->scr); | 378 | iounmap(t7l66xb->scr); |
360 | err_ioremap: | 379 | err_ioremap: |
361 | release_resource(&t7l66xb->rscr); | 380 | release_resource(&t7l66xb->rscr); |
362 | err_noirq: | ||
363 | err_request_scr: | 381 | err_request_scr: |
364 | kfree(t7l66xb); | 382 | kfree(t7l66xb); |
383 | clk_put(t7l66xb->clk48m); | ||
384 | err_clk48m_get: | ||
385 | clk_put(t7l66xb->clk32k); | ||
386 | err_clk32k_get: | ||
387 | err_noirq: | ||
365 | return ret; | 388 | return ret; |
366 | } | 389 | } |
367 | 390 | ||
@@ -372,7 +395,8 @@ static int t7l66xb_remove(struct platform_device *dev) | |||
372 | int ret; | 395 | int ret; |
373 | 396 | ||
374 | ret = pdata->disable(dev); | 397 | ret = pdata->disable(dev); |
375 | 398 | clk_disable(t7l66xb->clk48m); | |
399 | clk_put(t7l66xb->clk48m); | ||
376 | t7l66xb_detach_irq(dev); | 400 | t7l66xb_detach_irq(dev); |
377 | iounmap(t7l66xb->scr); | 401 | iounmap(t7l66xb->scr); |
378 | release_resource(&t7l66xb->rscr); | 402 | release_resource(&t7l66xb->rscr); |
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c index a22b21ac6cf8..43222c12fec1 100644 --- a/drivers/mfd/tc6387xb.c +++ b/drivers/mfd/tc6387xb.c | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/clk.h> | ||
15 | #include <linux/err.h> | 16 | #include <linux/err.h> |
16 | #include <linux/mfd/core.h> | 17 | #include <linux/mfd/core.h> |
17 | #include <linux/mfd/tmio.h> | 18 | #include <linux/mfd/tmio.h> |
@@ -24,18 +25,22 @@ enum { | |||
24 | #ifdef CONFIG_PM | 25 | #ifdef CONFIG_PM |
25 | static int tc6387xb_suspend(struct platform_device *dev, pm_message_t state) | 26 | static int tc6387xb_suspend(struct platform_device *dev, pm_message_t state) |
26 | { | 27 | { |
27 | struct tc6387xb_platform_data *pdata = platform_get_drvdata(dev); | 28 | struct clk *clk32k = platform_get_drvdata(dev); |
29 | struct tc6387xb_platform_data *pdata = dev->dev.platform_data; | ||
28 | 30 | ||
29 | if (pdata && pdata->suspend) | 31 | if (pdata && pdata->suspend) |
30 | pdata->suspend(dev); | 32 | pdata->suspend(dev); |
33 | clk_disable(clk32k); | ||
31 | 34 | ||
32 | return 0; | 35 | return 0; |
33 | } | 36 | } |
34 | 37 | ||
35 | static int tc6387xb_resume(struct platform_device *dev) | 38 | static int tc6387xb_resume(struct platform_device *dev) |
36 | { | 39 | { |
37 | struct tc6387xb_platform_data *pdata = platform_get_drvdata(dev); | 40 | struct clk *clk32k = platform_get_drvdata(dev); |
41 | struct tc6387xb_platform_data *pdata = dev->dev.platform_data; | ||
38 | 42 | ||
43 | clk_enable(clk32k); | ||
39 | if (pdata && pdata->resume) | 44 | if (pdata && pdata->resume) |
40 | pdata->resume(dev); | 45 | pdata->resume(dev); |
41 | 46 | ||
@@ -51,10 +56,9 @@ static int tc6387xb_resume(struct platform_device *dev) | |||
51 | static int tc6387xb_mmc_enable(struct platform_device *mmc) | 56 | static int tc6387xb_mmc_enable(struct platform_device *mmc) |
52 | { | 57 | { |
53 | struct platform_device *dev = to_platform_device(mmc->dev.parent); | 58 | struct platform_device *dev = to_platform_device(mmc->dev.parent); |
54 | struct tc6387xb_platform_data *tc6387xb = dev->dev.platform_data; | 59 | struct clk *clk32k = platform_get_drvdata(dev); |
55 | 60 | ||
56 | if (tc6387xb->enable_clk32k) | 61 | clk_enable(clk32k); |
57 | tc6387xb->enable_clk32k(dev); | ||
58 | 62 | ||
59 | return 0; | 63 | return 0; |
60 | } | 64 | } |
@@ -62,10 +66,9 @@ static int tc6387xb_mmc_enable(struct platform_device *mmc) | |||
62 | static int tc6387xb_mmc_disable(struct platform_device *mmc) | 66 | static int tc6387xb_mmc_disable(struct platform_device *mmc) |
63 | { | 67 | { |
64 | struct platform_device *dev = to_platform_device(mmc->dev.parent); | 68 | struct platform_device *dev = to_platform_device(mmc->dev.parent); |
65 | struct tc6387xb_platform_data *tc6387xb = dev->dev.platform_data; | 69 | struct clk *clk32k = platform_get_drvdata(dev); |
66 | 70 | ||
67 | if (tc6387xb->disable_clk32k) | 71 | clk_disable(clk32k); |
68 | tc6387xb->disable_clk32k(dev); | ||
69 | 72 | ||
70 | return 0; | 73 | return 0; |
71 | } | 74 | } |
@@ -102,14 +105,14 @@ static struct mfd_cell tc6387xb_cells[] = { | |||
102 | 105 | ||
103 | static int tc6387xb_probe(struct platform_device *dev) | 106 | static int tc6387xb_probe(struct platform_device *dev) |
104 | { | 107 | { |
105 | struct tc6387xb_platform_data *data = platform_get_drvdata(dev); | 108 | struct tc6387xb_platform_data *pdata = dev->dev.platform_data; |
106 | struct resource *iomem; | 109 | struct resource *iomem; |
110 | struct clk *clk32k; | ||
107 | int irq, ret; | 111 | int irq, ret; |
108 | 112 | ||
109 | iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); | 113 | iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); |
110 | if (!iomem) { | 114 | if (!iomem) { |
111 | ret = -EINVAL; | 115 | return -EINVAL; |
112 | goto err_resource; | ||
113 | } | 116 | } |
114 | 117 | ||
115 | ret = platform_get_irq(dev, 0); | 118 | ret = platform_get_irq(dev, 0); |
@@ -118,8 +121,15 @@ static int tc6387xb_probe(struct platform_device *dev) | |||
118 | else | 121 | else |
119 | goto err_resource; | 122 | goto err_resource; |
120 | 123 | ||
121 | if (data && data->enable) | 124 | clk32k = clk_get(&dev->dev, "CLK_CK32K"); |
122 | data->enable(dev); | 125 | if (IS_ERR(clk32k)) { |
126 | ret = PTR_ERR(clk32k); | ||
127 | goto err_resource; | ||
128 | } | ||
129 | platform_set_drvdata(dev, clk32k); | ||
130 | |||
131 | if (pdata && pdata->enable) | ||
132 | pdata->enable(dev); | ||
123 | 133 | ||
124 | printk(KERN_INFO "Toshiba tc6387xb initialised\n"); | 134 | printk(KERN_INFO "Toshiba tc6387xb initialised\n"); |
125 | 135 | ||
@@ -134,18 +144,19 @@ static int tc6387xb_probe(struct platform_device *dev) | |||
134 | if (!ret) | 144 | if (!ret) |
135 | return 0; | 145 | return 0; |
136 | 146 | ||
147 | clk_put(clk32k); | ||
137 | err_resource: | 148 | err_resource: |
138 | return ret; | 149 | return ret; |
139 | } | 150 | } |
140 | 151 | ||
141 | static int tc6387xb_remove(struct platform_device *dev) | 152 | static int tc6387xb_remove(struct platform_device *dev) |
142 | { | 153 | { |
143 | struct tc6387xb_platform_data *data = platform_get_drvdata(dev); | 154 | struct clk *clk32k = platform_get_drvdata(dev); |
144 | |||
145 | if (data && data->disable) | ||
146 | data->disable(dev); | ||
147 | 155 | ||
148 | /* FIXME - free the resources! */ | 156 | mfd_remove_devices(&dev->dev); |
157 | clk_disable(clk32k); | ||
158 | clk_put(clk32k); | ||
159 | platform_set_drvdata(dev, NULL); | ||
149 | 160 | ||
150 | return 0; | 161 | return 0; |
151 | } | 162 | } |
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index e4c1c788b5f8..f856e9463a9f 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c | |||
@@ -113,6 +113,8 @@ struct tc6393xb { | |||
113 | enum { | 113 | enum { |
114 | TC6393XB_CELL_NAND, | 114 | TC6393XB_CELL_NAND, |
115 | TC6393XB_CELL_MMC, | 115 | TC6393XB_CELL_MMC, |
116 | TC6393XB_CELL_OHCI, | ||
117 | TC6393XB_CELL_FB, | ||
116 | }; | 118 | }; |
117 | 119 | ||
118 | /*--------------------------------------------------------------------------*/ | 120 | /*--------------------------------------------------------------------------*/ |
@@ -170,6 +172,176 @@ static struct resource __devinitdata tc6393xb_mmc_resources[] = { | |||
170 | }, | 172 | }, |
171 | }; | 173 | }; |
172 | 174 | ||
175 | const static struct resource tc6393xb_ohci_resources[] = { | ||
176 | { | ||
177 | .start = 0x3000, | ||
178 | .end = 0x31ff, | ||
179 | .flags = IORESOURCE_MEM, | ||
180 | }, | ||
181 | { | ||
182 | .start = 0x0300, | ||
183 | .end = 0x03ff, | ||
184 | .flags = IORESOURCE_MEM, | ||
185 | }, | ||
186 | { | ||
187 | .start = 0x010000, | ||
188 | .end = 0x017fff, | ||
189 | .flags = IORESOURCE_MEM, | ||
190 | }, | ||
191 | { | ||
192 | .start = 0x018000, | ||
193 | .end = 0x01ffff, | ||
194 | .flags = IORESOURCE_MEM, | ||
195 | }, | ||
196 | { | ||
197 | .start = IRQ_TC6393_OHCI, | ||
198 | .end = IRQ_TC6393_OHCI, | ||
199 | .flags = IORESOURCE_IRQ, | ||
200 | }, | ||
201 | }; | ||
202 | |||
203 | static struct resource __devinitdata tc6393xb_fb_resources[] = { | ||
204 | { | ||
205 | .start = 0x5000, | ||
206 | .end = 0x51ff, | ||
207 | .flags = IORESOURCE_MEM, | ||
208 | }, | ||
209 | { | ||
210 | .start = 0x0500, | ||
211 | .end = 0x05ff, | ||
212 | .flags = IORESOURCE_MEM, | ||
213 | }, | ||
214 | { | ||
215 | .start = 0x100000, | ||
216 | .end = 0x1fffff, | ||
217 | .flags = IORESOURCE_MEM, | ||
218 | }, | ||
219 | { | ||
220 | .start = IRQ_TC6393_FB, | ||
221 | .end = IRQ_TC6393_FB, | ||
222 | .flags = IORESOURCE_IRQ, | ||
223 | }, | ||
224 | }; | ||
225 | |||
226 | static int tc6393xb_ohci_enable(struct platform_device *dev) | ||
227 | { | ||
228 | struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); | ||
229 | unsigned long flags; | ||
230 | u16 ccr; | ||
231 | u8 fer; | ||
232 | |||
233 | spin_lock_irqsave(&tc6393xb->lock, flags); | ||
234 | |||
235 | ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR); | ||
236 | ccr |= SCR_CCR_USBCK; | ||
237 | tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR); | ||
238 | |||
239 | fer = tmio_ioread8(tc6393xb->scr + SCR_FER); | ||
240 | fer |= SCR_FER_USBEN; | ||
241 | tmio_iowrite8(fer, tc6393xb->scr + SCR_FER); | ||
242 | |||
243 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | static int tc6393xb_ohci_disable(struct platform_device *dev) | ||
249 | { | ||
250 | struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); | ||
251 | unsigned long flags; | ||
252 | u16 ccr; | ||
253 | u8 fer; | ||
254 | |||
255 | spin_lock_irqsave(&tc6393xb->lock, flags); | ||
256 | |||
257 | fer = tmio_ioread8(tc6393xb->scr + SCR_FER); | ||
258 | fer &= ~SCR_FER_USBEN; | ||
259 | tmio_iowrite8(fer, tc6393xb->scr + SCR_FER); | ||
260 | |||
261 | ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR); | ||
262 | ccr &= ~SCR_CCR_USBCK; | ||
263 | tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR); | ||
264 | |||
265 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static int tc6393xb_fb_enable(struct platform_device *dev) | ||
271 | { | ||
272 | struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); | ||
273 | unsigned long flags; | ||
274 | u16 ccr; | ||
275 | |||
276 | spin_lock_irqsave(&tc6393xb->lock, flags); | ||
277 | |||
278 | ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR); | ||
279 | ccr &= ~SCR_CCR_MCLK_MASK; | ||
280 | ccr |= SCR_CCR_MCLK_48; | ||
281 | tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR); | ||
282 | |||
283 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | ||
284 | |||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | static int tc6393xb_fb_disable(struct platform_device *dev) | ||
289 | { | ||
290 | struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); | ||
291 | unsigned long flags; | ||
292 | u16 ccr; | ||
293 | |||
294 | spin_lock_irqsave(&tc6393xb->lock, flags); | ||
295 | |||
296 | ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR); | ||
297 | ccr &= ~SCR_CCR_MCLK_MASK; | ||
298 | ccr |= SCR_CCR_MCLK_OFF; | ||
299 | tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR); | ||
300 | |||
301 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | ||
302 | |||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | int tc6393xb_lcd_set_power(struct platform_device *fb, bool on) | ||
307 | { | ||
308 | struct platform_device *dev = to_platform_device(fb->dev.parent); | ||
309 | struct tc6393xb *tc6393xb = platform_get_drvdata(dev); | ||
310 | u8 fer; | ||
311 | unsigned long flags; | ||
312 | |||
313 | spin_lock_irqsave(&tc6393xb->lock, flags); | ||
314 | |||
315 | fer = ioread8(tc6393xb->scr + SCR_FER); | ||
316 | if (on) | ||
317 | fer |= SCR_FER_SLCDEN; | ||
318 | else | ||
319 | fer &= ~SCR_FER_SLCDEN; | ||
320 | iowrite8(fer, tc6393xb->scr + SCR_FER); | ||
321 | |||
322 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | ||
323 | |||
324 | return 0; | ||
325 | } | ||
326 | EXPORT_SYMBOL(tc6393xb_lcd_set_power); | ||
327 | |||
328 | int tc6393xb_lcd_mode(struct platform_device *fb, | ||
329 | const struct fb_videomode *mode) { | ||
330 | struct platform_device *dev = to_platform_device(fb->dev.parent); | ||
331 | struct tc6393xb *tc6393xb = platform_get_drvdata(dev); | ||
332 | unsigned long flags; | ||
333 | |||
334 | spin_lock_irqsave(&tc6393xb->lock, flags); | ||
335 | |||
336 | iowrite16(mode->pixclock, tc6393xb->scr + SCR_PLL1CR + 0); | ||
337 | iowrite16(mode->pixclock >> 16, tc6393xb->scr + SCR_PLL1CR + 2); | ||
338 | |||
339 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | ||
340 | |||
341 | return 0; | ||
342 | } | ||
343 | EXPORT_SYMBOL(tc6393xb_lcd_mode); | ||
344 | |||
173 | static struct mfd_cell __devinitdata tc6393xb_cells[] = { | 345 | static struct mfd_cell __devinitdata tc6393xb_cells[] = { |
174 | [TC6393XB_CELL_NAND] = { | 346 | [TC6393XB_CELL_NAND] = { |
175 | .name = "tmio-nand", | 347 | .name = "tmio-nand", |
@@ -182,6 +354,24 @@ static struct mfd_cell __devinitdata tc6393xb_cells[] = { | |||
182 | .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources), | 354 | .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources), |
183 | .resources = tc6393xb_mmc_resources, | 355 | .resources = tc6393xb_mmc_resources, |
184 | }, | 356 | }, |
357 | [TC6393XB_CELL_OHCI] = { | ||
358 | .name = "tmio-ohci", | ||
359 | .num_resources = ARRAY_SIZE(tc6393xb_ohci_resources), | ||
360 | .resources = tc6393xb_ohci_resources, | ||
361 | .enable = tc6393xb_ohci_enable, | ||
362 | .suspend = tc6393xb_ohci_disable, | ||
363 | .resume = tc6393xb_ohci_enable, | ||
364 | .disable = tc6393xb_ohci_disable, | ||
365 | }, | ||
366 | [TC6393XB_CELL_FB] = { | ||
367 | .name = "tmio-fb", | ||
368 | .num_resources = ARRAY_SIZE(tc6393xb_fb_resources), | ||
369 | .resources = tc6393xb_fb_resources, | ||
370 | .enable = tc6393xb_fb_enable, | ||
371 | .suspend = tc6393xb_fb_disable, | ||
372 | .resume = tc6393xb_fb_enable, | ||
373 | .disable = tc6393xb_fb_disable, | ||
374 | }, | ||
185 | }; | 375 | }; |
186 | 376 | ||
187 | /*--------------------------------------------------------------------------*/ | 377 | /*--------------------------------------------------------------------------*/ |
@@ -369,41 +559,12 @@ static void tc6393xb_detach_irq(struct platform_device *dev) | |||
369 | 559 | ||
370 | /*--------------------------------------------------------------------------*/ | 560 | /*--------------------------------------------------------------------------*/ |
371 | 561 | ||
372 | static int tc6393xb_hw_init(struct platform_device *dev) | ||
373 | { | ||
374 | struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; | ||
375 | struct tc6393xb *tc6393xb = platform_get_drvdata(dev); | ||
376 | int i; | ||
377 | |||
378 | iowrite8(tc6393xb->suspend_state.fer, tc6393xb->scr + SCR_FER); | ||
379 | iowrite16(tcpd->scr_pll2cr, tc6393xb->scr + SCR_PLL2CR); | ||
380 | iowrite16(tc6393xb->suspend_state.ccr, tc6393xb->scr + SCR_CCR); | ||
381 | iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN | | ||
382 | SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN | | ||
383 | BIT(15), tc6393xb->scr + SCR_MCR); | ||
384 | iowrite16(tcpd->scr_gper, tc6393xb->scr + SCR_GPER); | ||
385 | iowrite8(0, tc6393xb->scr + SCR_IRR); | ||
386 | iowrite8(0xbf, tc6393xb->scr + SCR_IMR); | ||
387 | |||
388 | for (i = 0; i < 3; i++) { | ||
389 | iowrite8(tc6393xb->suspend_state.gpo_dsr[i], | ||
390 | tc6393xb->scr + SCR_GPO_DSR(i)); | ||
391 | iowrite8(tc6393xb->suspend_state.gpo_doecr[i], | ||
392 | tc6393xb->scr + SCR_GPO_DOECR(i)); | ||
393 | iowrite8(tc6393xb->suspend_state.gpi_bcr[i], | ||
394 | tc6393xb->scr + SCR_GPI_BCR(i)); | ||
395 | } | ||
396 | |||
397 | return 0; | ||
398 | } | ||
399 | |||
400 | static int __devinit tc6393xb_probe(struct platform_device *dev) | 562 | static int __devinit tc6393xb_probe(struct platform_device *dev) |
401 | { | 563 | { |
402 | struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; | 564 | struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; |
403 | struct tc6393xb *tc6393xb; | 565 | struct tc6393xb *tc6393xb; |
404 | struct resource *iomem, *rscr; | 566 | struct resource *iomem, *rscr; |
405 | int ret, temp; | 567 | int ret, temp; |
406 | int i; | ||
407 | 568 | ||
408 | iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); | 569 | iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); |
409 | if (!iomem) | 570 | if (!iomem) |
@@ -458,21 +619,16 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) | |||
458 | if (ret) | 619 | if (ret) |
459 | goto err_enable; | 620 | goto err_enable; |
460 | 621 | ||
461 | tc6393xb->suspend_state.fer = 0; | 622 | iowrite8(0, tc6393xb->scr + SCR_FER); |
462 | 623 | iowrite16(tcpd->scr_pll2cr, tc6393xb->scr + SCR_PLL2CR); | |
463 | for (i = 0; i < 3; i++) { | 624 | iowrite16(SCR_CCR_UNK1 | SCR_CCR_HCLK_48, |
464 | tc6393xb->suspend_state.gpo_dsr[i] = | 625 | tc6393xb->scr + SCR_CCR); |
465 | (tcpd->scr_gpo_dsr >> (8 * i)) & 0xff; | 626 | iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN | |
466 | tc6393xb->suspend_state.gpo_doecr[i] = | 627 | SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN | |
467 | (tcpd->scr_gpo_doecr >> (8 * i)) & 0xff; | 628 | BIT(15), tc6393xb->scr + SCR_MCR); |
468 | } | 629 | iowrite16(tcpd->scr_gper, tc6393xb->scr + SCR_GPER); |
469 | 630 | iowrite8(0, tc6393xb->scr + SCR_IRR); | |
470 | tc6393xb->suspend_state.ccr = SCR_CCR_UNK1 | | 631 | iowrite8(0xbf, tc6393xb->scr + SCR_IMR); |
471 | SCR_CCR_HCLK_48; | ||
472 | |||
473 | ret = tc6393xb_hw_init(dev); | ||
474 | if (ret) | ||
475 | goto err_hw_init; | ||
476 | 632 | ||
477 | printk(KERN_INFO "Toshiba tc6393xb revision %d at 0x%08lx, irq %d\n", | 633 | printk(KERN_INFO "Toshiba tc6393xb revision %d at 0x%08lx, irq %d\n", |
478 | tmio_ioread8(tc6393xb->scr + SCR_REVID), | 634 | tmio_ioread8(tc6393xb->scr + SCR_REVID), |
@@ -488,16 +644,33 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) | |||
488 | 644 | ||
489 | tc6393xb_attach_irq(dev); | 645 | tc6393xb_attach_irq(dev); |
490 | 646 | ||
647 | if (tcpd->setup) { | ||
648 | ret = tcpd->setup(dev); | ||
649 | if (ret) | ||
650 | goto err_setup; | ||
651 | } | ||
652 | |||
491 | tc6393xb_cells[TC6393XB_CELL_NAND].driver_data = tcpd->nand_data; | 653 | tc6393xb_cells[TC6393XB_CELL_NAND].driver_data = tcpd->nand_data; |
492 | tc6393xb_cells[TC6393XB_CELL_NAND].platform_data = | 654 | tc6393xb_cells[TC6393XB_CELL_NAND].platform_data = |
493 | &tc6393xb_cells[TC6393XB_CELL_NAND]; | 655 | &tc6393xb_cells[TC6393XB_CELL_NAND]; |
494 | tc6393xb_cells[TC6393XB_CELL_NAND].data_size = | 656 | tc6393xb_cells[TC6393XB_CELL_NAND].data_size = |
495 | sizeof(tc6393xb_cells[TC6393XB_CELL_NAND]); | 657 | sizeof(tc6393xb_cells[TC6393XB_CELL_NAND]); |
658 | |||
496 | tc6393xb_cells[TC6393XB_CELL_MMC].platform_data = | 659 | tc6393xb_cells[TC6393XB_CELL_MMC].platform_data = |
497 | &tc6393xb_cells[TC6393XB_CELL_MMC]; | 660 | &tc6393xb_cells[TC6393XB_CELL_MMC]; |
498 | tc6393xb_cells[TC6393XB_CELL_MMC].data_size = | 661 | tc6393xb_cells[TC6393XB_CELL_MMC].data_size = |
499 | sizeof(tc6393xb_cells[TC6393XB_CELL_MMC]); | 662 | sizeof(tc6393xb_cells[TC6393XB_CELL_MMC]); |
500 | 663 | ||
664 | tc6393xb_cells[TC6393XB_CELL_OHCI].platform_data = | ||
665 | &tc6393xb_cells[TC6393XB_CELL_OHCI]; | ||
666 | tc6393xb_cells[TC6393XB_CELL_OHCI].data_size = | ||
667 | sizeof(tc6393xb_cells[TC6393XB_CELL_OHCI]); | ||
668 | |||
669 | tc6393xb_cells[TC6393XB_CELL_FB].driver_data = tcpd->fb_data; | ||
670 | tc6393xb_cells[TC6393XB_CELL_FB].platform_data = | ||
671 | &tc6393xb_cells[TC6393XB_CELL_FB]; | ||
672 | tc6393xb_cells[TC6393XB_CELL_FB].data_size = | ||
673 | sizeof(tc6393xb_cells[TC6393XB_CELL_FB]); | ||
501 | 674 | ||
502 | ret = mfd_add_devices(&dev->dev, dev->id, | 675 | ret = mfd_add_devices(&dev->dev, dev->id, |
503 | tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), | 676 | tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), |
@@ -506,12 +679,15 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) | |||
506 | if (!ret) | 679 | if (!ret) |
507 | return 0; | 680 | return 0; |
508 | 681 | ||
682 | if (tcpd->teardown) | ||
683 | tcpd->teardown(dev); | ||
684 | |||
685 | err_setup: | ||
509 | tc6393xb_detach_irq(dev); | 686 | tc6393xb_detach_irq(dev); |
510 | 687 | ||
511 | err_gpio_add: | 688 | err_gpio_add: |
512 | if (tc6393xb->gpio.base != -1) | 689 | if (tc6393xb->gpio.base != -1) |
513 | temp = gpiochip_remove(&tc6393xb->gpio); | 690 | temp = gpiochip_remove(&tc6393xb->gpio); |
514 | err_hw_init: | ||
515 | tcpd->disable(dev); | 691 | tcpd->disable(dev); |
516 | err_clk_enable: | 692 | err_clk_enable: |
517 | clk_disable(tc6393xb->clk); | 693 | clk_disable(tc6393xb->clk); |
@@ -535,6 +711,10 @@ static int __devexit tc6393xb_remove(struct platform_device *dev) | |||
535 | int ret; | 711 | int ret; |
536 | 712 | ||
537 | mfd_remove_devices(&dev->dev); | 713 | mfd_remove_devices(&dev->dev); |
714 | |||
715 | if (tcpd->teardown) | ||
716 | tcpd->teardown(dev); | ||
717 | |||
538 | tc6393xb_detach_irq(dev); | 718 | tc6393xb_detach_irq(dev); |
539 | 719 | ||
540 | if (tc6393xb->gpio.base != -1) { | 720 | if (tc6393xb->gpio.base != -1) { |
@@ -585,15 +765,37 @@ static int tc6393xb_resume(struct platform_device *dev) | |||
585 | struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; | 765 | struct tc6393xb_platform_data *tcpd = dev->dev.platform_data; |
586 | struct tc6393xb *tc6393xb = platform_get_drvdata(dev); | 766 | struct tc6393xb *tc6393xb = platform_get_drvdata(dev); |
587 | int ret; | 767 | int ret; |
768 | int i; | ||
588 | 769 | ||
589 | clk_enable(tc6393xb->clk); | 770 | clk_enable(tc6393xb->clk); |
590 | 771 | ||
591 | ret = tcpd->resume(dev); | 772 | ret = tcpd->resume(dev); |
592 | |||
593 | if (ret) | 773 | if (ret) |
594 | return ret; | 774 | return ret; |
595 | 775 | ||
596 | return tc6393xb_hw_init(dev); | 776 | if (!tcpd->resume_restore) |
777 | return 0; | ||
778 | |||
779 | iowrite8(tc6393xb->suspend_state.fer, tc6393xb->scr + SCR_FER); | ||
780 | iowrite16(tcpd->scr_pll2cr, tc6393xb->scr + SCR_PLL2CR); | ||
781 | iowrite16(tc6393xb->suspend_state.ccr, tc6393xb->scr + SCR_CCR); | ||
782 | iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN | | ||
783 | SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN | | ||
784 | BIT(15), tc6393xb->scr + SCR_MCR); | ||
785 | iowrite16(tcpd->scr_gper, tc6393xb->scr + SCR_GPER); | ||
786 | iowrite8(0, tc6393xb->scr + SCR_IRR); | ||
787 | iowrite8(0xbf, tc6393xb->scr + SCR_IMR); | ||
788 | |||
789 | for (i = 0; i < 3; i++) { | ||
790 | iowrite8(tc6393xb->suspend_state.gpo_dsr[i], | ||
791 | tc6393xb->scr + SCR_GPO_DSR(i)); | ||
792 | iowrite8(tc6393xb->suspend_state.gpo_doecr[i], | ||
793 | tc6393xb->scr + SCR_GPO_DOECR(i)); | ||
794 | iowrite8(tc6393xb->suspend_state.gpi_bcr[i], | ||
795 | tc6393xb->scr + SCR_GPI_BCR(i)); | ||
796 | } | ||
797 | |||
798 | return 0; | ||
597 | } | 799 | } |
598 | #else | 800 | #else |
599 | #define tc6393xb_suspend NULL | 801 | #define tc6393xb_suspend NULL |
diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c new file mode 100644 index 000000000000..fd9a0160202c --- /dev/null +++ b/drivers/mfd/twl4030-core.c | |||
@@ -0,0 +1,1193 @@ | |||
1 | /* | ||
2 | * twl4030_core.c - driver for TWL4030/TPS659x0 PM and audio CODEC devices | ||
3 | * | ||
4 | * Copyright (C) 2005-2006 Texas Instruments, Inc. | ||
5 | * | ||
6 | * Modifications to defer interrupt handling to a kernel thread: | ||
7 | * Copyright (C) 2006 MontaVista Software, Inc. | ||
8 | * | ||
9 | * Based on tlv320aic23.c: | ||
10 | * Copyright (c) by Kai Svahn <kai.svahn@nokia.com> | ||
11 | * | ||
12 | * Code cleanup and modifications to IRQ handler. | ||
13 | * by syed khasim <x0khasim@ti.com> | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or modify | ||
16 | * it under the terms of the GNU General Public License as published by | ||
17 | * the Free Software Foundation; either version 2 of the License, or | ||
18 | * (at your option) any later version. | ||
19 | * | ||
20 | * This program is distributed in the hope that it will be useful, | ||
21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
23 | * GNU General Public License for more details. | ||
24 | * | ||
25 | * You should have received a copy of the GNU General Public License | ||
26 | * along with this program; if not, write to the Free Software | ||
27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
28 | */ | ||
29 | |||
30 | #include <linux/kernel_stat.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/mutex.h> | ||
33 | #include <linux/interrupt.h> | ||
34 | #include <linux/irq.h> | ||
35 | #include <linux/random.h> | ||
36 | #include <linux/kthread.h> | ||
37 | #include <linux/platform_device.h> | ||
38 | #include <linux/clk.h> | ||
39 | |||
40 | #include <linux/i2c.h> | ||
41 | #include <linux/i2c/twl4030.h> | ||
42 | |||
43 | |||
44 | /* | ||
45 | * The TWL4030 "Triton 2" is one of a family of a multi-function "Power | ||
46 | * Management and System Companion Device" chips originally designed for | ||
47 | * use in OMAP2 and OMAP 3 based systems. Its control interfaces use I2C, | ||
48 | * often at around 3 Mbit/sec, including for interrupt handling. | ||
49 | * | ||
50 | * This driver core provides genirq support for the interrupts emitted, | ||
51 | * by the various modules, and exports register access primitives. | ||
52 | * | ||
53 | * FIXME this driver currently requires use of the first interrupt line | ||
54 | * (and associated registers). | ||
55 | */ | ||
56 | |||
57 | #define DRIVER_NAME "twl4030" | ||
58 | |||
59 | #if defined(CONFIG_TWL4030_BCI_BATTERY) || \ | ||
60 | defined(CONFIG_TWL4030_BCI_BATTERY_MODULE) | ||
61 | #define twl_has_bci() true | ||
62 | #else | ||
63 | #define twl_has_bci() false | ||
64 | #endif | ||
65 | |||
66 | #if defined(CONFIG_KEYBOARD_TWL4030) || defined(CONFIG_KEYBOARD_TWL4030_MODULE) | ||
67 | #define twl_has_keypad() true | ||
68 | #else | ||
69 | #define twl_has_keypad() false | ||
70 | #endif | ||
71 | |||
72 | #if defined(CONFIG_GPIO_TWL4030) || defined(CONFIG_GPIO_TWL4030_MODULE) | ||
73 | #define twl_has_gpio() true | ||
74 | #else | ||
75 | #define twl_has_gpio() false | ||
76 | #endif | ||
77 | |||
78 | #if defined(CONFIG_TWL4030_MADC) || defined(CONFIG_TWL4030_MADC_MODULE) | ||
79 | #define twl_has_madc() true | ||
80 | #else | ||
81 | #define twl_has_madc() false | ||
82 | #endif | ||
83 | |||
84 | #if defined(CONFIG_RTC_DRV_TWL4030) || defined(CONFIG_RTC_DRV_TWL4030_MODULE) | ||
85 | #define twl_has_rtc() true | ||
86 | #else | ||
87 | #define twl_has_rtc() false | ||
88 | #endif | ||
89 | |||
90 | #if defined(CONFIG_TWL4030_USB) || defined(CONFIG_TWL4030_USB_MODULE) | ||
91 | #define twl_has_usb() true | ||
92 | #else | ||
93 | #define twl_has_usb() false | ||
94 | #endif | ||
95 | |||
96 | static inline void activate_irq(int irq) | ||
97 | { | ||
98 | #ifdef CONFIG_ARM | ||
99 | /* ARM requires an extra step to clear IRQ_NOREQUEST, which it | ||
100 | * sets on behalf of every irq_chip. Also sets IRQ_NOPROBE. | ||
101 | */ | ||
102 | set_irq_flags(irq, IRQF_VALID); | ||
103 | #else | ||
104 | /* same effect on other architectures */ | ||
105 | set_irq_noprobe(irq); | ||
106 | #endif | ||
107 | } | ||
108 | |||
109 | /* Primary Interrupt Handler on TWL4030 Registers */ | ||
110 | |||
111 | /* Register Definitions */ | ||
112 | |||
113 | #define REG_PIH_ISR_P1 (0x1) | ||
114 | #define REG_PIH_ISR_P2 (0x2) | ||
115 | #define REG_PIH_SIR (0x3) | ||
116 | |||
117 | /* Triton Core internal information (BEGIN) */ | ||
118 | |||
119 | /* Last - for index max*/ | ||
120 | #define TWL4030_MODULE_LAST TWL4030_MODULE_SECURED_REG | ||
121 | |||
122 | #define TWL4030_NUM_SLAVES 4 | ||
123 | |||
124 | |||
125 | /* Base Address defns for twl4030_map[] */ | ||
126 | |||
127 | /* subchip/slave 0 - USB ID */ | ||
128 | #define TWL4030_BASEADD_USB 0x0000 | ||
129 | |||
130 | /* subchip/slave 1 - AUD ID */ | ||
131 | #define TWL4030_BASEADD_AUDIO_VOICE 0x0000 | ||
132 | #define TWL4030_BASEADD_GPIO 0x0098 | ||
133 | #define TWL4030_BASEADD_INTBR 0x0085 | ||
134 | #define TWL4030_BASEADD_PIH 0x0080 | ||
135 | #define TWL4030_BASEADD_TEST 0x004C | ||
136 | |||
137 | /* subchip/slave 2 - AUX ID */ | ||
138 | #define TWL4030_BASEADD_INTERRUPTS 0x00B9 | ||
139 | #define TWL4030_BASEADD_LED 0x00EE | ||
140 | #define TWL4030_BASEADD_MADC 0x0000 | ||
141 | #define TWL4030_BASEADD_MAIN_CHARGE 0x0074 | ||
142 | #define TWL4030_BASEADD_PRECHARGE 0x00AA | ||
143 | #define TWL4030_BASEADD_PWM0 0x00F8 | ||
144 | #define TWL4030_BASEADD_PWM1 0x00FB | ||
145 | #define TWL4030_BASEADD_PWMA 0x00EF | ||
146 | #define TWL4030_BASEADD_PWMB 0x00F1 | ||
147 | #define TWL4030_BASEADD_KEYPAD 0x00D2 | ||
148 | |||
149 | /* subchip/slave 3 - POWER ID */ | ||
150 | #define TWL4030_BASEADD_BACKUP 0x0014 | ||
151 | #define TWL4030_BASEADD_INT 0x002E | ||
152 | #define TWL4030_BASEADD_PM_MASTER 0x0036 | ||
153 | #define TWL4030_BASEADD_PM_RECEIVER 0x005B | ||
154 | #define TWL4030_BASEADD_RTC 0x001C | ||
155 | #define TWL4030_BASEADD_SECURED_REG 0x0000 | ||
156 | |||
157 | /* Triton Core internal information (END) */ | ||
158 | |||
159 | |||
160 | /* Few power values */ | ||
161 | #define R_CFG_BOOT 0x05 | ||
162 | #define R_PROTECT_KEY 0x0E | ||
163 | |||
164 | /* access control values for R_PROTECT_KEY */ | ||
165 | #define KEY_UNLOCK1 0xce | ||
166 | #define KEY_UNLOCK2 0xec | ||
167 | #define KEY_LOCK 0x00 | ||
168 | |||
169 | /* some fields in R_CFG_BOOT */ | ||
170 | #define HFCLK_FREQ_19p2_MHZ (1 << 0) | ||
171 | #define HFCLK_FREQ_26_MHZ (2 << 0) | ||
172 | #define HFCLK_FREQ_38p4_MHZ (3 << 0) | ||
173 | #define HIGH_PERF_SQ (1 << 3) | ||
174 | |||
175 | |||
176 | /*----------------------------------------------------------------------*/ | ||
177 | |||
178 | /** | ||
179 | * struct twl4030_mod_iregs - TWL module IMR/ISR regs to mask/clear at init | ||
180 | * @mod_no: TWL4030 module number (e.g., TWL4030_MODULE_GPIO) | ||
181 | * @sih_ctrl: address of module SIH_CTRL register | ||
182 | * @reg_cnt: number of IMR/ISR regs | ||
183 | * @imrs: pointer to array of TWL module interrupt mask register indices | ||
184 | * @isrs: pointer to array of TWL module interrupt status register indices | ||
185 | * | ||
186 | * Ties together TWL4030 modules and lists of IMR/ISR registers to mask/clear | ||
187 | * during twl_init_irq(). | ||
188 | */ | ||
189 | struct twl4030_mod_iregs { | ||
190 | const u8 mod_no; | ||
191 | const u8 sih_ctrl; | ||
192 | const u8 reg_cnt; | ||
193 | const u8 *imrs; | ||
194 | const u8 *isrs; | ||
195 | }; | ||
196 | |||
197 | /* TWL4030 INT module interrupt mask registers */ | ||
198 | static const u8 __initconst twl4030_int_imr_regs[] = { | ||
199 | TWL4030_INT_PWR_IMR1, | ||
200 | TWL4030_INT_PWR_IMR2, | ||
201 | }; | ||
202 | |||
203 | /* TWL4030 INT module interrupt status registers */ | ||
204 | static const u8 __initconst twl4030_int_isr_regs[] = { | ||
205 | TWL4030_INT_PWR_ISR1, | ||
206 | TWL4030_INT_PWR_ISR2, | ||
207 | }; | ||
208 | |||
209 | /* TWL4030 INTERRUPTS module interrupt mask registers */ | ||
210 | static const u8 __initconst twl4030_interrupts_imr_regs[] = { | ||
211 | TWL4030_INTERRUPTS_BCIIMR1A, | ||
212 | TWL4030_INTERRUPTS_BCIIMR1B, | ||
213 | TWL4030_INTERRUPTS_BCIIMR2A, | ||
214 | TWL4030_INTERRUPTS_BCIIMR2B, | ||
215 | }; | ||
216 | |||
217 | /* TWL4030 INTERRUPTS module interrupt status registers */ | ||
218 | static const u8 __initconst twl4030_interrupts_isr_regs[] = { | ||
219 | TWL4030_INTERRUPTS_BCIISR1A, | ||
220 | TWL4030_INTERRUPTS_BCIISR1B, | ||
221 | TWL4030_INTERRUPTS_BCIISR2A, | ||
222 | TWL4030_INTERRUPTS_BCIISR2B, | ||
223 | }; | ||
224 | |||
225 | /* TWL4030 MADC module interrupt mask registers */ | ||
226 | static const u8 __initconst twl4030_madc_imr_regs[] = { | ||
227 | TWL4030_MADC_IMR1, | ||
228 | TWL4030_MADC_IMR2, | ||
229 | }; | ||
230 | |||
231 | /* TWL4030 MADC module interrupt status registers */ | ||
232 | static const u8 __initconst twl4030_madc_isr_regs[] = { | ||
233 | TWL4030_MADC_ISR1, | ||
234 | TWL4030_MADC_ISR2, | ||
235 | }; | ||
236 | |||
237 | /* TWL4030 keypad module interrupt mask registers */ | ||
238 | static const u8 __initconst twl4030_keypad_imr_regs[] = { | ||
239 | TWL4030_KEYPAD_KEYP_IMR1, | ||
240 | TWL4030_KEYPAD_KEYP_IMR2, | ||
241 | }; | ||
242 | |||
243 | /* TWL4030 keypad module interrupt status registers */ | ||
244 | static const u8 __initconst twl4030_keypad_isr_regs[] = { | ||
245 | TWL4030_KEYPAD_KEYP_ISR1, | ||
246 | TWL4030_KEYPAD_KEYP_ISR2, | ||
247 | }; | ||
248 | |||
249 | /* TWL4030 GPIO module interrupt mask registers */ | ||
250 | static const u8 __initconst twl4030_gpio_imr_regs[] = { | ||
251 | REG_GPIO_IMR1A, | ||
252 | REG_GPIO_IMR1B, | ||
253 | REG_GPIO_IMR2A, | ||
254 | REG_GPIO_IMR2B, | ||
255 | REG_GPIO_IMR3A, | ||
256 | REG_GPIO_IMR3B, | ||
257 | }; | ||
258 | |||
259 | /* TWL4030 GPIO module interrupt status registers */ | ||
260 | static const u8 __initconst twl4030_gpio_isr_regs[] = { | ||
261 | REG_GPIO_ISR1A, | ||
262 | REG_GPIO_ISR1B, | ||
263 | REG_GPIO_ISR2A, | ||
264 | REG_GPIO_ISR2B, | ||
265 | REG_GPIO_ISR3A, | ||
266 | REG_GPIO_ISR3B, | ||
267 | }; | ||
268 | |||
269 | /* TWL4030 modules that have IMR/ISR registers that must be masked/cleared */ | ||
270 | static const struct twl4030_mod_iregs __initconst twl4030_mod_regs[] = { | ||
271 | { | ||
272 | .mod_no = TWL4030_MODULE_INT, | ||
273 | .sih_ctrl = TWL4030_INT_PWR_SIH_CTRL, | ||
274 | .reg_cnt = ARRAY_SIZE(twl4030_int_imr_regs), | ||
275 | .imrs = twl4030_int_imr_regs, | ||
276 | .isrs = twl4030_int_isr_regs, | ||
277 | }, | ||
278 | { | ||
279 | .mod_no = TWL4030_MODULE_INTERRUPTS, | ||
280 | .sih_ctrl = TWL4030_INTERRUPTS_BCISIHCTRL, | ||
281 | .reg_cnt = ARRAY_SIZE(twl4030_interrupts_imr_regs), | ||
282 | .imrs = twl4030_interrupts_imr_regs, | ||
283 | .isrs = twl4030_interrupts_isr_regs, | ||
284 | }, | ||
285 | { | ||
286 | .mod_no = TWL4030_MODULE_MADC, | ||
287 | .sih_ctrl = TWL4030_MADC_SIH_CTRL, | ||
288 | .reg_cnt = ARRAY_SIZE(twl4030_madc_imr_regs), | ||
289 | .imrs = twl4030_madc_imr_regs, | ||
290 | .isrs = twl4030_madc_isr_regs, | ||
291 | }, | ||
292 | { | ||
293 | .mod_no = TWL4030_MODULE_KEYPAD, | ||
294 | .sih_ctrl = TWL4030_KEYPAD_KEYP_SIH_CTRL, | ||
295 | .reg_cnt = ARRAY_SIZE(twl4030_keypad_imr_regs), | ||
296 | .imrs = twl4030_keypad_imr_regs, | ||
297 | .isrs = twl4030_keypad_isr_regs, | ||
298 | }, | ||
299 | { | ||
300 | .mod_no = TWL4030_MODULE_GPIO, | ||
301 | .sih_ctrl = REG_GPIO_SIH_CTRL, | ||
302 | .reg_cnt = ARRAY_SIZE(twl4030_gpio_imr_regs), | ||
303 | .imrs = twl4030_gpio_imr_regs, | ||
304 | .isrs = twl4030_gpio_isr_regs, | ||
305 | }, | ||
306 | }; | ||
307 | |||
308 | /*----------------------------------------------------------------*/ | ||
309 | |||
310 | /* is driver active, bound to a chip? */ | ||
311 | static bool inuse; | ||
312 | |||
313 | /* Structure for each TWL4030 Slave */ | ||
314 | struct twl4030_client { | ||
315 | struct i2c_client *client; | ||
316 | u8 address; | ||
317 | |||
318 | /* max numb of i2c_msg required is for read =2 */ | ||
319 | struct i2c_msg xfer_msg[2]; | ||
320 | |||
321 | /* To lock access to xfer_msg */ | ||
322 | struct mutex xfer_lock; | ||
323 | }; | ||
324 | |||
325 | static struct twl4030_client twl4030_modules[TWL4030_NUM_SLAVES]; | ||
326 | |||
327 | |||
328 | /* mapping the module id to slave id and base address */ | ||
329 | struct twl4030mapping { | ||
330 | unsigned char sid; /* Slave ID */ | ||
331 | unsigned char base; /* base address */ | ||
332 | }; | ||
333 | |||
334 | static struct twl4030mapping twl4030_map[TWL4030_MODULE_LAST + 1] = { | ||
335 | /* | ||
336 | * NOTE: don't change this table without updating the | ||
337 | * <linux/i2c/twl4030.h> defines for TWL4030_MODULE_* | ||
338 | * so they continue to match the order in this table. | ||
339 | */ | ||
340 | |||
341 | { 0, TWL4030_BASEADD_USB }, | ||
342 | |||
343 | { 1, TWL4030_BASEADD_AUDIO_VOICE }, | ||
344 | { 1, TWL4030_BASEADD_GPIO }, | ||
345 | { 1, TWL4030_BASEADD_INTBR }, | ||
346 | { 1, TWL4030_BASEADD_PIH }, | ||
347 | { 1, TWL4030_BASEADD_TEST }, | ||
348 | |||
349 | { 2, TWL4030_BASEADD_KEYPAD }, | ||
350 | { 2, TWL4030_BASEADD_MADC }, | ||
351 | { 2, TWL4030_BASEADD_INTERRUPTS }, | ||
352 | { 2, TWL4030_BASEADD_LED }, | ||
353 | { 2, TWL4030_BASEADD_MAIN_CHARGE }, | ||
354 | { 2, TWL4030_BASEADD_PRECHARGE }, | ||
355 | { 2, TWL4030_BASEADD_PWM0 }, | ||
356 | { 2, TWL4030_BASEADD_PWM1 }, | ||
357 | { 2, TWL4030_BASEADD_PWMA }, | ||
358 | { 2, TWL4030_BASEADD_PWMB }, | ||
359 | |||
360 | { 3, TWL4030_BASEADD_BACKUP }, | ||
361 | { 3, TWL4030_BASEADD_INT }, | ||
362 | { 3, TWL4030_BASEADD_PM_MASTER }, | ||
363 | { 3, TWL4030_BASEADD_PM_RECEIVER }, | ||
364 | { 3, TWL4030_BASEADD_RTC }, | ||
365 | { 3, TWL4030_BASEADD_SECURED_REG }, | ||
366 | }; | ||
367 | |||
368 | /*----------------------------------------------------------------------*/ | ||
369 | |||
370 | /* | ||
371 | * TWL4030 doesn't have PIH mask, hence dummy function for mask | ||
372 | * and unmask of the (eight) interrupts reported at that level ... | ||
373 | * masking is only available from SIH (secondary) modules. | ||
374 | */ | ||
375 | |||
376 | static void twl4030_i2c_ackirq(unsigned int irq) | ||
377 | { | ||
378 | } | ||
379 | |||
380 | static void twl4030_i2c_disableint(unsigned int irq) | ||
381 | { | ||
382 | } | ||
383 | |||
384 | static void twl4030_i2c_enableint(unsigned int irq) | ||
385 | { | ||
386 | } | ||
387 | |||
388 | static struct irq_chip twl4030_irq_chip = { | ||
389 | .name = "twl4030", | ||
390 | .ack = twl4030_i2c_ackirq, | ||
391 | .mask = twl4030_i2c_disableint, | ||
392 | .unmask = twl4030_i2c_enableint, | ||
393 | }; | ||
394 | |||
395 | /*----------------------------------------------------------------------*/ | ||
396 | |||
397 | /* Exported Functions */ | ||
398 | |||
399 | /** | ||
400 | * twl4030_i2c_write - Writes a n bit register in TWL4030 | ||
401 | * @mod_no: module number | ||
402 | * @value: an array of num_bytes+1 containing data to write | ||
403 | * @reg: register address (just offset will do) | ||
404 | * @num_bytes: number of bytes to transfer | ||
405 | * | ||
406 | * IMPORTANT: for 'value' parameter: Allocate value num_bytes+1 and | ||
407 | * valid data starts at Offset 1. | ||
408 | * | ||
409 | * Returns the result of operation - 0 is success | ||
410 | */ | ||
411 | int twl4030_i2c_write(u8 mod_no, u8 *value, u8 reg, u8 num_bytes) | ||
412 | { | ||
413 | int ret; | ||
414 | int sid; | ||
415 | struct twl4030_client *twl; | ||
416 | struct i2c_msg *msg; | ||
417 | |||
418 | if (unlikely(mod_no > TWL4030_MODULE_LAST)) { | ||
419 | pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); | ||
420 | return -EPERM; | ||
421 | } | ||
422 | sid = twl4030_map[mod_no].sid; | ||
423 | twl = &twl4030_modules[sid]; | ||
424 | |||
425 | if (unlikely(!inuse)) { | ||
426 | pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid); | ||
427 | return -EPERM; | ||
428 | } | ||
429 | mutex_lock(&twl->xfer_lock); | ||
430 | /* | ||
431 | * [MSG1]: fill the register address data | ||
432 | * fill the data Tx buffer | ||
433 | */ | ||
434 | msg = &twl->xfer_msg[0]; | ||
435 | msg->addr = twl->address; | ||
436 | msg->len = num_bytes + 1; | ||
437 | msg->flags = 0; | ||
438 | msg->buf = value; | ||
439 | /* over write the first byte of buffer with the register address */ | ||
440 | *value = twl4030_map[mod_no].base + reg; | ||
441 | ret = i2c_transfer(twl->client->adapter, twl->xfer_msg, 1); | ||
442 | mutex_unlock(&twl->xfer_lock); | ||
443 | |||
444 | /* i2cTransfer returns num messages.translate it pls.. */ | ||
445 | if (ret >= 0) | ||
446 | ret = 0; | ||
447 | return ret; | ||
448 | } | ||
449 | EXPORT_SYMBOL(twl4030_i2c_write); | ||
450 | |||
451 | /** | ||
452 | * twl4030_i2c_read - Reads a n bit register in TWL4030 | ||
453 | * @mod_no: module number | ||
454 | * @value: an array of num_bytes containing data to be read | ||
455 | * @reg: register address (just offset will do) | ||
456 | * @num_bytes: number of bytes to transfer | ||
457 | * | ||
458 | * Returns result of operation - num_bytes is success else failure. | ||
459 | */ | ||
460 | int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, u8 num_bytes) | ||
461 | { | ||
462 | int ret; | ||
463 | u8 val; | ||
464 | int sid; | ||
465 | struct twl4030_client *twl; | ||
466 | struct i2c_msg *msg; | ||
467 | |||
468 | if (unlikely(mod_no > TWL4030_MODULE_LAST)) { | ||
469 | pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); | ||
470 | return -EPERM; | ||
471 | } | ||
472 | sid = twl4030_map[mod_no].sid; | ||
473 | twl = &twl4030_modules[sid]; | ||
474 | |||
475 | if (unlikely(!inuse)) { | ||
476 | pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid); | ||
477 | return -EPERM; | ||
478 | } | ||
479 | mutex_lock(&twl->xfer_lock); | ||
480 | /* [MSG1] fill the register address data */ | ||
481 | msg = &twl->xfer_msg[0]; | ||
482 | msg->addr = twl->address; | ||
483 | msg->len = 1; | ||
484 | msg->flags = 0; /* Read the register value */ | ||
485 | val = twl4030_map[mod_no].base + reg; | ||
486 | msg->buf = &val; | ||
487 | /* [MSG2] fill the data rx buffer */ | ||
488 | msg = &twl->xfer_msg[1]; | ||
489 | msg->addr = twl->address; | ||
490 | msg->flags = I2C_M_RD; /* Read the register value */ | ||
491 | msg->len = num_bytes; /* only n bytes */ | ||
492 | msg->buf = value; | ||
493 | ret = i2c_transfer(twl->client->adapter, twl->xfer_msg, 2); | ||
494 | mutex_unlock(&twl->xfer_lock); | ||
495 | |||
496 | /* i2cTransfer returns num messages.translate it pls.. */ | ||
497 | if (ret >= 0) | ||
498 | ret = 0; | ||
499 | return ret; | ||
500 | } | ||
501 | EXPORT_SYMBOL(twl4030_i2c_read); | ||
502 | |||
503 | /** | ||
504 | * twl4030_i2c_write_u8 - Writes a 8 bit register in TWL4030 | ||
505 | * @mod_no: module number | ||
506 | * @value: the value to be written 8 bit | ||
507 | * @reg: register address (just offset will do) | ||
508 | * | ||
509 | * Returns result of operation - 0 is success | ||
510 | */ | ||
511 | int twl4030_i2c_write_u8(u8 mod_no, u8 value, u8 reg) | ||
512 | { | ||
513 | |||
514 | /* 2 bytes offset 1 contains the data offset 0 is used by i2c_write */ | ||
515 | u8 temp_buffer[2] = { 0 }; | ||
516 | /* offset 1 contains the data */ | ||
517 | temp_buffer[1] = value; | ||
518 | return twl4030_i2c_write(mod_no, temp_buffer, reg, 1); | ||
519 | } | ||
520 | EXPORT_SYMBOL(twl4030_i2c_write_u8); | ||
521 | |||
522 | /** | ||
523 | * twl4030_i2c_read_u8 - Reads a 8 bit register from TWL4030 | ||
524 | * @mod_no: module number | ||
525 | * @value: the value read 8 bit | ||
526 | * @reg: register address (just offset will do) | ||
527 | * | ||
528 | * Returns result of operation - 0 is success | ||
529 | */ | ||
530 | int twl4030_i2c_read_u8(u8 mod_no, u8 *value, u8 reg) | ||
531 | { | ||
532 | return twl4030_i2c_read(mod_no, value, reg, 1); | ||
533 | } | ||
534 | EXPORT_SYMBOL(twl4030_i2c_read_u8); | ||
535 | |||
536 | /*----------------------------------------------------------------------*/ | ||
537 | |||
538 | static unsigned twl4030_irq_base; | ||
539 | |||
540 | static struct completion irq_event; | ||
541 | |||
542 | /* | ||
543 | * This thread processes interrupts reported by the Primary Interrupt Handler. | ||
544 | */ | ||
545 | static int twl4030_irq_thread(void *data) | ||
546 | { | ||
547 | long irq = (long)data; | ||
548 | irq_desc_t *desc = irq_desc + irq; | ||
549 | static unsigned i2c_errors; | ||
550 | const static unsigned max_i2c_errors = 100; | ||
551 | |||
552 | current->flags |= PF_NOFREEZE; | ||
553 | |||
554 | while (!kthread_should_stop()) { | ||
555 | int ret; | ||
556 | int module_irq; | ||
557 | u8 pih_isr; | ||
558 | |||
559 | /* Wait for IRQ, then read PIH irq status (also blocking) */ | ||
560 | wait_for_completion_interruptible(&irq_event); | ||
561 | |||
562 | ret = twl4030_i2c_read_u8(TWL4030_MODULE_PIH, &pih_isr, | ||
563 | REG_PIH_ISR_P1); | ||
564 | if (ret) { | ||
565 | pr_warning("%s: I2C error %d reading PIH ISR\n", | ||
566 | DRIVER_NAME, ret); | ||
567 | if (++i2c_errors >= max_i2c_errors) { | ||
568 | printk(KERN_ERR "Maximum I2C error count" | ||
569 | " exceeded. Terminating %s.\n", | ||
570 | __func__); | ||
571 | break; | ||
572 | } | ||
573 | complete(&irq_event); | ||
574 | continue; | ||
575 | } | ||
576 | |||
577 | /* these handlers deal with the relevant SIH irq status */ | ||
578 | local_irq_disable(); | ||
579 | for (module_irq = twl4030_irq_base; | ||
580 | pih_isr; | ||
581 | pih_isr >>= 1, module_irq++) { | ||
582 | if (pih_isr & 0x1) { | ||
583 | irq_desc_t *d = irq_desc + module_irq; | ||
584 | |||
585 | d->handle_irq(module_irq, d); | ||
586 | } | ||
587 | } | ||
588 | local_irq_enable(); | ||
589 | |||
590 | desc->chip->unmask(irq); | ||
591 | } | ||
592 | |||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | /* | ||
597 | * do_twl4030_irq() is the desc->handle method for the twl4030 interrupt. | ||
598 | * This is a chained interrupt, so there is no desc->action method for it. | ||
599 | * Now we need to query the interrupt controller in the twl4030 to determine | ||
600 | * which module is generating the interrupt request. However, we can't do i2c | ||
601 | * transactions in interrupt context, so we must defer that work to a kernel | ||
602 | * thread. All we do here is acknowledge and mask the interrupt and wakeup | ||
603 | * the kernel thread. | ||
604 | */ | ||
605 | static void do_twl4030_irq(unsigned int irq, irq_desc_t *desc) | ||
606 | { | ||
607 | const unsigned int cpu = smp_processor_id(); | ||
608 | |||
609 | /* | ||
610 | * Earlier this was desc->triggered = 1; | ||
611 | */ | ||
612 | desc->status |= IRQ_LEVEL; | ||
613 | |||
614 | /* | ||
615 | * Acknowledge, clear _AND_ disable the interrupt. | ||
616 | */ | ||
617 | desc->chip->ack(irq); | ||
618 | |||
619 | if (!desc->depth) { | ||
620 | kstat_cpu(cpu).irqs[irq]++; | ||
621 | |||
622 | complete(&irq_event); | ||
623 | } | ||
624 | } | ||
625 | |||
626 | static struct task_struct * __init start_twl4030_irq_thread(long irq) | ||
627 | { | ||
628 | struct task_struct *thread; | ||
629 | |||
630 | init_completion(&irq_event); | ||
631 | thread = kthread_run(twl4030_irq_thread, (void *)irq, "twl4030-irq"); | ||
632 | if (!thread) | ||
633 | pr_err("%s: could not create twl4030 irq %ld thread!\n", | ||
634 | DRIVER_NAME, irq); | ||
635 | |||
636 | return thread; | ||
637 | } | ||
638 | |||
639 | /*----------------------------------------------------------------------*/ | ||
640 | |||
641 | static int add_children(struct twl4030_platform_data *pdata) | ||
642 | { | ||
643 | struct platform_device *pdev = NULL; | ||
644 | struct twl4030_client *twl = NULL; | ||
645 | int status = 0; | ||
646 | |||
647 | if (twl_has_bci() && pdata->bci) { | ||
648 | twl = &twl4030_modules[3]; | ||
649 | |||
650 | pdev = platform_device_alloc("twl4030_bci", -1); | ||
651 | if (!pdev) { | ||
652 | pr_debug("%s: can't alloc bci dev\n", DRIVER_NAME); | ||
653 | status = -ENOMEM; | ||
654 | goto err; | ||
655 | } | ||
656 | |||
657 | if (status == 0) { | ||
658 | pdev->dev.parent = &twl->client->dev; | ||
659 | status = platform_device_add_data(pdev, pdata->bci, | ||
660 | sizeof(*pdata->bci)); | ||
661 | if (status < 0) { | ||
662 | dev_dbg(&twl->client->dev, | ||
663 | "can't add bci data, %d\n", | ||
664 | status); | ||
665 | goto err; | ||
666 | } | ||
667 | } | ||
668 | |||
669 | if (status == 0) { | ||
670 | struct resource r = { | ||
671 | .start = TWL4030_PWRIRQ_CHG_PRES, | ||
672 | .flags = IORESOURCE_IRQ, | ||
673 | }; | ||
674 | |||
675 | status = platform_device_add_resources(pdev, &r, 1); | ||
676 | } | ||
677 | |||
678 | if (status == 0) | ||
679 | status = platform_device_add(pdev); | ||
680 | |||
681 | if (status < 0) { | ||
682 | platform_device_put(pdev); | ||
683 | dev_dbg(&twl->client->dev, | ||
684 | "can't create bci dev, %d\n", | ||
685 | status); | ||
686 | goto err; | ||
687 | } | ||
688 | } | ||
689 | |||
690 | if (twl_has_gpio() && pdata->gpio) { | ||
691 | twl = &twl4030_modules[1]; | ||
692 | |||
693 | pdev = platform_device_alloc("twl4030_gpio", -1); | ||
694 | if (!pdev) { | ||
695 | pr_debug("%s: can't alloc gpio dev\n", DRIVER_NAME); | ||
696 | status = -ENOMEM; | ||
697 | goto err; | ||
698 | } | ||
699 | |||
700 | /* more driver model init */ | ||
701 | if (status == 0) { | ||
702 | pdev->dev.parent = &twl->client->dev; | ||
703 | /* device_init_wakeup(&pdev->dev, 1); */ | ||
704 | |||
705 | status = platform_device_add_data(pdev, pdata->gpio, | ||
706 | sizeof(*pdata->gpio)); | ||
707 | if (status < 0) { | ||
708 | dev_dbg(&twl->client->dev, | ||
709 | "can't add gpio data, %d\n", | ||
710 | status); | ||
711 | goto err; | ||
712 | } | ||
713 | } | ||
714 | |||
715 | /* GPIO module IRQ */ | ||
716 | if (status == 0) { | ||
717 | struct resource r = { | ||
718 | .start = pdata->irq_base + 0, | ||
719 | .flags = IORESOURCE_IRQ, | ||
720 | }; | ||
721 | |||
722 | status = platform_device_add_resources(pdev, &r, 1); | ||
723 | } | ||
724 | |||
725 | if (status == 0) | ||
726 | status = platform_device_add(pdev); | ||
727 | |||
728 | if (status < 0) { | ||
729 | platform_device_put(pdev); | ||
730 | dev_dbg(&twl->client->dev, | ||
731 | "can't create gpio dev, %d\n", | ||
732 | status); | ||
733 | goto err; | ||
734 | } | ||
735 | } | ||
736 | |||
737 | if (twl_has_keypad() && pdata->keypad) { | ||
738 | pdev = platform_device_alloc("twl4030_keypad", -1); | ||
739 | if (pdev) { | ||
740 | twl = &twl4030_modules[2]; | ||
741 | pdev->dev.parent = &twl->client->dev; | ||
742 | device_init_wakeup(&pdev->dev, 1); | ||
743 | status = platform_device_add_data(pdev, pdata->keypad, | ||
744 | sizeof(*pdata->keypad)); | ||
745 | if (status < 0) { | ||
746 | dev_dbg(&twl->client->dev, | ||
747 | "can't add keypad data, %d\n", | ||
748 | status); | ||
749 | platform_device_put(pdev); | ||
750 | goto err; | ||
751 | } | ||
752 | status = platform_device_add(pdev); | ||
753 | if (status < 0) { | ||
754 | platform_device_put(pdev); | ||
755 | dev_dbg(&twl->client->dev, | ||
756 | "can't create keypad dev, %d\n", | ||
757 | status); | ||
758 | goto err; | ||
759 | } | ||
760 | } else { | ||
761 | pr_debug("%s: can't alloc keypad dev\n", DRIVER_NAME); | ||
762 | status = -ENOMEM; | ||
763 | goto err; | ||
764 | } | ||
765 | } | ||
766 | |||
767 | if (twl_has_madc() && pdata->madc) { | ||
768 | pdev = platform_device_alloc("twl4030_madc", -1); | ||
769 | if (pdev) { | ||
770 | twl = &twl4030_modules[2]; | ||
771 | pdev->dev.parent = &twl->client->dev; | ||
772 | device_init_wakeup(&pdev->dev, 1); | ||
773 | status = platform_device_add_data(pdev, pdata->madc, | ||
774 | sizeof(*pdata->madc)); | ||
775 | if (status < 0) { | ||
776 | platform_device_put(pdev); | ||
777 | dev_dbg(&twl->client->dev, | ||
778 | "can't add madc data, %d\n", | ||
779 | status); | ||
780 | goto err; | ||
781 | } | ||
782 | status = platform_device_add(pdev); | ||
783 | if (status < 0) { | ||
784 | platform_device_put(pdev); | ||
785 | dev_dbg(&twl->client->dev, | ||
786 | "can't create madc dev, %d\n", | ||
787 | status); | ||
788 | goto err; | ||
789 | } | ||
790 | } else { | ||
791 | pr_debug("%s: can't alloc madc dev\n", DRIVER_NAME); | ||
792 | status = -ENOMEM; | ||
793 | goto err; | ||
794 | } | ||
795 | } | ||
796 | |||
797 | if (twl_has_rtc()) { | ||
798 | twl = &twl4030_modules[3]; | ||
799 | |||
800 | pdev = platform_device_alloc("twl4030_rtc", -1); | ||
801 | if (!pdev) { | ||
802 | pr_debug("%s: can't alloc rtc dev\n", DRIVER_NAME); | ||
803 | status = -ENOMEM; | ||
804 | } else { | ||
805 | pdev->dev.parent = &twl->client->dev; | ||
806 | device_init_wakeup(&pdev->dev, 1); | ||
807 | } | ||
808 | |||
809 | /* | ||
810 | * REVISIT platform_data here currently might use of | ||
811 | * "msecure" line ... but for now we just expect board | ||
812 | * setup to tell the chip "we are secure" at all times. | ||
813 | * Eventually, Linux might become more aware of such | ||
814 | * HW security concerns, and "least privilege". | ||
815 | */ | ||
816 | |||
817 | /* RTC module IRQ */ | ||
818 | if (status == 0) { | ||
819 | struct resource r = { | ||
820 | /* REVISIT don't hard-wire this stuff */ | ||
821 | .start = TWL4030_PWRIRQ_RTC, | ||
822 | .flags = IORESOURCE_IRQ, | ||
823 | }; | ||
824 | |||
825 | status = platform_device_add_resources(pdev, &r, 1); | ||
826 | } | ||
827 | |||
828 | if (status == 0) | ||
829 | status = platform_device_add(pdev); | ||
830 | |||
831 | if (status < 0) { | ||
832 | platform_device_put(pdev); | ||
833 | dev_dbg(&twl->client->dev, | ||
834 | "can't create rtc dev, %d\n", | ||
835 | status); | ||
836 | goto err; | ||
837 | } | ||
838 | } | ||
839 | |||
840 | if (twl_has_usb() && pdata->usb) { | ||
841 | twl = &twl4030_modules[0]; | ||
842 | |||
843 | pdev = platform_device_alloc("twl4030_usb", -1); | ||
844 | if (!pdev) { | ||
845 | pr_debug("%s: can't alloc usb dev\n", DRIVER_NAME); | ||
846 | status = -ENOMEM; | ||
847 | goto err; | ||
848 | } | ||
849 | |||
850 | if (status == 0) { | ||
851 | pdev->dev.parent = &twl->client->dev; | ||
852 | device_init_wakeup(&pdev->dev, 1); | ||
853 | status = platform_device_add_data(pdev, pdata->usb, | ||
854 | sizeof(*pdata->usb)); | ||
855 | if (status < 0) { | ||
856 | platform_device_put(pdev); | ||
857 | dev_dbg(&twl->client->dev, | ||
858 | "can't add usb data, %d\n", | ||
859 | status); | ||
860 | goto err; | ||
861 | } | ||
862 | } | ||
863 | |||
864 | if (status == 0) { | ||
865 | struct resource r = { | ||
866 | .start = TWL4030_PWRIRQ_USB_PRES, | ||
867 | .flags = IORESOURCE_IRQ, | ||
868 | }; | ||
869 | |||
870 | status = platform_device_add_resources(pdev, &r, 1); | ||
871 | } | ||
872 | |||
873 | if (status == 0) | ||
874 | status = platform_device_add(pdev); | ||
875 | |||
876 | if (status < 0) { | ||
877 | platform_device_put(pdev); | ||
878 | dev_dbg(&twl->client->dev, | ||
879 | "can't create usb dev, %d\n", | ||
880 | status); | ||
881 | } | ||
882 | } | ||
883 | |||
884 | err: | ||
885 | if (status) | ||
886 | pr_err("failed to add twl4030's children (status %d)\n", status); | ||
887 | return status; | ||
888 | } | ||
889 | |||
890 | /*----------------------------------------------------------------------*/ | ||
891 | |||
892 | /* | ||
893 | * These three functions initialize the on-chip clock framework, | ||
894 | * letting it generate the right frequencies for USB, MADC, and | ||
895 | * other purposes. | ||
896 | */ | ||
897 | static inline int __init protect_pm_master(void) | ||
898 | { | ||
899 | int e = 0; | ||
900 | |||
901 | e = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, KEY_LOCK, | ||
902 | R_PROTECT_KEY); | ||
903 | return e; | ||
904 | } | ||
905 | |||
906 | static inline int __init unprotect_pm_master(void) | ||
907 | { | ||
908 | int e = 0; | ||
909 | |||
910 | e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, KEY_UNLOCK1, | ||
911 | R_PROTECT_KEY); | ||
912 | e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, KEY_UNLOCK2, | ||
913 | R_PROTECT_KEY); | ||
914 | return e; | ||
915 | } | ||
916 | |||
917 | static void __init clocks_init(void) | ||
918 | { | ||
919 | int e = 0; | ||
920 | struct clk *osc; | ||
921 | u32 rate; | ||
922 | u8 ctrl = HFCLK_FREQ_26_MHZ; | ||
923 | |||
924 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | ||
925 | if (cpu_is_omap2430()) | ||
926 | osc = clk_get(NULL, "osc_ck"); | ||
927 | else | ||
928 | osc = clk_get(NULL, "osc_sys_ck"); | ||
929 | #else | ||
930 | /* REVISIT for non-OMAP systems, pass the clock rate from | ||
931 | * board init code, using platform_data. | ||
932 | */ | ||
933 | osc = ERR_PTR(-EIO); | ||
934 | #endif | ||
935 | if (IS_ERR(osc)) { | ||
936 | printk(KERN_WARNING "Skipping twl4030 internal clock init and " | ||
937 | "using bootloader value (unknown osc rate)\n"); | ||
938 | return; | ||
939 | } | ||
940 | |||
941 | rate = clk_get_rate(osc); | ||
942 | clk_put(osc); | ||
943 | |||
944 | switch (rate) { | ||
945 | case 19200000: | ||
946 | ctrl = HFCLK_FREQ_19p2_MHZ; | ||
947 | break; | ||
948 | case 26000000: | ||
949 | ctrl = HFCLK_FREQ_26_MHZ; | ||
950 | break; | ||
951 | case 38400000: | ||
952 | ctrl = HFCLK_FREQ_38p4_MHZ; | ||
953 | break; | ||
954 | } | ||
955 | |||
956 | ctrl |= HIGH_PERF_SQ; | ||
957 | e |= unprotect_pm_master(); | ||
958 | /* effect->MADC+USB ck en */ | ||
959 | e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, ctrl, R_CFG_BOOT); | ||
960 | e |= protect_pm_master(); | ||
961 | |||
962 | if (e < 0) | ||
963 | pr_err("%s: clock init err [%d]\n", DRIVER_NAME, e); | ||
964 | } | ||
965 | |||
966 | /*----------------------------------------------------------------------*/ | ||
967 | |||
968 | /** | ||
969 | * twl4030_i2c_clear_isr - clear TWL4030 SIH ISR regs via read + write | ||
970 | * @mod_no: TWL4030 module number | ||
971 | * @reg: register index to clear | ||
972 | * @cor: value of the <module>_SIH_CTRL.COR bit (1 or 0) | ||
973 | * | ||
974 | * Either reads (cor == 1) or writes (cor == 0) to a TWL4030 interrupt | ||
975 | * status register to ensure that any prior interrupts are cleared. | ||
976 | * Returns the status from the I2C read operation. | ||
977 | */ | ||
978 | static int __init twl4030_i2c_clear_isr(u8 mod_no, u8 reg, u8 cor) | ||
979 | { | ||
980 | u8 tmp; | ||
981 | |||
982 | return (cor) ? twl4030_i2c_read_u8(mod_no, &tmp, reg) : | ||
983 | twl4030_i2c_write_u8(mod_no, 0xff, reg); | ||
984 | } | ||
985 | |||
986 | /** | ||
987 | * twl4030_read_cor_bit - are TWL module ISRs cleared by reads or writes? | ||
988 | * @mod_no: TWL4030 module number | ||
989 | * @reg: register index to clear | ||
990 | * | ||
991 | * Returns 1 if the TWL4030 SIH interrupt status registers (ISRs) for | ||
992 | * the specified TWL module are cleared by reads, or 0 if cleared by | ||
993 | * writes. | ||
994 | */ | ||
995 | static int twl4030_read_cor_bit(u8 mod_no, u8 reg) | ||
996 | { | ||
997 | u8 tmp = 0; | ||
998 | |||
999 | WARN_ON(twl4030_i2c_read_u8(mod_no, &tmp, reg) < 0); | ||
1000 | |||
1001 | tmp &= TWL4030_SIH_CTRL_COR_MASK; | ||
1002 | tmp >>= __ffs(TWL4030_SIH_CTRL_COR_MASK); | ||
1003 | |||
1004 | return tmp; | ||
1005 | } | ||
1006 | |||
1007 | /** | ||
1008 | * twl4030_mask_clear_intrs - mask and clear all TWL4030 interrupts | ||
1009 | * @t: pointer to twl4030_mod_iregs array | ||
1010 | * @t_sz: ARRAY_SIZE(t) (starting at 1) | ||
1011 | * | ||
1012 | * Mask all TWL4030 interrupt mask registers (IMRs) and clear all | ||
1013 | * interrupt status registers (ISRs). No return value, but will WARN if | ||
1014 | * any I2C operations fail. | ||
1015 | */ | ||
1016 | static void __init twl4030_mask_clear_intrs(const struct twl4030_mod_iregs *t, | ||
1017 | const u8 t_sz) | ||
1018 | { | ||
1019 | int i, j; | ||
1020 | |||
1021 | /* | ||
1022 | * N.B. - further efficiency is possible here. Eight I2C | ||
1023 | * operations on BCI and GPIO modules are avoidable if I2C | ||
1024 | * burst read/write transactions were implemented. Would | ||
1025 | * probably save about 1ms of boot time and a small amount of | ||
1026 | * power. | ||
1027 | */ | ||
1028 | for (i = 0; i < t_sz; i++) { | ||
1029 | const struct twl4030_mod_iregs tmr = t[i]; | ||
1030 | int cor; | ||
1031 | |||
1032 | /* Are ISRs cleared by reads or writes? */ | ||
1033 | cor = twl4030_read_cor_bit(tmr.mod_no, tmr.sih_ctrl); | ||
1034 | |||
1035 | for (j = 0; j < tmr.reg_cnt; j++) { | ||
1036 | |||
1037 | /* Mask interrupts at the TWL4030 */ | ||
1038 | WARN_ON(twl4030_i2c_write_u8(tmr.mod_no, 0xff, | ||
1039 | tmr.imrs[j]) < 0); | ||
1040 | |||
1041 | /* Clear TWL4030 ISRs */ | ||
1042 | WARN_ON(twl4030_i2c_clear_isr(tmr.mod_no, | ||
1043 | tmr.isrs[j], cor) < 0); | ||
1044 | } | ||
1045 | } | ||
1046 | } | ||
1047 | |||
1048 | |||
1049 | static void twl_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) | ||
1050 | { | ||
1051 | int i; | ||
1052 | |||
1053 | /* | ||
1054 | * Mask and clear all TWL4030 interrupts since initially we do | ||
1055 | * not have any TWL4030 module interrupt handlers present | ||
1056 | */ | ||
1057 | twl4030_mask_clear_intrs(twl4030_mod_regs, | ||
1058 | ARRAY_SIZE(twl4030_mod_regs)); | ||
1059 | |||
1060 | twl4030_irq_base = irq_base; | ||
1061 | |||
1062 | /* install an irq handler for each of the PIH modules */ | ||
1063 | for (i = irq_base; i < irq_end; i++) { | ||
1064 | set_irq_chip_and_handler(i, &twl4030_irq_chip, | ||
1065 | handle_simple_irq); | ||
1066 | activate_irq(i); | ||
1067 | } | ||
1068 | |||
1069 | /* install an irq handler to demultiplex the TWL4030 interrupt */ | ||
1070 | set_irq_data(irq_num, start_twl4030_irq_thread(irq_num)); | ||
1071 | set_irq_chained_handler(irq_num, do_twl4030_irq); | ||
1072 | } | ||
1073 | |||
1074 | /*----------------------------------------------------------------------*/ | ||
1075 | |||
1076 | static int twl4030_remove(struct i2c_client *client) | ||
1077 | { | ||
1078 | unsigned i; | ||
1079 | |||
1080 | /* FIXME undo twl_init_irq() */ | ||
1081 | if (twl4030_irq_base) { | ||
1082 | dev_err(&client->dev, "can't yet clean up IRQs?\n"); | ||
1083 | return -ENOSYS; | ||
1084 | } | ||
1085 | |||
1086 | for (i = 0; i < TWL4030_NUM_SLAVES; i++) { | ||
1087 | struct twl4030_client *twl = &twl4030_modules[i]; | ||
1088 | |||
1089 | if (twl->client && twl->client != client) | ||
1090 | i2c_unregister_device(twl->client); | ||
1091 | twl4030_modules[i].client = NULL; | ||
1092 | } | ||
1093 | inuse = false; | ||
1094 | return 0; | ||
1095 | } | ||
1096 | |||
1097 | /* NOTE: this driver only handles a single twl4030/tps659x0 chip */ | ||
1098 | static int | ||
1099 | twl4030_probe(struct i2c_client *client, const struct i2c_device_id *id) | ||
1100 | { | ||
1101 | int status; | ||
1102 | unsigned i; | ||
1103 | struct twl4030_platform_data *pdata = client->dev.platform_data; | ||
1104 | |||
1105 | if (!pdata) { | ||
1106 | dev_dbg(&client->dev, "no platform data?\n"); | ||
1107 | return -EINVAL; | ||
1108 | } | ||
1109 | |||
1110 | if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) { | ||
1111 | dev_dbg(&client->dev, "can't talk I2C?\n"); | ||
1112 | return -EIO; | ||
1113 | } | ||
1114 | |||
1115 | if (inuse || twl4030_irq_base) { | ||
1116 | dev_dbg(&client->dev, "driver is already in use\n"); | ||
1117 | return -EBUSY; | ||
1118 | } | ||
1119 | |||
1120 | for (i = 0; i < TWL4030_NUM_SLAVES; i++) { | ||
1121 | struct twl4030_client *twl = &twl4030_modules[i]; | ||
1122 | |||
1123 | twl->address = client->addr + i; | ||
1124 | if (i == 0) | ||
1125 | twl->client = client; | ||
1126 | else { | ||
1127 | twl->client = i2c_new_dummy(client->adapter, | ||
1128 | twl->address); | ||
1129 | if (!twl->client) { | ||
1130 | dev_err(&twl->client->dev, | ||
1131 | "can't attach client %d\n", i); | ||
1132 | status = -ENOMEM; | ||
1133 | goto fail; | ||
1134 | } | ||
1135 | strlcpy(twl->client->name, id->name, | ||
1136 | sizeof(twl->client->name)); | ||
1137 | } | ||
1138 | mutex_init(&twl->xfer_lock); | ||
1139 | } | ||
1140 | inuse = true; | ||
1141 | |||
1142 | /* setup clock framework */ | ||
1143 | clocks_init(); | ||
1144 | |||
1145 | /* Maybe init the T2 Interrupt subsystem */ | ||
1146 | if (client->irq | ||
1147 | && pdata->irq_base | ||
1148 | && pdata->irq_end > pdata->irq_base) { | ||
1149 | twl_init_irq(client->irq, pdata->irq_base, pdata->irq_end); | ||
1150 | dev_info(&client->dev, "IRQ %d chains IRQs %d..%d\n", | ||
1151 | client->irq, pdata->irq_base, pdata->irq_end - 1); | ||
1152 | } | ||
1153 | |||
1154 | status = add_children(pdata); | ||
1155 | fail: | ||
1156 | if (status < 0) | ||
1157 | twl4030_remove(client); | ||
1158 | return status; | ||
1159 | } | ||
1160 | |||
1161 | static const struct i2c_device_id twl4030_ids[] = { | ||
1162 | { "twl4030", 0 }, /* "Triton 2" */ | ||
1163 | { "tps65950", 0 }, /* catalog version of twl4030 */ | ||
1164 | { "tps65930", 0 }, /* fewer LDOs and DACs; no charger */ | ||
1165 | { "tps65920", 0 }, /* fewer LDOs; no codec or charger */ | ||
1166 | { "twl5030", 0 }, /* T2 updated */ | ||
1167 | { /* end of list */ }, | ||
1168 | }; | ||
1169 | MODULE_DEVICE_TABLE(i2c, twl4030_ids); | ||
1170 | |||
1171 | /* One Client Driver , 4 Clients */ | ||
1172 | static struct i2c_driver twl4030_driver = { | ||
1173 | .driver.name = DRIVER_NAME, | ||
1174 | .id_table = twl4030_ids, | ||
1175 | .probe = twl4030_probe, | ||
1176 | .remove = twl4030_remove, | ||
1177 | }; | ||
1178 | |||
1179 | static int __init twl4030_init(void) | ||
1180 | { | ||
1181 | return i2c_add_driver(&twl4030_driver); | ||
1182 | } | ||
1183 | subsys_initcall(twl4030_init); | ||
1184 | |||
1185 | static void __exit twl4030_exit(void) | ||
1186 | { | ||
1187 | i2c_del_driver(&twl4030_driver); | ||
1188 | } | ||
1189 | module_exit(twl4030_exit); | ||
1190 | |||
1191 | MODULE_AUTHOR("Texas Instruments, Inc."); | ||
1192 | MODULE_DESCRIPTION("I2C Core interface for TWL4030"); | ||
1193 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c index 25a7a5d08bce..bf87f675e7fa 100644 --- a/drivers/mfd/wm8350-core.c +++ b/drivers/mfd/wm8350-core.c | |||
@@ -1217,7 +1217,7 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq, | |||
1217 | 1217 | ||
1218 | mutex_init(&wm8350->irq_mutex); | 1218 | mutex_init(&wm8350->irq_mutex); |
1219 | INIT_WORK(&wm8350->irq_work, wm8350_irq_worker); | 1219 | INIT_WORK(&wm8350->irq_work, wm8350_irq_worker); |
1220 | if (irq != NO_IRQ) { | 1220 | if (irq) { |
1221 | ret = request_irq(irq, wm8350_irq, 0, | 1221 | ret = request_irq(irq, wm8350_irq, 0, |
1222 | "wm8350", wm8350); | 1222 | "wm8350", wm8350); |
1223 | if (ret != 0) { | 1223 | if (ret != 0) { |
diff --git a/drivers/misc/hp-wmi.c b/drivers/misc/hp-wmi.c index 5dabfb69ee53..4b7c24c519c3 100644 --- a/drivers/misc/hp-wmi.c +++ b/drivers/misc/hp-wmi.c | |||
@@ -82,6 +82,7 @@ static struct key_entry hp_wmi_keymap[] = { | |||
82 | {KE_KEY, 0x03, KEY_BRIGHTNESSDOWN}, | 82 | {KE_KEY, 0x03, KEY_BRIGHTNESSDOWN}, |
83 | {KE_KEY, 0x20e6, KEY_PROG1}, | 83 | {KE_KEY, 0x20e6, KEY_PROG1}, |
84 | {KE_KEY, 0x2142, KEY_MEDIA}, | 84 | {KE_KEY, 0x2142, KEY_MEDIA}, |
85 | {KE_KEY, 0x213b, KEY_INFO}, | ||
85 | {KE_KEY, 0x231b, KEY_HELP}, | 86 | {KE_KEY, 0x231b, KEY_HELP}, |
86 | {KE_END, 0} | 87 | {KE_END, 0} |
87 | }; | 88 | }; |
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 406989e992ba..7a72e75d5c67 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c | |||
@@ -132,6 +132,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock | |||
132 | 132 | ||
133 | blk_queue_prep_rq(mq->queue, mmc_prep_request); | 133 | blk_queue_prep_rq(mq->queue, mmc_prep_request); |
134 | blk_queue_ordered(mq->queue, QUEUE_ORDERED_DRAIN, NULL); | 134 | blk_queue_ordered(mq->queue, QUEUE_ORDERED_DRAIN, NULL); |
135 | queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mq->queue); | ||
135 | 136 | ||
136 | #ifdef CONFIG_MMC_BLOCK_BOUNCE | 137 | #ifdef CONFIG_MMC_BLOCK_BOUNCE |
137 | if (host->max_hw_segs == 1) { | 138 | if (host->max_hw_segs == 1) { |
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index ae16d845d746..3b2085b57769 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c | |||
@@ -3,6 +3,9 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel <tk@maintech.de> | 4 | * Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel <tk@maintech.de> |
5 | * | 5 | * |
6 | * Current driver maintained by Ben Dooks and Simtec Electronics | ||
7 | * Copyright (C) 2008 Simtec Electronics <ben-linux@fluff.org> | ||
8 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | 9 | * 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 as | 10 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
@@ -13,6 +16,7 @@ | |||
13 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
14 | #include <linux/mmc/host.h> | 17 | #include <linux/mmc/host.h> |
15 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/cpufreq.h> | ||
16 | #include <linux/irq.h> | 20 | #include <linux/irq.h> |
17 | #include <linux/io.h> | 21 | #include <linux/io.h> |
18 | 22 | ||
@@ -39,9 +43,9 @@ enum dbg_channels { | |||
39 | dbg_conf = (1 << 8), | 43 | dbg_conf = (1 << 8), |
40 | }; | 44 | }; |
41 | 45 | ||
42 | static const int dbgmap_err = dbg_err | dbg_fail; | 46 | static const int dbgmap_err = dbg_fail; |
43 | static const int dbgmap_info = dbg_info | dbg_conf; | 47 | static const int dbgmap_info = dbg_info | dbg_conf; |
44 | static const int dbgmap_debug = dbg_debug; | 48 | static const int dbgmap_debug = dbg_err | dbg_debug; |
45 | 49 | ||
46 | #define dbg(host, channels, args...) \ | 50 | #define dbg(host, channels, args...) \ |
47 | do { \ | 51 | do { \ |
@@ -189,7 +193,7 @@ static inline void clear_imask(struct s3cmci_host *host) | |||
189 | } | 193 | } |
190 | 194 | ||
191 | static inline int get_data_buffer(struct s3cmci_host *host, | 195 | static inline int get_data_buffer(struct s3cmci_host *host, |
192 | u32 *words, u32 **pointer) | 196 | u32 *bytes, u32 **pointer) |
193 | { | 197 | { |
194 | struct scatterlist *sg; | 198 | struct scatterlist *sg; |
195 | 199 | ||
@@ -206,7 +210,7 @@ static inline int get_data_buffer(struct s3cmci_host *host, | |||
206 | } | 210 | } |
207 | sg = &host->mrq->data->sg[host->pio_sgptr]; | 211 | sg = &host->mrq->data->sg[host->pio_sgptr]; |
208 | 212 | ||
209 | *words = sg->length >> 2; | 213 | *bytes = sg->length; |
210 | *pointer = sg_virt(sg); | 214 | *pointer = sg_virt(sg); |
211 | 215 | ||
212 | host->pio_sgptr++; | 216 | host->pio_sgptr++; |
@@ -222,7 +226,7 @@ static inline u32 fifo_count(struct s3cmci_host *host) | |||
222 | u32 fifostat = readl(host->base + S3C2410_SDIFSTA); | 226 | u32 fifostat = readl(host->base + S3C2410_SDIFSTA); |
223 | 227 | ||
224 | fifostat &= S3C2410_SDIFSTA_COUNTMASK; | 228 | fifostat &= S3C2410_SDIFSTA_COUNTMASK; |
225 | return fifostat >> 2; | 229 | return fifostat; |
226 | } | 230 | } |
227 | 231 | ||
228 | static inline u32 fifo_free(struct s3cmci_host *host) | 232 | static inline u32 fifo_free(struct s3cmci_host *host) |
@@ -230,13 +234,15 @@ static inline u32 fifo_free(struct s3cmci_host *host) | |||
230 | u32 fifostat = readl(host->base + S3C2410_SDIFSTA); | 234 | u32 fifostat = readl(host->base + S3C2410_SDIFSTA); |
231 | 235 | ||
232 | fifostat &= S3C2410_SDIFSTA_COUNTMASK; | 236 | fifostat &= S3C2410_SDIFSTA_COUNTMASK; |
233 | return (63 - fifostat) >> 2; | 237 | return 63 - fifostat; |
234 | } | 238 | } |
235 | 239 | ||
236 | static void do_pio_read(struct s3cmci_host *host) | 240 | static void do_pio_read(struct s3cmci_host *host) |
237 | { | 241 | { |
238 | int res; | 242 | int res; |
239 | u32 fifo; | 243 | u32 fifo; |
244 | u32 *ptr; | ||
245 | u32 fifo_words; | ||
240 | void __iomem *from_ptr; | 246 | void __iomem *from_ptr; |
241 | 247 | ||
242 | /* write real prescaler to host, it might be set slow to fix */ | 248 | /* write real prescaler to host, it might be set slow to fix */ |
@@ -245,8 +251,8 @@ static void do_pio_read(struct s3cmci_host *host) | |||
245 | from_ptr = host->base + host->sdidata; | 251 | from_ptr = host->base + host->sdidata; |
246 | 252 | ||
247 | while ((fifo = fifo_count(host))) { | 253 | while ((fifo = fifo_count(host))) { |
248 | if (!host->pio_words) { | 254 | if (!host->pio_bytes) { |
249 | res = get_data_buffer(host, &host->pio_words, | 255 | res = get_data_buffer(host, &host->pio_bytes, |
250 | &host->pio_ptr); | 256 | &host->pio_ptr); |
251 | if (res) { | 257 | if (res) { |
252 | host->pio_active = XFER_NONE; | 258 | host->pio_active = XFER_NONE; |
@@ -259,26 +265,47 @@ static void do_pio_read(struct s3cmci_host *host) | |||
259 | 265 | ||
260 | dbg(host, dbg_pio, | 266 | dbg(host, dbg_pio, |
261 | "pio_read(): new target: [%i]@[%p]\n", | 267 | "pio_read(): new target: [%i]@[%p]\n", |
262 | host->pio_words, host->pio_ptr); | 268 | host->pio_bytes, host->pio_ptr); |
263 | } | 269 | } |
264 | 270 | ||
265 | dbg(host, dbg_pio, | 271 | dbg(host, dbg_pio, |
266 | "pio_read(): fifo:[%02i] buffer:[%03i] dcnt:[%08X]\n", | 272 | "pio_read(): fifo:[%02i] buffer:[%03i] dcnt:[%08X]\n", |
267 | fifo, host->pio_words, | 273 | fifo, host->pio_bytes, |
268 | readl(host->base + S3C2410_SDIDCNT)); | 274 | readl(host->base + S3C2410_SDIDCNT)); |
269 | 275 | ||
270 | if (fifo > host->pio_words) | 276 | /* If we have reached the end of the block, we can |
271 | fifo = host->pio_words; | 277 | * read a word and get 1 to 3 bytes. If we in the |
278 | * middle of the block, we have to read full words, | ||
279 | * otherwise we will write garbage, so round down to | ||
280 | * an even multiple of 4. */ | ||
281 | if (fifo >= host->pio_bytes) | ||
282 | fifo = host->pio_bytes; | ||
283 | else | ||
284 | fifo -= fifo & 3; | ||
272 | 285 | ||
273 | host->pio_words -= fifo; | 286 | host->pio_bytes -= fifo; |
274 | host->pio_count += fifo; | 287 | host->pio_count += fifo; |
275 | 288 | ||
276 | while (fifo--) | 289 | fifo_words = fifo >> 2; |
277 | *(host->pio_ptr++) = readl(from_ptr); | 290 | ptr = host->pio_ptr; |
291 | while (fifo_words--) | ||
292 | *ptr++ = readl(from_ptr); | ||
293 | host->pio_ptr = ptr; | ||
294 | |||
295 | if (fifo & 3) { | ||
296 | u32 n = fifo & 3; | ||
297 | u32 data = readl(from_ptr); | ||
298 | u8 *p = (u8 *)host->pio_ptr; | ||
299 | |||
300 | while (n--) { | ||
301 | *p++ = data; | ||
302 | data >>= 8; | ||
303 | } | ||
304 | } | ||
278 | } | 305 | } |
279 | 306 | ||
280 | if (!host->pio_words) { | 307 | if (!host->pio_bytes) { |
281 | res = get_data_buffer(host, &host->pio_words, &host->pio_ptr); | 308 | res = get_data_buffer(host, &host->pio_bytes, &host->pio_ptr); |
282 | if (res) { | 309 | if (res) { |
283 | dbg(host, dbg_pio, | 310 | dbg(host, dbg_pio, |
284 | "pio_read(): complete (no more buffers).\n"); | 311 | "pio_read(): complete (no more buffers).\n"); |
@@ -298,12 +325,13 @@ static void do_pio_write(struct s3cmci_host *host) | |||
298 | void __iomem *to_ptr; | 325 | void __iomem *to_ptr; |
299 | int res; | 326 | int res; |
300 | u32 fifo; | 327 | u32 fifo; |
328 | u32 *ptr; | ||
301 | 329 | ||
302 | to_ptr = host->base + host->sdidata; | 330 | to_ptr = host->base + host->sdidata; |
303 | 331 | ||
304 | while ((fifo = fifo_free(host))) { | 332 | while ((fifo = fifo_free(host))) { |
305 | if (!host->pio_words) { | 333 | if (!host->pio_bytes) { |
306 | res = get_data_buffer(host, &host->pio_words, | 334 | res = get_data_buffer(host, &host->pio_bytes, |
307 | &host->pio_ptr); | 335 | &host->pio_ptr); |
308 | if (res) { | 336 | if (res) { |
309 | dbg(host, dbg_pio, | 337 | dbg(host, dbg_pio, |
@@ -315,18 +343,27 @@ static void do_pio_write(struct s3cmci_host *host) | |||
315 | 343 | ||
316 | dbg(host, dbg_pio, | 344 | dbg(host, dbg_pio, |
317 | "pio_write(): new source: [%i]@[%p]\n", | 345 | "pio_write(): new source: [%i]@[%p]\n", |
318 | host->pio_words, host->pio_ptr); | 346 | host->pio_bytes, host->pio_ptr); |
319 | 347 | ||
320 | } | 348 | } |
321 | 349 | ||
322 | if (fifo > host->pio_words) | 350 | /* If we have reached the end of the block, we have to |
323 | fifo = host->pio_words; | 351 | * write exactly the remaining number of bytes. If we |
352 | * in the middle of the block, we have to write full | ||
353 | * words, so round down to an even multiple of 4. */ | ||
354 | if (fifo >= host->pio_bytes) | ||
355 | fifo = host->pio_bytes; | ||
356 | else | ||
357 | fifo -= fifo & 3; | ||
324 | 358 | ||
325 | host->pio_words -= fifo; | 359 | host->pio_bytes -= fifo; |
326 | host->pio_count += fifo; | 360 | host->pio_count += fifo; |
327 | 361 | ||
362 | fifo = (fifo + 3) >> 2; | ||
363 | ptr = host->pio_ptr; | ||
328 | while (fifo--) | 364 | while (fifo--) |
329 | writel(*(host->pio_ptr++), to_ptr); | 365 | writel(*ptr++, to_ptr); |
366 | host->pio_ptr = ptr; | ||
330 | } | 367 | } |
331 | 368 | ||
332 | enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF); | 369 | enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF); |
@@ -349,9 +386,9 @@ static void pio_tasklet(unsigned long data) | |||
349 | clear_imask(host); | 386 | clear_imask(host); |
350 | if (host->pio_active != XFER_NONE) { | 387 | if (host->pio_active != XFER_NONE) { |
351 | dbg(host, dbg_err, "unfinished %s " | 388 | dbg(host, dbg_err, "unfinished %s " |
352 | "- pio_count:[%u] pio_words:[%u]\n", | 389 | "- pio_count:[%u] pio_bytes:[%u]\n", |
353 | (host->pio_active == XFER_READ) ? "read" : "write", | 390 | (host->pio_active == XFER_READ) ? "read" : "write", |
354 | host->pio_count, host->pio_words); | 391 | host->pio_count, host->pio_bytes); |
355 | 392 | ||
356 | if (host->mrq->data) | 393 | if (host->mrq->data) |
357 | host->mrq->data->error = -EINVAL; | 394 | host->mrq->data->error = -EINVAL; |
@@ -812,11 +849,10 @@ static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data) | |||
812 | /* We cannot deal with unaligned blocks with more than | 849 | /* We cannot deal with unaligned blocks with more than |
813 | * one block being transfered. */ | 850 | * one block being transfered. */ |
814 | 851 | ||
815 | if (data->blocks > 1) | 852 | if (data->blocks > 1) { |
853 | pr_warning("%s: can't do non-word sized block transfers (blksz %d)\n", __func__, data->blksz); | ||
816 | return -EINVAL; | 854 | return -EINVAL; |
817 | 855 | } | |
818 | /* No support yet for non-word block transfers. */ | ||
819 | return -EINVAL; | ||
820 | } | 856 | } |
821 | 857 | ||
822 | while (readl(host->base + S3C2410_SDIDSTA) & | 858 | while (readl(host->base + S3C2410_SDIDSTA) & |
@@ -896,7 +932,7 @@ static int s3cmci_prepare_pio(struct s3cmci_host *host, struct mmc_data *data) | |||
896 | BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR); | 932 | BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR); |
897 | 933 | ||
898 | host->pio_sgptr = 0; | 934 | host->pio_sgptr = 0; |
899 | host->pio_words = 0; | 935 | host->pio_bytes = 0; |
900 | host->pio_count = 0; | 936 | host->pio_count = 0; |
901 | host->pio_active = rw ? XFER_WRITE : XFER_READ; | 937 | host->pio_active = rw ? XFER_WRITE : XFER_READ; |
902 | 938 | ||
@@ -1033,10 +1069,33 @@ static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
1033 | s3cmci_send_request(mmc); | 1069 | s3cmci_send_request(mmc); |
1034 | } | 1070 | } |
1035 | 1071 | ||
1072 | static void s3cmci_set_clk(struct s3cmci_host *host, struct mmc_ios *ios) | ||
1073 | { | ||
1074 | u32 mci_psc; | ||
1075 | |||
1076 | /* Set clock */ | ||
1077 | for (mci_psc = 0; mci_psc < 255; mci_psc++) { | ||
1078 | host->real_rate = host->clk_rate / (host->clk_div*(mci_psc+1)); | ||
1079 | |||
1080 | if (host->real_rate <= ios->clock) | ||
1081 | break; | ||
1082 | } | ||
1083 | |||
1084 | if (mci_psc > 255) | ||
1085 | mci_psc = 255; | ||
1086 | |||
1087 | host->prescaler = mci_psc; | ||
1088 | writel(host->prescaler, host->base + S3C2410_SDIPRE); | ||
1089 | |||
1090 | /* If requested clock is 0, real_rate will be 0, too */ | ||
1091 | if (ios->clock == 0) | ||
1092 | host->real_rate = 0; | ||
1093 | } | ||
1094 | |||
1036 | static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 1095 | static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
1037 | { | 1096 | { |
1038 | struct s3cmci_host *host = mmc_priv(mmc); | 1097 | struct s3cmci_host *host = mmc_priv(mmc); |
1039 | u32 mci_psc, mci_con; | 1098 | u32 mci_con; |
1040 | 1099 | ||
1041 | /* Set the power state */ | 1100 | /* Set the power state */ |
1042 | 1101 | ||
@@ -1074,23 +1133,7 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1074 | break; | 1133 | break; |
1075 | } | 1134 | } |
1076 | 1135 | ||
1077 | /* Set clock */ | 1136 | s3cmci_set_clk(host, ios); |
1078 | for (mci_psc = 0; mci_psc < 255; mci_psc++) { | ||
1079 | host->real_rate = host->clk_rate / (host->clk_div*(mci_psc+1)); | ||
1080 | |||
1081 | if (host->real_rate <= ios->clock) | ||
1082 | break; | ||
1083 | } | ||
1084 | |||
1085 | if (mci_psc > 255) | ||
1086 | mci_psc = 255; | ||
1087 | |||
1088 | host->prescaler = mci_psc; | ||
1089 | writel(host->prescaler, host->base + S3C2410_SDIPRE); | ||
1090 | |||
1091 | /* If requested clock is 0, real_rate will be 0, too */ | ||
1092 | if (ios->clock == 0) | ||
1093 | host->real_rate = 0; | ||
1094 | 1137 | ||
1095 | /* Set CLOCK_ENABLE */ | 1138 | /* Set CLOCK_ENABLE */ |
1096 | if (ios->clock) | 1139 | if (ios->clock) |
@@ -1148,6 +1191,61 @@ static struct s3c24xx_mci_pdata s3cmci_def_pdata = { | |||
1148 | * checks. Any zero fields to ensure reaonable defaults are picked. */ | 1191 | * checks. Any zero fields to ensure reaonable defaults are picked. */ |
1149 | }; | 1192 | }; |
1150 | 1193 | ||
1194 | #ifdef CONFIG_CPU_FREQ | ||
1195 | |||
1196 | static int s3cmci_cpufreq_transition(struct notifier_block *nb, | ||
1197 | unsigned long val, void *data) | ||
1198 | { | ||
1199 | struct s3cmci_host *host; | ||
1200 | struct mmc_host *mmc; | ||
1201 | unsigned long newclk; | ||
1202 | unsigned long flags; | ||
1203 | |||
1204 | host = container_of(nb, struct s3cmci_host, freq_transition); | ||
1205 | newclk = clk_get_rate(host->clk); | ||
1206 | mmc = host->mmc; | ||
1207 | |||
1208 | if ((val == CPUFREQ_PRECHANGE && newclk > host->clk_rate) || | ||
1209 | (val == CPUFREQ_POSTCHANGE && newclk < host->clk_rate)) { | ||
1210 | spin_lock_irqsave(&mmc->lock, flags); | ||
1211 | |||
1212 | host->clk_rate = newclk; | ||
1213 | |||
1214 | if (mmc->ios.power_mode != MMC_POWER_OFF && | ||
1215 | mmc->ios.clock != 0) | ||
1216 | s3cmci_set_clk(host, &mmc->ios); | ||
1217 | |||
1218 | spin_unlock_irqrestore(&mmc->lock, flags); | ||
1219 | } | ||
1220 | |||
1221 | return 0; | ||
1222 | } | ||
1223 | |||
1224 | static inline int s3cmci_cpufreq_register(struct s3cmci_host *host) | ||
1225 | { | ||
1226 | host->freq_transition.notifier_call = s3cmci_cpufreq_transition; | ||
1227 | |||
1228 | return cpufreq_register_notifier(&host->freq_transition, | ||
1229 | CPUFREQ_TRANSITION_NOTIFIER); | ||
1230 | } | ||
1231 | |||
1232 | static inline void s3cmci_cpufreq_deregister(struct s3cmci_host *host) | ||
1233 | { | ||
1234 | cpufreq_unregister_notifier(&host->freq_transition, | ||
1235 | CPUFREQ_TRANSITION_NOTIFIER); | ||
1236 | } | ||
1237 | |||
1238 | #else | ||
1239 | static inline int s3cmci_cpufreq_register(struct s3cmci_host *host) | ||
1240 | { | ||
1241 | return 0; | ||
1242 | } | ||
1243 | |||
1244 | static inline void s3cmci_cpufreq_deregister(struct s3cmci_host *host) | ||
1245 | { | ||
1246 | } | ||
1247 | #endif | ||
1248 | |||
1151 | static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) | 1249 | static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) |
1152 | { | 1250 | { |
1153 | struct s3cmci_host *host; | 1251 | struct s3cmci_host *host; |
@@ -1298,10 +1396,16 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) | |||
1298 | (host->is2440?"2440":""), | 1396 | (host->is2440?"2440":""), |
1299 | host->base, host->irq, host->irq_cd, host->dma); | 1397 | host->base, host->irq, host->irq_cd, host->dma); |
1300 | 1398 | ||
1399 | ret = s3cmci_cpufreq_register(host); | ||
1400 | if (ret) { | ||
1401 | dev_err(&pdev->dev, "failed to register cpufreq\n"); | ||
1402 | goto free_dmabuf; | ||
1403 | } | ||
1404 | |||
1301 | ret = mmc_add_host(mmc); | 1405 | ret = mmc_add_host(mmc); |
1302 | if (ret) { | 1406 | if (ret) { |
1303 | dev_err(&pdev->dev, "failed to add mmc host.\n"); | 1407 | dev_err(&pdev->dev, "failed to add mmc host.\n"); |
1304 | goto free_dmabuf; | 1408 | goto free_cpufreq; |
1305 | } | 1409 | } |
1306 | 1410 | ||
1307 | platform_set_drvdata(pdev, mmc); | 1411 | platform_set_drvdata(pdev, mmc); |
@@ -1309,6 +1413,9 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) | |||
1309 | 1413 | ||
1310 | return 0; | 1414 | return 0; |
1311 | 1415 | ||
1416 | free_cpufreq: | ||
1417 | s3cmci_cpufreq_deregister(host); | ||
1418 | |||
1312 | free_dmabuf: | 1419 | free_dmabuf: |
1313 | clk_disable(host->clk); | 1420 | clk_disable(host->clk); |
1314 | 1421 | ||
@@ -1342,6 +1449,7 @@ static void s3cmci_shutdown(struct platform_device *pdev) | |||
1342 | if (host->irq_cd >= 0) | 1449 | if (host->irq_cd >= 0) |
1343 | free_irq(host->irq_cd, host); | 1450 | free_irq(host->irq_cd, host); |
1344 | 1451 | ||
1452 | s3cmci_cpufreq_deregister(host); | ||
1345 | mmc_remove_host(mmc); | 1453 | mmc_remove_host(mmc); |
1346 | clk_disable(host->clk); | 1454 | clk_disable(host->clk); |
1347 | } | 1455 | } |
@@ -1455,7 +1563,7 @@ module_exit(s3cmci_exit); | |||
1455 | 1563 | ||
1456 | MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver"); | 1564 | MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver"); |
1457 | MODULE_LICENSE("GPL v2"); | 1565 | MODULE_LICENSE("GPL v2"); |
1458 | MODULE_AUTHOR("Thomas Kleffel <tk@maintech.de>"); | 1566 | MODULE_AUTHOR("Thomas Kleffel <tk@maintech.de>, Ben Dooks <ben-linux@fluff.org>"); |
1459 | MODULE_ALIAS("platform:s3c2410-sdi"); | 1567 | MODULE_ALIAS("platform:s3c2410-sdi"); |
1460 | MODULE_ALIAS("platform:s3c2412-sdi"); | 1568 | MODULE_ALIAS("platform:s3c2412-sdi"); |
1461 | MODULE_ALIAS("platform:s3c2440-sdi"); | 1569 | MODULE_ALIAS("platform:s3c2440-sdi"); |
diff --git a/drivers/mmc/host/s3cmci.h b/drivers/mmc/host/s3cmci.h index 37d9c60010c9..ca1ba3d58cfd 100644 --- a/drivers/mmc/host/s3cmci.h +++ b/drivers/mmc/host/s3cmci.h | |||
@@ -51,7 +51,7 @@ struct s3cmci_host { | |||
51 | int dma_complete; | 51 | int dma_complete; |
52 | 52 | ||
53 | u32 pio_sgptr; | 53 | u32 pio_sgptr; |
54 | u32 pio_words; | 54 | u32 pio_bytes; |
55 | u32 pio_count; | 55 | u32 pio_count; |
56 | u32 *pio_ptr; | 56 | u32 *pio_ptr; |
57 | #define XFER_NONE 0 | 57 | #define XFER_NONE 0 |
@@ -67,4 +67,8 @@ struct s3cmci_host { | |||
67 | 67 | ||
68 | unsigned int ccnt, dcnt; | 68 | unsigned int ccnt, dcnt; |
69 | struct tasklet_struct pio_tasklet; | 69 | struct tasklet_struct pio_tasklet; |
70 | |||
71 | #ifdef CONFIG_CPU_FREQ | ||
72 | struct notifier_block freq_transition; | ||
73 | #endif | ||
70 | }; | 74 | }; |
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 14f11f8b9e5f..a90d50c2c3e5 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig | |||
@@ -172,6 +172,11 @@ config MTD_CHAR | |||
172 | memory chips, and also use ioctl() to obtain information about | 172 | memory chips, and also use ioctl() to obtain information about |
173 | the device, or to erase parts of it. | 173 | the device, or to erase parts of it. |
174 | 174 | ||
175 | config HAVE_MTD_OTP | ||
176 | bool | ||
177 | help | ||
178 | Enable access to OTP regions using MTD_CHAR. | ||
179 | |||
175 | config MTD_BLKDEVS | 180 | config MTD_BLKDEVS |
176 | tristate "Common interface to block layer for MTD 'translation layers'" | 181 | tristate "Common interface to block layer for MTD 'translation layers'" |
177 | depends on BLOCK | 182 | depends on BLOCK |
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig index 479d32b57a1e..9408099eec48 100644 --- a/drivers/mtd/chips/Kconfig +++ b/drivers/mtd/chips/Kconfig | |||
@@ -6,6 +6,7 @@ menu "RAM/ROM/Flash chip drivers" | |||
6 | config MTD_CFI | 6 | config MTD_CFI |
7 | tristate "Detect flash chips by Common Flash Interface (CFI) probe" | 7 | tristate "Detect flash chips by Common Flash Interface (CFI) probe" |
8 | select MTD_GEN_PROBE | 8 | select MTD_GEN_PROBE |
9 | select MTD_CFI_UTIL | ||
9 | help | 10 | help |
10 | The Common Flash Interface specification was developed by Intel, | 11 | The Common Flash Interface specification was developed by Intel, |
11 | AMD and other flash manufactures that provides a universal method | 12 | AMD and other flash manufactures that provides a universal method |
@@ -154,6 +155,7 @@ config MTD_CFI_I8 | |||
154 | config MTD_OTP | 155 | config MTD_OTP |
155 | bool "Protection Registers aka one-time programmable (OTP) bits" | 156 | bool "Protection Registers aka one-time programmable (OTP) bits" |
156 | depends on MTD_CFI_ADV_OPTIONS | 157 | depends on MTD_CFI_ADV_OPTIONS |
158 | select HAVE_MTD_OTP | ||
157 | default n | 159 | default n |
158 | help | 160 | help |
159 | This enables support for reading, writing and locking so called | 161 | This enables support for reading, writing and locking so called |
@@ -187,7 +189,7 @@ config MTD_CFI_INTELEXT | |||
187 | StrataFlash and other parts. | 189 | StrataFlash and other parts. |
188 | 190 | ||
189 | config MTD_CFI_AMDSTD | 191 | config MTD_CFI_AMDSTD |
190 | tristate "Support for AMD/Fujitsu flash chips" | 192 | tristate "Support for AMD/Fujitsu/Spansion flash chips" |
191 | depends on MTD_GEN_PROBE | 193 | depends on MTD_GEN_PROBE |
192 | select MTD_CFI_UTIL | 194 | select MTD_CFI_UTIL |
193 | help | 195 | help |
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 5f1b472137a0..c93a8be5d5f1 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c | |||
@@ -478,6 +478,28 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary) | |||
478 | else | 478 | else |
479 | cfi->chips[i].erase_time = 2000000; | 479 | cfi->chips[i].erase_time = 2000000; |
480 | 480 | ||
481 | if (cfi->cfiq->WordWriteTimeoutTyp && | ||
482 | cfi->cfiq->WordWriteTimeoutMax) | ||
483 | cfi->chips[i].word_write_time_max = | ||
484 | 1<<(cfi->cfiq->WordWriteTimeoutTyp + | ||
485 | cfi->cfiq->WordWriteTimeoutMax); | ||
486 | else | ||
487 | cfi->chips[i].word_write_time_max = 50000 * 8; | ||
488 | |||
489 | if (cfi->cfiq->BufWriteTimeoutTyp && | ||
490 | cfi->cfiq->BufWriteTimeoutMax) | ||
491 | cfi->chips[i].buffer_write_time_max = | ||
492 | 1<<(cfi->cfiq->BufWriteTimeoutTyp + | ||
493 | cfi->cfiq->BufWriteTimeoutMax); | ||
494 | |||
495 | if (cfi->cfiq->BlockEraseTimeoutTyp && | ||
496 | cfi->cfiq->BlockEraseTimeoutMax) | ||
497 | cfi->chips[i].erase_time_max = | ||
498 | 1000<<(cfi->cfiq->BlockEraseTimeoutTyp + | ||
499 | cfi->cfiq->BlockEraseTimeoutMax); | ||
500 | else | ||
501 | cfi->chips[i].erase_time_max = 2000000 * 8; | ||
502 | |||
481 | cfi->chips[i].ref_point_counter = 0; | 503 | cfi->chips[i].ref_point_counter = 0; |
482 | init_waitqueue_head(&(cfi->chips[i].wq)); | 504 | init_waitqueue_head(&(cfi->chips[i].wq)); |
483 | } | 505 | } |
@@ -703,6 +725,10 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long | |||
703 | struct cfi_pri_intelext *cfip = cfi->cmdset_priv; | 725 | struct cfi_pri_intelext *cfip = cfi->cmdset_priv; |
704 | unsigned long timeo = jiffies + HZ; | 726 | unsigned long timeo = jiffies + HZ; |
705 | 727 | ||
728 | /* Prevent setting state FL_SYNCING for chip in suspended state. */ | ||
729 | if (mode == FL_SYNCING && chip->oldstate != FL_READY) | ||
730 | goto sleep; | ||
731 | |||
706 | switch (chip->state) { | 732 | switch (chip->state) { |
707 | 733 | ||
708 | case FL_STATUS: | 734 | case FL_STATUS: |
@@ -808,8 +834,9 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr | |||
808 | DECLARE_WAITQUEUE(wait, current); | 834 | DECLARE_WAITQUEUE(wait, current); |
809 | 835 | ||
810 | retry: | 836 | retry: |
811 | if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING | 837 | if (chip->priv && |
812 | || mode == FL_OTP_WRITE || mode == FL_SHUTDOWN)) { | 838 | (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE |
839 | || mode == FL_SHUTDOWN) && chip->state != FL_SYNCING) { | ||
813 | /* | 840 | /* |
814 | * OK. We have possibility for contention on the write/erase | 841 | * OK. We have possibility for contention on the write/erase |
815 | * operations which are global to the real chip and not per | 842 | * operations which are global to the real chip and not per |
@@ -859,6 +886,14 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr | |||
859 | return ret; | 886 | return ret; |
860 | } | 887 | } |
861 | spin_lock(&shared->lock); | 888 | spin_lock(&shared->lock); |
889 | |||
890 | /* We should not own chip if it is already | ||
891 | * in FL_SYNCING state. Put contender and retry. */ | ||
892 | if (chip->state == FL_SYNCING) { | ||
893 | put_chip(map, contender, contender->start); | ||
894 | spin_unlock(contender->mutex); | ||
895 | goto retry; | ||
896 | } | ||
862 | spin_unlock(contender->mutex); | 897 | spin_unlock(contender->mutex); |
863 | } | 898 | } |
864 | 899 | ||
@@ -1012,7 +1047,7 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip, | |||
1012 | 1047 | ||
1013 | static int __xipram xip_wait_for_operation( | 1048 | static int __xipram xip_wait_for_operation( |
1014 | struct map_info *map, struct flchip *chip, | 1049 | struct map_info *map, struct flchip *chip, |
1015 | unsigned long adr, unsigned int chip_op_time ) | 1050 | unsigned long adr, unsigned int chip_op_time_max) |
1016 | { | 1051 | { |
1017 | struct cfi_private *cfi = map->fldrv_priv; | 1052 | struct cfi_private *cfi = map->fldrv_priv; |
1018 | struct cfi_pri_intelext *cfip = cfi->cmdset_priv; | 1053 | struct cfi_pri_intelext *cfip = cfi->cmdset_priv; |
@@ -1021,7 +1056,7 @@ static int __xipram xip_wait_for_operation( | |||
1021 | flstate_t oldstate, newstate; | 1056 | flstate_t oldstate, newstate; |
1022 | 1057 | ||
1023 | start = xip_currtime(); | 1058 | start = xip_currtime(); |
1024 | usec = chip_op_time * 8; | 1059 | usec = chip_op_time_max; |
1025 | if (usec == 0) | 1060 | if (usec == 0) |
1026 | usec = 500000; | 1061 | usec = 500000; |
1027 | done = 0; | 1062 | done = 0; |
@@ -1131,8 +1166,8 @@ static int __xipram xip_wait_for_operation( | |||
1131 | #define XIP_INVAL_CACHED_RANGE(map, from, size) \ | 1166 | #define XIP_INVAL_CACHED_RANGE(map, from, size) \ |
1132 | INVALIDATE_CACHED_RANGE(map, from, size) | 1167 | INVALIDATE_CACHED_RANGE(map, from, size) |
1133 | 1168 | ||
1134 | #define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, usec) \ | 1169 | #define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, usec, usec_max) \ |
1135 | xip_wait_for_operation(map, chip, cmd_adr, usec) | 1170 | xip_wait_for_operation(map, chip, cmd_adr, usec_max) |
1136 | 1171 | ||
1137 | #else | 1172 | #else |
1138 | 1173 | ||
@@ -1144,7 +1179,7 @@ static int __xipram xip_wait_for_operation( | |||
1144 | static int inval_cache_and_wait_for_operation( | 1179 | static int inval_cache_and_wait_for_operation( |
1145 | struct map_info *map, struct flchip *chip, | 1180 | struct map_info *map, struct flchip *chip, |
1146 | unsigned long cmd_adr, unsigned long inval_adr, int inval_len, | 1181 | unsigned long cmd_adr, unsigned long inval_adr, int inval_len, |
1147 | unsigned int chip_op_time) | 1182 | unsigned int chip_op_time, unsigned int chip_op_time_max) |
1148 | { | 1183 | { |
1149 | struct cfi_private *cfi = map->fldrv_priv; | 1184 | struct cfi_private *cfi = map->fldrv_priv; |
1150 | map_word status, status_OK = CMD(0x80); | 1185 | map_word status, status_OK = CMD(0x80); |
@@ -1156,8 +1191,7 @@ static int inval_cache_and_wait_for_operation( | |||
1156 | INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len); | 1191 | INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len); |
1157 | spin_lock(chip->mutex); | 1192 | spin_lock(chip->mutex); |
1158 | 1193 | ||
1159 | /* set our timeout to 8 times the expected delay */ | 1194 | timeo = chip_op_time_max; |
1160 | timeo = chip_op_time * 8; | ||
1161 | if (!timeo) | 1195 | if (!timeo) |
1162 | timeo = 500000; | 1196 | timeo = 500000; |
1163 | reset_timeo = timeo; | 1197 | reset_timeo = timeo; |
@@ -1217,8 +1251,8 @@ static int inval_cache_and_wait_for_operation( | |||
1217 | 1251 | ||
1218 | #endif | 1252 | #endif |
1219 | 1253 | ||
1220 | #define WAIT_TIMEOUT(map, chip, adr, udelay) \ | 1254 | #define WAIT_TIMEOUT(map, chip, adr, udelay, udelay_max) \ |
1221 | INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, udelay); | 1255 | INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, udelay, udelay_max); |
1222 | 1256 | ||
1223 | 1257 | ||
1224 | static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len) | 1258 | static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len) |
@@ -1452,7 +1486,8 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, | |||
1452 | 1486 | ||
1453 | ret = INVAL_CACHE_AND_WAIT(map, chip, adr, | 1487 | ret = INVAL_CACHE_AND_WAIT(map, chip, adr, |
1454 | adr, map_bankwidth(map), | 1488 | adr, map_bankwidth(map), |
1455 | chip->word_write_time); | 1489 | chip->word_write_time, |
1490 | chip->word_write_time_max); | ||
1456 | if (ret) { | 1491 | if (ret) { |
1457 | xip_enable(map, chip, adr); | 1492 | xip_enable(map, chip, adr); |
1458 | printk(KERN_ERR "%s: word write error (status timeout)\n", map->name); | 1493 | printk(KERN_ERR "%s: word write error (status timeout)\n", map->name); |
@@ -1623,7 +1658,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, | |||
1623 | 1658 | ||
1624 | chip->state = FL_WRITING_TO_BUFFER; | 1659 | chip->state = FL_WRITING_TO_BUFFER; |
1625 | map_write(map, write_cmd, cmd_adr); | 1660 | map_write(map, write_cmd, cmd_adr); |
1626 | ret = WAIT_TIMEOUT(map, chip, cmd_adr, 0); | 1661 | ret = WAIT_TIMEOUT(map, chip, cmd_adr, 0, 0); |
1627 | if (ret) { | 1662 | if (ret) { |
1628 | /* Argh. Not ready for write to buffer */ | 1663 | /* Argh. Not ready for write to buffer */ |
1629 | map_word Xstatus = map_read(map, cmd_adr); | 1664 | map_word Xstatus = map_read(map, cmd_adr); |
@@ -1640,7 +1675,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, | |||
1640 | 1675 | ||
1641 | /* Figure out the number of words to write */ | 1676 | /* Figure out the number of words to write */ |
1642 | word_gap = (-adr & (map_bankwidth(map)-1)); | 1677 | word_gap = (-adr & (map_bankwidth(map)-1)); |
1643 | words = (len - word_gap + map_bankwidth(map) - 1) / map_bankwidth(map); | 1678 | words = DIV_ROUND_UP(len - word_gap, map_bankwidth(map)); |
1644 | if (!word_gap) { | 1679 | if (!word_gap) { |
1645 | words--; | 1680 | words--; |
1646 | } else { | 1681 | } else { |
@@ -1692,7 +1727,8 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, | |||
1692 | 1727 | ||
1693 | ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, | 1728 | ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, |
1694 | initial_adr, initial_len, | 1729 | initial_adr, initial_len, |
1695 | chip->buffer_write_time); | 1730 | chip->buffer_write_time, |
1731 | chip->buffer_write_time_max); | ||
1696 | if (ret) { | 1732 | if (ret) { |
1697 | map_write(map, CMD(0x70), cmd_adr); | 1733 | map_write(map, CMD(0x70), cmd_adr); |
1698 | chip->state = FL_STATUS; | 1734 | chip->state = FL_STATUS; |
@@ -1827,7 +1863,8 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, | |||
1827 | 1863 | ||
1828 | ret = INVAL_CACHE_AND_WAIT(map, chip, adr, | 1864 | ret = INVAL_CACHE_AND_WAIT(map, chip, adr, |
1829 | adr, len, | 1865 | adr, len, |
1830 | chip->erase_time); | 1866 | chip->erase_time, |
1867 | chip->erase_time_max); | ||
1831 | if (ret) { | 1868 | if (ret) { |
1832 | map_write(map, CMD(0x70), adr); | 1869 | map_write(map, CMD(0x70), adr); |
1833 | chip->state = FL_STATUS; | 1870 | chip->state = FL_STATUS; |
@@ -2006,7 +2043,7 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip | |||
2006 | */ | 2043 | */ |
2007 | udelay = (!extp || !(extp->FeatureSupport & (1 << 5))) ? 1000000/HZ : 0; | 2044 | udelay = (!extp || !(extp->FeatureSupport & (1 << 5))) ? 1000000/HZ : 0; |
2008 | 2045 | ||
2009 | ret = WAIT_TIMEOUT(map, chip, adr, udelay); | 2046 | ret = WAIT_TIMEOUT(map, chip, adr, udelay, udelay * 100); |
2010 | if (ret) { | 2047 | if (ret) { |
2011 | map_write(map, CMD(0x70), adr); | 2048 | map_write(map, CMD(0x70), adr); |
2012 | chip->state = FL_STATUS; | 2049 | chip->state = FL_STATUS; |
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index a972cc6be436..3e6f5d8609e8 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c | |||
@@ -13,6 +13,8 @@ | |||
13 | * XIP support hooks by Vitaly Wool (based on code for Intel flash | 13 | * XIP support hooks by Vitaly Wool (based on code for Intel flash |
14 | * by Nicolas Pitre) | 14 | * by Nicolas Pitre) |
15 | * | 15 | * |
16 | * 25/09/2008 Christopher Moore: TopBottom fixup for many Macronix with CFI V1.0 | ||
17 | * | ||
16 | * Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com | 18 | * Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com |
17 | * | 19 | * |
18 | * This code is GPL | 20 | * This code is GPL |
@@ -43,6 +45,7 @@ | |||
43 | 45 | ||
44 | #define MANUFACTURER_AMD 0x0001 | 46 | #define MANUFACTURER_AMD 0x0001 |
45 | #define MANUFACTURER_ATMEL 0x001F | 47 | #define MANUFACTURER_ATMEL 0x001F |
48 | #define MANUFACTURER_MACRONIX 0x00C2 | ||
46 | #define MANUFACTURER_SST 0x00BF | 49 | #define MANUFACTURER_SST 0x00BF |
47 | #define SST49LF004B 0x0060 | 50 | #define SST49LF004B 0x0060 |
48 | #define SST49LF040B 0x0050 | 51 | #define SST49LF040B 0x0050 |
@@ -144,12 +147,44 @@ static void fixup_amd_bootblock(struct mtd_info *mtd, void* param) | |||
144 | 147 | ||
145 | if (((major << 8) | minor) < 0x3131) { | 148 | if (((major << 8) | minor) < 0x3131) { |
146 | /* CFI version 1.0 => don't trust bootloc */ | 149 | /* CFI version 1.0 => don't trust bootloc */ |
150 | |||
151 | DEBUG(MTD_DEBUG_LEVEL1, | ||
152 | "%s: JEDEC Vendor ID is 0x%02X Device ID is 0x%02X\n", | ||
153 | map->name, cfi->mfr, cfi->id); | ||
154 | |||
155 | /* AFAICS all 29LV400 with a bottom boot block have a device ID | ||
156 | * of 0x22BA in 16-bit mode and 0xBA in 8-bit mode. | ||
157 | * These were badly detected as they have the 0x80 bit set | ||
158 | * so treat them as a special case. | ||
159 | */ | ||
160 | if (((cfi->id == 0xBA) || (cfi->id == 0x22BA)) && | ||
161 | |||
162 | /* Macronix added CFI to their 2nd generation | ||
163 | * MX29LV400C B/T but AFAICS no other 29LV400 (AMD, | ||
164 | * Fujitsu, Spansion, EON, ESI and older Macronix) | ||
165 | * has CFI. | ||
166 | * | ||
167 | * Therefore also check the manufacturer. | ||
168 | * This reduces the risk of false detection due to | ||
169 | * the 8-bit device ID. | ||
170 | */ | ||
171 | (cfi->mfr == MANUFACTURER_MACRONIX)) { | ||
172 | DEBUG(MTD_DEBUG_LEVEL1, | ||
173 | "%s: Macronix MX29LV400C with bottom boot block" | ||
174 | " detected\n", map->name); | ||
175 | extp->TopBottom = 2; /* bottom boot */ | ||
176 | } else | ||
147 | if (cfi->id & 0x80) { | 177 | if (cfi->id & 0x80) { |
148 | printk(KERN_WARNING "%s: JEDEC Device ID is 0x%02X. Assuming broken CFI table.\n", map->name, cfi->id); | 178 | printk(KERN_WARNING "%s: JEDEC Device ID is 0x%02X. Assuming broken CFI table.\n", map->name, cfi->id); |
149 | extp->TopBottom = 3; /* top boot */ | 179 | extp->TopBottom = 3; /* top boot */ |
150 | } else { | 180 | } else { |
151 | extp->TopBottom = 2; /* bottom boot */ | 181 | extp->TopBottom = 2; /* bottom boot */ |
152 | } | 182 | } |
183 | |||
184 | DEBUG(MTD_DEBUG_LEVEL1, | ||
185 | "%s: AMD CFI PRI V%c.%c has no boot block field;" | ||
186 | " deduced %s from Device ID\n", map->name, major, minor, | ||
187 | extp->TopBottom == 2 ? "bottom" : "top"); | ||
153 | } | 188 | } |
154 | } | 189 | } |
155 | #endif | 190 | #endif |
@@ -178,10 +213,18 @@ static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param) | |||
178 | if (atmel_pri.Features & 0x02) | 213 | if (atmel_pri.Features & 0x02) |
179 | extp->EraseSuspend = 2; | 214 | extp->EraseSuspend = 2; |
180 | 215 | ||
181 | if (atmel_pri.BottomBoot) | 216 | /* Some chips got it backwards... */ |
182 | extp->TopBottom = 2; | 217 | if (cfi->id == AT49BV6416) { |
183 | else | 218 | if (atmel_pri.BottomBoot) |
184 | extp->TopBottom = 3; | 219 | extp->TopBottom = 3; |
220 | else | ||
221 | extp->TopBottom = 2; | ||
222 | } else { | ||
223 | if (atmel_pri.BottomBoot) | ||
224 | extp->TopBottom = 2; | ||
225 | else | ||
226 | extp->TopBottom = 3; | ||
227 | } | ||
185 | 228 | ||
186 | /* burst write mode not supported */ | 229 | /* burst write mode not supported */ |
187 | cfi->cfiq->BufWriteTimeoutTyp = 0; | 230 | cfi->cfiq->BufWriteTimeoutTyp = 0; |
@@ -243,6 +286,7 @@ static struct cfi_fixup cfi_fixup_table[] = { | |||
243 | { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL }, | 286 | { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL }, |
244 | #ifdef AMD_BOOTLOC_BUG | 287 | #ifdef AMD_BOOTLOC_BUG |
245 | { CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock, NULL }, | 288 | { CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock, NULL }, |
289 | { MANUFACTURER_MACRONIX, CFI_ID_ANY, fixup_amd_bootblock, NULL }, | ||
246 | #endif | 290 | #endif |
247 | { CFI_MFR_AMD, 0x0050, fixup_use_secsi, NULL, }, | 291 | { CFI_MFR_AMD, 0x0050, fixup_use_secsi, NULL, }, |
248 | { CFI_MFR_AMD, 0x0053, fixup_use_secsi, NULL, }, | 292 | { CFI_MFR_AMD, 0x0053, fixup_use_secsi, NULL, }, |
diff --git a/drivers/mtd/chips/cfi_probe.c b/drivers/mtd/chips/cfi_probe.c index c418e92e1d92..e63e6749429a 100644 --- a/drivers/mtd/chips/cfi_probe.c +++ b/drivers/mtd/chips/cfi_probe.c | |||
@@ -44,17 +44,14 @@ do { \ | |||
44 | 44 | ||
45 | #define xip_enable(base, map, cfi) \ | 45 | #define xip_enable(base, map, cfi) \ |
46 | do { \ | 46 | do { \ |
47 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); \ | 47 | cfi_qry_mode_off(base, map, cfi); \ |
48 | cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); \ | ||
49 | xip_allowed(base, map); \ | 48 | xip_allowed(base, map); \ |
50 | } while (0) | 49 | } while (0) |
51 | 50 | ||
52 | #define xip_disable_qry(base, map, cfi) \ | 51 | #define xip_disable_qry(base, map, cfi) \ |
53 | do { \ | 52 | do { \ |
54 | xip_disable(); \ | 53 | xip_disable(); \ |
55 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); \ | 54 | cfi_qry_mode_on(base, map, cfi); \ |
56 | cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); \ | ||
57 | cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); \ | ||
58 | } while (0) | 55 | } while (0) |
59 | 56 | ||
60 | #else | 57 | #else |
@@ -70,32 +67,6 @@ do { \ | |||
70 | in: interleave,type,mode | 67 | in: interleave,type,mode |
71 | ret: table index, <0 for error | 68 | ret: table index, <0 for error |
72 | */ | 69 | */ |
73 | static int __xipram qry_present(struct map_info *map, __u32 base, | ||
74 | struct cfi_private *cfi) | ||
75 | { | ||
76 | int osf = cfi->interleave * cfi->device_type; // scale factor | ||
77 | map_word val[3]; | ||
78 | map_word qry[3]; | ||
79 | |||
80 | qry[0] = cfi_build_cmd('Q', map, cfi); | ||
81 | qry[1] = cfi_build_cmd('R', map, cfi); | ||
82 | qry[2] = cfi_build_cmd('Y', map, cfi); | ||
83 | |||
84 | val[0] = map_read(map, base + osf*0x10); | ||
85 | val[1] = map_read(map, base + osf*0x11); | ||
86 | val[2] = map_read(map, base + osf*0x12); | ||
87 | |||
88 | if (!map_word_equal(map, qry[0], val[0])) | ||
89 | return 0; | ||
90 | |||
91 | if (!map_word_equal(map, qry[1], val[1])) | ||
92 | return 0; | ||
93 | |||
94 | if (!map_word_equal(map, qry[2], val[2])) | ||
95 | return 0; | ||
96 | |||
97 | return 1; // "QRY" found | ||
98 | } | ||
99 | 70 | ||
100 | static int __xipram cfi_probe_chip(struct map_info *map, __u32 base, | 71 | static int __xipram cfi_probe_chip(struct map_info *map, __u32 base, |
101 | unsigned long *chip_map, struct cfi_private *cfi) | 72 | unsigned long *chip_map, struct cfi_private *cfi) |
@@ -116,11 +87,7 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base, | |||
116 | } | 87 | } |
117 | 88 | ||
118 | xip_disable(); | 89 | xip_disable(); |
119 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); | 90 | if (!cfi_qry_mode_on(base, map, cfi)) { |
120 | cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); | ||
121 | cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); | ||
122 | |||
123 | if (!qry_present(map,base,cfi)) { | ||
124 | xip_enable(base, map, cfi); | 91 | xip_enable(base, map, cfi); |
125 | return 0; | 92 | return 0; |
126 | } | 93 | } |
@@ -141,14 +108,13 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base, | |||
141 | start = i << cfi->chipshift; | 108 | start = i << cfi->chipshift; |
142 | /* This chip should be in read mode if it's one | 109 | /* This chip should be in read mode if it's one |
143 | we've already touched. */ | 110 | we've already touched. */ |
144 | if (qry_present(map, start, cfi)) { | 111 | if (cfi_qry_present(map, start, cfi)) { |
145 | /* Eep. This chip also had the QRY marker. | 112 | /* Eep. This chip also had the QRY marker. |
146 | * Is it an alias for the new one? */ | 113 | * Is it an alias for the new one? */ |
147 | cfi_send_gen_cmd(0xF0, 0, start, map, cfi, cfi->device_type, NULL); | 114 | cfi_qry_mode_off(start, map, cfi); |
148 | cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL); | ||
149 | 115 | ||
150 | /* If the QRY marker goes away, it's an alias */ | 116 | /* If the QRY marker goes away, it's an alias */ |
151 | if (!qry_present(map, start, cfi)) { | 117 | if (!cfi_qry_present(map, start, cfi)) { |
152 | xip_allowed(base, map); | 118 | xip_allowed(base, map); |
153 | printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", | 119 | printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", |
154 | map->name, base, start); | 120 | map->name, base, start); |
@@ -158,10 +124,9 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base, | |||
158 | * unfortunate. Stick the new chip in read mode | 124 | * unfortunate. Stick the new chip in read mode |
159 | * too and if it's the same, assume it's an alias. */ | 125 | * too and if it's the same, assume it's an alias. */ |
160 | /* FIXME: Use other modes to do a proper check */ | 126 | /* FIXME: Use other modes to do a proper check */ |
161 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); | 127 | cfi_qry_mode_off(base, map, cfi); |
162 | cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL); | ||
163 | 128 | ||
164 | if (qry_present(map, base, cfi)) { | 129 | if (cfi_qry_present(map, base, cfi)) { |
165 | xip_allowed(base, map); | 130 | xip_allowed(base, map); |
166 | printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", | 131 | printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", |
167 | map->name, base, start); | 132 | map->name, base, start); |
@@ -176,8 +141,7 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base, | |||
176 | cfi->numchips++; | 141 | cfi->numchips++; |
177 | 142 | ||
178 | /* Put it back into Read Mode */ | 143 | /* Put it back into Read Mode */ |
179 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); | 144 | cfi_qry_mode_off(base, map, cfi); |
180 | cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); | ||
181 | xip_allowed(base, map); | 145 | xip_allowed(base, map); |
182 | 146 | ||
183 | printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n", | 147 | printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n", |
@@ -237,9 +201,7 @@ static int __xipram cfi_chip_setup(struct map_info *map, | |||
237 | cfi_read_query(map, base + 0xf * ofs_factor); | 201 | cfi_read_query(map, base + 0xf * ofs_factor); |
238 | 202 | ||
239 | /* Put it back into Read Mode */ | 203 | /* Put it back into Read Mode */ |
240 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); | 204 | cfi_qry_mode_off(base, map, cfi); |
241 | /* ... even if it's an Intel chip */ | ||
242 | cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); | ||
243 | xip_allowed(base, map); | 205 | xip_allowed(base, map); |
244 | 206 | ||
245 | /* Do any necessary byteswapping */ | 207 | /* Do any necessary byteswapping */ |
diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c index 0ee457018016..34d40e25d312 100644 --- a/drivers/mtd/chips/cfi_util.c +++ b/drivers/mtd/chips/cfi_util.c | |||
@@ -24,6 +24,66 @@ | |||
24 | #include <linux/mtd/cfi.h> | 24 | #include <linux/mtd/cfi.h> |
25 | #include <linux/mtd/compatmac.h> | 25 | #include <linux/mtd/compatmac.h> |
26 | 26 | ||
27 | int __xipram cfi_qry_present(struct map_info *map, __u32 base, | ||
28 | struct cfi_private *cfi) | ||
29 | { | ||
30 | int osf = cfi->interleave * cfi->device_type; /* scale factor */ | ||
31 | map_word val[3]; | ||
32 | map_word qry[3]; | ||
33 | |||
34 | qry[0] = cfi_build_cmd('Q', map, cfi); | ||
35 | qry[1] = cfi_build_cmd('R', map, cfi); | ||
36 | qry[2] = cfi_build_cmd('Y', map, cfi); | ||
37 | |||
38 | val[0] = map_read(map, base + osf*0x10); | ||
39 | val[1] = map_read(map, base + osf*0x11); | ||
40 | val[2] = map_read(map, base + osf*0x12); | ||
41 | |||
42 | if (!map_word_equal(map, qry[0], val[0])) | ||
43 | return 0; | ||
44 | |||
45 | if (!map_word_equal(map, qry[1], val[1])) | ||
46 | return 0; | ||
47 | |||
48 | if (!map_word_equal(map, qry[2], val[2])) | ||
49 | return 0; | ||
50 | |||
51 | return 1; /* "QRY" found */ | ||
52 | } | ||
53 | EXPORT_SYMBOL_GPL(cfi_qry_present); | ||
54 | |||
55 | int __xipram cfi_qry_mode_on(uint32_t base, struct map_info *map, | ||
56 | struct cfi_private *cfi) | ||
57 | { | ||
58 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); | ||
59 | cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); | ||
60 | if (cfi_qry_present(map, base, cfi)) | ||
61 | return 1; | ||
62 | /* QRY not found probably we deal with some odd CFI chips */ | ||
63 | /* Some revisions of some old Intel chips? */ | ||
64 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); | ||
65 | cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); | ||
66 | cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); | ||
67 | if (cfi_qry_present(map, base, cfi)) | ||
68 | return 1; | ||
69 | /* ST M29DW chips */ | ||
70 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); | ||
71 | cfi_send_gen_cmd(0x98, 0x555, base, map, cfi, cfi->device_type, NULL); | ||
72 | if (cfi_qry_present(map, base, cfi)) | ||
73 | return 1; | ||
74 | /* QRY not found */ | ||
75 | return 0; | ||
76 | } | ||
77 | EXPORT_SYMBOL_GPL(cfi_qry_mode_on); | ||
78 | |||
79 | void __xipram cfi_qry_mode_off(uint32_t base, struct map_info *map, | ||
80 | struct cfi_private *cfi) | ||
81 | { | ||
82 | cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); | ||
83 | cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); | ||
84 | } | ||
85 | EXPORT_SYMBOL_GPL(cfi_qry_mode_off); | ||
86 | |||
27 | struct cfi_extquery * | 87 | struct cfi_extquery * |
28 | __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name) | 88 | __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name) |
29 | { | 89 | { |
@@ -48,8 +108,7 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n | |||
48 | #endif | 108 | #endif |
49 | 109 | ||
50 | /* Switch it into Query Mode */ | 110 | /* Switch it into Query Mode */ |
51 | cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); | 111 | cfi_qry_mode_on(base, map, cfi); |
52 | |||
53 | /* Read in the Extended Query Table */ | 112 | /* Read in the Extended Query Table */ |
54 | for (i=0; i<size; i++) { | 113 | for (i=0; i<size; i++) { |
55 | ((unsigned char *)extp)[i] = | 114 | ((unsigned char *)extp)[i] = |
@@ -57,8 +116,7 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n | |||
57 | } | 116 | } |
58 | 117 | ||
59 | /* Make sure it returns to read mode */ | 118 | /* Make sure it returns to read mode */ |
60 | cfi_send_gen_cmd(0xf0, 0, base, map, cfi, cfi->device_type, NULL); | 119 | cfi_qry_mode_off(base, map, cfi); |
61 | cfi_send_gen_cmd(0xff, 0, base, map, cfi, cfi->device_type, NULL); | ||
62 | 120 | ||
63 | #ifdef CONFIG_MTD_XIP | 121 | #ifdef CONFIG_MTD_XIP |
64 | (void) map_read(map, base); | 122 | (void) map_read(map, base); |
diff --git a/drivers/mtd/chips/gen_probe.c b/drivers/mtd/chips/gen_probe.c index f061885b2812..e2dc96441e05 100644 --- a/drivers/mtd/chips/gen_probe.c +++ b/drivers/mtd/chips/gen_probe.c | |||
@@ -111,7 +111,7 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi | |||
111 | max_chips = 1; | 111 | max_chips = 1; |
112 | } | 112 | } |
113 | 113 | ||
114 | mapsize = sizeof(long) * ( (max_chips + BITS_PER_LONG-1) / BITS_PER_LONG ); | 114 | mapsize = sizeof(long) * DIV_ROUND_UP(max_chips, BITS_PER_LONG); |
115 | chip_map = kzalloc(mapsize, GFP_KERNEL); | 115 | chip_map = kzalloc(mapsize, GFP_KERNEL); |
116 | if (!chip_map) { | 116 | if (!chip_map) { |
117 | printk(KERN_WARNING "%s: kmalloc failed for CFI chip map\n", map->name); | 117 | printk(KERN_WARNING "%s: kmalloc failed for CFI chip map\n", map->name); |
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c index 71bc07f149b7..50a340388e74 100644 --- a/drivers/mtd/cmdlinepart.c +++ b/drivers/mtd/cmdlinepart.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * | 7 | * |
8 | * mtdparts=<mtddef>[;<mtddef] | 8 | * mtdparts=<mtddef>[;<mtddef] |
9 | * <mtddef> := <mtd-id>:<partdef>[,<partdef>] | 9 | * <mtddef> := <mtd-id>:<partdef>[,<partdef>] |
10 | * where <mtd-id> is the name from the "cat /proc/mtd" command | ||
10 | * <partdef> := <size>[@offset][<name>][ro][lk] | 11 | * <partdef> := <size>[@offset][<name>][ro][lk] |
11 | * <mtd-id> := unique name used in mapping driver/device (mtd->name) | 12 | * <mtd-id> := unique name used in mapping driver/device (mtd->name) |
12 | * <size> := standard linux memsize OR "-" to denote all remaining space | 13 | * <size> := standard linux memsize OR "-" to denote all remaining space |
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig index 9c613f06623c..6fde0a2e3567 100644 --- a/drivers/mtd/devices/Kconfig +++ b/drivers/mtd/devices/Kconfig | |||
@@ -59,6 +59,27 @@ config MTD_DATAFLASH | |||
59 | Sometimes DataFlash chips are packaged inside MMC-format | 59 | Sometimes DataFlash chips are packaged inside MMC-format |
60 | cards; at this writing, the MMC stack won't handle those. | 60 | cards; at this writing, the MMC stack won't handle those. |
61 | 61 | ||
62 | config MTD_DATAFLASH_WRITE_VERIFY | ||
63 | bool "Verify DataFlash page writes" | ||
64 | depends on MTD_DATAFLASH | ||
65 | help | ||
66 | This adds an extra check when data is written to the flash. | ||
67 | It may help if you are verifying chip setup (timings etc) on | ||
68 | your board. There is a rare possibility that even though the | ||
69 | device thinks the write was successful, a bit could have been | ||
70 | flipped accidentally due to device wear or something else. | ||
71 | |||
72 | config MTD_DATAFLASH_OTP | ||
73 | bool "DataFlash OTP support (Security Register)" | ||
74 | depends on MTD_DATAFLASH | ||
75 | select HAVE_MTD_OTP | ||
76 | help | ||
77 | Newer DataFlash chips (revisions C and D) support 128 bytes of | ||
78 | one-time-programmable (OTP) data. The first half may be written | ||
79 | (once) with up to 64 bytes of data, such as a serial number or | ||
80 | other key product data. The second half is programmed with a | ||
81 | unique-to-each-chip bit pattern at the factory. | ||
82 | |||
62 | config MTD_M25P80 | 83 | config MTD_M25P80 |
63 | tristate "Support most SPI Flash chips (AT26DF, M25P, W25X, ...)" | 84 | tristate "Support most SPI Flash chips (AT26DF, M25P, W25X, ...)" |
64 | depends on SPI_MASTER && EXPERIMENTAL | 85 | depends on SPI_MASTER && EXPERIMENTAL |
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index b35c3333e210..76a76751da36 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */ | 39 | #define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */ |
40 | #define OPCODE_BE_4K 0x20 /* Erase 4KiB block */ | 40 | #define OPCODE_BE_4K 0x20 /* Erase 4KiB block */ |
41 | #define OPCODE_BE_32K 0x52 /* Erase 32KiB block */ | 41 | #define OPCODE_BE_32K 0x52 /* Erase 32KiB block */ |
42 | #define OPCODE_BE 0xc7 /* Erase whole flash block */ | ||
42 | #define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */ | 43 | #define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */ |
43 | #define OPCODE_RDID 0x9f /* Read JEDEC ID */ | 44 | #define OPCODE_RDID 0x9f /* Read JEDEC ID */ |
44 | 45 | ||
@@ -161,6 +162,31 @@ static int wait_till_ready(struct m25p *flash) | |||
161 | return 1; | 162 | return 1; |
162 | } | 163 | } |
163 | 164 | ||
165 | /* | ||
166 | * Erase the whole flash memory | ||
167 | * | ||
168 | * Returns 0 if successful, non-zero otherwise. | ||
169 | */ | ||
170 | static int erase_block(struct m25p *flash) | ||
171 | { | ||
172 | DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %dKiB\n", | ||
173 | flash->spi->dev.bus_id, __func__, | ||
174 | flash->mtd.size / 1024); | ||
175 | |||
176 | /* Wait until finished previous write command. */ | ||
177 | if (wait_till_ready(flash)) | ||
178 | return 1; | ||
179 | |||
180 | /* Send write enable, then erase commands. */ | ||
181 | write_enable(flash); | ||
182 | |||
183 | /* Set up command buffer. */ | ||
184 | flash->command[0] = OPCODE_BE; | ||
185 | |||
186 | spi_write(flash->spi, flash->command, 1); | ||
187 | |||
188 | return 0; | ||
189 | } | ||
164 | 190 | ||
165 | /* | 191 | /* |
166 | * Erase one sector of flash memory at offset ``offset'' which is any | 192 | * Erase one sector of flash memory at offset ``offset'' which is any |
@@ -229,15 +255,21 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
229 | */ | 255 | */ |
230 | 256 | ||
231 | /* now erase those sectors */ | 257 | /* now erase those sectors */ |
232 | while (len) { | 258 | if (len == flash->mtd.size && erase_block(flash)) { |
233 | if (erase_sector(flash, addr)) { | 259 | instr->state = MTD_ERASE_FAILED; |
234 | instr->state = MTD_ERASE_FAILED; | 260 | mutex_unlock(&flash->lock); |
235 | mutex_unlock(&flash->lock); | 261 | return -EIO; |
236 | return -EIO; | 262 | } else { |
237 | } | 263 | while (len) { |
264 | if (erase_sector(flash, addr)) { | ||
265 | instr->state = MTD_ERASE_FAILED; | ||
266 | mutex_unlock(&flash->lock); | ||
267 | return -EIO; | ||
268 | } | ||
238 | 269 | ||
239 | addr += mtd->erasesize; | 270 | addr += mtd->erasesize; |
240 | len -= mtd->erasesize; | 271 | len -= mtd->erasesize; |
272 | } | ||
241 | } | 273 | } |
242 | 274 | ||
243 | mutex_unlock(&flash->lock); | 275 | mutex_unlock(&flash->lock); |
@@ -437,6 +469,7 @@ struct flash_info { | |||
437 | * then a two byte device id. | 469 | * then a two byte device id. |
438 | */ | 470 | */ |
439 | u32 jedec_id; | 471 | u32 jedec_id; |
472 | u16 ext_id; | ||
440 | 473 | ||
441 | /* The size listed here is what works with OPCODE_SE, which isn't | 474 | /* The size listed here is what works with OPCODE_SE, which isn't |
442 | * necessarily called a "sector" by the vendor. | 475 | * necessarily called a "sector" by the vendor. |
@@ -456,72 +489,75 @@ struct flash_info { | |||
456 | static struct flash_info __devinitdata m25p_data [] = { | 489 | static struct flash_info __devinitdata m25p_data [] = { |
457 | 490 | ||
458 | /* Atmel -- some are (confusingly) marketed as "DataFlash" */ | 491 | /* Atmel -- some are (confusingly) marketed as "DataFlash" */ |
459 | { "at25fs010", 0x1f6601, 32 * 1024, 4, SECT_4K, }, | 492 | { "at25fs010", 0x1f6601, 0, 32 * 1024, 4, SECT_4K, }, |
460 | { "at25fs040", 0x1f6604, 64 * 1024, 8, SECT_4K, }, | 493 | { "at25fs040", 0x1f6604, 0, 64 * 1024, 8, SECT_4K, }, |
461 | 494 | ||
462 | { "at25df041a", 0x1f4401, 64 * 1024, 8, SECT_4K, }, | 495 | { "at25df041a", 0x1f4401, 0, 64 * 1024, 8, SECT_4K, }, |
463 | { "at25df641", 0x1f4800, 64 * 1024, 128, SECT_4K, }, | 496 | { "at25df641", 0x1f4800, 0, 64 * 1024, 128, SECT_4K, }, |
464 | 497 | ||
465 | { "at26f004", 0x1f0400, 64 * 1024, 8, SECT_4K, }, | 498 | { "at26f004", 0x1f0400, 0, 64 * 1024, 8, SECT_4K, }, |
466 | { "at26df081a", 0x1f4501, 64 * 1024, 16, SECT_4K, }, | 499 | { "at26df081a", 0x1f4501, 0, 64 * 1024, 16, SECT_4K, }, |
467 | { "at26df161a", 0x1f4601, 64 * 1024, 32, SECT_4K, }, | 500 | { "at26df161a", 0x1f4601, 0, 64 * 1024, 32, SECT_4K, }, |
468 | { "at26df321", 0x1f4701, 64 * 1024, 64, SECT_4K, }, | 501 | { "at26df321", 0x1f4701, 0, 64 * 1024, 64, SECT_4K, }, |
469 | 502 | ||
470 | /* Spansion -- single (large) sector size only, at least | 503 | /* Spansion -- single (large) sector size only, at least |
471 | * for the chips listed here (without boot sectors). | 504 | * for the chips listed here (without boot sectors). |
472 | */ | 505 | */ |
473 | { "s25sl004a", 0x010212, 64 * 1024, 8, }, | 506 | { "s25sl004a", 0x010212, 0, 64 * 1024, 8, }, |
474 | { "s25sl008a", 0x010213, 64 * 1024, 16, }, | 507 | { "s25sl008a", 0x010213, 0, 64 * 1024, 16, }, |
475 | { "s25sl016a", 0x010214, 64 * 1024, 32, }, | 508 | { "s25sl016a", 0x010214, 0, 64 * 1024, 32, }, |
476 | { "s25sl032a", 0x010215, 64 * 1024, 64, }, | 509 | { "s25sl032a", 0x010215, 0, 64 * 1024, 64, }, |
477 | { "s25sl064a", 0x010216, 64 * 1024, 128, }, | 510 | { "s25sl064a", 0x010216, 0, 64 * 1024, 128, }, |
511 | { "s25sl12800", 0x012018, 0x0300, 256 * 1024, 64, }, | ||
512 | { "s25sl12801", 0x012018, 0x0301, 64 * 1024, 256, }, | ||
478 | 513 | ||
479 | /* SST -- large erase sizes are "overlays", "sectors" are 4K */ | 514 | /* SST -- large erase sizes are "overlays", "sectors" are 4K */ |
480 | { "sst25vf040b", 0xbf258d, 64 * 1024, 8, SECT_4K, }, | 515 | { "sst25vf040b", 0xbf258d, 0, 64 * 1024, 8, SECT_4K, }, |
481 | { "sst25vf080b", 0xbf258e, 64 * 1024, 16, SECT_4K, }, | 516 | { "sst25vf080b", 0xbf258e, 0, 64 * 1024, 16, SECT_4K, }, |
482 | { "sst25vf016b", 0xbf2541, 64 * 1024, 32, SECT_4K, }, | 517 | { "sst25vf016b", 0xbf2541, 0, 64 * 1024, 32, SECT_4K, }, |
483 | { "sst25vf032b", 0xbf254a, 64 * 1024, 64, SECT_4K, }, | 518 | { "sst25vf032b", 0xbf254a, 0, 64 * 1024, 64, SECT_4K, }, |
484 | 519 | ||
485 | /* ST Microelectronics -- newer production may have feature updates */ | 520 | /* ST Microelectronics -- newer production may have feature updates */ |
486 | { "m25p05", 0x202010, 32 * 1024, 2, }, | 521 | { "m25p05", 0x202010, 0, 32 * 1024, 2, }, |
487 | { "m25p10", 0x202011, 32 * 1024, 4, }, | 522 | { "m25p10", 0x202011, 0, 32 * 1024, 4, }, |
488 | { "m25p20", 0x202012, 64 * 1024, 4, }, | 523 | { "m25p20", 0x202012, 0, 64 * 1024, 4, }, |
489 | { "m25p40", 0x202013, 64 * 1024, 8, }, | 524 | { "m25p40", 0x202013, 0, 64 * 1024, 8, }, |
490 | { "m25p80", 0, 64 * 1024, 16, }, | 525 | { "m25p80", 0, 0, 64 * 1024, 16, }, |
491 | { "m25p16", 0x202015, 64 * 1024, 32, }, | 526 | { "m25p16", 0x202015, 0, 64 * 1024, 32, }, |
492 | { "m25p32", 0x202016, 64 * 1024, 64, }, | 527 | { "m25p32", 0x202016, 0, 64 * 1024, 64, }, |
493 | { "m25p64", 0x202017, 64 * 1024, 128, }, | 528 | { "m25p64", 0x202017, 0, 64 * 1024, 128, }, |
494 | { "m25p128", 0x202018, 256 * 1024, 64, }, | 529 | { "m25p128", 0x202018, 0, 256 * 1024, 64, }, |
495 | 530 | ||
496 | { "m45pe80", 0x204014, 64 * 1024, 16, }, | 531 | { "m45pe80", 0x204014, 0, 64 * 1024, 16, }, |
497 | { "m45pe16", 0x204015, 64 * 1024, 32, }, | 532 | { "m45pe16", 0x204015, 0, 64 * 1024, 32, }, |
498 | 533 | ||
499 | { "m25pe80", 0x208014, 64 * 1024, 16, }, | 534 | { "m25pe80", 0x208014, 0, 64 * 1024, 16, }, |
500 | { "m25pe16", 0x208015, 64 * 1024, 32, SECT_4K, }, | 535 | { "m25pe16", 0x208015, 0, 64 * 1024, 32, SECT_4K, }, |
501 | 536 | ||
502 | /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ | 537 | /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ |
503 | { "w25x10", 0xef3011, 64 * 1024, 2, SECT_4K, }, | 538 | { "w25x10", 0xef3011, 0, 64 * 1024, 2, SECT_4K, }, |
504 | { "w25x20", 0xef3012, 64 * 1024, 4, SECT_4K, }, | 539 | { "w25x20", 0xef3012, 0, 64 * 1024, 4, SECT_4K, }, |
505 | { "w25x40", 0xef3013, 64 * 1024, 8, SECT_4K, }, | 540 | { "w25x40", 0xef3013, 0, 64 * 1024, 8, SECT_4K, }, |
506 | { "w25x80", 0xef3014, 64 * 1024, 16, SECT_4K, }, | 541 | { "w25x80", 0xef3014, 0, 64 * 1024, 16, SECT_4K, }, |
507 | { "w25x16", 0xef3015, 64 * 1024, 32, SECT_4K, }, | 542 | { "w25x16", 0xef3015, 0, 64 * 1024, 32, SECT_4K, }, |
508 | { "w25x32", 0xef3016, 64 * 1024, 64, SECT_4K, }, | 543 | { "w25x32", 0xef3016, 0, 64 * 1024, 64, SECT_4K, }, |
509 | { "w25x64", 0xef3017, 64 * 1024, 128, SECT_4K, }, | 544 | { "w25x64", 0xef3017, 0, 64 * 1024, 128, SECT_4K, }, |
510 | }; | 545 | }; |
511 | 546 | ||
512 | static struct flash_info *__devinit jedec_probe(struct spi_device *spi) | 547 | static struct flash_info *__devinit jedec_probe(struct spi_device *spi) |
513 | { | 548 | { |
514 | int tmp; | 549 | int tmp; |
515 | u8 code = OPCODE_RDID; | 550 | u8 code = OPCODE_RDID; |
516 | u8 id[3]; | 551 | u8 id[5]; |
517 | u32 jedec; | 552 | u32 jedec; |
553 | u16 ext_jedec; | ||
518 | struct flash_info *info; | 554 | struct flash_info *info; |
519 | 555 | ||
520 | /* JEDEC also defines an optional "extended device information" | 556 | /* JEDEC also defines an optional "extended device information" |
521 | * string for after vendor-specific data, after the three bytes | 557 | * string for after vendor-specific data, after the three bytes |
522 | * we use here. Supporting some chips might require using it. | 558 | * we use here. Supporting some chips might require using it. |
523 | */ | 559 | */ |
524 | tmp = spi_write_then_read(spi, &code, 1, id, 3); | 560 | tmp = spi_write_then_read(spi, &code, 1, id, 5); |
525 | if (tmp < 0) { | 561 | if (tmp < 0) { |
526 | DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n", | 562 | DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n", |
527 | spi->dev.bus_id, tmp); | 563 | spi->dev.bus_id, tmp); |
@@ -533,10 +569,14 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi) | |||
533 | jedec = jedec << 8; | 569 | jedec = jedec << 8; |
534 | jedec |= id[2]; | 570 | jedec |= id[2]; |
535 | 571 | ||
572 | ext_jedec = id[3] << 8 | id[4]; | ||
573 | |||
536 | for (tmp = 0, info = m25p_data; | 574 | for (tmp = 0, info = m25p_data; |
537 | tmp < ARRAY_SIZE(m25p_data); | 575 | tmp < ARRAY_SIZE(m25p_data); |
538 | tmp++, info++) { | 576 | tmp++, info++) { |
539 | if (info->jedec_id == jedec) | 577 | if (info->jedec_id == jedec) |
578 | if (ext_jedec != 0 && info->ext_id != ext_jedec) | ||
579 | continue; | ||
540 | return info; | 580 | return info; |
541 | } | 581 | } |
542 | dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec); | 582 | dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec); |
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index 8bd0dea6885f..6dd9aff8bb2d 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c | |||
@@ -30,12 +30,10 @@ | |||
30 | * doesn't (yet) use these for any kind of i/o overlap or prefetching. | 30 | * doesn't (yet) use these for any kind of i/o overlap or prefetching. |
31 | * | 31 | * |
32 | * Sometimes DataFlash is packaged in MMC-format cards, although the | 32 | * Sometimes DataFlash is packaged in MMC-format cards, although the |
33 | * MMC stack can't use SPI (yet), or distinguish between MMC and DataFlash | 33 | * MMC stack can't (yet?) distinguish between MMC and DataFlash |
34 | * protocols during enumeration. | 34 | * protocols during enumeration. |
35 | */ | 35 | */ |
36 | 36 | ||
37 | #define CONFIG_DATAFLASH_WRITE_VERIFY | ||
38 | |||
39 | /* reads can bypass the buffers */ | 37 | /* reads can bypass the buffers */ |
40 | #define OP_READ_CONTINUOUS 0xE8 | 38 | #define OP_READ_CONTINUOUS 0xE8 |
41 | #define OP_READ_PAGE 0xD2 | 39 | #define OP_READ_PAGE 0xD2 |
@@ -80,7 +78,8 @@ | |||
80 | */ | 78 | */ |
81 | #define OP_READ_ID 0x9F | 79 | #define OP_READ_ID 0x9F |
82 | #define OP_READ_SECURITY 0x77 | 80 | #define OP_READ_SECURITY 0x77 |
83 | #define OP_WRITE_SECURITY 0x9A /* OTP bits */ | 81 | #define OP_WRITE_SECURITY_REVC 0x9A |
82 | #define OP_WRITE_SECURITY 0x9B /* revision D */ | ||
84 | 83 | ||
85 | 84 | ||
86 | struct dataflash { | 85 | struct dataflash { |
@@ -402,7 +401,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
402 | (void) dataflash_waitready(priv->spi); | 401 | (void) dataflash_waitready(priv->spi); |
403 | 402 | ||
404 | 403 | ||
405 | #ifdef CONFIG_DATAFLASH_WRITE_VERIFY | 404 | #ifdef CONFIG_MTD_DATAFLASH_VERIFY_WRITE |
406 | 405 | ||
407 | /* (3) Compare to Buffer1 */ | 406 | /* (3) Compare to Buffer1 */ |
408 | addr = pageaddr << priv->page_offset; | 407 | addr = pageaddr << priv->page_offset; |
@@ -431,7 +430,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
431 | } else | 430 | } else |
432 | status = 0; | 431 | status = 0; |
433 | 432 | ||
434 | #endif /* CONFIG_DATAFLASH_WRITE_VERIFY */ | 433 | #endif /* CONFIG_MTD_DATAFLASH_VERIFY_WRITE */ |
435 | 434 | ||
436 | remaining = remaining - writelen; | 435 | remaining = remaining - writelen; |
437 | pageaddr++; | 436 | pageaddr++; |
@@ -451,16 +450,192 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
451 | 450 | ||
452 | /* ......................................................................... */ | 451 | /* ......................................................................... */ |
453 | 452 | ||
453 | #ifdef CONFIG_MTD_DATAFLASH_OTP | ||
454 | |||
455 | static int dataflash_get_otp_info(struct mtd_info *mtd, | ||
456 | struct otp_info *info, size_t len) | ||
457 | { | ||
458 | /* Report both blocks as identical: bytes 0..64, locked. | ||
459 | * Unless the user block changed from all-ones, we can't | ||
460 | * tell whether it's still writable; so we assume it isn't. | ||
461 | */ | ||
462 | info->start = 0; | ||
463 | info->length = 64; | ||
464 | info->locked = 1; | ||
465 | return sizeof(*info); | ||
466 | } | ||
467 | |||
468 | static ssize_t otp_read(struct spi_device *spi, unsigned base, | ||
469 | uint8_t *buf, loff_t off, size_t len) | ||
470 | { | ||
471 | struct spi_message m; | ||
472 | size_t l; | ||
473 | uint8_t *scratch; | ||
474 | struct spi_transfer t; | ||
475 | int status; | ||
476 | |||
477 | if (off > 64) | ||
478 | return -EINVAL; | ||
479 | |||
480 | if ((off + len) > 64) | ||
481 | len = 64 - off; | ||
482 | if (len == 0) | ||
483 | return len; | ||
484 | |||
485 | spi_message_init(&m); | ||
486 | |||
487 | l = 4 + base + off + len; | ||
488 | scratch = kzalloc(l, GFP_KERNEL); | ||
489 | if (!scratch) | ||
490 | return -ENOMEM; | ||
491 | |||
492 | /* OUT: OP_READ_SECURITY, 3 don't-care bytes, zeroes | ||
493 | * IN: ignore 4 bytes, data bytes 0..N (max 127) | ||
494 | */ | ||
495 | scratch[0] = OP_READ_SECURITY; | ||
496 | |||
497 | memset(&t, 0, sizeof t); | ||
498 | t.tx_buf = scratch; | ||
499 | t.rx_buf = scratch; | ||
500 | t.len = l; | ||
501 | spi_message_add_tail(&t, &m); | ||
502 | |||
503 | dataflash_waitready(spi); | ||
504 | |||
505 | status = spi_sync(spi, &m); | ||
506 | if (status >= 0) { | ||
507 | memcpy(buf, scratch + 4 + base + off, len); | ||
508 | status = len; | ||
509 | } | ||
510 | |||
511 | kfree(scratch); | ||
512 | return status; | ||
513 | } | ||
514 | |||
515 | static int dataflash_read_fact_otp(struct mtd_info *mtd, | ||
516 | loff_t from, size_t len, size_t *retlen, u_char *buf) | ||
517 | { | ||
518 | struct dataflash *priv = (struct dataflash *)mtd->priv; | ||
519 | int status; | ||
520 | |||
521 | /* 64 bytes, from 0..63 ... start at 64 on-chip */ | ||
522 | mutex_lock(&priv->lock); | ||
523 | status = otp_read(priv->spi, 64, buf, from, len); | ||
524 | mutex_unlock(&priv->lock); | ||
525 | |||
526 | if (status < 0) | ||
527 | return status; | ||
528 | *retlen = status; | ||
529 | return 0; | ||
530 | } | ||
531 | |||
532 | static int dataflash_read_user_otp(struct mtd_info *mtd, | ||
533 | loff_t from, size_t len, size_t *retlen, u_char *buf) | ||
534 | { | ||
535 | struct dataflash *priv = (struct dataflash *)mtd->priv; | ||
536 | int status; | ||
537 | |||
538 | /* 64 bytes, from 0..63 ... start at 0 on-chip */ | ||
539 | mutex_lock(&priv->lock); | ||
540 | status = otp_read(priv->spi, 0, buf, from, len); | ||
541 | mutex_unlock(&priv->lock); | ||
542 | |||
543 | if (status < 0) | ||
544 | return status; | ||
545 | *retlen = status; | ||
546 | return 0; | ||
547 | } | ||
548 | |||
549 | static int dataflash_write_user_otp(struct mtd_info *mtd, | ||
550 | loff_t from, size_t len, size_t *retlen, u_char *buf) | ||
551 | { | ||
552 | struct spi_message m; | ||
553 | const size_t l = 4 + 64; | ||
554 | uint8_t *scratch; | ||
555 | struct spi_transfer t; | ||
556 | struct dataflash *priv = (struct dataflash *)mtd->priv; | ||
557 | int status; | ||
558 | |||
559 | if (len > 64) | ||
560 | return -EINVAL; | ||
561 | |||
562 | /* Strictly speaking, we *could* truncate the write ... but | ||
563 | * let's not do that for the only write that's ever possible. | ||
564 | */ | ||
565 | if ((from + len) > 64) | ||
566 | return -EINVAL; | ||
567 | |||
568 | /* OUT: OP_WRITE_SECURITY, 3 zeroes, 64 data-or-zero bytes | ||
569 | * IN: ignore all | ||
570 | */ | ||
571 | scratch = kzalloc(l, GFP_KERNEL); | ||
572 | if (!scratch) | ||
573 | return -ENOMEM; | ||
574 | scratch[0] = OP_WRITE_SECURITY; | ||
575 | memcpy(scratch + 4 + from, buf, len); | ||
576 | |||
577 | spi_message_init(&m); | ||
578 | |||
579 | memset(&t, 0, sizeof t); | ||
580 | t.tx_buf = scratch; | ||
581 | t.len = l; | ||
582 | spi_message_add_tail(&t, &m); | ||
583 | |||
584 | /* Write the OTP bits, if they've not yet been written. | ||
585 | * This modifies SRAM buffer1. | ||
586 | */ | ||
587 | mutex_lock(&priv->lock); | ||
588 | dataflash_waitready(priv->spi); | ||
589 | status = spi_sync(priv->spi, &m); | ||
590 | mutex_unlock(&priv->lock); | ||
591 | |||
592 | kfree(scratch); | ||
593 | |||
594 | if (status >= 0) { | ||
595 | status = 0; | ||
596 | *retlen = len; | ||
597 | } | ||
598 | return status; | ||
599 | } | ||
600 | |||
601 | static char *otp_setup(struct mtd_info *device, char revision) | ||
602 | { | ||
603 | device->get_fact_prot_info = dataflash_get_otp_info; | ||
604 | device->read_fact_prot_reg = dataflash_read_fact_otp; | ||
605 | device->get_user_prot_info = dataflash_get_otp_info; | ||
606 | device->read_user_prot_reg = dataflash_read_user_otp; | ||
607 | |||
608 | /* rev c parts (at45db321c and at45db1281 only!) use a | ||
609 | * different write procedure; not (yet?) implemented. | ||
610 | */ | ||
611 | if (revision > 'c') | ||
612 | device->write_user_prot_reg = dataflash_write_user_otp; | ||
613 | |||
614 | return ", OTP"; | ||
615 | } | ||
616 | |||
617 | #else | ||
618 | |||
619 | static char *otp_setup(struct mtd_info *device, char revision) | ||
620 | { | ||
621 | return " (OTP)"; | ||
622 | } | ||
623 | |||
624 | #endif | ||
625 | |||
626 | /* ......................................................................... */ | ||
627 | |||
454 | /* | 628 | /* |
455 | * Register DataFlash device with MTD subsystem. | 629 | * Register DataFlash device with MTD subsystem. |
456 | */ | 630 | */ |
457 | static int __devinit | 631 | static int __devinit |
458 | add_dataflash(struct spi_device *spi, char *name, | 632 | add_dataflash_otp(struct spi_device *spi, char *name, |
459 | int nr_pages, int pagesize, int pageoffset) | 633 | int nr_pages, int pagesize, int pageoffset, char revision) |
460 | { | 634 | { |
461 | struct dataflash *priv; | 635 | struct dataflash *priv; |
462 | struct mtd_info *device; | 636 | struct mtd_info *device; |
463 | struct flash_platform_data *pdata = spi->dev.platform_data; | 637 | struct flash_platform_data *pdata = spi->dev.platform_data; |
638 | char *otp_tag = ""; | ||
464 | 639 | ||
465 | priv = kzalloc(sizeof *priv, GFP_KERNEL); | 640 | priv = kzalloc(sizeof *priv, GFP_KERNEL); |
466 | if (!priv) | 641 | if (!priv) |
@@ -489,8 +664,12 @@ add_dataflash(struct spi_device *spi, char *name, | |||
489 | device->write = dataflash_write; | 664 | device->write = dataflash_write; |
490 | device->priv = priv; | 665 | device->priv = priv; |
491 | 666 | ||
492 | dev_info(&spi->dev, "%s (%d KBytes) pagesize %d bytes\n", | 667 | if (revision >= 'c') |
493 | name, DIV_ROUND_UP(device->size, 1024), pagesize); | 668 | otp_tag = otp_setup(device, revision); |
669 | |||
670 | dev_info(&spi->dev, "%s (%d KBytes) pagesize %d bytes%s\n", | ||
671 | name, DIV_ROUND_UP(device->size, 1024), | ||
672 | pagesize, otp_tag); | ||
494 | dev_set_drvdata(&spi->dev, priv); | 673 | dev_set_drvdata(&spi->dev, priv); |
495 | 674 | ||
496 | if (mtd_has_partitions()) { | 675 | if (mtd_has_partitions()) { |
@@ -519,6 +698,14 @@ add_dataflash(struct spi_device *spi, char *name, | |||
519 | return add_mtd_device(device) == 1 ? -ENODEV : 0; | 698 | return add_mtd_device(device) == 1 ? -ENODEV : 0; |
520 | } | 699 | } |
521 | 700 | ||
701 | static inline int __devinit | ||
702 | add_dataflash(struct spi_device *spi, char *name, | ||
703 | int nr_pages, int pagesize, int pageoffset) | ||
704 | { | ||
705 | return add_dataflash_otp(spi, name, nr_pages, pagesize, | ||
706 | pageoffset, 0); | ||
707 | } | ||
708 | |||
522 | struct flash_info { | 709 | struct flash_info { |
523 | char *name; | 710 | char *name; |
524 | 711 | ||
@@ -664,13 +851,16 @@ static int __devinit dataflash_probe(struct spi_device *spi) | |||
664 | * Try to detect dataflash by JEDEC ID. | 851 | * Try to detect dataflash by JEDEC ID. |
665 | * If it succeeds we know we have either a C or D part. | 852 | * If it succeeds we know we have either a C or D part. |
666 | * D will support power of 2 pagesize option. | 853 | * D will support power of 2 pagesize option. |
854 | * Both support the security register, though with different | ||
855 | * write procedures. | ||
667 | */ | 856 | */ |
668 | info = jedec_probe(spi); | 857 | info = jedec_probe(spi); |
669 | if (IS_ERR(info)) | 858 | if (IS_ERR(info)) |
670 | return PTR_ERR(info); | 859 | return PTR_ERR(info); |
671 | if (info != NULL) | 860 | if (info != NULL) |
672 | return add_dataflash(spi, info->name, info->nr_pages, | 861 | return add_dataflash_otp(spi, info->name, info->nr_pages, |
673 | info->pagesize, info->pageoffset); | 862 | info->pagesize, info->pageoffset, |
863 | (info->flags & SUP_POW2PS) ? 'd' : 'c'); | ||
674 | 864 | ||
675 | /* | 865 | /* |
676 | * Older chips support only legacy commands, identifing | 866 | * Older chips support only legacy commands, identifing |
diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c index c4f9d3378b24..50ce13887f63 100644 --- a/drivers/mtd/inftlcore.c +++ b/drivers/mtd/inftlcore.c | |||
@@ -388,6 +388,10 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned | |||
388 | if (thisEUN == targetEUN) | 388 | if (thisEUN == targetEUN) |
389 | break; | 389 | break; |
390 | 390 | ||
391 | /* Unlink the last block from the chain. */ | ||
392 | inftl->PUtable[prevEUN] = BLOCK_NIL; | ||
393 | |||
394 | /* Now try to erase it. */ | ||
391 | if (INFTL_formatblock(inftl, thisEUN) < 0) { | 395 | if (INFTL_formatblock(inftl, thisEUN) < 0) { |
392 | /* | 396 | /* |
393 | * Could not erase : mark block as reserved. | 397 | * Could not erase : mark block as reserved. |
@@ -396,7 +400,6 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned | |||
396 | } else { | 400 | } else { |
397 | /* Correctly erased : mark it as free */ | 401 | /* Correctly erased : mark it as free */ |
398 | inftl->PUtable[thisEUN] = BLOCK_FREE; | 402 | inftl->PUtable[thisEUN] = BLOCK_FREE; |
399 | inftl->PUtable[prevEUN] = BLOCK_NIL; | ||
400 | inftl->numfreeEUNs++; | 403 | inftl->numfreeEUNs++; |
401 | } | 404 | } |
402 | } | 405 | } |
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index df8e00bba07b..5ea169362164 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig | |||
@@ -332,30 +332,6 @@ config MTD_CFI_FLAGADM | |||
332 | Mapping for the Flaga digital module. If you don't have one, ignore | 332 | Mapping for the Flaga digital module. If you don't have one, ignore |
333 | this setting. | 333 | this setting. |
334 | 334 | ||
335 | config MTD_WALNUT | ||
336 | tristate "Flash device mapped on IBM 405GP Walnut" | ||
337 | depends on MTD_JEDECPROBE && WALNUT && !PPC_MERGE | ||
338 | help | ||
339 | This enables access routines for the flash chips on the IBM 405GP | ||
340 | Walnut board. If you have one of these boards and would like to | ||
341 | use the flash chips on it, say 'Y'. | ||
342 | |||
343 | config MTD_EBONY | ||
344 | tristate "Flash devices mapped on IBM 440GP Ebony" | ||
345 | depends on MTD_JEDECPROBE && EBONY && !PPC_MERGE | ||
346 | help | ||
347 | This enables access routines for the flash chips on the IBM 440GP | ||
348 | Ebony board. If you have one of these boards and would like to | ||
349 | use the flash chips on it, say 'Y'. | ||
350 | |||
351 | config MTD_OCOTEA | ||
352 | tristate "Flash devices mapped on IBM 440GX Ocotea" | ||
353 | depends on MTD_CFI && OCOTEA && !PPC_MERGE | ||
354 | help | ||
355 | This enables access routines for the flash chips on the IBM 440GX | ||
356 | Ocotea board. If you have one of these boards and would like to | ||
357 | use the flash chips on it, say 'Y'. | ||
358 | |||
359 | config MTD_REDWOOD | 335 | config MTD_REDWOOD |
360 | tristate "CFI Flash devices mapped on IBM Redwood" | 336 | tristate "CFI Flash devices mapped on IBM Redwood" |
361 | depends on MTD_CFI && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 ) | 337 | depends on MTD_CFI && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 ) |
@@ -458,13 +434,6 @@ config MTD_CEIVA | |||
458 | PhotoMax Digital Picture Frame. | 434 | PhotoMax Digital Picture Frame. |
459 | If you have such a device, say 'Y'. | 435 | If you have such a device, say 'Y'. |
460 | 436 | ||
461 | config MTD_NOR_TOTO | ||
462 | tristate "NOR Flash device on TOTO board" | ||
463 | depends on ARCH_OMAP && OMAP_TOTO | ||
464 | help | ||
465 | This enables access to the NOR flash on the Texas Instruments | ||
466 | TOTO board. | ||
467 | |||
468 | config MTD_H720X | 437 | config MTD_H720X |
469 | tristate "Hynix evaluation board mappings" | 438 | tristate "Hynix evaluation board mappings" |
470 | depends on MTD_CFI && ( ARCH_H7201 || ARCH_H7202 ) | 439 | depends on MTD_CFI && ( ARCH_H7201 || ARCH_H7202 ) |
@@ -522,7 +491,7 @@ config MTD_BFIN_ASYNC | |||
522 | 491 | ||
523 | config MTD_UCLINUX | 492 | config MTD_UCLINUX |
524 | tristate "Generic uClinux RAM/ROM filesystem support" | 493 | tristate "Generic uClinux RAM/ROM filesystem support" |
525 | depends on MTD_PARTITIONS && !MMU | 494 | depends on MTD_PARTITIONS && MTD_RAM && !MMU |
526 | help | 495 | help |
527 | Map driver to support image based filesystems for uClinux. | 496 | Map driver to support image based filesystems for uClinux. |
528 | 497 | ||
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index 6cda6df973e5..6d9ba35caf11 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile | |||
@@ -50,12 +50,8 @@ obj-$(CONFIG_MTD_REDWOOD) += redwood.o | |||
50 | obj-$(CONFIG_MTD_UCLINUX) += uclinux.o | 50 | obj-$(CONFIG_MTD_UCLINUX) += uclinux.o |
51 | obj-$(CONFIG_MTD_NETtel) += nettel.o | 51 | obj-$(CONFIG_MTD_NETtel) += nettel.o |
52 | obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o | 52 | obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o |
53 | obj-$(CONFIG_MTD_EBONY) += ebony.o | ||
54 | obj-$(CONFIG_MTD_OCOTEA) += ocotea.o | ||
55 | obj-$(CONFIG_MTD_WALNUT) += walnut.o | ||
56 | obj-$(CONFIG_MTD_H720X) += h720x-flash.o | 53 | obj-$(CONFIG_MTD_H720X) += h720x-flash.o |
57 | obj-$(CONFIG_MTD_SBC8240) += sbc8240.o | 54 | obj-$(CONFIG_MTD_SBC8240) += sbc8240.o |
58 | obj-$(CONFIG_MTD_NOR_TOTO) += omap-toto-flash.o | ||
59 | obj-$(CONFIG_MTD_IXP4XX) += ixp4xx.o | 55 | obj-$(CONFIG_MTD_IXP4XX) += ixp4xx.o |
60 | obj-$(CONFIG_MTD_IXP2000) += ixp2000.o | 56 | obj-$(CONFIG_MTD_IXP2000) += ixp2000.o |
61 | obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o | 57 | obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o |
diff --git a/drivers/mtd/maps/ebony.c b/drivers/mtd/maps/ebony.c deleted file mode 100644 index d92b7c70d3ed..000000000000 --- a/drivers/mtd/maps/ebony.c +++ /dev/null | |||
@@ -1,163 +0,0 @@ | |||
1 | /* | ||
2 | * Mapping for Ebony user flash | ||
3 | * | ||
4 | * Matt Porter <mporter@kernel.crashing.org> | ||
5 | * | ||
6 | * Copyright 2002-2004 MontaVista Software Inc. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/mtd/mtd.h> | ||
19 | #include <linux/mtd/map.h> | ||
20 | #include <linux/mtd/partitions.h> | ||
21 | #include <asm/io.h> | ||
22 | #include <asm/ibm44x.h> | ||
23 | #include <platforms/4xx/ebony.h> | ||
24 | |||
25 | static struct mtd_info *flash; | ||
26 | |||
27 | static struct map_info ebony_small_map = { | ||
28 | .name = "Ebony small flash", | ||
29 | .size = EBONY_SMALL_FLASH_SIZE, | ||
30 | .bankwidth = 1, | ||
31 | }; | ||
32 | |||
33 | static struct map_info ebony_large_map = { | ||
34 | .name = "Ebony large flash", | ||
35 | .size = EBONY_LARGE_FLASH_SIZE, | ||
36 | .bankwidth = 1, | ||
37 | }; | ||
38 | |||
39 | static struct mtd_partition ebony_small_partitions[] = { | ||
40 | { | ||
41 | .name = "OpenBIOS", | ||
42 | .offset = 0x0, | ||
43 | .size = 0x80000, | ||
44 | } | ||
45 | }; | ||
46 | |||
47 | static struct mtd_partition ebony_large_partitions[] = { | ||
48 | { | ||
49 | .name = "fs", | ||
50 | .offset = 0, | ||
51 | .size = 0x380000, | ||
52 | }, | ||
53 | { | ||
54 | .name = "firmware", | ||
55 | .offset = 0x380000, | ||
56 | .size = 0x80000, | ||
57 | } | ||
58 | }; | ||
59 | |||
60 | int __init init_ebony(void) | ||
61 | { | ||
62 | u8 fpga0_reg; | ||
63 | u8 __iomem *fpga0_adr; | ||
64 | unsigned long long small_flash_base, large_flash_base; | ||
65 | |||
66 | fpga0_adr = ioremap64(EBONY_FPGA_ADDR, 16); | ||
67 | if (!fpga0_adr) | ||
68 | return -ENOMEM; | ||
69 | |||
70 | fpga0_reg = readb(fpga0_adr); | ||
71 | iounmap(fpga0_adr); | ||
72 | |||
73 | if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) && | ||
74 | !EBONY_FLASH_SEL(fpga0_reg)) | ||
75 | small_flash_base = EBONY_SMALL_FLASH_HIGH2; | ||
76 | else if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) && | ||
77 | EBONY_FLASH_SEL(fpga0_reg)) | ||
78 | small_flash_base = EBONY_SMALL_FLASH_HIGH1; | ||
79 | else if (!EBONY_BOOT_SMALL_FLASH(fpga0_reg) && | ||
80 | !EBONY_FLASH_SEL(fpga0_reg)) | ||
81 | small_flash_base = EBONY_SMALL_FLASH_LOW2; | ||
82 | else | ||
83 | small_flash_base = EBONY_SMALL_FLASH_LOW1; | ||
84 | |||
85 | if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) && | ||
86 | !EBONY_ONBRD_FLASH_EN(fpga0_reg)) | ||
87 | large_flash_base = EBONY_LARGE_FLASH_LOW; | ||
88 | else | ||
89 | large_flash_base = EBONY_LARGE_FLASH_HIGH; | ||
90 | |||
91 | ebony_small_map.phys = small_flash_base; | ||
92 | ebony_small_map.virt = ioremap64(small_flash_base, | ||
93 | ebony_small_map.size); | ||
94 | |||
95 | if (!ebony_small_map.virt) { | ||
96 | printk("Failed to ioremap flash\n"); | ||
97 | return -EIO; | ||
98 | } | ||
99 | |||
100 | simple_map_init(&ebony_small_map); | ||
101 | |||
102 | flash = do_map_probe("jedec_probe", &ebony_small_map); | ||
103 | if (flash) { | ||
104 | flash->owner = THIS_MODULE; | ||
105 | add_mtd_partitions(flash, ebony_small_partitions, | ||
106 | ARRAY_SIZE(ebony_small_partitions)); | ||
107 | } else { | ||
108 | printk("map probe failed for flash\n"); | ||
109 | iounmap(ebony_small_map.virt); | ||
110 | return -ENXIO; | ||
111 | } | ||
112 | |||
113 | ebony_large_map.phys = large_flash_base; | ||
114 | ebony_large_map.virt = ioremap64(large_flash_base, | ||
115 | ebony_large_map.size); | ||
116 | |||
117 | if (!ebony_large_map.virt) { | ||
118 | printk("Failed to ioremap flash\n"); | ||
119 | iounmap(ebony_small_map.virt); | ||
120 | return -EIO; | ||
121 | } | ||
122 | |||
123 | simple_map_init(&ebony_large_map); | ||
124 | |||
125 | flash = do_map_probe("jedec_probe", &ebony_large_map); | ||
126 | if (flash) { | ||
127 | flash->owner = THIS_MODULE; | ||
128 | add_mtd_partitions(flash, ebony_large_partitions, | ||
129 | ARRAY_SIZE(ebony_large_partitions)); | ||
130 | } else { | ||
131 | printk("map probe failed for flash\n"); | ||
132 | iounmap(ebony_small_map.virt); | ||
133 | iounmap(ebony_large_map.virt); | ||
134 | return -ENXIO; | ||
135 | } | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static void __exit cleanup_ebony(void) | ||
141 | { | ||
142 | if (flash) { | ||
143 | del_mtd_partitions(flash); | ||
144 | map_destroy(flash); | ||
145 | } | ||
146 | |||
147 | if (ebony_small_map.virt) { | ||
148 | iounmap(ebony_small_map.virt); | ||
149 | ebony_small_map.virt = NULL; | ||
150 | } | ||
151 | |||
152 | if (ebony_large_map.virt) { | ||
153 | iounmap(ebony_large_map.virt); | ||
154 | ebony_large_map.virt = NULL; | ||
155 | } | ||
156 | } | ||
157 | |||
158 | module_init(init_ebony); | ||
159 | module_exit(cleanup_ebony); | ||
160 | |||
161 | MODULE_LICENSE("GPL"); | ||
162 | MODULE_AUTHOR("Matt Porter <mporter@kernel.crashing.org>"); | ||
163 | MODULE_DESCRIPTION("MTD map and partitions for IBM 440GP Ebony boards"); | ||
diff --git a/drivers/mtd/maps/ocotea.c b/drivers/mtd/maps/ocotea.c deleted file mode 100644 index 5522eac8c980..000000000000 --- a/drivers/mtd/maps/ocotea.c +++ /dev/null | |||
@@ -1,154 +0,0 @@ | |||
1 | /* | ||
2 | * Mapping for Ocotea user flash | ||
3 | * | ||
4 | * Matt Porter <mporter@kernel.crashing.org> | ||
5 | * | ||
6 | * Copyright 2002-2004 MontaVista Software Inc. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/mtd/mtd.h> | ||
19 | #include <linux/mtd/map.h> | ||
20 | #include <linux/mtd/partitions.h> | ||
21 | #include <asm/io.h> | ||
22 | #include <asm/ibm44x.h> | ||
23 | #include <platforms/4xx/ocotea.h> | ||
24 | |||
25 | static struct mtd_info *flash; | ||
26 | |||
27 | static struct map_info ocotea_small_map = { | ||
28 | .name = "Ocotea small flash", | ||
29 | .size = OCOTEA_SMALL_FLASH_SIZE, | ||
30 | .buswidth = 1, | ||
31 | }; | ||
32 | |||
33 | static struct map_info ocotea_large_map = { | ||
34 | .name = "Ocotea large flash", | ||
35 | .size = OCOTEA_LARGE_FLASH_SIZE, | ||
36 | .buswidth = 1, | ||
37 | }; | ||
38 | |||
39 | static struct mtd_partition ocotea_small_partitions[] = { | ||
40 | { | ||
41 | .name = "pibs", | ||
42 | .offset = 0x0, | ||
43 | .size = 0x100000, | ||
44 | } | ||
45 | }; | ||
46 | |||
47 | static struct mtd_partition ocotea_large_partitions[] = { | ||
48 | { | ||
49 | .name = "fs", | ||
50 | .offset = 0, | ||
51 | .size = 0x300000, | ||
52 | }, | ||
53 | { | ||
54 | .name = "firmware", | ||
55 | .offset = 0x300000, | ||
56 | .size = 0x100000, | ||
57 | } | ||
58 | }; | ||
59 | |||
60 | int __init init_ocotea(void) | ||
61 | { | ||
62 | u8 fpga0_reg; | ||
63 | u8 *fpga0_adr; | ||
64 | unsigned long long small_flash_base, large_flash_base; | ||
65 | |||
66 | fpga0_adr = ioremap64(OCOTEA_FPGA_ADDR, 16); | ||
67 | if (!fpga0_adr) | ||
68 | return -ENOMEM; | ||
69 | |||
70 | fpga0_reg = readb((unsigned long)fpga0_adr); | ||
71 | iounmap(fpga0_adr); | ||
72 | |||
73 | if (OCOTEA_BOOT_LARGE_FLASH(fpga0_reg)) { | ||
74 | small_flash_base = OCOTEA_SMALL_FLASH_HIGH; | ||
75 | large_flash_base = OCOTEA_LARGE_FLASH_LOW; | ||
76 | } | ||
77 | else { | ||
78 | small_flash_base = OCOTEA_SMALL_FLASH_LOW; | ||
79 | large_flash_base = OCOTEA_LARGE_FLASH_HIGH; | ||
80 | } | ||
81 | |||
82 | ocotea_small_map.phys = small_flash_base; | ||
83 | ocotea_small_map.virt = ioremap64(small_flash_base, | ||
84 | ocotea_small_map.size); | ||
85 | |||
86 | if (!ocotea_small_map.virt) { | ||
87 | printk("Failed to ioremap flash\n"); | ||
88 | return -EIO; | ||
89 | } | ||
90 | |||
91 | simple_map_init(&ocotea_small_map); | ||
92 | |||
93 | flash = do_map_probe("map_rom", &ocotea_small_map); | ||
94 | if (flash) { | ||
95 | flash->owner = THIS_MODULE; | ||
96 | add_mtd_partitions(flash, ocotea_small_partitions, | ||
97 | ARRAY_SIZE(ocotea_small_partitions)); | ||
98 | } else { | ||
99 | printk("map probe failed for flash\n"); | ||
100 | iounmap(ocotea_small_map.virt); | ||
101 | return -ENXIO; | ||
102 | } | ||
103 | |||
104 | ocotea_large_map.phys = large_flash_base; | ||
105 | ocotea_large_map.virt = ioremap64(large_flash_base, | ||
106 | ocotea_large_map.size); | ||
107 | |||
108 | if (!ocotea_large_map.virt) { | ||
109 | printk("Failed to ioremap flash\n"); | ||
110 | iounmap(ocotea_small_map.virt); | ||
111 | return -EIO; | ||
112 | } | ||
113 | |||
114 | simple_map_init(&ocotea_large_map); | ||
115 | |||
116 | flash = do_map_probe("cfi_probe", &ocotea_large_map); | ||
117 | if (flash) { | ||
118 | flash->owner = THIS_MODULE; | ||
119 | add_mtd_partitions(flash, ocotea_large_partitions, | ||
120 | ARRAY_SIZE(ocotea_large_partitions)); | ||
121 | } else { | ||
122 | printk("map probe failed for flash\n"); | ||
123 | iounmap(ocotea_small_map.virt); | ||
124 | iounmap(ocotea_large_map.virt); | ||
125 | return -ENXIO; | ||
126 | } | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static void __exit cleanup_ocotea(void) | ||
132 | { | ||
133 | if (flash) { | ||
134 | del_mtd_partitions(flash); | ||
135 | map_destroy(flash); | ||
136 | } | ||
137 | |||
138 | if (ocotea_small_map.virt) { | ||
139 | iounmap((void *)ocotea_small_map.virt); | ||
140 | ocotea_small_map.virt = 0; | ||
141 | } | ||
142 | |||
143 | if (ocotea_large_map.virt) { | ||
144 | iounmap((void *)ocotea_large_map.virt); | ||
145 | ocotea_large_map.virt = 0; | ||
146 | } | ||
147 | } | ||
148 | |||
149 | module_init(init_ocotea); | ||
150 | module_exit(cleanup_ocotea); | ||
151 | |||
152 | MODULE_LICENSE("GPL"); | ||
153 | MODULE_AUTHOR("Matt Porter <mporter@kernel.crashing.org>"); | ||
154 | MODULE_DESCRIPTION("MTD map and partitions for IBM 440GX Ocotea boards"); | ||
diff --git a/drivers/mtd/maps/omap-toto-flash.c b/drivers/mtd/maps/omap-toto-flash.c deleted file mode 100644 index 0a60ebbc2175..000000000000 --- a/drivers/mtd/maps/omap-toto-flash.c +++ /dev/null | |||
@@ -1,133 +0,0 @@ | |||
1 | /* | ||
2 | * NOR Flash memory access on TI Toto board | ||
3 | * | ||
4 | * jzhang@ti.com (C) 2003 Texas Instruments. | ||
5 | * | ||
6 | * (C) 2002 MontVista Software, Inc. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/types.h> | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/errno.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/slab.h> | ||
15 | |||
16 | #include <linux/mtd/mtd.h> | ||
17 | #include <linux/mtd/map.h> | ||
18 | #include <linux/mtd/partitions.h> | ||
19 | |||
20 | #include <asm/hardware.h> | ||
21 | #include <asm/io.h> | ||
22 | |||
23 | |||
24 | #ifndef CONFIG_ARCH_OMAP | ||
25 | #error This is for OMAP architecture only | ||
26 | #endif | ||
27 | |||
28 | //these lines need be moved to a hardware header file | ||
29 | #define OMAP_TOTO_FLASH_BASE 0xd8000000 | ||
30 | #define OMAP_TOTO_FLASH_SIZE 0x80000 | ||
31 | |||
32 | static struct map_info omap_toto_map_flash = { | ||
33 | .name = "OMAP Toto flash", | ||
34 | .bankwidth = 2, | ||
35 | .virt = (void __iomem *)OMAP_TOTO_FLASH_BASE, | ||
36 | }; | ||
37 | |||
38 | |||
39 | static struct mtd_partition toto_flash_partitions[] = { | ||
40 | { | ||
41 | .name = "BootLoader", | ||
42 | .size = 0x00040000, /* hopefully u-boot will stay 128k + 128*/ | ||
43 | .offset = 0, | ||
44 | .mask_flags = MTD_WRITEABLE, /* force read-only */ | ||
45 | }, { | ||
46 | .name = "ReservedSpace", | ||
47 | .size = 0x00030000, | ||
48 | .offset = MTDPART_OFS_APPEND, | ||
49 | //mask_flags: MTD_WRITEABLE, /* force read-only */ | ||
50 | }, { | ||
51 | .name = "EnvArea", /* bottom 64KiB for env vars */ | ||
52 | .size = MTDPART_SIZ_FULL, | ||
53 | .offset = MTDPART_OFS_APPEND, | ||
54 | } | ||
55 | }; | ||
56 | |||
57 | static struct mtd_partition *parsed_parts; | ||
58 | |||
59 | static struct mtd_info *flash_mtd; | ||
60 | |||
61 | static int __init init_flash (void) | ||
62 | { | ||
63 | |||
64 | struct mtd_partition *parts; | ||
65 | int nb_parts = 0; | ||
66 | int parsed_nr_parts = 0; | ||
67 | const char *part_type; | ||
68 | |||
69 | /* | ||
70 | * Static partition definition selection | ||
71 | */ | ||
72 | part_type = "static"; | ||
73 | |||
74 | parts = toto_flash_partitions; | ||
75 | nb_parts = ARRAY_SIZE(toto_flash_partitions); | ||
76 | omap_toto_map_flash.size = OMAP_TOTO_FLASH_SIZE; | ||
77 | omap_toto_map_flash.phys = virt_to_phys(OMAP_TOTO_FLASH_BASE); | ||
78 | |||
79 | simple_map_init(&omap_toto_map_flash); | ||
80 | /* | ||
81 | * Now let's probe for the actual flash. Do it here since | ||
82 | * specific machine settings might have been set above. | ||
83 | */ | ||
84 | printk(KERN_NOTICE "OMAP toto flash: probing %d-bit flash bus\n", | ||
85 | omap_toto_map_flash.bankwidth*8); | ||
86 | flash_mtd = do_map_probe("jedec_probe", &omap_toto_map_flash); | ||
87 | if (!flash_mtd) | ||
88 | return -ENXIO; | ||
89 | |||
90 | if (parsed_nr_parts > 0) { | ||
91 | parts = parsed_parts; | ||
92 | nb_parts = parsed_nr_parts; | ||
93 | } | ||
94 | |||
95 | if (nb_parts == 0) { | ||
96 | printk(KERN_NOTICE "OMAP toto flash: no partition info available," | ||
97 | "registering whole flash at once\n"); | ||
98 | if (add_mtd_device(flash_mtd)){ | ||
99 | return -ENXIO; | ||
100 | } | ||
101 | } else { | ||
102 | printk(KERN_NOTICE "Using %s partition definition\n", | ||
103 | part_type); | ||
104 | return add_mtd_partitions(flash_mtd, parts, nb_parts); | ||
105 | } | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | int __init omap_toto_mtd_init(void) | ||
110 | { | ||
111 | int status; | ||
112 | |||
113 | if (status = init_flash()) { | ||
114 | printk(KERN_ERR "OMAP Toto Flash: unable to init map for toto flash\n"); | ||
115 | } | ||
116 | return status; | ||
117 | } | ||
118 | |||
119 | static void __exit omap_toto_mtd_cleanup(void) | ||
120 | { | ||
121 | if (flash_mtd) { | ||
122 | del_mtd_partitions(flash_mtd); | ||
123 | map_destroy(flash_mtd); | ||
124 | kfree(parsed_parts); | ||
125 | } | ||
126 | } | ||
127 | |||
128 | module_init(omap_toto_mtd_init); | ||
129 | module_exit(omap_toto_mtd_cleanup); | ||
130 | |||
131 | MODULE_AUTHOR("Jian Zhang"); | ||
132 | MODULE_DESCRIPTION("OMAP Toto board map driver"); | ||
133 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c index 5c6a25c90380..48f4cf5cb9d1 100644 --- a/drivers/mtd/maps/pci.c +++ b/drivers/mtd/maps/pci.c | |||
@@ -203,15 +203,8 @@ intel_dc21285_init(struct pci_dev *dev, struct map_pci_info *map) | |||
203 | * not enabled, should we be allocating a new resource for it | 203 | * not enabled, should we be allocating a new resource for it |
204 | * or simply enabling it? | 204 | * or simply enabling it? |
205 | */ | 205 | */ |
206 | if (!(pci_resource_flags(dev, PCI_ROM_RESOURCE) & | 206 | pci_enable_rom(dev); |
207 | IORESOURCE_ROM_ENABLE)) { | 207 | printk("%s: enabling expansion ROM\n", pci_name(dev)); |
208 | u32 val; | ||
209 | pci_resource_flags(dev, PCI_ROM_RESOURCE) |= IORESOURCE_ROM_ENABLE; | ||
210 | pci_read_config_dword(dev, PCI_ROM_ADDRESS, &val); | ||
211 | val |= PCI_ROM_ADDRESS_ENABLE; | ||
212 | pci_write_config_dword(dev, PCI_ROM_ADDRESS, val); | ||
213 | printk("%s: enabling expansion ROM\n", pci_name(dev)); | ||
214 | } | ||
215 | } | 208 | } |
216 | 209 | ||
217 | if (!len || !base) | 210 | if (!len || !base) |
@@ -232,18 +225,13 @@ intel_dc21285_init(struct pci_dev *dev, struct map_pci_info *map) | |||
232 | static void | 225 | static void |
233 | intel_dc21285_exit(struct pci_dev *dev, struct map_pci_info *map) | 226 | intel_dc21285_exit(struct pci_dev *dev, struct map_pci_info *map) |
234 | { | 227 | { |
235 | u32 val; | ||
236 | |||
237 | if (map->base) | 228 | if (map->base) |
238 | iounmap(map->base); | 229 | iounmap(map->base); |
239 | 230 | ||
240 | /* | 231 | /* |
241 | * We need to undo the PCI BAR2/PCI ROM BAR address alteration. | 232 | * We need to undo the PCI BAR2/PCI ROM BAR address alteration. |
242 | */ | 233 | */ |
243 | pci_resource_flags(dev, PCI_ROM_RESOURCE) &= ~IORESOURCE_ROM_ENABLE; | 234 | pci_disable_rom(dev); |
244 | pci_read_config_dword(dev, PCI_ROM_ADDRESS, &val); | ||
245 | val &= ~PCI_ROM_ADDRESS_ENABLE; | ||
246 | pci_write_config_dword(dev, PCI_ROM_ADDRESS, val); | ||
247 | } | 235 | } |
248 | 236 | ||
249 | static unsigned long | 237 | static unsigned long |
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index 49acd4171893..5fcfec034a94 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c | |||
@@ -230,8 +230,7 @@ static int __devinit of_flash_probe(struct of_device *dev, | |||
230 | 230 | ||
231 | #ifdef CONFIG_MTD_OF_PARTS | 231 | #ifdef CONFIG_MTD_OF_PARTS |
232 | if (err == 0) { | 232 | if (err == 0) { |
233 | err = of_mtd_parse_partitions(&dev->dev, info->mtd, | 233 | err = of_mtd_parse_partitions(&dev->dev, dp, &info->parts); |
234 | dp, &info->parts); | ||
235 | if (err < 0) | 234 | if (err < 0) |
236 | return err; | 235 | return err; |
237 | } | 236 | } |
diff --git a/drivers/mtd/maps/walnut.c b/drivers/mtd/maps/walnut.c deleted file mode 100644 index e243476c8171..000000000000 --- a/drivers/mtd/maps/walnut.c +++ /dev/null | |||
@@ -1,122 +0,0 @@ | |||
1 | /* | ||
2 | * Mapping for Walnut flash | ||
3 | * (used ebony.c as a "framework") | ||
4 | * | ||
5 | * Heikki Lindholm <holindho@infradead.org> | ||
6 | * | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/mtd/mtd.h> | ||
19 | #include <linux/mtd/map.h> | ||
20 | #include <linux/mtd/partitions.h> | ||
21 | #include <asm/io.h> | ||
22 | #include <asm/ibm4xx.h> | ||
23 | #include <platforms/4xx/walnut.h> | ||
24 | |||
25 | /* these should be in platforms/4xx/walnut.h ? */ | ||
26 | #define WALNUT_FLASH_ONBD_N(x) (x & 0x02) | ||
27 | #define WALNUT_FLASH_SRAM_SEL(x) (x & 0x01) | ||
28 | #define WALNUT_FLASH_LOW 0xFFF00000 | ||
29 | #define WALNUT_FLASH_HIGH 0xFFF80000 | ||
30 | #define WALNUT_FLASH_SIZE 0x80000 | ||
31 | |||
32 | static struct mtd_info *flash; | ||
33 | |||
34 | static struct map_info walnut_map = { | ||
35 | .name = "Walnut flash", | ||
36 | .size = WALNUT_FLASH_SIZE, | ||
37 | .bankwidth = 1, | ||
38 | }; | ||
39 | |||
40 | /* Actually, OpenBIOS is the last 128 KiB of the flash - better | ||
41 | * partitioning could be made */ | ||
42 | static struct mtd_partition walnut_partitions[] = { | ||
43 | { | ||
44 | .name = "OpenBIOS", | ||
45 | .offset = 0x0, | ||
46 | .size = WALNUT_FLASH_SIZE, | ||
47 | /*.mask_flags = MTD_WRITEABLE, */ /* force read-only */ | ||
48 | } | ||
49 | }; | ||
50 | |||
51 | int __init init_walnut(void) | ||
52 | { | ||
53 | u8 fpga_brds1; | ||
54 | void *fpga_brds1_adr; | ||
55 | void *fpga_status_adr; | ||
56 | unsigned long flash_base; | ||
57 | |||
58 | /* this should already be mapped (platform/4xx/walnut.c) */ | ||
59 | fpga_status_adr = ioremap(WALNUT_FPGA_BASE, 8); | ||
60 | if (!fpga_status_adr) | ||
61 | return -ENOMEM; | ||
62 | |||
63 | fpga_brds1_adr = fpga_status_adr+5; | ||
64 | fpga_brds1 = readb(fpga_brds1_adr); | ||
65 | /* iounmap(fpga_status_adr); */ | ||
66 | |||
67 | if (WALNUT_FLASH_ONBD_N(fpga_brds1)) { | ||
68 | printk("The on-board flash is disabled (U79 sw 5)!"); | ||
69 | iounmap(fpga_status_adr); | ||
70 | return -EIO; | ||
71 | } | ||
72 | if (WALNUT_FLASH_SRAM_SEL(fpga_brds1)) | ||
73 | flash_base = WALNUT_FLASH_LOW; | ||
74 | else | ||
75 | flash_base = WALNUT_FLASH_HIGH; | ||
76 | |||
77 | walnut_map.phys = flash_base; | ||
78 | walnut_map.virt = | ||
79 | (void __iomem *)ioremap(flash_base, walnut_map.size); | ||
80 | |||
81 | if (!walnut_map.virt) { | ||
82 | printk("Failed to ioremap flash.\n"); | ||
83 | iounmap(fpga_status_adr); | ||
84 | return -EIO; | ||
85 | } | ||
86 | |||
87 | simple_map_init(&walnut_map); | ||
88 | |||
89 | flash = do_map_probe("jedec_probe", &walnut_map); | ||
90 | if (flash) { | ||
91 | flash->owner = THIS_MODULE; | ||
92 | add_mtd_partitions(flash, walnut_partitions, | ||
93 | ARRAY_SIZE(walnut_partitions)); | ||
94 | } else { | ||
95 | printk("map probe failed for flash\n"); | ||
96 | iounmap(fpga_status_adr); | ||
97 | return -ENXIO; | ||
98 | } | ||
99 | |||
100 | iounmap(fpga_status_adr); | ||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | static void __exit cleanup_walnut(void) | ||
105 | { | ||
106 | if (flash) { | ||
107 | del_mtd_partitions(flash); | ||
108 | map_destroy(flash); | ||
109 | } | ||
110 | |||
111 | if (walnut_map.virt) { | ||
112 | iounmap((void *)walnut_map.virt); | ||
113 | walnut_map.virt = 0; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | module_init(init_walnut); | ||
118 | module_exit(cleanup_walnut); | ||
119 | |||
120 | MODULE_LICENSE("GPL"); | ||
121 | MODULE_AUTHOR("Heikki Lindholm <holindho@infradead.org>"); | ||
122 | MODULE_DESCRIPTION("MTD map and partitions for IBM 405GP Walnut boards"); | ||
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 1c74762dec89..963840e9b5bf 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c | |||
@@ -348,7 +348,7 @@ static void mtdchar_erase_callback (struct erase_info *instr) | |||
348 | wake_up((wait_queue_head_t *)instr->priv); | 348 | wake_up((wait_queue_head_t *)instr->priv); |
349 | } | 349 | } |
350 | 350 | ||
351 | #if defined(CONFIG_MTD_OTP) || defined(CONFIG_MTD_ONENAND_OTP) | 351 | #ifdef CONFIG_HAVE_MTD_OTP |
352 | static int otp_select_filemode(struct mtd_file_info *mfi, int mode) | 352 | static int otp_select_filemode(struct mtd_file_info *mfi, int mode) |
353 | { | 353 | { |
354 | struct mtd_info *mtd = mfi->mtd; | 354 | struct mtd_info *mtd = mfi->mtd; |
@@ -665,7 +665,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file, | |||
665 | break; | 665 | break; |
666 | } | 666 | } |
667 | 667 | ||
668 | #if defined(CONFIG_MTD_OTP) || defined(CONFIG_MTD_ONENAND_OTP) | 668 | #ifdef CONFIG_HAVE_MTD_OTP |
669 | case OTPSELECT: | 669 | case OTPSELECT: |
670 | { | 670 | { |
671 | int mode; | 671 | int mode; |
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c index 2972a5edb73d..789842d0e6f2 100644 --- a/drivers/mtd/mtdconcat.c +++ b/drivers/mtd/mtdconcat.c | |||
@@ -444,7 +444,7 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
444 | return -EINVAL; | 444 | return -EINVAL; |
445 | } | 445 | } |
446 | 446 | ||
447 | instr->fail_addr = 0xffffffff; | 447 | instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; |
448 | 448 | ||
449 | /* make a local copy of instr to avoid modifying the caller's struct */ | 449 | /* make a local copy of instr to avoid modifying the caller's struct */ |
450 | erase = kmalloc(sizeof (struct erase_info), GFP_KERNEL); | 450 | erase = kmalloc(sizeof (struct erase_info), GFP_KERNEL); |
@@ -493,7 +493,7 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
493 | /* sanity check: should never happen since | 493 | /* sanity check: should never happen since |
494 | * block alignment has been checked above */ | 494 | * block alignment has been checked above */ |
495 | BUG_ON(err == -EINVAL); | 495 | BUG_ON(err == -EINVAL); |
496 | if (erase->fail_addr != 0xffffffff) | 496 | if (erase->fail_addr != MTD_FAIL_ADDR_UNKNOWN) |
497 | instr->fail_addr = erase->fail_addr + offset; | 497 | instr->fail_addr = erase->fail_addr + offset; |
498 | break; | 498 | break; |
499 | } | 499 | } |
diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index 5a680e1e61f1..aebb3b27edbd 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/interrupt.h> | 33 | #include <linux/interrupt.h> |
34 | #include <linux/mtd/mtd.h> | 34 | #include <linux/mtd/mtd.h> |
35 | 35 | ||
36 | #define MTDOOPS_KERNMSG_MAGIC 0x5d005d00 | ||
36 | #define OOPS_PAGE_SIZE 4096 | 37 | #define OOPS_PAGE_SIZE 4096 |
37 | 38 | ||
38 | static struct mtdoops_context { | 39 | static struct mtdoops_context { |
@@ -99,7 +100,7 @@ static void mtdoops_inc_counter(struct mtdoops_context *cxt) | |||
99 | int ret; | 100 | int ret; |
100 | 101 | ||
101 | cxt->nextpage++; | 102 | cxt->nextpage++; |
102 | if (cxt->nextpage > cxt->oops_pages) | 103 | if (cxt->nextpage >= cxt->oops_pages) |
103 | cxt->nextpage = 0; | 104 | cxt->nextpage = 0; |
104 | cxt->nextcount++; | 105 | cxt->nextcount++; |
105 | if (cxt->nextcount == 0xffffffff) | 106 | if (cxt->nextcount == 0xffffffff) |
@@ -141,7 +142,7 @@ static void mtdoops_workfunc_erase(struct work_struct *work) | |||
141 | mod = (cxt->nextpage * OOPS_PAGE_SIZE) % mtd->erasesize; | 142 | mod = (cxt->nextpage * OOPS_PAGE_SIZE) % mtd->erasesize; |
142 | if (mod != 0) { | 143 | if (mod != 0) { |
143 | cxt->nextpage = cxt->nextpage + ((mtd->erasesize - mod) / OOPS_PAGE_SIZE); | 144 | cxt->nextpage = cxt->nextpage + ((mtd->erasesize - mod) / OOPS_PAGE_SIZE); |
144 | if (cxt->nextpage > cxt->oops_pages) | 145 | if (cxt->nextpage >= cxt->oops_pages) |
145 | cxt->nextpage = 0; | 146 | cxt->nextpage = 0; |
146 | } | 147 | } |
147 | 148 | ||
@@ -158,7 +159,7 @@ badblock: | |||
158 | cxt->nextpage * OOPS_PAGE_SIZE); | 159 | cxt->nextpage * OOPS_PAGE_SIZE); |
159 | i++; | 160 | i++; |
160 | cxt->nextpage = cxt->nextpage + (mtd->erasesize / OOPS_PAGE_SIZE); | 161 | cxt->nextpage = cxt->nextpage + (mtd->erasesize / OOPS_PAGE_SIZE); |
161 | if (cxt->nextpage > cxt->oops_pages) | 162 | if (cxt->nextpage >= cxt->oops_pages) |
162 | cxt->nextpage = 0; | 163 | cxt->nextpage = 0; |
163 | if (i == (cxt->oops_pages / (mtd->erasesize / OOPS_PAGE_SIZE))) { | 164 | if (i == (cxt->oops_pages / (mtd->erasesize / OOPS_PAGE_SIZE))) { |
164 | printk(KERN_ERR "mtdoops: All blocks bad!\n"); | 165 | printk(KERN_ERR "mtdoops: All blocks bad!\n"); |
@@ -224,40 +225,40 @@ static void find_next_position(struct mtdoops_context *cxt) | |||
224 | { | 225 | { |
225 | struct mtd_info *mtd = cxt->mtd; | 226 | struct mtd_info *mtd = cxt->mtd; |
226 | int ret, page, maxpos = 0; | 227 | int ret, page, maxpos = 0; |
227 | u32 count, maxcount = 0xffffffff; | 228 | u32 count[2], maxcount = 0xffffffff; |
228 | size_t retlen; | 229 | size_t retlen; |
229 | 230 | ||
230 | for (page = 0; page < cxt->oops_pages; page++) { | 231 | for (page = 0; page < cxt->oops_pages; page++) { |
231 | ret = mtd->read(mtd, page * OOPS_PAGE_SIZE, 4, &retlen, (u_char *) &count); | 232 | ret = mtd->read(mtd, page * OOPS_PAGE_SIZE, 8, &retlen, (u_char *) &count[0]); |
232 | if ((retlen != 4) || ((ret < 0) && (ret != -EUCLEAN))) { | 233 | if ((retlen != 8) || ((ret < 0) && (ret != -EUCLEAN))) { |
233 | printk(KERN_ERR "mtdoops: Read failure at %d (%td of 4 read)" | 234 | printk(KERN_ERR "mtdoops: Read failure at %d (%td of 8 read)" |
234 | ", err %d.\n", page * OOPS_PAGE_SIZE, retlen, ret); | 235 | ", err %d.\n", page * OOPS_PAGE_SIZE, retlen, ret); |
235 | continue; | 236 | continue; |
236 | } | 237 | } |
237 | 238 | ||
238 | if (count == 0xffffffff) | 239 | if (count[1] != MTDOOPS_KERNMSG_MAGIC) |
240 | continue; | ||
241 | if (count[0] == 0xffffffff) | ||
239 | continue; | 242 | continue; |
240 | if (maxcount == 0xffffffff) { | 243 | if (maxcount == 0xffffffff) { |
241 | maxcount = count; | 244 | maxcount = count[0]; |
242 | maxpos = page; | 245 | maxpos = page; |
243 | } else if ((count < 0x40000000) && (maxcount > 0xc0000000)) { | 246 | } else if ((count[0] < 0x40000000) && (maxcount > 0xc0000000)) { |
244 | maxcount = count; | 247 | maxcount = count[0]; |
245 | maxpos = page; | 248 | maxpos = page; |
246 | } else if ((count > maxcount) && (count < 0xc0000000)) { | 249 | } else if ((count[0] > maxcount) && (count[0] < 0xc0000000)) { |
247 | maxcount = count; | 250 | maxcount = count[0]; |
248 | maxpos = page; | 251 | maxpos = page; |
249 | } else if ((count > maxcount) && (count > 0xc0000000) | 252 | } else if ((count[0] > maxcount) && (count[0] > 0xc0000000) |
250 | && (maxcount > 0x80000000)) { | 253 | && (maxcount > 0x80000000)) { |
251 | maxcount = count; | 254 | maxcount = count[0]; |
252 | maxpos = page; | 255 | maxpos = page; |
253 | } | 256 | } |
254 | } | 257 | } |
255 | if (maxcount == 0xffffffff) { | 258 | if (maxcount == 0xffffffff) { |
256 | cxt->nextpage = 0; | 259 | cxt->nextpage = 0; |
257 | cxt->nextcount = 1; | 260 | cxt->nextcount = 1; |
258 | cxt->ready = 1; | 261 | schedule_work(&cxt->work_erase); |
259 | printk(KERN_DEBUG "mtdoops: Ready %d, %d (first init)\n", | ||
260 | cxt->nextpage, cxt->nextcount); | ||
261 | return; | 262 | return; |
262 | } | 263 | } |
263 | 264 | ||
@@ -358,8 +359,9 @@ mtdoops_console_write(struct console *co, const char *s, unsigned int count) | |||
358 | 359 | ||
359 | if (cxt->writecount == 0) { | 360 | if (cxt->writecount == 0) { |
360 | u32 *stamp = cxt->oops_buf; | 361 | u32 *stamp = cxt->oops_buf; |
361 | *stamp = cxt->nextcount; | 362 | *stamp++ = cxt->nextcount; |
362 | cxt->writecount = 4; | 363 | *stamp = MTDOOPS_KERNMSG_MAGIC; |
364 | cxt->writecount = 8; | ||
363 | } | 365 | } |
364 | 366 | ||
365 | if ((count + cxt->writecount) > OOPS_PAGE_SIZE) | 367 | if ((count + cxt->writecount) > OOPS_PAGE_SIZE) |
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 9a06dc93ee0d..3728913fa5fa 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c | |||
@@ -214,7 +214,7 @@ static int part_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
214 | instr->addr += part->offset; | 214 | instr->addr += part->offset; |
215 | ret = part->master->erase(part->master, instr); | 215 | ret = part->master->erase(part->master, instr); |
216 | if (ret) { | 216 | if (ret) { |
217 | if (instr->fail_addr != 0xffffffff) | 217 | if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) |
218 | instr->fail_addr -= part->offset; | 218 | instr->fail_addr -= part->offset; |
219 | instr->addr -= part->offset; | 219 | instr->addr -= part->offset; |
220 | } | 220 | } |
@@ -226,7 +226,7 @@ void mtd_erase_callback(struct erase_info *instr) | |||
226 | if (instr->mtd->erase == part_erase) { | 226 | if (instr->mtd->erase == part_erase) { |
227 | struct mtd_part *part = PART(instr->mtd); | 227 | struct mtd_part *part = PART(instr->mtd); |
228 | 228 | ||
229 | if (instr->fail_addr != 0xffffffff) | 229 | if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) |
230 | instr->fail_addr -= part->offset; | 230 | instr->fail_addr -= part->offset; |
231 | instr->addr -= part->offset; | 231 | instr->addr -= part->offset; |
232 | } | 232 | } |
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 41f361c49b32..1c2e9450d663 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
@@ -56,6 +56,12 @@ config MTD_NAND_H1900 | |||
56 | help | 56 | help |
57 | This enables the driver for the iPAQ h1900 flash. | 57 | This enables the driver for the iPAQ h1900 flash. |
58 | 58 | ||
59 | config MTD_NAND_GPIO | ||
60 | tristate "GPIO NAND Flash driver" | ||
61 | depends on GENERIC_GPIO && ARM | ||
62 | help | ||
63 | This enables a GPIO based NAND flash driver. | ||
64 | |||
59 | config MTD_NAND_SPIA | 65 | config MTD_NAND_SPIA |
60 | tristate "NAND Flash device on SPIA board" | 66 | tristate "NAND Flash device on SPIA board" |
61 | depends on ARCH_P720T | 67 | depends on ARCH_P720T |
@@ -68,12 +74,6 @@ config MTD_NAND_AMS_DELTA | |||
68 | help | 74 | help |
69 | Support for NAND flash on Amstrad E3 (Delta). | 75 | Support for NAND flash on Amstrad E3 (Delta). |
70 | 76 | ||
71 | config MTD_NAND_TOTO | ||
72 | tristate "NAND Flash device on TOTO board" | ||
73 | depends on ARCH_OMAP && BROKEN | ||
74 | help | ||
75 | Support for NAND flash on Texas Instruments Toto platform. | ||
76 | |||
77 | config MTD_NAND_TS7250 | 77 | config MTD_NAND_TS7250 |
78 | tristate "NAND Flash device on TS-7250 board" | 78 | tristate "NAND Flash device on TS-7250 board" |
79 | depends on MACH_TS72XX | 79 | depends on MACH_TS72XX |
@@ -163,13 +163,6 @@ config MTD_NAND_S3C2410_HWECC | |||
163 | incorrect ECC generation, and if using these, the default of | 163 | incorrect ECC generation, and if using these, the default of |
164 | software ECC is preferable. | 164 | software ECC is preferable. |
165 | 165 | ||
166 | config MTD_NAND_NDFC | ||
167 | tristate "NDFC NanD Flash Controller" | ||
168 | depends on 4xx && !PPC_MERGE | ||
169 | select MTD_NAND_ECC_SMC | ||
170 | help | ||
171 | NDFC Nand Flash Controllers are integrated in IBM/AMCC's 4xx SoCs | ||
172 | |||
173 | config MTD_NAND_S3C2410_CLKSTOP | 166 | config MTD_NAND_S3C2410_CLKSTOP |
174 | bool "S3C2410 NAND IDLE clock stop" | 167 | bool "S3C2410 NAND IDLE clock stop" |
175 | depends on MTD_NAND_S3C2410 | 168 | depends on MTD_NAND_S3C2410 |
@@ -340,6 +333,13 @@ config MTD_NAND_PXA3xx | |||
340 | This enables the driver for the NAND flash device found on | 333 | This enables the driver for the NAND flash device found on |
341 | PXA3xx processors | 334 | PXA3xx processors |
342 | 335 | ||
336 | config MTD_NAND_PXA3xx_BUILTIN | ||
337 | bool "Use builtin definitions for some NAND chips (deprecated)" | ||
338 | depends on MTD_NAND_PXA3xx | ||
339 | help | ||
340 | This enables builtin definitions for some NAND chips. This | ||
341 | is deprecated in favor of platform specific data. | ||
342 | |||
343 | config MTD_NAND_CM_X270 | 343 | config MTD_NAND_CM_X270 |
344 | tristate "Support for NAND Flash on CM-X270 modules" | 344 | tristate "Support for NAND Flash on CM-X270 modules" |
345 | depends on MTD_NAND && MACH_ARMCORE | 345 | depends on MTD_NAND && MACH_ARMCORE |
@@ -400,10 +400,24 @@ config MTD_NAND_FSL_ELBC | |||
400 | 400 | ||
401 | config MTD_NAND_FSL_UPM | 401 | config MTD_NAND_FSL_UPM |
402 | tristate "Support for NAND on Freescale UPM" | 402 | tristate "Support for NAND on Freescale UPM" |
403 | depends on MTD_NAND && OF_GPIO && (PPC_83xx || PPC_85xx) | 403 | depends on MTD_NAND && (PPC_83xx || PPC_85xx) |
404 | select FSL_LBC | 404 | select FSL_LBC |
405 | help | 405 | help |
406 | Enables support for NAND Flash chips wired onto Freescale PowerPC | 406 | Enables support for NAND Flash chips wired onto Freescale PowerPC |
407 | processor localbus with User-Programmable Machine support. | 407 | processor localbus with User-Programmable Machine support. |
408 | 408 | ||
409 | config MTD_NAND_MXC | ||
410 | tristate "MXC NAND support" | ||
411 | depends on ARCH_MX2 | ||
412 | help | ||
413 | This enables the driver for the NAND flash controller on the | ||
414 | MXC processors. | ||
415 | |||
416 | config MTD_NAND_SH_FLCTL | ||
417 | tristate "Support for NAND on Renesas SuperH FLCTL" | ||
418 | depends on MTD_NAND && SUPERH && CPU_SUBTYPE_SH7723 | ||
419 | help | ||
420 | Several Renesas SuperH CPU has FLCTL. This option enables support | ||
421 | for NAND Flash using FLCTL. This driver support SH7723. | ||
422 | |||
409 | endif # MTD_NAND | 423 | endif # MTD_NAND |
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index b786c5da82da..b661586afbfc 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile | |||
@@ -8,7 +8,6 @@ obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o | |||
8 | obj-$(CONFIG_MTD_NAND_CAFE) += cafe_nand.o | 8 | obj-$(CONFIG_MTD_NAND_CAFE) += cafe_nand.o |
9 | obj-$(CONFIG_MTD_NAND_SPIA) += spia.o | 9 | obj-$(CONFIG_MTD_NAND_SPIA) += spia.o |
10 | obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o | 10 | obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o |
11 | obj-$(CONFIG_MTD_NAND_TOTO) += toto.o | ||
12 | obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o | 11 | obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o |
13 | obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o | 12 | obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o |
14 | obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o | 13 | obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o |
@@ -24,6 +23,7 @@ obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o | |||
24 | obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o | 23 | obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o |
25 | obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o | 24 | obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o |
26 | obj-$(CONFIG_MTD_NAND_ATMEL) += atmel_nand.o | 25 | obj-$(CONFIG_MTD_NAND_ATMEL) += atmel_nand.o |
26 | obj-$(CONFIG_MTD_NAND_GPIO) += gpio.o | ||
27 | obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o | 27 | obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o |
28 | obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o | 28 | obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o |
29 | obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o | 29 | obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o |
@@ -34,5 +34,7 @@ obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o | |||
34 | obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o | 34 | obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o |
35 | obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o | 35 | obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o |
36 | obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o | 36 | obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o |
37 | obj-$(CONFIG_MTD_NAND_SH_FLCTL) += sh_flctl.o | ||
38 | obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o | ||
37 | 39 | ||
38 | nand-objs := nand_base.o nand_bbt.o | 40 | nand-objs := nand_base.o nand_bbt.o |
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 3387e0d5076b..c98c1570a40b 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c | |||
@@ -174,48 +174,6 @@ static void atmel_write_buf16(struct mtd_info *mtd, const u8 *buf, int len) | |||
174 | } | 174 | } |
175 | 175 | ||
176 | /* | 176 | /* |
177 | * write oob for small pages | ||
178 | */ | ||
179 | static int atmel_nand_write_oob_512(struct mtd_info *mtd, | ||
180 | struct nand_chip *chip, int page) | ||
181 | { | ||
182 | int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad; | ||
183 | int eccsize = chip->ecc.size, length = mtd->oobsize; | ||
184 | int len, pos, status = 0; | ||
185 | const uint8_t *bufpoi = chip->oob_poi; | ||
186 | |||
187 | pos = eccsize + chunk; | ||
188 | |||
189 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, pos, page); | ||
190 | len = min_t(int, length, chunk); | ||
191 | chip->write_buf(mtd, bufpoi, len); | ||
192 | bufpoi += len; | ||
193 | length -= len; | ||
194 | if (length > 0) | ||
195 | chip->write_buf(mtd, bufpoi, length); | ||
196 | |||
197 | chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); | ||
198 | status = chip->waitfunc(mtd, chip); | ||
199 | |||
200 | return status & NAND_STATUS_FAIL ? -EIO : 0; | ||
201 | |||
202 | } | ||
203 | |||
204 | /* | ||
205 | * read oob for small pages | ||
206 | */ | ||
207 | static int atmel_nand_read_oob_512(struct mtd_info *mtd, | ||
208 | struct nand_chip *chip, int page, int sndcmd) | ||
209 | { | ||
210 | if (sndcmd) { | ||
211 | chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); | ||
212 | sndcmd = 0; | ||
213 | } | ||
214 | chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); | ||
215 | return sndcmd; | ||
216 | } | ||
217 | |||
218 | /* | ||
219 | * Calculate HW ECC | 177 | * Calculate HW ECC |
220 | * | 178 | * |
221 | * function called after a write | 179 | * function called after a write |
@@ -235,14 +193,14 @@ static int atmel_nand_calculate(struct mtd_info *mtd, | |||
235 | /* get the first 2 ECC bytes */ | 193 | /* get the first 2 ECC bytes */ |
236 | ecc_value = ecc_readl(host->ecc, PR); | 194 | ecc_value = ecc_readl(host->ecc, PR); |
237 | 195 | ||
238 | ecc_code[eccpos[0]] = ecc_value & 0xFF; | 196 | ecc_code[0] = ecc_value & 0xFF; |
239 | ecc_code[eccpos[1]] = (ecc_value >> 8) & 0xFF; | 197 | ecc_code[1] = (ecc_value >> 8) & 0xFF; |
240 | 198 | ||
241 | /* get the last 2 ECC bytes */ | 199 | /* get the last 2 ECC bytes */ |
242 | ecc_value = ecc_readl(host->ecc, NPR) & ATMEL_ECC_NPARITY; | 200 | ecc_value = ecc_readl(host->ecc, NPR) & ATMEL_ECC_NPARITY; |
243 | 201 | ||
244 | ecc_code[eccpos[2]] = ecc_value & 0xFF; | 202 | ecc_code[2] = ecc_value & 0xFF; |
245 | ecc_code[eccpos[3]] = (ecc_value >> 8) & 0xFF; | 203 | ecc_code[3] = (ecc_value >> 8) & 0xFF; |
246 | 204 | ||
247 | return 0; | 205 | return 0; |
248 | } | 206 | } |
@@ -476,14 +434,12 @@ static int __init atmel_nand_probe(struct platform_device *pdev) | |||
476 | res = -EIO; | 434 | res = -EIO; |
477 | goto err_ecc_ioremap; | 435 | goto err_ecc_ioremap; |
478 | } | 436 | } |
479 | nand_chip->ecc.mode = NAND_ECC_HW_SYNDROME; | 437 | nand_chip->ecc.mode = NAND_ECC_HW; |
480 | nand_chip->ecc.calculate = atmel_nand_calculate; | 438 | nand_chip->ecc.calculate = atmel_nand_calculate; |
481 | nand_chip->ecc.correct = atmel_nand_correct; | 439 | nand_chip->ecc.correct = atmel_nand_correct; |
482 | nand_chip->ecc.hwctl = atmel_nand_hwctl; | 440 | nand_chip->ecc.hwctl = atmel_nand_hwctl; |
483 | nand_chip->ecc.read_page = atmel_nand_read_page; | 441 | nand_chip->ecc.read_page = atmel_nand_read_page; |
484 | nand_chip->ecc.bytes = 4; | 442 | nand_chip->ecc.bytes = 4; |
485 | nand_chip->ecc.prepad = 0; | ||
486 | nand_chip->ecc.postpad = 0; | ||
487 | } | 443 | } |
488 | 444 | ||
489 | nand_chip->chip_delay = 20; /* 20us command delay time */ | 445 | nand_chip->chip_delay = 20; /* 20us command delay time */ |
@@ -514,7 +470,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev) | |||
514 | goto err_scan_ident; | 470 | goto err_scan_ident; |
515 | } | 471 | } |
516 | 472 | ||
517 | if (nand_chip->ecc.mode == NAND_ECC_HW_SYNDROME) { | 473 | if (nand_chip->ecc.mode == NAND_ECC_HW) { |
518 | /* ECC is calculated for the whole page (1 step) */ | 474 | /* ECC is calculated for the whole page (1 step) */ |
519 | nand_chip->ecc.size = mtd->writesize; | 475 | nand_chip->ecc.size = mtd->writesize; |
520 | 476 | ||
@@ -522,8 +478,6 @@ static int __init atmel_nand_probe(struct platform_device *pdev) | |||
522 | switch (mtd->writesize) { | 478 | switch (mtd->writesize) { |
523 | case 512: | 479 | case 512: |
524 | nand_chip->ecc.layout = &atmel_oobinfo_small; | 480 | nand_chip->ecc.layout = &atmel_oobinfo_small; |
525 | nand_chip->ecc.read_oob = atmel_nand_read_oob_512; | ||
526 | nand_chip->ecc.write_oob = atmel_nand_write_oob_512; | ||
527 | ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_528); | 481 | ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_528); |
528 | break; | 482 | break; |
529 | case 1024: | 483 | case 1024: |
diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c index 3370a800fd36..9f1b451005ca 100644 --- a/drivers/mtd/nand/cs553x_nand.c +++ b/drivers/mtd/nand/cs553x_nand.c | |||
@@ -289,8 +289,10 @@ static int __init cs553x_init(void) | |||
289 | int i; | 289 | int i; |
290 | uint64_t val; | 290 | uint64_t val; |
291 | 291 | ||
292 | #ifdef CONFIG_MTD_PARTITIONS | ||
292 | int mtd_parts_nb = 0; | 293 | int mtd_parts_nb = 0; |
293 | struct mtd_partition *mtd_parts = NULL; | 294 | struct mtd_partition *mtd_parts = NULL; |
295 | #endif | ||
294 | 296 | ||
295 | /* If the CPU isn't a Geode GX or LX, abort */ | 297 | /* If the CPU isn't a Geode GX or LX, abort */ |
296 | if (!is_geode()) | 298 | if (!is_geode()) |
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 98ad3cefcaf4..4aa5bd6158da 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c | |||
@@ -918,8 +918,7 @@ static int __devinit fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl, | |||
918 | 918 | ||
919 | #ifdef CONFIG_MTD_OF_PARTS | 919 | #ifdef CONFIG_MTD_OF_PARTS |
920 | if (ret == 0) { | 920 | if (ret == 0) { |
921 | ret = of_mtd_parse_partitions(priv->dev, &priv->mtd, | 921 | ret = of_mtd_parse_partitions(priv->dev, node, &parts); |
922 | node, &parts); | ||
923 | if (ret < 0) | 922 | if (ret < 0) |
924 | goto err; | 923 | goto err; |
925 | } | 924 | } |
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index 1ebfd87f00b4..024e3fffd4bb 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/delay.h> | ||
16 | #include <linux/mtd/nand.h> | 17 | #include <linux/mtd/nand.h> |
17 | #include <linux/mtd/nand_ecc.h> | 18 | #include <linux/mtd/nand_ecc.h> |
18 | #include <linux/mtd/partitions.h> | 19 | #include <linux/mtd/partitions.h> |
@@ -36,8 +37,6 @@ struct fsl_upm_nand { | |||
36 | uint8_t upm_cmd_offset; | 37 | uint8_t upm_cmd_offset; |
37 | void __iomem *io_base; | 38 | void __iomem *io_base; |
38 | int rnb_gpio; | 39 | int rnb_gpio; |
39 | const uint32_t *wait_pattern; | ||
40 | const uint32_t *wait_write; | ||
41 | int chip_delay; | 40 | int chip_delay; |
42 | }; | 41 | }; |
43 | 42 | ||
@@ -61,10 +60,11 @@ static void fun_wait_rnb(struct fsl_upm_nand *fun) | |||
61 | if (fun->rnb_gpio >= 0) { | 60 | if (fun->rnb_gpio >= 0) { |
62 | while (--cnt && !fun_chip_ready(&fun->mtd)) | 61 | while (--cnt && !fun_chip_ready(&fun->mtd)) |
63 | cpu_relax(); | 62 | cpu_relax(); |
63 | if (!cnt) | ||
64 | dev_err(fun->dev, "tired waiting for RNB\n"); | ||
65 | } else { | ||
66 | ndelay(100); | ||
64 | } | 67 | } |
65 | |||
66 | if (!cnt) | ||
67 | dev_err(fun->dev, "tired waiting for RNB\n"); | ||
68 | } | 68 | } |
69 | 69 | ||
70 | static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 70 | static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
@@ -89,8 +89,7 @@ static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | |||
89 | 89 | ||
90 | fsl_upm_run_pattern(&fun->upm, fun->io_base, cmd); | 90 | fsl_upm_run_pattern(&fun->upm, fun->io_base, cmd); |
91 | 91 | ||
92 | if (fun->wait_pattern) | 92 | fun_wait_rnb(fun); |
93 | fun_wait_rnb(fun); | ||
94 | } | 93 | } |
95 | 94 | ||
96 | static uint8_t fun_read_byte(struct mtd_info *mtd) | 95 | static uint8_t fun_read_byte(struct mtd_info *mtd) |
@@ -116,14 +115,16 @@ static void fun_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | |||
116 | 115 | ||
117 | for (i = 0; i < len; i++) { | 116 | for (i = 0; i < len; i++) { |
118 | out_8(fun->chip.IO_ADDR_W, buf[i]); | 117 | out_8(fun->chip.IO_ADDR_W, buf[i]); |
119 | if (fun->wait_write) | 118 | fun_wait_rnb(fun); |
120 | fun_wait_rnb(fun); | ||
121 | } | 119 | } |
122 | } | 120 | } |
123 | 121 | ||
124 | static int __devinit fun_chip_init(struct fsl_upm_nand *fun) | 122 | static int __devinit fun_chip_init(struct fsl_upm_nand *fun, |
123 | const struct device_node *upm_np, | ||
124 | const struct resource *io_res) | ||
125 | { | 125 | { |
126 | int ret; | 126 | int ret; |
127 | struct device_node *flash_np; | ||
127 | #ifdef CONFIG_MTD_PARTITIONS | 128 | #ifdef CONFIG_MTD_PARTITIONS |
128 | static const char *part_types[] = { "cmdlinepart", NULL, }; | 129 | static const char *part_types[] = { "cmdlinepart", NULL, }; |
129 | #endif | 130 | #endif |
@@ -143,18 +144,37 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun) | |||
143 | fun->mtd.priv = &fun->chip; | 144 | fun->mtd.priv = &fun->chip; |
144 | fun->mtd.owner = THIS_MODULE; | 145 | fun->mtd.owner = THIS_MODULE; |
145 | 146 | ||
147 | flash_np = of_get_next_child(upm_np, NULL); | ||
148 | if (!flash_np) | ||
149 | return -ENODEV; | ||
150 | |||
151 | fun->mtd.name = kasprintf(GFP_KERNEL, "%x.%s", io_res->start, | ||
152 | flash_np->name); | ||
153 | if (!fun->mtd.name) { | ||
154 | ret = -ENOMEM; | ||
155 | goto err; | ||
156 | } | ||
157 | |||
146 | ret = nand_scan(&fun->mtd, 1); | 158 | ret = nand_scan(&fun->mtd, 1); |
147 | if (ret) | 159 | if (ret) |
148 | return ret; | 160 | goto err; |
149 | |||
150 | fun->mtd.name = fun->dev->bus_id; | ||
151 | 161 | ||
152 | #ifdef CONFIG_MTD_PARTITIONS | 162 | #ifdef CONFIG_MTD_PARTITIONS |
153 | ret = parse_mtd_partitions(&fun->mtd, part_types, &fun->parts, 0); | 163 | ret = parse_mtd_partitions(&fun->mtd, part_types, &fun->parts, 0); |
164 | |||
165 | #ifdef CONFIG_MTD_OF_PARTS | ||
166 | if (ret == 0) | ||
167 | ret = of_mtd_parse_partitions(fun->dev, &fun->mtd, | ||
168 | flash_np, &fun->parts); | ||
169 | #endif | ||
154 | if (ret > 0) | 170 | if (ret > 0) |
155 | return add_mtd_partitions(&fun->mtd, fun->parts, ret); | 171 | ret = add_mtd_partitions(&fun->mtd, fun->parts, ret); |
172 | else | ||
156 | #endif | 173 | #endif |
157 | return add_mtd_device(&fun->mtd); | 174 | ret = add_mtd_device(&fun->mtd); |
175 | err: | ||
176 | of_node_put(flash_np); | ||
177 | return ret; | ||
158 | } | 178 | } |
159 | 179 | ||
160 | static int __devinit fun_probe(struct of_device *ofdev, | 180 | static int __devinit fun_probe(struct of_device *ofdev, |
@@ -211,6 +231,12 @@ static int __devinit fun_probe(struct of_device *ofdev, | |||
211 | goto err2; | 231 | goto err2; |
212 | } | 232 | } |
213 | 233 | ||
234 | prop = of_get_property(ofdev->node, "chip-delay", NULL); | ||
235 | if (prop) | ||
236 | fun->chip_delay = *prop; | ||
237 | else | ||
238 | fun->chip_delay = 50; | ||
239 | |||
214 | fun->io_base = devm_ioremap_nocache(&ofdev->dev, io_res.start, | 240 | fun->io_base = devm_ioremap_nocache(&ofdev->dev, io_res.start, |
215 | io_res.end - io_res.start + 1); | 241 | io_res.end - io_res.start + 1); |
216 | if (!fun->io_base) { | 242 | if (!fun->io_base) { |
@@ -220,17 +246,8 @@ static int __devinit fun_probe(struct of_device *ofdev, | |||
220 | 246 | ||
221 | fun->dev = &ofdev->dev; | 247 | fun->dev = &ofdev->dev; |
222 | fun->last_ctrl = NAND_CLE; | 248 | fun->last_ctrl = NAND_CLE; |
223 | fun->wait_pattern = of_get_property(ofdev->node, "fsl,wait-pattern", | ||
224 | NULL); | ||
225 | fun->wait_write = of_get_property(ofdev->node, "fsl,wait-write", NULL); | ||
226 | |||
227 | prop = of_get_property(ofdev->node, "chip-delay", NULL); | ||
228 | if (prop) | ||
229 | fun->chip_delay = *prop; | ||
230 | else | ||
231 | fun->chip_delay = 50; | ||
232 | 249 | ||
233 | ret = fun_chip_init(fun); | 250 | ret = fun_chip_init(fun, ofdev->node, &io_res); |
234 | if (ret) | 251 | if (ret) |
235 | goto err2; | 252 | goto err2; |
236 | 253 | ||
@@ -251,6 +268,7 @@ static int __devexit fun_remove(struct of_device *ofdev) | |||
251 | struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev); | 268 | struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev); |
252 | 269 | ||
253 | nand_release(&fun->mtd); | 270 | nand_release(&fun->mtd); |
271 | kfree(fun->mtd.name); | ||
254 | 272 | ||
255 | if (fun->rnb_gpio >= 0) | 273 | if (fun->rnb_gpio >= 0) |
256 | gpio_free(fun->rnb_gpio); | 274 | gpio_free(fun->rnb_gpio); |
diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/gpio.c new file mode 100644 index 000000000000..8f902e75aa85 --- /dev/null +++ b/drivers/mtd/nand/gpio.c | |||
@@ -0,0 +1,375 @@ | |||
1 | /* | ||
2 | * drivers/mtd/nand/gpio.c | ||
3 | * | ||
4 | * Updated, and converted to generic GPIO based driver by Russell King. | ||
5 | * | ||
6 | * Written by Ben Dooks <ben@simtec.co.uk> | ||
7 | * Based on 2.4 version by Mark Whittaker | ||
8 | * | ||
9 | * © 2004 Simtec Electronics | ||
10 | * | ||
11 | * Device driver for NAND connected via GPIO | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License version 2 as | ||
15 | * published by the Free Software Foundation. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/gpio.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/mtd/mtd.h> | ||
27 | #include <linux/mtd/nand.h> | ||
28 | #include <linux/mtd/partitions.h> | ||
29 | #include <linux/mtd/nand-gpio.h> | ||
30 | |||
31 | struct gpiomtd { | ||
32 | void __iomem *io_sync; | ||
33 | struct mtd_info mtd_info; | ||
34 | struct nand_chip nand_chip; | ||
35 | struct gpio_nand_platdata plat; | ||
36 | }; | ||
37 | |||
38 | #define gpio_nand_getpriv(x) container_of(x, struct gpiomtd, mtd_info) | ||
39 | |||
40 | |||
41 | #ifdef CONFIG_ARM | ||
42 | /* gpio_nand_dosync() | ||
43 | * | ||
44 | * Make sure the GPIO state changes occur in-order with writes to NAND | ||
45 | * memory region. | ||
46 | * Needed on PXA due to bus-reordering within the SoC itself (see section on | ||
47 | * I/O ordering in PXA manual (section 2.3, p35) | ||
48 | */ | ||
49 | static void gpio_nand_dosync(struct gpiomtd *gpiomtd) | ||
50 | { | ||
51 | unsigned long tmp; | ||
52 | |||
53 | if (gpiomtd->io_sync) { | ||
54 | /* | ||
55 | * Linux memory barriers don't cater for what's required here. | ||
56 | * What's required is what's here - a read from a separate | ||
57 | * region with a dependency on that read. | ||
58 | */ | ||
59 | tmp = readl(gpiomtd->io_sync); | ||
60 | asm volatile("mov %1, %0\n" : "=r" (tmp) : "r" (tmp)); | ||
61 | } | ||
62 | } | ||
63 | #else | ||
64 | static inline void gpio_nand_dosync(struct gpiomtd *gpiomtd) {} | ||
65 | #endif | ||
66 | |||
67 | static void gpio_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | ||
68 | { | ||
69 | struct gpiomtd *gpiomtd = gpio_nand_getpriv(mtd); | ||
70 | |||
71 | gpio_nand_dosync(gpiomtd); | ||
72 | |||
73 | if (ctrl & NAND_CTRL_CHANGE) { | ||
74 | gpio_set_value(gpiomtd->plat.gpio_nce, !(ctrl & NAND_NCE)); | ||
75 | gpio_set_value(gpiomtd->plat.gpio_cle, !!(ctrl & NAND_CLE)); | ||
76 | gpio_set_value(gpiomtd->plat.gpio_ale, !!(ctrl & NAND_ALE)); | ||
77 | gpio_nand_dosync(gpiomtd); | ||
78 | } | ||
79 | if (cmd == NAND_CMD_NONE) | ||
80 | return; | ||
81 | |||
82 | writeb(cmd, gpiomtd->nand_chip.IO_ADDR_W); | ||
83 | gpio_nand_dosync(gpiomtd); | ||
84 | } | ||
85 | |||
86 | static void gpio_nand_writebuf(struct mtd_info *mtd, const u_char *buf, int len) | ||
87 | { | ||
88 | struct nand_chip *this = mtd->priv; | ||
89 | |||
90 | writesb(this->IO_ADDR_W, buf, len); | ||
91 | } | ||
92 | |||
93 | static void gpio_nand_readbuf(struct mtd_info *mtd, u_char *buf, int len) | ||
94 | { | ||
95 | struct nand_chip *this = mtd->priv; | ||
96 | |||
97 | readsb(this->IO_ADDR_R, buf, len); | ||
98 | } | ||
99 | |||
100 | static int gpio_nand_verifybuf(struct mtd_info *mtd, const u_char *buf, int len) | ||
101 | { | ||
102 | struct nand_chip *this = mtd->priv; | ||
103 | unsigned char read, *p = (unsigned char *) buf; | ||
104 | int i, err = 0; | ||
105 | |||
106 | for (i = 0; i < len; i++) { | ||
107 | read = readb(this->IO_ADDR_R); | ||
108 | if (read != p[i]) { | ||
109 | pr_debug("%s: err at %d (read %04x vs %04x)\n", | ||
110 | __func__, i, read, p[i]); | ||
111 | err = -EFAULT; | ||
112 | } | ||
113 | } | ||
114 | return err; | ||
115 | } | ||
116 | |||
117 | static void gpio_nand_writebuf16(struct mtd_info *mtd, const u_char *buf, | ||
118 | int len) | ||
119 | { | ||
120 | struct nand_chip *this = mtd->priv; | ||
121 | |||
122 | if (IS_ALIGNED((unsigned long)buf, 2)) { | ||
123 | writesw(this->IO_ADDR_W, buf, len>>1); | ||
124 | } else { | ||
125 | int i; | ||
126 | unsigned short *ptr = (unsigned short *)buf; | ||
127 | |||
128 | for (i = 0; i < len; i += 2, ptr++) | ||
129 | writew(*ptr, this->IO_ADDR_W); | ||
130 | } | ||
131 | } | ||
132 | |||
133 | static void gpio_nand_readbuf16(struct mtd_info *mtd, u_char *buf, int len) | ||
134 | { | ||
135 | struct nand_chip *this = mtd->priv; | ||
136 | |||
137 | if (IS_ALIGNED((unsigned long)buf, 2)) { | ||
138 | readsw(this->IO_ADDR_R, buf, len>>1); | ||
139 | } else { | ||
140 | int i; | ||
141 | unsigned short *ptr = (unsigned short *)buf; | ||
142 | |||
143 | for (i = 0; i < len; i += 2, ptr++) | ||
144 | *ptr = readw(this->IO_ADDR_R); | ||
145 | } | ||
146 | } | ||
147 | |||
148 | static int gpio_nand_verifybuf16(struct mtd_info *mtd, const u_char *buf, | ||
149 | int len) | ||
150 | { | ||
151 | struct nand_chip *this = mtd->priv; | ||
152 | unsigned short read, *p = (unsigned short *) buf; | ||
153 | int i, err = 0; | ||
154 | len >>= 1; | ||
155 | |||
156 | for (i = 0; i < len; i++) { | ||
157 | read = readw(this->IO_ADDR_R); | ||
158 | if (read != p[i]) { | ||
159 | pr_debug("%s: err at %d (read %04x vs %04x)\n", | ||
160 | __func__, i, read, p[i]); | ||
161 | err = -EFAULT; | ||
162 | } | ||
163 | } | ||
164 | return err; | ||
165 | } | ||
166 | |||
167 | |||
168 | static int gpio_nand_devready(struct mtd_info *mtd) | ||
169 | { | ||
170 | struct gpiomtd *gpiomtd = gpio_nand_getpriv(mtd); | ||
171 | return gpio_get_value(gpiomtd->plat.gpio_rdy); | ||
172 | } | ||
173 | |||
174 | static int __devexit gpio_nand_remove(struct platform_device *dev) | ||
175 | { | ||
176 | struct gpiomtd *gpiomtd = platform_get_drvdata(dev); | ||
177 | struct resource *res; | ||
178 | |||
179 | nand_release(&gpiomtd->mtd_info); | ||
180 | |||
181 | res = platform_get_resource(dev, IORESOURCE_MEM, 1); | ||
182 | iounmap(gpiomtd->io_sync); | ||
183 | if (res) | ||
184 | release_mem_region(res->start, res->end - res->start + 1); | ||
185 | |||
186 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
187 | iounmap(gpiomtd->nand_chip.IO_ADDR_R); | ||
188 | release_mem_region(res->start, res->end - res->start + 1); | ||
189 | |||
190 | if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) | ||
191 | gpio_set_value(gpiomtd->plat.gpio_nwp, 0); | ||
192 | gpio_set_value(gpiomtd->plat.gpio_nce, 1); | ||
193 | |||
194 | gpio_free(gpiomtd->plat.gpio_cle); | ||
195 | gpio_free(gpiomtd->plat.gpio_ale); | ||
196 | gpio_free(gpiomtd->plat.gpio_nce); | ||
197 | if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) | ||
198 | gpio_free(gpiomtd->plat.gpio_nwp); | ||
199 | gpio_free(gpiomtd->plat.gpio_rdy); | ||
200 | |||
201 | kfree(gpiomtd); | ||
202 | |||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | static void __iomem *request_and_remap(struct resource *res, size_t size, | ||
207 | const char *name, int *err) | ||
208 | { | ||
209 | void __iomem *ptr; | ||
210 | |||
211 | if (!request_mem_region(res->start, res->end - res->start + 1, name)) { | ||
212 | *err = -EBUSY; | ||
213 | return NULL; | ||
214 | } | ||
215 | |||
216 | ptr = ioremap(res->start, size); | ||
217 | if (!ptr) { | ||
218 | release_mem_region(res->start, res->end - res->start + 1); | ||
219 | *err = -ENOMEM; | ||
220 | } | ||
221 | return ptr; | ||
222 | } | ||
223 | |||
224 | static int __devinit gpio_nand_probe(struct platform_device *dev) | ||
225 | { | ||
226 | struct gpiomtd *gpiomtd; | ||
227 | struct nand_chip *this; | ||
228 | struct resource *res0, *res1; | ||
229 | int ret; | ||
230 | |||
231 | if (!dev->dev.platform_data) | ||
232 | return -EINVAL; | ||
233 | |||
234 | res0 = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
235 | if (!res0) | ||
236 | return -EINVAL; | ||
237 | |||
238 | gpiomtd = kzalloc(sizeof(*gpiomtd), GFP_KERNEL); | ||
239 | if (gpiomtd == NULL) { | ||
240 | dev_err(&dev->dev, "failed to create NAND MTD\n"); | ||
241 | return -ENOMEM; | ||
242 | } | ||
243 | |||
244 | this = &gpiomtd->nand_chip; | ||
245 | this->IO_ADDR_R = request_and_remap(res0, 2, "NAND", &ret); | ||
246 | if (!this->IO_ADDR_R) { | ||
247 | dev_err(&dev->dev, "unable to map NAND\n"); | ||
248 | goto err_map; | ||
249 | } | ||
250 | |||
251 | res1 = platform_get_resource(dev, IORESOURCE_MEM, 1); | ||
252 | if (res1) { | ||
253 | gpiomtd->io_sync = request_and_remap(res1, 4, "NAND sync", &ret); | ||
254 | if (!gpiomtd->io_sync) { | ||
255 | dev_err(&dev->dev, "unable to map sync NAND\n"); | ||
256 | goto err_sync; | ||
257 | } | ||
258 | } | ||
259 | |||
260 | memcpy(&gpiomtd->plat, dev->dev.platform_data, sizeof(gpiomtd->plat)); | ||
261 | |||
262 | ret = gpio_request(gpiomtd->plat.gpio_nce, "NAND NCE"); | ||
263 | if (ret) | ||
264 | goto err_nce; | ||
265 | gpio_direction_output(gpiomtd->plat.gpio_nce, 1); | ||
266 | if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) { | ||
267 | ret = gpio_request(gpiomtd->plat.gpio_nwp, "NAND NWP"); | ||
268 | if (ret) | ||
269 | goto err_nwp; | ||
270 | gpio_direction_output(gpiomtd->plat.gpio_nwp, 1); | ||
271 | } | ||
272 | ret = gpio_request(gpiomtd->plat.gpio_ale, "NAND ALE"); | ||
273 | if (ret) | ||
274 | goto err_ale; | ||
275 | gpio_direction_output(gpiomtd->plat.gpio_ale, 0); | ||
276 | ret = gpio_request(gpiomtd->plat.gpio_cle, "NAND CLE"); | ||
277 | if (ret) | ||
278 | goto err_cle; | ||
279 | gpio_direction_output(gpiomtd->plat.gpio_cle, 0); | ||
280 | ret = gpio_request(gpiomtd->plat.gpio_rdy, "NAND RDY"); | ||
281 | if (ret) | ||
282 | goto err_rdy; | ||
283 | gpio_direction_input(gpiomtd->plat.gpio_rdy); | ||
284 | |||
285 | |||
286 | this->IO_ADDR_W = this->IO_ADDR_R; | ||
287 | this->ecc.mode = NAND_ECC_SOFT; | ||
288 | this->options = gpiomtd->plat.options; | ||
289 | this->chip_delay = gpiomtd->plat.chip_delay; | ||
290 | |||
291 | /* install our routines */ | ||
292 | this->cmd_ctrl = gpio_nand_cmd_ctrl; | ||
293 | this->dev_ready = gpio_nand_devready; | ||
294 | |||
295 | if (this->options & NAND_BUSWIDTH_16) { | ||
296 | this->read_buf = gpio_nand_readbuf16; | ||
297 | this->write_buf = gpio_nand_writebuf16; | ||
298 | this->verify_buf = gpio_nand_verifybuf16; | ||
299 | } else { | ||
300 | this->read_buf = gpio_nand_readbuf; | ||
301 | this->write_buf = gpio_nand_writebuf; | ||
302 | this->verify_buf = gpio_nand_verifybuf; | ||
303 | } | ||
304 | |||
305 | /* set the mtd private data for the nand driver */ | ||
306 | gpiomtd->mtd_info.priv = this; | ||
307 | gpiomtd->mtd_info.owner = THIS_MODULE; | ||
308 | |||
309 | if (nand_scan(&gpiomtd->mtd_info, 1)) { | ||
310 | dev_err(&dev->dev, "no nand chips found?\n"); | ||
311 | ret = -ENXIO; | ||
312 | goto err_wp; | ||
313 | } | ||
314 | |||
315 | if (gpiomtd->plat.adjust_parts) | ||
316 | gpiomtd->plat.adjust_parts(&gpiomtd->plat, | ||
317 | gpiomtd->mtd_info.size); | ||
318 | |||
319 | add_mtd_partitions(&gpiomtd->mtd_info, gpiomtd->plat.parts, | ||
320 | gpiomtd->plat.num_parts); | ||
321 | platform_set_drvdata(dev, gpiomtd); | ||
322 | |||
323 | return 0; | ||
324 | |||
325 | err_wp: | ||
326 | if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) | ||
327 | gpio_set_value(gpiomtd->plat.gpio_nwp, 0); | ||
328 | gpio_free(gpiomtd->plat.gpio_rdy); | ||
329 | err_rdy: | ||
330 | gpio_free(gpiomtd->plat.gpio_cle); | ||
331 | err_cle: | ||
332 | gpio_free(gpiomtd->plat.gpio_ale); | ||
333 | err_ale: | ||
334 | if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) | ||
335 | gpio_free(gpiomtd->plat.gpio_nwp); | ||
336 | err_nwp: | ||
337 | gpio_free(gpiomtd->plat.gpio_nce); | ||
338 | err_nce: | ||
339 | iounmap(gpiomtd->io_sync); | ||
340 | if (res1) | ||
341 | release_mem_region(res1->start, res1->end - res1->start + 1); | ||
342 | err_sync: | ||
343 | iounmap(gpiomtd->nand_chip.IO_ADDR_R); | ||
344 | release_mem_region(res0->start, res0->end - res0->start + 1); | ||
345 | err_map: | ||
346 | kfree(gpiomtd); | ||
347 | return ret; | ||
348 | } | ||
349 | |||
350 | static struct platform_driver gpio_nand_driver = { | ||
351 | .probe = gpio_nand_probe, | ||
352 | .remove = gpio_nand_remove, | ||
353 | .driver = { | ||
354 | .name = "gpio-nand", | ||
355 | }, | ||
356 | }; | ||
357 | |||
358 | static int __init gpio_nand_init(void) | ||
359 | { | ||
360 | printk(KERN_INFO "GPIO NAND driver, © 2004 Simtec Electronics\n"); | ||
361 | |||
362 | return platform_driver_register(&gpio_nand_driver); | ||
363 | } | ||
364 | |||
365 | static void __exit gpio_nand_exit(void) | ||
366 | { | ||
367 | platform_driver_unregister(&gpio_nand_driver); | ||
368 | } | ||
369 | |||
370 | module_init(gpio_nand_init); | ||
371 | module_exit(gpio_nand_exit); | ||
372 | |||
373 | MODULE_LICENSE("GPL"); | ||
374 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | ||
375 | MODULE_DESCRIPTION("GPIO NAND Driver"); | ||
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c new file mode 100644 index 000000000000..21fd4f1c4806 --- /dev/null +++ b/drivers/mtd/nand/mxc_nand.c | |||
@@ -0,0 +1,1077 @@ | |||
1 | /* | ||
2 | * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | * Copyright 2008 Sascha Hauer, kernel@pengutronix.de | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License | ||
7 | * as published by the Free Software Foundation; either version 2 | ||
8 | * of the License, or (at your option) any later version. | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
17 | * MA 02110-1301, USA. | ||
18 | */ | ||
19 | |||
20 | #include <linux/delay.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/mtd/mtd.h> | ||
25 | #include <linux/mtd/nand.h> | ||
26 | #include <linux/mtd/partitions.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/device.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/clk.h> | ||
31 | #include <linux/err.h> | ||
32 | #include <linux/io.h> | ||
33 | |||
34 | #include <asm/mach/flash.h> | ||
35 | #include <mach/mxc_nand.h> | ||
36 | |||
37 | #define DRIVER_NAME "mxc_nand" | ||
38 | |||
39 | /* Addresses for NFC registers */ | ||
40 | #define NFC_BUF_SIZE 0xE00 | ||
41 | #define NFC_BUF_ADDR 0xE04 | ||
42 | #define NFC_FLASH_ADDR 0xE06 | ||
43 | #define NFC_FLASH_CMD 0xE08 | ||
44 | #define NFC_CONFIG 0xE0A | ||
45 | #define NFC_ECC_STATUS_RESULT 0xE0C | ||
46 | #define NFC_RSLTMAIN_AREA 0xE0E | ||
47 | #define NFC_RSLTSPARE_AREA 0xE10 | ||
48 | #define NFC_WRPROT 0xE12 | ||
49 | #define NFC_UNLOCKSTART_BLKADDR 0xE14 | ||
50 | #define NFC_UNLOCKEND_BLKADDR 0xE16 | ||
51 | #define NFC_NF_WRPRST 0xE18 | ||
52 | #define NFC_CONFIG1 0xE1A | ||
53 | #define NFC_CONFIG2 0xE1C | ||
54 | |||
55 | /* Addresses for NFC RAM BUFFER Main area 0 */ | ||
56 | #define MAIN_AREA0 0x000 | ||
57 | #define MAIN_AREA1 0x200 | ||
58 | #define MAIN_AREA2 0x400 | ||
59 | #define MAIN_AREA3 0x600 | ||
60 | |||
61 | /* Addresses for NFC SPARE BUFFER Spare area 0 */ | ||
62 | #define SPARE_AREA0 0x800 | ||
63 | #define SPARE_AREA1 0x810 | ||
64 | #define SPARE_AREA2 0x820 | ||
65 | #define SPARE_AREA3 0x830 | ||
66 | |||
67 | /* Set INT to 0, FCMD to 1, rest to 0 in NFC_CONFIG2 Register | ||
68 | * for Command operation */ | ||
69 | #define NFC_CMD 0x1 | ||
70 | |||
71 | /* Set INT to 0, FADD to 1, rest to 0 in NFC_CONFIG2 Register | ||
72 | * for Address operation */ | ||
73 | #define NFC_ADDR 0x2 | ||
74 | |||
75 | /* Set INT to 0, FDI to 1, rest to 0 in NFC_CONFIG2 Register | ||
76 | * for Input operation */ | ||
77 | #define NFC_INPUT 0x4 | ||
78 | |||
79 | /* Set INT to 0, FDO to 001, rest to 0 in NFC_CONFIG2 Register | ||
80 | * for Data Output operation */ | ||
81 | #define NFC_OUTPUT 0x8 | ||
82 | |||
83 | /* Set INT to 0, FD0 to 010, rest to 0 in NFC_CONFIG2 Register | ||
84 | * for Read ID operation */ | ||
85 | #define NFC_ID 0x10 | ||
86 | |||
87 | /* Set INT to 0, FDO to 100, rest to 0 in NFC_CONFIG2 Register | ||
88 | * for Read Status operation */ | ||
89 | #define NFC_STATUS 0x20 | ||
90 | |||
91 | /* Set INT to 1, rest to 0 in NFC_CONFIG2 Register for Read | ||
92 | * Status operation */ | ||
93 | #define NFC_INT 0x8000 | ||
94 | |||
95 | #define NFC_SP_EN (1 << 2) | ||
96 | #define NFC_ECC_EN (1 << 3) | ||
97 | #define NFC_INT_MSK (1 << 4) | ||
98 | #define NFC_BIG (1 << 5) | ||
99 | #define NFC_RST (1 << 6) | ||
100 | #define NFC_CE (1 << 7) | ||
101 | #define NFC_ONE_CYCLE (1 << 8) | ||
102 | |||
103 | struct mxc_nand_host { | ||
104 | struct mtd_info mtd; | ||
105 | struct nand_chip nand; | ||
106 | struct mtd_partition *parts; | ||
107 | struct device *dev; | ||
108 | |||
109 | void __iomem *regs; | ||
110 | int spare_only; | ||
111 | int status_request; | ||
112 | int pagesize_2k; | ||
113 | uint16_t col_addr; | ||
114 | struct clk *clk; | ||
115 | int clk_act; | ||
116 | int irq; | ||
117 | |||
118 | wait_queue_head_t irq_waitq; | ||
119 | }; | ||
120 | |||
121 | /* Define delays in microsec for NAND device operations */ | ||
122 | #define TROP_US_DELAY 2000 | ||
123 | /* Macros to get byte and bit positions of ECC */ | ||
124 | #define COLPOS(x) ((x) >> 3) | ||
125 | #define BITPOS(x) ((x) & 0xf) | ||
126 | |||
127 | /* Define single bit Error positions in Main & Spare area */ | ||
128 | #define MAIN_SINGLEBIT_ERROR 0x4 | ||
129 | #define SPARE_SINGLEBIT_ERROR 0x1 | ||
130 | |||
131 | /* OOB placement block for use with hardware ecc generation */ | ||
132 | static struct nand_ecclayout nand_hw_eccoob_8 = { | ||
133 | .eccbytes = 5, | ||
134 | .eccpos = {6, 7, 8, 9, 10}, | ||
135 | .oobfree = {{0, 5}, {11, 5}, } | ||
136 | }; | ||
137 | |||
138 | static struct nand_ecclayout nand_hw_eccoob_16 = { | ||
139 | .eccbytes = 5, | ||
140 | .eccpos = {6, 7, 8, 9, 10}, | ||
141 | .oobfree = {{0, 6}, {12, 4}, } | ||
142 | }; | ||
143 | |||
144 | #ifdef CONFIG_MTD_PARTITIONS | ||
145 | static const char *part_probes[] = { "RedBoot", "cmdlinepart", NULL }; | ||
146 | #endif | ||
147 | |||
148 | static irqreturn_t mxc_nfc_irq(int irq, void *dev_id) | ||
149 | { | ||
150 | struct mxc_nand_host *host = dev_id; | ||
151 | |||
152 | uint16_t tmp; | ||
153 | |||
154 | tmp = readw(host->regs + NFC_CONFIG1); | ||
155 | tmp |= NFC_INT_MSK; /* Disable interrupt */ | ||
156 | writew(tmp, host->regs + NFC_CONFIG1); | ||
157 | |||
158 | wake_up(&host->irq_waitq); | ||
159 | |||
160 | return IRQ_HANDLED; | ||
161 | } | ||
162 | |||
163 | /* This function polls the NANDFC to wait for the basic operation to | ||
164 | * complete by checking the INT bit of config2 register. | ||
165 | */ | ||
166 | static void wait_op_done(struct mxc_nand_host *host, int max_retries, | ||
167 | uint16_t param, int useirq) | ||
168 | { | ||
169 | uint32_t tmp; | ||
170 | |||
171 | if (useirq) { | ||
172 | if ((readw(host->regs + NFC_CONFIG2) & NFC_INT) == 0) { | ||
173 | |||
174 | tmp = readw(host->regs + NFC_CONFIG1); | ||
175 | tmp &= ~NFC_INT_MSK; /* Enable interrupt */ | ||
176 | writew(tmp, host->regs + NFC_CONFIG1); | ||
177 | |||
178 | wait_event(host->irq_waitq, | ||
179 | readw(host->regs + NFC_CONFIG2) & NFC_INT); | ||
180 | |||
181 | tmp = readw(host->regs + NFC_CONFIG2); | ||
182 | tmp &= ~NFC_INT; | ||
183 | writew(tmp, host->regs + NFC_CONFIG2); | ||
184 | } | ||
185 | } else { | ||
186 | while (max_retries-- > 0) { | ||
187 | if (readw(host->regs + NFC_CONFIG2) & NFC_INT) { | ||
188 | tmp = readw(host->regs + NFC_CONFIG2); | ||
189 | tmp &= ~NFC_INT; | ||
190 | writew(tmp, host->regs + NFC_CONFIG2); | ||
191 | break; | ||
192 | } | ||
193 | udelay(1); | ||
194 | } | ||
195 | if (max_retries <= 0) | ||
196 | DEBUG(MTD_DEBUG_LEVEL0, "%s(%d): INT not set\n", | ||
197 | __func__, param); | ||
198 | } | ||
199 | } | ||
200 | |||
201 | /* This function issues the specified command to the NAND device and | ||
202 | * waits for completion. */ | ||
203 | static void send_cmd(struct mxc_nand_host *host, uint16_t cmd, int useirq) | ||
204 | { | ||
205 | DEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x, %d)\n", cmd, useirq); | ||
206 | |||
207 | writew(cmd, host->regs + NFC_FLASH_CMD); | ||
208 | writew(NFC_CMD, host->regs + NFC_CONFIG2); | ||
209 | |||
210 | /* Wait for operation to complete */ | ||
211 | wait_op_done(host, TROP_US_DELAY, cmd, useirq); | ||
212 | } | ||
213 | |||
214 | /* This function sends an address (or partial address) to the | ||
215 | * NAND device. The address is used to select the source/destination for | ||
216 | * a NAND command. */ | ||
217 | static void send_addr(struct mxc_nand_host *host, uint16_t addr, int islast) | ||
218 | { | ||
219 | DEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x %d)\n", addr, islast); | ||
220 | |||
221 | writew(addr, host->regs + NFC_FLASH_ADDR); | ||
222 | writew(NFC_ADDR, host->regs + NFC_CONFIG2); | ||
223 | |||
224 | /* Wait for operation to complete */ | ||
225 | wait_op_done(host, TROP_US_DELAY, addr, islast); | ||
226 | } | ||
227 | |||
228 | /* This function requests the NANDFC to initate the transfer | ||
229 | * of data currently in the NANDFC RAM buffer to the NAND device. */ | ||
230 | static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id, | ||
231 | int spare_only) | ||
232 | { | ||
233 | DEBUG(MTD_DEBUG_LEVEL3, "send_prog_page (%d)\n", spare_only); | ||
234 | |||
235 | /* NANDFC buffer 0 is used for page read/write */ | ||
236 | writew(buf_id, host->regs + NFC_BUF_ADDR); | ||
237 | |||
238 | /* Configure spare or page+spare access */ | ||
239 | if (!host->pagesize_2k) { | ||
240 | uint16_t config1 = readw(host->regs + NFC_CONFIG1); | ||
241 | if (spare_only) | ||
242 | config1 |= NFC_SP_EN; | ||
243 | else | ||
244 | config1 &= ~(NFC_SP_EN); | ||
245 | writew(config1, host->regs + NFC_CONFIG1); | ||
246 | } | ||
247 | |||
248 | writew(NFC_INPUT, host->regs + NFC_CONFIG2); | ||
249 | |||
250 | /* Wait for operation to complete */ | ||
251 | wait_op_done(host, TROP_US_DELAY, spare_only, true); | ||
252 | } | ||
253 | |||
254 | /* Requests NANDFC to initated the transfer of data from the | ||
255 | * NAND device into in the NANDFC ram buffer. */ | ||
256 | static void send_read_page(struct mxc_nand_host *host, uint8_t buf_id, | ||
257 | int spare_only) | ||
258 | { | ||
259 | DEBUG(MTD_DEBUG_LEVEL3, "send_read_page (%d)\n", spare_only); | ||
260 | |||
261 | /* NANDFC buffer 0 is used for page read/write */ | ||
262 | writew(buf_id, host->regs + NFC_BUF_ADDR); | ||
263 | |||
264 | /* Configure spare or page+spare access */ | ||
265 | if (!host->pagesize_2k) { | ||
266 | uint32_t config1 = readw(host->regs + NFC_CONFIG1); | ||
267 | if (spare_only) | ||
268 | config1 |= NFC_SP_EN; | ||
269 | else | ||
270 | config1 &= ~NFC_SP_EN; | ||
271 | writew(config1, host->regs + NFC_CONFIG1); | ||
272 | } | ||
273 | |||
274 | writew(NFC_OUTPUT, host->regs + NFC_CONFIG2); | ||
275 | |||
276 | /* Wait for operation to complete */ | ||
277 | wait_op_done(host, TROP_US_DELAY, spare_only, true); | ||
278 | } | ||
279 | |||
280 | /* Request the NANDFC to perform a read of the NAND device ID. */ | ||
281 | static void send_read_id(struct mxc_nand_host *host) | ||
282 | { | ||
283 | struct nand_chip *this = &host->nand; | ||
284 | uint16_t tmp; | ||
285 | |||
286 | /* NANDFC buffer 0 is used for device ID output */ | ||
287 | writew(0x0, host->regs + NFC_BUF_ADDR); | ||
288 | |||
289 | /* Read ID into main buffer */ | ||
290 | tmp = readw(host->regs + NFC_CONFIG1); | ||
291 | tmp &= ~NFC_SP_EN; | ||
292 | writew(tmp, host->regs + NFC_CONFIG1); | ||
293 | |||
294 | writew(NFC_ID, host->regs + NFC_CONFIG2); | ||
295 | |||
296 | /* Wait for operation to complete */ | ||
297 | wait_op_done(host, TROP_US_DELAY, 0, true); | ||
298 | |||
299 | if (this->options & NAND_BUSWIDTH_16) { | ||
300 | void __iomem *main_buf = host->regs + MAIN_AREA0; | ||
301 | /* compress the ID info */ | ||
302 | writeb(readb(main_buf + 2), main_buf + 1); | ||
303 | writeb(readb(main_buf + 4), main_buf + 2); | ||
304 | writeb(readb(main_buf + 6), main_buf + 3); | ||
305 | writeb(readb(main_buf + 8), main_buf + 4); | ||
306 | writeb(readb(main_buf + 10), main_buf + 5); | ||
307 | } | ||
308 | } | ||
309 | |||
310 | /* This function requests the NANDFC to perform a read of the | ||
311 | * NAND device status and returns the current status. */ | ||
312 | static uint16_t get_dev_status(struct mxc_nand_host *host) | ||
313 | { | ||
314 | void __iomem *main_buf = host->regs + MAIN_AREA1; | ||
315 | uint32_t store; | ||
316 | uint16_t ret, tmp; | ||
317 | /* Issue status request to NAND device */ | ||
318 | |||
319 | /* store the main area1 first word, later do recovery */ | ||
320 | store = readl(main_buf); | ||
321 | /* NANDFC buffer 1 is used for device status to prevent | ||
322 | * corruption of read/write buffer on status requests. */ | ||
323 | writew(1, host->regs + NFC_BUF_ADDR); | ||
324 | |||
325 | /* Read status into main buffer */ | ||
326 | tmp = readw(host->regs + NFC_CONFIG1); | ||
327 | tmp &= ~NFC_SP_EN; | ||
328 | writew(tmp, host->regs + NFC_CONFIG1); | ||
329 | |||
330 | writew(NFC_STATUS, host->regs + NFC_CONFIG2); | ||
331 | |||
332 | /* Wait for operation to complete */ | ||
333 | wait_op_done(host, TROP_US_DELAY, 0, true); | ||
334 | |||
335 | /* Status is placed in first word of main buffer */ | ||
336 | /* get status, then recovery area 1 data */ | ||
337 | ret = readw(main_buf); | ||
338 | writel(store, main_buf); | ||
339 | |||
340 | return ret; | ||
341 | } | ||
342 | |||
343 | /* This functions is used by upper layer to checks if device is ready */ | ||
344 | static int mxc_nand_dev_ready(struct mtd_info *mtd) | ||
345 | { | ||
346 | /* | ||
347 | * NFC handles R/B internally. Therefore, this function | ||
348 | * always returns status as ready. | ||
349 | */ | ||
350 | return 1; | ||
351 | } | ||
352 | |||
353 | static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode) | ||
354 | { | ||
355 | /* | ||
356 | * If HW ECC is enabled, we turn it on during init. There is | ||
357 | * no need to enable again here. | ||
358 | */ | ||
359 | } | ||
360 | |||
361 | static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat, | ||
362 | u_char *read_ecc, u_char *calc_ecc) | ||
363 | { | ||
364 | struct nand_chip *nand_chip = mtd->priv; | ||
365 | struct mxc_nand_host *host = nand_chip->priv; | ||
366 | |||
367 | /* | ||
368 | * 1-Bit errors are automatically corrected in HW. No need for | ||
369 | * additional correction. 2-Bit errors cannot be corrected by | ||
370 | * HW ECC, so we need to return failure | ||
371 | */ | ||
372 | uint16_t ecc_status = readw(host->regs + NFC_ECC_STATUS_RESULT); | ||
373 | |||
374 | if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) { | ||
375 | DEBUG(MTD_DEBUG_LEVEL0, | ||
376 | "MXC_NAND: HWECC uncorrectable 2-bit ECC error\n"); | ||
377 | return -1; | ||
378 | } | ||
379 | |||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, | ||
384 | u_char *ecc_code) | ||
385 | { | ||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | static u_char mxc_nand_read_byte(struct mtd_info *mtd) | ||
390 | { | ||
391 | struct nand_chip *nand_chip = mtd->priv; | ||
392 | struct mxc_nand_host *host = nand_chip->priv; | ||
393 | uint8_t ret = 0; | ||
394 | uint16_t col, rd_word; | ||
395 | uint16_t __iomem *main_buf = host->regs + MAIN_AREA0; | ||
396 | uint16_t __iomem *spare_buf = host->regs + SPARE_AREA0; | ||
397 | |||
398 | /* Check for status request */ | ||
399 | if (host->status_request) | ||
400 | return get_dev_status(host) & 0xFF; | ||
401 | |||
402 | /* Get column for 16-bit access */ | ||
403 | col = host->col_addr >> 1; | ||
404 | |||
405 | /* If we are accessing the spare region */ | ||
406 | if (host->spare_only) | ||
407 | rd_word = readw(&spare_buf[col]); | ||
408 | else | ||
409 | rd_word = readw(&main_buf[col]); | ||
410 | |||
411 | /* Pick upper/lower byte of word from RAM buffer */ | ||
412 | if (host->col_addr & 0x1) | ||
413 | ret = (rd_word >> 8) & 0xFF; | ||
414 | else | ||
415 | ret = rd_word & 0xFF; | ||
416 | |||
417 | /* Update saved column address */ | ||
418 | host->col_addr++; | ||
419 | |||
420 | return ret; | ||
421 | } | ||
422 | |||
423 | static uint16_t mxc_nand_read_word(struct mtd_info *mtd) | ||
424 | { | ||
425 | struct nand_chip *nand_chip = mtd->priv; | ||
426 | struct mxc_nand_host *host = nand_chip->priv; | ||
427 | uint16_t col, rd_word, ret; | ||
428 | uint16_t __iomem *p; | ||
429 | |||
430 | DEBUG(MTD_DEBUG_LEVEL3, | ||
431 | "mxc_nand_read_word(col = %d)\n", host->col_addr); | ||
432 | |||
433 | col = host->col_addr; | ||
434 | /* Adjust saved column address */ | ||
435 | if (col < mtd->writesize && host->spare_only) | ||
436 | col += mtd->writesize; | ||
437 | |||
438 | if (col < mtd->writesize) | ||
439 | p = (host->regs + MAIN_AREA0) + (col >> 1); | ||
440 | else | ||
441 | p = (host->regs + SPARE_AREA0) + ((col - mtd->writesize) >> 1); | ||
442 | |||
443 | if (col & 1) { | ||
444 | rd_word = readw(p); | ||
445 | ret = (rd_word >> 8) & 0xff; | ||
446 | rd_word = readw(&p[1]); | ||
447 | ret |= (rd_word << 8) & 0xff00; | ||
448 | |||
449 | } else | ||
450 | ret = readw(p); | ||
451 | |||
452 | /* Update saved column address */ | ||
453 | host->col_addr = col + 2; | ||
454 | |||
455 | return ret; | ||
456 | } | ||
457 | |||
458 | /* Write data of length len to buffer buf. The data to be | ||
459 | * written on NAND Flash is first copied to RAMbuffer. After the Data Input | ||
460 | * Operation by the NFC, the data is written to NAND Flash */ | ||
461 | static void mxc_nand_write_buf(struct mtd_info *mtd, | ||
462 | const u_char *buf, int len) | ||
463 | { | ||
464 | struct nand_chip *nand_chip = mtd->priv; | ||
465 | struct mxc_nand_host *host = nand_chip->priv; | ||
466 | int n, col, i = 0; | ||
467 | |||
468 | DEBUG(MTD_DEBUG_LEVEL3, | ||
469 | "mxc_nand_write_buf(col = %d, len = %d)\n", host->col_addr, | ||
470 | len); | ||
471 | |||
472 | col = host->col_addr; | ||
473 | |||
474 | /* Adjust saved column address */ | ||
475 | if (col < mtd->writesize && host->spare_only) | ||
476 | col += mtd->writesize; | ||
477 | |||
478 | n = mtd->writesize + mtd->oobsize - col; | ||
479 | n = min(len, n); | ||
480 | |||
481 | DEBUG(MTD_DEBUG_LEVEL3, | ||
482 | "%s:%d: col = %d, n = %d\n", __func__, __LINE__, col, n); | ||
483 | |||
484 | while (n) { | ||
485 | void __iomem *p; | ||
486 | |||
487 | if (col < mtd->writesize) | ||
488 | p = host->regs + MAIN_AREA0 + (col & ~3); | ||
489 | else | ||
490 | p = host->regs + SPARE_AREA0 - | ||
491 | mtd->writesize + (col & ~3); | ||
492 | |||
493 | DEBUG(MTD_DEBUG_LEVEL3, "%s:%d: p = %p\n", __func__, | ||
494 | __LINE__, p); | ||
495 | |||
496 | if (((col | (int)&buf[i]) & 3) || n < 16) { | ||
497 | uint32_t data = 0; | ||
498 | |||
499 | if (col & 3 || n < 4) | ||
500 | data = readl(p); | ||
501 | |||
502 | switch (col & 3) { | ||
503 | case 0: | ||
504 | if (n) { | ||
505 | data = (data & 0xffffff00) | | ||
506 | (buf[i++] << 0); | ||
507 | n--; | ||
508 | col++; | ||
509 | } | ||
510 | case 1: | ||
511 | if (n) { | ||
512 | data = (data & 0xffff00ff) | | ||
513 | (buf[i++] << 8); | ||
514 | n--; | ||
515 | col++; | ||
516 | } | ||
517 | case 2: | ||
518 | if (n) { | ||
519 | data = (data & 0xff00ffff) | | ||
520 | (buf[i++] << 16); | ||
521 | n--; | ||
522 | col++; | ||
523 | } | ||
524 | case 3: | ||
525 | if (n) { | ||
526 | data = (data & 0x00ffffff) | | ||
527 | (buf[i++] << 24); | ||
528 | n--; | ||
529 | col++; | ||
530 | } | ||
531 | } | ||
532 | |||
533 | writel(data, p); | ||
534 | } else { | ||
535 | int m = mtd->writesize - col; | ||
536 | |||
537 | if (col >= mtd->writesize) | ||
538 | m += mtd->oobsize; | ||
539 | |||
540 | m = min(n, m) & ~3; | ||
541 | |||
542 | DEBUG(MTD_DEBUG_LEVEL3, | ||
543 | "%s:%d: n = %d, m = %d, i = %d, col = %d\n", | ||
544 | __func__, __LINE__, n, m, i, col); | ||
545 | |||
546 | memcpy(p, &buf[i], m); | ||
547 | col += m; | ||
548 | i += m; | ||
549 | n -= m; | ||
550 | } | ||
551 | } | ||
552 | /* Update saved column address */ | ||
553 | host->col_addr = col; | ||
554 | } | ||
555 | |||
556 | /* Read the data buffer from the NAND Flash. To read the data from NAND | ||
557 | * Flash first the data output cycle is initiated by the NFC, which copies | ||
558 | * the data to RAMbuffer. This data of length len is then copied to buffer buf. | ||
559 | */ | ||
560 | static void mxc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) | ||
561 | { | ||
562 | struct nand_chip *nand_chip = mtd->priv; | ||
563 | struct mxc_nand_host *host = nand_chip->priv; | ||
564 | int n, col, i = 0; | ||
565 | |||
566 | DEBUG(MTD_DEBUG_LEVEL3, | ||
567 | "mxc_nand_read_buf(col = %d, len = %d)\n", host->col_addr, len); | ||
568 | |||
569 | col = host->col_addr; | ||
570 | |||
571 | /* Adjust saved column address */ | ||
572 | if (col < mtd->writesize && host->spare_only) | ||
573 | col += mtd->writesize; | ||
574 | |||
575 | n = mtd->writesize + mtd->oobsize - col; | ||
576 | n = min(len, n); | ||
577 | |||
578 | while (n) { | ||
579 | void __iomem *p; | ||
580 | |||
581 | if (col < mtd->writesize) | ||
582 | p = host->regs + MAIN_AREA0 + (col & ~3); | ||
583 | else | ||
584 | p = host->regs + SPARE_AREA0 - | ||
585 | mtd->writesize + (col & ~3); | ||
586 | |||
587 | if (((col | (int)&buf[i]) & 3) || n < 16) { | ||
588 | uint32_t data; | ||
589 | |||
590 | data = readl(p); | ||
591 | switch (col & 3) { | ||
592 | case 0: | ||
593 | if (n) { | ||
594 | buf[i++] = (uint8_t) (data); | ||
595 | n--; | ||
596 | col++; | ||
597 | } | ||
598 | case 1: | ||
599 | if (n) { | ||
600 | buf[i++] = (uint8_t) (data >> 8); | ||
601 | n--; | ||
602 | col++; | ||
603 | } | ||
604 | case 2: | ||
605 | if (n) { | ||
606 | buf[i++] = (uint8_t) (data >> 16); | ||
607 | n--; | ||
608 | col++; | ||
609 | } | ||
610 | case 3: | ||
611 | if (n) { | ||
612 | buf[i++] = (uint8_t) (data >> 24); | ||
613 | n--; | ||
614 | col++; | ||
615 | } | ||
616 | } | ||
617 | } else { | ||
618 | int m = mtd->writesize - col; | ||
619 | |||
620 | if (col >= mtd->writesize) | ||
621 | m += mtd->oobsize; | ||
622 | |||
623 | m = min(n, m) & ~3; | ||
624 | memcpy(&buf[i], p, m); | ||
625 | col += m; | ||
626 | i += m; | ||
627 | n -= m; | ||
628 | } | ||
629 | } | ||
630 | /* Update saved column address */ | ||
631 | host->col_addr = col; | ||
632 | |||
633 | } | ||
634 | |||
635 | /* Used by the upper layer to verify the data in NAND Flash | ||
636 | * with the data in the buf. */ | ||
637 | static int mxc_nand_verify_buf(struct mtd_info *mtd, | ||
638 | const u_char *buf, int len) | ||
639 | { | ||
640 | return -EFAULT; | ||
641 | } | ||
642 | |||
643 | /* This function is used by upper layer for select and | ||
644 | * deselect of the NAND chip */ | ||
645 | static void mxc_nand_select_chip(struct mtd_info *mtd, int chip) | ||
646 | { | ||
647 | struct nand_chip *nand_chip = mtd->priv; | ||
648 | struct mxc_nand_host *host = nand_chip->priv; | ||
649 | |||
650 | #ifdef CONFIG_MTD_NAND_MXC_FORCE_CE | ||
651 | if (chip > 0) { | ||
652 | DEBUG(MTD_DEBUG_LEVEL0, | ||
653 | "ERROR: Illegal chip select (chip = %d)\n", chip); | ||
654 | return; | ||
655 | } | ||
656 | |||
657 | if (chip == -1) { | ||
658 | writew(readw(host->regs + NFC_CONFIG1) & ~NFC_CE, | ||
659 | host->regs + NFC_CONFIG1); | ||
660 | return; | ||
661 | } | ||
662 | |||
663 | writew(readw(host->regs + NFC_CONFIG1) | NFC_CE, | ||
664 | host->regs + NFC_CONFIG1); | ||
665 | #endif | ||
666 | |||
667 | switch (chip) { | ||
668 | case -1: | ||
669 | /* Disable the NFC clock */ | ||
670 | if (host->clk_act) { | ||
671 | clk_disable(host->clk); | ||
672 | host->clk_act = 0; | ||
673 | } | ||
674 | break; | ||
675 | case 0: | ||
676 | /* Enable the NFC clock */ | ||
677 | if (!host->clk_act) { | ||
678 | clk_enable(host->clk); | ||
679 | host->clk_act = 1; | ||
680 | } | ||
681 | break; | ||
682 | |||
683 | default: | ||
684 | break; | ||
685 | } | ||
686 | } | ||
687 | |||
688 | /* Used by the upper layer to write command to NAND Flash for | ||
689 | * different operations to be carried out on NAND Flash */ | ||
690 | static void mxc_nand_command(struct mtd_info *mtd, unsigned command, | ||
691 | int column, int page_addr) | ||
692 | { | ||
693 | struct nand_chip *nand_chip = mtd->priv; | ||
694 | struct mxc_nand_host *host = nand_chip->priv; | ||
695 | int useirq = true; | ||
696 | |||
697 | DEBUG(MTD_DEBUG_LEVEL3, | ||
698 | "mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n", | ||
699 | command, column, page_addr); | ||
700 | |||
701 | /* Reset command state information */ | ||
702 | host->status_request = false; | ||
703 | |||
704 | /* Command pre-processing step */ | ||
705 | switch (command) { | ||
706 | |||
707 | case NAND_CMD_STATUS: | ||
708 | host->col_addr = 0; | ||
709 | host->status_request = true; | ||
710 | break; | ||
711 | |||
712 | case NAND_CMD_READ0: | ||
713 | host->col_addr = column; | ||
714 | host->spare_only = false; | ||
715 | useirq = false; | ||
716 | break; | ||
717 | |||
718 | case NAND_CMD_READOOB: | ||
719 | host->col_addr = column; | ||
720 | host->spare_only = true; | ||
721 | useirq = false; | ||
722 | if (host->pagesize_2k) | ||
723 | command = NAND_CMD_READ0; /* only READ0 is valid */ | ||
724 | break; | ||
725 | |||
726 | case NAND_CMD_SEQIN: | ||
727 | if (column >= mtd->writesize) { | ||
728 | /* | ||
729 | * FIXME: before send SEQIN command for write OOB, | ||
730 | * We must read one page out. | ||
731 | * For K9F1GXX has no READ1 command to set current HW | ||
732 | * pointer to spare area, we must write the whole page | ||
733 | * including OOB together. | ||
734 | */ | ||
735 | if (host->pagesize_2k) | ||
736 | /* call ourself to read a page */ | ||
737 | mxc_nand_command(mtd, NAND_CMD_READ0, 0, | ||
738 | page_addr); | ||
739 | |||
740 | host->col_addr = column - mtd->writesize; | ||
741 | host->spare_only = true; | ||
742 | |||
743 | /* Set program pointer to spare region */ | ||
744 | if (!host->pagesize_2k) | ||
745 | send_cmd(host, NAND_CMD_READOOB, false); | ||
746 | } else { | ||
747 | host->spare_only = false; | ||
748 | host->col_addr = column; | ||
749 | |||
750 | /* Set program pointer to page start */ | ||
751 | if (!host->pagesize_2k) | ||
752 | send_cmd(host, NAND_CMD_READ0, false); | ||
753 | } | ||
754 | useirq = false; | ||
755 | break; | ||
756 | |||
757 | case NAND_CMD_PAGEPROG: | ||
758 | send_prog_page(host, 0, host->spare_only); | ||
759 | |||
760 | if (host->pagesize_2k) { | ||
761 | /* data in 4 areas datas */ | ||
762 | send_prog_page(host, 1, host->spare_only); | ||
763 | send_prog_page(host, 2, host->spare_only); | ||
764 | send_prog_page(host, 3, host->spare_only); | ||
765 | } | ||
766 | |||
767 | break; | ||
768 | |||
769 | case NAND_CMD_ERASE1: | ||
770 | useirq = false; | ||
771 | break; | ||
772 | } | ||
773 | |||
774 | /* Write out the command to the device. */ | ||
775 | send_cmd(host, command, useirq); | ||
776 | |||
777 | /* Write out column address, if necessary */ | ||
778 | if (column != -1) { | ||
779 | /* | ||
780 | * MXC NANDFC can only perform full page+spare or | ||
781 | * spare-only read/write. When the upper layers | ||
782 | * layers perform a read/write buf operation, | ||
783 | * we will used the saved column adress to index into | ||
784 | * the full page. | ||
785 | */ | ||
786 | send_addr(host, 0, page_addr == -1); | ||
787 | if (host->pagesize_2k) | ||
788 | /* another col addr cycle for 2k page */ | ||
789 | send_addr(host, 0, false); | ||
790 | } | ||
791 | |||
792 | /* Write out page address, if necessary */ | ||
793 | if (page_addr != -1) { | ||
794 | /* paddr_0 - p_addr_7 */ | ||
795 | send_addr(host, (page_addr & 0xff), false); | ||
796 | |||
797 | if (host->pagesize_2k) { | ||
798 | send_addr(host, (page_addr >> 8) & 0xFF, false); | ||
799 | if (mtd->size >= 0x40000000) | ||
800 | send_addr(host, (page_addr >> 16) & 0xff, true); | ||
801 | } else { | ||
802 | /* One more address cycle for higher density devices */ | ||
803 | if (mtd->size >= 0x4000000) { | ||
804 | /* paddr_8 - paddr_15 */ | ||
805 | send_addr(host, (page_addr >> 8) & 0xff, false); | ||
806 | send_addr(host, (page_addr >> 16) & 0xff, true); | ||
807 | } else | ||
808 | /* paddr_8 - paddr_15 */ | ||
809 | send_addr(host, (page_addr >> 8) & 0xff, true); | ||
810 | } | ||
811 | } | ||
812 | |||
813 | /* Command post-processing step */ | ||
814 | switch (command) { | ||
815 | |||
816 | case NAND_CMD_RESET: | ||
817 | break; | ||
818 | |||
819 | case NAND_CMD_READOOB: | ||
820 | case NAND_CMD_READ0: | ||
821 | if (host->pagesize_2k) { | ||
822 | /* send read confirm command */ | ||
823 | send_cmd(host, NAND_CMD_READSTART, true); | ||
824 | /* read for each AREA */ | ||
825 | send_read_page(host, 0, host->spare_only); | ||
826 | send_read_page(host, 1, host->spare_only); | ||
827 | send_read_page(host, 2, host->spare_only); | ||
828 | send_read_page(host, 3, host->spare_only); | ||
829 | } else | ||
830 | send_read_page(host, 0, host->spare_only); | ||
831 | break; | ||
832 | |||
833 | case NAND_CMD_READID: | ||
834 | send_read_id(host); | ||
835 | break; | ||
836 | |||
837 | case NAND_CMD_PAGEPROG: | ||
838 | break; | ||
839 | |||
840 | case NAND_CMD_STATUS: | ||
841 | break; | ||
842 | |||
843 | case NAND_CMD_ERASE2: | ||
844 | break; | ||
845 | } | ||
846 | } | ||
847 | |||
848 | static int __init mxcnd_probe(struct platform_device *pdev) | ||
849 | { | ||
850 | struct nand_chip *this; | ||
851 | struct mtd_info *mtd; | ||
852 | struct mxc_nand_platform_data *pdata = pdev->dev.platform_data; | ||
853 | struct mxc_nand_host *host; | ||
854 | struct resource *res; | ||
855 | uint16_t tmp; | ||
856 | int err = 0, nr_parts = 0; | ||
857 | |||
858 | /* Allocate memory for MTD device structure and private data */ | ||
859 | host = kzalloc(sizeof(struct mxc_nand_host), GFP_KERNEL); | ||
860 | if (!host) | ||
861 | return -ENOMEM; | ||
862 | |||
863 | host->dev = &pdev->dev; | ||
864 | /* structures must be linked */ | ||
865 | this = &host->nand; | ||
866 | mtd = &host->mtd; | ||
867 | mtd->priv = this; | ||
868 | mtd->owner = THIS_MODULE; | ||
869 | |||
870 | /* 50 us command delay time */ | ||
871 | this->chip_delay = 5; | ||
872 | |||
873 | this->priv = host; | ||
874 | this->dev_ready = mxc_nand_dev_ready; | ||
875 | this->cmdfunc = mxc_nand_command; | ||
876 | this->select_chip = mxc_nand_select_chip; | ||
877 | this->read_byte = mxc_nand_read_byte; | ||
878 | this->read_word = mxc_nand_read_word; | ||
879 | this->write_buf = mxc_nand_write_buf; | ||
880 | this->read_buf = mxc_nand_read_buf; | ||
881 | this->verify_buf = mxc_nand_verify_buf; | ||
882 | |||
883 | host->clk = clk_get(&pdev->dev, "nfc_clk"); | ||
884 | if (IS_ERR(host->clk)) | ||
885 | goto eclk; | ||
886 | |||
887 | clk_enable(host->clk); | ||
888 | host->clk_act = 1; | ||
889 | |||
890 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
891 | if (!res) { | ||
892 | err = -ENODEV; | ||
893 | goto eres; | ||
894 | } | ||
895 | |||
896 | host->regs = ioremap(res->start, res->end - res->start + 1); | ||
897 | if (!host->regs) { | ||
898 | err = -EIO; | ||
899 | goto eres; | ||
900 | } | ||
901 | |||
902 | tmp = readw(host->regs + NFC_CONFIG1); | ||
903 | tmp |= NFC_INT_MSK; | ||
904 | writew(tmp, host->regs + NFC_CONFIG1); | ||
905 | |||
906 | init_waitqueue_head(&host->irq_waitq); | ||
907 | |||
908 | host->irq = platform_get_irq(pdev, 0); | ||
909 | |||
910 | err = request_irq(host->irq, mxc_nfc_irq, 0, "mxc_nd", host); | ||
911 | if (err) | ||
912 | goto eirq; | ||
913 | |||
914 | if (pdata->hw_ecc) { | ||
915 | this->ecc.calculate = mxc_nand_calculate_ecc; | ||
916 | this->ecc.hwctl = mxc_nand_enable_hwecc; | ||
917 | this->ecc.correct = mxc_nand_correct_data; | ||
918 | this->ecc.mode = NAND_ECC_HW; | ||
919 | this->ecc.size = 512; | ||
920 | this->ecc.bytes = 3; | ||
921 | this->ecc.layout = &nand_hw_eccoob_8; | ||
922 | tmp = readw(host->regs + NFC_CONFIG1); | ||
923 | tmp |= NFC_ECC_EN; | ||
924 | writew(tmp, host->regs + NFC_CONFIG1); | ||
925 | } else { | ||
926 | this->ecc.size = 512; | ||
927 | this->ecc.bytes = 3; | ||
928 | this->ecc.layout = &nand_hw_eccoob_8; | ||
929 | this->ecc.mode = NAND_ECC_SOFT; | ||
930 | tmp = readw(host->regs + NFC_CONFIG1); | ||
931 | tmp &= ~NFC_ECC_EN; | ||
932 | writew(tmp, host->regs + NFC_CONFIG1); | ||
933 | } | ||
934 | |||
935 | /* Reset NAND */ | ||
936 | this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); | ||
937 | |||
938 | /* preset operation */ | ||
939 | /* Unlock the internal RAM Buffer */ | ||
940 | writew(0x2, host->regs + NFC_CONFIG); | ||
941 | |||
942 | /* Blocks to be unlocked */ | ||
943 | writew(0x0, host->regs + NFC_UNLOCKSTART_BLKADDR); | ||
944 | writew(0x4000, host->regs + NFC_UNLOCKEND_BLKADDR); | ||
945 | |||
946 | /* Unlock Block Command for given address range */ | ||
947 | writew(0x4, host->regs + NFC_WRPROT); | ||
948 | |||
949 | /* NAND bus width determines access funtions used by upper layer */ | ||
950 | if (pdata->width == 2) { | ||
951 | this->options |= NAND_BUSWIDTH_16; | ||
952 | this->ecc.layout = &nand_hw_eccoob_16; | ||
953 | } | ||
954 | |||
955 | host->pagesize_2k = 0; | ||
956 | |||
957 | /* Scan to find existence of the device */ | ||
958 | if (nand_scan(mtd, 1)) { | ||
959 | DEBUG(MTD_DEBUG_LEVEL0, | ||
960 | "MXC_ND: Unable to find any NAND device.\n"); | ||
961 | err = -ENXIO; | ||
962 | goto escan; | ||
963 | } | ||
964 | |||
965 | /* Register the partitions */ | ||
966 | #ifdef CONFIG_MTD_PARTITIONS | ||
967 | nr_parts = | ||
968 | parse_mtd_partitions(mtd, part_probes, &host->parts, 0); | ||
969 | if (nr_parts > 0) | ||
970 | add_mtd_partitions(mtd, host->parts, nr_parts); | ||
971 | else | ||
972 | #endif | ||
973 | { | ||
974 | pr_info("Registering %s as whole device\n", mtd->name); | ||
975 | add_mtd_device(mtd); | ||
976 | } | ||
977 | |||
978 | platform_set_drvdata(pdev, host); | ||
979 | |||
980 | return 0; | ||
981 | |||
982 | escan: | ||
983 | free_irq(host->irq, NULL); | ||
984 | eirq: | ||
985 | iounmap(host->regs); | ||
986 | eres: | ||
987 | clk_put(host->clk); | ||
988 | eclk: | ||
989 | kfree(host); | ||
990 | |||
991 | return err; | ||
992 | } | ||
993 | |||
994 | static int __devexit mxcnd_remove(struct platform_device *pdev) | ||
995 | { | ||
996 | struct mxc_nand_host *host = platform_get_drvdata(pdev); | ||
997 | |||
998 | clk_put(host->clk); | ||
999 | |||
1000 | platform_set_drvdata(pdev, NULL); | ||
1001 | |||
1002 | nand_release(&host->mtd); | ||
1003 | free_irq(host->irq, NULL); | ||
1004 | iounmap(host->regs); | ||
1005 | kfree(host); | ||
1006 | |||
1007 | return 0; | ||
1008 | } | ||
1009 | |||
1010 | #ifdef CONFIG_PM | ||
1011 | static int mxcnd_suspend(struct platform_device *pdev, pm_message_t state) | ||
1012 | { | ||
1013 | struct mtd_info *info = platform_get_drvdata(pdev); | ||
1014 | int ret = 0; | ||
1015 | |||
1016 | DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND : NAND suspend\n"); | ||
1017 | if (info) | ||
1018 | ret = info->suspend(info); | ||
1019 | |||
1020 | /* Disable the NFC clock */ | ||
1021 | clk_disable(nfc_clk); /* FIXME */ | ||
1022 | |||
1023 | return ret; | ||
1024 | } | ||
1025 | |||
1026 | static int mxcnd_resume(struct platform_device *pdev) | ||
1027 | { | ||
1028 | struct mtd_info *info = platform_get_drvdata(pdev); | ||
1029 | int ret = 0; | ||
1030 | |||
1031 | DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND : NAND resume\n"); | ||
1032 | /* Enable the NFC clock */ | ||
1033 | clk_enable(nfc_clk); /* FIXME */ | ||
1034 | |||
1035 | if (info) | ||
1036 | info->resume(info); | ||
1037 | |||
1038 | return ret; | ||
1039 | } | ||
1040 | |||
1041 | #else | ||
1042 | # define mxcnd_suspend NULL | ||
1043 | # define mxcnd_resume NULL | ||
1044 | #endif /* CONFIG_PM */ | ||
1045 | |||
1046 | static struct platform_driver mxcnd_driver = { | ||
1047 | .driver = { | ||
1048 | .name = DRIVER_NAME, | ||
1049 | }, | ||
1050 | .remove = __exit_p(mxcnd_remove), | ||
1051 | .suspend = mxcnd_suspend, | ||
1052 | .resume = mxcnd_resume, | ||
1053 | }; | ||
1054 | |||
1055 | static int __init mxc_nd_init(void) | ||
1056 | { | ||
1057 | /* Register the device driver structure. */ | ||
1058 | pr_info("MXC MTD nand Driver\n"); | ||
1059 | if (platform_driver_probe(&mxcnd_driver, mxcnd_probe) != 0) { | ||
1060 | printk(KERN_ERR "Driver register failed for mxcnd_driver\n"); | ||
1061 | return -ENODEV; | ||
1062 | } | ||
1063 | return 0; | ||
1064 | } | ||
1065 | |||
1066 | static void __exit mxc_nd_cleanup(void) | ||
1067 | { | ||
1068 | /* Unregister the device structure */ | ||
1069 | platform_driver_unregister(&mxcnd_driver); | ||
1070 | } | ||
1071 | |||
1072 | module_init(mxc_nd_init); | ||
1073 | module_exit(mxc_nd_cleanup); | ||
1074 | |||
1075 | MODULE_AUTHOR("Freescale Semiconductor, Inc."); | ||
1076 | MODULE_DESCRIPTION("MXC NAND MTD driver"); | ||
1077 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index d1129bae6c27..0a9c9cd33f96 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -801,9 +801,9 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
801 | * nand_read_subpage - [REPLACABLE] software ecc based sub-page read function | 801 | * nand_read_subpage - [REPLACABLE] software ecc based sub-page read function |
802 | * @mtd: mtd info structure | 802 | * @mtd: mtd info structure |
803 | * @chip: nand chip info structure | 803 | * @chip: nand chip info structure |
804 | * @dataofs offset of requested data within the page | 804 | * @data_offs: offset of requested data within the page |
805 | * @readlen data length | 805 | * @readlen: data length |
806 | * @buf: buffer to store read data | 806 | * @bufpoi: buffer to store read data |
807 | */ | 807 | */ |
808 | static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi) | 808 | static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi) |
809 | { | 809 | { |
@@ -2042,7 +2042,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, | |||
2042 | return -EINVAL; | 2042 | return -EINVAL; |
2043 | } | 2043 | } |
2044 | 2044 | ||
2045 | instr->fail_addr = 0xffffffff; | 2045 | instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; |
2046 | 2046 | ||
2047 | /* Grab the lock and see if the device is available */ | 2047 | /* Grab the lock and see if the device is available */ |
2048 | nand_get_device(chip, mtd, FL_ERASING); | 2048 | nand_get_device(chip, mtd, FL_ERASING); |
@@ -2318,6 +2318,12 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2318 | /* Select the device */ | 2318 | /* Select the device */ |
2319 | chip->select_chip(mtd, 0); | 2319 | chip->select_chip(mtd, 0); |
2320 | 2320 | ||
2321 | /* | ||
2322 | * Reset the chip, required by some chips (e.g. Micron MT29FxGxxxxx) | ||
2323 | * after power-up | ||
2324 | */ | ||
2325 | chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); | ||
2326 | |||
2321 | /* Send the command for reading device ID */ | 2327 | /* Send the command for reading device ID */ |
2322 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); | 2328 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); |
2323 | 2329 | ||
@@ -2488,6 +2494,8 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips) | |||
2488 | /* Check for a chip array */ | 2494 | /* Check for a chip array */ |
2489 | for (i = 1; i < maxchips; i++) { | 2495 | for (i = 1; i < maxchips; i++) { |
2490 | chip->select_chip(mtd, i); | 2496 | chip->select_chip(mtd, i); |
2497 | /* See comment in nand_get_flash_type for reset */ | ||
2498 | chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); | ||
2491 | /* Send the command for reading device ID */ | 2499 | /* Send the command for reading device ID */ |
2492 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); | 2500 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); |
2493 | /* Read manufacturer and device IDs */ | 2501 | /* Read manufacturer and device IDs */ |
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c index 918a806a8471..868147acce2c 100644 --- a/drivers/mtd/nand/nand_ecc.c +++ b/drivers/mtd/nand/nand_ecc.c | |||
@@ -1,13 +1,18 @@ | |||
1 | /* | 1 | /* |
2 | * This file contains an ECC algorithm from Toshiba that detects and | 2 | * This file contains an ECC algorithm that detects and corrects 1 bit |
3 | * corrects 1 bit errors in a 256 byte block of data. | 3 | * errors in a 256 byte block of data. |
4 | * | 4 | * |
5 | * drivers/mtd/nand/nand_ecc.c | 5 | * drivers/mtd/nand/nand_ecc.c |
6 | * | 6 | * |
7 | * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com) | 7 | * Copyright © 2008 Koninklijke Philips Electronics NV. |
8 | * Toshiba America Electronics Components, Inc. | 8 | * Author: Frans Meulenbroeks |
9 | * | 9 | * |
10 | * Copyright (C) 2006 Thomas Gleixner <tglx@linutronix.de> | 10 | * Completely replaces the previous ECC implementation which was written by: |
11 | * Steven J. Hill (sjhill@realitydiluted.com) | ||
12 | * Thomas Gleixner (tglx@linutronix.de) | ||
13 | * | ||
14 | * Information on how this algorithm works and how it was developed | ||
15 | * can be found in Documentation/mtd/nand_ecc.txt | ||
11 | * | 16 | * |
12 | * This file is free software; you can redistribute it and/or modify it | 17 | * This file is free software; you can redistribute it and/or modify it |
13 | * under the terms of the GNU General Public License as published by the | 18 | * under the terms of the GNU General Public License as published by the |
@@ -23,174 +28,475 @@ | |||
23 | * with this file; if not, write to the Free Software Foundation, Inc., | 28 | * with this file; if not, write to the Free Software Foundation, Inc., |
24 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | 29 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
25 | * | 30 | * |
26 | * As a special exception, if other files instantiate templates or use | ||
27 | * macros or inline functions from these files, or you compile these | ||
28 | * files and link them with other works to produce a work based on these | ||
29 | * files, these files do not by themselves cause the resulting work to be | ||
30 | * covered by the GNU General Public License. However the source code for | ||
31 | * these files must still be made available in accordance with section (3) | ||
32 | * of the GNU General Public License. | ||
33 | * | ||
34 | * This exception does not invalidate any other reasons why a work based on | ||
35 | * this file might be covered by the GNU General Public License. | ||
36 | */ | 31 | */ |
37 | 32 | ||
33 | /* | ||
34 | * The STANDALONE macro is useful when running the code outside the kernel | ||
35 | * e.g. when running the code in a testbed or a benchmark program. | ||
36 | * When STANDALONE is used, the module related macros are commented out | ||
37 | * as well as the linux include files. | ||
38 | * Instead a private definition of mtd_info is given to satisfy the compiler | ||
39 | * (the code does not use mtd_info, so the code does not care) | ||
40 | */ | ||
41 | #ifndef STANDALONE | ||
38 | #include <linux/types.h> | 42 | #include <linux/types.h> |
39 | #include <linux/kernel.h> | 43 | #include <linux/kernel.h> |
40 | #include <linux/module.h> | 44 | #include <linux/module.h> |
45 | #include <linux/mtd/mtd.h> | ||
46 | #include <linux/mtd/nand.h> | ||
41 | #include <linux/mtd/nand_ecc.h> | 47 | #include <linux/mtd/nand_ecc.h> |
48 | #include <asm/byteorder.h> | ||
49 | #else | ||
50 | #include <stdint.h> | ||
51 | struct mtd_info; | ||
52 | #define EXPORT_SYMBOL(x) /* x */ | ||
53 | |||
54 | #define MODULE_LICENSE(x) /* x */ | ||
55 | #define MODULE_AUTHOR(x) /* x */ | ||
56 | #define MODULE_DESCRIPTION(x) /* x */ | ||
57 | |||
58 | #define printk printf | ||
59 | #define KERN_ERR "" | ||
60 | #endif | ||
61 | |||
62 | /* | ||
63 | * invparity is a 256 byte table that contains the odd parity | ||
64 | * for each byte. So if the number of bits in a byte is even, | ||
65 | * the array element is 1, and when the number of bits is odd | ||
66 | * the array eleemnt is 0. | ||
67 | */ | ||
68 | static const char invparity[256] = { | ||
69 | 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, | ||
70 | 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, | ||
71 | 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, | ||
72 | 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, | ||
73 | 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, | ||
74 | 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, | ||
75 | 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, | ||
76 | 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, | ||
77 | 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, | ||
78 | 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, | ||
79 | 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, | ||
80 | 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, | ||
81 | 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, | ||
82 | 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, | ||
83 | 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, | ||
84 | 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 | ||
85 | }; | ||
86 | |||
87 | /* | ||
88 | * bitsperbyte contains the number of bits per byte | ||
89 | * this is only used for testing and repairing parity | ||
90 | * (a precalculated value slightly improves performance) | ||
91 | */ | ||
92 | static const char bitsperbyte[256] = { | ||
93 | 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, | ||
94 | 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, | ||
95 | 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, | ||
96 | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, | ||
97 | 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, | ||
98 | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, | ||
99 | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, | ||
100 | 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, | ||
101 | 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, | ||
102 | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, | ||
103 | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, | ||
104 | 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, | ||
105 | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, | ||
106 | 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, | ||
107 | 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, | ||
108 | 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, | ||
109 | }; | ||
42 | 110 | ||
43 | /* | 111 | /* |
44 | * Pre-calculated 256-way 1 byte column parity | 112 | * addressbits is a lookup table to filter out the bits from the xor-ed |
113 | * ecc data that identify the faulty location. | ||
114 | * this is only used for repairing parity | ||
115 | * see the comments in nand_correct_data for more details | ||
45 | */ | 116 | */ |
46 | static const u_char nand_ecc_precalc_table[] = { | 117 | static const char addressbits[256] = { |
47 | 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00, | 118 | 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, |
48 | 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, | 119 | 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, |
49 | 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, | 120 | 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, |
50 | 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, | 121 | 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, |
51 | 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, | 122 | 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05, |
52 | 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, | 123 | 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07, |
53 | 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, | 124 | 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05, |
54 | 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, | 125 | 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07, |
55 | 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, | 126 | 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, |
56 | 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, | 127 | 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, |
57 | 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, | 128 | 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, |
58 | 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, | 129 | 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03, |
59 | 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, | 130 | 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05, |
60 | 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, | 131 | 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07, |
61 | 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, | 132 | 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05, |
62 | 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00 | 133 | 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07, |
134 | 0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09, | ||
135 | 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b, | ||
136 | 0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09, | ||
137 | 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b, | ||
138 | 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d, | ||
139 | 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f, | ||
140 | 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d, | ||
141 | 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f, | ||
142 | 0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09, | ||
143 | 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b, | ||
144 | 0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09, | ||
145 | 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b, | ||
146 | 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d, | ||
147 | 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f, | ||
148 | 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d, | ||
149 | 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f | ||
63 | }; | 150 | }; |
64 | 151 | ||
65 | /** | 152 | /** |
66 | * nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256-byte block | 153 | * nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256/512-byte |
154 | * block | ||
67 | * @mtd: MTD block structure | 155 | * @mtd: MTD block structure |
68 | * @dat: raw data | 156 | * @buf: input buffer with raw data |
69 | * @ecc_code: buffer for ECC | 157 | * @code: output buffer with ECC |
70 | */ | 158 | */ |
71 | int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, | 159 | int nand_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf, |
72 | u_char *ecc_code) | 160 | unsigned char *code) |
73 | { | 161 | { |
74 | uint8_t idx, reg1, reg2, reg3, tmp1, tmp2; | ||
75 | int i; | 162 | int i; |
163 | const uint32_t *bp = (uint32_t *)buf; | ||
164 | /* 256 or 512 bytes/ecc */ | ||
165 | const uint32_t eccsize_mult = | ||
166 | (((struct nand_chip *)mtd->priv)->ecc.size) >> 8; | ||
167 | uint32_t cur; /* current value in buffer */ | ||
168 | /* rp0..rp15..rp17 are the various accumulated parities (per byte) */ | ||
169 | uint32_t rp0, rp1, rp2, rp3, rp4, rp5, rp6, rp7; | ||
170 | uint32_t rp8, rp9, rp10, rp11, rp12, rp13, rp14, rp15, rp16; | ||
171 | uint32_t uninitialized_var(rp17); /* to make compiler happy */ | ||
172 | uint32_t par; /* the cumulative parity for all data */ | ||
173 | uint32_t tmppar; /* the cumulative parity for this iteration; | ||
174 | for rp12, rp14 and rp16 at the end of the | ||
175 | loop */ | ||
176 | |||
177 | par = 0; | ||
178 | rp4 = 0; | ||
179 | rp6 = 0; | ||
180 | rp8 = 0; | ||
181 | rp10 = 0; | ||
182 | rp12 = 0; | ||
183 | rp14 = 0; | ||
184 | rp16 = 0; | ||
185 | |||
186 | /* | ||
187 | * The loop is unrolled a number of times; | ||
188 | * This avoids if statements to decide on which rp value to update | ||
189 | * Also we process the data by longwords. | ||
190 | * Note: passing unaligned data might give a performance penalty. | ||
191 | * It is assumed that the buffers are aligned. | ||
192 | * tmppar is the cumulative sum of this iteration. | ||
193 | * needed for calculating rp12, rp14, rp16 and par | ||
194 | * also used as a performance improvement for rp6, rp8 and rp10 | ||
195 | */ | ||
196 | for (i = 0; i < eccsize_mult << 2; i++) { | ||
197 | cur = *bp++; | ||
198 | tmppar = cur; | ||
199 | rp4 ^= cur; | ||
200 | cur = *bp++; | ||
201 | tmppar ^= cur; | ||
202 | rp6 ^= tmppar; | ||
203 | cur = *bp++; | ||
204 | tmppar ^= cur; | ||
205 | rp4 ^= cur; | ||
206 | cur = *bp++; | ||
207 | tmppar ^= cur; | ||
208 | rp8 ^= tmppar; | ||
76 | 209 | ||
77 | /* Initialize variables */ | 210 | cur = *bp++; |
78 | reg1 = reg2 = reg3 = 0; | 211 | tmppar ^= cur; |
212 | rp4 ^= cur; | ||
213 | rp6 ^= cur; | ||
214 | cur = *bp++; | ||
215 | tmppar ^= cur; | ||
216 | rp6 ^= cur; | ||
217 | cur = *bp++; | ||
218 | tmppar ^= cur; | ||
219 | rp4 ^= cur; | ||
220 | cur = *bp++; | ||
221 | tmppar ^= cur; | ||
222 | rp10 ^= tmppar; | ||
79 | 223 | ||
80 | /* Build up column parity */ | 224 | cur = *bp++; |
81 | for(i = 0; i < 256; i++) { | 225 | tmppar ^= cur; |
82 | /* Get CP0 - CP5 from table */ | 226 | rp4 ^= cur; |
83 | idx = nand_ecc_precalc_table[*dat++]; | 227 | rp6 ^= cur; |
84 | reg1 ^= (idx & 0x3f); | 228 | rp8 ^= cur; |
229 | cur = *bp++; | ||
230 | tmppar ^= cur; | ||
231 | rp6 ^= cur; | ||
232 | rp8 ^= cur; | ||
233 | cur = *bp++; | ||
234 | tmppar ^= cur; | ||
235 | rp4 ^= cur; | ||
236 | rp8 ^= cur; | ||
237 | cur = *bp++; | ||
238 | tmppar ^= cur; | ||
239 | rp8 ^= cur; | ||
85 | 240 | ||
86 | /* All bit XOR = 1 ? */ | 241 | cur = *bp++; |
87 | if (idx & 0x40) { | 242 | tmppar ^= cur; |
88 | reg3 ^= (uint8_t) i; | 243 | rp4 ^= cur; |
89 | reg2 ^= ~((uint8_t) i); | 244 | rp6 ^= cur; |
90 | } | 245 | cur = *bp++; |
246 | tmppar ^= cur; | ||
247 | rp6 ^= cur; | ||
248 | cur = *bp++; | ||
249 | tmppar ^= cur; | ||
250 | rp4 ^= cur; | ||
251 | cur = *bp++; | ||
252 | tmppar ^= cur; | ||
253 | |||
254 | par ^= tmppar; | ||
255 | if ((i & 0x1) == 0) | ||
256 | rp12 ^= tmppar; | ||
257 | if ((i & 0x2) == 0) | ||
258 | rp14 ^= tmppar; | ||
259 | if (eccsize_mult == 2 && (i & 0x4) == 0) | ||
260 | rp16 ^= tmppar; | ||
91 | } | 261 | } |
92 | 262 | ||
93 | /* Create non-inverted ECC code from line parity */ | 263 | /* |
94 | tmp1 = (reg3 & 0x80) >> 0; /* B7 -> B7 */ | 264 | * handle the fact that we use longword operations |
95 | tmp1 |= (reg2 & 0x80) >> 1; /* B7 -> B6 */ | 265 | * we'll bring rp4..rp14..rp16 back to single byte entities by |
96 | tmp1 |= (reg3 & 0x40) >> 1; /* B6 -> B5 */ | 266 | * shifting and xoring first fold the upper and lower 16 bits, |
97 | tmp1 |= (reg2 & 0x40) >> 2; /* B6 -> B4 */ | 267 | * then the upper and lower 8 bits. |
98 | tmp1 |= (reg3 & 0x20) >> 2; /* B5 -> B3 */ | 268 | */ |
99 | tmp1 |= (reg2 & 0x20) >> 3; /* B5 -> B2 */ | 269 | rp4 ^= (rp4 >> 16); |
100 | tmp1 |= (reg3 & 0x10) >> 3; /* B4 -> B1 */ | 270 | rp4 ^= (rp4 >> 8); |
101 | tmp1 |= (reg2 & 0x10) >> 4; /* B4 -> B0 */ | 271 | rp4 &= 0xff; |
102 | 272 | rp6 ^= (rp6 >> 16); | |
103 | tmp2 = (reg3 & 0x08) << 4; /* B3 -> B7 */ | 273 | rp6 ^= (rp6 >> 8); |
104 | tmp2 |= (reg2 & 0x08) << 3; /* B3 -> B6 */ | 274 | rp6 &= 0xff; |
105 | tmp2 |= (reg3 & 0x04) << 3; /* B2 -> B5 */ | 275 | rp8 ^= (rp8 >> 16); |
106 | tmp2 |= (reg2 & 0x04) << 2; /* B2 -> B4 */ | 276 | rp8 ^= (rp8 >> 8); |
107 | tmp2 |= (reg3 & 0x02) << 2; /* B1 -> B3 */ | 277 | rp8 &= 0xff; |
108 | tmp2 |= (reg2 & 0x02) << 1; /* B1 -> B2 */ | 278 | rp10 ^= (rp10 >> 16); |
109 | tmp2 |= (reg3 & 0x01) << 1; /* B0 -> B1 */ | 279 | rp10 ^= (rp10 >> 8); |
110 | tmp2 |= (reg2 & 0x01) << 0; /* B7 -> B0 */ | 280 | rp10 &= 0xff; |
111 | 281 | rp12 ^= (rp12 >> 16); | |
112 | /* Calculate final ECC code */ | 282 | rp12 ^= (rp12 >> 8); |
113 | #ifdef CONFIG_MTD_NAND_ECC_SMC | 283 | rp12 &= 0xff; |
114 | ecc_code[0] = ~tmp2; | 284 | rp14 ^= (rp14 >> 16); |
115 | ecc_code[1] = ~tmp1; | 285 | rp14 ^= (rp14 >> 8); |
286 | rp14 &= 0xff; | ||
287 | if (eccsize_mult == 2) { | ||
288 | rp16 ^= (rp16 >> 16); | ||
289 | rp16 ^= (rp16 >> 8); | ||
290 | rp16 &= 0xff; | ||
291 | } | ||
292 | |||
293 | /* | ||
294 | * we also need to calculate the row parity for rp0..rp3 | ||
295 | * This is present in par, because par is now | ||
296 | * rp3 rp3 rp2 rp2 in little endian and | ||
297 | * rp2 rp2 rp3 rp3 in big endian | ||
298 | * as well as | ||
299 | * rp1 rp0 rp1 rp0 in little endian and | ||
300 | * rp0 rp1 rp0 rp1 in big endian | ||
301 | * First calculate rp2 and rp3 | ||
302 | */ | ||
303 | #ifdef __BIG_ENDIAN | ||
304 | rp2 = (par >> 16); | ||
305 | rp2 ^= (rp2 >> 8); | ||
306 | rp2 &= 0xff; | ||
307 | rp3 = par & 0xffff; | ||
308 | rp3 ^= (rp3 >> 8); | ||
309 | rp3 &= 0xff; | ||
116 | #else | 310 | #else |
117 | ecc_code[0] = ~tmp1; | 311 | rp3 = (par >> 16); |
118 | ecc_code[1] = ~tmp2; | 312 | rp3 ^= (rp3 >> 8); |
313 | rp3 &= 0xff; | ||
314 | rp2 = par & 0xffff; | ||
315 | rp2 ^= (rp2 >> 8); | ||
316 | rp2 &= 0xff; | ||
119 | #endif | 317 | #endif |
120 | ecc_code[2] = ((~reg1) << 2) | 0x03; | ||
121 | 318 | ||
122 | return 0; | 319 | /* reduce par to 16 bits then calculate rp1 and rp0 */ |
123 | } | 320 | par ^= (par >> 16); |
124 | EXPORT_SYMBOL(nand_calculate_ecc); | 321 | #ifdef __BIG_ENDIAN |
322 | rp0 = (par >> 8) & 0xff; | ||
323 | rp1 = (par & 0xff); | ||
324 | #else | ||
325 | rp1 = (par >> 8) & 0xff; | ||
326 | rp0 = (par & 0xff); | ||
327 | #endif | ||
125 | 328 | ||
126 | static inline int countbits(uint32_t byte) | 329 | /* finally reduce par to 8 bits */ |
127 | { | 330 | par ^= (par >> 8); |
128 | int res = 0; | 331 | par &= 0xff; |
129 | 332 | ||
130 | for (;byte; byte >>= 1) | 333 | /* |
131 | res += byte & 0x01; | 334 | * and calculate rp5..rp15..rp17 |
132 | return res; | 335 | * note that par = rp4 ^ rp5 and due to the commutative property |
336 | * of the ^ operator we can say: | ||
337 | * rp5 = (par ^ rp4); | ||
338 | * The & 0xff seems superfluous, but benchmarking learned that | ||
339 | * leaving it out gives slightly worse results. No idea why, probably | ||
340 | * it has to do with the way the pipeline in pentium is organized. | ||
341 | */ | ||
342 | rp5 = (par ^ rp4) & 0xff; | ||
343 | rp7 = (par ^ rp6) & 0xff; | ||
344 | rp9 = (par ^ rp8) & 0xff; | ||
345 | rp11 = (par ^ rp10) & 0xff; | ||
346 | rp13 = (par ^ rp12) & 0xff; | ||
347 | rp15 = (par ^ rp14) & 0xff; | ||
348 | if (eccsize_mult == 2) | ||
349 | rp17 = (par ^ rp16) & 0xff; | ||
350 | |||
351 | /* | ||
352 | * Finally calculate the ecc bits. | ||
353 | * Again here it might seem that there are performance optimisations | ||
354 | * possible, but benchmarks showed that on the system this is developed | ||
355 | * the code below is the fastest | ||
356 | */ | ||
357 | #ifdef CONFIG_MTD_NAND_ECC_SMC | ||
358 | code[0] = | ||
359 | (invparity[rp7] << 7) | | ||
360 | (invparity[rp6] << 6) | | ||
361 | (invparity[rp5] << 5) | | ||
362 | (invparity[rp4] << 4) | | ||
363 | (invparity[rp3] << 3) | | ||
364 | (invparity[rp2] << 2) | | ||
365 | (invparity[rp1] << 1) | | ||
366 | (invparity[rp0]); | ||
367 | code[1] = | ||
368 | (invparity[rp15] << 7) | | ||
369 | (invparity[rp14] << 6) | | ||
370 | (invparity[rp13] << 5) | | ||
371 | (invparity[rp12] << 4) | | ||
372 | (invparity[rp11] << 3) | | ||
373 | (invparity[rp10] << 2) | | ||
374 | (invparity[rp9] << 1) | | ||
375 | (invparity[rp8]); | ||
376 | #else | ||
377 | code[1] = | ||
378 | (invparity[rp7] << 7) | | ||
379 | (invparity[rp6] << 6) | | ||
380 | (invparity[rp5] << 5) | | ||
381 | (invparity[rp4] << 4) | | ||
382 | (invparity[rp3] << 3) | | ||
383 | (invparity[rp2] << 2) | | ||
384 | (invparity[rp1] << 1) | | ||
385 | (invparity[rp0]); | ||
386 | code[0] = | ||
387 | (invparity[rp15] << 7) | | ||
388 | (invparity[rp14] << 6) | | ||
389 | (invparity[rp13] << 5) | | ||
390 | (invparity[rp12] << 4) | | ||
391 | (invparity[rp11] << 3) | | ||
392 | (invparity[rp10] << 2) | | ||
393 | (invparity[rp9] << 1) | | ||
394 | (invparity[rp8]); | ||
395 | #endif | ||
396 | if (eccsize_mult == 1) | ||
397 | code[2] = | ||
398 | (invparity[par & 0xf0] << 7) | | ||
399 | (invparity[par & 0x0f] << 6) | | ||
400 | (invparity[par & 0xcc] << 5) | | ||
401 | (invparity[par & 0x33] << 4) | | ||
402 | (invparity[par & 0xaa] << 3) | | ||
403 | (invparity[par & 0x55] << 2) | | ||
404 | 3; | ||
405 | else | ||
406 | code[2] = | ||
407 | (invparity[par & 0xf0] << 7) | | ||
408 | (invparity[par & 0x0f] << 6) | | ||
409 | (invparity[par & 0xcc] << 5) | | ||
410 | (invparity[par & 0x33] << 4) | | ||
411 | (invparity[par & 0xaa] << 3) | | ||
412 | (invparity[par & 0x55] << 2) | | ||
413 | (invparity[rp17] << 1) | | ||
414 | (invparity[rp16] << 0); | ||
415 | return 0; | ||
133 | } | 416 | } |
417 | EXPORT_SYMBOL(nand_calculate_ecc); | ||
134 | 418 | ||
135 | /** | 419 | /** |
136 | * nand_correct_data - [NAND Interface] Detect and correct bit error(s) | 420 | * nand_correct_data - [NAND Interface] Detect and correct bit error(s) |
137 | * @mtd: MTD block structure | 421 | * @mtd: MTD block structure |
138 | * @dat: raw data read from the chip | 422 | * @buf: raw data read from the chip |
139 | * @read_ecc: ECC from the chip | 423 | * @read_ecc: ECC from the chip |
140 | * @calc_ecc: the ECC calculated from raw data | 424 | * @calc_ecc: the ECC calculated from raw data |
141 | * | 425 | * |
142 | * Detect and correct a 1 bit error for 256 byte block | 426 | * Detect and correct a 1 bit error for 256/512 byte block |
143 | */ | 427 | */ |
144 | int nand_correct_data(struct mtd_info *mtd, u_char *dat, | 428 | int nand_correct_data(struct mtd_info *mtd, unsigned char *buf, |
145 | u_char *read_ecc, u_char *calc_ecc) | 429 | unsigned char *read_ecc, unsigned char *calc_ecc) |
146 | { | 430 | { |
147 | uint8_t s0, s1, s2; | 431 | unsigned char b0, b1, b2; |
432 | unsigned char byte_addr, bit_addr; | ||
433 | /* 256 or 512 bytes/ecc */ | ||
434 | const uint32_t eccsize_mult = | ||
435 | (((struct nand_chip *)mtd->priv)->ecc.size) >> 8; | ||
148 | 436 | ||
437 | /* | ||
438 | * b0 to b2 indicate which bit is faulty (if any) | ||
439 | * we might need the xor result more than once, | ||
440 | * so keep them in a local var | ||
441 | */ | ||
149 | #ifdef CONFIG_MTD_NAND_ECC_SMC | 442 | #ifdef CONFIG_MTD_NAND_ECC_SMC |
150 | s0 = calc_ecc[0] ^ read_ecc[0]; | 443 | b0 = read_ecc[0] ^ calc_ecc[0]; |
151 | s1 = calc_ecc[1] ^ read_ecc[1]; | 444 | b1 = read_ecc[1] ^ calc_ecc[1]; |
152 | s2 = calc_ecc[2] ^ read_ecc[2]; | ||
153 | #else | 445 | #else |
154 | s1 = calc_ecc[0] ^ read_ecc[0]; | 446 | b0 = read_ecc[1] ^ calc_ecc[1]; |
155 | s0 = calc_ecc[1] ^ read_ecc[1]; | 447 | b1 = read_ecc[0] ^ calc_ecc[0]; |
156 | s2 = calc_ecc[2] ^ read_ecc[2]; | ||
157 | #endif | 448 | #endif |
158 | if ((s0 | s1 | s2) == 0) | 449 | b2 = read_ecc[2] ^ calc_ecc[2]; |
159 | return 0; | ||
160 | |||
161 | /* Check for a single bit error */ | ||
162 | if( ((s0 ^ (s0 >> 1)) & 0x55) == 0x55 && | ||
163 | ((s1 ^ (s1 >> 1)) & 0x55) == 0x55 && | ||
164 | ((s2 ^ (s2 >> 1)) & 0x54) == 0x54) { | ||
165 | 450 | ||
166 | uint32_t byteoffs, bitnum; | 451 | /* check if there are any bitfaults */ |
167 | 452 | ||
168 | byteoffs = (s1 << 0) & 0x80; | 453 | /* repeated if statements are slightly more efficient than switch ... */ |
169 | byteoffs |= (s1 << 1) & 0x40; | 454 | /* ordered in order of likelihood */ |
170 | byteoffs |= (s1 << 2) & 0x20; | ||
171 | byteoffs |= (s1 << 3) & 0x10; | ||
172 | 455 | ||
173 | byteoffs |= (s0 >> 4) & 0x08; | 456 | if ((b0 | b1 | b2) == 0) |
174 | byteoffs |= (s0 >> 3) & 0x04; | 457 | return 0; /* no error */ |
175 | byteoffs |= (s0 >> 2) & 0x02; | ||
176 | byteoffs |= (s0 >> 1) & 0x01; | ||
177 | |||
178 | bitnum = (s2 >> 5) & 0x04; | ||
179 | bitnum |= (s2 >> 4) & 0x02; | ||
180 | bitnum |= (s2 >> 3) & 0x01; | ||
181 | |||
182 | dat[byteoffs] ^= (1 << bitnum); | ||
183 | 458 | ||
459 | if ((((b0 ^ (b0 >> 1)) & 0x55) == 0x55) && | ||
460 | (((b1 ^ (b1 >> 1)) & 0x55) == 0x55) && | ||
461 | ((eccsize_mult == 1 && ((b2 ^ (b2 >> 1)) & 0x54) == 0x54) || | ||
462 | (eccsize_mult == 2 && ((b2 ^ (b2 >> 1)) & 0x55) == 0x55))) { | ||
463 | /* single bit error */ | ||
464 | /* | ||
465 | * rp17/rp15/13/11/9/7/5/3/1 indicate which byte is the faulty | ||
466 | * byte, cp 5/3/1 indicate the faulty bit. | ||
467 | * A lookup table (called addressbits) is used to filter | ||
468 | * the bits from the byte they are in. | ||
469 | * A marginal optimisation is possible by having three | ||
470 | * different lookup tables. | ||
471 | * One as we have now (for b0), one for b2 | ||
472 | * (that would avoid the >> 1), and one for b1 (with all values | ||
473 | * << 4). However it was felt that introducing two more tables | ||
474 | * hardly justify the gain. | ||
475 | * | ||
476 | * The b2 shift is there to get rid of the lowest two bits. | ||
477 | * We could also do addressbits[b2] >> 1 but for the | ||
478 | * performace it does not make any difference | ||
479 | */ | ||
480 | if (eccsize_mult == 1) | ||
481 | byte_addr = (addressbits[b1] << 4) + addressbits[b0]; | ||
482 | else | ||
483 | byte_addr = (addressbits[b2 & 0x3] << 8) + | ||
484 | (addressbits[b1] << 4) + addressbits[b0]; | ||
485 | bit_addr = addressbits[b2 >> 2]; | ||
486 | /* flip the bit */ | ||
487 | buf[byte_addr] ^= (1 << bit_addr); | ||
184 | return 1; | 488 | return 1; |
185 | } | ||
186 | 489 | ||
187 | if(countbits(s0 | ((uint32_t)s1 << 8) | ((uint32_t)s2 <<16)) == 1) | 490 | } |
188 | return 1; | 491 | /* count nr of bits; use table lookup, faster than calculating it */ |
492 | if ((bitsperbyte[b0] + bitsperbyte[b1] + bitsperbyte[b2]) == 1) | ||
493 | return 1; /* error in ecc data; no action needed */ | ||
189 | 494 | ||
190 | return -EBADMSG; | 495 | printk(KERN_ERR "uncorrectable error : "); |
496 | return -1; | ||
191 | } | 497 | } |
192 | EXPORT_SYMBOL(nand_correct_data); | 498 | EXPORT_SYMBOL(nand_correct_data); |
193 | 499 | ||
194 | MODULE_LICENSE("GPL"); | 500 | MODULE_LICENSE("GPL"); |
195 | MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>"); | 501 | MODULE_AUTHOR("Frans Meulenbroeks <fransmeulenbroeks@gmail.com>"); |
196 | MODULE_DESCRIPTION("Generic NAND ECC support"); | 502 | MODULE_DESCRIPTION("Generic NAND ECC support"); |
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index 556e8131ecdc..ae7c57781a68 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c | |||
@@ -38,7 +38,6 @@ | |||
38 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
39 | #include <linux/list.h> | 39 | #include <linux/list.h> |
40 | #include <linux/random.h> | 40 | #include <linux/random.h> |
41 | #include <asm/div64.h> | ||
42 | 41 | ||
43 | /* Default simulator parameters values */ | 42 | /* Default simulator parameters values */ |
44 | #if !defined(CONFIG_NANDSIM_FIRST_ID_BYTE) || \ | 43 | #if !defined(CONFIG_NANDSIM_FIRST_ID_BYTE) || \ |
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index a64ad15b8fdd..c0fa9c9edf08 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c | |||
@@ -115,55 +115,11 @@ enum { | |||
115 | STATE_PIO_WRITING, | 115 | STATE_PIO_WRITING, |
116 | }; | 116 | }; |
117 | 117 | ||
118 | struct pxa3xx_nand_timing { | ||
119 | unsigned int tCH; /* Enable signal hold time */ | ||
120 | unsigned int tCS; /* Enable signal setup time */ | ||
121 | unsigned int tWH; /* ND_nWE high duration */ | ||
122 | unsigned int tWP; /* ND_nWE pulse time */ | ||
123 | unsigned int tRH; /* ND_nRE high duration */ | ||
124 | unsigned int tRP; /* ND_nRE pulse width */ | ||
125 | unsigned int tR; /* ND_nWE high to ND_nRE low for read */ | ||
126 | unsigned int tWHR; /* ND_nWE high to ND_nRE low for status read */ | ||
127 | unsigned int tAR; /* ND_ALE low to ND_nRE low delay */ | ||
128 | }; | ||
129 | |||
130 | struct pxa3xx_nand_cmdset { | ||
131 | uint16_t read1; | ||
132 | uint16_t read2; | ||
133 | uint16_t program; | ||
134 | uint16_t read_status; | ||
135 | uint16_t read_id; | ||
136 | uint16_t erase; | ||
137 | uint16_t reset; | ||
138 | uint16_t lock; | ||
139 | uint16_t unlock; | ||
140 | uint16_t lock_status; | ||
141 | }; | ||
142 | |||
143 | struct pxa3xx_nand_flash { | ||
144 | struct pxa3xx_nand_timing *timing; /* NAND Flash timing */ | ||
145 | struct pxa3xx_nand_cmdset *cmdset; | ||
146 | |||
147 | uint32_t page_per_block;/* Pages per block (PG_PER_BLK) */ | ||
148 | uint32_t page_size; /* Page size in bytes (PAGE_SZ) */ | ||
149 | uint32_t flash_width; /* Width of Flash memory (DWIDTH_M) */ | ||
150 | uint32_t dfc_width; /* Width of flash controller(DWIDTH_C) */ | ||
151 | uint32_t num_blocks; /* Number of physical blocks in Flash */ | ||
152 | uint32_t chip_id; | ||
153 | |||
154 | /* NOTE: these are automatically calculated, do not define */ | ||
155 | size_t oob_size; | ||
156 | size_t read_id_bytes; | ||
157 | |||
158 | unsigned int col_addr_cycles; | ||
159 | unsigned int row_addr_cycles; | ||
160 | }; | ||
161 | |||
162 | struct pxa3xx_nand_info { | 118 | struct pxa3xx_nand_info { |
163 | struct nand_chip nand_chip; | 119 | struct nand_chip nand_chip; |
164 | 120 | ||
165 | struct platform_device *pdev; | 121 | struct platform_device *pdev; |
166 | struct pxa3xx_nand_flash *flash_info; | 122 | const struct pxa3xx_nand_flash *flash_info; |
167 | 123 | ||
168 | struct clk *clk; | 124 | struct clk *clk; |
169 | void __iomem *mmio_base; | 125 | void __iomem *mmio_base; |
@@ -202,12 +158,20 @@ struct pxa3xx_nand_info { | |||
202 | uint32_t ndcb0; | 158 | uint32_t ndcb0; |
203 | uint32_t ndcb1; | 159 | uint32_t ndcb1; |
204 | uint32_t ndcb2; | 160 | uint32_t ndcb2; |
161 | |||
162 | /* calculated from pxa3xx_nand_flash data */ | ||
163 | size_t oob_size; | ||
164 | size_t read_id_bytes; | ||
165 | |||
166 | unsigned int col_addr_cycles; | ||
167 | unsigned int row_addr_cycles; | ||
205 | }; | 168 | }; |
206 | 169 | ||
207 | static int use_dma = 1; | 170 | static int use_dma = 1; |
208 | module_param(use_dma, bool, 0444); | 171 | module_param(use_dma, bool, 0444); |
209 | MODULE_PARM_DESC(use_dma, "enable DMA for data transfering to/from NAND HW"); | 172 | MODULE_PARM_DESC(use_dma, "enable DMA for data transfering to/from NAND HW"); |
210 | 173 | ||
174 | #ifdef CONFIG_MTD_NAND_PXA3xx_BUILTIN | ||
211 | static struct pxa3xx_nand_cmdset smallpage_cmdset = { | 175 | static struct pxa3xx_nand_cmdset smallpage_cmdset = { |
212 | .read1 = 0x0000, | 176 | .read1 = 0x0000, |
213 | .read2 = 0x0050, | 177 | .read2 = 0x0050, |
@@ -291,11 +255,35 @@ static struct pxa3xx_nand_flash micron1GbX16 = { | |||
291 | .chip_id = 0xb12c, | 255 | .chip_id = 0xb12c, |
292 | }; | 256 | }; |
293 | 257 | ||
258 | static struct pxa3xx_nand_timing stm2GbX16_timing = { | ||
259 | .tCH = 10, | ||
260 | .tCS = 35, | ||
261 | .tWH = 15, | ||
262 | .tWP = 25, | ||
263 | .tRH = 15, | ||
264 | .tRP = 25, | ||
265 | .tR = 25000, | ||
266 | .tWHR = 60, | ||
267 | .tAR = 10, | ||
268 | }; | ||
269 | |||
270 | static struct pxa3xx_nand_flash stm2GbX16 = { | ||
271 | .timing = &stm2GbX16_timing, | ||
272 | .page_per_block = 64, | ||
273 | .page_size = 2048, | ||
274 | .flash_width = 16, | ||
275 | .dfc_width = 16, | ||
276 | .num_blocks = 2048, | ||
277 | .chip_id = 0xba20, | ||
278 | }; | ||
279 | |||
294 | static struct pxa3xx_nand_flash *builtin_flash_types[] = { | 280 | static struct pxa3xx_nand_flash *builtin_flash_types[] = { |
295 | &samsung512MbX16, | 281 | &samsung512MbX16, |
296 | µn1GbX8, | 282 | µn1GbX8, |
297 | µn1GbX16, | 283 | µn1GbX16, |
284 | &stm2GbX16, | ||
298 | }; | 285 | }; |
286 | #endif /* CONFIG_MTD_NAND_PXA3xx_BUILTIN */ | ||
299 | 287 | ||
300 | #define NDTR0_tCH(c) (min((c), 7) << 19) | 288 | #define NDTR0_tCH(c) (min((c), 7) << 19) |
301 | #define NDTR0_tCS(c) (min((c), 7) << 16) | 289 | #define NDTR0_tCS(c) (min((c), 7) << 16) |
@@ -312,7 +300,7 @@ static struct pxa3xx_nand_flash *builtin_flash_types[] = { | |||
312 | #define ns2cycle(ns, clk) (int)(((ns) * (clk / 1000000) / 1000) + 1) | 300 | #define ns2cycle(ns, clk) (int)(((ns) * (clk / 1000000) / 1000) + 1) |
313 | 301 | ||
314 | static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info, | 302 | static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info, |
315 | struct pxa3xx_nand_timing *t) | 303 | const struct pxa3xx_nand_timing *t) |
316 | { | 304 | { |
317 | unsigned long nand_clk = clk_get_rate(info->clk); | 305 | unsigned long nand_clk = clk_get_rate(info->clk); |
318 | uint32_t ndtr0, ndtr1; | 306 | uint32_t ndtr0, ndtr1; |
@@ -354,8 +342,8 @@ static int wait_for_event(struct pxa3xx_nand_info *info, uint32_t event) | |||
354 | static int prepare_read_prog_cmd(struct pxa3xx_nand_info *info, | 342 | static int prepare_read_prog_cmd(struct pxa3xx_nand_info *info, |
355 | uint16_t cmd, int column, int page_addr) | 343 | uint16_t cmd, int column, int page_addr) |
356 | { | 344 | { |
357 | struct pxa3xx_nand_flash *f = info->flash_info; | 345 | const struct pxa3xx_nand_flash *f = info->flash_info; |
358 | struct pxa3xx_nand_cmdset *cmdset = f->cmdset; | 346 | const struct pxa3xx_nand_cmdset *cmdset = f->cmdset; |
359 | 347 | ||
360 | /* calculate data size */ | 348 | /* calculate data size */ |
361 | switch (f->page_size) { | 349 | switch (f->page_size) { |
@@ -373,14 +361,14 @@ static int prepare_read_prog_cmd(struct pxa3xx_nand_info *info, | |||
373 | info->ndcb0 = cmd | ((cmd & 0xff00) ? NDCB0_DBC : 0); | 361 | info->ndcb0 = cmd | ((cmd & 0xff00) ? NDCB0_DBC : 0); |
374 | info->ndcb1 = 0; | 362 | info->ndcb1 = 0; |
375 | info->ndcb2 = 0; | 363 | info->ndcb2 = 0; |
376 | info->ndcb0 |= NDCB0_ADDR_CYC(f->row_addr_cycles + f->col_addr_cycles); | 364 | info->ndcb0 |= NDCB0_ADDR_CYC(info->row_addr_cycles + info->col_addr_cycles); |
377 | 365 | ||
378 | if (f->col_addr_cycles == 2) { | 366 | if (info->col_addr_cycles == 2) { |
379 | /* large block, 2 cycles for column address | 367 | /* large block, 2 cycles for column address |
380 | * row address starts from 3rd cycle | 368 | * row address starts from 3rd cycle |
381 | */ | 369 | */ |
382 | info->ndcb1 |= (page_addr << 16) | (column & 0xffff); | 370 | info->ndcb1 |= (page_addr << 16) | (column & 0xffff); |
383 | if (f->row_addr_cycles == 3) | 371 | if (info->row_addr_cycles == 3) |
384 | info->ndcb2 = (page_addr >> 16) & 0xff; | 372 | info->ndcb2 = (page_addr >> 16) & 0xff; |
385 | } else | 373 | } else |
386 | /* small block, 1 cycles for column address | 374 | /* small block, 1 cycles for column address |
@@ -406,7 +394,7 @@ static int prepare_erase_cmd(struct pxa3xx_nand_info *info, | |||
406 | 394 | ||
407 | static int prepare_other_cmd(struct pxa3xx_nand_info *info, uint16_t cmd) | 395 | static int prepare_other_cmd(struct pxa3xx_nand_info *info, uint16_t cmd) |
408 | { | 396 | { |
409 | struct pxa3xx_nand_cmdset *cmdset = info->flash_info->cmdset; | 397 | const struct pxa3xx_nand_cmdset *cmdset = info->flash_info->cmdset; |
410 | 398 | ||
411 | info->ndcb0 = cmd | ((cmd & 0xff00) ? NDCB0_DBC : 0); | 399 | info->ndcb0 = cmd | ((cmd & 0xff00) ? NDCB0_DBC : 0); |
412 | info->ndcb1 = 0; | 400 | info->ndcb1 = 0; |
@@ -641,8 +629,8 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command, | |||
641 | int column, int page_addr) | 629 | int column, int page_addr) |
642 | { | 630 | { |
643 | struct pxa3xx_nand_info *info = mtd->priv; | 631 | struct pxa3xx_nand_info *info = mtd->priv; |
644 | struct pxa3xx_nand_flash *flash_info = info->flash_info; | 632 | const struct pxa3xx_nand_flash *flash_info = info->flash_info; |
645 | struct pxa3xx_nand_cmdset *cmdset = flash_info->cmdset; | 633 | const struct pxa3xx_nand_cmdset *cmdset = flash_info->cmdset; |
646 | int ret; | 634 | int ret; |
647 | 635 | ||
648 | info->use_dma = (use_dma) ? 1 : 0; | 636 | info->use_dma = (use_dma) ? 1 : 0; |
@@ -720,7 +708,7 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command, | |||
720 | info->use_dma = 0; /* force PIO read */ | 708 | info->use_dma = 0; /* force PIO read */ |
721 | info->buf_start = 0; | 709 | info->buf_start = 0; |
722 | info->buf_count = (command == NAND_CMD_READID) ? | 710 | info->buf_count = (command == NAND_CMD_READID) ? |
723 | flash_info->read_id_bytes : 1; | 711 | info->read_id_bytes : 1; |
724 | 712 | ||
725 | if (prepare_other_cmd(info, (command == NAND_CMD_READID) ? | 713 | if (prepare_other_cmd(info, (command == NAND_CMD_READID) ? |
726 | cmdset->read_id : cmdset->read_status)) | 714 | cmdset->read_id : cmdset->read_status)) |
@@ -861,8 +849,8 @@ static int pxa3xx_nand_ecc_correct(struct mtd_info *mtd, | |||
861 | 849 | ||
862 | static int __readid(struct pxa3xx_nand_info *info, uint32_t *id) | 850 | static int __readid(struct pxa3xx_nand_info *info, uint32_t *id) |
863 | { | 851 | { |
864 | struct pxa3xx_nand_flash *f = info->flash_info; | 852 | const struct pxa3xx_nand_flash *f = info->flash_info; |
865 | struct pxa3xx_nand_cmdset *cmdset = f->cmdset; | 853 | const struct pxa3xx_nand_cmdset *cmdset = f->cmdset; |
866 | uint32_t ndcr; | 854 | uint32_t ndcr; |
867 | uint8_t id_buff[8]; | 855 | uint8_t id_buff[8]; |
868 | 856 | ||
@@ -891,7 +879,7 @@ fail_timeout: | |||
891 | } | 879 | } |
892 | 880 | ||
893 | static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info, | 881 | static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info, |
894 | struct pxa3xx_nand_flash *f) | 882 | const struct pxa3xx_nand_flash *f) |
895 | { | 883 | { |
896 | struct platform_device *pdev = info->pdev; | 884 | struct platform_device *pdev = info->pdev; |
897 | struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data; | 885 | struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data; |
@@ -904,25 +892,25 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info, | |||
904 | return -EINVAL; | 892 | return -EINVAL; |
905 | 893 | ||
906 | /* calculate flash information */ | 894 | /* calculate flash information */ |
907 | f->oob_size = (f->page_size == 2048) ? 64 : 16; | 895 | info->oob_size = (f->page_size == 2048) ? 64 : 16; |
908 | f->read_id_bytes = (f->page_size == 2048) ? 4 : 2; | 896 | info->read_id_bytes = (f->page_size == 2048) ? 4 : 2; |
909 | 897 | ||
910 | /* calculate addressing information */ | 898 | /* calculate addressing information */ |
911 | f->col_addr_cycles = (f->page_size == 2048) ? 2 : 1; | 899 | info->col_addr_cycles = (f->page_size == 2048) ? 2 : 1; |
912 | 900 | ||
913 | if (f->num_blocks * f->page_per_block > 65536) | 901 | if (f->num_blocks * f->page_per_block > 65536) |
914 | f->row_addr_cycles = 3; | 902 | info->row_addr_cycles = 3; |
915 | else | 903 | else |
916 | f->row_addr_cycles = 2; | 904 | info->row_addr_cycles = 2; |
917 | 905 | ||
918 | ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0; | 906 | ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0; |
919 | ndcr |= (f->col_addr_cycles == 2) ? NDCR_RA_START : 0; | 907 | ndcr |= (info->col_addr_cycles == 2) ? NDCR_RA_START : 0; |
920 | ndcr |= (f->page_per_block == 64) ? NDCR_PG_PER_BLK : 0; | 908 | ndcr |= (f->page_per_block == 64) ? NDCR_PG_PER_BLK : 0; |
921 | ndcr |= (f->page_size == 2048) ? NDCR_PAGE_SZ : 0; | 909 | ndcr |= (f->page_size == 2048) ? NDCR_PAGE_SZ : 0; |
922 | ndcr |= (f->flash_width == 16) ? NDCR_DWIDTH_M : 0; | 910 | ndcr |= (f->flash_width == 16) ? NDCR_DWIDTH_M : 0; |
923 | ndcr |= (f->dfc_width == 16) ? NDCR_DWIDTH_C : 0; | 911 | ndcr |= (f->dfc_width == 16) ? NDCR_DWIDTH_C : 0; |
924 | 912 | ||
925 | ndcr |= NDCR_RD_ID_CNT(f->read_id_bytes); | 913 | ndcr |= NDCR_RD_ID_CNT(info->read_id_bytes); |
926 | ndcr |= NDCR_SPARE_EN; /* enable spare by default */ | 914 | ndcr |= NDCR_SPARE_EN; /* enable spare by default */ |
927 | 915 | ||
928 | info->reg_ndcr = ndcr; | 916 | info->reg_ndcr = ndcr; |
@@ -932,12 +920,27 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info, | |||
932 | return 0; | 920 | return 0; |
933 | } | 921 | } |
934 | 922 | ||
935 | static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info) | 923 | static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info, |
924 | const struct pxa3xx_nand_platform_data *pdata) | ||
936 | { | 925 | { |
937 | struct pxa3xx_nand_flash *f; | 926 | const struct pxa3xx_nand_flash *f; |
938 | uint32_t id; | 927 | uint32_t id = -1; |
939 | int i; | 928 | int i; |
940 | 929 | ||
930 | for (i = 0; i<pdata->num_flash; ++i) { | ||
931 | f = pdata->flash + i; | ||
932 | |||
933 | if (pxa3xx_nand_config_flash(info, f)) | ||
934 | continue; | ||
935 | |||
936 | if (__readid(info, &id)) | ||
937 | continue; | ||
938 | |||
939 | if (id == f->chip_id) | ||
940 | return 0; | ||
941 | } | ||
942 | |||
943 | #ifdef CONFIG_MTD_NAND_PXA3xx_BUILTIN | ||
941 | for (i = 0; i < ARRAY_SIZE(builtin_flash_types); i++) { | 944 | for (i = 0; i < ARRAY_SIZE(builtin_flash_types); i++) { |
942 | 945 | ||
943 | f = builtin_flash_types[i]; | 946 | f = builtin_flash_types[i]; |
@@ -951,7 +954,11 @@ static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info) | |||
951 | if (id == f->chip_id) | 954 | if (id == f->chip_id) |
952 | return 0; | 955 | return 0; |
953 | } | 956 | } |
957 | #endif | ||
954 | 958 | ||
959 | dev_warn(&info->pdev->dev, | ||
960 | "failed to detect configured nand flash; found %04x instead of\n", | ||
961 | id); | ||
955 | return -ENODEV; | 962 | return -ENODEV; |
956 | } | 963 | } |
957 | 964 | ||
@@ -1014,7 +1021,7 @@ static struct nand_ecclayout hw_largepage_ecclayout = { | |||
1014 | static void pxa3xx_nand_init_mtd(struct mtd_info *mtd, | 1021 | static void pxa3xx_nand_init_mtd(struct mtd_info *mtd, |
1015 | struct pxa3xx_nand_info *info) | 1022 | struct pxa3xx_nand_info *info) |
1016 | { | 1023 | { |
1017 | struct pxa3xx_nand_flash *f = info->flash_info; | 1024 | const struct pxa3xx_nand_flash *f = info->flash_info; |
1018 | struct nand_chip *this = &info->nand_chip; | 1025 | struct nand_chip *this = &info->nand_chip; |
1019 | 1026 | ||
1020 | this->options = (f->flash_width == 16) ? NAND_BUSWIDTH_16: 0; | 1027 | this->options = (f->flash_width == 16) ? NAND_BUSWIDTH_16: 0; |
@@ -1135,7 +1142,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) | |||
1135 | goto fail_free_buf; | 1142 | goto fail_free_buf; |
1136 | } | 1143 | } |
1137 | 1144 | ||
1138 | ret = pxa3xx_nand_detect_flash(info); | 1145 | ret = pxa3xx_nand_detect_flash(info, pdata); |
1139 | if (ret) { | 1146 | if (ret) { |
1140 | dev_err(&pdev->dev, "failed to detect flash\n"); | 1147 | dev_err(&pdev->dev, "failed to detect flash\n"); |
1141 | ret = -ENODEV; | 1148 | ret = -ENODEV; |
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c new file mode 100644 index 000000000000..821acb08ff1c --- /dev/null +++ b/drivers/mtd/nand/sh_flctl.c | |||
@@ -0,0 +1,878 @@ | |||
1 | /* | ||
2 | * SuperH FLCTL nand controller | ||
3 | * | ||
4 | * Copyright © 2008 Renesas Solutions Corp. | ||
5 | * Copyright © 2008 Atom Create Engineering Co., Ltd. | ||
6 | * | ||
7 | * Based on fsl_elbc_nand.c, Copyright © 2006-2007 Freescale Semiconductor | ||
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 as published by | ||
11 | * the Free Software Foundation; version 2 of the License. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/io.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | |||
30 | #include <linux/mtd/mtd.h> | ||
31 | #include <linux/mtd/nand.h> | ||
32 | #include <linux/mtd/partitions.h> | ||
33 | #include <linux/mtd/sh_flctl.h> | ||
34 | |||
35 | static struct nand_ecclayout flctl_4secc_oob_16 = { | ||
36 | .eccbytes = 10, | ||
37 | .eccpos = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, | ||
38 | .oobfree = { | ||
39 | {.offset = 12, | ||
40 | . length = 4} }, | ||
41 | }; | ||
42 | |||
43 | static struct nand_ecclayout flctl_4secc_oob_64 = { | ||
44 | .eccbytes = 10, | ||
45 | .eccpos = {48, 49, 50, 51, 52, 53, 54, 55, 56, 57}, | ||
46 | .oobfree = { | ||
47 | {.offset = 60, | ||
48 | . length = 4} }, | ||
49 | }; | ||
50 | |||
51 | static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; | ||
52 | |||
53 | static struct nand_bbt_descr flctl_4secc_smallpage = { | ||
54 | .options = NAND_BBT_SCAN2NDPAGE, | ||
55 | .offs = 11, | ||
56 | .len = 1, | ||
57 | .pattern = scan_ff_pattern, | ||
58 | }; | ||
59 | |||
60 | static struct nand_bbt_descr flctl_4secc_largepage = { | ||
61 | .options = 0, | ||
62 | .offs = 58, | ||
63 | .len = 2, | ||
64 | .pattern = scan_ff_pattern, | ||
65 | }; | ||
66 | |||
67 | static void empty_fifo(struct sh_flctl *flctl) | ||
68 | { | ||
69 | writel(0x000c0000, FLINTDMACR(flctl)); /* FIFO Clear */ | ||
70 | writel(0x00000000, FLINTDMACR(flctl)); /* Clear Error flags */ | ||
71 | } | ||
72 | |||
73 | static void start_translation(struct sh_flctl *flctl) | ||
74 | { | ||
75 | writeb(TRSTRT, FLTRCR(flctl)); | ||
76 | } | ||
77 | |||
78 | static void wait_completion(struct sh_flctl *flctl) | ||
79 | { | ||
80 | uint32_t timeout = LOOP_TIMEOUT_MAX; | ||
81 | |||
82 | while (timeout--) { | ||
83 | if (readb(FLTRCR(flctl)) & TREND) { | ||
84 | writeb(0x0, FLTRCR(flctl)); | ||
85 | return; | ||
86 | } | ||
87 | udelay(1); | ||
88 | } | ||
89 | |||
90 | printk(KERN_ERR "wait_completion(): Timeout occured \n"); | ||
91 | writeb(0x0, FLTRCR(flctl)); | ||
92 | } | ||
93 | |||
94 | static void set_addr(struct mtd_info *mtd, int column, int page_addr) | ||
95 | { | ||
96 | struct sh_flctl *flctl = mtd_to_flctl(mtd); | ||
97 | uint32_t addr = 0; | ||
98 | |||
99 | if (column == -1) { | ||
100 | addr = page_addr; /* ERASE1 */ | ||
101 | } else if (page_addr != -1) { | ||
102 | /* SEQIN, READ0, etc.. */ | ||
103 | if (flctl->page_size) { | ||
104 | addr = column & 0x0FFF; | ||
105 | addr |= (page_addr & 0xff) << 16; | ||
106 | addr |= ((page_addr >> 8) & 0xff) << 24; | ||
107 | /* big than 128MB */ | ||
108 | if (flctl->rw_ADRCNT == ADRCNT2_E) { | ||
109 | uint32_t addr2; | ||
110 | addr2 = (page_addr >> 16) & 0xff; | ||
111 | writel(addr2, FLADR2(flctl)); | ||
112 | } | ||
113 | } else { | ||
114 | addr = column; | ||
115 | addr |= (page_addr & 0xff) << 8; | ||
116 | addr |= ((page_addr >> 8) & 0xff) << 16; | ||
117 | addr |= ((page_addr >> 16) & 0xff) << 24; | ||
118 | } | ||
119 | } | ||
120 | writel(addr, FLADR(flctl)); | ||
121 | } | ||
122 | |||
123 | static void wait_rfifo_ready(struct sh_flctl *flctl) | ||
124 | { | ||
125 | uint32_t timeout = LOOP_TIMEOUT_MAX; | ||
126 | |||
127 | while (timeout--) { | ||
128 | uint32_t val; | ||
129 | /* check FIFO */ | ||
130 | val = readl(FLDTCNTR(flctl)) >> 16; | ||
131 | if (val & 0xFF) | ||
132 | return; | ||
133 | udelay(1); | ||
134 | } | ||
135 | printk(KERN_ERR "wait_rfifo_ready(): Timeout occured \n"); | ||
136 | } | ||
137 | |||
138 | static void wait_wfifo_ready(struct sh_flctl *flctl) | ||
139 | { | ||
140 | uint32_t len, timeout = LOOP_TIMEOUT_MAX; | ||
141 | |||
142 | while (timeout--) { | ||
143 | /* check FIFO */ | ||
144 | len = (readl(FLDTCNTR(flctl)) >> 16) & 0xFF; | ||
145 | if (len >= 4) | ||
146 | return; | ||
147 | udelay(1); | ||
148 | } | ||
149 | printk(KERN_ERR "wait_wfifo_ready(): Timeout occured \n"); | ||
150 | } | ||
151 | |||
152 | static int wait_recfifo_ready(struct sh_flctl *flctl) | ||
153 | { | ||
154 | uint32_t timeout = LOOP_TIMEOUT_MAX; | ||
155 | int checked[4]; | ||
156 | void __iomem *ecc_reg[4]; | ||
157 | int i; | ||
158 | uint32_t data, size; | ||
159 | |||
160 | memset(checked, 0, sizeof(checked)); | ||
161 | |||
162 | while (timeout--) { | ||
163 | size = readl(FLDTCNTR(flctl)) >> 24; | ||
164 | if (size & 0xFF) | ||
165 | return 0; /* success */ | ||
166 | |||
167 | if (readl(FL4ECCCR(flctl)) & _4ECCFA) | ||
168 | return 1; /* can't correct */ | ||
169 | |||
170 | udelay(1); | ||
171 | if (!(readl(FL4ECCCR(flctl)) & _4ECCEND)) | ||
172 | continue; | ||
173 | |||
174 | /* start error correction */ | ||
175 | ecc_reg[0] = FL4ECCRESULT0(flctl); | ||
176 | ecc_reg[1] = FL4ECCRESULT1(flctl); | ||
177 | ecc_reg[2] = FL4ECCRESULT2(flctl); | ||
178 | ecc_reg[3] = FL4ECCRESULT3(flctl); | ||
179 | |||
180 | for (i = 0; i < 3; i++) { | ||
181 | data = readl(ecc_reg[i]); | ||
182 | if (data != INIT_FL4ECCRESULT_VAL && !checked[i]) { | ||
183 | uint8_t org; | ||
184 | int index; | ||
185 | |||
186 | index = data >> 16; | ||
187 | org = flctl->done_buff[index]; | ||
188 | flctl->done_buff[index] = org ^ (data & 0xFF); | ||
189 | checked[i] = 1; | ||
190 | } | ||
191 | } | ||
192 | |||
193 | writel(0, FL4ECCCR(flctl)); | ||
194 | } | ||
195 | |||
196 | printk(KERN_ERR "wait_recfifo_ready(): Timeout occured \n"); | ||
197 | return 1; /* timeout */ | ||
198 | } | ||
199 | |||
200 | static void wait_wecfifo_ready(struct sh_flctl *flctl) | ||
201 | { | ||
202 | uint32_t timeout = LOOP_TIMEOUT_MAX; | ||
203 | uint32_t len; | ||
204 | |||
205 | while (timeout--) { | ||
206 | /* check FLECFIFO */ | ||
207 | len = (readl(FLDTCNTR(flctl)) >> 24) & 0xFF; | ||
208 | if (len >= 4) | ||
209 | return; | ||
210 | udelay(1); | ||
211 | } | ||
212 | printk(KERN_ERR "wait_wecfifo_ready(): Timeout occured \n"); | ||
213 | } | ||
214 | |||
215 | static void read_datareg(struct sh_flctl *flctl, int offset) | ||
216 | { | ||
217 | unsigned long data; | ||
218 | unsigned long *buf = (unsigned long *)&flctl->done_buff[offset]; | ||
219 | |||
220 | wait_completion(flctl); | ||
221 | |||
222 | data = readl(FLDATAR(flctl)); | ||
223 | *buf = le32_to_cpu(data); | ||
224 | } | ||
225 | |||
226 | static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset) | ||
227 | { | ||
228 | int i, len_4align; | ||
229 | unsigned long *buf = (unsigned long *)&flctl->done_buff[offset]; | ||
230 | void *fifo_addr = (void *)FLDTFIFO(flctl); | ||
231 | |||
232 | len_4align = (rlen + 3) / 4; | ||
233 | |||
234 | for (i = 0; i < len_4align; i++) { | ||
235 | wait_rfifo_ready(flctl); | ||
236 | buf[i] = readl(fifo_addr); | ||
237 | buf[i] = be32_to_cpu(buf[i]); | ||
238 | } | ||
239 | } | ||
240 | |||
241 | static int read_ecfiforeg(struct sh_flctl *flctl, uint8_t *buff) | ||
242 | { | ||
243 | int i; | ||
244 | unsigned long *ecc_buf = (unsigned long *)buff; | ||
245 | void *fifo_addr = (void *)FLECFIFO(flctl); | ||
246 | |||
247 | for (i = 0; i < 4; i++) { | ||
248 | if (wait_recfifo_ready(flctl)) | ||
249 | return 1; | ||
250 | ecc_buf[i] = readl(fifo_addr); | ||
251 | ecc_buf[i] = be32_to_cpu(ecc_buf[i]); | ||
252 | } | ||
253 | |||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset) | ||
258 | { | ||
259 | int i, len_4align; | ||
260 | unsigned long *data = (unsigned long *)&flctl->done_buff[offset]; | ||
261 | void *fifo_addr = (void *)FLDTFIFO(flctl); | ||
262 | |||
263 | len_4align = (rlen + 3) / 4; | ||
264 | for (i = 0; i < len_4align; i++) { | ||
265 | wait_wfifo_ready(flctl); | ||
266 | writel(cpu_to_be32(data[i]), fifo_addr); | ||
267 | } | ||
268 | } | ||
269 | |||
270 | static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_val) | ||
271 | { | ||
272 | struct sh_flctl *flctl = mtd_to_flctl(mtd); | ||
273 | uint32_t flcmncr_val = readl(FLCMNCR(flctl)); | ||
274 | uint32_t flcmdcr_val, addr_len_bytes = 0; | ||
275 | |||
276 | /* Set SNAND bit if page size is 2048byte */ | ||
277 | if (flctl->page_size) | ||
278 | flcmncr_val |= SNAND_E; | ||
279 | else | ||
280 | flcmncr_val &= ~SNAND_E; | ||
281 | |||
282 | /* default FLCMDCR val */ | ||
283 | flcmdcr_val = DOCMD1_E | DOADR_E; | ||
284 | |||
285 | /* Set for FLCMDCR */ | ||
286 | switch (cmd) { | ||
287 | case NAND_CMD_ERASE1: | ||
288 | addr_len_bytes = flctl->erase_ADRCNT; | ||
289 | flcmdcr_val |= DOCMD2_E; | ||
290 | break; | ||
291 | case NAND_CMD_READ0: | ||
292 | case NAND_CMD_READOOB: | ||
293 | addr_len_bytes = flctl->rw_ADRCNT; | ||
294 | flcmdcr_val |= CDSRC_E; | ||
295 | break; | ||
296 | case NAND_CMD_SEQIN: | ||
297 | /* This case is that cmd is READ0 or READ1 or READ00 */ | ||
298 | flcmdcr_val &= ~DOADR_E; /* ONLY execute 1st cmd */ | ||
299 | break; | ||
300 | case NAND_CMD_PAGEPROG: | ||
301 | addr_len_bytes = flctl->rw_ADRCNT; | ||
302 | flcmdcr_val |= DOCMD2_E | CDSRC_E | SELRW; | ||
303 | break; | ||
304 | case NAND_CMD_READID: | ||
305 | flcmncr_val &= ~SNAND_E; | ||
306 | addr_len_bytes = ADRCNT_1; | ||
307 | break; | ||
308 | case NAND_CMD_STATUS: | ||
309 | case NAND_CMD_RESET: | ||
310 | flcmncr_val &= ~SNAND_E; | ||
311 | flcmdcr_val &= ~(DOADR_E | DOSR_E); | ||
312 | break; | ||
313 | default: | ||
314 | break; | ||
315 | } | ||
316 | |||
317 | /* Set address bytes parameter */ | ||
318 | flcmdcr_val |= addr_len_bytes; | ||
319 | |||
320 | /* Now actually write */ | ||
321 | writel(flcmncr_val, FLCMNCR(flctl)); | ||
322 | writel(flcmdcr_val, FLCMDCR(flctl)); | ||
323 | writel(flcmcdr_val, FLCMCDR(flctl)); | ||
324 | } | ||
325 | |||
326 | static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | ||
327 | uint8_t *buf) | ||
328 | { | ||
329 | int i, eccsize = chip->ecc.size; | ||
330 | int eccbytes = chip->ecc.bytes; | ||
331 | int eccsteps = chip->ecc.steps; | ||
332 | uint8_t *p = buf; | ||
333 | struct sh_flctl *flctl = mtd_to_flctl(mtd); | ||
334 | |||
335 | for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) | ||
336 | chip->read_buf(mtd, p, eccsize); | ||
337 | |||
338 | for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { | ||
339 | if (flctl->hwecc_cant_correct[i]) | ||
340 | mtd->ecc_stats.failed++; | ||
341 | else | ||
342 | mtd->ecc_stats.corrected += 0; | ||
343 | } | ||
344 | |||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | static void flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | ||
349 | const uint8_t *buf) | ||
350 | { | ||
351 | int i, eccsize = chip->ecc.size; | ||
352 | int eccbytes = chip->ecc.bytes; | ||
353 | int eccsteps = chip->ecc.steps; | ||
354 | const uint8_t *p = buf; | ||
355 | |||
356 | for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) | ||
357 | chip->write_buf(mtd, p, eccsize); | ||
358 | } | ||
359 | |||
360 | static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr) | ||
361 | { | ||
362 | struct sh_flctl *flctl = mtd_to_flctl(mtd); | ||
363 | int sector, page_sectors; | ||
364 | |||
365 | if (flctl->page_size) | ||
366 | page_sectors = 4; | ||
367 | else | ||
368 | page_sectors = 1; | ||
369 | |||
370 | writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE | _4ECCCORRECT, | ||
371 | FLCMNCR(flctl)); | ||
372 | |||
373 | set_cmd_regs(mtd, NAND_CMD_READ0, | ||
374 | (NAND_CMD_READSTART << 8) | NAND_CMD_READ0); | ||
375 | |||
376 | for (sector = 0; sector < page_sectors; sector++) { | ||
377 | int ret; | ||
378 | |||
379 | empty_fifo(flctl); | ||
380 | writel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl)); | ||
381 | writel(page_addr << 2 | sector, FLADR(flctl)); | ||
382 | |||
383 | start_translation(flctl); | ||
384 | read_fiforeg(flctl, 512, 512 * sector); | ||
385 | |||
386 | ret = read_ecfiforeg(flctl, | ||
387 | &flctl->done_buff[mtd->writesize + 16 * sector]); | ||
388 | |||
389 | if (ret) | ||
390 | flctl->hwecc_cant_correct[sector] = 1; | ||
391 | |||
392 | writel(0x0, FL4ECCCR(flctl)); | ||
393 | wait_completion(flctl); | ||
394 | } | ||
395 | writel(readl(FLCMNCR(flctl)) & ~(ACM_SACCES_MODE | _4ECCCORRECT), | ||
396 | FLCMNCR(flctl)); | ||
397 | } | ||
398 | |||
399 | static void execmd_read_oob(struct mtd_info *mtd, int page_addr) | ||
400 | { | ||
401 | struct sh_flctl *flctl = mtd_to_flctl(mtd); | ||
402 | |||
403 | set_cmd_regs(mtd, NAND_CMD_READ0, | ||
404 | (NAND_CMD_READSTART << 8) | NAND_CMD_READ0); | ||
405 | |||
406 | empty_fifo(flctl); | ||
407 | if (flctl->page_size) { | ||
408 | int i; | ||
409 | /* In case that the page size is 2k */ | ||
410 | for (i = 0; i < 16 * 3; i++) | ||
411 | flctl->done_buff[i] = 0xFF; | ||
412 | |||
413 | set_addr(mtd, 3 * 528 + 512, page_addr); | ||
414 | writel(16, FLDTCNTR(flctl)); | ||
415 | |||
416 | start_translation(flctl); | ||
417 | read_fiforeg(flctl, 16, 16 * 3); | ||
418 | wait_completion(flctl); | ||
419 | } else { | ||
420 | /* In case that the page size is 512b */ | ||
421 | set_addr(mtd, 512, page_addr); | ||
422 | writel(16, FLDTCNTR(flctl)); | ||
423 | |||
424 | start_translation(flctl); | ||
425 | read_fiforeg(flctl, 16, 0); | ||
426 | wait_completion(flctl); | ||
427 | } | ||
428 | } | ||
429 | |||
430 | static void execmd_write_page_sector(struct mtd_info *mtd) | ||
431 | { | ||
432 | struct sh_flctl *flctl = mtd_to_flctl(mtd); | ||
433 | int i, page_addr = flctl->seqin_page_addr; | ||
434 | int sector, page_sectors; | ||
435 | |||
436 | if (flctl->page_size) | ||
437 | page_sectors = 4; | ||
438 | else | ||
439 | page_sectors = 1; | ||
440 | |||
441 | writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE, FLCMNCR(flctl)); | ||
442 | |||
443 | set_cmd_regs(mtd, NAND_CMD_PAGEPROG, | ||
444 | (NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN); | ||
445 | |||
446 | for (sector = 0; sector < page_sectors; sector++) { | ||
447 | empty_fifo(flctl); | ||
448 | writel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl)); | ||
449 | writel(page_addr << 2 | sector, FLADR(flctl)); | ||
450 | |||
451 | start_translation(flctl); | ||
452 | write_fiforeg(flctl, 512, 512 * sector); | ||
453 | |||
454 | for (i = 0; i < 4; i++) { | ||
455 | wait_wecfifo_ready(flctl); /* wait for write ready */ | ||
456 | writel(0xFFFFFFFF, FLECFIFO(flctl)); | ||
457 | } | ||
458 | wait_completion(flctl); | ||
459 | } | ||
460 | |||
461 | writel(readl(FLCMNCR(flctl)) & ~ACM_SACCES_MODE, FLCMNCR(flctl)); | ||
462 | } | ||
463 | |||
464 | static void execmd_write_oob(struct mtd_info *mtd) | ||
465 | { | ||
466 | struct sh_flctl *flctl = mtd_to_flctl(mtd); | ||
467 | int page_addr = flctl->seqin_page_addr; | ||
468 | int sector, page_sectors; | ||
469 | |||
470 | if (flctl->page_size) { | ||
471 | sector = 3; | ||
472 | page_sectors = 4; | ||
473 | } else { | ||
474 | sector = 0; | ||
475 | page_sectors = 1; | ||
476 | } | ||
477 | |||
478 | set_cmd_regs(mtd, NAND_CMD_PAGEPROG, | ||
479 | (NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN); | ||
480 | |||
481 | for (; sector < page_sectors; sector++) { | ||
482 | empty_fifo(flctl); | ||
483 | set_addr(mtd, sector * 528 + 512, page_addr); | ||
484 | writel(16, FLDTCNTR(flctl)); /* set read size */ | ||
485 | |||
486 | start_translation(flctl); | ||
487 | write_fiforeg(flctl, 16, 16 * sector); | ||
488 | wait_completion(flctl); | ||
489 | } | ||
490 | } | ||
491 | |||
492 | static void flctl_cmdfunc(struct mtd_info *mtd, unsigned int command, | ||
493 | int column, int page_addr) | ||
494 | { | ||
495 | struct sh_flctl *flctl = mtd_to_flctl(mtd); | ||
496 | uint32_t read_cmd = 0; | ||
497 | |||
498 | flctl->read_bytes = 0; | ||
499 | if (command != NAND_CMD_PAGEPROG) | ||
500 | flctl->index = 0; | ||
501 | |||
502 | switch (command) { | ||
503 | case NAND_CMD_READ1: | ||
504 | case NAND_CMD_READ0: | ||
505 | if (flctl->hwecc) { | ||
506 | /* read page with hwecc */ | ||
507 | execmd_read_page_sector(mtd, page_addr); | ||
508 | break; | ||
509 | } | ||
510 | empty_fifo(flctl); | ||
511 | if (flctl->page_size) | ||
512 | set_cmd_regs(mtd, command, (NAND_CMD_READSTART << 8) | ||
513 | | command); | ||
514 | else | ||
515 | set_cmd_regs(mtd, command, command); | ||
516 | |||
517 | set_addr(mtd, 0, page_addr); | ||
518 | |||
519 | flctl->read_bytes = mtd->writesize + mtd->oobsize; | ||
520 | flctl->index += column; | ||
521 | goto read_normal_exit; | ||
522 | |||
523 | case NAND_CMD_READOOB: | ||
524 | if (flctl->hwecc) { | ||
525 | /* read page with hwecc */ | ||
526 | execmd_read_oob(mtd, page_addr); | ||
527 | break; | ||
528 | } | ||
529 | |||
530 | empty_fifo(flctl); | ||
531 | if (flctl->page_size) { | ||
532 | set_cmd_regs(mtd, command, (NAND_CMD_READSTART << 8) | ||
533 | | NAND_CMD_READ0); | ||
534 | set_addr(mtd, mtd->writesize, page_addr); | ||
535 | } else { | ||
536 | set_cmd_regs(mtd, command, command); | ||
537 | set_addr(mtd, 0, page_addr); | ||
538 | } | ||
539 | flctl->read_bytes = mtd->oobsize; | ||
540 | goto read_normal_exit; | ||
541 | |||
542 | case NAND_CMD_READID: | ||
543 | empty_fifo(flctl); | ||
544 | set_cmd_regs(mtd, command, command); | ||
545 | set_addr(mtd, 0, 0); | ||
546 | |||
547 | flctl->read_bytes = 4; | ||
548 | writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */ | ||
549 | start_translation(flctl); | ||
550 | read_datareg(flctl, 0); /* read and end */ | ||
551 | break; | ||
552 | |||
553 | case NAND_CMD_ERASE1: | ||
554 | flctl->erase1_page_addr = page_addr; | ||
555 | break; | ||
556 | |||
557 | case NAND_CMD_ERASE2: | ||
558 | set_cmd_regs(mtd, NAND_CMD_ERASE1, | ||
559 | (command << 8) | NAND_CMD_ERASE1); | ||
560 | set_addr(mtd, -1, flctl->erase1_page_addr); | ||
561 | start_translation(flctl); | ||
562 | wait_completion(flctl); | ||
563 | break; | ||
564 | |||
565 | case NAND_CMD_SEQIN: | ||
566 | if (!flctl->page_size) { | ||
567 | /* output read command */ | ||
568 | if (column >= mtd->writesize) { | ||
569 | column -= mtd->writesize; | ||
570 | read_cmd = NAND_CMD_READOOB; | ||
571 | } else if (column < 256) { | ||
572 | read_cmd = NAND_CMD_READ0; | ||
573 | } else { | ||
574 | column -= 256; | ||
575 | read_cmd = NAND_CMD_READ1; | ||
576 | } | ||
577 | } | ||
578 | flctl->seqin_column = column; | ||
579 | flctl->seqin_page_addr = page_addr; | ||
580 | flctl->seqin_read_cmd = read_cmd; | ||
581 | break; | ||
582 | |||
583 | case NAND_CMD_PAGEPROG: | ||
584 | empty_fifo(flctl); | ||
585 | if (!flctl->page_size) { | ||
586 | set_cmd_regs(mtd, NAND_CMD_SEQIN, | ||
587 | flctl->seqin_read_cmd); | ||
588 | set_addr(mtd, -1, -1); | ||
589 | writel(0, FLDTCNTR(flctl)); /* set 0 size */ | ||
590 | start_translation(flctl); | ||
591 | wait_completion(flctl); | ||
592 | } | ||
593 | if (flctl->hwecc) { | ||
594 | /* write page with hwecc */ | ||
595 | if (flctl->seqin_column == mtd->writesize) | ||
596 | execmd_write_oob(mtd); | ||
597 | else if (!flctl->seqin_column) | ||
598 | execmd_write_page_sector(mtd); | ||
599 | else | ||
600 | printk(KERN_ERR "Invalid address !?\n"); | ||
601 | break; | ||
602 | } | ||
603 | set_cmd_regs(mtd, command, (command << 8) | NAND_CMD_SEQIN); | ||
604 | set_addr(mtd, flctl->seqin_column, flctl->seqin_page_addr); | ||
605 | writel(flctl->index, FLDTCNTR(flctl)); /* set write size */ | ||
606 | start_translation(flctl); | ||
607 | write_fiforeg(flctl, flctl->index, 0); | ||
608 | wait_completion(flctl); | ||
609 | break; | ||
610 | |||
611 | case NAND_CMD_STATUS: | ||
612 | set_cmd_regs(mtd, command, command); | ||
613 | set_addr(mtd, -1, -1); | ||
614 | |||
615 | flctl->read_bytes = 1; | ||
616 | writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */ | ||
617 | start_translation(flctl); | ||
618 | read_datareg(flctl, 0); /* read and end */ | ||
619 | break; | ||
620 | |||
621 | case NAND_CMD_RESET: | ||
622 | set_cmd_regs(mtd, command, command); | ||
623 | set_addr(mtd, -1, -1); | ||
624 | |||
625 | writel(0, FLDTCNTR(flctl)); /* set 0 size */ | ||
626 | start_translation(flctl); | ||
627 | wait_completion(flctl); | ||
628 | break; | ||
629 | |||
630 | default: | ||
631 | break; | ||
632 | } | ||
633 | return; | ||
634 | |||
635 | read_normal_exit: | ||
636 | writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */ | ||
637 | start_translation(flctl); | ||
638 | read_fiforeg(flctl, flctl->read_bytes, 0); | ||
639 | wait_completion(flctl); | ||
640 | return; | ||
641 | } | ||
642 | |||
643 | static void flctl_select_chip(struct mtd_info *mtd, int chipnr) | ||
644 | { | ||
645 | struct sh_flctl *flctl = mtd_to_flctl(mtd); | ||
646 | uint32_t flcmncr_val = readl(FLCMNCR(flctl)); | ||
647 | |||
648 | switch (chipnr) { | ||
649 | case -1: | ||
650 | flcmncr_val &= ~CE0_ENABLE; | ||
651 | writel(flcmncr_val, FLCMNCR(flctl)); | ||
652 | break; | ||
653 | case 0: | ||
654 | flcmncr_val |= CE0_ENABLE; | ||
655 | writel(flcmncr_val, FLCMNCR(flctl)); | ||
656 | break; | ||
657 | default: | ||
658 | BUG(); | ||
659 | } | ||
660 | } | ||
661 | |||
662 | static void flctl_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | ||
663 | { | ||
664 | struct sh_flctl *flctl = mtd_to_flctl(mtd); | ||
665 | int i, index = flctl->index; | ||
666 | |||
667 | for (i = 0; i < len; i++) | ||
668 | flctl->done_buff[index + i] = buf[i]; | ||
669 | flctl->index += len; | ||
670 | } | ||
671 | |||
672 | static uint8_t flctl_read_byte(struct mtd_info *mtd) | ||
673 | { | ||
674 | struct sh_flctl *flctl = mtd_to_flctl(mtd); | ||
675 | int index = flctl->index; | ||
676 | uint8_t data; | ||
677 | |||
678 | data = flctl->done_buff[index]; | ||
679 | flctl->index++; | ||
680 | return data; | ||
681 | } | ||
682 | |||
683 | static void flctl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | ||
684 | { | ||
685 | int i; | ||
686 | |||
687 | for (i = 0; i < len; i++) | ||
688 | buf[i] = flctl_read_byte(mtd); | ||
689 | } | ||
690 | |||
691 | static int flctl_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) | ||
692 | { | ||
693 | int i; | ||
694 | |||
695 | for (i = 0; i < len; i++) | ||
696 | if (buf[i] != flctl_read_byte(mtd)) | ||
697 | return -EFAULT; | ||
698 | return 0; | ||
699 | } | ||
700 | |||
701 | static void flctl_register_init(struct sh_flctl *flctl, unsigned long val) | ||
702 | { | ||
703 | writel(val, FLCMNCR(flctl)); | ||
704 | } | ||
705 | |||
706 | static int flctl_chip_init_tail(struct mtd_info *mtd) | ||
707 | { | ||
708 | struct sh_flctl *flctl = mtd_to_flctl(mtd); | ||
709 | struct nand_chip *chip = &flctl->chip; | ||
710 | |||
711 | if (mtd->writesize == 512) { | ||
712 | flctl->page_size = 0; | ||
713 | if (chip->chipsize > (32 << 20)) { | ||
714 | /* big than 32MB */ | ||
715 | flctl->rw_ADRCNT = ADRCNT_4; | ||
716 | flctl->erase_ADRCNT = ADRCNT_3; | ||
717 | } else if (chip->chipsize > (2 << 16)) { | ||
718 | /* big than 128KB */ | ||
719 | flctl->rw_ADRCNT = ADRCNT_3; | ||
720 | flctl->erase_ADRCNT = ADRCNT_2; | ||
721 | } else { | ||
722 | flctl->rw_ADRCNT = ADRCNT_2; | ||
723 | flctl->erase_ADRCNT = ADRCNT_1; | ||
724 | } | ||
725 | } else { | ||
726 | flctl->page_size = 1; | ||
727 | if (chip->chipsize > (128 << 20)) { | ||
728 | /* big than 128MB */ | ||
729 | flctl->rw_ADRCNT = ADRCNT2_E; | ||
730 | flctl->erase_ADRCNT = ADRCNT_3; | ||
731 | } else if (chip->chipsize > (8 << 16)) { | ||
732 | /* big than 512KB */ | ||
733 | flctl->rw_ADRCNT = ADRCNT_4; | ||
734 | flctl->erase_ADRCNT = ADRCNT_2; | ||
735 | } else { | ||
736 | flctl->rw_ADRCNT = ADRCNT_3; | ||
737 | flctl->erase_ADRCNT = ADRCNT_1; | ||
738 | } | ||
739 | } | ||
740 | |||
741 | if (flctl->hwecc) { | ||
742 | if (mtd->writesize == 512) { | ||
743 | chip->ecc.layout = &flctl_4secc_oob_16; | ||
744 | chip->badblock_pattern = &flctl_4secc_smallpage; | ||
745 | } else { | ||
746 | chip->ecc.layout = &flctl_4secc_oob_64; | ||
747 | chip->badblock_pattern = &flctl_4secc_largepage; | ||
748 | } | ||
749 | |||
750 | chip->ecc.size = 512; | ||
751 | chip->ecc.bytes = 10; | ||
752 | chip->ecc.read_page = flctl_read_page_hwecc; | ||
753 | chip->ecc.write_page = flctl_write_page_hwecc; | ||
754 | chip->ecc.mode = NAND_ECC_HW; | ||
755 | |||
756 | /* 4 symbols ECC enabled */ | ||
757 | writel(readl(FLCMNCR(flctl)) | _4ECCEN | ECCPOS2 | ECCPOS_02, | ||
758 | FLCMNCR(flctl)); | ||
759 | } else { | ||
760 | chip->ecc.mode = NAND_ECC_SOFT; | ||
761 | } | ||
762 | |||
763 | return 0; | ||
764 | } | ||
765 | |||
766 | static int __init flctl_probe(struct platform_device *pdev) | ||
767 | { | ||
768 | struct resource *res; | ||
769 | struct sh_flctl *flctl; | ||
770 | struct mtd_info *flctl_mtd; | ||
771 | struct nand_chip *nand; | ||
772 | struct sh_flctl_platform_data *pdata; | ||
773 | int ret; | ||
774 | |||
775 | pdata = pdev->dev.platform_data; | ||
776 | if (pdata == NULL) { | ||
777 | printk(KERN_ERR "sh_flctl platform_data not found.\n"); | ||
778 | return -ENODEV; | ||
779 | } | ||
780 | |||
781 | flctl = kzalloc(sizeof(struct sh_flctl), GFP_KERNEL); | ||
782 | if (!flctl) { | ||
783 | printk(KERN_ERR "Unable to allocate NAND MTD dev structure.\n"); | ||
784 | return -ENOMEM; | ||
785 | } | ||
786 | |||
787 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
788 | if (!res) { | ||
789 | printk(KERN_ERR "%s: resource not found.\n", __func__); | ||
790 | ret = -ENODEV; | ||
791 | goto err; | ||
792 | } | ||
793 | |||
794 | flctl->reg = ioremap(res->start, res->end - res->start + 1); | ||
795 | if (flctl->reg == NULL) { | ||
796 | printk(KERN_ERR "%s: ioremap error.\n", __func__); | ||
797 | ret = -ENOMEM; | ||
798 | goto err; | ||
799 | } | ||
800 | |||
801 | platform_set_drvdata(pdev, flctl); | ||
802 | flctl_mtd = &flctl->mtd; | ||
803 | nand = &flctl->chip; | ||
804 | flctl_mtd->priv = nand; | ||
805 | flctl->hwecc = pdata->has_hwecc; | ||
806 | |||
807 | flctl_register_init(flctl, pdata->flcmncr_val); | ||
808 | |||
809 | nand->options = NAND_NO_AUTOINCR; | ||
810 | |||
811 | /* Set address of hardware control function */ | ||
812 | /* 20 us command delay time */ | ||
813 | nand->chip_delay = 20; | ||
814 | |||
815 | nand->read_byte = flctl_read_byte; | ||
816 | nand->write_buf = flctl_write_buf; | ||
817 | nand->read_buf = flctl_read_buf; | ||
818 | nand->verify_buf = flctl_verify_buf; | ||
819 | nand->select_chip = flctl_select_chip; | ||
820 | nand->cmdfunc = flctl_cmdfunc; | ||
821 | |||
822 | ret = nand_scan_ident(flctl_mtd, 1); | ||
823 | if (ret) | ||
824 | goto err; | ||
825 | |||
826 | ret = flctl_chip_init_tail(flctl_mtd); | ||
827 | if (ret) | ||
828 | goto err; | ||
829 | |||
830 | ret = nand_scan_tail(flctl_mtd); | ||
831 | if (ret) | ||
832 | goto err; | ||
833 | |||
834 | add_mtd_partitions(flctl_mtd, pdata->parts, pdata->nr_parts); | ||
835 | |||
836 | return 0; | ||
837 | |||
838 | err: | ||
839 | kfree(flctl); | ||
840 | return ret; | ||
841 | } | ||
842 | |||
843 | static int __exit flctl_remove(struct platform_device *pdev) | ||
844 | { | ||
845 | struct sh_flctl *flctl = platform_get_drvdata(pdev); | ||
846 | |||
847 | nand_release(&flctl->mtd); | ||
848 | kfree(flctl); | ||
849 | |||
850 | return 0; | ||
851 | } | ||
852 | |||
853 | static struct platform_driver flctl_driver = { | ||
854 | .probe = flctl_probe, | ||
855 | .remove = flctl_remove, | ||
856 | .driver = { | ||
857 | .name = "sh_flctl", | ||
858 | .owner = THIS_MODULE, | ||
859 | }, | ||
860 | }; | ||
861 | |||
862 | static int __init flctl_nand_init(void) | ||
863 | { | ||
864 | return platform_driver_register(&flctl_driver); | ||
865 | } | ||
866 | |||
867 | static void __exit flctl_nand_cleanup(void) | ||
868 | { | ||
869 | platform_driver_unregister(&flctl_driver); | ||
870 | } | ||
871 | |||
872 | module_init(flctl_nand_init); | ||
873 | module_exit(flctl_nand_cleanup); | ||
874 | |||
875 | MODULE_LICENSE("GPL"); | ||
876 | MODULE_AUTHOR("Yoshihiro Shimoda"); | ||
877 | MODULE_DESCRIPTION("SuperH FLCTL driver"); | ||
878 | MODULE_ALIAS("platform:sh_flctl"); | ||
diff --git a/drivers/mtd/nand/toto.c b/drivers/mtd/nand/toto.c deleted file mode 100644 index bbf492e6830d..000000000000 --- a/drivers/mtd/nand/toto.c +++ /dev/null | |||
@@ -1,206 +0,0 @@ | |||
1 | /* | ||
2 | * drivers/mtd/nand/toto.c | ||
3 | * | ||
4 | * Copyright (c) 2003 Texas Instruments | ||
5 | * | ||
6 | * Derived from drivers/mtd/autcpu12.c | ||
7 | * | ||
8 | * Copyright (c) 2002 Thomas Gleixner <tgxl@linutronix.de> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * Overview: | ||
15 | * This is a device driver for the NAND flash device found on the | ||
16 | * TI fido board. It supports 32MiB and 64MiB cards | ||
17 | */ | ||
18 | |||
19 | #include <linux/slab.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/mtd/mtd.h> | ||
24 | #include <linux/mtd/nand.h> | ||
25 | #include <linux/mtd/partitions.h> | ||
26 | #include <asm/io.h> | ||
27 | #include <asm/arch/hardware.h> | ||
28 | #include <asm/sizes.h> | ||
29 | #include <asm/arch/toto.h> | ||
30 | #include <asm/arch-omap1510/hardware.h> | ||
31 | #include <asm/arch/gpio.h> | ||
32 | |||
33 | #define CONFIG_NAND_WORKAROUND 1 | ||
34 | |||
35 | /* | ||
36 | * MTD structure for TOTO board | ||
37 | */ | ||
38 | static struct mtd_info *toto_mtd = NULL; | ||
39 | |||
40 | static unsigned long toto_io_base = OMAP_FLASH_1_BASE; | ||
41 | |||
42 | /* | ||
43 | * Define partitions for flash devices | ||
44 | */ | ||
45 | |||
46 | static struct mtd_partition partition_info64M[] = { | ||
47 | { .name = "toto kernel partition 1", | ||
48 | .offset = 0, | ||
49 | .size = 2 * SZ_1M }, | ||
50 | { .name = "toto file sys partition 2", | ||
51 | .offset = 2 * SZ_1M, | ||
52 | .size = 14 * SZ_1M }, | ||
53 | { .name = "toto user partition 3", | ||
54 | .offset = 16 * SZ_1M, | ||
55 | .size = 16 * SZ_1M }, | ||
56 | { .name = "toto devboard extra partition 4", | ||
57 | .offset = 32 * SZ_1M, | ||
58 | .size = 32 * SZ_1M }, | ||
59 | }; | ||
60 | |||
61 | static struct mtd_partition partition_info32M[] = { | ||
62 | { .name = "toto kernel partition 1", | ||
63 | .offset = 0, | ||
64 | .size = 2 * SZ_1M }, | ||
65 | { .name = "toto file sys partition 2", | ||
66 | .offset = 2 * SZ_1M, | ||
67 | .size = 14 * SZ_1M }, | ||
68 | { .name = "toto user partition 3", | ||
69 | .offset = 16 * SZ_1M, | ||
70 | .size = 16 * SZ_1M }, | ||
71 | }; | ||
72 | |||
73 | #define NUM_PARTITIONS32M 3 | ||
74 | #define NUM_PARTITIONS64M 4 | ||
75 | |||
76 | /* | ||
77 | * hardware specific access to control-lines | ||
78 | * | ||
79 | * ctrl: | ||
80 | * NAND_NCE: bit 0 -> bit 14 (0x4000) | ||
81 | * NAND_CLE: bit 1 -> bit 12 (0x1000) | ||
82 | * NAND_ALE: bit 2 -> bit 1 (0x0002) | ||
83 | */ | ||
84 | static void toto_hwcontrol(struct mtd_info *mtd, int cmd, | ||
85 | unsigned int ctrl) | ||
86 | { | ||
87 | struct nand_chip *chip = mtd->priv; | ||
88 | |||
89 | if (ctrl & NAND_CTRL_CHANGE) { | ||
90 | unsigned long bits; | ||
91 | |||
92 | /* hopefully enough time for tc make proceding write to clear */ | ||
93 | udelay(1); | ||
94 | |||
95 | bits = (~ctrl & NAND_NCE) << 14; | ||
96 | bits |= (ctrl & NAND_CLE) << 12; | ||
97 | bits |= (ctrl & NAND_ALE) >> 1; | ||
98 | |||
99 | #warning Wild guess as gpiosetout() is nowhere defined in the kernel source - tglx | ||
100 | gpiosetout(0x5002, bits); | ||
101 | |||
102 | #ifdef CONFIG_NAND_WORKAROUND | ||
103 | /* "some" dev boards busted, blue wired to rts2 :( */ | ||
104 | rts2setout(2, (ctrl & NAND_CLE) << 1); | ||
105 | #endif | ||
106 | /* allow time to ensure gpio state to over take memory write */ | ||
107 | udelay(1); | ||
108 | } | ||
109 | |||
110 | if (cmd != NAND_CMD_NONE) | ||
111 | writeb(cmd, chip->IO_ADDR_W); | ||
112 | } | ||
113 | |||
114 | /* | ||
115 | * Main initialization routine | ||
116 | */ | ||
117 | static int __init toto_init(void) | ||
118 | { | ||
119 | struct nand_chip *this; | ||
120 | int err = 0; | ||
121 | |||
122 | /* Allocate memory for MTD device structure and private data */ | ||
123 | toto_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); | ||
124 | if (!toto_mtd) { | ||
125 | printk(KERN_WARNING "Unable to allocate toto NAND MTD device structure.\n"); | ||
126 | err = -ENOMEM; | ||
127 | goto out; | ||
128 | } | ||
129 | |||
130 | /* Get pointer to private data */ | ||
131 | this = (struct nand_chip *)(&toto_mtd[1]); | ||
132 | |||
133 | /* Initialize structures */ | ||
134 | memset(toto_mtd, 0, sizeof(struct mtd_info)); | ||
135 | memset(this, 0, sizeof(struct nand_chip)); | ||
136 | |||
137 | /* Link the private data with the MTD structure */ | ||
138 | toto_mtd->priv = this; | ||
139 | toto_mtd->owner = THIS_MODULE; | ||
140 | |||
141 | /* Set address of NAND IO lines */ | ||
142 | this->IO_ADDR_R = toto_io_base; | ||
143 | this->IO_ADDR_W = toto_io_base; | ||
144 | this->cmd_ctrl = toto_hwcontrol; | ||
145 | this->dev_ready = NULL; | ||
146 | /* 25 us command delay time */ | ||
147 | this->chip_delay = 30; | ||
148 | this->ecc.mode = NAND_ECC_SOFT; | ||
149 | |||
150 | /* Scan to find existance of the device */ | ||
151 | if (nand_scan(toto_mtd, 1)) { | ||
152 | err = -ENXIO; | ||
153 | goto out_mtd; | ||
154 | } | ||
155 | |||
156 | /* Register the partitions */ | ||
157 | switch (toto_mtd->size) { | ||
158 | case SZ_64M: | ||
159 | add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); | ||
160 | break; | ||
161 | case SZ_32M: | ||
162 | add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); | ||
163 | break; | ||
164 | default:{ | ||
165 | printk(KERN_WARNING "Unsupported Nand device\n"); | ||
166 | err = -ENXIO; | ||
167 | goto out_buf; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | gpioreserve(NAND_MASK); /* claim our gpios */ | ||
172 | archflashwp(0, 0); /* open up flash for writing */ | ||
173 | |||
174 | goto out; | ||
175 | |||
176 | out_mtd: | ||
177 | kfree(toto_mtd); | ||
178 | out: | ||
179 | return err; | ||
180 | } | ||
181 | |||
182 | module_init(toto_init); | ||
183 | |||
184 | /* | ||
185 | * Clean up routine | ||
186 | */ | ||
187 | static void __exit toto_cleanup(void) | ||
188 | { | ||
189 | /* Release resources, unregister device */ | ||
190 | nand_release(toto_mtd); | ||
191 | |||
192 | /* Free the MTD device structure */ | ||
193 | kfree(toto_mtd); | ||
194 | |||
195 | /* stop flash writes */ | ||
196 | archflashwp(0, 1); | ||
197 | |||
198 | /* release gpios to system */ | ||
199 | gpiorelease(NAND_MASK); | ||
200 | } | ||
201 | |||
202 | module_exit(toto_cleanup); | ||
203 | |||
204 | MODULE_LICENSE("GPL"); | ||
205 | MODULE_AUTHOR("Richard Woodruff <r-woodruff2@ti.com>"); | ||
206 | MODULE_DESCRIPTION("Glue layer for NAND flash on toto board"); | ||
diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c index 4f80c2fd89af..9e45b3f39c0e 100644 --- a/drivers/mtd/ofpart.c +++ b/drivers/mtd/ofpart.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/mtd/partitions.h> | 20 | #include <linux/mtd/partitions.h> |
21 | 21 | ||
22 | int __devinit of_mtd_parse_partitions(struct device *dev, | 22 | int __devinit of_mtd_parse_partitions(struct device *dev, |
23 | struct mtd_info *mtd, | ||
24 | struct device_node *node, | 23 | struct device_node *node, |
25 | struct mtd_partition **pparts) | 24 | struct mtd_partition **pparts) |
26 | { | 25 | { |
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig index cb41cbca64f7..79fa79e8f8de 100644 --- a/drivers/mtd/onenand/Kconfig +++ b/drivers/mtd/onenand/Kconfig | |||
@@ -27,8 +27,16 @@ config MTD_ONENAND_GENERIC | |||
27 | help | 27 | help |
28 | Support for OneNAND flash via platform device driver. | 28 | Support for OneNAND flash via platform device driver. |
29 | 29 | ||
30 | config MTD_ONENAND_OMAP2 | ||
31 | tristate "OneNAND on OMAP2/OMAP3 support" | ||
32 | depends on MTD_ONENAND && (ARCH_OMAP2 || ARCH_OMAP3) | ||
33 | help | ||
34 | Support for a OneNAND flash device connected to an OMAP2/OMAP3 CPU | ||
35 | via the GPMC memory controller. | ||
36 | |||
30 | config MTD_ONENAND_OTP | 37 | config MTD_ONENAND_OTP |
31 | bool "OneNAND OTP Support" | 38 | bool "OneNAND OTP Support" |
39 | select HAVE_MTD_OTP | ||
32 | help | 40 | help |
33 | One Block of the NAND Flash Array memory is reserved as | 41 | One Block of the NAND Flash Array memory is reserved as |
34 | a One-Time Programmable Block memory area. | 42 | a One-Time Programmable Block memory area. |
diff --git a/drivers/mtd/onenand/Makefile b/drivers/mtd/onenand/Makefile index 4d2eacfd7e11..64b6cc61a520 100644 --- a/drivers/mtd/onenand/Makefile +++ b/drivers/mtd/onenand/Makefile | |||
@@ -7,6 +7,7 @@ obj-$(CONFIG_MTD_ONENAND) += onenand.o | |||
7 | 7 | ||
8 | # Board specific. | 8 | # Board specific. |
9 | obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o | 9 | obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o |
10 | obj-$(CONFIG_MTD_ONENAND_OMAP2) += omap2.o | ||
10 | 11 | ||
11 | # Simulator | 12 | # Simulator |
12 | obj-$(CONFIG_MTD_ONENAND_SIM) += onenand_sim.o | 13 | obj-$(CONFIG_MTD_ONENAND_SIM) += onenand_sim.o |
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c new file mode 100644 index 000000000000..8387e05daae2 --- /dev/null +++ b/drivers/mtd/onenand/omap2.c | |||
@@ -0,0 +1,802 @@ | |||
1 | /* | ||
2 | * linux/drivers/mtd/onenand/omap2.c | ||
3 | * | ||
4 | * OneNAND driver for OMAP2 / OMAP3 | ||
5 | * | ||
6 | * Copyright © 2005-2006 Nokia Corporation | ||
7 | * | ||
8 | * Author: Jarkko Lavinen <jarkko.lavinen@nokia.com> and Juha Yrjölä | ||
9 | * IRQ and DMA support written by Timo Teras | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License version 2 as published by | ||
13 | * the Free Software Foundation. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
16 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
18 | * more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License along with | ||
21 | * this program; see the file COPYING. If not, write to the Free Software | ||
22 | * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #include <linux/device.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/mtd/mtd.h> | ||
30 | #include <linux/mtd/onenand.h> | ||
31 | #include <linux/mtd/partitions.h> | ||
32 | #include <linux/platform_device.h> | ||
33 | #include <linux/interrupt.h> | ||
34 | #include <linux/delay.h> | ||
35 | |||
36 | #include <asm/io.h> | ||
37 | #include <asm/mach/flash.h> | ||
38 | #include <asm/arch/gpmc.h> | ||
39 | #include <asm/arch/onenand.h> | ||
40 | #include <asm/arch/gpio.h> | ||
41 | #include <asm/arch/gpmc.h> | ||
42 | #include <asm/arch/pm.h> | ||
43 | |||
44 | #include <linux/dma-mapping.h> | ||
45 | #include <asm/dma-mapping.h> | ||
46 | #include <asm/arch/dma.h> | ||
47 | |||
48 | #include <asm/arch/board.h> | ||
49 | |||
50 | #define DRIVER_NAME "omap2-onenand" | ||
51 | |||
52 | #define ONENAND_IO_SIZE SZ_128K | ||
53 | #define ONENAND_BUFRAM_SIZE (1024 * 5) | ||
54 | |||
55 | struct omap2_onenand { | ||
56 | struct platform_device *pdev; | ||
57 | int gpmc_cs; | ||
58 | unsigned long phys_base; | ||
59 | int gpio_irq; | ||
60 | struct mtd_info mtd; | ||
61 | struct mtd_partition *parts; | ||
62 | struct onenand_chip onenand; | ||
63 | struct completion irq_done; | ||
64 | struct completion dma_done; | ||
65 | int dma_channel; | ||
66 | int freq; | ||
67 | int (*setup)(void __iomem *base, int freq); | ||
68 | }; | ||
69 | |||
70 | static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data) | ||
71 | { | ||
72 | struct omap2_onenand *c = data; | ||
73 | |||
74 | complete(&c->dma_done); | ||
75 | } | ||
76 | |||
77 | static irqreturn_t omap2_onenand_interrupt(int irq, void *dev_id) | ||
78 | { | ||
79 | struct omap2_onenand *c = dev_id; | ||
80 | |||
81 | complete(&c->irq_done); | ||
82 | |||
83 | return IRQ_HANDLED; | ||
84 | } | ||
85 | |||
86 | static inline unsigned short read_reg(struct omap2_onenand *c, int reg) | ||
87 | { | ||
88 | return readw(c->onenand.base + reg); | ||
89 | } | ||
90 | |||
91 | static inline void write_reg(struct omap2_onenand *c, unsigned short value, | ||
92 | int reg) | ||
93 | { | ||
94 | writew(value, c->onenand.base + reg); | ||
95 | } | ||
96 | |||
97 | static void wait_err(char *msg, int state, unsigned int ctrl, unsigned int intr) | ||
98 | { | ||
99 | printk(KERN_ERR "onenand_wait: %s! state %d ctrl 0x%04x intr 0x%04x\n", | ||
100 | msg, state, ctrl, intr); | ||
101 | } | ||
102 | |||
103 | static void wait_warn(char *msg, int state, unsigned int ctrl, | ||
104 | unsigned int intr) | ||
105 | { | ||
106 | printk(KERN_WARNING "onenand_wait: %s! state %d ctrl 0x%04x " | ||
107 | "intr 0x%04x\n", msg, state, ctrl, intr); | ||
108 | } | ||
109 | |||
110 | static int omap2_onenand_wait(struct mtd_info *mtd, int state) | ||
111 | { | ||
112 | struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd); | ||
113 | unsigned int intr = 0; | ||
114 | unsigned int ctrl; | ||
115 | unsigned long timeout; | ||
116 | u32 syscfg; | ||
117 | |||
118 | if (state == FL_RESETING) { | ||
119 | int i; | ||
120 | |||
121 | for (i = 0; i < 20; i++) { | ||
122 | udelay(1); | ||
123 | intr = read_reg(c, ONENAND_REG_INTERRUPT); | ||
124 | if (intr & ONENAND_INT_MASTER) | ||
125 | break; | ||
126 | } | ||
127 | ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS); | ||
128 | if (ctrl & ONENAND_CTRL_ERROR) { | ||
129 | wait_err("controller error", state, ctrl, intr); | ||
130 | return -EIO; | ||
131 | } | ||
132 | if (!(intr & ONENAND_INT_RESET)) { | ||
133 | wait_err("timeout", state, ctrl, intr); | ||
134 | return -EIO; | ||
135 | } | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | if (state != FL_READING) { | ||
140 | int result; | ||
141 | |||
142 | /* Turn interrupts on */ | ||
143 | syscfg = read_reg(c, ONENAND_REG_SYS_CFG1); | ||
144 | if (!(syscfg & ONENAND_SYS_CFG1_IOBE)) { | ||
145 | syscfg |= ONENAND_SYS_CFG1_IOBE; | ||
146 | write_reg(c, syscfg, ONENAND_REG_SYS_CFG1); | ||
147 | if (cpu_is_omap34xx()) | ||
148 | /* Add a delay to let GPIO settle */ | ||
149 | syscfg = read_reg(c, ONENAND_REG_SYS_CFG1); | ||
150 | } | ||
151 | |||
152 | INIT_COMPLETION(c->irq_done); | ||
153 | if (c->gpio_irq) { | ||
154 | result = omap_get_gpio_datain(c->gpio_irq); | ||
155 | if (result == -1) { | ||
156 | ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS); | ||
157 | intr = read_reg(c, ONENAND_REG_INTERRUPT); | ||
158 | wait_err("gpio error", state, ctrl, intr); | ||
159 | return -EIO; | ||
160 | } | ||
161 | } else | ||
162 | result = 0; | ||
163 | if (result == 0) { | ||
164 | int retry_cnt = 0; | ||
165 | retry: | ||
166 | result = wait_for_completion_timeout(&c->irq_done, | ||
167 | msecs_to_jiffies(20)); | ||
168 | if (result == 0) { | ||
169 | /* Timeout after 20ms */ | ||
170 | ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS); | ||
171 | if (ctrl & ONENAND_CTRL_ONGO) { | ||
172 | /* | ||
173 | * The operation seems to be still going | ||
174 | * so give it some more time. | ||
175 | */ | ||
176 | retry_cnt += 1; | ||
177 | if (retry_cnt < 3) | ||
178 | goto retry; | ||
179 | intr = read_reg(c, | ||
180 | ONENAND_REG_INTERRUPT); | ||
181 | wait_err("timeout", state, ctrl, intr); | ||
182 | return -EIO; | ||
183 | } | ||
184 | intr = read_reg(c, ONENAND_REG_INTERRUPT); | ||
185 | if ((intr & ONENAND_INT_MASTER) == 0) | ||
186 | wait_warn("timeout", state, ctrl, intr); | ||
187 | } | ||
188 | } | ||
189 | } else { | ||
190 | int retry_cnt = 0; | ||
191 | |||
192 | /* Turn interrupts off */ | ||
193 | syscfg = read_reg(c, ONENAND_REG_SYS_CFG1); | ||
194 | syscfg &= ~ONENAND_SYS_CFG1_IOBE; | ||
195 | write_reg(c, syscfg, ONENAND_REG_SYS_CFG1); | ||
196 | |||
197 | timeout = jiffies + msecs_to_jiffies(20); | ||
198 | while (1) { | ||
199 | if (time_before(jiffies, timeout)) { | ||
200 | intr = read_reg(c, ONENAND_REG_INTERRUPT); | ||
201 | if (intr & ONENAND_INT_MASTER) | ||
202 | break; | ||
203 | } else { | ||
204 | /* Timeout after 20ms */ | ||
205 | ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS); | ||
206 | if (ctrl & ONENAND_CTRL_ONGO) { | ||
207 | /* | ||
208 | * The operation seems to be still going | ||
209 | * so give it some more time. | ||
210 | */ | ||
211 | retry_cnt += 1; | ||
212 | if (retry_cnt < 3) { | ||
213 | timeout = jiffies + | ||
214 | msecs_to_jiffies(20); | ||
215 | continue; | ||
216 | } | ||
217 | } | ||
218 | break; | ||
219 | } | ||
220 | } | ||
221 | } | ||
222 | |||
223 | intr = read_reg(c, ONENAND_REG_INTERRUPT); | ||
224 | ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS); | ||
225 | |||
226 | if (intr & ONENAND_INT_READ) { | ||
227 | int ecc = read_reg(c, ONENAND_REG_ECC_STATUS); | ||
228 | |||
229 | if (ecc) { | ||
230 | unsigned int addr1, addr8; | ||
231 | |||
232 | addr1 = read_reg(c, ONENAND_REG_START_ADDRESS1); | ||
233 | addr8 = read_reg(c, ONENAND_REG_START_ADDRESS8); | ||
234 | if (ecc & ONENAND_ECC_2BIT_ALL) { | ||
235 | printk(KERN_ERR "onenand_wait: ECC error = " | ||
236 | "0x%04x, addr1 %#x, addr8 %#x\n", | ||
237 | ecc, addr1, addr8); | ||
238 | mtd->ecc_stats.failed++; | ||
239 | return -EBADMSG; | ||
240 | } else if (ecc & ONENAND_ECC_1BIT_ALL) { | ||
241 | printk(KERN_NOTICE "onenand_wait: correctable " | ||
242 | "ECC error = 0x%04x, addr1 %#x, " | ||
243 | "addr8 %#x\n", ecc, addr1, addr8); | ||
244 | mtd->ecc_stats.corrected++; | ||
245 | } | ||
246 | } | ||
247 | } else if (state == FL_READING) { | ||
248 | wait_err("timeout", state, ctrl, intr); | ||
249 | return -EIO; | ||
250 | } | ||
251 | |||
252 | if (ctrl & ONENAND_CTRL_ERROR) { | ||
253 | wait_err("controller error", state, ctrl, intr); | ||
254 | if (ctrl & ONENAND_CTRL_LOCK) | ||
255 | printk(KERN_ERR "onenand_wait: " | ||
256 | "Device is write protected!!!\n"); | ||
257 | return -EIO; | ||
258 | } | ||
259 | |||
260 | if (ctrl & 0xFE9F) | ||
261 | wait_warn("unexpected controller status", state, ctrl, intr); | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static inline int omap2_onenand_bufferram_offset(struct mtd_info *mtd, int area) | ||
267 | { | ||
268 | struct onenand_chip *this = mtd->priv; | ||
269 | |||
270 | if (ONENAND_CURRENT_BUFFERRAM(this)) { | ||
271 | if (area == ONENAND_DATARAM) | ||
272 | return mtd->writesize; | ||
273 | if (area == ONENAND_SPARERAM) | ||
274 | return mtd->oobsize; | ||
275 | } | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | #if defined(CONFIG_ARCH_OMAP3) || defined(MULTI_OMAP2) | ||
281 | |||
282 | static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area, | ||
283 | unsigned char *buffer, int offset, | ||
284 | size_t count) | ||
285 | { | ||
286 | struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd); | ||
287 | struct onenand_chip *this = mtd->priv; | ||
288 | dma_addr_t dma_src, dma_dst; | ||
289 | int bram_offset; | ||
290 | unsigned long timeout; | ||
291 | void *buf = (void *)buffer; | ||
292 | size_t xtra; | ||
293 | volatile unsigned *done; | ||
294 | |||
295 | bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset; | ||
296 | if (bram_offset & 3 || (size_t)buf & 3 || count < 384) | ||
297 | goto out_copy; | ||
298 | |||
299 | if (buf >= high_memory) { | ||
300 | struct page *p1; | ||
301 | |||
302 | if (((size_t)buf & PAGE_MASK) != | ||
303 | ((size_t)(buf + count - 1) & PAGE_MASK)) | ||
304 | goto out_copy; | ||
305 | p1 = vmalloc_to_page(buf); | ||
306 | if (!p1) | ||
307 | goto out_copy; | ||
308 | buf = page_address(p1) + ((size_t)buf & ~PAGE_MASK); | ||
309 | } | ||
310 | |||
311 | xtra = count & 3; | ||
312 | if (xtra) { | ||
313 | count -= xtra; | ||
314 | memcpy(buf + count, this->base + bram_offset + count, xtra); | ||
315 | } | ||
316 | |||
317 | dma_src = c->phys_base + bram_offset; | ||
318 | dma_dst = dma_map_single(&c->pdev->dev, buf, count, DMA_FROM_DEVICE); | ||
319 | if (dma_mapping_error(&c->pdev->dev, dma_dst)) { | ||
320 | dev_err(&c->pdev->dev, | ||
321 | "Couldn't DMA map a %d byte buffer\n", | ||
322 | count); | ||
323 | goto out_copy; | ||
324 | } | ||
325 | |||
326 | omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32, | ||
327 | count >> 2, 1, 0, 0, 0); | ||
328 | omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC, | ||
329 | dma_src, 0, 0); | ||
330 | omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC, | ||
331 | dma_dst, 0, 0); | ||
332 | |||
333 | INIT_COMPLETION(c->dma_done); | ||
334 | omap_start_dma(c->dma_channel); | ||
335 | |||
336 | timeout = jiffies + msecs_to_jiffies(20); | ||
337 | done = &c->dma_done.done; | ||
338 | while (time_before(jiffies, timeout)) | ||
339 | if (*done) | ||
340 | break; | ||
341 | |||
342 | dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE); | ||
343 | |||
344 | if (!*done) { | ||
345 | dev_err(&c->pdev->dev, "timeout waiting for DMA\n"); | ||
346 | goto out_copy; | ||
347 | } | ||
348 | |||
349 | return 0; | ||
350 | |||
351 | out_copy: | ||
352 | memcpy(buf, this->base + bram_offset, count); | ||
353 | return 0; | ||
354 | } | ||
355 | |||
356 | static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area, | ||
357 | const unsigned char *buffer, | ||
358 | int offset, size_t count) | ||
359 | { | ||
360 | struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd); | ||
361 | struct onenand_chip *this = mtd->priv; | ||
362 | dma_addr_t dma_src, dma_dst; | ||
363 | int bram_offset; | ||
364 | unsigned long timeout; | ||
365 | void *buf = (void *)buffer; | ||
366 | volatile unsigned *done; | ||
367 | |||
368 | bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset; | ||
369 | if (bram_offset & 3 || (size_t)buf & 3 || count < 384) | ||
370 | goto out_copy; | ||
371 | |||
372 | /* panic_write() may be in an interrupt context */ | ||
373 | if (in_interrupt()) | ||
374 | goto out_copy; | ||
375 | |||
376 | if (buf >= high_memory) { | ||
377 | struct page *p1; | ||
378 | |||
379 | if (((size_t)buf & PAGE_MASK) != | ||
380 | ((size_t)(buf + count - 1) & PAGE_MASK)) | ||
381 | goto out_copy; | ||
382 | p1 = vmalloc_to_page(buf); | ||
383 | if (!p1) | ||
384 | goto out_copy; | ||
385 | buf = page_address(p1) + ((size_t)buf & ~PAGE_MASK); | ||
386 | } | ||
387 | |||
388 | dma_src = dma_map_single(&c->pdev->dev, buf, count, DMA_TO_DEVICE); | ||
389 | dma_dst = c->phys_base + bram_offset; | ||
390 | if (dma_mapping_error(&c->pdev->dev, dma_dst)) { | ||
391 | dev_err(&c->pdev->dev, | ||
392 | "Couldn't DMA map a %d byte buffer\n", | ||
393 | count); | ||
394 | return -1; | ||
395 | } | ||
396 | |||
397 | omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32, | ||
398 | count >> 2, 1, 0, 0, 0); | ||
399 | omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC, | ||
400 | dma_src, 0, 0); | ||
401 | omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC, | ||
402 | dma_dst, 0, 0); | ||
403 | |||
404 | INIT_COMPLETION(c->dma_done); | ||
405 | omap_start_dma(c->dma_channel); | ||
406 | |||
407 | timeout = jiffies + msecs_to_jiffies(20); | ||
408 | done = &c->dma_done.done; | ||
409 | while (time_before(jiffies, timeout)) | ||
410 | if (*done) | ||
411 | break; | ||
412 | |||
413 | dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_TO_DEVICE); | ||
414 | |||
415 | if (!*done) { | ||
416 | dev_err(&c->pdev->dev, "timeout waiting for DMA\n"); | ||
417 | goto out_copy; | ||
418 | } | ||
419 | |||
420 | return 0; | ||
421 | |||
422 | out_copy: | ||
423 | memcpy(this->base + bram_offset, buf, count); | ||
424 | return 0; | ||
425 | } | ||
426 | |||
427 | #else | ||
428 | |||
429 | int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area, | ||
430 | unsigned char *buffer, int offset, | ||
431 | size_t count); | ||
432 | |||
433 | int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area, | ||
434 | const unsigned char *buffer, | ||
435 | int offset, size_t count); | ||
436 | |||
437 | #endif | ||
438 | |||
439 | #if defined(CONFIG_ARCH_OMAP2) || defined(MULTI_OMAP2) | ||
440 | |||
441 | static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area, | ||
442 | unsigned char *buffer, int offset, | ||
443 | size_t count) | ||
444 | { | ||
445 | struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd); | ||
446 | struct onenand_chip *this = mtd->priv; | ||
447 | dma_addr_t dma_src, dma_dst; | ||
448 | int bram_offset; | ||
449 | |||
450 | bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset; | ||
451 | /* DMA is not used. Revisit PM requirements before enabling it. */ | ||
452 | if (1 || (c->dma_channel < 0) || | ||
453 | ((void *) buffer >= (void *) high_memory) || (bram_offset & 3) || | ||
454 | (((unsigned int) buffer) & 3) || (count < 1024) || (count & 3)) { | ||
455 | memcpy(buffer, (__force void *)(this->base + bram_offset), | ||
456 | count); | ||
457 | return 0; | ||
458 | } | ||
459 | |||
460 | dma_src = c->phys_base + bram_offset; | ||
461 | dma_dst = dma_map_single(&c->pdev->dev, buffer, count, | ||
462 | DMA_FROM_DEVICE); | ||
463 | if (dma_mapping_error(&c->pdev->dev, dma_dst)) { | ||
464 | dev_err(&c->pdev->dev, | ||
465 | "Couldn't DMA map a %d byte buffer\n", | ||
466 | count); | ||
467 | return -1; | ||
468 | } | ||
469 | |||
470 | omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32, | ||
471 | count / 4, 1, 0, 0, 0); | ||
472 | omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC, | ||
473 | dma_src, 0, 0); | ||
474 | omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC, | ||
475 | dma_dst, 0, 0); | ||
476 | |||
477 | INIT_COMPLETION(c->dma_done); | ||
478 | omap_start_dma(c->dma_channel); | ||
479 | wait_for_completion(&c->dma_done); | ||
480 | |||
481 | dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE); | ||
482 | |||
483 | return 0; | ||
484 | } | ||
485 | |||
486 | static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area, | ||
487 | const unsigned char *buffer, | ||
488 | int offset, size_t count) | ||
489 | { | ||
490 | struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd); | ||
491 | struct onenand_chip *this = mtd->priv; | ||
492 | dma_addr_t dma_src, dma_dst; | ||
493 | int bram_offset; | ||
494 | |||
495 | bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset; | ||
496 | /* DMA is not used. Revisit PM requirements before enabling it. */ | ||
497 | if (1 || (c->dma_channel < 0) || | ||
498 | ((void *) buffer >= (void *) high_memory) || (bram_offset & 3) || | ||
499 | (((unsigned int) buffer) & 3) || (count < 1024) || (count & 3)) { | ||
500 | memcpy((__force void *)(this->base + bram_offset), buffer, | ||
501 | count); | ||
502 | return 0; | ||
503 | } | ||
504 | |||
505 | dma_src = dma_map_single(&c->pdev->dev, (void *) buffer, count, | ||
506 | DMA_TO_DEVICE); | ||
507 | dma_dst = c->phys_base + bram_offset; | ||
508 | if (dma_mapping_error(&c->pdev->dev, dma_dst)) { | ||
509 | dev_err(&c->pdev->dev, | ||
510 | "Couldn't DMA map a %d byte buffer\n", | ||
511 | count); | ||
512 | return -1; | ||
513 | } | ||
514 | |||
515 | omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S16, | ||
516 | count / 2, 1, 0, 0, 0); | ||
517 | omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC, | ||
518 | dma_src, 0, 0); | ||
519 | omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC, | ||
520 | dma_dst, 0, 0); | ||
521 | |||
522 | INIT_COMPLETION(c->dma_done); | ||
523 | omap_start_dma(c->dma_channel); | ||
524 | wait_for_completion(&c->dma_done); | ||
525 | |||
526 | dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_TO_DEVICE); | ||
527 | |||
528 | return 0; | ||
529 | } | ||
530 | |||
531 | #else | ||
532 | |||
533 | int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area, | ||
534 | unsigned char *buffer, int offset, | ||
535 | size_t count); | ||
536 | |||
537 | int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area, | ||
538 | const unsigned char *buffer, | ||
539 | int offset, size_t count); | ||
540 | |||
541 | #endif | ||
542 | |||
543 | static struct platform_driver omap2_onenand_driver; | ||
544 | |||
545 | static int __adjust_timing(struct device *dev, void *data) | ||
546 | { | ||
547 | int ret = 0; | ||
548 | struct omap2_onenand *c; | ||
549 | |||
550 | c = dev_get_drvdata(dev); | ||
551 | |||
552 | BUG_ON(c->setup == NULL); | ||
553 | |||
554 | /* DMA is not in use so this is all that is needed */ | ||
555 | /* Revisit for OMAP3! */ | ||
556 | ret = c->setup(c->onenand.base, c->freq); | ||
557 | |||
558 | return ret; | ||
559 | } | ||
560 | |||
561 | int omap2_onenand_rephase(void) | ||
562 | { | ||
563 | return driver_for_each_device(&omap2_onenand_driver.driver, NULL, | ||
564 | NULL, __adjust_timing); | ||
565 | } | ||
566 | |||
567 | static void __devexit omap2_onenand_shutdown(struct platform_device *pdev) | ||
568 | { | ||
569 | struct omap2_onenand *c = dev_get_drvdata(&pdev->dev); | ||
570 | |||
571 | /* With certain content in the buffer RAM, the OMAP boot ROM code | ||
572 | * can recognize the flash chip incorrectly. Zero it out before | ||
573 | * soft reset. | ||
574 | */ | ||
575 | memset((__force void *)c->onenand.base, 0, ONENAND_BUFRAM_SIZE); | ||
576 | } | ||
577 | |||
578 | static int __devinit omap2_onenand_probe(struct platform_device *pdev) | ||
579 | { | ||
580 | struct omap_onenand_platform_data *pdata; | ||
581 | struct omap2_onenand *c; | ||
582 | int r; | ||
583 | |||
584 | pdata = pdev->dev.platform_data; | ||
585 | if (pdata == NULL) { | ||
586 | dev_err(&pdev->dev, "platform data missing\n"); | ||
587 | return -ENODEV; | ||
588 | } | ||
589 | |||
590 | c = kzalloc(sizeof(struct omap2_onenand), GFP_KERNEL); | ||
591 | if (!c) | ||
592 | return -ENOMEM; | ||
593 | |||
594 | init_completion(&c->irq_done); | ||
595 | init_completion(&c->dma_done); | ||
596 | c->gpmc_cs = pdata->cs; | ||
597 | c->gpio_irq = pdata->gpio_irq; | ||
598 | c->dma_channel = pdata->dma_channel; | ||
599 | if (c->dma_channel < 0) { | ||
600 | /* if -1, don't use DMA */ | ||
601 | c->gpio_irq = 0; | ||
602 | } | ||
603 | |||
604 | r = gpmc_cs_request(c->gpmc_cs, ONENAND_IO_SIZE, &c->phys_base); | ||
605 | if (r < 0) { | ||
606 | dev_err(&pdev->dev, "Cannot request GPMC CS\n"); | ||
607 | goto err_kfree; | ||
608 | } | ||
609 | |||
610 | if (request_mem_region(c->phys_base, ONENAND_IO_SIZE, | ||
611 | pdev->dev.driver->name) == NULL) { | ||
612 | dev_err(&pdev->dev, "Cannot reserve memory region at 0x%08lx, " | ||
613 | "size: 0x%x\n", c->phys_base, ONENAND_IO_SIZE); | ||
614 | r = -EBUSY; | ||
615 | goto err_free_cs; | ||
616 | } | ||
617 | c->onenand.base = ioremap(c->phys_base, ONENAND_IO_SIZE); | ||
618 | if (c->onenand.base == NULL) { | ||
619 | r = -ENOMEM; | ||
620 | goto err_release_mem_region; | ||
621 | } | ||
622 | |||
623 | if (pdata->onenand_setup != NULL) { | ||
624 | r = pdata->onenand_setup(c->onenand.base, c->freq); | ||
625 | if (r < 0) { | ||
626 | dev_err(&pdev->dev, "Onenand platform setup failed: " | ||
627 | "%d\n", r); | ||
628 | goto err_iounmap; | ||
629 | } | ||
630 | c->setup = pdata->onenand_setup; | ||
631 | } | ||
632 | |||
633 | if (c->gpio_irq) { | ||
634 | if ((r = omap_request_gpio(c->gpio_irq)) < 0) { | ||
635 | dev_err(&pdev->dev, "Failed to request GPIO%d for " | ||
636 | "OneNAND\n", c->gpio_irq); | ||
637 | goto err_iounmap; | ||
638 | } | ||
639 | omap_set_gpio_direction(c->gpio_irq, 1); | ||
640 | |||
641 | if ((r = request_irq(OMAP_GPIO_IRQ(c->gpio_irq), | ||
642 | omap2_onenand_interrupt, IRQF_TRIGGER_RISING, | ||
643 | pdev->dev.driver->name, c)) < 0) | ||
644 | goto err_release_gpio; | ||
645 | } | ||
646 | |||
647 | if (c->dma_channel >= 0) { | ||
648 | r = omap_request_dma(0, pdev->dev.driver->name, | ||
649 | omap2_onenand_dma_cb, (void *) c, | ||
650 | &c->dma_channel); | ||
651 | if (r == 0) { | ||
652 | omap_set_dma_write_mode(c->dma_channel, | ||
653 | OMAP_DMA_WRITE_NON_POSTED); | ||
654 | omap_set_dma_src_data_pack(c->dma_channel, 1); | ||
655 | omap_set_dma_src_burst_mode(c->dma_channel, | ||
656 | OMAP_DMA_DATA_BURST_8); | ||
657 | omap_set_dma_dest_data_pack(c->dma_channel, 1); | ||
658 | omap_set_dma_dest_burst_mode(c->dma_channel, | ||
659 | OMAP_DMA_DATA_BURST_8); | ||
660 | } else { | ||
661 | dev_info(&pdev->dev, | ||
662 | "failed to allocate DMA for OneNAND, " | ||
663 | "using PIO instead\n"); | ||
664 | c->dma_channel = -1; | ||
665 | } | ||
666 | } | ||
667 | |||
668 | dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual " | ||
669 | "base %p\n", c->gpmc_cs, c->phys_base, | ||
670 | c->onenand.base); | ||
671 | |||
672 | c->pdev = pdev; | ||
673 | c->mtd.name = pdev->dev.bus_id; | ||
674 | c->mtd.priv = &c->onenand; | ||
675 | c->mtd.owner = THIS_MODULE; | ||
676 | |||
677 | if (c->dma_channel >= 0) { | ||
678 | struct onenand_chip *this = &c->onenand; | ||
679 | |||
680 | this->wait = omap2_onenand_wait; | ||
681 | if (cpu_is_omap34xx()) { | ||
682 | this->read_bufferram = omap3_onenand_read_bufferram; | ||
683 | this->write_bufferram = omap3_onenand_write_bufferram; | ||
684 | } else { | ||
685 | this->read_bufferram = omap2_onenand_read_bufferram; | ||
686 | this->write_bufferram = omap2_onenand_write_bufferram; | ||
687 | } | ||
688 | } | ||
689 | |||
690 | if ((r = onenand_scan(&c->mtd, 1)) < 0) | ||
691 | goto err_release_dma; | ||
692 | |||
693 | switch ((c->onenand.version_id >> 4) & 0xf) { | ||
694 | case 0: | ||
695 | c->freq = 40; | ||
696 | break; | ||
697 | case 1: | ||
698 | c->freq = 54; | ||
699 | break; | ||
700 | case 2: | ||
701 | c->freq = 66; | ||
702 | break; | ||
703 | case 3: | ||
704 | c->freq = 83; | ||
705 | break; | ||
706 | } | ||
707 | |||
708 | #ifdef CONFIG_MTD_PARTITIONS | ||
709 | if (pdata->parts != NULL) | ||
710 | r = add_mtd_partitions(&c->mtd, pdata->parts, | ||
711 | pdata->nr_parts); | ||
712 | else | ||
713 | #endif | ||
714 | r = add_mtd_device(&c->mtd); | ||
715 | if (r < 0) | ||
716 | goto err_release_onenand; | ||
717 | |||
718 | platform_set_drvdata(pdev, c); | ||
719 | |||
720 | return 0; | ||
721 | |||
722 | err_release_onenand: | ||
723 | onenand_release(&c->mtd); | ||
724 | err_release_dma: | ||
725 | if (c->dma_channel != -1) | ||
726 | omap_free_dma(c->dma_channel); | ||
727 | if (c->gpio_irq) | ||
728 | free_irq(OMAP_GPIO_IRQ(c->gpio_irq), c); | ||
729 | err_release_gpio: | ||
730 | if (c->gpio_irq) | ||
731 | omap_free_gpio(c->gpio_irq); | ||
732 | err_iounmap: | ||
733 | iounmap(c->onenand.base); | ||
734 | err_release_mem_region: | ||
735 | release_mem_region(c->phys_base, ONENAND_IO_SIZE); | ||
736 | err_free_cs: | ||
737 | gpmc_cs_free(c->gpmc_cs); | ||
738 | err_kfree: | ||
739 | kfree(c); | ||
740 | |||
741 | return r; | ||
742 | } | ||
743 | |||
744 | static int __devexit omap2_onenand_remove(struct platform_device *pdev) | ||
745 | { | ||
746 | struct omap2_onenand *c = dev_get_drvdata(&pdev->dev); | ||
747 | |||
748 | BUG_ON(c == NULL); | ||
749 | |||
750 | #ifdef CONFIG_MTD_PARTITIONS | ||
751 | if (c->parts) | ||
752 | del_mtd_partitions(&c->mtd); | ||
753 | else | ||
754 | del_mtd_device(&c->mtd); | ||
755 | #else | ||
756 | del_mtd_device(&c->mtd); | ||
757 | #endif | ||
758 | |||
759 | onenand_release(&c->mtd); | ||
760 | if (c->dma_channel != -1) | ||
761 | omap_free_dma(c->dma_channel); | ||
762 | omap2_onenand_shutdown(pdev); | ||
763 | platform_set_drvdata(pdev, NULL); | ||
764 | if (c->gpio_irq) { | ||
765 | free_irq(OMAP_GPIO_IRQ(c->gpio_irq), c); | ||
766 | omap_free_gpio(c->gpio_irq); | ||
767 | } | ||
768 | iounmap(c->onenand.base); | ||
769 | release_mem_region(c->phys_base, ONENAND_IO_SIZE); | ||
770 | kfree(c); | ||
771 | |||
772 | return 0; | ||
773 | } | ||
774 | |||
775 | static struct platform_driver omap2_onenand_driver = { | ||
776 | .probe = omap2_onenand_probe, | ||
777 | .remove = omap2_onenand_remove, | ||
778 | .shutdown = omap2_onenand_shutdown, | ||
779 | .driver = { | ||
780 | .name = DRIVER_NAME, | ||
781 | .owner = THIS_MODULE, | ||
782 | }, | ||
783 | }; | ||
784 | |||
785 | static int __init omap2_onenand_init(void) | ||
786 | { | ||
787 | printk(KERN_INFO "OneNAND driver initializing\n"); | ||
788 | return platform_driver_register(&omap2_onenand_driver); | ||
789 | } | ||
790 | |||
791 | static void __exit omap2_onenand_exit(void) | ||
792 | { | ||
793 | platform_driver_unregister(&omap2_onenand_driver); | ||
794 | } | ||
795 | |||
796 | module_init(omap2_onenand_init); | ||
797 | module_exit(omap2_onenand_exit); | ||
798 | |||
799 | MODULE_ALIAS(DRIVER_NAME); | ||
800 | MODULE_LICENSE("GPL"); | ||
801 | MODULE_AUTHOR("Jarkko Lavinen <jarkko.lavinen@nokia.com>"); | ||
802 | MODULE_DESCRIPTION("Glue layer for OneNAND flash on OMAP2 / OMAP3"); | ||
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 926cf3a4135d..90ed319f26e6 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c | |||
@@ -1794,7 +1794,7 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
1794 | return -EINVAL; | 1794 | return -EINVAL; |
1795 | } | 1795 | } |
1796 | 1796 | ||
1797 | instr->fail_addr = 0xffffffff; | 1797 | instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN; |
1798 | 1798 | ||
1799 | /* Grab the lock and see if the device is available */ | 1799 | /* Grab the lock and see if the device is available */ |
1800 | onenand_get_device(mtd, FL_ERASING); | 1800 | onenand_get_device(mtd, FL_ERASING); |
diff --git a/drivers/mtd/ssfdc.c b/drivers/mtd/ssfdc.c index a5f3d60047d4..33a5d6ed6f18 100644 --- a/drivers/mtd/ssfdc.c +++ b/drivers/mtd/ssfdc.c | |||
@@ -321,8 +321,7 @@ static void ssfdcr_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) | |||
321 | DEBUG(MTD_DEBUG_LEVEL1, | 321 | DEBUG(MTD_DEBUG_LEVEL1, |
322 | "SSFDC_RO: cis_block=%d,erase_size=%d,map_len=%d,n_zones=%d\n", | 322 | "SSFDC_RO: cis_block=%d,erase_size=%d,map_len=%d,n_zones=%d\n", |
323 | ssfdc->cis_block, ssfdc->erase_size, ssfdc->map_len, | 323 | ssfdc->cis_block, ssfdc->erase_size, ssfdc->map_len, |
324 | (ssfdc->map_len + MAX_PHYS_BLK_PER_ZONE - 1) / | 324 | DIV_ROUND_UP(ssfdc->map_len, MAX_PHYS_BLK_PER_ZONE)); |
325 | MAX_PHYS_BLK_PER_ZONE); | ||
326 | 325 | ||
327 | /* Set geometry */ | 326 | /* Set geometry */ |
328 | ssfdc->heads = 16; | 327 | ssfdc->heads = 16; |
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 03c759b4eeb5..b30a0b83d7f1 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c | |||
@@ -104,12 +104,9 @@ static int vol_cdev_open(struct inode *inode, struct file *file) | |||
104 | struct ubi_volume_desc *desc; | 104 | struct ubi_volume_desc *desc; |
105 | int vol_id = iminor(inode) - 1, mode, ubi_num; | 105 | int vol_id = iminor(inode) - 1, mode, ubi_num; |
106 | 106 | ||
107 | lock_kernel(); | ||
108 | ubi_num = ubi_major2num(imajor(inode)); | 107 | ubi_num = ubi_major2num(imajor(inode)); |
109 | if (ubi_num < 0) { | 108 | if (ubi_num < 0) |
110 | unlock_kernel(); | ||
111 | return ubi_num; | 109 | return ubi_num; |
112 | } | ||
113 | 110 | ||
114 | if (file->f_mode & FMODE_WRITE) | 111 | if (file->f_mode & FMODE_WRITE) |
115 | mode = UBI_READWRITE; | 112 | mode = UBI_READWRITE; |
@@ -119,7 +116,6 @@ static int vol_cdev_open(struct inode *inode, struct file *file) | |||
119 | dbg_gen("open volume %d, mode %d", vol_id, mode); | 116 | dbg_gen("open volume %d, mode %d", vol_id, mode); |
120 | 117 | ||
121 | desc = ubi_open_volume(ubi_num, vol_id, mode); | 118 | desc = ubi_open_volume(ubi_num, vol_id, mode); |
122 | unlock_kernel(); | ||
123 | if (IS_ERR(desc)) | 119 | if (IS_ERR(desc)) |
124 | return PTR_ERR(desc); | 120 | return PTR_ERR(desc); |
125 | 121 | ||
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index 967bb4406df9..4f2daa5bbecf 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c | |||
@@ -387,7 +387,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si, | |||
387 | pnum, vol_id, lnum, ec, sqnum, bitflips); | 387 | pnum, vol_id, lnum, ec, sqnum, bitflips); |
388 | 388 | ||
389 | sv = add_volume(si, vol_id, pnum, vid_hdr); | 389 | sv = add_volume(si, vol_id, pnum, vid_hdr); |
390 | if (IS_ERR(sv) < 0) | 390 | if (IS_ERR(sv)) |
391 | return PTR_ERR(sv); | 391 | return PTR_ERR(sv); |
392 | 392 | ||
393 | if (si->max_sqnum < sqnum) | 393 | if (si->max_sqnum < sqnum) |
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 217d0e111b2a..333c8941552f 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c | |||
@@ -244,8 +244,8 @@ static int vtbl_check(const struct ubi_device *ubi, | |||
244 | } | 244 | } |
245 | 245 | ||
246 | if (reserved_pebs > ubi->good_peb_count) { | 246 | if (reserved_pebs > ubi->good_peb_count) { |
247 | dbg_err("too large reserved_pebs, good PEBs %d", | 247 | dbg_err("too large reserved_pebs %d, good PEBs %d", |
248 | ubi->good_peb_count); | 248 | reserved_pebs, ubi->good_peb_count); |
249 | err = 9; | 249 | err = 9; |
250 | goto bad; | 250 | goto bad; |
251 | } | 251 | } |
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 491ee16da5c1..9ba295d9dd97 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c | |||
@@ -90,7 +90,7 @@ static int vortex_debug = 1; | |||
90 | #include <linux/eisa.h> | 90 | #include <linux/eisa.h> |
91 | #include <linux/bitops.h> | 91 | #include <linux/bitops.h> |
92 | #include <linux/jiffies.h> | 92 | #include <linux/jiffies.h> |
93 | #include <asm/irq.h> /* For NR_IRQS only. */ | 93 | #include <asm/irq.h> /* For nr_irqs only. */ |
94 | #include <asm/io.h> | 94 | #include <asm/io.h> |
95 | #include <asm/uaccess.h> | 95 | #include <asm/uaccess.h> |
96 | 96 | ||
@@ -1221,7 +1221,7 @@ static int __devinit vortex_probe1(struct device *gendev, | |||
1221 | if (print_info) | 1221 | if (print_info) |
1222 | printk(", IRQ %d\n", dev->irq); | 1222 | printk(", IRQ %d\n", dev->irq); |
1223 | /* Tell them about an invalid IRQ. */ | 1223 | /* Tell them about an invalid IRQ. */ |
1224 | if (dev->irq <= 0 || dev->irq >= NR_IRQS) | 1224 | if (dev->irq <= 0 || dev->irq >= nr_irqs) |
1225 | printk(KERN_WARNING " *** Warning: IRQ %d is unlikely to work! ***\n", | 1225 | printk(KERN_WARNING " *** Warning: IRQ %d is unlikely to work! ***\n", |
1226 | dev->irq); | 1226 | dev->irq); |
1227 | 1227 | ||
diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c index 17ac6975d70d..b6a816e60c0f 100644 --- a/drivers/net/hamradio/baycom_ser_fdx.c +++ b/drivers/net/hamradio/baycom_ser_fdx.c | |||
@@ -416,10 +416,10 @@ static int ser12_open(struct net_device *dev) | |||
416 | if (!dev || !bc) | 416 | if (!dev || !bc) |
417 | return -ENXIO; | 417 | return -ENXIO; |
418 | if (!dev->base_addr || dev->base_addr > 0xffff-SER12_EXTENT || | 418 | if (!dev->base_addr || dev->base_addr > 0xffff-SER12_EXTENT || |
419 | dev->irq < 2 || dev->irq > NR_IRQS) { | 419 | dev->irq < 2 || dev->irq > nr_irqs) { |
420 | printk(KERN_INFO "baycom_ser_fdx: invalid portnumber (max %u) " | 420 | printk(KERN_INFO "baycom_ser_fdx: invalid portnumber (max %u) " |
421 | "or irq (2 <= irq <= %d)\n", | 421 | "or irq (2 <= irq <= %d)\n", |
422 | 0xffff-SER12_EXTENT, NR_IRQS); | 422 | 0xffff-SER12_EXTENT, nr_irqs); |
423 | return -ENXIO; | 423 | return -ENXIO; |
424 | } | 424 | } |
425 | if (bc->baud < 300 || bc->baud > 4800) { | 425 | if (bc->baud < 300 || bc->baud > 4800) { |
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index 45ae9d1191d7..c17e39bc5460 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c | |||
@@ -1465,7 +1465,7 @@ static void z8530_init(void) | |||
1465 | printk(KERN_INFO "Init Z8530 driver: %u channels, IRQ", Nchips*2); | 1465 | printk(KERN_INFO "Init Z8530 driver: %u channels, IRQ", Nchips*2); |
1466 | 1466 | ||
1467 | flag=" "; | 1467 | flag=" "; |
1468 | for (k = 0; k < NR_IRQS; k++) | 1468 | for (k = 0; k < nr_irqs; k++) |
1469 | if (Ivec[k].used) | 1469 | if (Ivec[k].used) |
1470 | { | 1470 | { |
1471 | printk("%s%d", flag, k); | 1471 | printk("%s%d", flag, k); |
@@ -1728,7 +1728,7 @@ static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1728 | 1728 | ||
1729 | if (hwcfg.irq == 2) hwcfg.irq = 9; | 1729 | if (hwcfg.irq == 2) hwcfg.irq = 9; |
1730 | 1730 | ||
1731 | if (hwcfg.irq < 0 || hwcfg.irq >= NR_IRQS) | 1731 | if (hwcfg.irq < 0 || hwcfg.irq >= nr_irqs) |
1732 | return -EINVAL; | 1732 | return -EINVAL; |
1733 | 1733 | ||
1734 | if (!Ivec[hwcfg.irq].used && hwcfg.irq) | 1734 | if (!Ivec[hwcfg.irq].used && hwcfg.irq) |
@@ -2148,7 +2148,7 @@ static void __exit scc_cleanup_driver(void) | |||
2148 | } | 2148 | } |
2149 | 2149 | ||
2150 | /* To unload the port must be closed so no real IRQ pending */ | 2150 | /* To unload the port must be closed so no real IRQ pending */ |
2151 | for (k=0; k < NR_IRQS ; k++) | 2151 | for (k = 0; k < nr_irqs ; k++) |
2152 | if (Ivec[k].used) free_irq(k, NULL); | 2152 | if (Ivec[k].used) free_irq(k, NULL); |
2153 | 2153 | ||
2154 | local_irq_enable(); | 2154 | local_irq_enable(); |
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index b39d1cc1ef04..a24bb68887ab 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c | |||
@@ -1205,11 +1205,12 @@ static int sh_eth_drv_probe(struct platform_device *pdev) | |||
1205 | devno = 0; | 1205 | devno = 0; |
1206 | 1206 | ||
1207 | ndev->dma = -1; | 1207 | ndev->dma = -1; |
1208 | ndev->irq = platform_get_irq(pdev, 0); | 1208 | ret = platform_get_irq(pdev, 0); |
1209 | if (ndev->irq < 0) { | 1209 | if (ret < 0) { |
1210 | ret = -ENODEV; | 1210 | ret = -ENODEV; |
1211 | goto out_release; | 1211 | goto out_release; |
1212 | } | 1212 | } |
1213 | ndev->irq = ret; | ||
1213 | 1214 | ||
1214 | SET_NETDEV_DEV(ndev, &pdev->dev); | 1215 | SET_NETDEV_DEV(ndev, &pdev->dev); |
1215 | 1216 | ||
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index 38b90e7a7ed3..7914867110ed 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c | |||
@@ -168,7 +168,7 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size, | |||
168 | netif_device_detach(pegasus->net); | 168 | netif_device_detach(pegasus->net); |
169 | if (netif_msg_drv(pegasus) && printk_ratelimit()) | 169 | if (netif_msg_drv(pegasus) && printk_ratelimit()) |
170 | dev_err(&pegasus->intf->dev, "%s, status %d\n", | 170 | dev_err(&pegasus->intf->dev, "%s, status %d\n", |
171 | __FUNCTION__, ret); | 171 | __func__, ret); |
172 | goto out; | 172 | goto out; |
173 | } | 173 | } |
174 | 174 | ||
@@ -192,7 +192,7 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size, | |||
192 | if (!buffer) { | 192 | if (!buffer) { |
193 | if (netif_msg_drv(pegasus)) | 193 | if (netif_msg_drv(pegasus)) |
194 | dev_warn(&pegasus->intf->dev, "out of memory in %s\n", | 194 | dev_warn(&pegasus->intf->dev, "out of memory in %s\n", |
195 | __FUNCTION__); | 195 | __func__); |
196 | return -ENOMEM; | 196 | return -ENOMEM; |
197 | } | 197 | } |
198 | memcpy(buffer, data, size); | 198 | memcpy(buffer, data, size); |
diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c index f972fef87c98..ee51b6a5e605 100644 --- a/drivers/net/wan/sbni.c +++ b/drivers/net/wan/sbni.c | |||
@@ -318,7 +318,7 @@ sbni_pci_probe( struct net_device *dev ) | |||
318 | continue; | 318 | continue; |
319 | } | 319 | } |
320 | 320 | ||
321 | if( pci_irq_line <= 0 || pci_irq_line >= NR_IRQS ) | 321 | if (pci_irq_line <= 0 || pci_irq_line >= nr_irqs) |
322 | printk( KERN_WARNING " WARNING: The PCI BIOS assigned " | 322 | printk( KERN_WARNING " WARNING: The PCI BIOS assigned " |
323 | "this PCI card to IRQ %d, which is unlikely " | 323 | "this PCI card to IRQ %d, which is unlikely " |
324 | "to work!.\n" | 324 | "to work!.\n" |
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index b30e38f3a50d..dcc1e9958d2f 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c | |||
@@ -66,15 +66,8 @@ | |||
66 | #undef DEBUG_CCIO_RUN_SG | 66 | #undef DEBUG_CCIO_RUN_SG |
67 | 67 | ||
68 | #ifdef CONFIG_PROC_FS | 68 | #ifdef CONFIG_PROC_FS |
69 | /* | 69 | /* depends on proc fs support. But costs CPU performance. */ |
70 | * CCIO_SEARCH_TIME can help measure how fast the bitmap search is. | 70 | #undef CCIO_COLLECT_STATS |
71 | * impacts performance though - ditch it if you don't use it. | ||
72 | */ | ||
73 | #define CCIO_SEARCH_TIME | ||
74 | #undef CCIO_MAP_STATS | ||
75 | #else | ||
76 | #undef CCIO_SEARCH_TIME | ||
77 | #undef CCIO_MAP_STATS | ||
78 | #endif | 71 | #endif |
79 | 72 | ||
80 | #include <linux/proc_fs.h> | 73 | #include <linux/proc_fs.h> |
@@ -239,12 +232,10 @@ struct ioc { | |||
239 | u32 res_size; /* size of resource map in bytes */ | 232 | u32 res_size; /* size of resource map in bytes */ |
240 | spinlock_t res_lock; | 233 | spinlock_t res_lock; |
241 | 234 | ||
242 | #ifdef CCIO_SEARCH_TIME | 235 | #ifdef CCIO_COLLECT_STATS |
243 | #define CCIO_SEARCH_SAMPLE 0x100 | 236 | #define CCIO_SEARCH_SAMPLE 0x100 |
244 | unsigned long avg_search[CCIO_SEARCH_SAMPLE]; | 237 | unsigned long avg_search[CCIO_SEARCH_SAMPLE]; |
245 | unsigned long avg_idx; /* current index into avg_search */ | 238 | unsigned long avg_idx; /* current index into avg_search */ |
246 | #endif | ||
247 | #ifdef CCIO_MAP_STATS | ||
248 | unsigned long used_pages; | 239 | unsigned long used_pages; |
249 | unsigned long msingle_calls; | 240 | unsigned long msingle_calls; |
250 | unsigned long msingle_pages; | 241 | unsigned long msingle_pages; |
@@ -351,7 +342,7 @@ ccio_alloc_range(struct ioc *ioc, struct device *dev, size_t size) | |||
351 | unsigned int pages_needed = size >> IOVP_SHIFT; | 342 | unsigned int pages_needed = size >> IOVP_SHIFT; |
352 | unsigned int res_idx; | 343 | unsigned int res_idx; |
353 | unsigned long boundary_size; | 344 | unsigned long boundary_size; |
354 | #ifdef CCIO_SEARCH_TIME | 345 | #ifdef CCIO_COLLECT_STATS |
355 | unsigned long cr_start = mfctl(16); | 346 | unsigned long cr_start = mfctl(16); |
356 | #endif | 347 | #endif |
357 | 348 | ||
@@ -406,7 +397,7 @@ resource_found: | |||
406 | DBG_RES("%s() res_idx %d res_hint: %d\n", | 397 | DBG_RES("%s() res_idx %d res_hint: %d\n", |
407 | __func__, res_idx, ioc->res_hint); | 398 | __func__, res_idx, ioc->res_hint); |
408 | 399 | ||
409 | #ifdef CCIO_SEARCH_TIME | 400 | #ifdef CCIO_COLLECT_STATS |
410 | { | 401 | { |
411 | unsigned long cr_end = mfctl(16); | 402 | unsigned long cr_end = mfctl(16); |
412 | unsigned long tmp = cr_end - cr_start; | 403 | unsigned long tmp = cr_end - cr_start; |
@@ -416,7 +407,7 @@ resource_found: | |||
416 | ioc->avg_search[ioc->avg_idx++] = cr_start; | 407 | ioc->avg_search[ioc->avg_idx++] = cr_start; |
417 | ioc->avg_idx &= CCIO_SEARCH_SAMPLE - 1; | 408 | ioc->avg_idx &= CCIO_SEARCH_SAMPLE - 1; |
418 | #endif | 409 | #endif |
419 | #ifdef CCIO_MAP_STATS | 410 | #ifdef CCIO_COLLECT_STATS |
420 | ioc->used_pages += pages_needed; | 411 | ioc->used_pages += pages_needed; |
421 | #endif | 412 | #endif |
422 | /* | 413 | /* |
@@ -452,7 +443,7 @@ ccio_free_range(struct ioc *ioc, dma_addr_t iova, unsigned long pages_mapped) | |||
452 | DBG_RES("%s(): res_idx: %d pages_mapped %d\n", | 443 | DBG_RES("%s(): res_idx: %d pages_mapped %d\n", |
453 | __func__, res_idx, pages_mapped); | 444 | __func__, res_idx, pages_mapped); |
454 | 445 | ||
455 | #ifdef CCIO_MAP_STATS | 446 | #ifdef CCIO_COLLECT_STATS |
456 | ioc->used_pages -= pages_mapped; | 447 | ioc->used_pages -= pages_mapped; |
457 | #endif | 448 | #endif |
458 | 449 | ||
@@ -764,7 +755,7 @@ ccio_map_single(struct device *dev, void *addr, size_t size, | |||
764 | size = ALIGN(size + offset, IOVP_SIZE); | 755 | size = ALIGN(size + offset, IOVP_SIZE); |
765 | spin_lock_irqsave(&ioc->res_lock, flags); | 756 | spin_lock_irqsave(&ioc->res_lock, flags); |
766 | 757 | ||
767 | #ifdef CCIO_MAP_STATS | 758 | #ifdef CCIO_COLLECT_STATS |
768 | ioc->msingle_calls++; | 759 | ioc->msingle_calls++; |
769 | ioc->msingle_pages += size >> IOVP_SHIFT; | 760 | ioc->msingle_pages += size >> IOVP_SHIFT; |
770 | #endif | 761 | #endif |
@@ -828,7 +819,7 @@ ccio_unmap_single(struct device *dev, dma_addr_t iova, size_t size, | |||
828 | 819 | ||
829 | spin_lock_irqsave(&ioc->res_lock, flags); | 820 | spin_lock_irqsave(&ioc->res_lock, flags); |
830 | 821 | ||
831 | #ifdef CCIO_MAP_STATS | 822 | #ifdef CCIO_COLLECT_STATS |
832 | ioc->usingle_calls++; | 823 | ioc->usingle_calls++; |
833 | ioc->usingle_pages += size >> IOVP_SHIFT; | 824 | ioc->usingle_pages += size >> IOVP_SHIFT; |
834 | #endif | 825 | #endif |
@@ -894,7 +885,7 @@ ccio_free_consistent(struct device *dev, size_t size, void *cpu_addr, | |||
894 | */ | 885 | */ |
895 | #define PIDE_FLAG 0x80000000UL | 886 | #define PIDE_FLAG 0x80000000UL |
896 | 887 | ||
897 | #ifdef CCIO_MAP_STATS | 888 | #ifdef CCIO_COLLECT_STATS |
898 | #define IOMMU_MAP_STATS | 889 | #define IOMMU_MAP_STATS |
899 | #endif | 890 | #endif |
900 | #include "iommu-helpers.h" | 891 | #include "iommu-helpers.h" |
@@ -938,7 +929,7 @@ ccio_map_sg(struct device *dev, struct scatterlist *sglist, int nents, | |||
938 | 929 | ||
939 | spin_lock_irqsave(&ioc->res_lock, flags); | 930 | spin_lock_irqsave(&ioc->res_lock, flags); |
940 | 931 | ||
941 | #ifdef CCIO_MAP_STATS | 932 | #ifdef CCIO_COLLECT_STATS |
942 | ioc->msg_calls++; | 933 | ioc->msg_calls++; |
943 | #endif | 934 | #endif |
944 | 935 | ||
@@ -997,13 +988,13 @@ ccio_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents, | |||
997 | DBG_RUN_SG("%s() START %d entries, %08lx,%x\n", | 988 | DBG_RUN_SG("%s() START %d entries, %08lx,%x\n", |
998 | __func__, nents, sg_virt_addr(sglist), sglist->length); | 989 | __func__, nents, sg_virt_addr(sglist), sglist->length); |
999 | 990 | ||
1000 | #ifdef CCIO_MAP_STATS | 991 | #ifdef CCIO_COLLECT_STATS |
1001 | ioc->usg_calls++; | 992 | ioc->usg_calls++; |
1002 | #endif | 993 | #endif |
1003 | 994 | ||
1004 | while(sg_dma_len(sglist) && nents--) { | 995 | while(sg_dma_len(sglist) && nents--) { |
1005 | 996 | ||
1006 | #ifdef CCIO_MAP_STATS | 997 | #ifdef CCIO_COLLECT_STATS |
1007 | ioc->usg_pages += sg_dma_len(sglist) >> PAGE_SHIFT; | 998 | ioc->usg_pages += sg_dma_len(sglist) >> PAGE_SHIFT; |
1008 | #endif | 999 | #endif |
1009 | ccio_unmap_single(dev, sg_dma_address(sglist), | 1000 | ccio_unmap_single(dev, sg_dma_address(sglist), |
@@ -1048,7 +1039,7 @@ static int ccio_proc_info(struct seq_file *m, void *p) | |||
1048 | len += seq_printf(m, "IO PDIR size : %d bytes (%d entries)\n", | 1039 | len += seq_printf(m, "IO PDIR size : %d bytes (%d entries)\n", |
1049 | total_pages * 8, total_pages); | 1040 | total_pages * 8, total_pages); |
1050 | 1041 | ||
1051 | #ifdef CCIO_MAP_STATS | 1042 | #ifdef CCIO_COLLECT_STATS |
1052 | len += seq_printf(m, "IO PDIR entries : %ld free %ld used (%d%%)\n", | 1043 | len += seq_printf(m, "IO PDIR entries : %ld free %ld used (%d%%)\n", |
1053 | total_pages - ioc->used_pages, ioc->used_pages, | 1044 | total_pages - ioc->used_pages, ioc->used_pages, |
1054 | (int)(ioc->used_pages * 100 / total_pages)); | 1045 | (int)(ioc->used_pages * 100 / total_pages)); |
@@ -1057,7 +1048,7 @@ static int ccio_proc_info(struct seq_file *m, void *p) | |||
1057 | len += seq_printf(m, "Resource bitmap : %d bytes (%d pages)\n", | 1048 | len += seq_printf(m, "Resource bitmap : %d bytes (%d pages)\n", |
1058 | ioc->res_size, total_pages); | 1049 | ioc->res_size, total_pages); |
1059 | 1050 | ||
1060 | #ifdef CCIO_SEARCH_TIME | 1051 | #ifdef CCIO_COLLECT_STATS |
1061 | min = max = ioc->avg_search[0]; | 1052 | min = max = ioc->avg_search[0]; |
1062 | for(j = 0; j < CCIO_SEARCH_SAMPLE; ++j) { | 1053 | for(j = 0; j < CCIO_SEARCH_SAMPLE; ++j) { |
1063 | avg += ioc->avg_search[j]; | 1054 | avg += ioc->avg_search[j]; |
@@ -1070,7 +1061,7 @@ static int ccio_proc_info(struct seq_file *m, void *p) | |||
1070 | len += seq_printf(m, " Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", | 1061 | len += seq_printf(m, " Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n", |
1071 | min, avg, max); | 1062 | min, avg, max); |
1072 | #endif | 1063 | #endif |
1073 | #ifdef CCIO_MAP_STATS | 1064 | #ifdef CCIO_COLLECT_STATS |
1074 | len += seq_printf(m, "pci_map_single(): %8ld calls %8ld pages (avg %d/1000)\n", | 1065 | len += seq_printf(m, "pci_map_single(): %8ld calls %8ld pages (avg %d/1000)\n", |
1075 | ioc->msingle_calls, ioc->msingle_pages, | 1066 | ioc->msingle_calls, ioc->msingle_pages, |
1076 | (int)((ioc->msingle_pages * 1000)/ioc->msingle_calls)); | 1067 | (int)((ioc->msingle_pages * 1000)/ioc->msingle_calls)); |
@@ -1088,7 +1079,7 @@ static int ccio_proc_info(struct seq_file *m, void *p) | |||
1088 | len += seq_printf(m, "pci_unmap_sg() : %8ld calls %8ld pages (avg %d/1000)\n\n\n", | 1079 | len += seq_printf(m, "pci_unmap_sg() : %8ld calls %8ld pages (avg %d/1000)\n\n\n", |
1089 | ioc->usg_calls, ioc->usg_pages, | 1080 | ioc->usg_calls, ioc->usg_pages, |
1090 | (int)((ioc->usg_pages * 1000)/ioc->usg_calls)); | 1081 | (int)((ioc->usg_pages * 1000)/ioc->usg_calls)); |
1091 | #endif /* CCIO_MAP_STATS */ | 1082 | #endif /* CCIO_COLLECT_STATS */ |
1092 | 1083 | ||
1093 | ioc = ioc->next; | 1084 | ioc = ioc->next; |
1094 | } | 1085 | } |
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index fd56128525d1..3bc54b30c3a1 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c | |||
@@ -298,7 +298,8 @@ struct pci_port_ops dino_port_ops = { | |||
298 | 298 | ||
299 | static void dino_disable_irq(unsigned int irq) | 299 | static void dino_disable_irq(unsigned int irq) |
300 | { | 300 | { |
301 | struct dino_device *dino_dev = irq_desc[irq].chip_data; | 301 | struct irq_desc *desc = irq_to_desc(irq); |
302 | struct dino_device *dino_dev = desc->chip_data; | ||
302 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); | 303 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); |
303 | 304 | ||
304 | DBG(KERN_WARNING "%s(0x%p, %d)\n", __func__, dino_dev, irq); | 305 | DBG(KERN_WARNING "%s(0x%p, %d)\n", __func__, dino_dev, irq); |
@@ -310,7 +311,8 @@ static void dino_disable_irq(unsigned int irq) | |||
310 | 311 | ||
311 | static void dino_enable_irq(unsigned int irq) | 312 | static void dino_enable_irq(unsigned int irq) |
312 | { | 313 | { |
313 | struct dino_device *dino_dev = irq_desc[irq].chip_data; | 314 | struct irq_desc *desc = irq_to_desc(irq); |
315 | struct dino_device *dino_dev = desc->chip_data; | ||
314 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); | 316 | int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); |
315 | u32 tmp; | 317 | u32 tmp; |
316 | 318 | ||
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c index 771cef592542..7891db50c483 100644 --- a/drivers/parisc/eisa.c +++ b/drivers/parisc/eisa.c | |||
@@ -346,10 +346,10 @@ static int __init eisa_probe(struct parisc_device *dev) | |||
346 | } | 346 | } |
347 | 347 | ||
348 | /* Reserve IRQ2 */ | 348 | /* Reserve IRQ2 */ |
349 | irq_desc[2].action = &irq2_action; | 349 | irq_to_desc(2)->action = &irq2_action; |
350 | 350 | ||
351 | for (i = 0; i < 16; i++) { | 351 | for (i = 0; i < 16; i++) { |
352 | irq_desc[i].chip = &eisa_interrupt_type; | 352 | irq_to_desc(i)->chip = &eisa_interrupt_type; |
353 | } | 353 | } |
354 | 354 | ||
355 | EISA_bus = 1; | 355 | EISA_bus = 1; |
diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c index f7d088b897ee..e76db9e4d504 100644 --- a/drivers/parisc/gsc.c +++ b/drivers/parisc/gsc.c | |||
@@ -108,7 +108,8 @@ int gsc_find_local_irq(unsigned int irq, int *global_irqs, int limit) | |||
108 | 108 | ||
109 | static void gsc_asic_disable_irq(unsigned int irq) | 109 | static void gsc_asic_disable_irq(unsigned int irq) |
110 | { | 110 | { |
111 | struct gsc_asic *irq_dev = irq_desc[irq].chip_data; | 111 | struct irq_desc *desc = irq_to_desc(irq); |
112 | struct gsc_asic *irq_dev = desc->chip_data; | ||
112 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); | 113 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); |
113 | u32 imr; | 114 | u32 imr; |
114 | 115 | ||
@@ -123,7 +124,8 @@ static void gsc_asic_disable_irq(unsigned int irq) | |||
123 | 124 | ||
124 | static void gsc_asic_enable_irq(unsigned int irq) | 125 | static void gsc_asic_enable_irq(unsigned int irq) |
125 | { | 126 | { |
126 | struct gsc_asic *irq_dev = irq_desc[irq].chip_data; | 127 | struct irq_desc *desc = irq_to_desc(irq); |
128 | struct gsc_asic *irq_dev = desc->chip_data; | ||
127 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); | 129 | int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); |
128 | u32 imr; | 130 | u32 imr; |
129 | 131 | ||
@@ -159,12 +161,14 @@ static struct hw_interrupt_type gsc_asic_interrupt_type = { | |||
159 | int gsc_assign_irq(struct hw_interrupt_type *type, void *data) | 161 | int gsc_assign_irq(struct hw_interrupt_type *type, void *data) |
160 | { | 162 | { |
161 | static int irq = GSC_IRQ_BASE; | 163 | static int irq = GSC_IRQ_BASE; |
164 | struct irq_desc *desc; | ||
162 | 165 | ||
163 | if (irq > GSC_IRQ_MAX) | 166 | if (irq > GSC_IRQ_MAX) |
164 | return NO_IRQ; | 167 | return NO_IRQ; |
165 | 168 | ||
166 | irq_desc[irq].chip = type; | 169 | desc = irq_to_desc(irq); |
167 | irq_desc[irq].chip_data = data; | 170 | desc->chip = type; |
171 | desc->chip_data = data; | ||
168 | return irq++; | 172 | return irq++; |
169 | } | 173 | } |
170 | 174 | ||
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 6fb3f7979f21..7beffcab2745 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c | |||
@@ -619,7 +619,9 @@ iosapic_set_irt_data( struct vector_info *vi, u32 *dp0, u32 *dp1) | |||
619 | 619 | ||
620 | static struct vector_info *iosapic_get_vector(unsigned int irq) | 620 | static struct vector_info *iosapic_get_vector(unsigned int irq) |
621 | { | 621 | { |
622 | return irq_desc[irq].chip_data; | 622 | struct irq_desc *desc = irq_to_desc(irq); |
623 | |||
624 | return desc->chip_data; | ||
623 | } | 625 | } |
624 | 626 | ||
625 | static void iosapic_disable_irq(unsigned int irq) | 627 | static void iosapic_disable_irq(unsigned int irq) |
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index 1e8d2d17f04c..1e93c837514f 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c | |||
@@ -363,7 +363,9 @@ int superio_fixup_irq(struct pci_dev *pcidev) | |||
363 | #endif | 363 | #endif |
364 | 364 | ||
365 | for (i = 0; i < 16; i++) { | 365 | for (i = 0; i < 16; i++) { |
366 | irq_desc[i].chip = &superio_interrupt_type; | 366 | struct irq_desc *desc = irq_to_desc(i); |
367 | |||
368 | desc->chip = &superio_interrupt_type; | ||
367 | } | 369 | } |
368 | 370 | ||
369 | /* | 371 | /* |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 529d9d7727b0..999cc4088b59 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -151,6 +151,13 @@ void pci_bus_add_devices(struct pci_bus *bus) | |||
151 | if (retval) | 151 | if (retval) |
152 | dev_err(&dev->dev, "Error creating cpuaffinity" | 152 | dev_err(&dev->dev, "Error creating cpuaffinity" |
153 | " file, continuing...\n"); | 153 | " file, continuing...\n"); |
154 | |||
155 | retval = device_create_file(&child_bus->dev, | ||
156 | &dev_attr_cpulistaffinity); | ||
157 | if (retval) | ||
158 | dev_err(&dev->dev, | ||
159 | "Error creating cpulistaffinity" | ||
160 | " file, continuing...\n"); | ||
154 | } | 161 | } |
155 | } | 162 | } |
156 | } | 163 | } |
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index e842e756308a..8b29c307f1a1 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c | |||
@@ -193,7 +193,7 @@ dmar_parse_dev(struct dmar_drhd_unit *dmaru) | |||
193 | { | 193 | { |
194 | struct acpi_dmar_hardware_unit *drhd; | 194 | struct acpi_dmar_hardware_unit *drhd; |
195 | static int include_all; | 195 | static int include_all; |
196 | int ret; | 196 | int ret = 0; |
197 | 197 | ||
198 | drhd = (struct acpi_dmar_hardware_unit *) dmaru->hdr; | 198 | drhd = (struct acpi_dmar_hardware_unit *) dmaru->hdr; |
199 | 199 | ||
@@ -212,7 +212,7 @@ dmar_parse_dev(struct dmar_drhd_unit *dmaru) | |||
212 | include_all = 1; | 212 | include_all = 1; |
213 | } | 213 | } |
214 | 214 | ||
215 | if (ret || (dmaru->devices_cnt == 0 && !dmaru->include_all)) { | 215 | if (ret) { |
216 | list_del(&dmaru->list); | 216 | list_del(&dmaru->list); |
217 | kfree(dmaru); | 217 | kfree(dmaru); |
218 | } | 218 | } |
@@ -289,6 +289,24 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header) | |||
289 | } | 289 | } |
290 | } | 290 | } |
291 | 291 | ||
292 | /** | ||
293 | * dmar_table_detect - checks to see if the platform supports DMAR devices | ||
294 | */ | ||
295 | static int __init dmar_table_detect(void) | ||
296 | { | ||
297 | acpi_status status = AE_OK; | ||
298 | |||
299 | /* if we could find DMAR table, then there are DMAR devices */ | ||
300 | status = acpi_get_table(ACPI_SIG_DMAR, 0, | ||
301 | (struct acpi_table_header **)&dmar_tbl); | ||
302 | |||
303 | if (ACPI_SUCCESS(status) && !dmar_tbl) { | ||
304 | printk (KERN_WARNING PREFIX "Unable to map DMAR\n"); | ||
305 | status = AE_NOT_FOUND; | ||
306 | } | ||
307 | |||
308 | return (ACPI_SUCCESS(status) ? 1 : 0); | ||
309 | } | ||
292 | 310 | ||
293 | /** | 311 | /** |
294 | * parse_dmar_table - parses the DMA reporting table | 312 | * parse_dmar_table - parses the DMA reporting table |
@@ -300,6 +318,12 @@ parse_dmar_table(void) | |||
300 | struct acpi_dmar_header *entry_header; | 318 | struct acpi_dmar_header *entry_header; |
301 | int ret = 0; | 319 | int ret = 0; |
302 | 320 | ||
321 | /* | ||
322 | * Do it again, earlier dmar_tbl mapping could be mapped with | ||
323 | * fixed map. | ||
324 | */ | ||
325 | dmar_table_detect(); | ||
326 | |||
303 | dmar = (struct acpi_table_dmar *)dmar_tbl; | 327 | dmar = (struct acpi_table_dmar *)dmar_tbl; |
304 | if (!dmar) | 328 | if (!dmar) |
305 | return -ENODEV; | 329 | return -ENODEV; |
@@ -373,10 +397,10 @@ dmar_find_matched_drhd_unit(struct pci_dev *dev) | |||
373 | 397 | ||
374 | int __init dmar_dev_scope_init(void) | 398 | int __init dmar_dev_scope_init(void) |
375 | { | 399 | { |
376 | struct dmar_drhd_unit *drhd; | 400 | struct dmar_drhd_unit *drhd, *drhd_n; |
377 | int ret = -ENODEV; | 401 | int ret = -ENODEV; |
378 | 402 | ||
379 | for_each_drhd_unit(drhd) { | 403 | list_for_each_entry_safe(drhd, drhd_n, &dmar_drhd_units, list) { |
380 | ret = dmar_parse_dev(drhd); | 404 | ret = dmar_parse_dev(drhd); |
381 | if (ret) | 405 | if (ret) |
382 | return ret; | 406 | return ret; |
@@ -384,8 +408,8 @@ int __init dmar_dev_scope_init(void) | |||
384 | 408 | ||
385 | #ifdef CONFIG_DMAR | 409 | #ifdef CONFIG_DMAR |
386 | { | 410 | { |
387 | struct dmar_rmrr_unit *rmrr; | 411 | struct dmar_rmrr_unit *rmrr, *rmrr_n; |
388 | for_each_rmrr_units(rmrr) { | 412 | list_for_each_entry_safe(rmrr, rmrr_n, &dmar_rmrr_units, list) { |
389 | ret = rmrr_parse_dev(rmrr); | 413 | ret = rmrr_parse_dev(rmrr); |
390 | if (ret) | 414 | if (ret) |
391 | return ret; | 415 | return ret; |
@@ -430,30 +454,11 @@ int __init dmar_table_init(void) | |||
430 | return 0; | 454 | return 0; |
431 | } | 455 | } |
432 | 456 | ||
433 | /** | ||
434 | * early_dmar_detect - checks to see if the platform supports DMAR devices | ||
435 | */ | ||
436 | int __init early_dmar_detect(void) | ||
437 | { | ||
438 | acpi_status status = AE_OK; | ||
439 | |||
440 | /* if we could find DMAR table, then there are DMAR devices */ | ||
441 | status = acpi_get_table(ACPI_SIG_DMAR, 0, | ||
442 | (struct acpi_table_header **)&dmar_tbl); | ||
443 | |||
444 | if (ACPI_SUCCESS(status) && !dmar_tbl) { | ||
445 | printk (KERN_WARNING PREFIX "Unable to map DMAR\n"); | ||
446 | status = AE_NOT_FOUND; | ||
447 | } | ||
448 | |||
449 | return (ACPI_SUCCESS(status) ? 1 : 0); | ||
450 | } | ||
451 | |||
452 | void __init detect_intel_iommu(void) | 457 | void __init detect_intel_iommu(void) |
453 | { | 458 | { |
454 | int ret; | 459 | int ret; |
455 | 460 | ||
456 | ret = early_dmar_detect(); | 461 | ret = dmar_table_detect(); |
457 | 462 | ||
458 | #ifdef CONFIG_DMAR | 463 | #ifdef CONFIG_DMAR |
459 | { | 464 | { |
@@ -479,14 +484,16 @@ void __init detect_intel_iommu(void) | |||
479 | " x2apic support\n"); | 484 | " x2apic support\n"); |
480 | 485 | ||
481 | dmar_disabled = 1; | 486 | dmar_disabled = 1; |
482 | return; | 487 | goto end; |
483 | } | 488 | } |
484 | 489 | ||
485 | if (ret && !no_iommu && !iommu_detected && !swiotlb && | 490 | if (ret && !no_iommu && !iommu_detected && !swiotlb && |
486 | !dmar_disabled) | 491 | !dmar_disabled) |
487 | iommu_detected = 1; | 492 | iommu_detected = 1; |
488 | } | 493 | } |
494 | end: | ||
489 | #endif | 495 | #endif |
496 | dmar_tbl = NULL; | ||
490 | } | 497 | } |
491 | 498 | ||
492 | 499 | ||
diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c index 7d27631e6e62..8cfd1c4926c8 100644 --- a/drivers/pci/hotplug/ibmphp_ebda.c +++ b/drivers/pci/hotplug/ibmphp_ebda.c | |||
@@ -123,10 +123,8 @@ static struct ebda_pci_rsrc *alloc_ebda_pci_rsrc (void) | |||
123 | static void __init print_bus_info (void) | 123 | static void __init print_bus_info (void) |
124 | { | 124 | { |
125 | struct bus_info *ptr; | 125 | struct bus_info *ptr; |
126 | struct list_head *ptr1; | ||
127 | 126 | ||
128 | list_for_each (ptr1, &bus_info_head) { | 127 | list_for_each_entry(ptr, &bus_info_head, bus_info_list) { |
129 | ptr = list_entry (ptr1, struct bus_info, bus_info_list); | ||
130 | debug ("%s - slot_min = %x\n", __func__, ptr->slot_min); | 128 | debug ("%s - slot_min = %x\n", __func__, ptr->slot_min); |
131 | debug ("%s - slot_max = %x\n", __func__, ptr->slot_max); | 129 | debug ("%s - slot_max = %x\n", __func__, ptr->slot_max); |
132 | debug ("%s - slot_count = %x\n", __func__, ptr->slot_count); | 130 | debug ("%s - slot_count = %x\n", __func__, ptr->slot_count); |
@@ -146,10 +144,8 @@ static void __init print_bus_info (void) | |||
146 | static void print_lo_info (void) | 144 | static void print_lo_info (void) |
147 | { | 145 | { |
148 | struct rio_detail *ptr; | 146 | struct rio_detail *ptr; |
149 | struct list_head *ptr1; | ||
150 | debug ("print_lo_info ----\n"); | 147 | debug ("print_lo_info ----\n"); |
151 | list_for_each (ptr1, &rio_lo_head) { | 148 | list_for_each_entry(ptr, &rio_lo_head, rio_detail_list) { |
152 | ptr = list_entry (ptr1, struct rio_detail, rio_detail_list); | ||
153 | debug ("%s - rio_node_id = %x\n", __func__, ptr->rio_node_id); | 149 | debug ("%s - rio_node_id = %x\n", __func__, ptr->rio_node_id); |
154 | debug ("%s - rio_type = %x\n", __func__, ptr->rio_type); | 150 | debug ("%s - rio_type = %x\n", __func__, ptr->rio_type); |
155 | debug ("%s - owner_id = %x\n", __func__, ptr->owner_id); | 151 | debug ("%s - owner_id = %x\n", __func__, ptr->owner_id); |
@@ -163,10 +159,8 @@ static void print_lo_info (void) | |||
163 | static void print_vg_info (void) | 159 | static void print_vg_info (void) |
164 | { | 160 | { |
165 | struct rio_detail *ptr; | 161 | struct rio_detail *ptr; |
166 | struct list_head *ptr1; | ||
167 | debug ("%s ---\n", __func__); | 162 | debug ("%s ---\n", __func__); |
168 | list_for_each (ptr1, &rio_vg_head) { | 163 | list_for_each_entry(ptr, &rio_vg_head, rio_detail_list) { |
169 | ptr = list_entry (ptr1, struct rio_detail, rio_detail_list); | ||
170 | debug ("%s - rio_node_id = %x\n", __func__, ptr->rio_node_id); | 164 | debug ("%s - rio_node_id = %x\n", __func__, ptr->rio_node_id); |
171 | debug ("%s - rio_type = %x\n", __func__, ptr->rio_type); | 165 | debug ("%s - rio_type = %x\n", __func__, ptr->rio_type); |
172 | debug ("%s - owner_id = %x\n", __func__, ptr->owner_id); | 166 | debug ("%s - owner_id = %x\n", __func__, ptr->owner_id); |
@@ -180,10 +174,8 @@ static void print_vg_info (void) | |||
180 | static void __init print_ebda_pci_rsrc (void) | 174 | static void __init print_ebda_pci_rsrc (void) |
181 | { | 175 | { |
182 | struct ebda_pci_rsrc *ptr; | 176 | struct ebda_pci_rsrc *ptr; |
183 | struct list_head *ptr1; | ||
184 | 177 | ||
185 | list_for_each (ptr1, &ibmphp_ebda_pci_rsrc_head) { | 178 | list_for_each_entry(ptr, &ibmphp_ebda_pci_rsrc_head, ebda_pci_rsrc_list) { |
186 | ptr = list_entry (ptr1, struct ebda_pci_rsrc, ebda_pci_rsrc_list); | ||
187 | debug ("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n", | 179 | debug ("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n", |
188 | __func__, ptr->rsrc_type ,ptr->bus_num, ptr->dev_fun,ptr->start_addr, ptr->end_addr); | 180 | __func__, ptr->rsrc_type ,ptr->bus_num, ptr->dev_fun,ptr->start_addr, ptr->end_addr); |
189 | } | 181 | } |
@@ -192,10 +184,8 @@ static void __init print_ebda_pci_rsrc (void) | |||
192 | static void __init print_ibm_slot (void) | 184 | static void __init print_ibm_slot (void) |
193 | { | 185 | { |
194 | struct slot *ptr; | 186 | struct slot *ptr; |
195 | struct list_head *ptr1; | ||
196 | 187 | ||
197 | list_for_each (ptr1, &ibmphp_slot_head) { | 188 | list_for_each_entry(ptr, &ibmphp_slot_head, ibm_slot_list) { |
198 | ptr = list_entry (ptr1, struct slot, ibm_slot_list); | ||
199 | debug ("%s - slot_number: %x\n", __func__, ptr->number); | 189 | debug ("%s - slot_number: %x\n", __func__, ptr->number); |
200 | } | 190 | } |
201 | } | 191 | } |
@@ -203,10 +193,8 @@ static void __init print_ibm_slot (void) | |||
203 | static void __init print_opt_vg (void) | 193 | static void __init print_opt_vg (void) |
204 | { | 194 | { |
205 | struct opt_rio *ptr; | 195 | struct opt_rio *ptr; |
206 | struct list_head *ptr1; | ||
207 | debug ("%s ---\n", __func__); | 196 | debug ("%s ---\n", __func__); |
208 | list_for_each (ptr1, &opt_vg_head) { | 197 | list_for_each_entry(ptr, &opt_vg_head, opt_rio_list) { |
209 | ptr = list_entry (ptr1, struct opt_rio, opt_rio_list); | ||
210 | debug ("%s - rio_type %x\n", __func__, ptr->rio_type); | 198 | debug ("%s - rio_type %x\n", __func__, ptr->rio_type); |
211 | debug ("%s - chassis_num: %x\n", __func__, ptr->chassis_num); | 199 | debug ("%s - chassis_num: %x\n", __func__, ptr->chassis_num); |
212 | debug ("%s - first_slot_num: %x\n", __func__, ptr->first_slot_num); | 200 | debug ("%s - first_slot_num: %x\n", __func__, ptr->first_slot_num); |
@@ -217,13 +205,9 @@ static void __init print_opt_vg (void) | |||
217 | static void __init print_ebda_hpc (void) | 205 | static void __init print_ebda_hpc (void) |
218 | { | 206 | { |
219 | struct controller *hpc_ptr; | 207 | struct controller *hpc_ptr; |
220 | struct list_head *ptr1; | ||
221 | u16 index; | 208 | u16 index; |
222 | 209 | ||
223 | list_for_each (ptr1, &ebda_hpc_head) { | 210 | list_for_each_entry(hpc_ptr, &ebda_hpc_head, ebda_hpc_list) { |
224 | |||
225 | hpc_ptr = list_entry (ptr1, struct controller, ebda_hpc_list); | ||
226 | |||
227 | for (index = 0; index < hpc_ptr->slot_count; index++) { | 211 | for (index = 0; index < hpc_ptr->slot_count; index++) { |
228 | debug ("%s - physical slot#: %x\n", __func__, hpc_ptr->slots[index].slot_num); | 212 | debug ("%s - physical slot#: %x\n", __func__, hpc_ptr->slots[index].slot_num); |
229 | debug ("%s - pci bus# of the slot: %x\n", __func__, hpc_ptr->slots[index].slot_bus_num); | 213 | debug ("%s - pci bus# of the slot: %x\n", __func__, hpc_ptr->slots[index].slot_bus_num); |
@@ -460,9 +444,7 @@ static int __init ebda_rio_table (void) | |||
460 | static struct opt_rio *search_opt_vg (u8 chassis_num) | 444 | static struct opt_rio *search_opt_vg (u8 chassis_num) |
461 | { | 445 | { |
462 | struct opt_rio *ptr; | 446 | struct opt_rio *ptr; |
463 | struct list_head *ptr1; | 447 | list_for_each_entry(ptr, &opt_vg_head, opt_rio_list) { |
464 | list_for_each (ptr1, &opt_vg_head) { | ||
465 | ptr = list_entry (ptr1, struct opt_rio, opt_rio_list); | ||
466 | if (ptr->chassis_num == chassis_num) | 448 | if (ptr->chassis_num == chassis_num) |
467 | return ptr; | 449 | return ptr; |
468 | } | 450 | } |
@@ -473,10 +455,8 @@ static int __init combine_wpg_for_chassis (void) | |||
473 | { | 455 | { |
474 | struct opt_rio *opt_rio_ptr = NULL; | 456 | struct opt_rio *opt_rio_ptr = NULL; |
475 | struct rio_detail *rio_detail_ptr = NULL; | 457 | struct rio_detail *rio_detail_ptr = NULL; |
476 | struct list_head *list_head_ptr = NULL; | ||
477 | 458 | ||
478 | list_for_each (list_head_ptr, &rio_vg_head) { | 459 | list_for_each_entry(rio_detail_ptr, &rio_vg_head, rio_detail_list) { |
479 | rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list); | ||
480 | opt_rio_ptr = search_opt_vg (rio_detail_ptr->chassis_num); | 460 | opt_rio_ptr = search_opt_vg (rio_detail_ptr->chassis_num); |
481 | if (!opt_rio_ptr) { | 461 | if (!opt_rio_ptr) { |
482 | opt_rio_ptr = kzalloc(sizeof(struct opt_rio), GFP_KERNEL); | 462 | opt_rio_ptr = kzalloc(sizeof(struct opt_rio), GFP_KERNEL); |
@@ -497,14 +477,12 @@ static int __init combine_wpg_for_chassis (void) | |||
497 | } | 477 | } |
498 | 478 | ||
499 | /* | 479 | /* |
500 | * reorgnizing linked list of expansion box | 480 | * reorganizing linked list of expansion box |
501 | */ | 481 | */ |
502 | static struct opt_rio_lo *search_opt_lo (u8 chassis_num) | 482 | static struct opt_rio_lo *search_opt_lo (u8 chassis_num) |
503 | { | 483 | { |
504 | struct opt_rio_lo *ptr; | 484 | struct opt_rio_lo *ptr; |
505 | struct list_head *ptr1; | 485 | list_for_each_entry(ptr, &opt_lo_head, opt_rio_lo_list) { |
506 | list_for_each (ptr1, &opt_lo_head) { | ||
507 | ptr = list_entry (ptr1, struct opt_rio_lo, opt_rio_lo_list); | ||
508 | if (ptr->chassis_num == chassis_num) | 486 | if (ptr->chassis_num == chassis_num) |
509 | return ptr; | 487 | return ptr; |
510 | } | 488 | } |
@@ -515,10 +493,8 @@ static int combine_wpg_for_expansion (void) | |||
515 | { | 493 | { |
516 | struct opt_rio_lo *opt_rio_lo_ptr = NULL; | 494 | struct opt_rio_lo *opt_rio_lo_ptr = NULL; |
517 | struct rio_detail *rio_detail_ptr = NULL; | 495 | struct rio_detail *rio_detail_ptr = NULL; |
518 | struct list_head *list_head_ptr = NULL; | ||
519 | 496 | ||
520 | list_for_each (list_head_ptr, &rio_lo_head) { | 497 | list_for_each_entry(rio_detail_ptr, &rio_lo_head, rio_detail_list) { |
521 | rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list); | ||
522 | opt_rio_lo_ptr = search_opt_lo (rio_detail_ptr->chassis_num); | 498 | opt_rio_lo_ptr = search_opt_lo (rio_detail_ptr->chassis_num); |
523 | if (!opt_rio_lo_ptr) { | 499 | if (!opt_rio_lo_ptr) { |
524 | opt_rio_lo_ptr = kzalloc(sizeof(struct opt_rio_lo), GFP_KERNEL); | 500 | opt_rio_lo_ptr = kzalloc(sizeof(struct opt_rio_lo), GFP_KERNEL); |
@@ -550,20 +526,17 @@ static int first_slot_num (u8 slot_num, u8 first_slot, u8 var) | |||
550 | { | 526 | { |
551 | struct opt_rio *opt_vg_ptr = NULL; | 527 | struct opt_rio *opt_vg_ptr = NULL; |
552 | struct opt_rio_lo *opt_lo_ptr = NULL; | 528 | struct opt_rio_lo *opt_lo_ptr = NULL; |
553 | struct list_head *ptr = NULL; | ||
554 | int rc = 0; | 529 | int rc = 0; |
555 | 530 | ||
556 | if (!var) { | 531 | if (!var) { |
557 | list_for_each (ptr, &opt_vg_head) { | 532 | list_for_each_entry(opt_vg_ptr, &opt_vg_head, opt_rio_list) { |
558 | opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list); | ||
559 | if ((first_slot < opt_vg_ptr->first_slot_num) && (slot_num >= opt_vg_ptr->first_slot_num)) { | 533 | if ((first_slot < opt_vg_ptr->first_slot_num) && (slot_num >= opt_vg_ptr->first_slot_num)) { |
560 | rc = -ENODEV; | 534 | rc = -ENODEV; |
561 | break; | 535 | break; |
562 | } | 536 | } |
563 | } | 537 | } |
564 | } else { | 538 | } else { |
565 | list_for_each (ptr, &opt_lo_head) { | 539 | list_for_each_entry(opt_lo_ptr, &opt_lo_head, opt_rio_lo_list) { |
566 | opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list); | ||
567 | if ((first_slot < opt_lo_ptr->first_slot_num) && (slot_num >= opt_lo_ptr->first_slot_num)) { | 540 | if ((first_slot < opt_lo_ptr->first_slot_num) && (slot_num >= opt_lo_ptr->first_slot_num)) { |
568 | rc = -ENODEV; | 541 | rc = -ENODEV; |
569 | break; | 542 | break; |
@@ -576,10 +549,8 @@ static int first_slot_num (u8 slot_num, u8 first_slot, u8 var) | |||
576 | static struct opt_rio_lo * find_rxe_num (u8 slot_num) | 549 | static struct opt_rio_lo * find_rxe_num (u8 slot_num) |
577 | { | 550 | { |
578 | struct opt_rio_lo *opt_lo_ptr; | 551 | struct opt_rio_lo *opt_lo_ptr; |
579 | struct list_head *ptr; | ||
580 | 552 | ||
581 | list_for_each (ptr, &opt_lo_head) { | 553 | list_for_each_entry(opt_lo_ptr, &opt_lo_head, opt_rio_lo_list) { |
582 | opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list); | ||
583 | //check to see if this slot_num belongs to expansion box | 554 | //check to see if this slot_num belongs to expansion box |
584 | if ((slot_num >= opt_lo_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_lo_ptr->first_slot_num, 1))) | 555 | if ((slot_num >= opt_lo_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_lo_ptr->first_slot_num, 1))) |
585 | return opt_lo_ptr; | 556 | return opt_lo_ptr; |
@@ -590,10 +561,8 @@ static struct opt_rio_lo * find_rxe_num (u8 slot_num) | |||
590 | static struct opt_rio * find_chassis_num (u8 slot_num) | 561 | static struct opt_rio * find_chassis_num (u8 slot_num) |
591 | { | 562 | { |
592 | struct opt_rio *opt_vg_ptr; | 563 | struct opt_rio *opt_vg_ptr; |
593 | struct list_head *ptr; | ||
594 | 564 | ||
595 | list_for_each (ptr, &opt_vg_head) { | 565 | list_for_each_entry(opt_vg_ptr, &opt_vg_head, opt_rio_list) { |
596 | opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list); | ||
597 | //check to see if this slot_num belongs to chassis | 566 | //check to see if this slot_num belongs to chassis |
598 | if ((slot_num >= opt_vg_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_vg_ptr->first_slot_num, 0))) | 567 | if ((slot_num >= opt_vg_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_vg_ptr->first_slot_num, 0))) |
599 | return opt_vg_ptr; | 568 | return opt_vg_ptr; |
@@ -607,11 +576,9 @@ static struct opt_rio * find_chassis_num (u8 slot_num) | |||
607 | static u8 calculate_first_slot (u8 slot_num) | 576 | static u8 calculate_first_slot (u8 slot_num) |
608 | { | 577 | { |
609 | u8 first_slot = 1; | 578 | u8 first_slot = 1; |
610 | struct list_head * list; | ||
611 | struct slot * slot_cur; | 579 | struct slot * slot_cur; |
612 | 580 | ||
613 | list_for_each (list, &ibmphp_slot_head) { | 581 | list_for_each_entry(slot_cur, &ibmphp_slot_head, ibm_slot_list) { |
614 | slot_cur = list_entry (list, struct slot, ibm_slot_list); | ||
615 | if (slot_cur->ctrl) { | 582 | if (slot_cur->ctrl) { |
616 | if ((slot_cur->ctrl->ctlr_type != 4) && (slot_cur->ctrl->ending_slot_num > first_slot) && (slot_num > slot_cur->ctrl->ending_slot_num)) | 583 | if ((slot_cur->ctrl->ctlr_type != 4) && (slot_cur->ctrl->ending_slot_num > first_slot) && (slot_num > slot_cur->ctrl->ending_slot_num)) |
617 | first_slot = slot_cur->ctrl->ending_slot_num; | 584 | first_slot = slot_cur->ctrl->ending_slot_num; |
@@ -767,7 +734,6 @@ static int __init ebda_rsrc_controller (void) | |||
767 | struct bus_info *bus_info_ptr1, *bus_info_ptr2; | 734 | struct bus_info *bus_info_ptr1, *bus_info_ptr2; |
768 | int rc; | 735 | int rc; |
769 | struct slot *tmp_slot; | 736 | struct slot *tmp_slot; |
770 | struct list_head *list; | ||
771 | 737 | ||
772 | addr = hpc_list_ptr->phys_addr; | 738 | addr = hpc_list_ptr->phys_addr; |
773 | for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) { | 739 | for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) { |
@@ -997,9 +963,7 @@ static int __init ebda_rsrc_controller (void) | |||
997 | 963 | ||
998 | } /* each hpc */ | 964 | } /* each hpc */ |
999 | 965 | ||
1000 | list_for_each (list, &ibmphp_slot_head) { | 966 | list_for_each_entry(tmp_slot, &ibmphp_slot_head, ibm_slot_list) { |
1001 | tmp_slot = list_entry (list, struct slot, ibm_slot_list); | ||
1002 | |||
1003 | snprintf (tmp_slot->hotplug_slot->name, 30, "%s", create_file_name (tmp_slot)); | 967 | snprintf (tmp_slot->hotplug_slot->name, 30, "%s", create_file_name (tmp_slot)); |
1004 | pci_hp_register(tmp_slot->hotplug_slot, | 968 | pci_hp_register(tmp_slot->hotplug_slot, |
1005 | pci_find_bus(0, tmp_slot->bus), tmp_slot->device); | 969 | pci_find_bus(0, tmp_slot->bus), tmp_slot->device); |
@@ -1101,10 +1065,8 @@ u16 ibmphp_get_total_controllers (void) | |||
1101 | struct slot *ibmphp_get_slot_from_physical_num (u8 physical_num) | 1065 | struct slot *ibmphp_get_slot_from_physical_num (u8 physical_num) |
1102 | { | 1066 | { |
1103 | struct slot *slot; | 1067 | struct slot *slot; |
1104 | struct list_head *list; | ||
1105 | 1068 | ||
1106 | list_for_each (list, &ibmphp_slot_head) { | 1069 | list_for_each_entry(slot, &ibmphp_slot_head, ibm_slot_list) { |
1107 | slot = list_entry (list, struct slot, ibm_slot_list); | ||
1108 | if (slot->number == physical_num) | 1070 | if (slot->number == physical_num) |
1109 | return slot; | 1071 | return slot; |
1110 | } | 1072 | } |
@@ -1120,10 +1082,8 @@ struct slot *ibmphp_get_slot_from_physical_num (u8 physical_num) | |||
1120 | struct bus_info *ibmphp_find_same_bus_num (u32 num) | 1082 | struct bus_info *ibmphp_find_same_bus_num (u32 num) |
1121 | { | 1083 | { |
1122 | struct bus_info *ptr; | 1084 | struct bus_info *ptr; |
1123 | struct list_head *ptr1; | ||
1124 | 1085 | ||
1125 | list_for_each (ptr1, &bus_info_head) { | 1086 | list_for_each_entry(ptr, &bus_info_head, bus_info_list) { |
1126 | ptr = list_entry (ptr1, struct bus_info, bus_info_list); | ||
1127 | if (ptr->busno == num) | 1087 | if (ptr->busno == num) |
1128 | return ptr; | 1088 | return ptr; |
1129 | } | 1089 | } |
@@ -1136,10 +1096,8 @@ struct bus_info *ibmphp_find_same_bus_num (u32 num) | |||
1136 | int ibmphp_get_bus_index (u8 num) | 1096 | int ibmphp_get_bus_index (u8 num) |
1137 | { | 1097 | { |
1138 | struct bus_info *ptr; | 1098 | struct bus_info *ptr; |
1139 | struct list_head *ptr1; | ||
1140 | 1099 | ||
1141 | list_for_each (ptr1, &bus_info_head) { | 1100 | list_for_each_entry(ptr, &bus_info_head, bus_info_list) { |
1142 | ptr = list_entry (ptr1, struct bus_info, bus_info_list); | ||
1143 | if (ptr->busno == num) | 1101 | if (ptr->busno == num) |
1144 | return ptr->index; | 1102 | return ptr->index; |
1145 | } | 1103 | } |
@@ -1212,11 +1170,9 @@ static struct pci_driver ibmphp_driver = { | |||
1212 | int ibmphp_register_pci (void) | 1170 | int ibmphp_register_pci (void) |
1213 | { | 1171 | { |
1214 | struct controller *ctrl; | 1172 | struct controller *ctrl; |
1215 | struct list_head *tmp; | ||
1216 | int rc = 0; | 1173 | int rc = 0; |
1217 | 1174 | ||
1218 | list_for_each (tmp, &ebda_hpc_head) { | 1175 | list_for_each_entry(ctrl, &ebda_hpc_head, ebda_hpc_list) { |
1219 | ctrl = list_entry (tmp, struct controller, ebda_hpc_list); | ||
1220 | if (ctrl->ctlr_type == 1) { | 1176 | if (ctrl->ctlr_type == 1) { |
1221 | rc = pci_register_driver(&ibmphp_driver); | 1177 | rc = pci_register_driver(&ibmphp_driver); |
1222 | break; | 1178 | break; |
@@ -1227,12 +1183,10 @@ int ibmphp_register_pci (void) | |||
1227 | static int ibmphp_probe (struct pci_dev * dev, const struct pci_device_id *ids) | 1183 | static int ibmphp_probe (struct pci_dev * dev, const struct pci_device_id *ids) |
1228 | { | 1184 | { |
1229 | struct controller *ctrl; | 1185 | struct controller *ctrl; |
1230 | struct list_head *tmp; | ||
1231 | 1186 | ||
1232 | debug ("inside ibmphp_probe\n"); | 1187 | debug ("inside ibmphp_probe\n"); |
1233 | 1188 | ||
1234 | list_for_each (tmp, &ebda_hpc_head) { | 1189 | list_for_each_entry(ctrl, &ebda_hpc_head, ebda_hpc_list) { |
1235 | ctrl = list_entry (tmp, struct controller, ebda_hpc_list); | ||
1236 | if (ctrl->ctlr_type == 1) { | 1190 | if (ctrl->ctlr_type == 1) { |
1237 | if ((dev->devfn == ctrl->u.pci_ctlr.dev_fun) && (dev->bus->number == ctrl->u.pci_ctlr.bus)) { | 1191 | if ((dev->devfn == ctrl->u.pci_ctlr.dev_fun) && (dev->bus->number == ctrl->u.pci_ctlr.bus)) { |
1238 | ctrl->ctrl_dev = dev; | 1192 | ctrl->ctrl_dev = dev; |
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 5f85b1b120e3..2e6c4474644e 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c | |||
@@ -102,13 +102,13 @@ static int get_##name (struct hotplug_slot *slot, type *value) \ | |||
102 | { \ | 102 | { \ |
103 | struct hotplug_slot_ops *ops = slot->ops; \ | 103 | struct hotplug_slot_ops *ops = slot->ops; \ |
104 | int retval = 0; \ | 104 | int retval = 0; \ |
105 | if (try_module_get(ops->owner)) { \ | 105 | if (!try_module_get(ops->owner)) \ |
106 | if (ops->get_##name) \ | 106 | return -ENODEV; \ |
107 | retval = ops->get_##name(slot, value); \ | 107 | if (ops->get_##name) \ |
108 | else \ | 108 | retval = ops->get_##name(slot, value); \ |
109 | *value = slot->info->name; \ | 109 | else \ |
110 | module_put(ops->owner); \ | 110 | *value = slot->info->name; \ |
111 | } \ | 111 | module_put(ops->owner); \ |
112 | return retval; \ | 112 | return retval; \ |
113 | } | 113 | } |
114 | 114 | ||
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 9e6cec67e1cc..c367978bd7fe 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -57,6 +57,19 @@ extern struct workqueue_struct *pciehp_wq; | |||
57 | #define warn(format, arg...) \ | 57 | #define warn(format, arg...) \ |
58 | printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) | 58 | printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) |
59 | 59 | ||
60 | #define ctrl_dbg(ctrl, format, arg...) \ | ||
61 | do { \ | ||
62 | if (pciehp_debug) \ | ||
63 | dev_printk(, &ctrl->pcie->device, \ | ||
64 | format, ## arg); \ | ||
65 | } while (0) | ||
66 | #define ctrl_err(ctrl, format, arg...) \ | ||
67 | dev_err(&ctrl->pcie->device, format, ## arg) | ||
68 | #define ctrl_info(ctrl, format, arg...) \ | ||
69 | dev_info(&ctrl->pcie->device, format, ## arg) | ||
70 | #define ctrl_warn(ctrl, format, arg...) \ | ||
71 | dev_warn(&ctrl->pcie->device, format, ## arg) | ||
72 | |||
60 | #define SLOT_NAME_SIZE 10 | 73 | #define SLOT_NAME_SIZE 10 |
61 | struct slot { | 74 | struct slot { |
62 | u8 bus; | 75 | u8 bus; |
@@ -87,6 +100,7 @@ struct controller { | |||
87 | int num_slots; /* Number of slots on ctlr */ | 100 | int num_slots; /* Number of slots on ctlr */ |
88 | int slot_num_inc; /* 1 or -1 */ | 101 | int slot_num_inc; /* 1 or -1 */ |
89 | struct pci_dev *pci_dev; | 102 | struct pci_dev *pci_dev; |
103 | struct pcie_device *pcie; /* PCI Express port service */ | ||
90 | struct list_head slot_list; | 104 | struct list_head slot_list; |
91 | struct hpc_ops *hpc_ops; | 105 | struct hpc_ops *hpc_ops; |
92 | wait_queue_head_t queue; /* sleep & wake process */ | 106 | wait_queue_head_t queue; /* sleep & wake process */ |
@@ -170,7 +184,7 @@ static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device) | |||
170 | return slot; | 184 | return slot; |
171 | } | 185 | } |
172 | 186 | ||
173 | err("%s: slot (device=0x%x) not found\n", __func__, device); | 187 | ctrl_err(ctrl, "%s: slot (device=0x%x) not found\n", __func__, device); |
174 | return NULL; | 188 | return NULL; |
175 | } | 189 | } |
176 | 190 | ||
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 4fd5355bc3b5..c748a19db89d 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -144,9 +144,10 @@ set_lock_exit: | |||
144 | * sysfs interface which allows the user to toggle the Electro Mechanical | 144 | * sysfs interface which allows the user to toggle the Electro Mechanical |
145 | * Interlock. Valid values are either 0 or 1. 0 == unlock, 1 == lock | 145 | * Interlock. Valid values are either 0 or 1. 0 == unlock, 1 == lock |
146 | */ | 146 | */ |
147 | static ssize_t lock_write_file(struct hotplug_slot *slot, const char *buf, | 147 | static ssize_t lock_write_file(struct hotplug_slot *hotplug_slot, |
148 | size_t count) | 148 | const char *buf, size_t count) |
149 | { | 149 | { |
150 | struct slot *slot = hotplug_slot->private; | ||
150 | unsigned long llock; | 151 | unsigned long llock; |
151 | u8 lock; | 152 | u8 lock; |
152 | int retval = 0; | 153 | int retval = 0; |
@@ -157,10 +158,11 @@ static ssize_t lock_write_file(struct hotplug_slot *slot, const char *buf, | |||
157 | switch (lock) { | 158 | switch (lock) { |
158 | case 0: | 159 | case 0: |
159 | case 1: | 160 | case 1: |
160 | retval = set_lock_status(slot, lock); | 161 | retval = set_lock_status(hotplug_slot, lock); |
161 | break; | 162 | break; |
162 | default: | 163 | default: |
163 | err ("%d is an invalid lock value\n", lock); | 164 | ctrl_err(slot->ctrl, "%d is an invalid lock value\n", |
165 | lock); | ||
164 | retval = -EINVAL; | 166 | retval = -EINVAL; |
165 | } | 167 | } |
166 | if (retval) | 168 | if (retval) |
@@ -180,7 +182,10 @@ static struct hotplug_slot_attribute hotplug_slot_attr_lock = { | |||
180 | */ | 182 | */ |
181 | static void release_slot(struct hotplug_slot *hotplug_slot) | 183 | static void release_slot(struct hotplug_slot *hotplug_slot) |
182 | { | 184 | { |
183 | dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name); | 185 | struct slot *slot = hotplug_slot->private; |
186 | |||
187 | ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n", | ||
188 | __func__, hotplug_slot->name); | ||
184 | 189 | ||
185 | kfree(hotplug_slot->info); | 190 | kfree(hotplug_slot->info); |
186 | kfree(hotplug_slot); | 191 | kfree(hotplug_slot); |
@@ -215,9 +220,9 @@ static int init_slots(struct controller *ctrl) | |||
215 | get_adapter_status(hotplug_slot, &info->adapter_status); | 220 | get_adapter_status(hotplug_slot, &info->adapter_status); |
216 | slot->hotplug_slot = hotplug_slot; | 221 | slot->hotplug_slot = hotplug_slot; |
217 | 222 | ||
218 | dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x " | 223 | ctrl_dbg(ctrl, "Registering bus=%x dev=%x hp_slot=%x sun=%x " |
219 | "slot_device_offset=%x\n", slot->bus, slot->device, | 224 | "slot_device_offset=%x\n", slot->bus, slot->device, |
220 | slot->hp_slot, slot->number, ctrl->slot_device_offset); | 225 | slot->hp_slot, slot->number, ctrl->slot_device_offset); |
221 | duplicate_name: | 226 | duplicate_name: |
222 | retval = pci_hp_register(hotplug_slot, | 227 | retval = pci_hp_register(hotplug_slot, |
223 | ctrl->pci_dev->subordinate, | 228 | ctrl->pci_dev->subordinate, |
@@ -233,9 +238,11 @@ duplicate_name: | |||
233 | if (len < SLOT_NAME_SIZE) | 238 | if (len < SLOT_NAME_SIZE) |
234 | goto duplicate_name; | 239 | goto duplicate_name; |
235 | else | 240 | else |
236 | err("duplicate slot name overflow\n"); | 241 | ctrl_err(ctrl, "duplicate slot name " |
242 | "overflow\n"); | ||
237 | } | 243 | } |
238 | err("pci_hp_register failed with error %d\n", retval); | 244 | ctrl_err(ctrl, "pci_hp_register failed with error %d\n", |
245 | retval); | ||
239 | goto error_info; | 246 | goto error_info; |
240 | } | 247 | } |
241 | /* create additional sysfs entries */ | 248 | /* create additional sysfs entries */ |
@@ -244,7 +251,8 @@ duplicate_name: | |||
244 | &hotplug_slot_attr_lock.attr); | 251 | &hotplug_slot_attr_lock.attr); |
245 | if (retval) { | 252 | if (retval) { |
246 | pci_hp_deregister(hotplug_slot); | 253 | pci_hp_deregister(hotplug_slot); |
247 | err("cannot create additional sysfs entries\n"); | 254 | ctrl_err(ctrl, "cannot create additional sysfs " |
255 | "entries\n"); | ||
248 | goto error_info; | 256 | goto error_info; |
249 | } | 257 | } |
250 | } | 258 | } |
@@ -278,7 +286,8 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) | |||
278 | { | 286 | { |
279 | struct slot *slot = hotplug_slot->private; | 287 | struct slot *slot = hotplug_slot->private; |
280 | 288 | ||
281 | dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name); | 289 | ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n", |
290 | __func__, hotplug_slot->name); | ||
282 | 291 | ||
283 | hotplug_slot->info->attention_status = status; | 292 | hotplug_slot->info->attention_status = status; |
284 | 293 | ||
@@ -293,7 +302,8 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) | |||
293 | { | 302 | { |
294 | struct slot *slot = hotplug_slot->private; | 303 | struct slot *slot = hotplug_slot->private; |
295 | 304 | ||
296 | dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name); | 305 | ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n", |
306 | __func__, hotplug_slot->name); | ||
297 | 307 | ||
298 | return pciehp_sysfs_enable_slot(slot); | 308 | return pciehp_sysfs_enable_slot(slot); |
299 | } | 309 | } |
@@ -303,7 +313,8 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) | |||
303 | { | 313 | { |
304 | struct slot *slot = hotplug_slot->private; | 314 | struct slot *slot = hotplug_slot->private; |
305 | 315 | ||
306 | dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name); | 316 | ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n", |
317 | __func__, hotplug_slot->name); | ||
307 | 318 | ||
308 | return pciehp_sysfs_disable_slot(slot); | 319 | return pciehp_sysfs_disable_slot(slot); |
309 | } | 320 | } |
@@ -313,7 +324,8 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) | |||
313 | struct slot *slot = hotplug_slot->private; | 324 | struct slot *slot = hotplug_slot->private; |
314 | int retval; | 325 | int retval; |
315 | 326 | ||
316 | dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name); | 327 | ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n", |
328 | __func__, hotplug_slot->name); | ||
317 | 329 | ||
318 | retval = slot->hpc_ops->get_power_status(slot, value); | 330 | retval = slot->hpc_ops->get_power_status(slot, value); |
319 | if (retval < 0) | 331 | if (retval < 0) |
@@ -327,7 +339,8 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) | |||
327 | struct slot *slot = hotplug_slot->private; | 339 | struct slot *slot = hotplug_slot->private; |
328 | int retval; | 340 | int retval; |
329 | 341 | ||
330 | dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name); | 342 | ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n", |
343 | __func__, hotplug_slot->name); | ||
331 | 344 | ||
332 | retval = slot->hpc_ops->get_attention_status(slot, value); | 345 | retval = slot->hpc_ops->get_attention_status(slot, value); |
333 | if (retval < 0) | 346 | if (retval < 0) |
@@ -341,7 +354,8 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) | |||
341 | struct slot *slot = hotplug_slot->private; | 354 | struct slot *slot = hotplug_slot->private; |
342 | int retval; | 355 | int retval; |
343 | 356 | ||
344 | dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name); | 357 | ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n", |
358 | __func__, hotplug_slot->name); | ||
345 | 359 | ||
346 | retval = slot->hpc_ops->get_latch_status(slot, value); | 360 | retval = slot->hpc_ops->get_latch_status(slot, value); |
347 | if (retval < 0) | 361 | if (retval < 0) |
@@ -355,7 +369,8 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) | |||
355 | struct slot *slot = hotplug_slot->private; | 369 | struct slot *slot = hotplug_slot->private; |
356 | int retval; | 370 | int retval; |
357 | 371 | ||
358 | dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name); | 372 | ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n", |
373 | __func__, hotplug_slot->name); | ||
359 | 374 | ||
360 | retval = slot->hpc_ops->get_adapter_status(slot, value); | 375 | retval = slot->hpc_ops->get_adapter_status(slot, value); |
361 | if (retval < 0) | 376 | if (retval < 0) |
@@ -370,7 +385,8 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, | |||
370 | struct slot *slot = hotplug_slot->private; | 385 | struct slot *slot = hotplug_slot->private; |
371 | int retval; | 386 | int retval; |
372 | 387 | ||
373 | dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name); | 388 | ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n", |
389 | __func__, hotplug_slot->name); | ||
374 | 390 | ||
375 | retval = slot->hpc_ops->get_max_bus_speed(slot, value); | 391 | retval = slot->hpc_ops->get_max_bus_speed(slot, value); |
376 | if (retval < 0) | 392 | if (retval < 0) |
@@ -384,7 +400,8 @@ static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe | |||
384 | struct slot *slot = hotplug_slot->private; | 400 | struct slot *slot = hotplug_slot->private; |
385 | int retval; | 401 | int retval; |
386 | 402 | ||
387 | dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name); | 403 | ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n", |
404 | __func__, hotplug_slot->name); | ||
388 | 405 | ||
389 | retval = slot->hpc_ops->get_cur_bus_speed(slot, value); | 406 | retval = slot->hpc_ops->get_cur_bus_speed(slot, value); |
390 | if (retval < 0) | 407 | if (retval < 0) |
@@ -402,14 +419,15 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ | |||
402 | struct pci_dev *pdev = dev->port; | 419 | struct pci_dev *pdev = dev->port; |
403 | 420 | ||
404 | if (pciehp_force) | 421 | if (pciehp_force) |
405 | dbg("Bypassing BIOS check for pciehp use on %s\n", | 422 | dev_info(&dev->device, |
406 | pci_name(pdev)); | 423 | "Bypassing BIOS check for pciehp use on %s\n", |
424 | pci_name(pdev)); | ||
407 | else if (pciehp_get_hp_hw_control_from_firmware(pdev)) | 425 | else if (pciehp_get_hp_hw_control_from_firmware(pdev)) |
408 | goto err_out_none; | 426 | goto err_out_none; |
409 | 427 | ||
410 | ctrl = pcie_init(dev); | 428 | ctrl = pcie_init(dev); |
411 | if (!ctrl) { | 429 | if (!ctrl) { |
412 | dbg("%s: controller initialization failed\n", PCIE_MODULE_NAME); | 430 | dev_err(&dev->device, "controller initialization failed\n"); |
413 | goto err_out_none; | 431 | goto err_out_none; |
414 | } | 432 | } |
415 | set_service_data(dev, ctrl); | 433 | set_service_data(dev, ctrl); |
@@ -418,11 +436,10 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ | |||
418 | rc = init_slots(ctrl); | 436 | rc = init_slots(ctrl); |
419 | if (rc) { | 437 | if (rc) { |
420 | if (rc == -EBUSY) | 438 | if (rc == -EBUSY) |
421 | warn("%s: slot already registered by another " | 439 | ctrl_warn(ctrl, "slot already registered by another " |
422 | "hotplug driver\n", PCIE_MODULE_NAME); | 440 | "hotplug driver\n"); |
423 | else | 441 | else |
424 | err("%s: slot initialization failed\n", | 442 | ctrl_err(ctrl, "slot initialization failed\n"); |
425 | PCIE_MODULE_NAME); | ||
426 | goto err_out_release_ctlr; | 443 | goto err_out_release_ctlr; |
427 | } | 444 | } |
428 | 445 | ||
@@ -461,13 +478,13 @@ static void pciehp_remove (struct pcie_device *dev) | |||
461 | #ifdef CONFIG_PM | 478 | #ifdef CONFIG_PM |
462 | static int pciehp_suspend (struct pcie_device *dev, pm_message_t state) | 479 | static int pciehp_suspend (struct pcie_device *dev, pm_message_t state) |
463 | { | 480 | { |
464 | printk("%s ENTRY\n", __func__); | 481 | dev_info(&dev->device, "%s ENTRY\n", __func__); |
465 | return 0; | 482 | return 0; |
466 | } | 483 | } |
467 | 484 | ||
468 | static int pciehp_resume (struct pcie_device *dev) | 485 | static int pciehp_resume (struct pcie_device *dev) |
469 | { | 486 | { |
470 | printk("%s ENTRY\n", __func__); | 487 | dev_info(&dev->device, "%s ENTRY\n", __func__); |
471 | if (pciehp_force) { | 488 | if (pciehp_force) { |
472 | struct controller *ctrl = get_service_data(dev); | 489 | struct controller *ctrl = get_service_data(dev); |
473 | struct slot *t_slot; | 490 | struct slot *t_slot; |
@@ -497,10 +514,9 @@ static struct pcie_port_service_id port_pci_ids[] = { { | |||
497 | .driver_data = 0, | 514 | .driver_data = 0, |
498 | }, { /* end: all zeroes */ } | 515 | }, { /* end: all zeroes */ } |
499 | }; | 516 | }; |
500 | static const char device_name[] = "hpdriver"; | ||
501 | 517 | ||
502 | static struct pcie_port_service_driver hpdriver_portdrv = { | 518 | static struct pcie_port_service_driver hpdriver_portdrv = { |
503 | .name = (char *)device_name, | 519 | .name = PCIE_MODULE_NAME, |
504 | .id_table = &port_pci_ids[0], | 520 | .id_table = &port_pci_ids[0], |
505 | 521 | ||
506 | .probe = pciehp_probe, | 522 | .probe = pciehp_probe, |
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 96a5d55a4983..acb7f9efd182 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -58,14 +58,15 @@ static int queue_interrupt_event(struct slot *p_slot, u32 event_type) | |||
58 | u8 pciehp_handle_attention_button(struct slot *p_slot) | 58 | u8 pciehp_handle_attention_button(struct slot *p_slot) |
59 | { | 59 | { |
60 | u32 event_type; | 60 | u32 event_type; |
61 | struct controller *ctrl = p_slot->ctrl; | ||
61 | 62 | ||
62 | /* Attention Button Change */ | 63 | /* Attention Button Change */ |
63 | dbg("pciehp: Attention button interrupt received.\n"); | 64 | ctrl_dbg(ctrl, "Attention button interrupt received.\n"); |
64 | 65 | ||
65 | /* | 66 | /* |
66 | * Button pressed - See if need to TAKE ACTION!!! | 67 | * Button pressed - See if need to TAKE ACTION!!! |
67 | */ | 68 | */ |
68 | info("Button pressed on Slot(%s)\n", p_slot->name); | 69 | ctrl_info(ctrl, "Button pressed on Slot(%s)\n", p_slot->name); |
69 | event_type = INT_BUTTON_PRESS; | 70 | event_type = INT_BUTTON_PRESS; |
70 | 71 | ||
71 | queue_interrupt_event(p_slot, event_type); | 72 | queue_interrupt_event(p_slot, event_type); |
@@ -77,22 +78,23 @@ u8 pciehp_handle_switch_change(struct slot *p_slot) | |||
77 | { | 78 | { |
78 | u8 getstatus; | 79 | u8 getstatus; |
79 | u32 event_type; | 80 | u32 event_type; |
81 | struct controller *ctrl = p_slot->ctrl; | ||
80 | 82 | ||
81 | /* Switch Change */ | 83 | /* Switch Change */ |
82 | dbg("pciehp: Switch interrupt received.\n"); | 84 | ctrl_dbg(ctrl, "Switch interrupt received.\n"); |
83 | 85 | ||
84 | p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); | 86 | p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); |
85 | if (getstatus) { | 87 | if (getstatus) { |
86 | /* | 88 | /* |
87 | * Switch opened | 89 | * Switch opened |
88 | */ | 90 | */ |
89 | info("Latch open on Slot(%s)\n", p_slot->name); | 91 | ctrl_info(ctrl, "Latch open on Slot(%s)\n", p_slot->name); |
90 | event_type = INT_SWITCH_OPEN; | 92 | event_type = INT_SWITCH_OPEN; |
91 | } else { | 93 | } else { |
92 | /* | 94 | /* |
93 | * Switch closed | 95 | * Switch closed |
94 | */ | 96 | */ |
95 | info("Latch close on Slot(%s)\n", p_slot->name); | 97 | ctrl_info(ctrl, "Latch close on Slot(%s)\n", p_slot->name); |
96 | event_type = INT_SWITCH_CLOSE; | 98 | event_type = INT_SWITCH_CLOSE; |
97 | } | 99 | } |
98 | 100 | ||
@@ -105,9 +107,10 @@ u8 pciehp_handle_presence_change(struct slot *p_slot) | |||
105 | { | 107 | { |
106 | u32 event_type; | 108 | u32 event_type; |
107 | u8 presence_save; | 109 | u8 presence_save; |
110 | struct controller *ctrl = p_slot->ctrl; | ||
108 | 111 | ||
109 | /* Presence Change */ | 112 | /* Presence Change */ |
110 | dbg("pciehp: Presence/Notify input change.\n"); | 113 | ctrl_dbg(ctrl, "Presence/Notify input change.\n"); |
111 | 114 | ||
112 | /* Switch is open, assume a presence change | 115 | /* Switch is open, assume a presence change |
113 | * Save the presence state | 116 | * Save the presence state |
@@ -117,13 +120,13 @@ u8 pciehp_handle_presence_change(struct slot *p_slot) | |||
117 | /* | 120 | /* |
118 | * Card Present | 121 | * Card Present |
119 | */ | 122 | */ |
120 | info("Card present on Slot(%s)\n", p_slot->name); | 123 | ctrl_info(ctrl, "Card present on Slot(%s)\n", p_slot->name); |
121 | event_type = INT_PRESENCE_ON; | 124 | event_type = INT_PRESENCE_ON; |
122 | } else { | 125 | } else { |
123 | /* | 126 | /* |
124 | * Not Present | 127 | * Not Present |
125 | */ | 128 | */ |
126 | info("Card not present on Slot(%s)\n", p_slot->name); | 129 | ctrl_info(ctrl, "Card not present on Slot(%s)\n", p_slot->name); |
127 | event_type = INT_PRESENCE_OFF; | 130 | event_type = INT_PRESENCE_OFF; |
128 | } | 131 | } |
129 | 132 | ||
@@ -135,23 +138,25 @@ u8 pciehp_handle_presence_change(struct slot *p_slot) | |||
135 | u8 pciehp_handle_power_fault(struct slot *p_slot) | 138 | u8 pciehp_handle_power_fault(struct slot *p_slot) |
136 | { | 139 | { |
137 | u32 event_type; | 140 | u32 event_type; |
141 | struct controller *ctrl = p_slot->ctrl; | ||
138 | 142 | ||
139 | /* power fault */ | 143 | /* power fault */ |
140 | dbg("pciehp: Power fault interrupt received.\n"); | 144 | ctrl_dbg(ctrl, "Power fault interrupt received.\n"); |
141 | 145 | ||
142 | if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) { | 146 | if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) { |
143 | /* | 147 | /* |
144 | * power fault Cleared | 148 | * power fault Cleared |
145 | */ | 149 | */ |
146 | info("Power fault cleared on Slot(%s)\n", p_slot->name); | 150 | ctrl_info(ctrl, "Power fault cleared on Slot(%s)\n", |
151 | p_slot->name); | ||
147 | event_type = INT_POWER_FAULT_CLEAR; | 152 | event_type = INT_POWER_FAULT_CLEAR; |
148 | } else { | 153 | } else { |
149 | /* | 154 | /* |
150 | * power fault | 155 | * power fault |
151 | */ | 156 | */ |
152 | info("Power fault on Slot(%s)\n", p_slot->name); | 157 | ctrl_info(ctrl, "Power fault on Slot(%s)\n", p_slot->name); |
153 | event_type = INT_POWER_FAULT; | 158 | event_type = INT_POWER_FAULT; |
154 | info("power fault bit %x set\n", 0); | 159 | ctrl_info(ctrl, "power fault bit %x set\n", 0); |
155 | } | 160 | } |
156 | 161 | ||
157 | queue_interrupt_event(p_slot, event_type); | 162 | queue_interrupt_event(p_slot, event_type); |
@@ -168,8 +173,9 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot) | |||
168 | /* turn off slot, turn on Amber LED, turn off Green LED if supported*/ | 173 | /* turn off slot, turn on Amber LED, turn off Green LED if supported*/ |
169 | if (POWER_CTRL(ctrl)) { | 174 | if (POWER_CTRL(ctrl)) { |
170 | if (pslot->hpc_ops->power_off_slot(pslot)) { | 175 | if (pslot->hpc_ops->power_off_slot(pslot)) { |
171 | err("%s: Issue of Slot Power Off command failed\n", | 176 | ctrl_err(ctrl, |
172 | __func__); | 177 | "%s: Issue of Slot Power Off command failed\n", |
178 | __func__); | ||
173 | return; | 179 | return; |
174 | } | 180 | } |
175 | } | 181 | } |
@@ -186,8 +192,8 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot) | |||
186 | 192 | ||
187 | if (ATTN_LED(ctrl)) { | 193 | if (ATTN_LED(ctrl)) { |
188 | if (pslot->hpc_ops->set_attention_status(pslot, 1)) { | 194 | if (pslot->hpc_ops->set_attention_status(pslot, 1)) { |
189 | err("%s: Issue of Set Attention Led command failed\n", | 195 | ctrl_err(ctrl, "%s: Issue of Set Attention " |
190 | __func__); | 196 | "Led command failed\n", __func__); |
191 | return; | 197 | return; |
192 | } | 198 | } |
193 | } | 199 | } |
@@ -205,9 +211,9 @@ static int board_added(struct slot *p_slot) | |||
205 | int retval = 0; | 211 | int retval = 0; |
206 | struct controller *ctrl = p_slot->ctrl; | 212 | struct controller *ctrl = p_slot->ctrl; |
207 | 213 | ||
208 | dbg("%s: slot device, slot offset, hp slot = %d, %d ,%d\n", | 214 | ctrl_dbg(ctrl, "%s: slot device, slot offset, hp slot = %d, %d ,%d\n", |
209 | __func__, p_slot->device, | 215 | __func__, p_slot->device, ctrl->slot_device_offset, |
210 | ctrl->slot_device_offset, p_slot->hp_slot); | 216 | p_slot->hp_slot); |
211 | 217 | ||
212 | if (POWER_CTRL(ctrl)) { | 218 | if (POWER_CTRL(ctrl)) { |
213 | /* Power on slot */ | 219 | /* Power on slot */ |
@@ -225,22 +231,22 @@ static int board_added(struct slot *p_slot) | |||
225 | /* Check link training status */ | 231 | /* Check link training status */ |
226 | retval = p_slot->hpc_ops->check_lnk_status(ctrl); | 232 | retval = p_slot->hpc_ops->check_lnk_status(ctrl); |
227 | if (retval) { | 233 | if (retval) { |
228 | err("%s: Failed to check link status\n", __func__); | 234 | ctrl_err(ctrl, "%s: Failed to check link status\n", __func__); |
229 | set_slot_off(ctrl, p_slot); | 235 | set_slot_off(ctrl, p_slot); |
230 | return retval; | 236 | return retval; |
231 | } | 237 | } |
232 | 238 | ||
233 | /* Check for a power fault */ | 239 | /* Check for a power fault */ |
234 | if (p_slot->hpc_ops->query_power_fault(p_slot)) { | 240 | if (p_slot->hpc_ops->query_power_fault(p_slot)) { |
235 | dbg("%s: power fault detected\n", __func__); | 241 | ctrl_dbg(ctrl, "%s: power fault detected\n", __func__); |
236 | retval = POWER_FAILURE; | 242 | retval = POWER_FAILURE; |
237 | goto err_exit; | 243 | goto err_exit; |
238 | } | 244 | } |
239 | 245 | ||
240 | retval = pciehp_configure_device(p_slot); | 246 | retval = pciehp_configure_device(p_slot); |
241 | if (retval) { | 247 | if (retval) { |
242 | err("Cannot add device 0x%x:%x\n", p_slot->bus, | 248 | ctrl_err(ctrl, "Cannot add device 0x%x:%x\n", |
243 | p_slot->device); | 249 | p_slot->bus, p_slot->device); |
244 | goto err_exit; | 250 | goto err_exit; |
245 | } | 251 | } |
246 | 252 | ||
@@ -272,14 +278,14 @@ static int remove_board(struct slot *p_slot) | |||
272 | if (retval) | 278 | if (retval) |
273 | return retval; | 279 | return retval; |
274 | 280 | ||
275 | dbg("In %s, hp_slot = %d\n", __func__, p_slot->hp_slot); | 281 | ctrl_dbg(ctrl, "In %s, hp_slot = %d\n", __func__, p_slot->hp_slot); |
276 | 282 | ||
277 | if (POWER_CTRL(ctrl)) { | 283 | if (POWER_CTRL(ctrl)) { |
278 | /* power off slot */ | 284 | /* power off slot */ |
279 | retval = p_slot->hpc_ops->power_off_slot(p_slot); | 285 | retval = p_slot->hpc_ops->power_off_slot(p_slot); |
280 | if (retval) { | 286 | if (retval) { |
281 | err("%s: Issue of Slot Disable command failed\n", | 287 | ctrl_err(ctrl, "%s: Issue of Slot Disable command " |
282 | __func__); | 288 | "failed\n", __func__); |
283 | return retval; | 289 | return retval; |
284 | } | 290 | } |
285 | } | 291 | } |
@@ -320,8 +326,8 @@ static void pciehp_power_thread(struct work_struct *work) | |||
320 | switch (p_slot->state) { | 326 | switch (p_slot->state) { |
321 | case POWEROFF_STATE: | 327 | case POWEROFF_STATE: |
322 | mutex_unlock(&p_slot->lock); | 328 | mutex_unlock(&p_slot->lock); |
323 | dbg("%s: disabling bus:device(%x:%x)\n", | 329 | ctrl_dbg(p_slot->ctrl, "%s: disabling bus:device(%x:%x)\n", |
324 | __func__, p_slot->bus, p_slot->device); | 330 | __func__, p_slot->bus, p_slot->device); |
325 | pciehp_disable_slot(p_slot); | 331 | pciehp_disable_slot(p_slot); |
326 | mutex_lock(&p_slot->lock); | 332 | mutex_lock(&p_slot->lock); |
327 | p_slot->state = STATIC_STATE; | 333 | p_slot->state = STATIC_STATE; |
@@ -349,7 +355,8 @@ void pciehp_queue_pushbutton_work(struct work_struct *work) | |||
349 | 355 | ||
350 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 356 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
351 | if (!info) { | 357 | if (!info) { |
352 | err("%s: Cannot allocate memory\n", __func__); | 358 | ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n", |
359 | __func__); | ||
353 | return; | 360 | return; |
354 | } | 361 | } |
355 | info->p_slot = p_slot; | 362 | info->p_slot = p_slot; |
@@ -403,12 +410,14 @@ static void handle_button_press_event(struct slot *p_slot) | |||
403 | p_slot->hpc_ops->get_power_status(p_slot, &getstatus); | 410 | p_slot->hpc_ops->get_power_status(p_slot, &getstatus); |
404 | if (getstatus) { | 411 | if (getstatus) { |
405 | p_slot->state = BLINKINGOFF_STATE; | 412 | p_slot->state = BLINKINGOFF_STATE; |
406 | info("PCI slot #%s - powering off due to button " | 413 | ctrl_info(ctrl, |
407 | "press.\n", p_slot->name); | 414 | "PCI slot #%s - powering off due to button " |
415 | "press.\n", p_slot->name); | ||
408 | } else { | 416 | } else { |
409 | p_slot->state = BLINKINGON_STATE; | 417 | p_slot->state = BLINKINGON_STATE; |
410 | info("PCI slot #%s - powering on due to button " | 418 | ctrl_info(ctrl, |
411 | "press.\n", p_slot->name); | 419 | "PCI slot #%s - powering on due to button " |
420 | "press.\n", p_slot->name); | ||
412 | } | 421 | } |
413 | /* blink green LED and turn off amber */ | 422 | /* blink green LED and turn off amber */ |
414 | if (PWR_LED(ctrl)) | 423 | if (PWR_LED(ctrl)) |
@@ -425,8 +434,8 @@ static void handle_button_press_event(struct slot *p_slot) | |||
425 | * press the attention again before the 5 sec. limit | 434 | * press the attention again before the 5 sec. limit |
426 | * expires to cancel hot-add or hot-remove | 435 | * expires to cancel hot-add or hot-remove |
427 | */ | 436 | */ |
428 | info("Button cancel on Slot(%s)\n", p_slot->name); | 437 | ctrl_info(ctrl, "Button cancel on Slot(%s)\n", p_slot->name); |
429 | dbg("%s: button cancel\n", __func__); | 438 | ctrl_dbg(ctrl, "%s: button cancel\n", __func__); |
430 | cancel_delayed_work(&p_slot->work); | 439 | cancel_delayed_work(&p_slot->work); |
431 | if (p_slot->state == BLINKINGOFF_STATE) { | 440 | if (p_slot->state == BLINKINGOFF_STATE) { |
432 | if (PWR_LED(ctrl)) | 441 | if (PWR_LED(ctrl)) |
@@ -437,8 +446,8 @@ static void handle_button_press_event(struct slot *p_slot) | |||
437 | } | 446 | } |
438 | if (ATTN_LED(ctrl)) | 447 | if (ATTN_LED(ctrl)) |
439 | p_slot->hpc_ops->set_attention_status(p_slot, 0); | 448 | p_slot->hpc_ops->set_attention_status(p_slot, 0); |
440 | info("PCI slot #%s - action canceled due to button press\n", | 449 | ctrl_info(ctrl, "PCI slot #%s - action canceled " |
441 | p_slot->name); | 450 | "due to button press\n", p_slot->name); |
442 | p_slot->state = STATIC_STATE; | 451 | p_slot->state = STATIC_STATE; |
443 | break; | 452 | break; |
444 | case POWEROFF_STATE: | 453 | case POWEROFF_STATE: |
@@ -448,11 +457,11 @@ static void handle_button_press_event(struct slot *p_slot) | |||
448 | * this means that the previous attention button action | 457 | * this means that the previous attention button action |
449 | * to hot-add or hot-remove is undergoing | 458 | * to hot-add or hot-remove is undergoing |
450 | */ | 459 | */ |
451 | info("Button ignore on Slot(%s)\n", p_slot->name); | 460 | ctrl_info(ctrl, "Button ignore on Slot(%s)\n", p_slot->name); |
452 | update_slot_info(p_slot); | 461 | update_slot_info(p_slot); |
453 | break; | 462 | break; |
454 | default: | 463 | default: |
455 | warn("Not a valid state\n"); | 464 | ctrl_warn(ctrl, "Not a valid state\n"); |
456 | break; | 465 | break; |
457 | } | 466 | } |
458 | } | 467 | } |
@@ -467,7 +476,8 @@ static void handle_surprise_event(struct slot *p_slot) | |||
467 | 476 | ||
468 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 477 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
469 | if (!info) { | 478 | if (!info) { |
470 | err("%s: Cannot allocate memory\n", __func__); | 479 | ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n", |
480 | __func__); | ||
471 | return; | 481 | return; |
472 | } | 482 | } |
473 | info->p_slot = p_slot; | 483 | info->p_slot = p_slot; |
@@ -505,7 +515,7 @@ static void interrupt_event_handler(struct work_struct *work) | |||
505 | case INT_PRESENCE_OFF: | 515 | case INT_PRESENCE_OFF: |
506 | if (!HP_SUPR_RM(ctrl)) | 516 | if (!HP_SUPR_RM(ctrl)) |
507 | break; | 517 | break; |
508 | dbg("Surprise Removal\n"); | 518 | ctrl_dbg(ctrl, "Surprise Removal\n"); |
509 | update_slot_info(p_slot); | 519 | update_slot_info(p_slot); |
510 | handle_surprise_event(p_slot); | 520 | handle_surprise_event(p_slot); |
511 | break; | 521 | break; |
@@ -522,22 +532,23 @@ int pciehp_enable_slot(struct slot *p_slot) | |||
522 | { | 532 | { |
523 | u8 getstatus = 0; | 533 | u8 getstatus = 0; |
524 | int rc; | 534 | int rc; |
535 | struct controller *ctrl = p_slot->ctrl; | ||
525 | 536 | ||
526 | /* Check to see if (latch closed, card present, power off) */ | 537 | /* Check to see if (latch closed, card present, power off) */ |
527 | mutex_lock(&p_slot->ctrl->crit_sect); | 538 | mutex_lock(&p_slot->ctrl->crit_sect); |
528 | 539 | ||
529 | rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); | 540 | rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); |
530 | if (rc || !getstatus) { | 541 | if (rc || !getstatus) { |
531 | info("%s: no adapter on slot(%s)\n", __func__, | 542 | ctrl_info(ctrl, "%s: no adapter on slot(%s)\n", |
532 | p_slot->name); | 543 | __func__, p_slot->name); |
533 | mutex_unlock(&p_slot->ctrl->crit_sect); | 544 | mutex_unlock(&p_slot->ctrl->crit_sect); |
534 | return -ENODEV; | 545 | return -ENODEV; |
535 | } | 546 | } |
536 | if (MRL_SENS(p_slot->ctrl)) { | 547 | if (MRL_SENS(p_slot->ctrl)) { |
537 | rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); | 548 | rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); |
538 | if (rc || getstatus) { | 549 | if (rc || getstatus) { |
539 | info("%s: latch open on slot(%s)\n", __func__, | 550 | ctrl_info(ctrl, "%s: latch open on slot(%s)\n", |
540 | p_slot->name); | 551 | __func__, p_slot->name); |
541 | mutex_unlock(&p_slot->ctrl->crit_sect); | 552 | mutex_unlock(&p_slot->ctrl->crit_sect); |
542 | return -ENODEV; | 553 | return -ENODEV; |
543 | } | 554 | } |
@@ -546,8 +557,8 @@ int pciehp_enable_slot(struct slot *p_slot) | |||
546 | if (POWER_CTRL(p_slot->ctrl)) { | 557 | if (POWER_CTRL(p_slot->ctrl)) { |
547 | rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); | 558 | rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); |
548 | if (rc || getstatus) { | 559 | if (rc || getstatus) { |
549 | info("%s: already enabled on slot(%s)\n", __func__, | 560 | ctrl_info(ctrl, "%s: already enabled on slot(%s)\n", |
550 | p_slot->name); | 561 | __func__, p_slot->name); |
551 | mutex_unlock(&p_slot->ctrl->crit_sect); | 562 | mutex_unlock(&p_slot->ctrl->crit_sect); |
552 | return -EINVAL; | 563 | return -EINVAL; |
553 | } | 564 | } |
@@ -571,6 +582,7 @@ int pciehp_disable_slot(struct slot *p_slot) | |||
571 | { | 582 | { |
572 | u8 getstatus = 0; | 583 | u8 getstatus = 0; |
573 | int ret = 0; | 584 | int ret = 0; |
585 | struct controller *ctrl = p_slot->ctrl; | ||
574 | 586 | ||
575 | if (!p_slot->ctrl) | 587 | if (!p_slot->ctrl) |
576 | return 1; | 588 | return 1; |
@@ -581,8 +593,8 @@ int pciehp_disable_slot(struct slot *p_slot) | |||
581 | if (!HP_SUPR_RM(p_slot->ctrl)) { | 593 | if (!HP_SUPR_RM(p_slot->ctrl)) { |
582 | ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); | 594 | ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); |
583 | if (ret || !getstatus) { | 595 | if (ret || !getstatus) { |
584 | info("%s: no adapter on slot(%s)\n", __func__, | 596 | ctrl_info(ctrl, "%s: no adapter on slot(%s)\n", |
585 | p_slot->name); | 597 | __func__, p_slot->name); |
586 | mutex_unlock(&p_slot->ctrl->crit_sect); | 598 | mutex_unlock(&p_slot->ctrl->crit_sect); |
587 | return -ENODEV; | 599 | return -ENODEV; |
588 | } | 600 | } |
@@ -591,8 +603,8 @@ int pciehp_disable_slot(struct slot *p_slot) | |||
591 | if (MRL_SENS(p_slot->ctrl)) { | 603 | if (MRL_SENS(p_slot->ctrl)) { |
592 | ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); | 604 | ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); |
593 | if (ret || getstatus) { | 605 | if (ret || getstatus) { |
594 | info("%s: latch open on slot(%s)\n", __func__, | 606 | ctrl_info(ctrl, "%s: latch open on slot(%s)\n", |
595 | p_slot->name); | 607 | __func__, p_slot->name); |
596 | mutex_unlock(&p_slot->ctrl->crit_sect); | 608 | mutex_unlock(&p_slot->ctrl->crit_sect); |
597 | return -ENODEV; | 609 | return -ENODEV; |
598 | } | 610 | } |
@@ -601,8 +613,8 @@ int pciehp_disable_slot(struct slot *p_slot) | |||
601 | if (POWER_CTRL(p_slot->ctrl)) { | 613 | if (POWER_CTRL(p_slot->ctrl)) { |
602 | ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); | 614 | ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); |
603 | if (ret || !getstatus) { | 615 | if (ret || !getstatus) { |
604 | info("%s: already disabled slot(%s)\n", __func__, | 616 | ctrl_info(ctrl, "%s: already disabled slot(%s)\n", |
605 | p_slot->name); | 617 | __func__, p_slot->name); |
606 | mutex_unlock(&p_slot->ctrl->crit_sect); | 618 | mutex_unlock(&p_slot->ctrl->crit_sect); |
607 | return -EINVAL; | 619 | return -EINVAL; |
608 | } | 620 | } |
@@ -618,6 +630,7 @@ int pciehp_disable_slot(struct slot *p_slot) | |||
618 | int pciehp_sysfs_enable_slot(struct slot *p_slot) | 630 | int pciehp_sysfs_enable_slot(struct slot *p_slot) |
619 | { | 631 | { |
620 | int retval = -ENODEV; | 632 | int retval = -ENODEV; |
633 | struct controller *ctrl = p_slot->ctrl; | ||
621 | 634 | ||
622 | mutex_lock(&p_slot->lock); | 635 | mutex_lock(&p_slot->lock); |
623 | switch (p_slot->state) { | 636 | switch (p_slot->state) { |
@@ -631,15 +644,15 @@ int pciehp_sysfs_enable_slot(struct slot *p_slot) | |||
631 | p_slot->state = STATIC_STATE; | 644 | p_slot->state = STATIC_STATE; |
632 | break; | 645 | break; |
633 | case POWERON_STATE: | 646 | case POWERON_STATE: |
634 | info("Slot %s is already in powering on state\n", | 647 | ctrl_info(ctrl, "Slot %s is already in powering on state\n", |
635 | p_slot->name); | 648 | p_slot->name); |
636 | break; | 649 | break; |
637 | case BLINKINGOFF_STATE: | 650 | case BLINKINGOFF_STATE: |
638 | case POWEROFF_STATE: | 651 | case POWEROFF_STATE: |
639 | info("Already enabled on slot %s\n", p_slot->name); | 652 | ctrl_info(ctrl, "Already enabled on slot %s\n", p_slot->name); |
640 | break; | 653 | break; |
641 | default: | 654 | default: |
642 | err("Not a valid state on slot %s\n", p_slot->name); | 655 | ctrl_err(ctrl, "Not a valid state on slot %s\n", p_slot->name); |
643 | break; | 656 | break; |
644 | } | 657 | } |
645 | mutex_unlock(&p_slot->lock); | 658 | mutex_unlock(&p_slot->lock); |
@@ -650,6 +663,7 @@ int pciehp_sysfs_enable_slot(struct slot *p_slot) | |||
650 | int pciehp_sysfs_disable_slot(struct slot *p_slot) | 663 | int pciehp_sysfs_disable_slot(struct slot *p_slot) |
651 | { | 664 | { |
652 | int retval = -ENODEV; | 665 | int retval = -ENODEV; |
666 | struct controller *ctrl = p_slot->ctrl; | ||
653 | 667 | ||
654 | mutex_lock(&p_slot->lock); | 668 | mutex_lock(&p_slot->lock); |
655 | switch (p_slot->state) { | 669 | switch (p_slot->state) { |
@@ -663,15 +677,15 @@ int pciehp_sysfs_disable_slot(struct slot *p_slot) | |||
663 | p_slot->state = STATIC_STATE; | 677 | p_slot->state = STATIC_STATE; |
664 | break; | 678 | break; |
665 | case POWEROFF_STATE: | 679 | case POWEROFF_STATE: |
666 | info("Slot %s is already in powering off state\n", | 680 | ctrl_info(ctrl, "Slot %s is already in powering off state\n", |
667 | p_slot->name); | 681 | p_slot->name); |
668 | break; | 682 | break; |
669 | case BLINKINGON_STATE: | 683 | case BLINKINGON_STATE: |
670 | case POWERON_STATE: | 684 | case POWERON_STATE: |
671 | info("Already disabled on slot %s\n", p_slot->name); | 685 | ctrl_info(ctrl, "Already disabled on slot %s\n", p_slot->name); |
672 | break; | 686 | break; |
673 | default: | 687 | default: |
674 | err("Not a valid state on slot %s\n", p_slot->name); | 688 | ctrl_err(ctrl, "Not a valid state on slot %s\n", p_slot->name); |
675 | break; | 689 | break; |
676 | } | 690 | } |
677 | mutex_unlock(&p_slot->lock); | 691 | mutex_unlock(&p_slot->lock); |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 9d934ddee956..8e9530c4c36d 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -223,7 +223,7 @@ static void start_int_poll_timer(struct controller *ctrl, int sec) | |||
223 | 223 | ||
224 | static inline int pciehp_request_irq(struct controller *ctrl) | 224 | static inline int pciehp_request_irq(struct controller *ctrl) |
225 | { | 225 | { |
226 | int retval, irq = ctrl->pci_dev->irq; | 226 | int retval, irq = ctrl->pcie->irq; |
227 | 227 | ||
228 | /* Install interrupt polling timer. Start with 10 sec delay */ | 228 | /* Install interrupt polling timer. Start with 10 sec delay */ |
229 | if (pciehp_poll_mode) { | 229 | if (pciehp_poll_mode) { |
@@ -235,7 +235,8 @@ static inline int pciehp_request_irq(struct controller *ctrl) | |||
235 | /* Installs the interrupt handler */ | 235 | /* Installs the interrupt handler */ |
236 | retval = request_irq(irq, pcie_isr, IRQF_SHARED, MY_NAME, ctrl); | 236 | retval = request_irq(irq, pcie_isr, IRQF_SHARED, MY_NAME, ctrl); |
237 | if (retval) | 237 | if (retval) |
238 | err("Cannot get irq %d for the hotplug controller\n", irq); | 238 | ctrl_err(ctrl, "Cannot get irq %d for the hotplug controller\n", |
239 | irq); | ||
239 | return retval; | 240 | return retval; |
240 | } | 241 | } |
241 | 242 | ||
@@ -244,7 +245,7 @@ static inline void pciehp_free_irq(struct controller *ctrl) | |||
244 | if (pciehp_poll_mode) | 245 | if (pciehp_poll_mode) |
245 | del_timer_sync(&ctrl->poll_timer); | 246 | del_timer_sync(&ctrl->poll_timer); |
246 | else | 247 | else |
247 | free_irq(ctrl->pci_dev->irq, ctrl); | 248 | free_irq(ctrl->pcie->irq, ctrl); |
248 | } | 249 | } |
249 | 250 | ||
250 | static int pcie_poll_cmd(struct controller *ctrl) | 251 | static int pcie_poll_cmd(struct controller *ctrl) |
@@ -282,7 +283,7 @@ static void pcie_wait_cmd(struct controller *ctrl, int poll) | |||
282 | else | 283 | else |
283 | rc = wait_event_timeout(ctrl->queue, !ctrl->cmd_busy, timeout); | 284 | rc = wait_event_timeout(ctrl->queue, !ctrl->cmd_busy, timeout); |
284 | if (!rc) | 285 | if (!rc) |
285 | dbg("Command not completed in 1000 msec\n"); | 286 | ctrl_dbg(ctrl, "Command not completed in 1000 msec\n"); |
286 | } | 287 | } |
287 | 288 | ||
288 | /** | 289 | /** |
@@ -301,7 +302,8 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) | |||
301 | 302 | ||
302 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | 303 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
303 | if (retval) { | 304 | if (retval) { |
304 | err("%s: Cannot read SLOTSTATUS register\n", __func__); | 305 | ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n", |
306 | __func__); | ||
305 | goto out; | 307 | goto out; |
306 | } | 308 | } |
307 | 309 | ||
@@ -312,26 +314,28 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) | |||
312 | * proceed forward to issue the next command according | 314 | * proceed forward to issue the next command according |
313 | * to spec. Just print out the error message. | 315 | * to spec. Just print out the error message. |
314 | */ | 316 | */ |
315 | dbg("%s: CMD_COMPLETED not clear after 1 sec.\n", | 317 | ctrl_dbg(ctrl, |
316 | __func__); | 318 | "%s: CMD_COMPLETED not clear after 1 sec.\n", |
319 | __func__); | ||
317 | } else if (!NO_CMD_CMPL(ctrl)) { | 320 | } else if (!NO_CMD_CMPL(ctrl)) { |
318 | /* | 321 | /* |
319 | * This controller semms to notify of command completed | 322 | * This controller semms to notify of command completed |
320 | * event even though it supports none of power | 323 | * event even though it supports none of power |
321 | * controller, attention led, power led and EMI. | 324 | * controller, attention led, power led and EMI. |
322 | */ | 325 | */ |
323 | dbg("%s: Unexpected CMD_COMPLETED. Need to wait for " | 326 | ctrl_dbg(ctrl, "%s: Unexpected CMD_COMPLETED. Need to " |
324 | "command completed event.\n", __func__); | 327 | "wait for command completed event.\n", |
328 | __func__); | ||
325 | ctrl->no_cmd_complete = 0; | 329 | ctrl->no_cmd_complete = 0; |
326 | } else { | 330 | } else { |
327 | dbg("%s: Unexpected CMD_COMPLETED. Maybe the " | 331 | ctrl_dbg(ctrl, "%s: Unexpected CMD_COMPLETED. Maybe " |
328 | "controller is broken.\n", __func__); | 332 | "the controller is broken.\n", __func__); |
329 | } | 333 | } |
330 | } | 334 | } |
331 | 335 | ||
332 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 336 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); |
333 | if (retval) { | 337 | if (retval) { |
334 | err("%s: Cannot read SLOTCTRL register\n", __func__); | 338 | ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); |
335 | goto out; | 339 | goto out; |
336 | } | 340 | } |
337 | 341 | ||
@@ -341,7 +345,8 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) | |||
341 | smp_mb(); | 345 | smp_mb(); |
342 | retval = pciehp_writew(ctrl, SLOTCTRL, slot_ctrl); | 346 | retval = pciehp_writew(ctrl, SLOTCTRL, slot_ctrl); |
343 | if (retval) | 347 | if (retval) |
344 | err("%s: Cannot write to SLOTCTRL register\n", __func__); | 348 | ctrl_err(ctrl, "%s: Cannot write to SLOTCTRL register\n", |
349 | __func__); | ||
345 | 350 | ||
346 | /* | 351 | /* |
347 | * Wait for command completion. | 352 | * Wait for command completion. |
@@ -370,14 +375,15 @@ static int hpc_check_lnk_status(struct controller *ctrl) | |||
370 | 375 | ||
371 | retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status); | 376 | retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status); |
372 | if (retval) { | 377 | if (retval) { |
373 | err("%s: Cannot read LNKSTATUS register\n", __func__); | 378 | ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n", |
379 | __func__); | ||
374 | return retval; | 380 | return retval; |
375 | } | 381 | } |
376 | 382 | ||
377 | dbg("%s: lnk_status = %x\n", __func__, lnk_status); | 383 | ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status); |
378 | if ( (lnk_status & LNK_TRN) || (lnk_status & LNK_TRN_ERR) || | 384 | if ( (lnk_status & LNK_TRN) || (lnk_status & LNK_TRN_ERR) || |
379 | !(lnk_status & NEG_LINK_WD)) { | 385 | !(lnk_status & NEG_LINK_WD)) { |
380 | err("%s : Link Training Error occurs \n", __func__); | 386 | ctrl_err(ctrl, "%s : Link Training Error occurs \n", __func__); |
381 | retval = -1; | 387 | retval = -1; |
382 | return retval; | 388 | return retval; |
383 | } | 389 | } |
@@ -394,12 +400,12 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status) | |||
394 | 400 | ||
395 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 401 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); |
396 | if (retval) { | 402 | if (retval) { |
397 | err("%s: Cannot read SLOTCTRL register\n", __func__); | 403 | ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); |
398 | return retval; | 404 | return retval; |
399 | } | 405 | } |
400 | 406 | ||
401 | dbg("%s: SLOTCTRL %x, value read %x\n", | 407 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", |
402 | __func__, ctrl->cap_base + SLOTCTRL, slot_ctrl); | 408 | __func__, ctrl->cap_base + SLOTCTRL, slot_ctrl); |
403 | 409 | ||
404 | atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6; | 410 | atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6; |
405 | 411 | ||
@@ -433,11 +439,11 @@ static int hpc_get_power_status(struct slot *slot, u8 *status) | |||
433 | 439 | ||
434 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 440 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); |
435 | if (retval) { | 441 | if (retval) { |
436 | err("%s: Cannot read SLOTCTRL register\n", __func__); | 442 | ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); |
437 | return retval; | 443 | return retval; |
438 | } | 444 | } |
439 | dbg("%s: SLOTCTRL %x value read %x\n", | 445 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n", |
440 | __func__, ctrl->cap_base + SLOTCTRL, slot_ctrl); | 446 | __func__, ctrl->cap_base + SLOTCTRL, slot_ctrl); |
441 | 447 | ||
442 | pwr_state = (slot_ctrl & PWR_CTRL) >> 10; | 448 | pwr_state = (slot_ctrl & PWR_CTRL) >> 10; |
443 | 449 | ||
@@ -464,7 +470,8 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status) | |||
464 | 470 | ||
465 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | 471 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
466 | if (retval) { | 472 | if (retval) { |
467 | err("%s: Cannot read SLOTSTATUS register\n", __func__); | 473 | ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n", |
474 | __func__); | ||
468 | return retval; | 475 | return retval; |
469 | } | 476 | } |
470 | 477 | ||
@@ -482,7 +489,8 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status) | |||
482 | 489 | ||
483 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | 490 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
484 | if (retval) { | 491 | if (retval) { |
485 | err("%s: Cannot read SLOTSTATUS register\n", __func__); | 492 | ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n", |
493 | __func__); | ||
486 | return retval; | 494 | return retval; |
487 | } | 495 | } |
488 | card_state = (u8)((slot_status & PRSN_STATE) >> 6); | 496 | card_state = (u8)((slot_status & PRSN_STATE) >> 6); |
@@ -500,7 +508,7 @@ static int hpc_query_power_fault(struct slot *slot) | |||
500 | 508 | ||
501 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | 509 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
502 | if (retval) { | 510 | if (retval) { |
503 | err("%s: Cannot check for power fault\n", __func__); | 511 | ctrl_err(ctrl, "%s: Cannot check for power fault\n", __func__); |
504 | return retval; | 512 | return retval; |
505 | } | 513 | } |
506 | pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1); | 514 | pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1); |
@@ -516,7 +524,7 @@ static int hpc_get_emi_status(struct slot *slot, u8 *status) | |||
516 | 524 | ||
517 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | 525 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
518 | if (retval) { | 526 | if (retval) { |
519 | err("%s : Cannot check EMI status\n", __func__); | 527 | ctrl_err(ctrl, "%s : Cannot check EMI status\n", __func__); |
520 | return retval; | 528 | return retval; |
521 | } | 529 | } |
522 | *status = (slot_status & EMI_STATE) >> EMI_STATUS_BIT; | 530 | *status = (slot_status & EMI_STATE) >> EMI_STATUS_BIT; |
@@ -560,8 +568,8 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) | |||
560 | return -1; | 568 | return -1; |
561 | } | 569 | } |
562 | rc = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 570 | rc = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
563 | dbg("%s: SLOTCTRL %x write cmd %x\n", | 571 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", |
564 | __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 572 | __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); |
565 | 573 | ||
566 | return rc; | 574 | return rc; |
567 | } | 575 | } |
@@ -575,8 +583,8 @@ static void hpc_set_green_led_on(struct slot *slot) | |||
575 | slot_cmd = 0x0100; | 583 | slot_cmd = 0x0100; |
576 | cmd_mask = PWR_LED_CTRL; | 584 | cmd_mask = PWR_LED_CTRL; |
577 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 585 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
578 | dbg("%s: SLOTCTRL %x write cmd %x\n", | 586 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", |
579 | __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 587 | __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); |
580 | } | 588 | } |
581 | 589 | ||
582 | static void hpc_set_green_led_off(struct slot *slot) | 590 | static void hpc_set_green_led_off(struct slot *slot) |
@@ -588,8 +596,8 @@ static void hpc_set_green_led_off(struct slot *slot) | |||
588 | slot_cmd = 0x0300; | 596 | slot_cmd = 0x0300; |
589 | cmd_mask = PWR_LED_CTRL; | 597 | cmd_mask = PWR_LED_CTRL; |
590 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 598 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
591 | dbg("%s: SLOTCTRL %x write cmd %x\n", | 599 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", |
592 | __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 600 | __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); |
593 | } | 601 | } |
594 | 602 | ||
595 | static void hpc_set_green_led_blink(struct slot *slot) | 603 | static void hpc_set_green_led_blink(struct slot *slot) |
@@ -601,8 +609,8 @@ static void hpc_set_green_led_blink(struct slot *slot) | |||
601 | slot_cmd = 0x0200; | 609 | slot_cmd = 0x0200; |
602 | cmd_mask = PWR_LED_CTRL; | 610 | cmd_mask = PWR_LED_CTRL; |
603 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 611 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
604 | dbg("%s: SLOTCTRL %x write cmd %x\n", | 612 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", |
605 | __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 613 | __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); |
606 | } | 614 | } |
607 | 615 | ||
608 | static int hpc_power_on_slot(struct slot * slot) | 616 | static int hpc_power_on_slot(struct slot * slot) |
@@ -613,20 +621,22 @@ static int hpc_power_on_slot(struct slot * slot) | |||
613 | u16 slot_status; | 621 | u16 slot_status; |
614 | int retval = 0; | 622 | int retval = 0; |
615 | 623 | ||
616 | dbg("%s: slot->hp_slot %x\n", __func__, slot->hp_slot); | 624 | ctrl_dbg(ctrl, "%s: slot->hp_slot %x\n", __func__, slot->hp_slot); |
617 | 625 | ||
618 | /* Clear sticky power-fault bit from previous power failures */ | 626 | /* Clear sticky power-fault bit from previous power failures */ |
619 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | 627 | retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
620 | if (retval) { | 628 | if (retval) { |
621 | err("%s: Cannot read SLOTSTATUS register\n", __func__); | 629 | ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n", |
630 | __func__); | ||
622 | return retval; | 631 | return retval; |
623 | } | 632 | } |
624 | slot_status &= PWR_FAULT_DETECTED; | 633 | slot_status &= PWR_FAULT_DETECTED; |
625 | if (slot_status) { | 634 | if (slot_status) { |
626 | retval = pciehp_writew(ctrl, SLOTSTATUS, slot_status); | 635 | retval = pciehp_writew(ctrl, SLOTSTATUS, slot_status); |
627 | if (retval) { | 636 | if (retval) { |
628 | err("%s: Cannot write to SLOTSTATUS register\n", | 637 | ctrl_err(ctrl, |
629 | __func__); | 638 | "%s: Cannot write to SLOTSTATUS register\n", |
639 | __func__); | ||
630 | return retval; | 640 | return retval; |
631 | } | 641 | } |
632 | } | 642 | } |
@@ -644,11 +654,12 @@ static int hpc_power_on_slot(struct slot * slot) | |||
644 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 654 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
645 | 655 | ||
646 | if (retval) { | 656 | if (retval) { |
647 | err("%s: Write %x command failed!\n", __func__, slot_cmd); | 657 | ctrl_err(ctrl, "%s: Write %x command failed!\n", |
658 | __func__, slot_cmd); | ||
648 | return -1; | 659 | return -1; |
649 | } | 660 | } |
650 | dbg("%s: SLOTCTRL %x write cmd %x\n", | 661 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", |
651 | __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 662 | __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); |
652 | 663 | ||
653 | return retval; | 664 | return retval; |
654 | } | 665 | } |
@@ -694,7 +705,7 @@ static int hpc_power_off_slot(struct slot * slot) | |||
694 | int retval = 0; | 705 | int retval = 0; |
695 | int changed; | 706 | int changed; |
696 | 707 | ||
697 | dbg("%s: slot->hp_slot %x\n", __func__, slot->hp_slot); | 708 | ctrl_dbg(ctrl, "%s: slot->hp_slot %x\n", __func__, slot->hp_slot); |
698 | 709 | ||
699 | /* | 710 | /* |
700 | * Set Bad DLLP Mask bit in Correctable Error Mask | 711 | * Set Bad DLLP Mask bit in Correctable Error Mask |
@@ -722,12 +733,12 @@ static int hpc_power_off_slot(struct slot * slot) | |||
722 | 733 | ||
723 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 734 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
724 | if (retval) { | 735 | if (retval) { |
725 | err("%s: Write command failed!\n", __func__); | 736 | ctrl_err(ctrl, "%s: Write command failed!\n", __func__); |
726 | retval = -1; | 737 | retval = -1; |
727 | goto out; | 738 | goto out; |
728 | } | 739 | } |
729 | dbg("%s: SLOTCTRL %x write cmd %x\n", | 740 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", |
730 | __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 741 | __func__, ctrl->cap_base + SLOTCTRL, slot_cmd); |
731 | out: | 742 | out: |
732 | if (changed) | 743 | if (changed) |
733 | pcie_unmask_bad_dllp(ctrl); | 744 | pcie_unmask_bad_dllp(ctrl); |
@@ -749,7 +760,8 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
749 | intr_loc = 0; | 760 | intr_loc = 0; |
750 | do { | 761 | do { |
751 | if (pciehp_readw(ctrl, SLOTSTATUS, &detected)) { | 762 | if (pciehp_readw(ctrl, SLOTSTATUS, &detected)) { |
752 | err("%s: Cannot read SLOTSTATUS\n", __func__); | 763 | ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS\n", |
764 | __func__); | ||
753 | return IRQ_NONE; | 765 | return IRQ_NONE; |
754 | } | 766 | } |
755 | 767 | ||
@@ -760,12 +772,13 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
760 | if (!intr_loc) | 772 | if (!intr_loc) |
761 | return IRQ_NONE; | 773 | return IRQ_NONE; |
762 | if (detected && pciehp_writew(ctrl, SLOTSTATUS, detected)) { | 774 | if (detected && pciehp_writew(ctrl, SLOTSTATUS, detected)) { |
763 | err("%s: Cannot write to SLOTSTATUS\n", __func__); | 775 | ctrl_err(ctrl, "%s: Cannot write to SLOTSTATUS\n", |
776 | __func__); | ||
764 | return IRQ_NONE; | 777 | return IRQ_NONE; |
765 | } | 778 | } |
766 | } while (detected); | 779 | } while (detected); |
767 | 780 | ||
768 | dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc); | 781 | ctrl_dbg(ctrl, "%s: intr_loc %x\n", __func__, intr_loc); |
769 | 782 | ||
770 | /* Check Command Complete Interrupt Pending */ | 783 | /* Check Command Complete Interrupt Pending */ |
771 | if (intr_loc & CMD_COMPLETED) { | 784 | if (intr_loc & CMD_COMPLETED) { |
@@ -807,7 +820,7 @@ static int hpc_get_max_lnk_speed(struct slot *slot, enum pci_bus_speed *value) | |||
807 | 820 | ||
808 | retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap); | 821 | retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap); |
809 | if (retval) { | 822 | if (retval) { |
810 | err("%s: Cannot read LNKCAP register\n", __func__); | 823 | ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__); |
811 | return retval; | 824 | return retval; |
812 | } | 825 | } |
813 | 826 | ||
@@ -821,7 +834,7 @@ static int hpc_get_max_lnk_speed(struct slot *slot, enum pci_bus_speed *value) | |||
821 | } | 834 | } |
822 | 835 | ||
823 | *value = lnk_speed; | 836 | *value = lnk_speed; |
824 | dbg("Max link speed = %d\n", lnk_speed); | 837 | ctrl_dbg(ctrl, "Max link speed = %d\n", lnk_speed); |
825 | 838 | ||
826 | return retval; | 839 | return retval; |
827 | } | 840 | } |
@@ -836,7 +849,7 @@ static int hpc_get_max_lnk_width(struct slot *slot, | |||
836 | 849 | ||
837 | retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap); | 850 | retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap); |
838 | if (retval) { | 851 | if (retval) { |
839 | err("%s: Cannot read LNKCAP register\n", __func__); | 852 | ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__); |
840 | return retval; | 853 | return retval; |
841 | } | 854 | } |
842 | 855 | ||
@@ -871,7 +884,7 @@ static int hpc_get_max_lnk_width(struct slot *slot, | |||
871 | } | 884 | } |
872 | 885 | ||
873 | *value = lnk_wdth; | 886 | *value = lnk_wdth; |
874 | dbg("Max link width = %d\n", lnk_wdth); | 887 | ctrl_dbg(ctrl, "Max link width = %d\n", lnk_wdth); |
875 | 888 | ||
876 | return retval; | 889 | return retval; |
877 | } | 890 | } |
@@ -885,7 +898,8 @@ static int hpc_get_cur_lnk_speed(struct slot *slot, enum pci_bus_speed *value) | |||
885 | 898 | ||
886 | retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status); | 899 | retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status); |
887 | if (retval) { | 900 | if (retval) { |
888 | err("%s: Cannot read LNKSTATUS register\n", __func__); | 901 | ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n", |
902 | __func__); | ||
889 | return retval; | 903 | return retval; |
890 | } | 904 | } |
891 | 905 | ||
@@ -899,7 +913,7 @@ static int hpc_get_cur_lnk_speed(struct slot *slot, enum pci_bus_speed *value) | |||
899 | } | 913 | } |
900 | 914 | ||
901 | *value = lnk_speed; | 915 | *value = lnk_speed; |
902 | dbg("Current link speed = %d\n", lnk_speed); | 916 | ctrl_dbg(ctrl, "Current link speed = %d\n", lnk_speed); |
903 | 917 | ||
904 | return retval; | 918 | return retval; |
905 | } | 919 | } |
@@ -914,7 +928,8 @@ static int hpc_get_cur_lnk_width(struct slot *slot, | |||
914 | 928 | ||
915 | retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status); | 929 | retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status); |
916 | if (retval) { | 930 | if (retval) { |
917 | err("%s: Cannot read LNKSTATUS register\n", __func__); | 931 | ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n", |
932 | __func__); | ||
918 | return retval; | 933 | return retval; |
919 | } | 934 | } |
920 | 935 | ||
@@ -949,7 +964,7 @@ static int hpc_get_cur_lnk_width(struct slot *slot, | |||
949 | } | 964 | } |
950 | 965 | ||
951 | *value = lnk_wdth; | 966 | *value = lnk_wdth; |
952 | dbg("Current link width = %d\n", lnk_wdth); | 967 | ctrl_dbg(ctrl, "Current link width = %d\n", lnk_wdth); |
953 | 968 | ||
954 | return retval; | 969 | return retval; |
955 | } | 970 | } |
@@ -998,7 +1013,8 @@ int pcie_enable_notification(struct controller *ctrl) | |||
998 | PWR_FAULT_DETECT_ENABLE | HP_INTR_ENABLE | CMD_CMPL_INTR_ENABLE; | 1013 | PWR_FAULT_DETECT_ENABLE | HP_INTR_ENABLE | CMD_CMPL_INTR_ENABLE; |
999 | 1014 | ||
1000 | if (pcie_write_cmd(ctrl, cmd, mask)) { | 1015 | if (pcie_write_cmd(ctrl, cmd, mask)) { |
1001 | err("%s: Cannot enable software notification\n", __func__); | 1016 | ctrl_err(ctrl, "%s: Cannot enable software notification\n", |
1017 | __func__); | ||
1002 | return -1; | 1018 | return -1; |
1003 | } | 1019 | } |
1004 | return 0; | 1020 | return 0; |
@@ -1010,7 +1026,8 @@ static void pcie_disable_notification(struct controller *ctrl) | |||
1010 | mask = PRSN_DETECT_ENABLE | ATTN_BUTTN_ENABLE | MRL_DETECT_ENABLE | | 1026 | mask = PRSN_DETECT_ENABLE | ATTN_BUTTN_ENABLE | MRL_DETECT_ENABLE | |
1011 | PWR_FAULT_DETECT_ENABLE | HP_INTR_ENABLE | CMD_CMPL_INTR_ENABLE; | 1027 | PWR_FAULT_DETECT_ENABLE | HP_INTR_ENABLE | CMD_CMPL_INTR_ENABLE; |
1012 | if (pcie_write_cmd(ctrl, 0, mask)) | 1028 | if (pcie_write_cmd(ctrl, 0, mask)) |
1013 | warn("%s: Cannot disable software notification\n", __func__); | 1029 | ctrl_warn(ctrl, "%s: Cannot disable software notification\n", |
1030 | __func__); | ||
1014 | } | 1031 | } |
1015 | 1032 | ||
1016 | static int pcie_init_notification(struct controller *ctrl) | 1033 | static int pcie_init_notification(struct controller *ctrl) |
@@ -1071,34 +1088,45 @@ static inline void dbg_ctrl(struct controller *ctrl) | |||
1071 | if (!pciehp_debug) | 1088 | if (!pciehp_debug) |
1072 | return; | 1089 | return; |
1073 | 1090 | ||
1074 | dbg("Hotplug Controller:\n"); | 1091 | ctrl_info(ctrl, "Hotplug Controller:\n"); |
1075 | dbg(" Seg/Bus/Dev/Func/IRQ : %s IRQ %d\n", pci_name(pdev), pdev->irq); | 1092 | ctrl_info(ctrl, " Seg/Bus/Dev/Func/IRQ : %s IRQ %d\n", |
1076 | dbg(" Vendor ID : 0x%04x\n", pdev->vendor); | 1093 | pci_name(pdev), pdev->irq); |
1077 | dbg(" Device ID : 0x%04x\n", pdev->device); | 1094 | ctrl_info(ctrl, " Vendor ID : 0x%04x\n", pdev->vendor); |
1078 | dbg(" Subsystem ID : 0x%04x\n", pdev->subsystem_device); | 1095 | ctrl_info(ctrl, " Device ID : 0x%04x\n", pdev->device); |
1079 | dbg(" Subsystem Vendor ID : 0x%04x\n", pdev->subsystem_vendor); | 1096 | ctrl_info(ctrl, " Subsystem ID : 0x%04x\n", |
1080 | dbg(" PCIe Cap offset : 0x%02x\n", ctrl->cap_base); | 1097 | pdev->subsystem_device); |
1098 | ctrl_info(ctrl, " Subsystem Vendor ID : 0x%04x\n", | ||
1099 | pdev->subsystem_vendor); | ||
1100 | ctrl_info(ctrl, " PCIe Cap offset : 0x%02x\n", ctrl->cap_base); | ||
1081 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | 1101 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { |
1082 | if (!pci_resource_len(pdev, i)) | 1102 | if (!pci_resource_len(pdev, i)) |
1083 | continue; | 1103 | continue; |
1084 | dbg(" PCI resource [%d] : 0x%llx@0x%llx\n", i, | 1104 | ctrl_info(ctrl, " PCI resource [%d] : 0x%llx@0x%llx\n", |
1085 | (unsigned long long)pci_resource_len(pdev, i), | 1105 | i, (unsigned long long)pci_resource_len(pdev, i), |
1086 | (unsigned long long)pci_resource_start(pdev, i)); | 1106 | (unsigned long long)pci_resource_start(pdev, i)); |
1087 | } | 1107 | } |
1088 | dbg("Slot Capabilities : 0x%08x\n", ctrl->slot_cap); | 1108 | ctrl_info(ctrl, "Slot Capabilities : 0x%08x\n", ctrl->slot_cap); |
1089 | dbg(" Physical Slot Number : %d\n", ctrl->first_slot); | 1109 | ctrl_info(ctrl, " Physical Slot Number : %d\n", ctrl->first_slot); |
1090 | dbg(" Attention Button : %3s\n", ATTN_BUTTN(ctrl) ? "yes" : "no"); | 1110 | ctrl_info(ctrl, " Attention Button : %3s\n", |
1091 | dbg(" Power Controller : %3s\n", POWER_CTRL(ctrl) ? "yes" : "no"); | 1111 | ATTN_BUTTN(ctrl) ? "yes" : "no"); |
1092 | dbg(" MRL Sensor : %3s\n", MRL_SENS(ctrl) ? "yes" : "no"); | 1112 | ctrl_info(ctrl, " Power Controller : %3s\n", |
1093 | dbg(" Attention Indicator : %3s\n", ATTN_LED(ctrl) ? "yes" : "no"); | 1113 | POWER_CTRL(ctrl) ? "yes" : "no"); |
1094 | dbg(" Power Indicator : %3s\n", PWR_LED(ctrl) ? "yes" : "no"); | 1114 | ctrl_info(ctrl, " MRL Sensor : %3s\n", |
1095 | dbg(" Hot-Plug Surprise : %3s\n", HP_SUPR_RM(ctrl) ? "yes" : "no"); | 1115 | MRL_SENS(ctrl) ? "yes" : "no"); |
1096 | dbg(" EMI Present : %3s\n", EMI(ctrl) ? "yes" : "no"); | 1116 | ctrl_info(ctrl, " Attention Indicator : %3s\n", |
1097 | dbg(" Command Completed : %3s\n", NO_CMD_CMPL(ctrl)? "no" : "yes"); | 1117 | ATTN_LED(ctrl) ? "yes" : "no"); |
1118 | ctrl_info(ctrl, " Power Indicator : %3s\n", | ||
1119 | PWR_LED(ctrl) ? "yes" : "no"); | ||
1120 | ctrl_info(ctrl, " Hot-Plug Surprise : %3s\n", | ||
1121 | HP_SUPR_RM(ctrl) ? "yes" : "no"); | ||
1122 | ctrl_info(ctrl, " EMI Present : %3s\n", | ||
1123 | EMI(ctrl) ? "yes" : "no"); | ||
1124 | ctrl_info(ctrl, " Command Completed : %3s\n", | ||
1125 | NO_CMD_CMPL(ctrl) ? "no" : "yes"); | ||
1098 | pciehp_readw(ctrl, SLOTSTATUS, ®16); | 1126 | pciehp_readw(ctrl, SLOTSTATUS, ®16); |
1099 | dbg("Slot Status : 0x%04x\n", reg16); | 1127 | ctrl_info(ctrl, "Slot Status : 0x%04x\n", reg16); |
1100 | pciehp_readw(ctrl, SLOTCTRL, ®16); | 1128 | pciehp_readw(ctrl, SLOTCTRL, ®16); |
1101 | dbg("Slot Control : 0x%04x\n", reg16); | 1129 | ctrl_info(ctrl, "Slot Control : 0x%04x\n", reg16); |
1102 | } | 1130 | } |
1103 | 1131 | ||
1104 | struct controller *pcie_init(struct pcie_device *dev) | 1132 | struct controller *pcie_init(struct pcie_device *dev) |
@@ -1109,19 +1137,21 @@ struct controller *pcie_init(struct pcie_device *dev) | |||
1109 | 1137 | ||
1110 | ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); | 1138 | ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); |
1111 | if (!ctrl) { | 1139 | if (!ctrl) { |
1112 | err("%s : out of memory\n", __func__); | 1140 | dev_err(&dev->device, "%s : out of memory\n", __func__); |
1113 | goto abort; | 1141 | goto abort; |
1114 | } | 1142 | } |
1115 | INIT_LIST_HEAD(&ctrl->slot_list); | 1143 | INIT_LIST_HEAD(&ctrl->slot_list); |
1116 | 1144 | ||
1145 | ctrl->pcie = dev; | ||
1117 | ctrl->pci_dev = pdev; | 1146 | ctrl->pci_dev = pdev; |
1118 | ctrl->cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP); | 1147 | ctrl->cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP); |
1119 | if (!ctrl->cap_base) { | 1148 | if (!ctrl->cap_base) { |
1120 | err("%s: Cannot find PCI Express capability\n", __func__); | 1149 | ctrl_err(ctrl, "%s: Cannot find PCI Express capability\n", |
1150 | __func__); | ||
1121 | goto abort; | 1151 | goto abort; |
1122 | } | 1152 | } |
1123 | if (pciehp_readl(ctrl, SLOTCAP, &slot_cap)) { | 1153 | if (pciehp_readl(ctrl, SLOTCAP, &slot_cap)) { |
1124 | err("%s: Cannot read SLOTCAP register\n", __func__); | 1154 | ctrl_err(ctrl, "%s: Cannot read SLOTCAP register\n", __func__); |
1125 | goto abort; | 1155 | goto abort; |
1126 | } | 1156 | } |
1127 | 1157 | ||
@@ -1161,9 +1191,9 @@ struct controller *pcie_init(struct pcie_device *dev) | |||
1161 | goto abort_ctrl; | 1191 | goto abort_ctrl; |
1162 | } | 1192 | } |
1163 | 1193 | ||
1164 | info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", | 1194 | ctrl_info(ctrl, "HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", |
1165 | pdev->vendor, pdev->device, | 1195 | pdev->vendor, pdev->device, pdev->subsystem_vendor, |
1166 | pdev->subsystem_vendor, pdev->subsystem_device); | 1196 | pdev->subsystem_device); |
1167 | 1197 | ||
1168 | if (pcie_init_slot(ctrl)) | 1198 | if (pcie_init_slot(ctrl)) |
1169 | goto abort_ctrl; | 1199 | goto abort_ctrl; |
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 6040dcceb256..ffd11148fbe2 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c | |||
@@ -198,18 +198,20 @@ int pciehp_configure_device(struct slot *p_slot) | |||
198 | struct pci_dev *dev; | 198 | struct pci_dev *dev; |
199 | struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; | 199 | struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; |
200 | int num, fn; | 200 | int num, fn; |
201 | struct controller *ctrl = p_slot->ctrl; | ||
201 | 202 | ||
202 | dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0)); | 203 | dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0)); |
203 | if (dev) { | 204 | if (dev) { |
204 | err("Device %s already exists at %x:%x, cannot hot-add\n", | 205 | ctrl_err(ctrl, |
205 | pci_name(dev), p_slot->bus, p_slot->device); | 206 | "Device %s already exists at %x:%x, cannot hot-add\n", |
207 | pci_name(dev), p_slot->bus, p_slot->device); | ||
206 | pci_dev_put(dev); | 208 | pci_dev_put(dev); |
207 | return -EINVAL; | 209 | return -EINVAL; |
208 | } | 210 | } |
209 | 211 | ||
210 | num = pci_scan_slot(parent, PCI_DEVFN(p_slot->device, 0)); | 212 | num = pci_scan_slot(parent, PCI_DEVFN(p_slot->device, 0)); |
211 | if (num == 0) { | 213 | if (num == 0) { |
212 | err("No new device found\n"); | 214 | ctrl_err(ctrl, "No new device found\n"); |
213 | return -ENODEV; | 215 | return -ENODEV; |
214 | } | 216 | } |
215 | 217 | ||
@@ -218,8 +220,8 @@ int pciehp_configure_device(struct slot *p_slot) | |||
218 | if (!dev) | 220 | if (!dev) |
219 | continue; | 221 | continue; |
220 | if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { | 222 | if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { |
221 | err("Cannot hot-add display device %s\n", | 223 | ctrl_err(ctrl, "Cannot hot-add display device %s\n", |
222 | pci_name(dev)); | 224 | pci_name(dev)); |
223 | pci_dev_put(dev); | 225 | pci_dev_put(dev); |
224 | continue; | 226 | continue; |
225 | } | 227 | } |
@@ -244,9 +246,10 @@ int pciehp_unconfigure_device(struct slot *p_slot) | |||
244 | u8 presence = 0; | 246 | u8 presence = 0; |
245 | struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; | 247 | struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; |
246 | u16 command; | 248 | u16 command; |
249 | struct controller *ctrl = p_slot->ctrl; | ||
247 | 250 | ||
248 | dbg("%s: bus/dev = %x/%x\n", __func__, p_slot->bus, | 251 | ctrl_dbg(ctrl, "%s: bus/dev = %x/%x\n", __func__, |
249 | p_slot->device); | 252 | p_slot->bus, p_slot->device); |
250 | ret = p_slot->hpc_ops->get_adapter_status(p_slot, &presence); | 253 | ret = p_slot->hpc_ops->get_adapter_status(p_slot, &presence); |
251 | if (ret) | 254 | if (ret) |
252 | presence = 0; | 255 | presence = 0; |
@@ -257,16 +260,17 @@ int pciehp_unconfigure_device(struct slot *p_slot) | |||
257 | if (!temp) | 260 | if (!temp) |
258 | continue; | 261 | continue; |
259 | if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) { | 262 | if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) { |
260 | err("Cannot remove display device %s\n", | 263 | ctrl_err(ctrl, "Cannot remove display device %s\n", |
261 | pci_name(temp)); | 264 | pci_name(temp)); |
262 | pci_dev_put(temp); | 265 | pci_dev_put(temp); |
263 | continue; | 266 | continue; |
264 | } | 267 | } |
265 | if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) { | 268 | if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) { |
266 | pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl); | 269 | pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl); |
267 | if (bctl & PCI_BRIDGE_CTL_VGA) { | 270 | if (bctl & PCI_BRIDGE_CTL_VGA) { |
268 | err("Cannot remove display device %s\n", | 271 | ctrl_err(ctrl, |
269 | pci_name(temp)); | 272 | "Cannot remove display device %s\n", |
273 | pci_name(temp)); | ||
270 | pci_dev_put(temp); | 274 | pci_dev_put(temp); |
271 | continue; | 275 | continue; |
272 | } | 276 | } |
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 7d5921b1ee78..419919a87b0f 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h | |||
@@ -46,10 +46,10 @@ | |||
46 | #define PRESENT 1 /* Card in slot */ | 46 | #define PRESENT 1 /* Card in slot */ |
47 | 47 | ||
48 | #define MY_NAME "rpaphp" | 48 | #define MY_NAME "rpaphp" |
49 | extern int debug; | 49 | extern int rpaphp_debug; |
50 | #define dbg(format, arg...) \ | 50 | #define dbg(format, arg...) \ |
51 | do { \ | 51 | do { \ |
52 | if (debug) \ | 52 | if (rpaphp_debug) \ |
53 | printk(KERN_DEBUG "%s: " format, \ | 53 | printk(KERN_DEBUG "%s: " format, \ |
54 | MY_NAME , ## arg); \ | 54 | MY_NAME , ## arg); \ |
55 | } while (0) | 55 | } while (0) |
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 1f84f402acdb..95d02a08fdc7 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c | |||
@@ -37,7 +37,7 @@ | |||
37 | /* and pci_do_scan_bus */ | 37 | /* and pci_do_scan_bus */ |
38 | #include "rpaphp.h" | 38 | #include "rpaphp.h" |
39 | 39 | ||
40 | int debug; | 40 | int rpaphp_debug; |
41 | LIST_HEAD(rpaphp_slot_head); | 41 | LIST_HEAD(rpaphp_slot_head); |
42 | 42 | ||
43 | #define DRIVER_VERSION "0.1" | 43 | #define DRIVER_VERSION "0.1" |
@@ -50,7 +50,7 @@ MODULE_AUTHOR(DRIVER_AUTHOR); | |||
50 | MODULE_DESCRIPTION(DRIVER_DESC); | 50 | MODULE_DESCRIPTION(DRIVER_DESC); |
51 | MODULE_LICENSE("GPL"); | 51 | MODULE_LICENSE("GPL"); |
52 | 52 | ||
53 | module_param(debug, bool, 0644); | 53 | module_param_named(debug, rpaphp_debug, bool, 0644); |
54 | 54 | ||
55 | /** | 55 | /** |
56 | * set_attention_status - set attention LED | 56 | * set_attention_status - set attention LED |
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 5acfd4f3d4cb..513e1e282391 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c | |||
@@ -123,7 +123,7 @@ int rpaphp_enable_slot(struct slot *slot) | |||
123 | slot->state = CONFIGURED; | 123 | slot->state = CONFIGURED; |
124 | } | 124 | } |
125 | 125 | ||
126 | if (debug) { | 126 | if (rpaphp_debug) { |
127 | struct pci_dev *dev; | 127 | struct pci_dev *dev; |
128 | dbg("%s: pci_devs of slot[%s]\n", __func__, slot->dn->full_name); | 128 | dbg("%s: pci_devs of slot[%s]\n", __func__, slot->dn->full_name); |
129 | list_for_each_entry (dev, &bus->devices, bus_list) | 129 | list_for_each_entry (dev, &bus->devices, bus_list) |
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c index 279c940a0039..bf7d6ce9bbb3 100644 --- a/drivers/pci/htirq.c +++ b/drivers/pci/htirq.c | |||
@@ -126,7 +126,8 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update) | |||
126 | cfg->msg.address_hi = 0xffffffff; | 126 | cfg->msg.address_hi = 0xffffffff; |
127 | 127 | ||
128 | irq = create_irq(); | 128 | irq = create_irq(); |
129 | if (irq < 0) { | 129 | |
130 | if (irq <= 0) { | ||
130 | kfree(cfg); | 131 | kfree(cfg); |
131 | return -EBUSY; | 132 | return -EBUSY; |
132 | } | 133 | } |
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index fc5f2dbf5323..8b51e10b7783 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -563,7 +563,7 @@ static int __iommu_flush_context(struct intel_iommu *iommu, | |||
563 | 563 | ||
564 | spin_unlock_irqrestore(&iommu->register_lock, flag); | 564 | spin_unlock_irqrestore(&iommu->register_lock, flag); |
565 | 565 | ||
566 | /* flush context entry will implictly flush write buffer */ | 566 | /* flush context entry will implicitly flush write buffer */ |
567 | return 0; | 567 | return 0; |
568 | } | 568 | } |
569 | 569 | ||
@@ -656,7 +656,7 @@ static int __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did, | |||
656 | if (DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type)) | 656 | if (DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type)) |
657 | pr_debug("IOMMU: tlb flush request %Lx, actual %Lx\n", | 657 | pr_debug("IOMMU: tlb flush request %Lx, actual %Lx\n", |
658 | DMA_TLB_IIRG(type), DMA_TLB_IAIG(val)); | 658 | DMA_TLB_IIRG(type), DMA_TLB_IAIG(val)); |
659 | /* flush context entry will implictly flush write buffer */ | 659 | /* flush iotlb entry will implicitly flush write buffer */ |
660 | return 0; | 660 | return 0; |
661 | } | 661 | } |
662 | 662 | ||
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c index 738d4c89581c..2de5a3238c94 100644 --- a/drivers/pci/intr_remapping.c +++ b/drivers/pci/intr_remapping.c | |||
@@ -1,3 +1,4 @@ | |||
1 | #include <linux/interrupt.h> | ||
1 | #include <linux/dmar.h> | 2 | #include <linux/dmar.h> |
2 | #include <linux/spinlock.h> | 3 | #include <linux/spinlock.h> |
3 | #include <linux/jiffies.h> | 4 | #include <linux/jiffies.h> |
@@ -11,41 +12,64 @@ static struct ioapic_scope ir_ioapic[MAX_IO_APICS]; | |||
11 | static int ir_ioapic_num; | 12 | static int ir_ioapic_num; |
12 | int intr_remapping_enabled; | 13 | int intr_remapping_enabled; |
13 | 14 | ||
14 | static struct { | 15 | struct irq_2_iommu { |
15 | struct intel_iommu *iommu; | 16 | struct intel_iommu *iommu; |
16 | u16 irte_index; | 17 | u16 irte_index; |
17 | u16 sub_handle; | 18 | u16 sub_handle; |
18 | u8 irte_mask; | 19 | u8 irte_mask; |
19 | } irq_2_iommu[NR_IRQS]; | 20 | }; |
21 | |||
22 | static struct irq_2_iommu irq_2_iommuX[NR_IRQS]; | ||
23 | |||
24 | static struct irq_2_iommu *irq_2_iommu(unsigned int irq) | ||
25 | { | ||
26 | return (irq < nr_irqs) ? irq_2_iommuX + irq : NULL; | ||
27 | } | ||
28 | |||
29 | static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq) | ||
30 | { | ||
31 | return irq_2_iommu(irq); | ||
32 | } | ||
20 | 33 | ||
21 | static DEFINE_SPINLOCK(irq_2_ir_lock); | 34 | static DEFINE_SPINLOCK(irq_2_ir_lock); |
22 | 35 | ||
23 | int irq_remapped(int irq) | 36 | static struct irq_2_iommu *valid_irq_2_iommu(unsigned int irq) |
24 | { | 37 | { |
25 | if (irq > NR_IRQS) | 38 | struct irq_2_iommu *irq_iommu; |
26 | return 0; | 39 | |
40 | irq_iommu = irq_2_iommu(irq); | ||
41 | |||
42 | if (!irq_iommu) | ||
43 | return NULL; | ||
44 | |||
45 | if (!irq_iommu->iommu) | ||
46 | return NULL; | ||
27 | 47 | ||
28 | if (!irq_2_iommu[irq].iommu) | 48 | return irq_iommu; |
29 | return 0; | 49 | } |
30 | 50 | ||
31 | return 1; | 51 | int irq_remapped(int irq) |
52 | { | ||
53 | return valid_irq_2_iommu(irq) != NULL; | ||
32 | } | 54 | } |
33 | 55 | ||
34 | int get_irte(int irq, struct irte *entry) | 56 | int get_irte(int irq, struct irte *entry) |
35 | { | 57 | { |
36 | int index; | 58 | int index; |
59 | struct irq_2_iommu *irq_iommu; | ||
37 | 60 | ||
38 | if (!entry || irq > NR_IRQS) | 61 | if (!entry) |
39 | return -1; | 62 | return -1; |
40 | 63 | ||
41 | spin_lock(&irq_2_ir_lock); | 64 | spin_lock(&irq_2_ir_lock); |
42 | if (!irq_2_iommu[irq].iommu) { | 65 | irq_iommu = valid_irq_2_iommu(irq); |
66 | if (!irq_iommu) { | ||
43 | spin_unlock(&irq_2_ir_lock); | 67 | spin_unlock(&irq_2_ir_lock); |
44 | return -1; | 68 | return -1; |
45 | } | 69 | } |
46 | 70 | ||
47 | index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle; | 71 | index = irq_iommu->irte_index + irq_iommu->sub_handle; |
48 | *entry = *(irq_2_iommu[irq].iommu->ir_table->base + index); | 72 | *entry = *(irq_iommu->iommu->ir_table->base + index); |
49 | 73 | ||
50 | spin_unlock(&irq_2_ir_lock); | 74 | spin_unlock(&irq_2_ir_lock); |
51 | return 0; | 75 | return 0; |
@@ -54,6 +78,7 @@ int get_irte(int irq, struct irte *entry) | |||
54 | int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) | 78 | int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) |
55 | { | 79 | { |
56 | struct ir_table *table = iommu->ir_table; | 80 | struct ir_table *table = iommu->ir_table; |
81 | struct irq_2_iommu *irq_iommu; | ||
57 | u16 index, start_index; | 82 | u16 index, start_index; |
58 | unsigned int mask = 0; | 83 | unsigned int mask = 0; |
59 | int i; | 84 | int i; |
@@ -61,6 +86,10 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) | |||
61 | if (!count) | 86 | if (!count) |
62 | return -1; | 87 | return -1; |
63 | 88 | ||
89 | /* protect irq_2_iommu_alloc later */ | ||
90 | if (irq >= nr_irqs) | ||
91 | return -1; | ||
92 | |||
64 | /* | 93 | /* |
65 | * start the IRTE search from index 0. | 94 | * start the IRTE search from index 0. |
66 | */ | 95 | */ |
@@ -100,10 +129,11 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) | |||
100 | for (i = index; i < index + count; i++) | 129 | for (i = index; i < index + count; i++) |
101 | table->base[i].present = 1; | 130 | table->base[i].present = 1; |
102 | 131 | ||
103 | irq_2_iommu[irq].iommu = iommu; | 132 | irq_iommu = irq_2_iommu_alloc(irq); |
104 | irq_2_iommu[irq].irte_index = index; | 133 | irq_iommu->iommu = iommu; |
105 | irq_2_iommu[irq].sub_handle = 0; | 134 | irq_iommu->irte_index = index; |
106 | irq_2_iommu[irq].irte_mask = mask; | 135 | irq_iommu->sub_handle = 0; |
136 | irq_iommu->irte_mask = mask; | ||
107 | 137 | ||
108 | spin_unlock(&irq_2_ir_lock); | 138 | spin_unlock(&irq_2_ir_lock); |
109 | 139 | ||
@@ -124,31 +154,33 @@ static void qi_flush_iec(struct intel_iommu *iommu, int index, int mask) | |||
124 | int map_irq_to_irte_handle(int irq, u16 *sub_handle) | 154 | int map_irq_to_irte_handle(int irq, u16 *sub_handle) |
125 | { | 155 | { |
126 | int index; | 156 | int index; |
157 | struct irq_2_iommu *irq_iommu; | ||
127 | 158 | ||
128 | spin_lock(&irq_2_ir_lock); | 159 | spin_lock(&irq_2_ir_lock); |
129 | if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) { | 160 | irq_iommu = valid_irq_2_iommu(irq); |
161 | if (!irq_iommu) { | ||
130 | spin_unlock(&irq_2_ir_lock); | 162 | spin_unlock(&irq_2_ir_lock); |
131 | return -1; | 163 | return -1; |
132 | } | 164 | } |
133 | 165 | ||
134 | *sub_handle = irq_2_iommu[irq].sub_handle; | 166 | *sub_handle = irq_iommu->sub_handle; |
135 | index = irq_2_iommu[irq].irte_index; | 167 | index = irq_iommu->irte_index; |
136 | spin_unlock(&irq_2_ir_lock); | 168 | spin_unlock(&irq_2_ir_lock); |
137 | return index; | 169 | return index; |
138 | } | 170 | } |
139 | 171 | ||
140 | int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) | 172 | int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) |
141 | { | 173 | { |
174 | struct irq_2_iommu *irq_iommu; | ||
175 | |||
142 | spin_lock(&irq_2_ir_lock); | 176 | spin_lock(&irq_2_ir_lock); |
143 | if (irq >= NR_IRQS || irq_2_iommu[irq].iommu) { | ||
144 | spin_unlock(&irq_2_ir_lock); | ||
145 | return -1; | ||
146 | } | ||
147 | 177 | ||
148 | irq_2_iommu[irq].iommu = iommu; | 178 | irq_iommu = irq_2_iommu_alloc(irq); |
149 | irq_2_iommu[irq].irte_index = index; | 179 | |
150 | irq_2_iommu[irq].sub_handle = subhandle; | 180 | irq_iommu->iommu = iommu; |
151 | irq_2_iommu[irq].irte_mask = 0; | 181 | irq_iommu->irte_index = index; |
182 | irq_iommu->sub_handle = subhandle; | ||
183 | irq_iommu->irte_mask = 0; | ||
152 | 184 | ||
153 | spin_unlock(&irq_2_ir_lock); | 185 | spin_unlock(&irq_2_ir_lock); |
154 | 186 | ||
@@ -157,16 +189,19 @@ int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) | |||
157 | 189 | ||
158 | int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index) | 190 | int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index) |
159 | { | 191 | { |
192 | struct irq_2_iommu *irq_iommu; | ||
193 | |||
160 | spin_lock(&irq_2_ir_lock); | 194 | spin_lock(&irq_2_ir_lock); |
161 | if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) { | 195 | irq_iommu = valid_irq_2_iommu(irq); |
196 | if (!irq_iommu) { | ||
162 | spin_unlock(&irq_2_ir_lock); | 197 | spin_unlock(&irq_2_ir_lock); |
163 | return -1; | 198 | return -1; |
164 | } | 199 | } |
165 | 200 | ||
166 | irq_2_iommu[irq].iommu = NULL; | 201 | irq_iommu->iommu = NULL; |
167 | irq_2_iommu[irq].irte_index = 0; | 202 | irq_iommu->irte_index = 0; |
168 | irq_2_iommu[irq].sub_handle = 0; | 203 | irq_iommu->sub_handle = 0; |
169 | irq_2_iommu[irq].irte_mask = 0; | 204 | irq_2_iommu(irq)->irte_mask = 0; |
170 | 205 | ||
171 | spin_unlock(&irq_2_ir_lock); | 206 | spin_unlock(&irq_2_ir_lock); |
172 | 207 | ||
@@ -178,16 +213,18 @@ int modify_irte(int irq, struct irte *irte_modified) | |||
178 | int index; | 213 | int index; |
179 | struct irte *irte; | 214 | struct irte *irte; |
180 | struct intel_iommu *iommu; | 215 | struct intel_iommu *iommu; |
216 | struct irq_2_iommu *irq_iommu; | ||
181 | 217 | ||
182 | spin_lock(&irq_2_ir_lock); | 218 | spin_lock(&irq_2_ir_lock); |
183 | if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) { | 219 | irq_iommu = valid_irq_2_iommu(irq); |
220 | if (!irq_iommu) { | ||
184 | spin_unlock(&irq_2_ir_lock); | 221 | spin_unlock(&irq_2_ir_lock); |
185 | return -1; | 222 | return -1; |
186 | } | 223 | } |
187 | 224 | ||
188 | iommu = irq_2_iommu[irq].iommu; | 225 | iommu = irq_iommu->iommu; |
189 | 226 | ||
190 | index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle; | 227 | index = irq_iommu->irte_index + irq_iommu->sub_handle; |
191 | irte = &iommu->ir_table->base[index]; | 228 | irte = &iommu->ir_table->base[index]; |
192 | 229 | ||
193 | set_64bit((unsigned long *)irte, irte_modified->low | (1 << 1)); | 230 | set_64bit((unsigned long *)irte, irte_modified->low | (1 << 1)); |
@@ -203,18 +240,20 @@ int flush_irte(int irq) | |||
203 | { | 240 | { |
204 | int index; | 241 | int index; |
205 | struct intel_iommu *iommu; | 242 | struct intel_iommu *iommu; |
243 | struct irq_2_iommu *irq_iommu; | ||
206 | 244 | ||
207 | spin_lock(&irq_2_ir_lock); | 245 | spin_lock(&irq_2_ir_lock); |
208 | if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) { | 246 | irq_iommu = valid_irq_2_iommu(irq); |
247 | if (!irq_iommu) { | ||
209 | spin_unlock(&irq_2_ir_lock); | 248 | spin_unlock(&irq_2_ir_lock); |
210 | return -1; | 249 | return -1; |
211 | } | 250 | } |
212 | 251 | ||
213 | iommu = irq_2_iommu[irq].iommu; | 252 | iommu = irq_iommu->iommu; |
214 | 253 | ||
215 | index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle; | 254 | index = irq_iommu->irte_index + irq_iommu->sub_handle; |
216 | 255 | ||
217 | qi_flush_iec(iommu, index, irq_2_iommu[irq].irte_mask); | 256 | qi_flush_iec(iommu, index, irq_iommu->irte_mask); |
218 | spin_unlock(&irq_2_ir_lock); | 257 | spin_unlock(&irq_2_ir_lock); |
219 | 258 | ||
220 | return 0; | 259 | return 0; |
@@ -246,28 +285,30 @@ int free_irte(int irq) | |||
246 | int index, i; | 285 | int index, i; |
247 | struct irte *irte; | 286 | struct irte *irte; |
248 | struct intel_iommu *iommu; | 287 | struct intel_iommu *iommu; |
288 | struct irq_2_iommu *irq_iommu; | ||
249 | 289 | ||
250 | spin_lock(&irq_2_ir_lock); | 290 | spin_lock(&irq_2_ir_lock); |
251 | if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) { | 291 | irq_iommu = valid_irq_2_iommu(irq); |
292 | if (!irq_iommu) { | ||
252 | spin_unlock(&irq_2_ir_lock); | 293 | spin_unlock(&irq_2_ir_lock); |
253 | return -1; | 294 | return -1; |
254 | } | 295 | } |
255 | 296 | ||
256 | iommu = irq_2_iommu[irq].iommu; | 297 | iommu = irq_iommu->iommu; |
257 | 298 | ||
258 | index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle; | 299 | index = irq_iommu->irte_index + irq_iommu->sub_handle; |
259 | irte = &iommu->ir_table->base[index]; | 300 | irte = &iommu->ir_table->base[index]; |
260 | 301 | ||
261 | if (!irq_2_iommu[irq].sub_handle) { | 302 | if (!irq_iommu->sub_handle) { |
262 | for (i = 0; i < (1 << irq_2_iommu[irq].irte_mask); i++) | 303 | for (i = 0; i < (1 << irq_iommu->irte_mask); i++) |
263 | set_64bit((unsigned long *)irte, 0); | 304 | set_64bit((unsigned long *)irte, 0); |
264 | qi_flush_iec(iommu, index, irq_2_iommu[irq].irte_mask); | 305 | qi_flush_iec(iommu, index, irq_iommu->irte_mask); |
265 | } | 306 | } |
266 | 307 | ||
267 | irq_2_iommu[irq].iommu = NULL; | 308 | irq_iommu->iommu = NULL; |
268 | irq_2_iommu[irq].irte_index = 0; | 309 | irq_iommu->irte_index = 0; |
269 | irq_2_iommu[irq].sub_handle = 0; | 310 | irq_iommu->sub_handle = 0; |
270 | irq_2_iommu[irq].irte_mask = 0; | 311 | irq_iommu->irte_mask = 0; |
271 | 312 | ||
272 | spin_unlock(&irq_2_ir_lock); | 313 | spin_unlock(&irq_2_ir_lock); |
273 | 314 | ||
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 4a10b5624f72..d2812013fd22 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -378,23 +378,21 @@ static int msi_capability_init(struct pci_dev *dev) | |||
378 | entry->msi_attrib.masked = 1; | 378 | entry->msi_attrib.masked = 1; |
379 | entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ | 379 | entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ |
380 | entry->msi_attrib.pos = pos; | 380 | entry->msi_attrib.pos = pos; |
381 | if (is_mask_bit_support(control)) { | 381 | if (entry->msi_attrib.maskbit) { |
382 | entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos, | 382 | entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos, |
383 | is_64bit_address(control)); | 383 | entry->msi_attrib.is_64); |
384 | } | 384 | } |
385 | entry->dev = dev; | 385 | entry->dev = dev; |
386 | if (entry->msi_attrib.maskbit) { | 386 | if (entry->msi_attrib.maskbit) { |
387 | unsigned int maskbits, temp; | 387 | unsigned int maskbits, temp; |
388 | /* All MSIs are unmasked by default, Mask them all */ | 388 | /* All MSIs are unmasked by default, Mask them all */ |
389 | pci_read_config_dword(dev, | 389 | pci_read_config_dword(dev, |
390 | msi_mask_bits_reg(pos, is_64bit_address(control)), | 390 | msi_mask_bits_reg(pos, entry->msi_attrib.is_64), |
391 | &maskbits); | 391 | &maskbits); |
392 | temp = (1 << multi_msi_capable(control)); | 392 | temp = (1 << multi_msi_capable(control)); |
393 | temp = ((temp - 1) & ~temp); | 393 | temp = ((temp - 1) & ~temp); |
394 | maskbits |= temp; | 394 | maskbits |= temp; |
395 | pci_write_config_dword(dev, | 395 | pci_write_config_dword(dev, entry->msi_attrib.is_64, maskbits); |
396 | msi_mask_bits_reg(pos, is_64bit_address(control)), | ||
397 | maskbits); | ||
398 | entry->msi_attrib.maskbits_mask = temp; | 396 | entry->msi_attrib.maskbits_mask = temp; |
399 | } | 397 | } |
400 | list_add_tail(&entry->list, &dev->msi_list); | 398 | list_add_tail(&entry->list, &dev->msi_list); |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index a13f53486114..b4cdd690ae71 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -43,18 +43,32 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count) | |||
43 | { | 43 | { |
44 | struct pci_dynid *dynid; | 44 | struct pci_dynid *dynid; |
45 | struct pci_driver *pdrv = to_pci_driver(driver); | 45 | struct pci_driver *pdrv = to_pci_driver(driver); |
46 | const struct pci_device_id *ids = pdrv->id_table; | ||
46 | __u32 vendor, device, subvendor=PCI_ANY_ID, | 47 | __u32 vendor, device, subvendor=PCI_ANY_ID, |
47 | subdevice=PCI_ANY_ID, class=0, class_mask=0; | 48 | subdevice=PCI_ANY_ID, class=0, class_mask=0; |
48 | unsigned long driver_data=0; | 49 | unsigned long driver_data=0; |
49 | int fields=0; | 50 | int fields=0; |
50 | int retval = 0; | 51 | int retval; |
51 | 52 | ||
52 | fields = sscanf(buf, "%x %x %x %x %x %x %lux", | 53 | fields = sscanf(buf, "%x %x %x %x %x %x %lx", |
53 | &vendor, &device, &subvendor, &subdevice, | 54 | &vendor, &device, &subvendor, &subdevice, |
54 | &class, &class_mask, &driver_data); | 55 | &class, &class_mask, &driver_data); |
55 | if (fields < 2) | 56 | if (fields < 2) |
56 | return -EINVAL; | 57 | return -EINVAL; |
57 | 58 | ||
59 | /* Only accept driver_data values that match an existing id_table | ||
60 | entry */ | ||
61 | retval = -EINVAL; | ||
62 | while (ids->vendor || ids->subvendor || ids->class_mask) { | ||
63 | if (driver_data == ids->driver_data) { | ||
64 | retval = 0; | ||
65 | break; | ||
66 | } | ||
67 | ids++; | ||
68 | } | ||
69 | if (retval) /* No match */ | ||
70 | return retval; | ||
71 | |||
58 | dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); | 72 | dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); |
59 | if (!dynid) | 73 | if (!dynid) |
60 | return -ENOMEM; | 74 | return -ENOMEM; |
@@ -65,8 +79,7 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count) | |||
65 | dynid->id.subdevice = subdevice; | 79 | dynid->id.subdevice = subdevice; |
66 | dynid->id.class = class; | 80 | dynid->id.class = class; |
67 | dynid->id.class_mask = class_mask; | 81 | dynid->id.class_mask = class_mask; |
68 | dynid->id.driver_data = pdrv->dynids.use_driver_data ? | 82 | dynid->id.driver_data = driver_data; |
69 | driver_data : 0UL; | ||
70 | 83 | ||
71 | spin_lock(&pdrv->dynids.lock); | 84 | spin_lock(&pdrv->dynids.lock); |
72 | list_add_tail(&dynid->node, &pdrv->dynids.list); | 85 | list_add_tail(&dynid->node, &pdrv->dynids.list); |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 77baff022f71..110022d78689 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -423,7 +423,7 @@ pci_write_vpd(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
423 | * Reads 1, 2, or 4 bytes from legacy I/O port space using an arch specific | 423 | * Reads 1, 2, or 4 bytes from legacy I/O port space using an arch specific |
424 | * callback routine (pci_legacy_read). | 424 | * callback routine (pci_legacy_read). |
425 | */ | 425 | */ |
426 | ssize_t | 426 | static ssize_t |
427 | pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, | 427 | pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, |
428 | char *buf, loff_t off, size_t count) | 428 | char *buf, loff_t off, size_t count) |
429 | { | 429 | { |
@@ -448,7 +448,7 @@ pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
448 | * Writes 1, 2, or 4 bytes from legacy I/O port space using an arch specific | 448 | * Writes 1, 2, or 4 bytes from legacy I/O port space using an arch specific |
449 | * callback routine (pci_legacy_write). | 449 | * callback routine (pci_legacy_write). |
450 | */ | 450 | */ |
451 | ssize_t | 451 | static ssize_t |
452 | pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, | 452 | pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, |
453 | char *buf, loff_t off, size_t count) | 453 | char *buf, loff_t off, size_t count) |
454 | { | 454 | { |
@@ -468,11 +468,11 @@ pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
468 | * @attr: struct bin_attribute for this file | 468 | * @attr: struct bin_attribute for this file |
469 | * @vma: struct vm_area_struct passed to mmap | 469 | * @vma: struct vm_area_struct passed to mmap |
470 | * | 470 | * |
471 | * Uses an arch specific callback, pci_mmap_legacy_page_range, to mmap | 471 | * Uses an arch specific callback, pci_mmap_legacy_mem_page_range, to mmap |
472 | * legacy memory space (first meg of bus space) into application virtual | 472 | * legacy memory space (first meg of bus space) into application virtual |
473 | * memory space. | 473 | * memory space. |
474 | */ | 474 | */ |
475 | int | 475 | static int |
476 | pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr, | 476 | pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr, |
477 | struct vm_area_struct *vma) | 477 | struct vm_area_struct *vma) |
478 | { | 478 | { |
@@ -480,7 +480,90 @@ pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr, | |||
480 | struct device, | 480 | struct device, |
481 | kobj)); | 481 | kobj)); |
482 | 482 | ||
483 | return pci_mmap_legacy_page_range(bus, vma); | 483 | return pci_mmap_legacy_page_range(bus, vma, pci_mmap_mem); |
484 | } | ||
485 | |||
486 | /** | ||
487 | * pci_mmap_legacy_io - map legacy PCI IO into user memory space | ||
488 | * @kobj: kobject corresponding to device to be mapped | ||
489 | * @attr: struct bin_attribute for this file | ||
490 | * @vma: struct vm_area_struct passed to mmap | ||
491 | * | ||
492 | * Uses an arch specific callback, pci_mmap_legacy_io_page_range, to mmap | ||
493 | * legacy IO space (first meg of bus space) into application virtual | ||
494 | * memory space. Returns -ENOSYS if the operation isn't supported | ||
495 | */ | ||
496 | static int | ||
497 | pci_mmap_legacy_io(struct kobject *kobj, struct bin_attribute *attr, | ||
498 | struct vm_area_struct *vma) | ||
499 | { | ||
500 | struct pci_bus *bus = to_pci_bus(container_of(kobj, | ||
501 | struct device, | ||
502 | kobj)); | ||
503 | |||
504 | return pci_mmap_legacy_page_range(bus, vma, pci_mmap_io); | ||
505 | } | ||
506 | |||
507 | /** | ||
508 | * pci_create_legacy_files - create legacy I/O port and memory files | ||
509 | * @b: bus to create files under | ||
510 | * | ||
511 | * Some platforms allow access to legacy I/O port and ISA memory space on | ||
512 | * a per-bus basis. This routine creates the files and ties them into | ||
513 | * their associated read, write and mmap files from pci-sysfs.c | ||
514 | * | ||
515 | * On error unwind, but don't propogate the error to the caller | ||
516 | * as it is ok to set up the PCI bus without these files. | ||
517 | */ | ||
518 | void pci_create_legacy_files(struct pci_bus *b) | ||
519 | { | ||
520 | int error; | ||
521 | |||
522 | b->legacy_io = kzalloc(sizeof(struct bin_attribute) * 2, | ||
523 | GFP_ATOMIC); | ||
524 | if (!b->legacy_io) | ||
525 | goto kzalloc_err; | ||
526 | |||
527 | b->legacy_io->attr.name = "legacy_io"; | ||
528 | b->legacy_io->size = 0xffff; | ||
529 | b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; | ||
530 | b->legacy_io->read = pci_read_legacy_io; | ||
531 | b->legacy_io->write = pci_write_legacy_io; | ||
532 | b->legacy_io->mmap = pci_mmap_legacy_io; | ||
533 | error = device_create_bin_file(&b->dev, b->legacy_io); | ||
534 | if (error) | ||
535 | goto legacy_io_err; | ||
536 | |||
537 | /* Allocated above after the legacy_io struct */ | ||
538 | b->legacy_mem = b->legacy_io + 1; | ||
539 | b->legacy_mem->attr.name = "legacy_mem"; | ||
540 | b->legacy_mem->size = 1024*1024; | ||
541 | b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; | ||
542 | b->legacy_mem->mmap = pci_mmap_legacy_mem; | ||
543 | error = device_create_bin_file(&b->dev, b->legacy_mem); | ||
544 | if (error) | ||
545 | goto legacy_mem_err; | ||
546 | |||
547 | return; | ||
548 | |||
549 | legacy_mem_err: | ||
550 | device_remove_bin_file(&b->dev, b->legacy_io); | ||
551 | legacy_io_err: | ||
552 | kfree(b->legacy_io); | ||
553 | b->legacy_io = NULL; | ||
554 | kzalloc_err: | ||
555 | printk(KERN_WARNING "pci: warning: could not create legacy I/O port " | ||
556 | "and ISA memory resources to sysfs\n"); | ||
557 | return; | ||
558 | } | ||
559 | |||
560 | void pci_remove_legacy_files(struct pci_bus *b) | ||
561 | { | ||
562 | if (b->legacy_io) { | ||
563 | device_remove_bin_file(&b->dev, b->legacy_io); | ||
564 | device_remove_bin_file(&b->dev, b->legacy_mem); | ||
565 | kfree(b->legacy_io); /* both are allocated here */ | ||
566 | } | ||
484 | } | 567 | } |
485 | #endif /* HAVE_PCI_LEGACY */ | 568 | #endif /* HAVE_PCI_LEGACY */ |
486 | 569 | ||
@@ -715,7 +798,7 @@ static struct bin_attribute pci_config_attr = { | |||
715 | .name = "config", | 798 | .name = "config", |
716 | .mode = S_IRUGO | S_IWUSR, | 799 | .mode = S_IRUGO | S_IWUSR, |
717 | }, | 800 | }, |
718 | .size = 256, | 801 | .size = PCI_CFG_SPACE_SIZE, |
719 | .read = pci_read_config, | 802 | .read = pci_read_config, |
720 | .write = pci_write_config, | 803 | .write = pci_write_config, |
721 | }; | 804 | }; |
@@ -725,7 +808,7 @@ static struct bin_attribute pcie_config_attr = { | |||
725 | .name = "config", | 808 | .name = "config", |
726 | .mode = S_IRUGO | S_IWUSR, | 809 | .mode = S_IRUGO | S_IWUSR, |
727 | }, | 810 | }, |
728 | .size = 4096, | 811 | .size = PCI_CFG_SPACE_EXP_SIZE, |
729 | .read = pci_read_config, | 812 | .read = pci_read_config, |
730 | .write = pci_write_config, | 813 | .write = pci_write_config, |
731 | }; | 814 | }; |
@@ -735,86 +818,103 @@ int __attribute__ ((weak)) pcibios_add_platform_entries(struct pci_dev *dev) | |||
735 | return 0; | 818 | return 0; |
736 | } | 819 | } |
737 | 820 | ||
821 | static int pci_create_capabilities_sysfs(struct pci_dev *dev) | ||
822 | { | ||
823 | int retval; | ||
824 | struct bin_attribute *attr; | ||
825 | |||
826 | /* If the device has VPD, try to expose it in sysfs. */ | ||
827 | if (dev->vpd) { | ||
828 | attr = kzalloc(sizeof(*attr), GFP_ATOMIC); | ||
829 | if (!attr) | ||
830 | return -ENOMEM; | ||
831 | |||
832 | attr->size = dev->vpd->len; | ||
833 | attr->attr.name = "vpd"; | ||
834 | attr->attr.mode = S_IRUSR | S_IWUSR; | ||
835 | attr->read = pci_read_vpd; | ||
836 | attr->write = pci_write_vpd; | ||
837 | retval = sysfs_create_bin_file(&dev->dev.kobj, attr); | ||
838 | if (retval) { | ||
839 | kfree(dev->vpd->attr); | ||
840 | return retval; | ||
841 | } | ||
842 | dev->vpd->attr = attr; | ||
843 | } | ||
844 | |||
845 | /* Active State Power Management */ | ||
846 | pcie_aspm_create_sysfs_dev_files(dev); | ||
847 | |||
848 | return 0; | ||
849 | } | ||
850 | |||
738 | int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) | 851 | int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) |
739 | { | 852 | { |
740 | struct bin_attribute *attr = NULL; | ||
741 | int retval; | 853 | int retval; |
854 | int rom_size = 0; | ||
855 | struct bin_attribute *attr; | ||
742 | 856 | ||
743 | if (!sysfs_initialized) | 857 | if (!sysfs_initialized) |
744 | return -EACCES; | 858 | return -EACCES; |
745 | 859 | ||
746 | if (pdev->cfg_size < 4096) | 860 | if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE) |
747 | retval = sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr); | 861 | retval = sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr); |
748 | else | 862 | else |
749 | retval = sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr); | 863 | retval = sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr); |
750 | if (retval) | 864 | if (retval) |
751 | goto err; | 865 | goto err; |
752 | 866 | ||
753 | /* If the device has VPD, try to expose it in sysfs. */ | ||
754 | if (pdev->vpd) { | ||
755 | attr = kzalloc(sizeof(*attr), GFP_ATOMIC); | ||
756 | if (attr) { | ||
757 | pdev->vpd->attr = attr; | ||
758 | attr->size = pdev->vpd->len; | ||
759 | attr->attr.name = "vpd"; | ||
760 | attr->attr.mode = S_IRUSR | S_IWUSR; | ||
761 | attr->read = pci_read_vpd; | ||
762 | attr->write = pci_write_vpd; | ||
763 | retval = sysfs_create_bin_file(&pdev->dev.kobj, attr); | ||
764 | if (retval) | ||
765 | goto err_vpd; | ||
766 | } else { | ||
767 | retval = -ENOMEM; | ||
768 | goto err_config_file; | ||
769 | } | ||
770 | } | ||
771 | |||
772 | retval = pci_create_resource_files(pdev); | 867 | retval = pci_create_resource_files(pdev); |
773 | if (retval) | 868 | if (retval) |
774 | goto err_vpd_file; | 869 | goto err_config_file; |
870 | |||
871 | if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) | ||
872 | rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE); | ||
873 | else if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW) | ||
874 | rom_size = 0x20000; | ||
775 | 875 | ||
776 | /* If the device has a ROM, try to expose it in sysfs. */ | 876 | /* If the device has a ROM, try to expose it in sysfs. */ |
777 | if (pci_resource_len(pdev, PCI_ROM_RESOURCE) || | 877 | if (rom_size) { |
778 | (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)) { | ||
779 | attr = kzalloc(sizeof(*attr), GFP_ATOMIC); | 878 | attr = kzalloc(sizeof(*attr), GFP_ATOMIC); |
780 | if (attr) { | 879 | if (!attr) { |
781 | pdev->rom_attr = attr; | ||
782 | attr->size = pci_resource_len(pdev, PCI_ROM_RESOURCE); | ||
783 | attr->attr.name = "rom"; | ||
784 | attr->attr.mode = S_IRUSR; | ||
785 | attr->read = pci_read_rom; | ||
786 | attr->write = pci_write_rom; | ||
787 | retval = sysfs_create_bin_file(&pdev->dev.kobj, attr); | ||
788 | if (retval) | ||
789 | goto err_rom; | ||
790 | } else { | ||
791 | retval = -ENOMEM; | 880 | retval = -ENOMEM; |
792 | goto err_resource_files; | 881 | goto err_resource_files; |
793 | } | 882 | } |
883 | attr->size = rom_size; | ||
884 | attr->attr.name = "rom"; | ||
885 | attr->attr.mode = S_IRUSR; | ||
886 | attr->read = pci_read_rom; | ||
887 | attr->write = pci_write_rom; | ||
888 | retval = sysfs_create_bin_file(&pdev->dev.kobj, attr); | ||
889 | if (retval) { | ||
890 | kfree(attr); | ||
891 | goto err_resource_files; | ||
892 | } | ||
893 | pdev->rom_attr = attr; | ||
794 | } | 894 | } |
895 | |||
795 | /* add platform-specific attributes */ | 896 | /* add platform-specific attributes */ |
796 | if (pcibios_add_platform_entries(pdev)) | 897 | retval = pcibios_add_platform_entries(pdev); |
898 | if (retval) | ||
797 | goto err_rom_file; | 899 | goto err_rom_file; |
798 | 900 | ||
799 | pcie_aspm_create_sysfs_dev_files(pdev); | 901 | /* add sysfs entries for various capabilities */ |
902 | retval = pci_create_capabilities_sysfs(pdev); | ||
903 | if (retval) | ||
904 | goto err_rom_file; | ||
800 | 905 | ||
801 | return 0; | 906 | return 0; |
802 | 907 | ||
803 | err_rom_file: | 908 | err_rom_file: |
804 | if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) | 909 | if (rom_size) { |
805 | sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr); | 910 | sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr); |
806 | err_rom: | 911 | kfree(pdev->rom_attr); |
807 | kfree(pdev->rom_attr); | 912 | pdev->rom_attr = NULL; |
913 | } | ||
808 | err_resource_files: | 914 | err_resource_files: |
809 | pci_remove_resource_files(pdev); | 915 | pci_remove_resource_files(pdev); |
810 | err_vpd_file: | ||
811 | if (pdev->vpd) { | ||
812 | sysfs_remove_bin_file(&pdev->dev.kobj, pdev->vpd->attr); | ||
813 | err_vpd: | ||
814 | kfree(pdev->vpd->attr); | ||
815 | } | ||
816 | err_config_file: | 916 | err_config_file: |
817 | if (pdev->cfg_size < 4096) | 917 | if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE) |
818 | sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr); | 918 | sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr); |
819 | else | 919 | else |
820 | sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr); | 920 | sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr); |
@@ -822,6 +922,16 @@ err: | |||
822 | return retval; | 922 | return retval; |
823 | } | 923 | } |
824 | 924 | ||
925 | static void pci_remove_capabilities_sysfs(struct pci_dev *dev) | ||
926 | { | ||
927 | if (dev->vpd && dev->vpd->attr) { | ||
928 | sysfs_remove_bin_file(&dev->dev.kobj, dev->vpd->attr); | ||
929 | kfree(dev->vpd->attr); | ||
930 | } | ||
931 | |||
932 | pcie_aspm_remove_sysfs_dev_files(dev); | ||
933 | } | ||
934 | |||
825 | /** | 935 | /** |
826 | * pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files | 936 | * pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files |
827 | * @pdev: device whose entries we should free | 937 | * @pdev: device whose entries we should free |
@@ -830,27 +940,28 @@ err: | |||
830 | */ | 940 | */ |
831 | void pci_remove_sysfs_dev_files(struct pci_dev *pdev) | 941 | void pci_remove_sysfs_dev_files(struct pci_dev *pdev) |
832 | { | 942 | { |
943 | int rom_size = 0; | ||
944 | |||
833 | if (!sysfs_initialized) | 945 | if (!sysfs_initialized) |
834 | return; | 946 | return; |
835 | 947 | ||
836 | pcie_aspm_remove_sysfs_dev_files(pdev); | 948 | pci_remove_capabilities_sysfs(pdev); |
837 | 949 | ||
838 | if (pdev->vpd) { | 950 | if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE) |
839 | sysfs_remove_bin_file(&pdev->dev.kobj, pdev->vpd->attr); | ||
840 | kfree(pdev->vpd->attr); | ||
841 | } | ||
842 | if (pdev->cfg_size < 4096) | ||
843 | sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr); | 951 | sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr); |
844 | else | 952 | else |
845 | sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr); | 953 | sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr); |
846 | 954 | ||
847 | pci_remove_resource_files(pdev); | 955 | pci_remove_resource_files(pdev); |
848 | 956 | ||
849 | if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) { | 957 | if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) |
850 | if (pdev->rom_attr) { | 958 | rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE); |
851 | sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr); | 959 | else if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW) |
852 | kfree(pdev->rom_attr); | 960 | rom_size = 0x20000; |
853 | } | 961 | |
962 | if (rom_size && pdev->rom_attr) { | ||
963 | sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr); | ||
964 | kfree(pdev->rom_attr); | ||
854 | } | 965 | } |
855 | } | 966 | } |
856 | 967 | ||
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index c9884bba22de..4db261e13e69 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -213,10 +213,13 @@ int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap) | |||
213 | int pci_find_ext_capability(struct pci_dev *dev, int cap) | 213 | int pci_find_ext_capability(struct pci_dev *dev, int cap) |
214 | { | 214 | { |
215 | u32 header; | 215 | u32 header; |
216 | int ttl = 480; /* 3840 bytes, minimum 8 bytes per capability */ | 216 | int ttl; |
217 | int pos = 0x100; | 217 | int pos = PCI_CFG_SPACE_SIZE; |
218 | 218 | ||
219 | if (dev->cfg_size <= 256) | 219 | /* minimum 8 bytes per capability */ |
220 | ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8; | ||
221 | |||
222 | if (dev->cfg_size <= PCI_CFG_SPACE_SIZE) | ||
220 | return 0; | 223 | return 0; |
221 | 224 | ||
222 | if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL) | 225 | if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL) |
@@ -234,7 +237,7 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap) | |||
234 | return pos; | 237 | return pos; |
235 | 238 | ||
236 | pos = PCI_EXT_CAP_NEXT(header); | 239 | pos = PCI_EXT_CAP_NEXT(header); |
237 | if (pos < 0x100) | 240 | if (pos < PCI_CFG_SPACE_SIZE) |
238 | break; | 241 | break; |
239 | 242 | ||
240 | if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL) | 243 | if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL) |
@@ -1127,6 +1130,27 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) | |||
1127 | } | 1130 | } |
1128 | 1131 | ||
1129 | /** | 1132 | /** |
1133 | * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold | ||
1134 | * @dev: PCI device to prepare | ||
1135 | * @enable: True to enable wake-up event generation; false to disable | ||
1136 | * | ||
1137 | * Many drivers want the device to wake up the system from D3_hot or D3_cold | ||
1138 | * and this function allows them to set that up cleanly - pci_enable_wake() | ||
1139 | * should not be called twice in a row to enable wake-up due to PCI PM vs ACPI | ||
1140 | * ordering constraints. | ||
1141 | * | ||
1142 | * This function only returns error code if the device is not capable of | ||
1143 | * generating PME# from both D3_hot and D3_cold, and the platform is unable to | ||
1144 | * enable wake-up power for it. | ||
1145 | */ | ||
1146 | int pci_wake_from_d3(struct pci_dev *dev, bool enable) | ||
1147 | { | ||
1148 | return pci_pme_capable(dev, PCI_D3cold) ? | ||
1149 | pci_enable_wake(dev, PCI_D3cold, enable) : | ||
1150 | pci_enable_wake(dev, PCI_D3hot, enable); | ||
1151 | } | ||
1152 | |||
1153 | /** | ||
1130 | * pci_target_state - find an appropriate low power state for a given PCI dev | 1154 | * pci_target_state - find an appropriate low power state for a given PCI dev |
1131 | * @dev: PCI device | 1155 | * @dev: PCI device |
1132 | * | 1156 | * |
@@ -1242,25 +1266,25 @@ void pci_pm_init(struct pci_dev *dev) | |||
1242 | dev->d1_support = false; | 1266 | dev->d1_support = false; |
1243 | dev->d2_support = false; | 1267 | dev->d2_support = false; |
1244 | if (!pci_no_d1d2(dev)) { | 1268 | if (!pci_no_d1d2(dev)) { |
1245 | if (pmc & PCI_PM_CAP_D1) { | 1269 | if (pmc & PCI_PM_CAP_D1) |
1246 | dev_printk(KERN_DEBUG, &dev->dev, "supports D1\n"); | ||
1247 | dev->d1_support = true; | 1270 | dev->d1_support = true; |
1248 | } | 1271 | if (pmc & PCI_PM_CAP_D2) |
1249 | if (pmc & PCI_PM_CAP_D2) { | ||
1250 | dev_printk(KERN_DEBUG, &dev->dev, "supports D2\n"); | ||
1251 | dev->d2_support = true; | 1272 | dev->d2_support = true; |
1252 | } | 1273 | |
1274 | if (dev->d1_support || dev->d2_support) | ||
1275 | dev_printk(KERN_DEBUG, &dev->dev, "supports%s%s\n", | ||
1276 | dev->d1_support ? " D1" : "", | ||
1277 | dev->d2_support ? " D2" : ""); | ||
1253 | } | 1278 | } |
1254 | 1279 | ||
1255 | pmc &= PCI_PM_CAP_PME_MASK; | 1280 | pmc &= PCI_PM_CAP_PME_MASK; |
1256 | if (pmc) { | 1281 | if (pmc) { |
1257 | dev_printk(KERN_INFO, &dev->dev, | 1282 | dev_info(&dev->dev, "PME# supported from%s%s%s%s%s\n", |
1258 | "PME# supported from%s%s%s%s%s\n", | 1283 | (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "", |
1259 | (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "", | 1284 | (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "", |
1260 | (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "", | 1285 | (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "", |
1261 | (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "", | 1286 | (pmc & PCI_PM_CAP_PME_D3) ? " D3hot" : "", |
1262 | (pmc & PCI_PM_CAP_PME_D3) ? " D3hot" : "", | 1287 | (pmc & PCI_PM_CAP_PME_D3cold) ? " D3cold" : ""); |
1263 | (pmc & PCI_PM_CAP_PME_D3cold) ? " D3cold" : ""); | ||
1264 | dev->pme_support = pmc >> PCI_PM_CAP_PME_SHIFT; | 1288 | dev->pme_support = pmc >> PCI_PM_CAP_PME_SHIFT; |
1265 | /* | 1289 | /* |
1266 | * Make device's PM flags reflect the wake-up capability, but | 1290 | * Make device's PM flags reflect the wake-up capability, but |
@@ -1275,6 +1299,38 @@ void pci_pm_init(struct pci_dev *dev) | |||
1275 | } | 1299 | } |
1276 | } | 1300 | } |
1277 | 1301 | ||
1302 | /** | ||
1303 | * pci_enable_ari - enable ARI forwarding if hardware support it | ||
1304 | * @dev: the PCI device | ||
1305 | */ | ||
1306 | void pci_enable_ari(struct pci_dev *dev) | ||
1307 | { | ||
1308 | int pos; | ||
1309 | u32 cap; | ||
1310 | u16 ctrl; | ||
1311 | |||
1312 | if (!dev->is_pcie) | ||
1313 | return; | ||
1314 | |||
1315 | if (dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && | ||
1316 | dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) | ||
1317 | return; | ||
1318 | |||
1319 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | ||
1320 | if (!pos) | ||
1321 | return; | ||
1322 | |||
1323 | pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap); | ||
1324 | if (!(cap & PCI_EXP_DEVCAP2_ARI)) | ||
1325 | return; | ||
1326 | |||
1327 | pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl); | ||
1328 | ctrl |= PCI_EXP_DEVCTL2_ARI; | ||
1329 | pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl); | ||
1330 | |||
1331 | dev->ari_enabled = 1; | ||
1332 | } | ||
1333 | |||
1278 | int | 1334 | int |
1279 | pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge) | 1335 | pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge) |
1280 | { | 1336 | { |
@@ -1358,11 +1414,10 @@ int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) | |||
1358 | return 0; | 1414 | return 0; |
1359 | 1415 | ||
1360 | err_out: | 1416 | err_out: |
1361 | dev_warn(&pdev->dev, "BAR %d: can't reserve %s region [%#llx-%#llx]\n", | 1417 | dev_warn(&pdev->dev, "BAR %d: can't reserve %s region %pR\n", |
1362 | bar, | 1418 | bar, |
1363 | pci_resource_flags(pdev, bar) & IORESOURCE_IO ? "I/O" : "mem", | 1419 | pci_resource_flags(pdev, bar) & IORESOURCE_IO ? "I/O" : "mem", |
1364 | (unsigned long long)pci_resource_start(pdev, bar), | 1420 | &pdev->resource[bar]); |
1365 | (unsigned long long)pci_resource_end(pdev, bar)); | ||
1366 | return -EBUSY; | 1421 | return -EBUSY; |
1367 | } | 1422 | } |
1368 | 1423 | ||
@@ -1943,6 +1998,7 @@ EXPORT_SYMBOL(pci_restore_state); | |||
1943 | EXPORT_SYMBOL(pci_pme_capable); | 1998 | EXPORT_SYMBOL(pci_pme_capable); |
1944 | EXPORT_SYMBOL(pci_pme_active); | 1999 | EXPORT_SYMBOL(pci_pme_active); |
1945 | EXPORT_SYMBOL(pci_enable_wake); | 2000 | EXPORT_SYMBOL(pci_enable_wake); |
2001 | EXPORT_SYMBOL(pci_wake_from_d3); | ||
1946 | EXPORT_SYMBOL(pci_target_state); | 2002 | EXPORT_SYMBOL(pci_target_state); |
1947 | EXPORT_SYMBOL(pci_prepare_to_sleep); | 2003 | EXPORT_SYMBOL(pci_prepare_to_sleep); |
1948 | EXPORT_SYMBOL(pci_back_from_sleep); | 2004 | EXPORT_SYMBOL(pci_back_from_sleep); |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index d807cd786f20..b205ab866a1d 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -1,3 +1,9 @@ | |||
1 | #ifndef DRIVERS_PCI_H | ||
2 | #define DRIVERS_PCI_H | ||
3 | |||
4 | #define PCI_CFG_SPACE_SIZE 256 | ||
5 | #define PCI_CFG_SPACE_EXP_SIZE 4096 | ||
6 | |||
1 | /* Functions internal to the PCI core code */ | 7 | /* Functions internal to the PCI core code */ |
2 | 8 | ||
3 | extern int pci_uevent(struct device *dev, struct kobj_uevent_env *env); | 9 | extern int pci_uevent(struct device *dev, struct kobj_uevent_env *env); |
@@ -76,7 +82,13 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; } | |||
76 | /* Functions for PCI Hotplug drivers to use */ | 82 | /* Functions for PCI Hotplug drivers to use */ |
77 | extern unsigned int pci_do_scan_bus(struct pci_bus *bus); | 83 | extern unsigned int pci_do_scan_bus(struct pci_bus *bus); |
78 | 84 | ||
85 | #ifdef HAVE_PCI_LEGACY | ||
86 | extern void pci_create_legacy_files(struct pci_bus *bus); | ||
79 | extern void pci_remove_legacy_files(struct pci_bus *bus); | 87 | extern void pci_remove_legacy_files(struct pci_bus *bus); |
88 | #else | ||
89 | static inline void pci_create_legacy_files(struct pci_bus *bus) { return; } | ||
90 | static inline void pci_remove_legacy_files(struct pci_bus *bus) { return; } | ||
91 | #endif | ||
80 | 92 | ||
81 | /* Lock for read/write access to pci device and bus lists */ | 93 | /* Lock for read/write access to pci device and bus lists */ |
82 | extern struct rw_semaphore pci_bus_sem; | 94 | extern struct rw_semaphore pci_bus_sem; |
@@ -109,6 +121,7 @@ static inline int pci_no_d1d2(struct pci_dev *dev) | |||
109 | extern int pcie_mch_quirk; | 121 | extern int pcie_mch_quirk; |
110 | extern struct device_attribute pci_dev_attrs[]; | 122 | extern struct device_attribute pci_dev_attrs[]; |
111 | extern struct device_attribute dev_attr_cpuaffinity; | 123 | extern struct device_attribute dev_attr_cpuaffinity; |
124 | extern struct device_attribute dev_attr_cpulistaffinity; | ||
112 | 125 | ||
113 | /** | 126 | /** |
114 | * pci_match_one_device - Tell if a PCI device structure has a matching | 127 | * pci_match_one_device - Tell if a PCI device structure has a matching |
@@ -144,3 +157,16 @@ struct pci_slot_attribute { | |||
144 | }; | 157 | }; |
145 | #define to_pci_slot_attr(s) container_of(s, struct pci_slot_attribute, attr) | 158 | #define to_pci_slot_attr(s) container_of(s, struct pci_slot_attribute, attr) |
146 | 159 | ||
160 | extern void pci_enable_ari(struct pci_dev *dev); | ||
161 | /** | ||
162 | * pci_ari_enabled - query ARI forwarding status | ||
163 | * @dev: the PCI device | ||
164 | * | ||
165 | * Returns 1 if ARI forwarding is enabled, or 0 if not enabled; | ||
166 | */ | ||
167 | static inline int pci_ari_enabled(struct pci_dev *dev) | ||
168 | { | ||
169 | return dev->ari_enabled; | ||
170 | } | ||
171 | |||
172 | #endif /* DRIVERS_PCI_H */ | ||
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index 77036f46acfe..e390707661dd 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c | |||
@@ -105,7 +105,7 @@ static irqreturn_t aer_irq(int irq, void *context) | |||
105 | unsigned long flags; | 105 | unsigned long flags; |
106 | int pos; | 106 | int pos; |
107 | 107 | ||
108 | pos = pci_find_aer_capability(pdev->port); | 108 | pos = pci_find_ext_capability(pdev->port, PCI_EXT_CAP_ID_ERR); |
109 | /* | 109 | /* |
110 | * Must lock access to Root Error Status Reg, Root Error ID Reg, | 110 | * Must lock access to Root Error Status Reg, Root Error ID Reg, |
111 | * and Root error producer/consumer index | 111 | * and Root error producer/consumer index |
@@ -252,7 +252,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev) | |||
252 | u32 status; | 252 | u32 status; |
253 | int pos; | 253 | int pos; |
254 | 254 | ||
255 | pos = pci_find_aer_capability(dev); | 255 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
256 | 256 | ||
257 | /* Disable Root's interrupt in response to error messages */ | 257 | /* Disable Root's interrupt in response to error messages */ |
258 | pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, 0); | 258 | pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, 0); |
@@ -316,7 +316,7 @@ static void aer_error_resume(struct pci_dev *dev) | |||
316 | pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, reg16); | 316 | pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, reg16); |
317 | 317 | ||
318 | /* Clean AER Root Error Status */ | 318 | /* Clean AER Root Error Status */ |
319 | pos = pci_find_aer_capability(dev); | 319 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
320 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); | 320 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); |
321 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask); | 321 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask); |
322 | if (dev->error_state == pci_channel_io_normal) | 322 | if (dev->error_state == pci_channel_io_normal) |
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index ee5e7b5176d0..dfc63d01f20a 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
@@ -28,41 +28,15 @@ | |||
28 | static int forceload; | 28 | static int forceload; |
29 | module_param(forceload, bool, 0); | 29 | module_param(forceload, bool, 0); |
30 | 30 | ||
31 | #define PCI_CFG_SPACE_SIZE (0x100) | ||
32 | int pci_find_aer_capability(struct pci_dev *dev) | ||
33 | { | ||
34 | int pos; | ||
35 | u32 reg32 = 0; | ||
36 | |||
37 | /* Check if it's a pci-express device */ | ||
38 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | ||
39 | if (!pos) | ||
40 | return 0; | ||
41 | |||
42 | /* Check if it supports pci-express AER */ | ||
43 | pos = PCI_CFG_SPACE_SIZE; | ||
44 | while (pos) { | ||
45 | if (pci_read_config_dword(dev, pos, ®32)) | ||
46 | return 0; | ||
47 | |||
48 | /* some broken boards return ~0 */ | ||
49 | if (reg32 == 0xffffffff) | ||
50 | return 0; | ||
51 | |||
52 | if (PCI_EXT_CAP_ID(reg32) == PCI_EXT_CAP_ID_ERR) | ||
53 | break; | ||
54 | |||
55 | pos = reg32 >> 20; | ||
56 | } | ||
57 | |||
58 | return pos; | ||
59 | } | ||
60 | |||
61 | int pci_enable_pcie_error_reporting(struct pci_dev *dev) | 31 | int pci_enable_pcie_error_reporting(struct pci_dev *dev) |
62 | { | 32 | { |
63 | u16 reg16 = 0; | 33 | u16 reg16 = 0; |
64 | int pos; | 34 | int pos; |
65 | 35 | ||
36 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | ||
37 | if (!pos) | ||
38 | return -EIO; | ||
39 | |||
66 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 40 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); |
67 | if (!pos) | 41 | if (!pos) |
68 | return -EIO; | 42 | return -EIO; |
@@ -102,7 +76,7 @@ int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev) | |||
102 | int pos; | 76 | int pos; |
103 | u32 status, mask; | 77 | u32 status, mask; |
104 | 78 | ||
105 | pos = pci_find_aer_capability(dev); | 79 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
106 | if (!pos) | 80 | if (!pos) |
107 | return -EIO; | 81 | return -EIO; |
108 | 82 | ||
@@ -123,7 +97,7 @@ int pci_cleanup_aer_correct_error_status(struct pci_dev *dev) | |||
123 | int pos; | 97 | int pos; |
124 | u32 status; | 98 | u32 status; |
125 | 99 | ||
126 | pos = pci_find_aer_capability(dev); | 100 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
127 | if (!pos) | 101 | if (!pos) |
128 | return -EIO; | 102 | return -EIO; |
129 | 103 | ||
@@ -502,7 +476,7 @@ static void handle_error_source(struct pcie_device * aerdev, | |||
502 | * Correctable error does not need software intevention. | 476 | * Correctable error does not need software intevention. |
503 | * No need to go through error recovery process. | 477 | * No need to go through error recovery process. |
504 | */ | 478 | */ |
505 | pos = pci_find_aer_capability(dev); | 479 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
506 | if (pos) | 480 | if (pos) |
507 | pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, | 481 | pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, |
508 | info.status); | 482 | info.status); |
@@ -542,7 +516,7 @@ void aer_enable_rootport(struct aer_rpc *rpc) | |||
542 | reg16 &= ~(SYSTEM_ERROR_INTR_ON_MESG_MASK); | 516 | reg16 &= ~(SYSTEM_ERROR_INTR_ON_MESG_MASK); |
543 | pci_write_config_word(pdev, pos + PCI_EXP_RTCTL, reg16); | 517 | pci_write_config_word(pdev, pos + PCI_EXP_RTCTL, reg16); |
544 | 518 | ||
545 | aer_pos = pci_find_aer_capability(pdev); | 519 | aer_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); |
546 | /* Clear error status */ | 520 | /* Clear error status */ |
547 | pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, ®32); | 521 | pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, ®32); |
548 | pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32); | 522 | pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32); |
@@ -579,7 +553,7 @@ static void disable_root_aer(struct aer_rpc *rpc) | |||
579 | u32 reg32; | 553 | u32 reg32; |
580 | int pos; | 554 | int pos; |
581 | 555 | ||
582 | pos = pci_find_aer_capability(pdev); | 556 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); |
583 | /* Disable Root's interrupt in response to error messages */ | 557 | /* Disable Root's interrupt in response to error messages */ |
584 | pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0); | 558 | pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0); |
585 | 559 | ||
@@ -618,7 +592,7 @@ static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info) | |||
618 | { | 592 | { |
619 | int pos; | 593 | int pos; |
620 | 594 | ||
621 | pos = pci_find_aer_capability(dev); | 595 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
622 | 596 | ||
623 | /* The device might not support AER */ | 597 | /* The device might not support AER */ |
624 | if (!pos) | 598 | if (!pos) |
@@ -755,7 +729,6 @@ int aer_init(struct pcie_device *dev) | |||
755 | return AER_SUCCESS; | 729 | return AER_SUCCESS; |
756 | } | 730 | } |
757 | 731 | ||
758 | EXPORT_SYMBOL_GPL(pci_find_aer_capability); | ||
759 | EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting); | 732 | EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting); |
760 | EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting); | 733 | EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting); |
761 | EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status); | 734 | EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status); |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 851f5b83cdbc..8f63f4c6b85f 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -528,9 +528,9 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) | |||
528 | pci_read_config_dword(child_dev, child_pos + PCI_EXP_DEVCAP, | 528 | pci_read_config_dword(child_dev, child_pos + PCI_EXP_DEVCAP, |
529 | ®32); | 529 | ®32); |
530 | if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) { | 530 | if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) { |
531 | printk("Pre-1.1 PCIe device detected, " | 531 | dev_printk(KERN_INFO, &child_dev->dev, "disabling ASPM" |
532 | "disable ASPM for %s. It can be enabled forcedly" | 532 | " on pre-1.1 PCIe device. You can enable it" |
533 | " with 'pcie_aspm=force'\n", pci_name(pdev)); | 533 | " with 'pcie_aspm=force'\n"); |
534 | return -EINVAL; | 534 | return -EINVAL; |
535 | } | 535 | } |
536 | } | 536 | } |
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index 3656e0349dd1..2529f3f2ea5a 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h | |||
@@ -25,7 +25,6 @@ | |||
25 | #define PCIE_CAPABILITIES_REG 0x2 | 25 | #define PCIE_CAPABILITIES_REG 0x2 |
26 | #define PCIE_SLOT_CAPABILITIES_REG 0x14 | 26 | #define PCIE_SLOT_CAPABILITIES_REG 0x14 |
27 | #define PCIE_PORT_DEVICE_MAXSERVICES 4 | 27 | #define PCIE_PORT_DEVICE_MAXSERVICES 4 |
28 | #define PCI_CFG_SPACE_SIZE 256 | ||
29 | 28 | ||
30 | #define get_descriptor_id(type, service) (((type - 4) << 4) | service) | 29 | #define get_descriptor_id(type, service) (((type - 4) << 4) | service) |
31 | 30 | ||
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 890f0d2b370a..2e091e014829 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -195,24 +195,11 @@ static int get_port_device_capability(struct pci_dev *dev) | |||
195 | /* PME Capable - root port capability */ | 195 | /* PME Capable - root port capability */ |
196 | if (((reg16 >> 4) & PORT_TYPE_MASK) == PCIE_RC_PORT) | 196 | if (((reg16 >> 4) & PORT_TYPE_MASK) == PCIE_RC_PORT) |
197 | services |= PCIE_PORT_SERVICE_PME; | 197 | services |= PCIE_PORT_SERVICE_PME; |
198 | 198 | ||
199 | pos = PCI_CFG_SPACE_SIZE; | 199 | if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) |
200 | while (pos) { | 200 | services |= PCIE_PORT_SERVICE_AER; |
201 | pci_read_config_dword(dev, pos, ®32); | 201 | if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC)) |
202 | switch (reg32 & 0xffff) { | 202 | services |= PCIE_PORT_SERVICE_VC; |
203 | case PCI_EXT_CAP_ID_ERR: | ||
204 | services |= PCIE_PORT_SERVICE_AER; | ||
205 | pos = reg32 >> 20; | ||
206 | break; | ||
207 | case PCI_EXT_CAP_ID_VC: | ||
208 | services |= PCIE_PORT_SERVICE_VC; | ||
209 | pos = reg32 >> 20; | ||
210 | break; | ||
211 | default: | ||
212 | pos = 0; | ||
213 | break; | ||
214 | } | ||
215 | } | ||
216 | 203 | ||
217 | return services; | 204 | return services; |
218 | } | 205 | } |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 367c9c20000d..584422da8d8b 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -91,7 +91,7 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev, | |||
91 | 91 | ||
92 | pci_set_master(dev); | 92 | pci_set_master(dev); |
93 | if (!dev->irq && dev->pin) { | 93 | if (!dev->irq && dev->pin) { |
94 | dev_warn(&dev->dev, "device [%04x/%04x] has invalid IRQ; " | 94 | dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; " |
95 | "check vendor BIOS\n", dev->vendor, dev->device); | 95 | "check vendor BIOS\n", dev->vendor, dev->device); |
96 | } | 96 | } |
97 | if (pcie_port_device_register(dev)) { | 97 | if (pcie_port_device_register(dev)) { |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index dd9161a054e1..aaaf0a1fed22 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -14,8 +14,6 @@ | |||
14 | 14 | ||
15 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ | 15 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ |
16 | #define CARDBUS_RESERVE_BUSNR 3 | 16 | #define CARDBUS_RESERVE_BUSNR 3 |
17 | #define PCI_CFG_SPACE_SIZE 256 | ||
18 | #define PCI_CFG_SPACE_EXP_SIZE 4096 | ||
19 | 17 | ||
20 | /* Ugh. Need to stop exporting this to modules. */ | 18 | /* Ugh. Need to stop exporting this to modules. */ |
21 | LIST_HEAD(pci_root_buses); | 19 | LIST_HEAD(pci_root_buses); |
@@ -44,72 +42,6 @@ int no_pci_devices(void) | |||
44 | } | 42 | } |
45 | EXPORT_SYMBOL(no_pci_devices); | 43 | EXPORT_SYMBOL(no_pci_devices); |
46 | 44 | ||
47 | #ifdef HAVE_PCI_LEGACY | ||
48 | /** | ||
49 | * pci_create_legacy_files - create legacy I/O port and memory files | ||
50 | * @b: bus to create files under | ||
51 | * | ||
52 | * Some platforms allow access to legacy I/O port and ISA memory space on | ||
53 | * a per-bus basis. This routine creates the files and ties them into | ||
54 | * their associated read, write and mmap files from pci-sysfs.c | ||
55 | * | ||
56 | * On error unwind, but don't propogate the error to the caller | ||
57 | * as it is ok to set up the PCI bus without these files. | ||
58 | */ | ||
59 | static void pci_create_legacy_files(struct pci_bus *b) | ||
60 | { | ||
61 | int error; | ||
62 | |||
63 | b->legacy_io = kzalloc(sizeof(struct bin_attribute) * 2, | ||
64 | GFP_ATOMIC); | ||
65 | if (!b->legacy_io) | ||
66 | goto kzalloc_err; | ||
67 | |||
68 | b->legacy_io->attr.name = "legacy_io"; | ||
69 | b->legacy_io->size = 0xffff; | ||
70 | b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; | ||
71 | b->legacy_io->read = pci_read_legacy_io; | ||
72 | b->legacy_io->write = pci_write_legacy_io; | ||
73 | error = device_create_bin_file(&b->dev, b->legacy_io); | ||
74 | if (error) | ||
75 | goto legacy_io_err; | ||
76 | |||
77 | /* Allocated above after the legacy_io struct */ | ||
78 | b->legacy_mem = b->legacy_io + 1; | ||
79 | b->legacy_mem->attr.name = "legacy_mem"; | ||
80 | b->legacy_mem->size = 1024*1024; | ||
81 | b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; | ||
82 | b->legacy_mem->mmap = pci_mmap_legacy_mem; | ||
83 | error = device_create_bin_file(&b->dev, b->legacy_mem); | ||
84 | if (error) | ||
85 | goto legacy_mem_err; | ||
86 | |||
87 | return; | ||
88 | |||
89 | legacy_mem_err: | ||
90 | device_remove_bin_file(&b->dev, b->legacy_io); | ||
91 | legacy_io_err: | ||
92 | kfree(b->legacy_io); | ||
93 | b->legacy_io = NULL; | ||
94 | kzalloc_err: | ||
95 | printk(KERN_WARNING "pci: warning: could not create legacy I/O port " | ||
96 | "and ISA memory resources to sysfs\n"); | ||
97 | return; | ||
98 | } | ||
99 | |||
100 | void pci_remove_legacy_files(struct pci_bus *b) | ||
101 | { | ||
102 | if (b->legacy_io) { | ||
103 | device_remove_bin_file(&b->dev, b->legacy_io); | ||
104 | device_remove_bin_file(&b->dev, b->legacy_mem); | ||
105 | kfree(b->legacy_io); /* both are allocated here */ | ||
106 | } | ||
107 | } | ||
108 | #else /* !HAVE_PCI_LEGACY */ | ||
109 | static inline void pci_create_legacy_files(struct pci_bus *bus) { return; } | ||
110 | void pci_remove_legacy_files(struct pci_bus *bus) { return; } | ||
111 | #endif /* HAVE_PCI_LEGACY */ | ||
112 | |||
113 | /* | 45 | /* |
114 | * PCI Bus Class Devices | 46 | * PCI Bus Class Devices |
115 | */ | 47 | */ |
@@ -219,7 +151,7 @@ static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar) | |||
219 | 151 | ||
220 | res->flags = bar & ~PCI_BASE_ADDRESS_MEM_MASK; | 152 | res->flags = bar & ~PCI_BASE_ADDRESS_MEM_MASK; |
221 | 153 | ||
222 | if (res->flags == PCI_BASE_ADDRESS_MEM_TYPE_64) | 154 | if (res->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) |
223 | return pci_bar_mem64; | 155 | return pci_bar_mem64; |
224 | return pci_bar_mem32; | 156 | return pci_bar_mem32; |
225 | } | 157 | } |
@@ -304,9 +236,8 @@ static int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
304 | } else { | 236 | } else { |
305 | res->start = l64; | 237 | res->start = l64; |
306 | res->end = l64 + sz64; | 238 | res->end = l64 + sz64; |
307 | printk(KERN_DEBUG "PCI: %s reg %x 64bit mmio: [%llx, %llx]\n", | 239 | dev_printk(KERN_DEBUG, &dev->dev, |
308 | pci_name(dev), pos, (unsigned long long)res->start, | 240 | "reg %x 64bit mmio: %pR\n", pos, res); |
309 | (unsigned long long)res->end); | ||
310 | } | 241 | } |
311 | } else { | 242 | } else { |
312 | sz = pci_size(l, sz, mask); | 243 | sz = pci_size(l, sz, mask); |
@@ -316,9 +247,10 @@ static int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
316 | 247 | ||
317 | res->start = l; | 248 | res->start = l; |
318 | res->end = l + sz; | 249 | res->end = l + sz; |
319 | printk(KERN_DEBUG "PCI: %s reg %x %s: [%llx, %llx]\n", pci_name(dev), | 250 | |
320 | pos, (res->flags & IORESOURCE_IO) ? "io port":"32bit mmio", | 251 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x %s: %pR\n", pos, |
321 | (unsigned long long)res->start, (unsigned long long)res->end); | 252 | (res->flags & IORESOURCE_IO) ? "io port" : "32bit mmio", |
253 | res); | ||
322 | } | 254 | } |
323 | 255 | ||
324 | out: | 256 | out: |
@@ -389,9 +321,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) | |||
389 | res->start = base; | 321 | res->start = base; |
390 | if (!res->end) | 322 | if (!res->end) |
391 | res->end = limit + 0xfff; | 323 | res->end = limit + 0xfff; |
392 | printk(KERN_DEBUG "PCI: bridge %s io port: [%llx, %llx]\n", | 324 | dev_printk(KERN_DEBUG, &dev->dev, "bridge io port: %pR\n", res); |
393 | pci_name(dev), (unsigned long long) res->start, | ||
394 | (unsigned long long) res->end); | ||
395 | } | 325 | } |
396 | 326 | ||
397 | res = child->resource[1]; | 327 | res = child->resource[1]; |
@@ -403,9 +333,8 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) | |||
403 | res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; | 333 | res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; |
404 | res->start = base; | 334 | res->start = base; |
405 | res->end = limit + 0xfffff; | 335 | res->end = limit + 0xfffff; |
406 | printk(KERN_DEBUG "PCI: bridge %s 32bit mmio: [%llx, %llx]\n", | 336 | dev_printk(KERN_DEBUG, &dev->dev, "bridge 32bit mmio: %pR\n", |
407 | pci_name(dev), (unsigned long long) res->start, | 337 | res); |
408 | (unsigned long long) res->end); | ||
409 | } | 338 | } |
410 | 339 | ||
411 | res = child->resource[2]; | 340 | res = child->resource[2]; |
@@ -441,9 +370,9 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) | |||
441 | res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH; | 370 | res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH; |
442 | res->start = base; | 371 | res->start = base; |
443 | res->end = limit + 0xfffff; | 372 | res->end = limit + 0xfffff; |
444 | printk(KERN_DEBUG "PCI: bridge %s %sbit mmio pref: [%llx, %llx]\n", | 373 | dev_printk(KERN_DEBUG, &dev->dev, "bridge %sbit mmio pref: %pR\n", |
445 | pci_name(dev), (res->flags & PCI_PREF_RANGE_TYPE_64) ? "64" : "32", | 374 | (res->flags & PCI_PREF_RANGE_TYPE_64) ? "64" : "32", |
446 | (unsigned long long) res->start, (unsigned long long) res->end); | 375 | res); |
447 | } | 376 | } |
448 | } | 377 | } |
449 | 378 | ||
@@ -764,7 +693,7 @@ static int pci_setup_device(struct pci_dev * dev) | |||
764 | dev->class = class; | 693 | dev->class = class; |
765 | class >>= 8; | 694 | class >>= 8; |
766 | 695 | ||
767 | dev_dbg(&dev->dev, "found [%04x/%04x] class %06x header type %02x\n", | 696 | dev_dbg(&dev->dev, "found [%04x:%04x] class %06x header type %02x\n", |
768 | dev->vendor, dev->device, class, dev->hdr_type); | 697 | dev->vendor, dev->device, class, dev->hdr_type); |
769 | 698 | ||
770 | /* "Unknown power state" */ | 699 | /* "Unknown power state" */ |
@@ -846,6 +775,11 @@ static int pci_setup_device(struct pci_dev * dev) | |||
846 | return 0; | 775 | return 0; |
847 | } | 776 | } |
848 | 777 | ||
778 | static void pci_release_capabilities(struct pci_dev *dev) | ||
779 | { | ||
780 | pci_vpd_release(dev); | ||
781 | } | ||
782 | |||
849 | /** | 783 | /** |
850 | * pci_release_dev - free a pci device structure when all users of it are finished. | 784 | * pci_release_dev - free a pci device structure when all users of it are finished. |
851 | * @dev: device that's been disconnected | 785 | * @dev: device that's been disconnected |
@@ -858,7 +792,7 @@ static void pci_release_dev(struct device *dev) | |||
858 | struct pci_dev *pci_dev; | 792 | struct pci_dev *pci_dev; |
859 | 793 | ||
860 | pci_dev = to_pci_dev(dev); | 794 | pci_dev = to_pci_dev(dev); |
861 | pci_vpd_release(pci_dev); | 795 | pci_release_capabilities(pci_dev); |
862 | kfree(pci_dev); | 796 | kfree(pci_dev); |
863 | } | 797 | } |
864 | 798 | ||
@@ -889,8 +823,9 @@ static void set_pcie_port_type(struct pci_dev *pdev) | |||
889 | int pci_cfg_space_size_ext(struct pci_dev *dev) | 823 | int pci_cfg_space_size_ext(struct pci_dev *dev) |
890 | { | 824 | { |
891 | u32 status; | 825 | u32 status; |
826 | int pos = PCI_CFG_SPACE_SIZE; | ||
892 | 827 | ||
893 | if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL) | 828 | if (pci_read_config_dword(dev, pos, &status) != PCIBIOS_SUCCESSFUL) |
894 | goto fail; | 829 | goto fail; |
895 | if (status == 0xffffffff) | 830 | if (status == 0xffffffff) |
896 | goto fail; | 831 | goto fail; |
@@ -938,8 +873,6 @@ struct pci_dev *alloc_pci_dev(void) | |||
938 | 873 | ||
939 | INIT_LIST_HEAD(&dev->bus_list); | 874 | INIT_LIST_HEAD(&dev->bus_list); |
940 | 875 | ||
941 | pci_msi_init_pci_dev(dev); | ||
942 | |||
943 | return dev; | 876 | return dev; |
944 | } | 877 | } |
945 | EXPORT_SYMBOL(alloc_pci_dev); | 878 | EXPORT_SYMBOL(alloc_pci_dev); |
@@ -951,6 +884,7 @@ EXPORT_SYMBOL(alloc_pci_dev); | |||
951 | static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) | 884 | static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) |
952 | { | 885 | { |
953 | struct pci_dev *dev; | 886 | struct pci_dev *dev; |
887 | struct pci_slot *slot; | ||
954 | u32 l; | 888 | u32 l; |
955 | u8 hdr_type; | 889 | u8 hdr_type; |
956 | int delay = 1; | 890 | int delay = 1; |
@@ -999,6 +933,10 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) | |||
999 | dev->error_state = pci_channel_io_normal; | 933 | dev->error_state = pci_channel_io_normal; |
1000 | set_pcie_port_type(dev); | 934 | set_pcie_port_type(dev); |
1001 | 935 | ||
936 | list_for_each_entry(slot, &bus->slots, list) | ||
937 | if (PCI_SLOT(devfn) == slot->number) | ||
938 | dev->slot = slot; | ||
939 | |||
1002 | /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer) | 940 | /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer) |
1003 | set this higher, assuming the system even supports it. */ | 941 | set this higher, assuming the system even supports it. */ |
1004 | dev->dma_mask = 0xffffffff; | 942 | dev->dma_mask = 0xffffffff; |
@@ -1007,9 +945,22 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) | |||
1007 | return NULL; | 945 | return NULL; |
1008 | } | 946 | } |
1009 | 947 | ||
948 | return dev; | ||
949 | } | ||
950 | |||
951 | static void pci_init_capabilities(struct pci_dev *dev) | ||
952 | { | ||
953 | /* MSI/MSI-X list */ | ||
954 | pci_msi_init_pci_dev(dev); | ||
955 | |||
956 | /* Power Management */ | ||
957 | pci_pm_init(dev); | ||
958 | |||
959 | /* Vital Product Data */ | ||
1010 | pci_vpd_pci22_init(dev); | 960 | pci_vpd_pci22_init(dev); |
1011 | 961 | ||
1012 | return dev; | 962 | /* Alternative Routing-ID Forwarding */ |
963 | pci_enable_ari(dev); | ||
1013 | } | 964 | } |
1014 | 965 | ||
1015 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) | 966 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) |
@@ -1028,8 +979,8 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) | |||
1028 | /* Fix up broken headers */ | 979 | /* Fix up broken headers */ |
1029 | pci_fixup_device(pci_fixup_header, dev); | 980 | pci_fixup_device(pci_fixup_header, dev); |
1030 | 981 | ||
1031 | /* Initialize power management of the device */ | 982 | /* Initialize various capabilities */ |
1032 | pci_pm_init(dev); | 983 | pci_init_capabilities(dev); |
1033 | 984 | ||
1034 | /* | 985 | /* |
1035 | * Add the device to our list of discovered devices | 986 | * Add the device to our list of discovered devices |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index e872ac925b4b..bbf66ea8fd87 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -24,6 +24,14 @@ | |||
24 | #include <linux/kallsyms.h> | 24 | #include <linux/kallsyms.h> |
25 | #include "pci.h" | 25 | #include "pci.h" |
26 | 26 | ||
27 | int isa_dma_bridge_buggy; | ||
28 | EXPORT_SYMBOL(isa_dma_bridge_buggy); | ||
29 | int pci_pci_problems; | ||
30 | EXPORT_SYMBOL(pci_pci_problems); | ||
31 | int pcie_mch_quirk; | ||
32 | EXPORT_SYMBOL(pcie_mch_quirk); | ||
33 | |||
34 | #ifdef CONFIG_PCI_QUIRKS | ||
27 | /* The Mellanox Tavor device gives false positive parity errors | 35 | /* The Mellanox Tavor device gives false positive parity errors |
28 | * Mark this device with a broken_parity_status, to allow | 36 | * Mark this device with a broken_parity_status, to allow |
29 | * PCI scanning code to "skip" this now blacklisted device. | 37 | * PCI scanning code to "skip" this now blacklisted device. |
@@ -62,8 +70,6 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_p | |||
62 | 70 | ||
63 | This appears to be BIOS not version dependent. So presumably there is a | 71 | This appears to be BIOS not version dependent. So presumably there is a |
64 | chipset level fix */ | 72 | chipset level fix */ |
65 | int isa_dma_bridge_buggy; | ||
66 | EXPORT_SYMBOL(isa_dma_bridge_buggy); | ||
67 | 73 | ||
68 | static void __devinit quirk_isa_dma_hangs(struct pci_dev *dev) | 74 | static void __devinit quirk_isa_dma_hangs(struct pci_dev *dev) |
69 | { | 75 | { |
@@ -84,9 +90,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_1, quirk_isa_d | |||
84 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_2, quirk_isa_dma_hangs); | 90 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_2, quirk_isa_dma_hangs); |
85 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs); | 91 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs); |
86 | 92 | ||
87 | int pci_pci_problems; | ||
88 | EXPORT_SYMBOL(pci_pci_problems); | ||
89 | |||
90 | /* | 93 | /* |
91 | * Chipsets where PCI->PCI transfers vanish or hang | 94 | * Chipsets where PCI->PCI transfers vanish or hang |
92 | */ | 95 | */ |
@@ -1362,9 +1365,6 @@ static void __init quirk_alder_ioapic(struct pci_dev *pdev) | |||
1362 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EESSC, quirk_alder_ioapic); | 1365 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EESSC, quirk_alder_ioapic); |
1363 | #endif | 1366 | #endif |
1364 | 1367 | ||
1365 | int pcie_mch_quirk; | ||
1366 | EXPORT_SYMBOL(pcie_mch_quirk); | ||
1367 | |||
1368 | static void __devinit quirk_pcie_mch(struct pci_dev *pdev) | 1368 | static void __devinit quirk_pcie_mch(struct pci_dev *pdev) |
1369 | { | 1369 | { |
1370 | pcie_mch_quirk = 1; | 1370 | pcie_mch_quirk = 1; |
@@ -1555,84 +1555,6 @@ static void __devinit fixup_rev1_53c810(struct pci_dev* dev) | |||
1555 | } | 1555 | } |
1556 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810); | 1556 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810); |
1557 | 1557 | ||
1558 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) | ||
1559 | { | ||
1560 | while (f < end) { | ||
1561 | if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) && | ||
1562 | (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) { | ||
1563 | #ifdef DEBUG | ||
1564 | dev_dbg(&dev->dev, "calling %pF\n", f->hook); | ||
1565 | #endif | ||
1566 | f->hook(dev); | ||
1567 | } | ||
1568 | f++; | ||
1569 | } | ||
1570 | } | ||
1571 | |||
1572 | extern struct pci_fixup __start_pci_fixups_early[]; | ||
1573 | extern struct pci_fixup __end_pci_fixups_early[]; | ||
1574 | extern struct pci_fixup __start_pci_fixups_header[]; | ||
1575 | extern struct pci_fixup __end_pci_fixups_header[]; | ||
1576 | extern struct pci_fixup __start_pci_fixups_final[]; | ||
1577 | extern struct pci_fixup __end_pci_fixups_final[]; | ||
1578 | extern struct pci_fixup __start_pci_fixups_enable[]; | ||
1579 | extern struct pci_fixup __end_pci_fixups_enable[]; | ||
1580 | extern struct pci_fixup __start_pci_fixups_resume[]; | ||
1581 | extern struct pci_fixup __end_pci_fixups_resume[]; | ||
1582 | extern struct pci_fixup __start_pci_fixups_resume_early[]; | ||
1583 | extern struct pci_fixup __end_pci_fixups_resume_early[]; | ||
1584 | extern struct pci_fixup __start_pci_fixups_suspend[]; | ||
1585 | extern struct pci_fixup __end_pci_fixups_suspend[]; | ||
1586 | |||
1587 | |||
1588 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) | ||
1589 | { | ||
1590 | struct pci_fixup *start, *end; | ||
1591 | |||
1592 | switch(pass) { | ||
1593 | case pci_fixup_early: | ||
1594 | start = __start_pci_fixups_early; | ||
1595 | end = __end_pci_fixups_early; | ||
1596 | break; | ||
1597 | |||
1598 | case pci_fixup_header: | ||
1599 | start = __start_pci_fixups_header; | ||
1600 | end = __end_pci_fixups_header; | ||
1601 | break; | ||
1602 | |||
1603 | case pci_fixup_final: | ||
1604 | start = __start_pci_fixups_final; | ||
1605 | end = __end_pci_fixups_final; | ||
1606 | break; | ||
1607 | |||
1608 | case pci_fixup_enable: | ||
1609 | start = __start_pci_fixups_enable; | ||
1610 | end = __end_pci_fixups_enable; | ||
1611 | break; | ||
1612 | |||
1613 | case pci_fixup_resume: | ||
1614 | start = __start_pci_fixups_resume; | ||
1615 | end = __end_pci_fixups_resume; | ||
1616 | break; | ||
1617 | |||
1618 | case pci_fixup_resume_early: | ||
1619 | start = __start_pci_fixups_resume_early; | ||
1620 | end = __end_pci_fixups_resume_early; | ||
1621 | break; | ||
1622 | |||
1623 | case pci_fixup_suspend: | ||
1624 | start = __start_pci_fixups_suspend; | ||
1625 | end = __end_pci_fixups_suspend; | ||
1626 | break; | ||
1627 | |||
1628 | default: | ||
1629 | /* stupid compiler warning, you would think with an enum... */ | ||
1630 | return; | ||
1631 | } | ||
1632 | pci_do_fixups(dev, start, end); | ||
1633 | } | ||
1634 | EXPORT_SYMBOL(pci_fixup_device); | ||
1635 | |||
1636 | /* Enable 1k I/O space granularity on the Intel P64H2 */ | 1558 | /* Enable 1k I/O space granularity on the Intel P64H2 */ |
1637 | static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev) | 1559 | static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev) |
1638 | { | 1560 | { |
@@ -2006,3 +1928,82 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4375, | |||
2006 | quirk_msi_intx_disable_bug); | 1928 | quirk_msi_intx_disable_bug); |
2007 | 1929 | ||
2008 | #endif /* CONFIG_PCI_MSI */ | 1930 | #endif /* CONFIG_PCI_MSI */ |
1931 | |||
1932 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) | ||
1933 | { | ||
1934 | while (f < end) { | ||
1935 | if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) && | ||
1936 | (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) { | ||
1937 | dev_dbg(&dev->dev, "calling %pF\n", f->hook); | ||
1938 | f->hook(dev); | ||
1939 | } | ||
1940 | f++; | ||
1941 | } | ||
1942 | } | ||
1943 | |||
1944 | extern struct pci_fixup __start_pci_fixups_early[]; | ||
1945 | extern struct pci_fixup __end_pci_fixups_early[]; | ||
1946 | extern struct pci_fixup __start_pci_fixups_header[]; | ||
1947 | extern struct pci_fixup __end_pci_fixups_header[]; | ||
1948 | extern struct pci_fixup __start_pci_fixups_final[]; | ||
1949 | extern struct pci_fixup __end_pci_fixups_final[]; | ||
1950 | extern struct pci_fixup __start_pci_fixups_enable[]; | ||
1951 | extern struct pci_fixup __end_pci_fixups_enable[]; | ||
1952 | extern struct pci_fixup __start_pci_fixups_resume[]; | ||
1953 | extern struct pci_fixup __end_pci_fixups_resume[]; | ||
1954 | extern struct pci_fixup __start_pci_fixups_resume_early[]; | ||
1955 | extern struct pci_fixup __end_pci_fixups_resume_early[]; | ||
1956 | extern struct pci_fixup __start_pci_fixups_suspend[]; | ||
1957 | extern struct pci_fixup __end_pci_fixups_suspend[]; | ||
1958 | |||
1959 | |||
1960 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) | ||
1961 | { | ||
1962 | struct pci_fixup *start, *end; | ||
1963 | |||
1964 | switch(pass) { | ||
1965 | case pci_fixup_early: | ||
1966 | start = __start_pci_fixups_early; | ||
1967 | end = __end_pci_fixups_early; | ||
1968 | break; | ||
1969 | |||
1970 | case pci_fixup_header: | ||
1971 | start = __start_pci_fixups_header; | ||
1972 | end = __end_pci_fixups_header; | ||
1973 | break; | ||
1974 | |||
1975 | case pci_fixup_final: | ||
1976 | start = __start_pci_fixups_final; | ||
1977 | end = __end_pci_fixups_final; | ||
1978 | break; | ||
1979 | |||
1980 | case pci_fixup_enable: | ||
1981 | start = __start_pci_fixups_enable; | ||
1982 | end = __end_pci_fixups_enable; | ||
1983 | break; | ||
1984 | |||
1985 | case pci_fixup_resume: | ||
1986 | start = __start_pci_fixups_resume; | ||
1987 | end = __end_pci_fixups_resume; | ||
1988 | break; | ||
1989 | |||
1990 | case pci_fixup_resume_early: | ||
1991 | start = __start_pci_fixups_resume_early; | ||
1992 | end = __end_pci_fixups_resume_early; | ||
1993 | break; | ||
1994 | |||
1995 | case pci_fixup_suspend: | ||
1996 | start = __start_pci_fixups_suspend; | ||
1997 | end = __end_pci_fixups_suspend; | ||
1998 | break; | ||
1999 | |||
2000 | default: | ||
2001 | /* stupid compiler warning, you would think with an enum... */ | ||
2002 | return; | ||
2003 | } | ||
2004 | pci_do_fixups(dev, start, end); | ||
2005 | } | ||
2006 | #else | ||
2007 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) {} | ||
2008 | #endif | ||
2009 | EXPORT_SYMBOL(pci_fixup_device); | ||
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index bdc2a44d68e1..042e08924421 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c | |||
@@ -73,6 +73,7 @@ void pci_remove_bus(struct pci_bus *pci_bus) | |||
73 | up_write(&pci_bus_sem); | 73 | up_write(&pci_bus_sem); |
74 | pci_remove_legacy_files(pci_bus); | 74 | pci_remove_legacy_files(pci_bus); |
75 | device_remove_file(&pci_bus->dev, &dev_attr_cpuaffinity); | 75 | device_remove_file(&pci_bus->dev, &dev_attr_cpuaffinity); |
76 | device_remove_file(&pci_bus->dev, &dev_attr_cpulistaffinity); | ||
76 | device_unregister(&pci_bus->dev); | 77 | device_unregister(&pci_bus->dev); |
77 | } | 78 | } |
78 | EXPORT_SYMBOL(pci_remove_bus); | 79 | EXPORT_SYMBOL(pci_remove_bus); |
@@ -114,13 +115,9 @@ void pci_remove_behind_bridge(struct pci_dev *dev) | |||
114 | { | 115 | { |
115 | struct list_head *l, *n; | 116 | struct list_head *l, *n; |
116 | 117 | ||
117 | if (dev->subordinate) { | 118 | if (dev->subordinate) |
118 | list_for_each_safe(l, n, &dev->subordinate->devices) { | 119 | list_for_each_safe(l, n, &dev->subordinate->devices) |
119 | struct pci_dev *dev = pci_dev_b(l); | 120 | pci_remove_bus_device(pci_dev_b(l)); |
120 | |||
121 | pci_remove_bus_device(dev); | ||
122 | } | ||
123 | } | ||
124 | } | 121 | } |
125 | 122 | ||
126 | static void pci_stop_bus_devices(struct pci_bus *bus) | 123 | static void pci_stop_bus_devices(struct pci_bus *bus) |
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index bd5c0e031398..1f5f6143f35c 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
@@ -21,7 +21,7 @@ | |||
21 | * between the ROM and other resources, so enabling it may disable access | 21 | * between the ROM and other resources, so enabling it may disable access |
22 | * to MMIO registers or other card memory. | 22 | * to MMIO registers or other card memory. |
23 | */ | 23 | */ |
24 | static int pci_enable_rom(struct pci_dev *pdev) | 24 | int pci_enable_rom(struct pci_dev *pdev) |
25 | { | 25 | { |
26 | struct resource *res = pdev->resource + PCI_ROM_RESOURCE; | 26 | struct resource *res = pdev->resource + PCI_ROM_RESOURCE; |
27 | struct pci_bus_region region; | 27 | struct pci_bus_region region; |
@@ -45,7 +45,7 @@ static int pci_enable_rom(struct pci_dev *pdev) | |||
45 | * Disable ROM decoding on a PCI device by turning off the last bit in the | 45 | * Disable ROM decoding on a PCI device by turning off the last bit in the |
46 | * ROM BAR. | 46 | * ROM BAR. |
47 | */ | 47 | */ |
48 | static void pci_disable_rom(struct pci_dev *pdev) | 48 | void pci_disable_rom(struct pci_dev *pdev) |
49 | { | 49 | { |
50 | u32 rom_addr; | 50 | u32 rom_addr; |
51 | pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr); | 51 | pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr); |
@@ -260,3 +260,5 @@ void pci_cleanup_rom(struct pci_dev *pdev) | |||
260 | 260 | ||
261 | EXPORT_SYMBOL(pci_map_rom); | 261 | EXPORT_SYMBOL(pci_map_rom); |
262 | EXPORT_SYMBOL(pci_unmap_rom); | 262 | EXPORT_SYMBOL(pci_unmap_rom); |
263 | EXPORT_SYMBOL_GPL(pci_enable_rom); | ||
264 | EXPORT_SYMBOL_GPL(pci_disable_rom); | ||
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index d5e2106760f8..ea979f2bc6db 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -299,7 +299,7 @@ static void pbus_size_io(struct pci_bus *bus) | |||
299 | 299 | ||
300 | if (r->parent || !(r->flags & IORESOURCE_IO)) | 300 | if (r->parent || !(r->flags & IORESOURCE_IO)) |
301 | continue; | 301 | continue; |
302 | r_size = r->end - r->start + 1; | 302 | r_size = resource_size(r); |
303 | 303 | ||
304 | if (r_size < 0x400) | 304 | if (r_size < 0x400) |
305 | /* Might be re-aligned for ISA */ | 305 | /* Might be re-aligned for ISA */ |
@@ -350,16 +350,13 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long | |||
350 | 350 | ||
351 | if (r->parent || (r->flags & mask) != type) | 351 | if (r->parent || (r->flags & mask) != type) |
352 | continue; | 352 | continue; |
353 | r_size = r->end - r->start + 1; | 353 | r_size = resource_size(r); |
354 | /* For bridges size != alignment */ | 354 | /* For bridges size != alignment */ |
355 | align = resource_alignment(r); | 355 | align = resource_alignment(r); |
356 | order = __ffs(align) - 20; | 356 | order = __ffs(align) - 20; |
357 | if (order > 11) { | 357 | if (order > 11) { |
358 | dev_warn(&dev->dev, "BAR %d bad alignment %llx: " | 358 | dev_warn(&dev->dev, "BAR %d bad alignment %llx: " |
359 | "%#016llx-%#016llx\n", i, | 359 | "%pR\n", i, (unsigned long long)align, r); |
360 | (unsigned long long)align, | ||
361 | (unsigned long long)r->start, | ||
362 | (unsigned long long)r->end); | ||
363 | r->flags = 0; | 360 | r->flags = 0; |
364 | continue; | 361 | continue; |
365 | } | 362 | } |
@@ -539,11 +536,9 @@ static void pci_bus_dump_res(struct pci_bus *bus) | |||
539 | if (!res) | 536 | if (!res) |
540 | continue; | 537 | continue; |
541 | 538 | ||
542 | printk(KERN_INFO "bus: %02x index %x %s: [%llx, %llx]\n", | 539 | printk(KERN_INFO "bus: %02x index %x %s: %pR\n", |
543 | bus->number, i, | 540 | bus->number, i, |
544 | (res->flags & IORESOURCE_IO) ? "io port" : "mmio", | 541 | (res->flags & IORESOURCE_IO) ? "io port" : "mmio", res); |
545 | (unsigned long long) res->start, | ||
546 | (unsigned long long) res->end); | ||
547 | } | 542 | } |
548 | } | 543 | } |
549 | 544 | ||
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 1a5fc83c71b3..2dbd96cce2d8 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -49,10 +49,8 @@ void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) | |||
49 | 49 | ||
50 | pcibios_resource_to_bus(dev, ®ion, res); | 50 | pcibios_resource_to_bus(dev, ®ion, res); |
51 | 51 | ||
52 | dev_dbg(&dev->dev, "BAR %d: got res [%#llx-%#llx] bus [%#llx-%#llx] " | 52 | dev_dbg(&dev->dev, "BAR %d: got res %pR bus [%#llx-%#llx] " |
53 | "flags %#lx\n", resno, | 53 | "flags %#lx\n", resno, res, |
54 | (unsigned long long)res->start, | ||
55 | (unsigned long long)res->end, | ||
56 | (unsigned long long)region.start, | 54 | (unsigned long long)region.start, |
57 | (unsigned long long)region.end, | 55 | (unsigned long long)region.end, |
58 | (unsigned long)res->flags); | 56 | (unsigned long)res->flags); |
@@ -114,13 +112,11 @@ int pci_claim_resource(struct pci_dev *dev, int resource) | |||
114 | err = insert_resource(root, res); | 112 | err = insert_resource(root, res); |
115 | 113 | ||
116 | if (err) { | 114 | if (err) { |
117 | dev_err(&dev->dev, "BAR %d: %s of %s [%#llx-%#llx]\n", | 115 | dev_err(&dev->dev, "BAR %d: %s of %s %pR\n", |
118 | resource, | 116 | resource, |
119 | root ? "address space collision on" : | 117 | root ? "address space collision on" : |
120 | "no parent found for", | 118 | "no parent found for", |
121 | dtype, | 119 | dtype, res); |
122 | (unsigned long long)res->start, | ||
123 | (unsigned long long)res->end); | ||
124 | } | 120 | } |
125 | 121 | ||
126 | return err; | 122 | return err; |
@@ -133,15 +129,14 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
133 | resource_size_t size, min, align; | 129 | resource_size_t size, min, align; |
134 | int ret; | 130 | int ret; |
135 | 131 | ||
136 | size = res->end - res->start + 1; | 132 | size = resource_size(res); |
137 | min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; | 133 | min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; |
138 | 134 | ||
139 | align = resource_alignment(res); | 135 | align = resource_alignment(res); |
140 | if (!align) { | 136 | if (!align) { |
141 | dev_err(&dev->dev, "BAR %d: can't allocate resource (bogus " | 137 | dev_err(&dev->dev, "BAR %d: can't allocate resource (bogus " |
142 | "alignment) [%#llx-%#llx] flags %#lx\n", | 138 | "alignment) %pR flags %#lx\n", |
143 | resno, (unsigned long long)res->start, | 139 | resno, res, res->flags); |
144 | (unsigned long long)res->end, res->flags); | ||
145 | return -EINVAL; | 140 | return -EINVAL; |
146 | } | 141 | } |
147 | 142 | ||
@@ -162,11 +157,8 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
162 | } | 157 | } |
163 | 158 | ||
164 | if (ret) { | 159 | if (ret) { |
165 | dev_err(&dev->dev, "BAR %d: can't allocate %s resource " | 160 | dev_err(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", |
166 | "[%#llx-%#llx]\n", resno, | 161 | resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res); |
167 | res->flags & IORESOURCE_IO ? "I/O" : "mem", | ||
168 | (unsigned long long)res->start, | ||
169 | (unsigned long long)res->end); | ||
170 | } else { | 162 | } else { |
171 | res->flags &= ~IORESOURCE_STARTALIGN; | 163 | res->flags &= ~IORESOURCE_STARTALIGN; |
172 | if (resno < PCI_BRIDGE_RESOURCES) | 164 | if (resno < PCI_BRIDGE_RESOURCES) |
@@ -202,11 +194,8 @@ int pci_assign_resource_fixed(struct pci_dev *dev, int resno) | |||
202 | } | 194 | } |
203 | 195 | ||
204 | if (ret) { | 196 | if (ret) { |
205 | dev_err(&dev->dev, "BAR %d: can't allocate %s resource " | 197 | dev_err(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", |
206 | "[%#llx-%#llx\n]", resno, | 198 | resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res); |
207 | res->flags & IORESOURCE_IO ? "I/O" : "mem", | ||
208 | (unsigned long long)res->start, | ||
209 | (unsigned long long)res->end); | ||
210 | } else if (resno < PCI_BRIDGE_RESOURCES) { | 199 | } else if (resno < PCI_BRIDGE_RESOURCES) { |
211 | pci_update_resource(dev, res, resno); | 200 | pci_update_resource(dev, res, resno); |
212 | } | 201 | } |
@@ -237,9 +226,8 @@ void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) | |||
237 | r_align = resource_alignment(r); | 226 | r_align = resource_alignment(r); |
238 | if (!r_align) { | 227 | if (!r_align) { |
239 | dev_warn(&dev->dev, "BAR %d: bogus alignment " | 228 | dev_warn(&dev->dev, "BAR %d: bogus alignment " |
240 | "[%#llx-%#llx] flags %#lx\n", | 229 | "%pR flags %#lx\n", |
241 | i, (unsigned long long)r->start, | 230 | i, r, r->flags); |
242 | (unsigned long long)r->end, r->flags); | ||
243 | continue; | 231 | continue; |
244 | } | 232 | } |
245 | for (list = head; ; list = list->next) { | 233 | for (list = head; ; list = list->next) { |
@@ -287,9 +275,7 @@ int pci_enable_resources(struct pci_dev *dev, int mask) | |||
287 | 275 | ||
288 | if (!r->parent) { | 276 | if (!r->parent) { |
289 | dev_err(&dev->dev, "device not available because of " | 277 | dev_err(&dev->dev, "device not available because of " |
290 | "BAR %d [%#llx-%#llx] collisions\n", i, | 278 | "BAR %d %pR collisions\n", i, r); |
291 | (unsigned long long) r->start, | ||
292 | (unsigned long long) r->end); | ||
293 | return -EINVAL; | 279 | return -EINVAL; |
294 | } | 280 | } |
295 | 281 | ||
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index 7e5b85cbd948..0c6db03698ea 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c | |||
@@ -49,11 +49,16 @@ static ssize_t address_read_file(struct pci_slot *slot, char *buf) | |||
49 | 49 | ||
50 | static void pci_slot_release(struct kobject *kobj) | 50 | static void pci_slot_release(struct kobject *kobj) |
51 | { | 51 | { |
52 | struct pci_dev *dev; | ||
52 | struct pci_slot *slot = to_pci_slot(kobj); | 53 | struct pci_slot *slot = to_pci_slot(kobj); |
53 | 54 | ||
54 | pr_debug("%s: releasing pci_slot on %x:%d\n", __func__, | 55 | pr_debug("%s: releasing pci_slot on %x:%d\n", __func__, |
55 | slot->bus->number, slot->number); | 56 | slot->bus->number, slot->number); |
56 | 57 | ||
58 | list_for_each_entry(dev, &slot->bus->devices, bus_list) | ||
59 | if (PCI_SLOT(dev->devfn) == slot->number) | ||
60 | dev->slot = NULL; | ||
61 | |||
57 | list_del(&slot->list); | 62 | list_del(&slot->list); |
58 | 63 | ||
59 | kfree(slot); | 64 | kfree(slot); |
@@ -108,6 +113,7 @@ static struct kobj_type pci_slot_ktype = { | |||
108 | struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr, | 113 | struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr, |
109 | const char *name) | 114 | const char *name) |
110 | { | 115 | { |
116 | struct pci_dev *dev; | ||
111 | struct pci_slot *slot; | 117 | struct pci_slot *slot; |
112 | int err; | 118 | int err; |
113 | 119 | ||
@@ -150,6 +156,10 @@ placeholder: | |||
150 | INIT_LIST_HEAD(&slot->list); | 156 | INIT_LIST_HEAD(&slot->list); |
151 | list_add(&slot->list, &parent->slots); | 157 | list_add(&slot->list, &parent->slots); |
152 | 158 | ||
159 | list_for_each_entry(dev, &parent->devices, bus_list) | ||
160 | if (PCI_SLOT(dev->devfn) == slot_nr) | ||
161 | dev->slot = slot; | ||
162 | |||
153 | /* Don't care if debug printk has a -1 for slot_nr */ | 163 | /* Don't care if debug printk has a -1 for slot_nr */ |
154 | pr_debug("%s: created pci_slot on %04x:%02x:%02x\n", | 164 | pr_debug("%s: created pci_slot on %04x:%02x:%02x\n", |
155 | __func__, pci_domain_nr(parent), parent->number, slot_nr); | 165 | __func__, pci_domain_nr(parent), parent->number, slot_nr); |
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c index a0ffb8ebfe00..9e1140f085fd 100644 --- a/drivers/pcmcia/at91_cf.c +++ b/drivers/pcmcia/at91_cf.c | |||
@@ -273,7 +273,7 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
273 | goto fail0d; | 273 | goto fail0d; |
274 | cf->socket.pci_irq = board->irq_pin; | 274 | cf->socket.pci_irq = board->irq_pin; |
275 | } else | 275 | } else |
276 | cf->socket.pci_irq = NR_IRQS + 1; | 276 | cf->socket.pci_irq = nr_irqs + 1; |
277 | 277 | ||
278 | /* pcmcia layer only remaps "real" memory not iospace */ | 278 | /* pcmcia layer only remaps "real" memory not iospace */ |
279 | cf->socket.io_offset = (unsigned long) | 279 | cf->socket.io_offset = (unsigned long) |
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c index 117dc12ab438..9ef69cdb3183 100644 --- a/drivers/pcmcia/hd64465_ss.c +++ b/drivers/pcmcia/hd64465_ss.c | |||
@@ -233,15 +233,18 @@ static struct hw_interrupt_type hd64465_ss_irq_type = { | |||
233 | */ | 233 | */ |
234 | static void hs_map_irq(hs_socket_t *sp, unsigned int irq) | 234 | static void hs_map_irq(hs_socket_t *sp, unsigned int irq) |
235 | { | 235 | { |
236 | struct irq_desc *desc; | ||
237 | |||
236 | DPRINTK("hs_map_irq(sock=%d irq=%d)\n", sp->number, irq); | 238 | DPRINTK("hs_map_irq(sock=%d irq=%d)\n", sp->number, irq); |
237 | 239 | ||
238 | if (irq >= HS_NUM_MAPPED_IRQS) | 240 | if (irq >= HS_NUM_MAPPED_IRQS) |
239 | return; | 241 | return; |
240 | 242 | ||
243 | desc = irq_to_desc(irq); | ||
241 | hs_mapped_irq[irq].sock = sp; | 244 | hs_mapped_irq[irq].sock = sp; |
242 | /* insert ourselves as the irq controller */ | 245 | /* insert ourselves as the irq controller */ |
243 | hs_mapped_irq[irq].old_handler = irq_desc[irq].chip; | 246 | hs_mapped_irq[irq].old_handler = desc->chip; |
244 | irq_desc[irq].chip = &hd64465_ss_irq_type; | 247 | desc->chip = &hd64465_ss_irq_type; |
245 | } | 248 | } |
246 | 249 | ||
247 | 250 | ||
@@ -250,13 +253,16 @@ static void hs_map_irq(hs_socket_t *sp, unsigned int irq) | |||
250 | */ | 253 | */ |
251 | static void hs_unmap_irq(hs_socket_t *sp, unsigned int irq) | 254 | static void hs_unmap_irq(hs_socket_t *sp, unsigned int irq) |
252 | { | 255 | { |
256 | struct irq_desc *desc; | ||
257 | |||
253 | DPRINTK("hs_unmap_irq(sock=%d irq=%d)\n", sp->number, irq); | 258 | DPRINTK("hs_unmap_irq(sock=%d irq=%d)\n", sp->number, irq); |
254 | 259 | ||
255 | if (irq >= HS_NUM_MAPPED_IRQS) | 260 | if (irq >= HS_NUM_MAPPED_IRQS) |
256 | return; | 261 | return; |
257 | 262 | ||
263 | desc = irq_to_desc(irq); | ||
258 | /* restore the original irq controller */ | 264 | /* restore the original irq controller */ |
259 | irq_desc[irq].chip = hs_mapped_irq[irq].old_handler; | 265 | desc->chip = hs_mapped_irq[irq].old_handler; |
260 | } | 266 | } |
261 | 267 | ||
262 | /*============================================================*/ | 268 | /*============================================================*/ |
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c index eee2f1cb213c..b2c412419059 100644 --- a/drivers/pcmcia/vrc4171_card.c +++ b/drivers/pcmcia/vrc4171_card.c | |||
@@ -639,7 +639,7 @@ static int __devinit vrc4171_card_setup(char *options) | |||
639 | int irq; | 639 | int irq; |
640 | options += 4; | 640 | options += 4; |
641 | irq = simple_strtoul(options, &options, 0); | 641 | irq = simple_strtoul(options, &options, 0); |
642 | if (irq >= 0 && irq < NR_IRQS) | 642 | if (irq >= 0 && irq < nr_irqs) |
643 | vrc4171_irq = irq; | 643 | vrc4171_irq = irq; |
644 | 644 | ||
645 | if (*options != ',') | 645 | if (*options != ',') |
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 63bb57910445..8e0c2b47803c 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig | |||
@@ -51,7 +51,7 @@ config BATTERY_OLPC | |||
51 | 51 | ||
52 | config BATTERY_TOSA | 52 | config BATTERY_TOSA |
53 | tristate "Sharp SL-6000 (tosa) battery" | 53 | tristate "Sharp SL-6000 (tosa) battery" |
54 | depends on MACH_TOSA && MFD_TC6393XB | 54 | depends on MACH_TOSA && MFD_TC6393XB && TOUCHSCREEN_WM97XX |
55 | help | 55 | help |
56 | Say Y to enable support for the battery on the Sharp Zaurus | 56 | Say Y to enable support for the battery on the Sharp Zaurus |
57 | SL-6000 (tosa) models. | 57 | SL-6000 (tosa) models. |
@@ -62,4 +62,10 @@ config BATTERY_WM97XX | |||
62 | help | 62 | help |
63 | Say Y to enable support for battery measured by WM97xx aux port. | 63 | Say Y to enable support for battery measured by WM97xx aux port. |
64 | 64 | ||
65 | config BATTERY_BQ27x00 | ||
66 | tristate "BQ27200 battery driver" | ||
67 | depends on I2C | ||
68 | help | ||
69 | Say Y here to enable support for batteries with BQ27200(I2C) chip. | ||
70 | |||
65 | endif # POWER_SUPPLY | 71 | endif # POWER_SUPPLY |
diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 4e20026cc45a..e8f1ecec5d8f 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile | |||
@@ -21,4 +21,5 @@ obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o | |||
21 | obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o | 21 | obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o |
22 | obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o | 22 | obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o |
23 | obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o | 23 | obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o |
24 | obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o \ No newline at end of file | 24 | obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o |
25 | obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o | ||
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c new file mode 100644 index 000000000000..0c056fcc01ce --- /dev/null +++ b/drivers/power/bq27x00_battery.c | |||
@@ -0,0 +1,381 @@ | |||
1 | /* | ||
2 | * BQ27x00 battery driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Rodolfo Giometti <giometti@linux.it> | ||
5 | * Copyright (C) 2008 Eurotech S.p.A. <info@eurotech.it> | ||
6 | * | ||
7 | * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc. | ||
8 | * | ||
9 | * This package 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 | * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
14 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
15 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
16 | * | ||
17 | */ | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/param.h> | ||
20 | #include <linux/jiffies.h> | ||
21 | #include <linux/workqueue.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/power_supply.h> | ||
25 | #include <linux/idr.h> | ||
26 | #include <linux/i2c.h> | ||
27 | #include <asm/unaligned.h> | ||
28 | |||
29 | #define DRIVER_VERSION "1.0.0" | ||
30 | |||
31 | #define BQ27x00_REG_TEMP 0x06 | ||
32 | #define BQ27x00_REG_VOLT 0x08 | ||
33 | #define BQ27x00_REG_RSOC 0x0B /* Relative State-of-Charge */ | ||
34 | #define BQ27x00_REG_AI 0x14 | ||
35 | #define BQ27x00_REG_FLAGS 0x0A | ||
36 | |||
37 | /* If the system has several batteries we need a different name for each | ||
38 | * of them... | ||
39 | */ | ||
40 | static DEFINE_IDR(battery_id); | ||
41 | static DEFINE_MUTEX(battery_mutex); | ||
42 | |||
43 | struct bq27x00_device_info; | ||
44 | struct bq27x00_access_methods { | ||
45 | int (*read)(u8 reg, int *rt_value, int b_single, | ||
46 | struct bq27x00_device_info *di); | ||
47 | }; | ||
48 | |||
49 | struct bq27x00_device_info { | ||
50 | struct device *dev; | ||
51 | int id; | ||
52 | int voltage_uV; | ||
53 | int current_uA; | ||
54 | int temp_C; | ||
55 | int charge_rsoc; | ||
56 | struct bq27x00_access_methods *bus; | ||
57 | struct power_supply bat; | ||
58 | |||
59 | struct i2c_client *client; | ||
60 | }; | ||
61 | |||
62 | static enum power_supply_property bq27x00_battery_props[] = { | ||
63 | POWER_SUPPLY_PROP_PRESENT, | ||
64 | POWER_SUPPLY_PROP_VOLTAGE_NOW, | ||
65 | POWER_SUPPLY_PROP_CURRENT_NOW, | ||
66 | POWER_SUPPLY_PROP_CAPACITY, | ||
67 | POWER_SUPPLY_PROP_TEMP, | ||
68 | }; | ||
69 | |||
70 | /* | ||
71 | * Common code for BQ27x00 devices | ||
72 | */ | ||
73 | |||
74 | static int bq27x00_read(u8 reg, int *rt_value, int b_single, | ||
75 | struct bq27x00_device_info *di) | ||
76 | { | ||
77 | int ret; | ||
78 | |||
79 | ret = di->bus->read(reg, rt_value, b_single, di); | ||
80 | *rt_value = be16_to_cpu(*rt_value); | ||
81 | |||
82 | return ret; | ||
83 | } | ||
84 | |||
85 | /* | ||
86 | * Return the battery temperature in Celcius degrees | ||
87 | * Or < 0 if something fails. | ||
88 | */ | ||
89 | static int bq27x00_battery_temperature(struct bq27x00_device_info *di) | ||
90 | { | ||
91 | int ret; | ||
92 | int temp = 0; | ||
93 | |||
94 | ret = bq27x00_read(BQ27x00_REG_TEMP, &temp, 0, di); | ||
95 | if (ret) { | ||
96 | dev_err(di->dev, "error reading temperature\n"); | ||
97 | return ret; | ||
98 | } | ||
99 | |||
100 | return (temp >> 2) - 273; | ||
101 | } | ||
102 | |||
103 | /* | ||
104 | * Return the battery Voltage in milivolts | ||
105 | * Or < 0 if something fails. | ||
106 | */ | ||
107 | static int bq27x00_battery_voltage(struct bq27x00_device_info *di) | ||
108 | { | ||
109 | int ret; | ||
110 | int volt = 0; | ||
111 | |||
112 | ret = bq27x00_read(BQ27x00_REG_VOLT, &volt, 0, di); | ||
113 | if (ret) { | ||
114 | dev_err(di->dev, "error reading voltage\n"); | ||
115 | return ret; | ||
116 | } | ||
117 | |||
118 | return volt; | ||
119 | } | ||
120 | |||
121 | /* | ||
122 | * Return the battery average current | ||
123 | * Note that current can be negative signed as well | ||
124 | * Or 0 if something fails. | ||
125 | */ | ||
126 | static int bq27x00_battery_current(struct bq27x00_device_info *di) | ||
127 | { | ||
128 | int ret; | ||
129 | int curr = 0; | ||
130 | int flags = 0; | ||
131 | |||
132 | ret = bq27x00_read(BQ27x00_REG_AI, &curr, 0, di); | ||
133 | if (ret) { | ||
134 | dev_err(di->dev, "error reading current\n"); | ||
135 | return 0; | ||
136 | } | ||
137 | ret = bq27x00_read(BQ27x00_REG_FLAGS, &flags, 0, di); | ||
138 | if (ret < 0) { | ||
139 | dev_err(di->dev, "error reading flags\n"); | ||
140 | return 0; | ||
141 | } | ||
142 | if ((flags & (1 << 7)) != 0) { | ||
143 | dev_dbg(di->dev, "negative current!\n"); | ||
144 | return -curr; | ||
145 | } | ||
146 | return curr; | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * Return the battery Relative State-of-Charge | ||
151 | * Or < 0 if something fails. | ||
152 | */ | ||
153 | static int bq27x00_battery_rsoc(struct bq27x00_device_info *di) | ||
154 | { | ||
155 | int ret; | ||
156 | int rsoc = 0; | ||
157 | |||
158 | ret = bq27x00_read(BQ27x00_REG_RSOC, &rsoc, 1, di); | ||
159 | if (ret) { | ||
160 | dev_err(di->dev, "error reading relative State-of-Charge\n"); | ||
161 | return ret; | ||
162 | } | ||
163 | |||
164 | return rsoc >> 8; | ||
165 | } | ||
166 | |||
167 | #define to_bq27x00_device_info(x) container_of((x), \ | ||
168 | struct bq27x00_device_info, bat); | ||
169 | |||
170 | static int bq27x00_battery_get_property(struct power_supply *psy, | ||
171 | enum power_supply_property psp, | ||
172 | union power_supply_propval *val) | ||
173 | { | ||
174 | struct bq27x00_device_info *di = to_bq27x00_device_info(psy); | ||
175 | |||
176 | switch (psp) { | ||
177 | case POWER_SUPPLY_PROP_VOLTAGE_NOW: | ||
178 | case POWER_SUPPLY_PROP_PRESENT: | ||
179 | val->intval = bq27x00_battery_voltage(di); | ||
180 | if (psp == POWER_SUPPLY_PROP_PRESENT) | ||
181 | val->intval = val->intval <= 0 ? 0 : 1; | ||
182 | break; | ||
183 | case POWER_SUPPLY_PROP_CURRENT_NOW: | ||
184 | val->intval = bq27x00_battery_current(di); | ||
185 | break; | ||
186 | case POWER_SUPPLY_PROP_CAPACITY: | ||
187 | val->intval = bq27x00_battery_rsoc(di); | ||
188 | break; | ||
189 | case POWER_SUPPLY_PROP_TEMP: | ||
190 | val->intval = bq27x00_battery_temperature(di); | ||
191 | break; | ||
192 | default: | ||
193 | return -EINVAL; | ||
194 | } | ||
195 | |||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | static void bq27x00_powersupply_init(struct bq27x00_device_info *di) | ||
200 | { | ||
201 | di->bat.type = POWER_SUPPLY_TYPE_BATTERY; | ||
202 | di->bat.properties = bq27x00_battery_props; | ||
203 | di->bat.num_properties = ARRAY_SIZE(bq27x00_battery_props); | ||
204 | di->bat.get_property = bq27x00_battery_get_property; | ||
205 | di->bat.external_power_changed = NULL; | ||
206 | } | ||
207 | |||
208 | /* | ||
209 | * BQ27200 specific code | ||
210 | */ | ||
211 | |||
212 | static int bq27200_read(u8 reg, int *rt_value, int b_single, | ||
213 | struct bq27x00_device_info *di) | ||
214 | { | ||
215 | struct i2c_client *client = di->client; | ||
216 | struct i2c_msg msg[1]; | ||
217 | unsigned char data[2]; | ||
218 | int err; | ||
219 | |||
220 | if (!client->adapter) | ||
221 | return -ENODEV; | ||
222 | |||
223 | msg->addr = client->addr; | ||
224 | msg->flags = 0; | ||
225 | msg->len = 1; | ||
226 | msg->buf = data; | ||
227 | |||
228 | data[0] = reg; | ||
229 | err = i2c_transfer(client->adapter, msg, 1); | ||
230 | |||
231 | if (err >= 0) { | ||
232 | if (!b_single) | ||
233 | msg->len = 2; | ||
234 | else | ||
235 | msg->len = 1; | ||
236 | |||
237 | msg->flags = I2C_M_RD; | ||
238 | err = i2c_transfer(client->adapter, msg, 1); | ||
239 | if (err >= 0) { | ||
240 | if (!b_single) | ||
241 | *rt_value = get_unaligned_be16(data); | ||
242 | else | ||
243 | *rt_value = data[0]; | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | } | ||
248 | return err; | ||
249 | } | ||
250 | |||
251 | static int bq27200_battery_probe(struct i2c_client *client, | ||
252 | const struct i2c_device_id *id) | ||
253 | { | ||
254 | char *name; | ||
255 | struct bq27x00_device_info *di; | ||
256 | struct bq27x00_access_methods *bus; | ||
257 | int num; | ||
258 | int retval = 0; | ||
259 | |||
260 | /* Get new ID for the new battery device */ | ||
261 | retval = idr_pre_get(&battery_id, GFP_KERNEL); | ||
262 | if (retval == 0) | ||
263 | return -ENOMEM; | ||
264 | mutex_lock(&battery_mutex); | ||
265 | retval = idr_get_new(&battery_id, client, &num); | ||
266 | mutex_unlock(&battery_mutex); | ||
267 | if (retval < 0) | ||
268 | return retval; | ||
269 | |||
270 | name = kasprintf(GFP_KERNEL, "bq27200-%d", num); | ||
271 | if (!name) { | ||
272 | dev_err(&client->dev, "failed to allocate device name\n"); | ||
273 | retval = -ENOMEM; | ||
274 | goto batt_failed_1; | ||
275 | } | ||
276 | |||
277 | di = kzalloc(sizeof(*di), GFP_KERNEL); | ||
278 | if (!di) { | ||
279 | dev_err(&client->dev, "failed to allocate device info data\n"); | ||
280 | retval = -ENOMEM; | ||
281 | goto batt_failed_2; | ||
282 | } | ||
283 | di->id = num; | ||
284 | |||
285 | bus = kzalloc(sizeof(*bus), GFP_KERNEL); | ||
286 | if (!bus) { | ||
287 | dev_err(&client->dev, "failed to allocate access method " | ||
288 | "data\n"); | ||
289 | retval = -ENOMEM; | ||
290 | goto batt_failed_3; | ||
291 | } | ||
292 | |||
293 | i2c_set_clientdata(client, di); | ||
294 | di->dev = &client->dev; | ||
295 | di->bat.name = name; | ||
296 | bus->read = &bq27200_read; | ||
297 | di->bus = bus; | ||
298 | di->client = client; | ||
299 | |||
300 | bq27x00_powersupply_init(di); | ||
301 | |||
302 | retval = power_supply_register(&client->dev, &di->bat); | ||
303 | if (retval) { | ||
304 | dev_err(&client->dev, "failed to register battery\n"); | ||
305 | goto batt_failed_4; | ||
306 | } | ||
307 | |||
308 | dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION); | ||
309 | |||
310 | return 0; | ||
311 | |||
312 | batt_failed_4: | ||
313 | kfree(bus); | ||
314 | batt_failed_3: | ||
315 | kfree(di); | ||
316 | batt_failed_2: | ||
317 | kfree(name); | ||
318 | batt_failed_1: | ||
319 | mutex_lock(&battery_mutex); | ||
320 | idr_remove(&battery_id, num); | ||
321 | mutex_unlock(&battery_mutex); | ||
322 | |||
323 | return retval; | ||
324 | } | ||
325 | |||
326 | static int bq27200_battery_remove(struct i2c_client *client) | ||
327 | { | ||
328 | struct bq27x00_device_info *di = i2c_get_clientdata(client); | ||
329 | |||
330 | power_supply_unregister(&di->bat); | ||
331 | |||
332 | kfree(di->bat.name); | ||
333 | |||
334 | mutex_lock(&battery_mutex); | ||
335 | idr_remove(&battery_id, di->id); | ||
336 | mutex_unlock(&battery_mutex); | ||
337 | |||
338 | kfree(di); | ||
339 | |||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | /* | ||
344 | * Module stuff | ||
345 | */ | ||
346 | |||
347 | static const struct i2c_device_id bq27200_id[] = { | ||
348 | { "bq27200", 0 }, | ||
349 | {}, | ||
350 | }; | ||
351 | |||
352 | static struct i2c_driver bq27200_battery_driver = { | ||
353 | .driver = { | ||
354 | .name = "bq27200-battery", | ||
355 | }, | ||
356 | .probe = bq27200_battery_probe, | ||
357 | .remove = bq27200_battery_remove, | ||
358 | .id_table = bq27200_id, | ||
359 | }; | ||
360 | |||
361 | static int __init bq27x00_battery_init(void) | ||
362 | { | ||
363 | int ret; | ||
364 | |||
365 | ret = i2c_add_driver(&bq27200_battery_driver); | ||
366 | if (ret) | ||
367 | printk(KERN_ERR "Unable to register BQ27200 driver\n"); | ||
368 | |||
369 | return ret; | ||
370 | } | ||
371 | module_init(bq27x00_battery_init); | ||
372 | |||
373 | static void __exit bq27x00_battery_exit(void) | ||
374 | { | ||
375 | i2c_del_driver(&bq27200_battery_driver); | ||
376 | } | ||
377 | module_exit(bq27x00_battery_exit); | ||
378 | |||
379 | MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); | ||
380 | MODULE_DESCRIPTION("BQ27x00 battery monitor driver"); | ||
381 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c index 0471ec743ab9..d30bb766fcef 100644 --- a/drivers/power/pda_power.c +++ b/drivers/power/pda_power.c | |||
@@ -334,13 +334,16 @@ static int pda_power_remove(struct platform_device *pdev) | |||
334 | } | 334 | } |
335 | 335 | ||
336 | #ifdef CONFIG_PM | 336 | #ifdef CONFIG_PM |
337 | static int ac_wakeup_enabled; | ||
338 | static int usb_wakeup_enabled; | ||
339 | |||
337 | static int pda_power_suspend(struct platform_device *pdev, pm_message_t state) | 340 | static int pda_power_suspend(struct platform_device *pdev, pm_message_t state) |
338 | { | 341 | { |
339 | if (device_may_wakeup(&pdev->dev)) { | 342 | if (device_may_wakeup(&pdev->dev)) { |
340 | if (ac_irq) | 343 | if (ac_irq) |
341 | enable_irq_wake(ac_irq->start); | 344 | ac_wakeup_enabled = !enable_irq_wake(ac_irq->start); |
342 | if (usb_irq) | 345 | if (usb_irq) |
343 | enable_irq_wake(usb_irq->start); | 346 | usb_wakeup_enabled = !enable_irq_wake(usb_irq->start); |
344 | } | 347 | } |
345 | 348 | ||
346 | return 0; | 349 | return 0; |
@@ -349,9 +352,9 @@ static int pda_power_suspend(struct platform_device *pdev, pm_message_t state) | |||
349 | static int pda_power_resume(struct platform_device *pdev) | 352 | static int pda_power_resume(struct platform_device *pdev) |
350 | { | 353 | { |
351 | if (device_may_wakeup(&pdev->dev)) { | 354 | if (device_may_wakeup(&pdev->dev)) { |
352 | if (usb_irq) | 355 | if (usb_irq && usb_wakeup_enabled) |
353 | disable_irq_wake(usb_irq->start); | 356 | disable_irq_wake(usb_irq->start); |
354 | if (ac_irq) | 357 | if (ac_irq && ac_wakeup_enabled) |
355 | disable_irq_wake(ac_irq->start); | 358 | disable_irq_wake(ac_irq->start); |
356 | } | 359 | } |
357 | 360 | ||
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c index 3007695f90c8..5520040449c4 100644 --- a/drivers/power/power_supply_core.c +++ b/drivers/power/power_supply_core.c | |||
@@ -87,6 +87,30 @@ int power_supply_am_i_supplied(struct power_supply *psy) | |||
87 | return error; | 87 | return error; |
88 | } | 88 | } |
89 | 89 | ||
90 | static int __power_supply_is_system_supplied(struct device *dev, void *data) | ||
91 | { | ||
92 | union power_supply_propval ret = {0,}; | ||
93 | struct power_supply *psy = dev_get_drvdata(dev); | ||
94 | |||
95 | if (psy->type != POWER_SUPPLY_TYPE_BATTERY) { | ||
96 | if (psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &ret)) | ||
97 | return 0; | ||
98 | if (ret.intval) | ||
99 | return ret.intval; | ||
100 | } | ||
101 | return 0; | ||
102 | } | ||
103 | |||
104 | int power_supply_is_system_supplied(void) | ||
105 | { | ||
106 | int error; | ||
107 | |||
108 | error = class_for_each_device(power_supply_class, NULL, NULL, | ||
109 | __power_supply_is_system_supplied); | ||
110 | |||
111 | return error; | ||
112 | } | ||
113 | |||
90 | int power_supply_register(struct device *parent, struct power_supply *psy) | 114 | int power_supply_register(struct device *parent, struct power_supply *psy) |
91 | { | 115 | { |
92 | int rc = 0; | 116 | int rc = 0; |
@@ -148,6 +172,7 @@ static void __exit power_supply_class_exit(void) | |||
148 | 172 | ||
149 | EXPORT_SYMBOL_GPL(power_supply_changed); | 173 | EXPORT_SYMBOL_GPL(power_supply_changed); |
150 | EXPORT_SYMBOL_GPL(power_supply_am_i_supplied); | 174 | EXPORT_SYMBOL_GPL(power_supply_am_i_supplied); |
175 | EXPORT_SYMBOL_GPL(power_supply_is_system_supplied); | ||
151 | EXPORT_SYMBOL_GPL(power_supply_register); | 176 | EXPORT_SYMBOL_GPL(power_supply_register); |
152 | EXPORT_SYMBOL_GPL(power_supply_unregister); | 177 | EXPORT_SYMBOL_GPL(power_supply_unregister); |
153 | 178 | ||
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index fe2aeb11939b..23ae8460f5c1 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c | |||
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | #define POWER_SUPPLY_ATTR(_name) \ | 31 | #define POWER_SUPPLY_ATTR(_name) \ |
32 | { \ | 32 | { \ |
33 | .attr = { .name = #_name, .mode = 0444, .owner = THIS_MODULE }, \ | 33 | .attr = { .name = #_name, .mode = 0444 }, \ |
34 | .show = power_supply_show_property, \ | 34 | .show = power_supply_show_property, \ |
35 | .store = NULL, \ | 35 | .store = NULL, \ |
36 | } | 36 | } |
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c index 6f2f90ebb020..06848b254d57 100644 --- a/drivers/ps3/ps3av.c +++ b/drivers/ps3/ps3av.c | |||
@@ -915,6 +915,22 @@ int ps3av_video_mute(int mute) | |||
915 | 915 | ||
916 | EXPORT_SYMBOL_GPL(ps3av_video_mute); | 916 | EXPORT_SYMBOL_GPL(ps3av_video_mute); |
917 | 917 | ||
918 | /* mute analog output only */ | ||
919 | int ps3av_audio_mute_analog(int mute) | ||
920 | { | ||
921 | int i, res; | ||
922 | |||
923 | for (i = 0; i < ps3av->av_hw_conf.num_of_avmulti; i++) { | ||
924 | res = ps3av_cmd_av_audio_mute(1, | ||
925 | &ps3av->av_port[i + ps3av->av_hw_conf.num_of_hdmi], | ||
926 | mute); | ||
927 | if (res < 0) | ||
928 | return -1; | ||
929 | } | ||
930 | return 0; | ||
931 | } | ||
932 | EXPORT_SYMBOL_GPL(ps3av_audio_mute_analog); | ||
933 | |||
918 | int ps3av_audio_mute(int mute) | 934 | int ps3av_audio_mute(int mute) |
919 | { | 935 | { |
920 | return ps3av_set_audio_mute(mute ? PS3AV_CMD_MUTE_ON | 936 | return ps3av_set_audio_mute(mute ? PS3AV_CMD_MUTE_ON |
diff --git a/drivers/ps3/ps3av_cmd.c b/drivers/ps3/ps3av_cmd.c index 7f880c26122f..11eb50318fec 100644 --- a/drivers/ps3/ps3av_cmd.c +++ b/drivers/ps3/ps3av_cmd.c | |||
@@ -660,9 +660,10 @@ u32 ps3av_cmd_set_av_audio_param(void *p, u32 port, | |||
660 | } | 660 | } |
661 | 661 | ||
662 | /* default cs val */ | 662 | /* default cs val */ |
663 | static const u8 ps3av_mode_cs_info[] = { | 663 | u8 ps3av_mode_cs_info[] = { |
664 | 0x00, 0x09, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00 | 664 | 0x00, 0x09, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00 |
665 | }; | 665 | }; |
666 | EXPORT_SYMBOL_GPL(ps3av_mode_cs_info); | ||
666 | 667 | ||
667 | #define CS_44 0x00 | 668 | #define CS_44 0x00 |
668 | #define CS_48 0x02 | 669 | #define CS_48 0x02 |
@@ -677,7 +678,7 @@ void ps3av_cmd_set_audio_mode(struct ps3av_pkt_audio_mode *audio, u32 avport, | |||
677 | u32 ch, u32 fs, u32 word_bits, u32 format, | 678 | u32 ch, u32 fs, u32 word_bits, u32 format, |
678 | u32 source) | 679 | u32 source) |
679 | { | 680 | { |
680 | int spdif_through, spdif_bitstream; | 681 | int spdif_through; |
681 | int i; | 682 | int i; |
682 | 683 | ||
683 | if (!(ch | fs | format | word_bits | source)) { | 684 | if (!(ch | fs | format | word_bits | source)) { |
@@ -687,7 +688,6 @@ void ps3av_cmd_set_audio_mode(struct ps3av_pkt_audio_mode *audio, u32 avport, | |||
687 | format = PS3AV_CMD_AUDIO_FORMAT_PCM; | 688 | format = PS3AV_CMD_AUDIO_FORMAT_PCM; |
688 | source = PS3AV_CMD_AUDIO_SOURCE_SERIAL; | 689 | source = PS3AV_CMD_AUDIO_SOURCE_SERIAL; |
689 | } | 690 | } |
690 | spdif_through = spdif_bitstream = 0; /* XXX not supported */ | ||
691 | 691 | ||
692 | /* audio mode */ | 692 | /* audio mode */ |
693 | memset(audio, 0, sizeof(*audio)); | 693 | memset(audio, 0, sizeof(*audio)); |
@@ -777,16 +777,17 @@ void ps3av_cmd_set_audio_mode(struct ps3av_pkt_audio_mode *audio, u32 avport, | |||
777 | break; | 777 | break; |
778 | } | 778 | } |
779 | 779 | ||
780 | /* non-audio bit */ | ||
781 | spdif_through = audio->audio_cs_info[0] & 0x02; | ||
782 | |||
780 | /* pass through setting */ | 783 | /* pass through setting */ |
781 | if (spdif_through && | 784 | if (spdif_through && |
782 | (avport == PS3AV_CMD_AVPORT_SPDIF_0 || | 785 | (avport == PS3AV_CMD_AVPORT_SPDIF_0 || |
783 | avport == PS3AV_CMD_AVPORT_SPDIF_1)) { | 786 | avport == PS3AV_CMD_AVPORT_SPDIF_1 || |
787 | avport == PS3AV_CMD_AVPORT_HDMI_0 || | ||
788 | avport == PS3AV_CMD_AVPORT_HDMI_1)) { | ||
784 | audio->audio_word_bits = PS3AV_CMD_AUDIO_WORD_BITS_16; | 789 | audio->audio_word_bits = PS3AV_CMD_AUDIO_WORD_BITS_16; |
785 | audio->audio_source = PS3AV_CMD_AUDIO_SOURCE_SPDIF; | 790 | audio->audio_format = PS3AV_CMD_AUDIO_FORMAT_BITSTREAM; |
786 | if (spdif_bitstream) { | ||
787 | audio->audio_format = PS3AV_CMD_AUDIO_FORMAT_BITSTREAM; | ||
788 | audio->audio_cs_info[0] |= CS_BIT; | ||
789 | } | ||
790 | } | 791 | } |
791 | } | 792 | } |
792 | 793 | ||
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index f660ef3e5b29..814f49fde530 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -610,6 +610,14 @@ config RTC_DRV_RS5C313 | |||
610 | help | 610 | help |
611 | If you say yes here you get support for the Ricoh RS5C313 RTC chips. | 611 | If you say yes here you get support for the Ricoh RS5C313 RTC chips. |
612 | 612 | ||
613 | config RTC_DRV_PARISC | ||
614 | tristate "PA-RISC firmware RTC support" | ||
615 | depends on PARISC | ||
616 | help | ||
617 | Say Y or M here to enable RTC support on PA-RISC systems using | ||
618 | firmware calls. If you do not know what you are doing, you should | ||
619 | just say Y. | ||
620 | |||
613 | config RTC_DRV_PPC | 621 | config RTC_DRV_PPC |
614 | tristate "PowerPC machine dependent RTC support" | 622 | tristate "PowerPC machine dependent RTC support" |
615 | depends on PPC | 623 | depends on PPC |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index d05928b3ca94..d6a9ac7176ea 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -51,6 +51,7 @@ obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o | |||
51 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o | 51 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o |
52 | obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o | 52 | obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o |
53 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o | 53 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o |
54 | obj-$(CONFIG_RTC_DRV_PARISC) += rtc-parisc.o | ||
54 | obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o | 55 | obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o |
55 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o | 56 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o |
56 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o | 57 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o |
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index 37082616482b..b5bf93706913 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c | |||
@@ -53,21 +53,21 @@ static void at91_rtc_decodetime(unsigned int timereg, unsigned int calreg, | |||
53 | } while ((time != at91_sys_read(timereg)) || | 53 | } while ((time != at91_sys_read(timereg)) || |
54 | (date != at91_sys_read(calreg))); | 54 | (date != at91_sys_read(calreg))); |
55 | 55 | ||
56 | tm->tm_sec = BCD2BIN((time & AT91_RTC_SEC) >> 0); | 56 | tm->tm_sec = bcd2bin((time & AT91_RTC_SEC) >> 0); |
57 | tm->tm_min = BCD2BIN((time & AT91_RTC_MIN) >> 8); | 57 | tm->tm_min = bcd2bin((time & AT91_RTC_MIN) >> 8); |
58 | tm->tm_hour = BCD2BIN((time & AT91_RTC_HOUR) >> 16); | 58 | tm->tm_hour = bcd2bin((time & AT91_RTC_HOUR) >> 16); |
59 | 59 | ||
60 | /* | 60 | /* |
61 | * The Calendar Alarm register does not have a field for | 61 | * The Calendar Alarm register does not have a field for |
62 | * the year - so these will return an invalid value. When an | 62 | * the year - so these will return an invalid value. When an |
63 | * alarm is set, at91_alarm_year wille store the current year. | 63 | * alarm is set, at91_alarm_year wille store the current year. |
64 | */ | 64 | */ |
65 | tm->tm_year = BCD2BIN(date & AT91_RTC_CENT) * 100; /* century */ | 65 | tm->tm_year = bcd2bin(date & AT91_RTC_CENT) * 100; /* century */ |
66 | tm->tm_year += BCD2BIN((date & AT91_RTC_YEAR) >> 8); /* year */ | 66 | tm->tm_year += bcd2bin((date & AT91_RTC_YEAR) >> 8); /* year */ |
67 | 67 | ||
68 | tm->tm_wday = BCD2BIN((date & AT91_RTC_DAY) >> 21) - 1; /* day of the week [0-6], Sunday=0 */ | 68 | tm->tm_wday = bcd2bin((date & AT91_RTC_DAY) >> 21) - 1; /* day of the week [0-6], Sunday=0 */ |
69 | tm->tm_mon = BCD2BIN((date & AT91_RTC_MONTH) >> 16) - 1; | 69 | tm->tm_mon = bcd2bin((date & AT91_RTC_MONTH) >> 16) - 1; |
70 | tm->tm_mday = BCD2BIN((date & AT91_RTC_DATE) >> 24); | 70 | tm->tm_mday = bcd2bin((date & AT91_RTC_DATE) >> 24); |
71 | } | 71 | } |
72 | 72 | ||
73 | /* | 73 | /* |
@@ -106,16 +106,16 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
106 | at91_sys_write(AT91_RTC_IDR, AT91_RTC_ACKUPD); | 106 | at91_sys_write(AT91_RTC_IDR, AT91_RTC_ACKUPD); |
107 | 107 | ||
108 | at91_sys_write(AT91_RTC_TIMR, | 108 | at91_sys_write(AT91_RTC_TIMR, |
109 | BIN2BCD(tm->tm_sec) << 0 | 109 | bin2bcd(tm->tm_sec) << 0 |
110 | | BIN2BCD(tm->tm_min) << 8 | 110 | | bin2bcd(tm->tm_min) << 8 |
111 | | BIN2BCD(tm->tm_hour) << 16); | 111 | | bin2bcd(tm->tm_hour) << 16); |
112 | 112 | ||
113 | at91_sys_write(AT91_RTC_CALR, | 113 | at91_sys_write(AT91_RTC_CALR, |
114 | BIN2BCD((tm->tm_year + 1900) / 100) /* century */ | 114 | bin2bcd((tm->tm_year + 1900) / 100) /* century */ |
115 | | BIN2BCD(tm->tm_year % 100) << 8 /* year */ | 115 | | bin2bcd(tm->tm_year % 100) << 8 /* year */ |
116 | | BIN2BCD(tm->tm_mon + 1) << 16 /* tm_mon starts at zero */ | 116 | | bin2bcd(tm->tm_mon + 1) << 16 /* tm_mon starts at zero */ |
117 | | BIN2BCD(tm->tm_wday + 1) << 21 /* day of the week [0-6], Sunday=0 */ | 117 | | bin2bcd(tm->tm_wday + 1) << 21 /* day of the week [0-6], Sunday=0 */ |
118 | | BIN2BCD(tm->tm_mday) << 24); | 118 | | bin2bcd(tm->tm_mday) << 24); |
119 | 119 | ||
120 | /* Restart Time/Calendar */ | 120 | /* Restart Time/Calendar */ |
121 | cr = at91_sys_read(AT91_RTC_CR); | 121 | cr = at91_sys_read(AT91_RTC_CR); |
@@ -162,13 +162,13 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
162 | 162 | ||
163 | at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); | 163 | at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); |
164 | at91_sys_write(AT91_RTC_TIMALR, | 164 | at91_sys_write(AT91_RTC_TIMALR, |
165 | BIN2BCD(tm.tm_sec) << 0 | 165 | bin2bcd(tm.tm_sec) << 0 |
166 | | BIN2BCD(tm.tm_min) << 8 | 166 | | bin2bcd(tm.tm_min) << 8 |
167 | | BIN2BCD(tm.tm_hour) << 16 | 167 | | bin2bcd(tm.tm_hour) << 16 |
168 | | AT91_RTC_HOUREN | AT91_RTC_MINEN | AT91_RTC_SECEN); | 168 | | AT91_RTC_HOUREN | AT91_RTC_MINEN | AT91_RTC_SECEN); |
169 | at91_sys_write(AT91_RTC_CALALR, | 169 | at91_sys_write(AT91_RTC_CALALR, |
170 | BIN2BCD(tm.tm_mon + 1) << 16 /* tm_mon starts at zero */ | 170 | bin2bcd(tm.tm_mon + 1) << 16 /* tm_mon starts at zero */ |
171 | | BIN2BCD(tm.tm_mday) << 24 | 171 | | bin2bcd(tm.tm_mday) << 24 |
172 | | AT91_RTC_DATEEN | AT91_RTC_MTHEN); | 172 | | AT91_RTC_DATEEN | AT91_RTC_MTHEN); |
173 | 173 | ||
174 | if (alrm->enabled) { | 174 | if (alrm->enabled) { |
diff --git a/drivers/rtc/rtc-bq4802.c b/drivers/rtc/rtc-bq4802.c index 189a018bdf34..d00a274df8fc 100644 --- a/drivers/rtc/rtc-bq4802.c +++ b/drivers/rtc/rtc-bq4802.c | |||
@@ -71,14 +71,14 @@ static int bq4802_read_time(struct device *dev, struct rtc_time *tm) | |||
71 | 71 | ||
72 | spin_unlock_irqrestore(&p->lock, flags); | 72 | spin_unlock_irqrestore(&p->lock, flags); |
73 | 73 | ||
74 | BCD_TO_BIN(tm->tm_sec); | 74 | tm->tm_sec = bcd2bin(tm->tm_sec); |
75 | BCD_TO_BIN(tm->tm_min); | 75 | tm->tm_min = bcd2bin(tm->tm_min); |
76 | BCD_TO_BIN(tm->tm_hour); | 76 | tm->tm_hour = bcd2bin(tm->tm_hour); |
77 | BCD_TO_BIN(tm->tm_mday); | 77 | tm->tm_mday = bcd2bin(tm->tm_mday); |
78 | BCD_TO_BIN(tm->tm_mon); | 78 | tm->tm_mon = bcd2bin(tm->tm_mon); |
79 | BCD_TO_BIN(tm->tm_year); | 79 | tm->tm_year = bcd2bin(tm->tm_year); |
80 | BCD_TO_BIN(tm->tm_wday); | 80 | tm->tm_wday = bcd2bin(tm->tm_wday); |
81 | BCD_TO_BIN(century); | 81 | century = bcd2bin(century); |
82 | 82 | ||
83 | tm->tm_year += (century * 100); | 83 | tm->tm_year += (century * 100); |
84 | tm->tm_year -= 1900; | 84 | tm->tm_year -= 1900; |
@@ -106,13 +106,13 @@ static int bq4802_set_time(struct device *dev, struct rtc_time *tm) | |||
106 | min = tm->tm_min; | 106 | min = tm->tm_min; |
107 | sec = tm->tm_sec; | 107 | sec = tm->tm_sec; |
108 | 108 | ||
109 | BIN_TO_BCD(sec); | 109 | sec = bin2bcd(sec); |
110 | BIN_TO_BCD(min); | 110 | min = bin2bcd(min); |
111 | BIN_TO_BCD(hrs); | 111 | hrs = bin2bcd(hrs); |
112 | BIN_TO_BCD(day); | 112 | day = bin2bcd(day); |
113 | BIN_TO_BCD(mon); | 113 | mon = bin2bcd(mon); |
114 | BIN_TO_BCD(yrs); | 114 | yrs = bin2bcd(yrs); |
115 | BIN_TO_BCD(century); | 115 | century = bin2bcd(century); |
116 | 116 | ||
117 | spin_lock_irqsave(&p->lock, flags); | 117 | spin_lock_irqsave(&p->lock, flags); |
118 | 118 | ||
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 963ad0b6a4e9..5549231179a2 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -143,6 +143,43 @@ static inline int hpet_unregister_irq_handler(irq_handler_t handler) | |||
143 | 143 | ||
144 | /*----------------------------------------------------------------*/ | 144 | /*----------------------------------------------------------------*/ |
145 | 145 | ||
146 | #ifdef RTC_PORT | ||
147 | |||
148 | /* Most newer x86 systems have two register banks, the first used | ||
149 | * for RTC and NVRAM and the second only for NVRAM. Caller must | ||
150 | * own rtc_lock ... and we won't worry about access during NMI. | ||
151 | */ | ||
152 | #define can_bank2 true | ||
153 | |||
154 | static inline unsigned char cmos_read_bank2(unsigned char addr) | ||
155 | { | ||
156 | outb(addr, RTC_PORT(2)); | ||
157 | return inb(RTC_PORT(3)); | ||
158 | } | ||
159 | |||
160 | static inline void cmos_write_bank2(unsigned char val, unsigned char addr) | ||
161 | { | ||
162 | outb(addr, RTC_PORT(2)); | ||
163 | outb(val, RTC_PORT(2)); | ||
164 | } | ||
165 | |||
166 | #else | ||
167 | |||
168 | #define can_bank2 false | ||
169 | |||
170 | static inline unsigned char cmos_read_bank2(unsigned char addr) | ||
171 | { | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static inline void cmos_write_bank2(unsigned char val, unsigned char addr) | ||
176 | { | ||
177 | } | ||
178 | |||
179 | #endif | ||
180 | |||
181 | /*----------------------------------------------------------------*/ | ||
182 | |||
146 | static int cmos_read_time(struct device *dev, struct rtc_time *t) | 183 | static int cmos_read_time(struct device *dev, struct rtc_time *t) |
147 | { | 184 | { |
148 | /* REVISIT: if the clock has a "century" register, use | 185 | /* REVISIT: if the clock has a "century" register, use |
@@ -203,26 +240,26 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
203 | /* REVISIT this assumes PC style usage: always BCD */ | 240 | /* REVISIT this assumes PC style usage: always BCD */ |
204 | 241 | ||
205 | if (((unsigned)t->time.tm_sec) < 0x60) | 242 | if (((unsigned)t->time.tm_sec) < 0x60) |
206 | t->time.tm_sec = BCD2BIN(t->time.tm_sec); | 243 | t->time.tm_sec = bcd2bin(t->time.tm_sec); |
207 | else | 244 | else |
208 | t->time.tm_sec = -1; | 245 | t->time.tm_sec = -1; |
209 | if (((unsigned)t->time.tm_min) < 0x60) | 246 | if (((unsigned)t->time.tm_min) < 0x60) |
210 | t->time.tm_min = BCD2BIN(t->time.tm_min); | 247 | t->time.tm_min = bcd2bin(t->time.tm_min); |
211 | else | 248 | else |
212 | t->time.tm_min = -1; | 249 | t->time.tm_min = -1; |
213 | if (((unsigned)t->time.tm_hour) < 0x24) | 250 | if (((unsigned)t->time.tm_hour) < 0x24) |
214 | t->time.tm_hour = BCD2BIN(t->time.tm_hour); | 251 | t->time.tm_hour = bcd2bin(t->time.tm_hour); |
215 | else | 252 | else |
216 | t->time.tm_hour = -1; | 253 | t->time.tm_hour = -1; |
217 | 254 | ||
218 | if (cmos->day_alrm) { | 255 | if (cmos->day_alrm) { |
219 | if (((unsigned)t->time.tm_mday) <= 0x31) | 256 | if (((unsigned)t->time.tm_mday) <= 0x31) |
220 | t->time.tm_mday = BCD2BIN(t->time.tm_mday); | 257 | t->time.tm_mday = bcd2bin(t->time.tm_mday); |
221 | else | 258 | else |
222 | t->time.tm_mday = -1; | 259 | t->time.tm_mday = -1; |
223 | if (cmos->mon_alrm) { | 260 | if (cmos->mon_alrm) { |
224 | if (((unsigned)t->time.tm_mon) <= 0x12) | 261 | if (((unsigned)t->time.tm_mon) <= 0x12) |
225 | t->time.tm_mon = BCD2BIN(t->time.tm_mon) - 1; | 262 | t->time.tm_mon = bcd2bin(t->time.tm_mon) - 1; |
226 | else | 263 | else |
227 | t->time.tm_mon = -1; | 264 | t->time.tm_mon = -1; |
228 | } | 265 | } |
@@ -294,19 +331,19 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
294 | /* Writing 0xff means "don't care" or "match all". */ | 331 | /* Writing 0xff means "don't care" or "match all". */ |
295 | 332 | ||
296 | mon = t->time.tm_mon + 1; | 333 | mon = t->time.tm_mon + 1; |
297 | mon = (mon <= 12) ? BIN2BCD(mon) : 0xff; | 334 | mon = (mon <= 12) ? bin2bcd(mon) : 0xff; |
298 | 335 | ||
299 | mday = t->time.tm_mday; | 336 | mday = t->time.tm_mday; |
300 | mday = (mday >= 1 && mday <= 31) ? BIN2BCD(mday) : 0xff; | 337 | mday = (mday >= 1 && mday <= 31) ? bin2bcd(mday) : 0xff; |
301 | 338 | ||
302 | hrs = t->time.tm_hour; | 339 | hrs = t->time.tm_hour; |
303 | hrs = (hrs < 24) ? BIN2BCD(hrs) : 0xff; | 340 | hrs = (hrs < 24) ? bin2bcd(hrs) : 0xff; |
304 | 341 | ||
305 | min = t->time.tm_min; | 342 | min = t->time.tm_min; |
306 | min = (min < 60) ? BIN2BCD(min) : 0xff; | 343 | min = (min < 60) ? bin2bcd(min) : 0xff; |
307 | 344 | ||
308 | sec = t->time.tm_sec; | 345 | sec = t->time.tm_sec; |
309 | sec = (sec < 60) ? BIN2BCD(sec) : 0xff; | 346 | sec = (sec < 60) ? bin2bcd(sec) : 0xff; |
310 | 347 | ||
311 | spin_lock_irq(&rtc_lock); | 348 | spin_lock_irq(&rtc_lock); |
312 | 349 | ||
@@ -491,12 +528,21 @@ cmos_nvram_read(struct kobject *kobj, struct bin_attribute *attr, | |||
491 | 528 | ||
492 | if (unlikely(off >= attr->size)) | 529 | if (unlikely(off >= attr->size)) |
493 | return 0; | 530 | return 0; |
531 | if (unlikely(off < 0)) | ||
532 | return -EINVAL; | ||
494 | if ((off + count) > attr->size) | 533 | if ((off + count) > attr->size) |
495 | count = attr->size - off; | 534 | count = attr->size - off; |
496 | 535 | ||
536 | off += NVRAM_OFFSET; | ||
497 | spin_lock_irq(&rtc_lock); | 537 | spin_lock_irq(&rtc_lock); |
498 | for (retval = 0, off += NVRAM_OFFSET; count--; retval++, off++) | 538 | for (retval = 0; count; count--, off++, retval++) { |
499 | *buf++ = CMOS_READ(off); | 539 | if (off < 128) |
540 | *buf++ = CMOS_READ(off); | ||
541 | else if (can_bank2) | ||
542 | *buf++ = cmos_read_bank2(off); | ||
543 | else | ||
544 | break; | ||
545 | } | ||
500 | spin_unlock_irq(&rtc_lock); | 546 | spin_unlock_irq(&rtc_lock); |
501 | 547 | ||
502 | return retval; | 548 | return retval; |
@@ -512,6 +558,8 @@ cmos_nvram_write(struct kobject *kobj, struct bin_attribute *attr, | |||
512 | cmos = dev_get_drvdata(container_of(kobj, struct device, kobj)); | 558 | cmos = dev_get_drvdata(container_of(kobj, struct device, kobj)); |
513 | if (unlikely(off >= attr->size)) | 559 | if (unlikely(off >= attr->size)) |
514 | return -EFBIG; | 560 | return -EFBIG; |
561 | if (unlikely(off < 0)) | ||
562 | return -EINVAL; | ||
515 | if ((off + count) > attr->size) | 563 | if ((off + count) > attr->size) |
516 | count = attr->size - off; | 564 | count = attr->size - off; |
517 | 565 | ||
@@ -520,15 +568,20 @@ cmos_nvram_write(struct kobject *kobj, struct bin_attribute *attr, | |||
520 | * here. If userspace is smart enough to know what fields of | 568 | * here. If userspace is smart enough to know what fields of |
521 | * NVRAM to update, updating checksums is also part of its job. | 569 | * NVRAM to update, updating checksums is also part of its job. |
522 | */ | 570 | */ |
571 | off += NVRAM_OFFSET; | ||
523 | spin_lock_irq(&rtc_lock); | 572 | spin_lock_irq(&rtc_lock); |
524 | for (retval = 0, off += NVRAM_OFFSET; count--; retval++, off++) { | 573 | for (retval = 0; count; count--, off++, retval++) { |
525 | /* don't trash RTC registers */ | 574 | /* don't trash RTC registers */ |
526 | if (off == cmos->day_alrm | 575 | if (off == cmos->day_alrm |
527 | || off == cmos->mon_alrm | 576 | || off == cmos->mon_alrm |
528 | || off == cmos->century) | 577 | || off == cmos->century) |
529 | buf++; | 578 | buf++; |
530 | else | 579 | else if (off < 128) |
531 | CMOS_WRITE(*buf++, off); | 580 | CMOS_WRITE(*buf++, off); |
581 | else if (can_bank2) | ||
582 | cmos_write_bank2(*buf++, off); | ||
583 | else | ||
584 | break; | ||
532 | } | 585 | } |
533 | spin_unlock_irq(&rtc_lock); | 586 | spin_unlock_irq(&rtc_lock); |
534 | 587 | ||
@@ -539,7 +592,6 @@ static struct bin_attribute nvram = { | |||
539 | .attr = { | 592 | .attr = { |
540 | .name = "nvram", | 593 | .name = "nvram", |
541 | .mode = S_IRUGO | S_IWUSR, | 594 | .mode = S_IRUGO | S_IWUSR, |
542 | .owner = THIS_MODULE, | ||
543 | }, | 595 | }, |
544 | 596 | ||
545 | .read = cmos_nvram_read, | 597 | .read = cmos_nvram_read, |
@@ -631,8 +683,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
631 | 683 | ||
632 | /* Heuristic to deduce NVRAM size ... do what the legacy NVRAM | 684 | /* Heuristic to deduce NVRAM size ... do what the legacy NVRAM |
633 | * driver did, but don't reject unknown configs. Old hardware | 685 | * driver did, but don't reject unknown configs. Old hardware |
634 | * won't address 128 bytes, and for now we ignore the way newer | 686 | * won't address 128 bytes. Newer chips have multiple banks, |
635 | * chips can address 256 bytes (using two more i/o ports). | 687 | * though they may not be listed in one I/O resource. |
636 | */ | 688 | */ |
637 | #if defined(CONFIG_ATARI) | 689 | #if defined(CONFIG_ATARI) |
638 | address_space = 64; | 690 | address_space = 64; |
@@ -642,6 +694,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
642 | #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes. | 694 | #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes. |
643 | address_space = 128; | 695 | address_space = 128; |
644 | #endif | 696 | #endif |
697 | if (can_bank2 && ports->end > (ports->start + 1)) | ||
698 | address_space = 256; | ||
645 | 699 | ||
646 | /* For ACPI systems extension info comes from the FADT. On others, | 700 | /* For ACPI systems extension info comes from the FADT. On others, |
647 | * board specific setup provides it as appropriate. Systems where | 701 | * board specific setup provides it as appropriate. Systems where |
@@ -740,7 +794,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
740 | goto cleanup2; | 794 | goto cleanup2; |
741 | } | 795 | } |
742 | 796 | ||
743 | pr_info("%s: alarms up to one %s%s%s\n", | 797 | pr_info("%s: alarms up to one %s%s, %zd bytes nvram, %s irqs\n", |
744 | cmos_rtc.rtc->dev.bus_id, | 798 | cmos_rtc.rtc->dev.bus_id, |
745 | is_valid_irq(rtc_irq) | 799 | is_valid_irq(rtc_irq) |
746 | ? (cmos_rtc.mon_alrm | 800 | ? (cmos_rtc.mon_alrm |
@@ -749,6 +803,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
749 | ? "month" : "day")) | 803 | ? "month" : "day")) |
750 | : "no", | 804 | : "no", |
751 | cmos_rtc.century ? ", y3k" : "", | 805 | cmos_rtc.century ? ", y3k" : "", |
806 | nvram.size, | ||
752 | is_hpet_enabled() ? ", hpet irqs" : ""); | 807 | is_hpet_enabled() ? ", hpet irqs" : ""); |
753 | 808 | ||
754 | return 0; | 809 | return 0; |
diff --git a/drivers/rtc/rtc-ds1216.c b/drivers/rtc/rtc-ds1216.c index 0b17770b032b..9a234a4ec06d 100644 --- a/drivers/rtc/rtc-ds1216.c +++ b/drivers/rtc/rtc-ds1216.c | |||
@@ -86,19 +86,19 @@ static int ds1216_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
86 | ds1216_switch_ds_to_clock(priv->ioaddr); | 86 | ds1216_switch_ds_to_clock(priv->ioaddr); |
87 | ds1216_read(priv->ioaddr, (u8 *)®s); | 87 | ds1216_read(priv->ioaddr, (u8 *)®s); |
88 | 88 | ||
89 | tm->tm_sec = BCD2BIN(regs.sec); | 89 | tm->tm_sec = bcd2bin(regs.sec); |
90 | tm->tm_min = BCD2BIN(regs.min); | 90 | tm->tm_min = bcd2bin(regs.min); |
91 | if (regs.hour & DS1216_HOUR_1224) { | 91 | if (regs.hour & DS1216_HOUR_1224) { |
92 | /* AM/PM mode */ | 92 | /* AM/PM mode */ |
93 | tm->tm_hour = BCD2BIN(regs.hour & 0x1f); | 93 | tm->tm_hour = bcd2bin(regs.hour & 0x1f); |
94 | if (regs.hour & DS1216_HOUR_AMPM) | 94 | if (regs.hour & DS1216_HOUR_AMPM) |
95 | tm->tm_hour += 12; | 95 | tm->tm_hour += 12; |
96 | } else | 96 | } else |
97 | tm->tm_hour = BCD2BIN(regs.hour & 0x3f); | 97 | tm->tm_hour = bcd2bin(regs.hour & 0x3f); |
98 | tm->tm_wday = (regs.wday & 7) - 1; | 98 | tm->tm_wday = (regs.wday & 7) - 1; |
99 | tm->tm_mday = BCD2BIN(regs.mday & 0x3f); | 99 | tm->tm_mday = bcd2bin(regs.mday & 0x3f); |
100 | tm->tm_mon = BCD2BIN(regs.month & 0x1f); | 100 | tm->tm_mon = bcd2bin(regs.month & 0x1f); |
101 | tm->tm_year = BCD2BIN(regs.year); | 101 | tm->tm_year = bcd2bin(regs.year); |
102 | if (tm->tm_year < 70) | 102 | if (tm->tm_year < 70) |
103 | tm->tm_year += 100; | 103 | tm->tm_year += 100; |
104 | return 0; | 104 | return 0; |
@@ -114,19 +114,19 @@ static int ds1216_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
114 | ds1216_read(priv->ioaddr, (u8 *)®s); | 114 | ds1216_read(priv->ioaddr, (u8 *)®s); |
115 | 115 | ||
116 | regs.tsec = 0; /* clear 0.1 and 0.01 seconds */ | 116 | regs.tsec = 0; /* clear 0.1 and 0.01 seconds */ |
117 | regs.sec = BIN2BCD(tm->tm_sec); | 117 | regs.sec = bin2bcd(tm->tm_sec); |
118 | regs.min = BIN2BCD(tm->tm_min); | 118 | regs.min = bin2bcd(tm->tm_min); |
119 | regs.hour &= DS1216_HOUR_1224; | 119 | regs.hour &= DS1216_HOUR_1224; |
120 | if (regs.hour && tm->tm_hour > 12) { | 120 | if (regs.hour && tm->tm_hour > 12) { |
121 | regs.hour |= DS1216_HOUR_AMPM; | 121 | regs.hour |= DS1216_HOUR_AMPM; |
122 | tm->tm_hour -= 12; | 122 | tm->tm_hour -= 12; |
123 | } | 123 | } |
124 | regs.hour |= BIN2BCD(tm->tm_hour); | 124 | regs.hour |= bin2bcd(tm->tm_hour); |
125 | regs.wday &= ~7; | 125 | regs.wday &= ~7; |
126 | regs.wday |= tm->tm_wday; | 126 | regs.wday |= tm->tm_wday; |
127 | regs.mday = BIN2BCD(tm->tm_mday); | 127 | regs.mday = bin2bcd(tm->tm_mday); |
128 | regs.month = BIN2BCD(tm->tm_mon); | 128 | regs.month = bin2bcd(tm->tm_mon); |
129 | regs.year = BIN2BCD(tm->tm_year % 100); | 129 | regs.year = bin2bcd(tm->tm_year % 100); |
130 | 130 | ||
131 | ds1216_switch_ds_to_clock(priv->ioaddr); | 131 | ds1216_switch_ds_to_clock(priv->ioaddr); |
132 | ds1216_write(priv->ioaddr, (u8 *)®s); | 132 | ds1216_write(priv->ioaddr, (u8 *)®s); |
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c index b9397818f73a..184556620778 100644 --- a/drivers/rtc/rtc-ds1302.c +++ b/drivers/rtc/rtc-ds1302.c | |||
@@ -40,7 +40,7 @@ | |||
40 | #define RTC_SCLK 0x0400 | 40 | #define RTC_SCLK 0x0400 |
41 | 41 | ||
42 | #ifdef CONFIG_SH_SECUREEDGE5410 | 42 | #ifdef CONFIG_SH_SECUREEDGE5410 |
43 | #include <asm/snapgear.h> | 43 | #include <mach/snapgear.h> |
44 | #define set_dp(x) SECUREEDGE_WRITE_IOPORT(x, 0x1c00) | 44 | #define set_dp(x) SECUREEDGE_WRITE_IOPORT(x, 0x1c00) |
45 | #define get_dp() SECUREEDGE_READ_IOPORT() | 45 | #define get_dp() SECUREEDGE_READ_IOPORT() |
46 | #else | 46 | #else |
@@ -107,13 +107,13 @@ static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
107 | 107 | ||
108 | spin_lock_irq(&rtc->lock); | 108 | spin_lock_irq(&rtc->lock); |
109 | 109 | ||
110 | tm->tm_sec = BCD2BIN(ds1302_readbyte(RTC_ADDR_SEC)); | 110 | tm->tm_sec = bcd2bin(ds1302_readbyte(RTC_ADDR_SEC)); |
111 | tm->tm_min = BCD2BIN(ds1302_readbyte(RTC_ADDR_MIN)); | 111 | tm->tm_min = bcd2bin(ds1302_readbyte(RTC_ADDR_MIN)); |
112 | tm->tm_hour = BCD2BIN(ds1302_readbyte(RTC_ADDR_HOUR)); | 112 | tm->tm_hour = bcd2bin(ds1302_readbyte(RTC_ADDR_HOUR)); |
113 | tm->tm_wday = BCD2BIN(ds1302_readbyte(RTC_ADDR_DAY)); | 113 | tm->tm_wday = bcd2bin(ds1302_readbyte(RTC_ADDR_DAY)); |
114 | tm->tm_mday = BCD2BIN(ds1302_readbyte(RTC_ADDR_DATE)); | 114 | tm->tm_mday = bcd2bin(ds1302_readbyte(RTC_ADDR_DATE)); |
115 | tm->tm_mon = BCD2BIN(ds1302_readbyte(RTC_ADDR_MON)) - 1; | 115 | tm->tm_mon = bcd2bin(ds1302_readbyte(RTC_ADDR_MON)) - 1; |
116 | tm->tm_year = BCD2BIN(ds1302_readbyte(RTC_ADDR_YEAR)); | 116 | tm->tm_year = bcd2bin(ds1302_readbyte(RTC_ADDR_YEAR)); |
117 | 117 | ||
118 | if (tm->tm_year < 70) | 118 | if (tm->tm_year < 70) |
119 | tm->tm_year += 100; | 119 | tm->tm_year += 100; |
@@ -141,13 +141,13 @@ static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
141 | /* Stop RTC */ | 141 | /* Stop RTC */ |
142 | ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80); | 142 | ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80); |
143 | 143 | ||
144 | ds1302_writebyte(RTC_ADDR_SEC, BIN2BCD(tm->tm_sec)); | 144 | ds1302_writebyte(RTC_ADDR_SEC, bin2bcd(tm->tm_sec)); |
145 | ds1302_writebyte(RTC_ADDR_MIN, BIN2BCD(tm->tm_min)); | 145 | ds1302_writebyte(RTC_ADDR_MIN, bin2bcd(tm->tm_min)); |
146 | ds1302_writebyte(RTC_ADDR_HOUR, BIN2BCD(tm->tm_hour)); | 146 | ds1302_writebyte(RTC_ADDR_HOUR, bin2bcd(tm->tm_hour)); |
147 | ds1302_writebyte(RTC_ADDR_DAY, BIN2BCD(tm->tm_wday)); | 147 | ds1302_writebyte(RTC_ADDR_DAY, bin2bcd(tm->tm_wday)); |
148 | ds1302_writebyte(RTC_ADDR_DATE, BIN2BCD(tm->tm_mday)); | 148 | ds1302_writebyte(RTC_ADDR_DATE, bin2bcd(tm->tm_mday)); |
149 | ds1302_writebyte(RTC_ADDR_MON, BIN2BCD(tm->tm_mon + 1)); | 149 | ds1302_writebyte(RTC_ADDR_MON, bin2bcd(tm->tm_mon + 1)); |
150 | ds1302_writebyte(RTC_ADDR_YEAR, BIN2BCD(tm->tm_year % 100)); | 150 | ds1302_writebyte(RTC_ADDR_YEAR, bin2bcd(tm->tm_year % 100)); |
151 | 151 | ||
152 | /* Start RTC */ | 152 | /* Start RTC */ |
153 | ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80); | 153 | ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80); |
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index b91d02a3ace9..fc372df6534b 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c | |||
@@ -114,10 +114,10 @@ static unsigned bcd2hour(u8 bcd) | |||
114 | hour = 12; | 114 | hour = 12; |
115 | bcd &= ~DS1305_HR_PM; | 115 | bcd &= ~DS1305_HR_PM; |
116 | } | 116 | } |
117 | hour += BCD2BIN(bcd); | 117 | hour += bcd2bin(bcd); |
118 | return hour - 1; | 118 | return hour - 1; |
119 | } | 119 | } |
120 | return BCD2BIN(bcd); | 120 | return bcd2bin(bcd); |
121 | } | 121 | } |
122 | 122 | ||
123 | static u8 hour2bcd(bool hr12, int hour) | 123 | static u8 hour2bcd(bool hr12, int hour) |
@@ -125,11 +125,11 @@ static u8 hour2bcd(bool hr12, int hour) | |||
125 | if (hr12) { | 125 | if (hr12) { |
126 | hour++; | 126 | hour++; |
127 | if (hour <= 12) | 127 | if (hour <= 12) |
128 | return DS1305_HR_12 | BIN2BCD(hour); | 128 | return DS1305_HR_12 | bin2bcd(hour); |
129 | hour -= 12; | 129 | hour -= 12; |
130 | return DS1305_HR_12 | DS1305_HR_PM | BIN2BCD(hour); | 130 | return DS1305_HR_12 | DS1305_HR_PM | bin2bcd(hour); |
131 | } | 131 | } |
132 | return BIN2BCD(hour); | 132 | return bin2bcd(hour); |
133 | } | 133 | } |
134 | 134 | ||
135 | /*----------------------------------------------------------------------*/ | 135 | /*----------------------------------------------------------------------*/ |
@@ -206,13 +206,13 @@ static int ds1305_get_time(struct device *dev, struct rtc_time *time) | |||
206 | buf[4], buf[5], buf[6]); | 206 | buf[4], buf[5], buf[6]); |
207 | 207 | ||
208 | /* Decode the registers */ | 208 | /* Decode the registers */ |
209 | time->tm_sec = BCD2BIN(buf[DS1305_SEC]); | 209 | time->tm_sec = bcd2bin(buf[DS1305_SEC]); |
210 | time->tm_min = BCD2BIN(buf[DS1305_MIN]); | 210 | time->tm_min = bcd2bin(buf[DS1305_MIN]); |
211 | time->tm_hour = bcd2hour(buf[DS1305_HOUR]); | 211 | time->tm_hour = bcd2hour(buf[DS1305_HOUR]); |
212 | time->tm_wday = buf[DS1305_WDAY] - 1; | 212 | time->tm_wday = buf[DS1305_WDAY] - 1; |
213 | time->tm_mday = BCD2BIN(buf[DS1305_MDAY]); | 213 | time->tm_mday = bcd2bin(buf[DS1305_MDAY]); |
214 | time->tm_mon = BCD2BIN(buf[DS1305_MON]) - 1; | 214 | time->tm_mon = bcd2bin(buf[DS1305_MON]) - 1; |
215 | time->tm_year = BCD2BIN(buf[DS1305_YEAR]) + 100; | 215 | time->tm_year = bcd2bin(buf[DS1305_YEAR]) + 100; |
216 | 216 | ||
217 | dev_vdbg(dev, "%s secs=%d, mins=%d, " | 217 | dev_vdbg(dev, "%s secs=%d, mins=%d, " |
218 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | 218 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", |
@@ -239,13 +239,13 @@ static int ds1305_set_time(struct device *dev, struct rtc_time *time) | |||
239 | /* Write registers starting at the first time/date address. */ | 239 | /* Write registers starting at the first time/date address. */ |
240 | *bp++ = DS1305_WRITE | DS1305_SEC; | 240 | *bp++ = DS1305_WRITE | DS1305_SEC; |
241 | 241 | ||
242 | *bp++ = BIN2BCD(time->tm_sec); | 242 | *bp++ = bin2bcd(time->tm_sec); |
243 | *bp++ = BIN2BCD(time->tm_min); | 243 | *bp++ = bin2bcd(time->tm_min); |
244 | *bp++ = hour2bcd(ds1305->hr12, time->tm_hour); | 244 | *bp++ = hour2bcd(ds1305->hr12, time->tm_hour); |
245 | *bp++ = (time->tm_wday < 7) ? (time->tm_wday + 1) : 1; | 245 | *bp++ = (time->tm_wday < 7) ? (time->tm_wday + 1) : 1; |
246 | *bp++ = BIN2BCD(time->tm_mday); | 246 | *bp++ = bin2bcd(time->tm_mday); |
247 | *bp++ = BIN2BCD(time->tm_mon + 1); | 247 | *bp++ = bin2bcd(time->tm_mon + 1); |
248 | *bp++ = BIN2BCD(time->tm_year - 100); | 248 | *bp++ = bin2bcd(time->tm_year - 100); |
249 | 249 | ||
250 | dev_dbg(dev, "%s: %02x %02x %02x, %02x %02x %02x %02x\n", | 250 | dev_dbg(dev, "%s: %02x %02x %02x, %02x %02x %02x %02x\n", |
251 | "write", buf[1], buf[2], buf[3], | 251 | "write", buf[1], buf[2], buf[3], |
@@ -329,8 +329,8 @@ static int ds1305_get_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
329 | * fill in the rest ... and also handle rollover to tomorrow when | 329 | * fill in the rest ... and also handle rollover to tomorrow when |
330 | * that's needed. | 330 | * that's needed. |
331 | */ | 331 | */ |
332 | alm->time.tm_sec = BCD2BIN(buf[DS1305_SEC]); | 332 | alm->time.tm_sec = bcd2bin(buf[DS1305_SEC]); |
333 | alm->time.tm_min = BCD2BIN(buf[DS1305_MIN]); | 333 | alm->time.tm_min = bcd2bin(buf[DS1305_MIN]); |
334 | alm->time.tm_hour = bcd2hour(buf[DS1305_HOUR]); | 334 | alm->time.tm_hour = bcd2hour(buf[DS1305_HOUR]); |
335 | alm->time.tm_mday = -1; | 335 | alm->time.tm_mday = -1; |
336 | alm->time.tm_mon = -1; | 336 | alm->time.tm_mon = -1; |
@@ -387,8 +387,8 @@ static int ds1305_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | |||
387 | 387 | ||
388 | /* write alarm */ | 388 | /* write alarm */ |
389 | buf[0] = DS1305_WRITE | DS1305_ALM0(DS1305_SEC); | 389 | buf[0] = DS1305_WRITE | DS1305_ALM0(DS1305_SEC); |
390 | buf[1 + DS1305_SEC] = BIN2BCD(alm->time.tm_sec); | 390 | buf[1 + DS1305_SEC] = bin2bcd(alm->time.tm_sec); |
391 | buf[1 + DS1305_MIN] = BIN2BCD(alm->time.tm_min); | 391 | buf[1 + DS1305_MIN] = bin2bcd(alm->time.tm_min); |
392 | buf[1 + DS1305_HOUR] = hour2bcd(ds1305->hr12, alm->time.tm_hour); | 392 | buf[1 + DS1305_HOUR] = hour2bcd(ds1305->hr12, alm->time.tm_hour); |
393 | buf[1 + DS1305_WDAY] = DS1305_ALM_DISABLE; | 393 | buf[1 + DS1305_WDAY] = DS1305_ALM_DISABLE; |
394 | 394 | ||
@@ -606,7 +606,6 @@ ds1305_nvram_write(struct kobject *kobj, struct bin_attribute *attr, | |||
606 | static struct bin_attribute nvram = { | 606 | static struct bin_attribute nvram = { |
607 | .attr.name = "nvram", | 607 | .attr.name = "nvram", |
608 | .attr.mode = S_IRUGO | S_IWUSR, | 608 | .attr.mode = S_IRUGO | S_IWUSR, |
609 | .attr.owner = THIS_MODULE, | ||
610 | .read = ds1305_nvram_read, | 609 | .read = ds1305_nvram_read, |
611 | .write = ds1305_nvram_write, | 610 | .write = ds1305_nvram_write, |
612 | .size = DS1305_NVRAM_LEN, | 611 | .size = DS1305_NVRAM_LEN, |
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 4fcf0734a6ef..162330b9d1dc 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
@@ -222,17 +222,17 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t) | |||
222 | ds1307->regs[4], ds1307->regs[5], | 222 | ds1307->regs[4], ds1307->regs[5], |
223 | ds1307->regs[6]); | 223 | ds1307->regs[6]); |
224 | 224 | ||
225 | t->tm_sec = BCD2BIN(ds1307->regs[DS1307_REG_SECS] & 0x7f); | 225 | t->tm_sec = bcd2bin(ds1307->regs[DS1307_REG_SECS] & 0x7f); |
226 | t->tm_min = BCD2BIN(ds1307->regs[DS1307_REG_MIN] & 0x7f); | 226 | t->tm_min = bcd2bin(ds1307->regs[DS1307_REG_MIN] & 0x7f); |
227 | tmp = ds1307->regs[DS1307_REG_HOUR] & 0x3f; | 227 | tmp = ds1307->regs[DS1307_REG_HOUR] & 0x3f; |
228 | t->tm_hour = BCD2BIN(tmp); | 228 | t->tm_hour = bcd2bin(tmp); |
229 | t->tm_wday = BCD2BIN(ds1307->regs[DS1307_REG_WDAY] & 0x07) - 1; | 229 | t->tm_wday = bcd2bin(ds1307->regs[DS1307_REG_WDAY] & 0x07) - 1; |
230 | t->tm_mday = BCD2BIN(ds1307->regs[DS1307_REG_MDAY] & 0x3f); | 230 | t->tm_mday = bcd2bin(ds1307->regs[DS1307_REG_MDAY] & 0x3f); |
231 | tmp = ds1307->regs[DS1307_REG_MONTH] & 0x1f; | 231 | tmp = ds1307->regs[DS1307_REG_MONTH] & 0x1f; |
232 | t->tm_mon = BCD2BIN(tmp) - 1; | 232 | t->tm_mon = bcd2bin(tmp) - 1; |
233 | 233 | ||
234 | /* assume 20YY not 19YY, and ignore DS1337_BIT_CENTURY */ | 234 | /* assume 20YY not 19YY, and ignore DS1337_BIT_CENTURY */ |
235 | t->tm_year = BCD2BIN(ds1307->regs[DS1307_REG_YEAR]) + 100; | 235 | t->tm_year = bcd2bin(ds1307->regs[DS1307_REG_YEAR]) + 100; |
236 | 236 | ||
237 | dev_dbg(dev, "%s secs=%d, mins=%d, " | 237 | dev_dbg(dev, "%s secs=%d, mins=%d, " |
238 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | 238 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", |
@@ -258,16 +258,16 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t) | |||
258 | t->tm_mon, t->tm_year, t->tm_wday); | 258 | t->tm_mon, t->tm_year, t->tm_wday); |
259 | 259 | ||
260 | *buf++ = 0; /* first register addr */ | 260 | *buf++ = 0; /* first register addr */ |
261 | buf[DS1307_REG_SECS] = BIN2BCD(t->tm_sec); | 261 | buf[DS1307_REG_SECS] = bin2bcd(t->tm_sec); |
262 | buf[DS1307_REG_MIN] = BIN2BCD(t->tm_min); | 262 | buf[DS1307_REG_MIN] = bin2bcd(t->tm_min); |
263 | buf[DS1307_REG_HOUR] = BIN2BCD(t->tm_hour); | 263 | buf[DS1307_REG_HOUR] = bin2bcd(t->tm_hour); |
264 | buf[DS1307_REG_WDAY] = BIN2BCD(t->tm_wday + 1); | 264 | buf[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1); |
265 | buf[DS1307_REG_MDAY] = BIN2BCD(t->tm_mday); | 265 | buf[DS1307_REG_MDAY] = bin2bcd(t->tm_mday); |
266 | buf[DS1307_REG_MONTH] = BIN2BCD(t->tm_mon + 1); | 266 | buf[DS1307_REG_MONTH] = bin2bcd(t->tm_mon + 1); |
267 | 267 | ||
268 | /* assume 20YY not 19YY */ | 268 | /* assume 20YY not 19YY */ |
269 | tmp = t->tm_year - 100; | 269 | tmp = t->tm_year - 100; |
270 | buf[DS1307_REG_YEAR] = BIN2BCD(tmp); | 270 | buf[DS1307_REG_YEAR] = bin2bcd(tmp); |
271 | 271 | ||
272 | switch (ds1307->type) { | 272 | switch (ds1307->type) { |
273 | case ds_1337: | 273 | case ds_1337: |
@@ -551,7 +551,6 @@ static struct bin_attribute nvram = { | |||
551 | .attr = { | 551 | .attr = { |
552 | .name = "nvram", | 552 | .name = "nvram", |
553 | .mode = S_IRUGO | S_IWUSR, | 553 | .mode = S_IRUGO | S_IWUSR, |
554 | .owner = THIS_MODULE, | ||
555 | }, | 554 | }, |
556 | 555 | ||
557 | .read = ds1307_nvram_read, | 556 | .read = ds1307_nvram_read, |
@@ -709,18 +708,18 @@ read_rtc: | |||
709 | } | 708 | } |
710 | 709 | ||
711 | tmp = ds1307->regs[DS1307_REG_SECS]; | 710 | tmp = ds1307->regs[DS1307_REG_SECS]; |
712 | tmp = BCD2BIN(tmp & 0x7f); | 711 | tmp = bcd2bin(tmp & 0x7f); |
713 | if (tmp > 60) | 712 | if (tmp > 60) |
714 | goto exit_bad; | 713 | goto exit_bad; |
715 | tmp = BCD2BIN(ds1307->regs[DS1307_REG_MIN] & 0x7f); | 714 | tmp = bcd2bin(ds1307->regs[DS1307_REG_MIN] & 0x7f); |
716 | if (tmp > 60) | 715 | if (tmp > 60) |
717 | goto exit_bad; | 716 | goto exit_bad; |
718 | 717 | ||
719 | tmp = BCD2BIN(ds1307->regs[DS1307_REG_MDAY] & 0x3f); | 718 | tmp = bcd2bin(ds1307->regs[DS1307_REG_MDAY] & 0x3f); |
720 | if (tmp == 0 || tmp > 31) | 719 | if (tmp == 0 || tmp > 31) |
721 | goto exit_bad; | 720 | goto exit_bad; |
722 | 721 | ||
723 | tmp = BCD2BIN(ds1307->regs[DS1307_REG_MONTH] & 0x1f); | 722 | tmp = bcd2bin(ds1307->regs[DS1307_REG_MONTH] & 0x1f); |
724 | if (tmp == 0 || tmp > 12) | 723 | if (tmp == 0 || tmp > 12) |
725 | goto exit_bad; | 724 | goto exit_bad; |
726 | 725 | ||
@@ -739,14 +738,14 @@ read_rtc: | |||
739 | /* Be sure we're in 24 hour mode. Multi-master systems | 738 | /* Be sure we're in 24 hour mode. Multi-master systems |
740 | * take note... | 739 | * take note... |
741 | */ | 740 | */ |
742 | tmp = BCD2BIN(tmp & 0x1f); | 741 | tmp = bcd2bin(tmp & 0x1f); |
743 | if (tmp == 12) | 742 | if (tmp == 12) |
744 | tmp = 0; | 743 | tmp = 0; |
745 | if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM) | 744 | if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM) |
746 | tmp += 12; | 745 | tmp += 12; |
747 | i2c_smbus_write_byte_data(client, | 746 | i2c_smbus_write_byte_data(client, |
748 | DS1307_REG_HOUR, | 747 | DS1307_REG_HOUR, |
749 | BIN2BCD(tmp)); | 748 | bin2bcd(tmp)); |
750 | } | 749 | } |
751 | 750 | ||
752 | ds1307->rtc = rtc_device_register(client->name, &client->dev, | 751 | ds1307->rtc = rtc_device_register(client->name, &client->dev, |
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index 86981d34fbb6..25caada78398 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c | |||
@@ -153,8 +153,8 @@ ds1511_wdog_set(unsigned long deciseconds) | |||
153 | /* | 153 | /* |
154 | * set the wdog values in the wdog registers | 154 | * set the wdog values in the wdog registers |
155 | */ | 155 | */ |
156 | rtc_write(BIN2BCD(deciseconds % 100), DS1511_WD_MSEC); | 156 | rtc_write(bin2bcd(deciseconds % 100), DS1511_WD_MSEC); |
157 | rtc_write(BIN2BCD(deciseconds / 100), DS1511_WD_SEC); | 157 | rtc_write(bin2bcd(deciseconds / 100), DS1511_WD_SEC); |
158 | /* | 158 | /* |
159 | * set wdog enable and wdog 'steering' bit to issue a reset | 159 | * set wdog enable and wdog 'steering' bit to issue a reset |
160 | */ | 160 | */ |
@@ -220,13 +220,13 @@ static int ds1511_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm) | |||
220 | /* | 220 | /* |
221 | * each register is a different number of valid bits | 221 | * each register is a different number of valid bits |
222 | */ | 222 | */ |
223 | sec = BIN2BCD(sec) & 0x7f; | 223 | sec = bin2bcd(sec) & 0x7f; |
224 | min = BIN2BCD(min) & 0x7f; | 224 | min = bin2bcd(min) & 0x7f; |
225 | hrs = BIN2BCD(hrs) & 0x3f; | 225 | hrs = bin2bcd(hrs) & 0x3f; |
226 | day = BIN2BCD(day) & 0x3f; | 226 | day = bin2bcd(day) & 0x3f; |
227 | mon = BIN2BCD(mon) & 0x1f; | 227 | mon = bin2bcd(mon) & 0x1f; |
228 | yrs = BIN2BCD(yrs) & 0xff; | 228 | yrs = bin2bcd(yrs) & 0xff; |
229 | cen = BIN2BCD(cen) & 0xff; | 229 | cen = bin2bcd(cen) & 0xff; |
230 | 230 | ||
231 | spin_lock_irqsave(&ds1511_lock, flags); | 231 | spin_lock_irqsave(&ds1511_lock, flags); |
232 | rtc_disable_update(); | 232 | rtc_disable_update(); |
@@ -264,14 +264,14 @@ static int ds1511_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm) | |||
264 | rtc_enable_update(); | 264 | rtc_enable_update(); |
265 | spin_unlock_irqrestore(&ds1511_lock, flags); | 265 | spin_unlock_irqrestore(&ds1511_lock, flags); |
266 | 266 | ||
267 | rtc_tm->tm_sec = BCD2BIN(rtc_tm->tm_sec); | 267 | rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec); |
268 | rtc_tm->tm_min = BCD2BIN(rtc_tm->tm_min); | 268 | rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min); |
269 | rtc_tm->tm_hour = BCD2BIN(rtc_tm->tm_hour); | 269 | rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour); |
270 | rtc_tm->tm_mday = BCD2BIN(rtc_tm->tm_mday); | 270 | rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday); |
271 | rtc_tm->tm_wday = BCD2BIN(rtc_tm->tm_wday); | 271 | rtc_tm->tm_wday = bcd2bin(rtc_tm->tm_wday); |
272 | rtc_tm->tm_mon = BCD2BIN(rtc_tm->tm_mon); | 272 | rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon); |
273 | rtc_tm->tm_year = BCD2BIN(rtc_tm->tm_year); | 273 | rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year); |
274 | century = BCD2BIN(century) * 100; | 274 | century = bcd2bin(century) * 100; |
275 | 275 | ||
276 | /* | 276 | /* |
277 | * Account for differences between how the RTC uses the values | 277 | * Account for differences between how the RTC uses the values |
@@ -304,16 +304,16 @@ ds1511_rtc_update_alarm(struct rtc_plat_data *pdata) | |||
304 | 304 | ||
305 | spin_lock_irqsave(&pdata->rtc->irq_lock, flags); | 305 | spin_lock_irqsave(&pdata->rtc->irq_lock, flags); |
306 | rtc_write(pdata->alrm_mday < 0 || (pdata->irqen & RTC_UF) ? | 306 | rtc_write(pdata->alrm_mday < 0 || (pdata->irqen & RTC_UF) ? |
307 | 0x80 : BIN2BCD(pdata->alrm_mday) & 0x3f, | 307 | 0x80 : bin2bcd(pdata->alrm_mday) & 0x3f, |
308 | RTC_ALARM_DATE); | 308 | RTC_ALARM_DATE); |
309 | rtc_write(pdata->alrm_hour < 0 || (pdata->irqen & RTC_UF) ? | 309 | rtc_write(pdata->alrm_hour < 0 || (pdata->irqen & RTC_UF) ? |
310 | 0x80 : BIN2BCD(pdata->alrm_hour) & 0x3f, | 310 | 0x80 : bin2bcd(pdata->alrm_hour) & 0x3f, |
311 | RTC_ALARM_HOUR); | 311 | RTC_ALARM_HOUR); |
312 | rtc_write(pdata->alrm_min < 0 || (pdata->irqen & RTC_UF) ? | 312 | rtc_write(pdata->alrm_min < 0 || (pdata->irqen & RTC_UF) ? |
313 | 0x80 : BIN2BCD(pdata->alrm_min) & 0x7f, | 313 | 0x80 : bin2bcd(pdata->alrm_min) & 0x7f, |
314 | RTC_ALARM_MIN); | 314 | RTC_ALARM_MIN); |
315 | rtc_write(pdata->alrm_sec < 0 || (pdata->irqen & RTC_UF) ? | 315 | rtc_write(pdata->alrm_sec < 0 || (pdata->irqen & RTC_UF) ? |
316 | 0x80 : BIN2BCD(pdata->alrm_sec) & 0x7f, | 316 | 0x80 : bin2bcd(pdata->alrm_sec) & 0x7f, |
317 | RTC_ALARM_SEC); | 317 | RTC_ALARM_SEC); |
318 | rtc_write(rtc_read(RTC_CMD) | (pdata->irqen ? RTC_TIE : 0), RTC_CMD); | 318 | rtc_write(rtc_read(RTC_CMD) | (pdata->irqen ? RTC_TIE : 0), RTC_CMD); |
319 | rtc_read(RTC_CMD1); /* clear interrupts */ | 319 | rtc_read(RTC_CMD1); /* clear interrupts */ |
@@ -481,7 +481,6 @@ static struct bin_attribute ds1511_nvram_attr = { | |||
481 | .attr = { | 481 | .attr = { |
482 | .name = "nvram", | 482 | .name = "nvram", |
483 | .mode = S_IRUGO | S_IWUGO, | 483 | .mode = S_IRUGO | S_IWUGO, |
484 | .owner = THIS_MODULE, | ||
485 | }, | 484 | }, |
486 | .size = DS1511_RAM_MAX, | 485 | .size = DS1511_RAM_MAX, |
487 | .read = ds1511_nvram_read, | 486 | .read = ds1511_nvram_read, |
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index 4ef59285b489..b9475cd20210 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c | |||
@@ -78,17 +78,17 @@ static int ds1553_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
78 | void __iomem *ioaddr = pdata->ioaddr; | 78 | void __iomem *ioaddr = pdata->ioaddr; |
79 | u8 century; | 79 | u8 century; |
80 | 80 | ||
81 | century = BIN2BCD((tm->tm_year + 1900) / 100); | 81 | century = bin2bcd((tm->tm_year + 1900) / 100); |
82 | 82 | ||
83 | writeb(RTC_WRITE, pdata->ioaddr + RTC_CONTROL); | 83 | writeb(RTC_WRITE, pdata->ioaddr + RTC_CONTROL); |
84 | 84 | ||
85 | writeb(BIN2BCD(tm->tm_year % 100), ioaddr + RTC_YEAR); | 85 | writeb(bin2bcd(tm->tm_year % 100), ioaddr + RTC_YEAR); |
86 | writeb(BIN2BCD(tm->tm_mon + 1), ioaddr + RTC_MONTH); | 86 | writeb(bin2bcd(tm->tm_mon + 1), ioaddr + RTC_MONTH); |
87 | writeb(BIN2BCD(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY); | 87 | writeb(bin2bcd(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY); |
88 | writeb(BIN2BCD(tm->tm_mday), ioaddr + RTC_DATE); | 88 | writeb(bin2bcd(tm->tm_mday), ioaddr + RTC_DATE); |
89 | writeb(BIN2BCD(tm->tm_hour), ioaddr + RTC_HOURS); | 89 | writeb(bin2bcd(tm->tm_hour), ioaddr + RTC_HOURS); |
90 | writeb(BIN2BCD(tm->tm_min), ioaddr + RTC_MINUTES); | 90 | writeb(bin2bcd(tm->tm_min), ioaddr + RTC_MINUTES); |
91 | writeb(BIN2BCD(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS); | 91 | writeb(bin2bcd(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS); |
92 | 92 | ||
93 | /* RTC_CENTURY and RTC_CONTROL share same register */ | 93 | /* RTC_CENTURY and RTC_CONTROL share same register */ |
94 | writeb(RTC_WRITE | (century & RTC_CENTURY_MASK), ioaddr + RTC_CENTURY); | 94 | writeb(RTC_WRITE | (century & RTC_CENTURY_MASK), ioaddr + RTC_CENTURY); |
@@ -118,14 +118,14 @@ static int ds1553_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
118 | year = readb(ioaddr + RTC_YEAR); | 118 | year = readb(ioaddr + RTC_YEAR); |
119 | century = readb(ioaddr + RTC_CENTURY) & RTC_CENTURY_MASK; | 119 | century = readb(ioaddr + RTC_CENTURY) & RTC_CENTURY_MASK; |
120 | writeb(0, ioaddr + RTC_CONTROL); | 120 | writeb(0, ioaddr + RTC_CONTROL); |
121 | tm->tm_sec = BCD2BIN(second); | 121 | tm->tm_sec = bcd2bin(second); |
122 | tm->tm_min = BCD2BIN(minute); | 122 | tm->tm_min = bcd2bin(minute); |
123 | tm->tm_hour = BCD2BIN(hour); | 123 | tm->tm_hour = bcd2bin(hour); |
124 | tm->tm_mday = BCD2BIN(day); | 124 | tm->tm_mday = bcd2bin(day); |
125 | tm->tm_wday = BCD2BIN(week); | 125 | tm->tm_wday = bcd2bin(week); |
126 | tm->tm_mon = BCD2BIN(month) - 1; | 126 | tm->tm_mon = bcd2bin(month) - 1; |
127 | /* year is 1900 + tm->tm_year */ | 127 | /* year is 1900 + tm->tm_year */ |
128 | tm->tm_year = BCD2BIN(year) + BCD2BIN(century) * 100 - 1900; | 128 | tm->tm_year = bcd2bin(year) + bcd2bin(century) * 100 - 1900; |
129 | 129 | ||
130 | if (rtc_valid_tm(tm) < 0) { | 130 | if (rtc_valid_tm(tm) < 0) { |
131 | dev_err(dev, "retrieved date/time is not valid.\n"); | 131 | dev_err(dev, "retrieved date/time is not valid.\n"); |
@@ -141,16 +141,16 @@ static void ds1553_rtc_update_alarm(struct rtc_plat_data *pdata) | |||
141 | 141 | ||
142 | spin_lock_irqsave(&pdata->rtc->irq_lock, flags); | 142 | spin_lock_irqsave(&pdata->rtc->irq_lock, flags); |
143 | writeb(pdata->alrm_mday < 0 || (pdata->irqen & RTC_UF) ? | 143 | writeb(pdata->alrm_mday < 0 || (pdata->irqen & RTC_UF) ? |
144 | 0x80 : BIN2BCD(pdata->alrm_mday), | 144 | 0x80 : bin2bcd(pdata->alrm_mday), |
145 | ioaddr + RTC_DATE_ALARM); | 145 | ioaddr + RTC_DATE_ALARM); |
146 | writeb(pdata->alrm_hour < 0 || (pdata->irqen & RTC_UF) ? | 146 | writeb(pdata->alrm_hour < 0 || (pdata->irqen & RTC_UF) ? |
147 | 0x80 : BIN2BCD(pdata->alrm_hour), | 147 | 0x80 : bin2bcd(pdata->alrm_hour), |
148 | ioaddr + RTC_HOURS_ALARM); | 148 | ioaddr + RTC_HOURS_ALARM); |
149 | writeb(pdata->alrm_min < 0 || (pdata->irqen & RTC_UF) ? | 149 | writeb(pdata->alrm_min < 0 || (pdata->irqen & RTC_UF) ? |
150 | 0x80 : BIN2BCD(pdata->alrm_min), | 150 | 0x80 : bin2bcd(pdata->alrm_min), |
151 | ioaddr + RTC_MINUTES_ALARM); | 151 | ioaddr + RTC_MINUTES_ALARM); |
152 | writeb(pdata->alrm_sec < 0 || (pdata->irqen & RTC_UF) ? | 152 | writeb(pdata->alrm_sec < 0 || (pdata->irqen & RTC_UF) ? |
153 | 0x80 : BIN2BCD(pdata->alrm_sec), | 153 | 0x80 : bin2bcd(pdata->alrm_sec), |
154 | ioaddr + RTC_SECONDS_ALARM); | 154 | ioaddr + RTC_SECONDS_ALARM); |
155 | writeb(pdata->irqen ? RTC_INTS_AE : 0, ioaddr + RTC_INTERRUPTS); | 155 | writeb(pdata->irqen ? RTC_INTS_AE : 0, ioaddr + RTC_INTERRUPTS); |
156 | readb(ioaddr + RTC_FLAGS); /* clear interrupts */ | 156 | readb(ioaddr + RTC_FLAGS); /* clear interrupts */ |
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index 24d35ede2dbf..8bc8501bffc8 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c | |||
@@ -66,17 +66,17 @@ static int ds1742_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
66 | void __iomem *ioaddr = pdata->ioaddr_rtc; | 66 | void __iomem *ioaddr = pdata->ioaddr_rtc; |
67 | u8 century; | 67 | u8 century; |
68 | 68 | ||
69 | century = BIN2BCD((tm->tm_year + 1900) / 100); | 69 | century = bin2bcd((tm->tm_year + 1900) / 100); |
70 | 70 | ||
71 | writeb(RTC_WRITE, ioaddr + RTC_CONTROL); | 71 | writeb(RTC_WRITE, ioaddr + RTC_CONTROL); |
72 | 72 | ||
73 | writeb(BIN2BCD(tm->tm_year % 100), ioaddr + RTC_YEAR); | 73 | writeb(bin2bcd(tm->tm_year % 100), ioaddr + RTC_YEAR); |
74 | writeb(BIN2BCD(tm->tm_mon + 1), ioaddr + RTC_MONTH); | 74 | writeb(bin2bcd(tm->tm_mon + 1), ioaddr + RTC_MONTH); |
75 | writeb(BIN2BCD(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY); | 75 | writeb(bin2bcd(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY); |
76 | writeb(BIN2BCD(tm->tm_mday), ioaddr + RTC_DATE); | 76 | writeb(bin2bcd(tm->tm_mday), ioaddr + RTC_DATE); |
77 | writeb(BIN2BCD(tm->tm_hour), ioaddr + RTC_HOURS); | 77 | writeb(bin2bcd(tm->tm_hour), ioaddr + RTC_HOURS); |
78 | writeb(BIN2BCD(tm->tm_min), ioaddr + RTC_MINUTES); | 78 | writeb(bin2bcd(tm->tm_min), ioaddr + RTC_MINUTES); |
79 | writeb(BIN2BCD(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS); | 79 | writeb(bin2bcd(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS); |
80 | 80 | ||
81 | /* RTC_CENTURY and RTC_CONTROL share same register */ | 81 | /* RTC_CENTURY and RTC_CONTROL share same register */ |
82 | writeb(RTC_WRITE | (century & RTC_CENTURY_MASK), ioaddr + RTC_CENTURY); | 82 | writeb(RTC_WRITE | (century & RTC_CENTURY_MASK), ioaddr + RTC_CENTURY); |
@@ -106,14 +106,14 @@ static int ds1742_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
106 | year = readb(ioaddr + RTC_YEAR); | 106 | year = readb(ioaddr + RTC_YEAR); |
107 | century = readb(ioaddr + RTC_CENTURY) & RTC_CENTURY_MASK; | 107 | century = readb(ioaddr + RTC_CENTURY) & RTC_CENTURY_MASK; |
108 | writeb(0, ioaddr + RTC_CONTROL); | 108 | writeb(0, ioaddr + RTC_CONTROL); |
109 | tm->tm_sec = BCD2BIN(second); | 109 | tm->tm_sec = bcd2bin(second); |
110 | tm->tm_min = BCD2BIN(minute); | 110 | tm->tm_min = bcd2bin(minute); |
111 | tm->tm_hour = BCD2BIN(hour); | 111 | tm->tm_hour = bcd2bin(hour); |
112 | tm->tm_mday = BCD2BIN(day); | 112 | tm->tm_mday = bcd2bin(day); |
113 | tm->tm_wday = BCD2BIN(week); | 113 | tm->tm_wday = bcd2bin(week); |
114 | tm->tm_mon = BCD2BIN(month) - 1; | 114 | tm->tm_mon = bcd2bin(month) - 1; |
115 | /* year is 1900 + tm->tm_year */ | 115 | /* year is 1900 + tm->tm_year */ |
116 | tm->tm_year = BCD2BIN(year) + BCD2BIN(century) * 100 - 1900; | 116 | tm->tm_year = bcd2bin(year) + bcd2bin(century) * 100 - 1900; |
117 | 117 | ||
118 | if (rtc_valid_tm(tm) < 0) { | 118 | if (rtc_valid_tm(tm) < 0) { |
119 | dev_err(dev, "retrieved date/time is not valid.\n"); | 119 | dev_err(dev, "retrieved date/time is not valid.\n"); |
diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c index abfdfcbaa059..3a7be11cc6b9 100644 --- a/drivers/rtc/rtc-fm3130.c +++ b/drivers/rtc/rtc-fm3130.c | |||
@@ -131,17 +131,17 @@ static int fm3130_get_time(struct device *dev, struct rtc_time *t) | |||
131 | fm3130->regs[0xc], fm3130->regs[0xd], | 131 | fm3130->regs[0xc], fm3130->regs[0xd], |
132 | fm3130->regs[0xe]); | 132 | fm3130->regs[0xe]); |
133 | 133 | ||
134 | t->tm_sec = BCD2BIN(fm3130->regs[FM3130_RTC_SECONDS] & 0x7f); | 134 | t->tm_sec = bcd2bin(fm3130->regs[FM3130_RTC_SECONDS] & 0x7f); |
135 | t->tm_min = BCD2BIN(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f); | 135 | t->tm_min = bcd2bin(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f); |
136 | tmp = fm3130->regs[FM3130_RTC_HOURS] & 0x3f; | 136 | tmp = fm3130->regs[FM3130_RTC_HOURS] & 0x3f; |
137 | t->tm_hour = BCD2BIN(tmp); | 137 | t->tm_hour = bcd2bin(tmp); |
138 | t->tm_wday = BCD2BIN(fm3130->regs[FM3130_RTC_DAY] & 0x07) - 1; | 138 | t->tm_wday = bcd2bin(fm3130->regs[FM3130_RTC_DAY] & 0x07) - 1; |
139 | t->tm_mday = BCD2BIN(fm3130->regs[FM3130_RTC_DATE] & 0x3f); | 139 | t->tm_mday = bcd2bin(fm3130->regs[FM3130_RTC_DATE] & 0x3f); |
140 | tmp = fm3130->regs[FM3130_RTC_MONTHS] & 0x1f; | 140 | tmp = fm3130->regs[FM3130_RTC_MONTHS] & 0x1f; |
141 | t->tm_mon = BCD2BIN(tmp) - 1; | 141 | t->tm_mon = bcd2bin(tmp) - 1; |
142 | 142 | ||
143 | /* assume 20YY not 19YY, and ignore CF bit */ | 143 | /* assume 20YY not 19YY, and ignore CF bit */ |
144 | t->tm_year = BCD2BIN(fm3130->regs[FM3130_RTC_YEARS]) + 100; | 144 | t->tm_year = bcd2bin(fm3130->regs[FM3130_RTC_YEARS]) + 100; |
145 | 145 | ||
146 | dev_dbg(dev, "%s secs=%d, mins=%d, " | 146 | dev_dbg(dev, "%s secs=%d, mins=%d, " |
147 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | 147 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", |
@@ -167,16 +167,16 @@ static int fm3130_set_time(struct device *dev, struct rtc_time *t) | |||
167 | t->tm_mon, t->tm_year, t->tm_wday); | 167 | t->tm_mon, t->tm_year, t->tm_wday); |
168 | 168 | ||
169 | /* first register addr */ | 169 | /* first register addr */ |
170 | buf[FM3130_RTC_SECONDS] = BIN2BCD(t->tm_sec); | 170 | buf[FM3130_RTC_SECONDS] = bin2bcd(t->tm_sec); |
171 | buf[FM3130_RTC_MINUTES] = BIN2BCD(t->tm_min); | 171 | buf[FM3130_RTC_MINUTES] = bin2bcd(t->tm_min); |
172 | buf[FM3130_RTC_HOURS] = BIN2BCD(t->tm_hour); | 172 | buf[FM3130_RTC_HOURS] = bin2bcd(t->tm_hour); |
173 | buf[FM3130_RTC_DAY] = BIN2BCD(t->tm_wday + 1); | 173 | buf[FM3130_RTC_DAY] = bin2bcd(t->tm_wday + 1); |
174 | buf[FM3130_RTC_DATE] = BIN2BCD(t->tm_mday); | 174 | buf[FM3130_RTC_DATE] = bin2bcd(t->tm_mday); |
175 | buf[FM3130_RTC_MONTHS] = BIN2BCD(t->tm_mon + 1); | 175 | buf[FM3130_RTC_MONTHS] = bin2bcd(t->tm_mon + 1); |
176 | 176 | ||
177 | /* assume 20YY not 19YY */ | 177 | /* assume 20YY not 19YY */ |
178 | tmp = t->tm_year - 100; | 178 | tmp = t->tm_year - 100; |
179 | buf[FM3130_RTC_YEARS] = BIN2BCD(tmp); | 179 | buf[FM3130_RTC_YEARS] = bin2bcd(tmp); |
180 | 180 | ||
181 | dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x" | 181 | dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x" |
182 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", | 182 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", |
@@ -222,11 +222,11 @@ static int fm3130_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
222 | fm3130->regs[FM3130_ALARM_MONTHS]); | 222 | fm3130->regs[FM3130_ALARM_MONTHS]); |
223 | 223 | ||
224 | 224 | ||
225 | tm->tm_sec = BCD2BIN(fm3130->regs[FM3130_ALARM_SECONDS] & 0x7F); | 225 | tm->tm_sec = bcd2bin(fm3130->regs[FM3130_ALARM_SECONDS] & 0x7F); |
226 | tm->tm_min = BCD2BIN(fm3130->regs[FM3130_ALARM_MINUTES] & 0x7F); | 226 | tm->tm_min = bcd2bin(fm3130->regs[FM3130_ALARM_MINUTES] & 0x7F); |
227 | tm->tm_hour = BCD2BIN(fm3130->regs[FM3130_ALARM_HOURS] & 0x3F); | 227 | tm->tm_hour = bcd2bin(fm3130->regs[FM3130_ALARM_HOURS] & 0x3F); |
228 | tm->tm_mday = BCD2BIN(fm3130->regs[FM3130_ALARM_DATE] & 0x3F); | 228 | tm->tm_mday = bcd2bin(fm3130->regs[FM3130_ALARM_DATE] & 0x3F); |
229 | tm->tm_mon = BCD2BIN(fm3130->regs[FM3130_ALARM_MONTHS] & 0x1F); | 229 | tm->tm_mon = bcd2bin(fm3130->regs[FM3130_ALARM_MONTHS] & 0x1F); |
230 | if (tm->tm_mon > 0) | 230 | if (tm->tm_mon > 0) |
231 | tm->tm_mon -= 1; /* RTC is 1-12, tm_mon is 0-11 */ | 231 | tm->tm_mon -= 1; /* RTC is 1-12, tm_mon is 0-11 */ |
232 | dev_dbg(dev, "%s secs=%d, mins=%d, " | 232 | dev_dbg(dev, "%s secs=%d, mins=%d, " |
@@ -252,23 +252,23 @@ static int fm3130_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
252 | 252 | ||
253 | if (tm->tm_sec != -1) | 253 | if (tm->tm_sec != -1) |
254 | fm3130->regs[FM3130_ALARM_SECONDS] = | 254 | fm3130->regs[FM3130_ALARM_SECONDS] = |
255 | BIN2BCD(tm->tm_sec) | 0x80; | 255 | bin2bcd(tm->tm_sec) | 0x80; |
256 | 256 | ||
257 | if (tm->tm_min != -1) | 257 | if (tm->tm_min != -1) |
258 | fm3130->regs[FM3130_ALARM_MINUTES] = | 258 | fm3130->regs[FM3130_ALARM_MINUTES] = |
259 | BIN2BCD(tm->tm_min) | 0x80; | 259 | bin2bcd(tm->tm_min) | 0x80; |
260 | 260 | ||
261 | if (tm->tm_hour != -1) | 261 | if (tm->tm_hour != -1) |
262 | fm3130->regs[FM3130_ALARM_HOURS] = | 262 | fm3130->regs[FM3130_ALARM_HOURS] = |
263 | BIN2BCD(tm->tm_hour) | 0x80; | 263 | bin2bcd(tm->tm_hour) | 0x80; |
264 | 264 | ||
265 | if (tm->tm_mday != -1) | 265 | if (tm->tm_mday != -1) |
266 | fm3130->regs[FM3130_ALARM_DATE] = | 266 | fm3130->regs[FM3130_ALARM_DATE] = |
267 | BIN2BCD(tm->tm_mday) | 0x80; | 267 | bin2bcd(tm->tm_mday) | 0x80; |
268 | 268 | ||
269 | if (tm->tm_mon != -1) | 269 | if (tm->tm_mon != -1) |
270 | fm3130->regs[FM3130_ALARM_MONTHS] = | 270 | fm3130->regs[FM3130_ALARM_MONTHS] = |
271 | BIN2BCD(tm->tm_mon + 1) | 0x80; | 271 | bin2bcd(tm->tm_mon + 1) | 0x80; |
272 | 272 | ||
273 | dev_dbg(dev, "alarm write %02x %02x %02x %02x %02x\n", | 273 | dev_dbg(dev, "alarm write %02x %02x %02x %02x %02x\n", |
274 | fm3130->regs[FM3130_ALARM_SECONDS], | 274 | fm3130->regs[FM3130_ALARM_SECONDS], |
@@ -414,18 +414,18 @@ static int __devinit fm3130_probe(struct i2c_client *client, | |||
414 | /* TODO */ | 414 | /* TODO */ |
415 | /* TODO need to sanity check alarm */ | 415 | /* TODO need to sanity check alarm */ |
416 | tmp = fm3130->regs[FM3130_RTC_SECONDS]; | 416 | tmp = fm3130->regs[FM3130_RTC_SECONDS]; |
417 | tmp = BCD2BIN(tmp & 0x7f); | 417 | tmp = bcd2bin(tmp & 0x7f); |
418 | if (tmp > 60) | 418 | if (tmp > 60) |
419 | goto exit_bad; | 419 | goto exit_bad; |
420 | tmp = BCD2BIN(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f); | 420 | tmp = bcd2bin(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f); |
421 | if (tmp > 60) | 421 | if (tmp > 60) |
422 | goto exit_bad; | 422 | goto exit_bad; |
423 | 423 | ||
424 | tmp = BCD2BIN(fm3130->regs[FM3130_RTC_DATE] & 0x3f); | 424 | tmp = bcd2bin(fm3130->regs[FM3130_RTC_DATE] & 0x3f); |
425 | if (tmp == 0 || tmp > 31) | 425 | if (tmp == 0 || tmp > 31) |
426 | goto exit_bad; | 426 | goto exit_bad; |
427 | 427 | ||
428 | tmp = BCD2BIN(fm3130->regs[FM3130_RTC_MONTHS] & 0x1f); | 428 | tmp = bcd2bin(fm3130->regs[FM3130_RTC_MONTHS] & 0x1f); |
429 | if (tmp == 0 || tmp > 12) | 429 | if (tmp == 0 || tmp > 12) |
430 | goto exit_bad; | 430 | goto exit_bad; |
431 | 431 | ||
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index a81adab6e515..2cd77ab8fc66 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c | |||
@@ -259,26 +259,26 @@ isl1208_i2c_read_time(struct i2c_client *client, struct rtc_time *tm) | |||
259 | return sr; | 259 | return sr; |
260 | } | 260 | } |
261 | 261 | ||
262 | tm->tm_sec = BCD2BIN(regs[ISL1208_REG_SC]); | 262 | tm->tm_sec = bcd2bin(regs[ISL1208_REG_SC]); |
263 | tm->tm_min = BCD2BIN(regs[ISL1208_REG_MN]); | 263 | tm->tm_min = bcd2bin(regs[ISL1208_REG_MN]); |
264 | 264 | ||
265 | /* HR field has a more complex interpretation */ | 265 | /* HR field has a more complex interpretation */ |
266 | { | 266 | { |
267 | const u8 _hr = regs[ISL1208_REG_HR]; | 267 | const u8 _hr = regs[ISL1208_REG_HR]; |
268 | if (_hr & ISL1208_REG_HR_MIL) /* 24h format */ | 268 | if (_hr & ISL1208_REG_HR_MIL) /* 24h format */ |
269 | tm->tm_hour = BCD2BIN(_hr & 0x3f); | 269 | tm->tm_hour = bcd2bin(_hr & 0x3f); |
270 | else { | 270 | else { |
271 | /* 12h format */ | 271 | /* 12h format */ |
272 | tm->tm_hour = BCD2BIN(_hr & 0x1f); | 272 | tm->tm_hour = bcd2bin(_hr & 0x1f); |
273 | if (_hr & ISL1208_REG_HR_PM) /* PM flag set */ | 273 | if (_hr & ISL1208_REG_HR_PM) /* PM flag set */ |
274 | tm->tm_hour += 12; | 274 | tm->tm_hour += 12; |
275 | } | 275 | } |
276 | } | 276 | } |
277 | 277 | ||
278 | tm->tm_mday = BCD2BIN(regs[ISL1208_REG_DT]); | 278 | tm->tm_mday = bcd2bin(regs[ISL1208_REG_DT]); |
279 | tm->tm_mon = BCD2BIN(regs[ISL1208_REG_MO]) - 1; /* rtc starts at 1 */ | 279 | tm->tm_mon = bcd2bin(regs[ISL1208_REG_MO]) - 1; /* rtc starts at 1 */ |
280 | tm->tm_year = BCD2BIN(regs[ISL1208_REG_YR]) + 100; | 280 | tm->tm_year = bcd2bin(regs[ISL1208_REG_YR]) + 100; |
281 | tm->tm_wday = BCD2BIN(regs[ISL1208_REG_DW]); | 281 | tm->tm_wday = bcd2bin(regs[ISL1208_REG_DW]); |
282 | 282 | ||
283 | return 0; | 283 | return 0; |
284 | } | 284 | } |
@@ -305,13 +305,13 @@ isl1208_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm) | |||
305 | } | 305 | } |
306 | 306 | ||
307 | /* MSB of each alarm register is an enable bit */ | 307 | /* MSB of each alarm register is an enable bit */ |
308 | tm->tm_sec = BCD2BIN(regs[ISL1208_REG_SCA - ISL1208_REG_SCA] & 0x7f); | 308 | tm->tm_sec = bcd2bin(regs[ISL1208_REG_SCA - ISL1208_REG_SCA] & 0x7f); |
309 | tm->tm_min = BCD2BIN(regs[ISL1208_REG_MNA - ISL1208_REG_SCA] & 0x7f); | 309 | tm->tm_min = bcd2bin(regs[ISL1208_REG_MNA - ISL1208_REG_SCA] & 0x7f); |
310 | tm->tm_hour = BCD2BIN(regs[ISL1208_REG_HRA - ISL1208_REG_SCA] & 0x3f); | 310 | tm->tm_hour = bcd2bin(regs[ISL1208_REG_HRA - ISL1208_REG_SCA] & 0x3f); |
311 | tm->tm_mday = BCD2BIN(regs[ISL1208_REG_DTA - ISL1208_REG_SCA] & 0x3f); | 311 | tm->tm_mday = bcd2bin(regs[ISL1208_REG_DTA - ISL1208_REG_SCA] & 0x3f); |
312 | tm->tm_mon = | 312 | tm->tm_mon = |
313 | BCD2BIN(regs[ISL1208_REG_MOA - ISL1208_REG_SCA] & 0x1f) - 1; | 313 | bcd2bin(regs[ISL1208_REG_MOA - ISL1208_REG_SCA] & 0x1f) - 1; |
314 | tm->tm_wday = BCD2BIN(regs[ISL1208_REG_DWA - ISL1208_REG_SCA] & 0x03); | 314 | tm->tm_wday = bcd2bin(regs[ISL1208_REG_DWA - ISL1208_REG_SCA] & 0x03); |
315 | 315 | ||
316 | return 0; | 316 | return 0; |
317 | } | 317 | } |
@@ -328,15 +328,15 @@ isl1208_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm) | |||
328 | int sr; | 328 | int sr; |
329 | u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, }; | 329 | u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, }; |
330 | 330 | ||
331 | regs[ISL1208_REG_SC] = BIN2BCD(tm->tm_sec); | 331 | regs[ISL1208_REG_SC] = bin2bcd(tm->tm_sec); |
332 | regs[ISL1208_REG_MN] = BIN2BCD(tm->tm_min); | 332 | regs[ISL1208_REG_MN] = bin2bcd(tm->tm_min); |
333 | regs[ISL1208_REG_HR] = BIN2BCD(tm->tm_hour) | ISL1208_REG_HR_MIL; | 333 | regs[ISL1208_REG_HR] = bin2bcd(tm->tm_hour) | ISL1208_REG_HR_MIL; |
334 | 334 | ||
335 | regs[ISL1208_REG_DT] = BIN2BCD(tm->tm_mday); | 335 | regs[ISL1208_REG_DT] = bin2bcd(tm->tm_mday); |
336 | regs[ISL1208_REG_MO] = BIN2BCD(tm->tm_mon + 1); | 336 | regs[ISL1208_REG_MO] = bin2bcd(tm->tm_mon + 1); |
337 | regs[ISL1208_REG_YR] = BIN2BCD(tm->tm_year - 100); | 337 | regs[ISL1208_REG_YR] = bin2bcd(tm->tm_year - 100); |
338 | 338 | ||
339 | regs[ISL1208_REG_DW] = BIN2BCD(tm->tm_wday & 7); | 339 | regs[ISL1208_REG_DW] = bin2bcd(tm->tm_wday & 7); |
340 | 340 | ||
341 | sr = isl1208_i2c_get_sr(client); | 341 | sr = isl1208_i2c_get_sr(client); |
342 | if (sr < 0) { | 342 | if (sr < 0) { |
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 470fb2d29545..893f7dece239 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c | |||
@@ -110,15 +110,15 @@ static int m41t80_get_datetime(struct i2c_client *client, | |||
110 | return -EIO; | 110 | return -EIO; |
111 | } | 111 | } |
112 | 112 | ||
113 | tm->tm_sec = BCD2BIN(buf[M41T80_REG_SEC] & 0x7f); | 113 | tm->tm_sec = bcd2bin(buf[M41T80_REG_SEC] & 0x7f); |
114 | tm->tm_min = BCD2BIN(buf[M41T80_REG_MIN] & 0x7f); | 114 | tm->tm_min = bcd2bin(buf[M41T80_REG_MIN] & 0x7f); |
115 | tm->tm_hour = BCD2BIN(buf[M41T80_REG_HOUR] & 0x3f); | 115 | tm->tm_hour = bcd2bin(buf[M41T80_REG_HOUR] & 0x3f); |
116 | tm->tm_mday = BCD2BIN(buf[M41T80_REG_DAY] & 0x3f); | 116 | tm->tm_mday = bcd2bin(buf[M41T80_REG_DAY] & 0x3f); |
117 | tm->tm_wday = buf[M41T80_REG_WDAY] & 0x07; | 117 | tm->tm_wday = buf[M41T80_REG_WDAY] & 0x07; |
118 | tm->tm_mon = BCD2BIN(buf[M41T80_REG_MON] & 0x1f) - 1; | 118 | tm->tm_mon = bcd2bin(buf[M41T80_REG_MON] & 0x1f) - 1; |
119 | 119 | ||
120 | /* assume 20YY not 19YY, and ignore the Century Bit */ | 120 | /* assume 20YY not 19YY, and ignore the Century Bit */ |
121 | tm->tm_year = BCD2BIN(buf[M41T80_REG_YEAR]) + 100; | 121 | tm->tm_year = bcd2bin(buf[M41T80_REG_YEAR]) + 100; |
122 | return 0; | 122 | return 0; |
123 | } | 123 | } |
124 | 124 | ||
@@ -161,19 +161,19 @@ static int m41t80_set_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
161 | /* Merge time-data and register flags into buf[0..7] */ | 161 | /* Merge time-data and register flags into buf[0..7] */ |
162 | buf[M41T80_REG_SSEC] = 0; | 162 | buf[M41T80_REG_SSEC] = 0; |
163 | buf[M41T80_REG_SEC] = | 163 | buf[M41T80_REG_SEC] = |
164 | BIN2BCD(tm->tm_sec) | (buf[M41T80_REG_SEC] & ~0x7f); | 164 | bin2bcd(tm->tm_sec) | (buf[M41T80_REG_SEC] & ~0x7f); |
165 | buf[M41T80_REG_MIN] = | 165 | buf[M41T80_REG_MIN] = |
166 | BIN2BCD(tm->tm_min) | (buf[M41T80_REG_MIN] & ~0x7f); | 166 | bin2bcd(tm->tm_min) | (buf[M41T80_REG_MIN] & ~0x7f); |
167 | buf[M41T80_REG_HOUR] = | 167 | buf[M41T80_REG_HOUR] = |
168 | BIN2BCD(tm->tm_hour) | (buf[M41T80_REG_HOUR] & ~0x3f) ; | 168 | bin2bcd(tm->tm_hour) | (buf[M41T80_REG_HOUR] & ~0x3f) ; |
169 | buf[M41T80_REG_WDAY] = | 169 | buf[M41T80_REG_WDAY] = |
170 | (tm->tm_wday & 0x07) | (buf[M41T80_REG_WDAY] & ~0x07); | 170 | (tm->tm_wday & 0x07) | (buf[M41T80_REG_WDAY] & ~0x07); |
171 | buf[M41T80_REG_DAY] = | 171 | buf[M41T80_REG_DAY] = |
172 | BIN2BCD(tm->tm_mday) | (buf[M41T80_REG_DAY] & ~0x3f); | 172 | bin2bcd(tm->tm_mday) | (buf[M41T80_REG_DAY] & ~0x3f); |
173 | buf[M41T80_REG_MON] = | 173 | buf[M41T80_REG_MON] = |
174 | BIN2BCD(tm->tm_mon + 1) | (buf[M41T80_REG_MON] & ~0x1f); | 174 | bin2bcd(tm->tm_mon + 1) | (buf[M41T80_REG_MON] & ~0x1f); |
175 | /* assume 20YY not 19YY */ | 175 | /* assume 20YY not 19YY */ |
176 | buf[M41T80_REG_YEAR] = BIN2BCD(tm->tm_year % 100); | 176 | buf[M41T80_REG_YEAR] = bin2bcd(tm->tm_year % 100); |
177 | 177 | ||
178 | if (i2c_transfer(client->adapter, msgs, 1) != 1) { | 178 | if (i2c_transfer(client->adapter, msgs, 1) != 1) { |
179 | dev_err(&client->dev, "write error\n"); | 179 | dev_err(&client->dev, "write error\n"); |
@@ -288,15 +288,15 @@ static int m41t80_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
288 | 288 | ||
289 | wbuf[0] = M41T80_REG_ALARM_MON; /* offset into rtc's regs */ | 289 | wbuf[0] = M41T80_REG_ALARM_MON; /* offset into rtc's regs */ |
290 | reg[M41T80_REG_ALARM_SEC] |= t->time.tm_sec >= 0 ? | 290 | reg[M41T80_REG_ALARM_SEC] |= t->time.tm_sec >= 0 ? |
291 | BIN2BCD(t->time.tm_sec) : 0x80; | 291 | bin2bcd(t->time.tm_sec) : 0x80; |
292 | reg[M41T80_REG_ALARM_MIN] |= t->time.tm_min >= 0 ? | 292 | reg[M41T80_REG_ALARM_MIN] |= t->time.tm_min >= 0 ? |
293 | BIN2BCD(t->time.tm_min) : 0x80; | 293 | bin2bcd(t->time.tm_min) : 0x80; |
294 | reg[M41T80_REG_ALARM_HOUR] |= t->time.tm_hour >= 0 ? | 294 | reg[M41T80_REG_ALARM_HOUR] |= t->time.tm_hour >= 0 ? |
295 | BIN2BCD(t->time.tm_hour) : 0x80; | 295 | bin2bcd(t->time.tm_hour) : 0x80; |
296 | reg[M41T80_REG_ALARM_DAY] |= t->time.tm_mday >= 0 ? | 296 | reg[M41T80_REG_ALARM_DAY] |= t->time.tm_mday >= 0 ? |
297 | BIN2BCD(t->time.tm_mday) : 0x80; | 297 | bin2bcd(t->time.tm_mday) : 0x80; |
298 | if (t->time.tm_mon >= 0) | 298 | if (t->time.tm_mon >= 0) |
299 | reg[M41T80_REG_ALARM_MON] |= BIN2BCD(t->time.tm_mon + 1); | 299 | reg[M41T80_REG_ALARM_MON] |= bin2bcd(t->time.tm_mon + 1); |
300 | else | 300 | else |
301 | reg[M41T80_REG_ALARM_DAY] |= 0x40; | 301 | reg[M41T80_REG_ALARM_DAY] |= 0x40; |
302 | 302 | ||
@@ -347,15 +347,15 @@ static int m41t80_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
347 | t->time.tm_mday = -1; | 347 | t->time.tm_mday = -1; |
348 | t->time.tm_mon = -1; | 348 | t->time.tm_mon = -1; |
349 | if (!(reg[M41T80_REG_ALARM_SEC] & 0x80)) | 349 | if (!(reg[M41T80_REG_ALARM_SEC] & 0x80)) |
350 | t->time.tm_sec = BCD2BIN(reg[M41T80_REG_ALARM_SEC] & 0x7f); | 350 | t->time.tm_sec = bcd2bin(reg[M41T80_REG_ALARM_SEC] & 0x7f); |
351 | if (!(reg[M41T80_REG_ALARM_MIN] & 0x80)) | 351 | if (!(reg[M41T80_REG_ALARM_MIN] & 0x80)) |
352 | t->time.tm_min = BCD2BIN(reg[M41T80_REG_ALARM_MIN] & 0x7f); | 352 | t->time.tm_min = bcd2bin(reg[M41T80_REG_ALARM_MIN] & 0x7f); |
353 | if (!(reg[M41T80_REG_ALARM_HOUR] & 0x80)) | 353 | if (!(reg[M41T80_REG_ALARM_HOUR] & 0x80)) |
354 | t->time.tm_hour = BCD2BIN(reg[M41T80_REG_ALARM_HOUR] & 0x3f); | 354 | t->time.tm_hour = bcd2bin(reg[M41T80_REG_ALARM_HOUR] & 0x3f); |
355 | if (!(reg[M41T80_REG_ALARM_DAY] & 0x80)) | 355 | if (!(reg[M41T80_REG_ALARM_DAY] & 0x80)) |
356 | t->time.tm_mday = BCD2BIN(reg[M41T80_REG_ALARM_DAY] & 0x3f); | 356 | t->time.tm_mday = bcd2bin(reg[M41T80_REG_ALARM_DAY] & 0x3f); |
357 | if (!(reg[M41T80_REG_ALARM_DAY] & 0x40)) | 357 | if (!(reg[M41T80_REG_ALARM_DAY] & 0x40)) |
358 | t->time.tm_mon = BCD2BIN(reg[M41T80_REG_ALARM_MON] & 0x1f) - 1; | 358 | t->time.tm_mon = bcd2bin(reg[M41T80_REG_ALARM_MON] & 0x1f) - 1; |
359 | t->time.tm_year = -1; | 359 | t->time.tm_year = -1; |
360 | t->time.tm_wday = -1; | 360 | t->time.tm_wday = -1; |
361 | t->time.tm_yday = -1; | 361 | t->time.tm_yday = -1; |
diff --git a/drivers/rtc/rtc-m41t94.c b/drivers/rtc/rtc-m41t94.c index 9b19499c829e..c3a18c58daf6 100644 --- a/drivers/rtc/rtc-m41t94.c +++ b/drivers/rtc/rtc-m41t94.c | |||
@@ -41,17 +41,17 @@ static int m41t94_set_time(struct device *dev, struct rtc_time *tm) | |||
41 | tm->tm_mon, tm->tm_year, tm->tm_wday); | 41 | tm->tm_mon, tm->tm_year, tm->tm_wday); |
42 | 42 | ||
43 | buf[0] = 0x80 | M41T94_REG_SECONDS; /* write time + date */ | 43 | buf[0] = 0x80 | M41T94_REG_SECONDS; /* write time + date */ |
44 | buf[M41T94_REG_SECONDS] = BIN2BCD(tm->tm_sec); | 44 | buf[M41T94_REG_SECONDS] = bin2bcd(tm->tm_sec); |
45 | buf[M41T94_REG_MINUTES] = BIN2BCD(tm->tm_min); | 45 | buf[M41T94_REG_MINUTES] = bin2bcd(tm->tm_min); |
46 | buf[M41T94_REG_HOURS] = BIN2BCD(tm->tm_hour); | 46 | buf[M41T94_REG_HOURS] = bin2bcd(tm->tm_hour); |
47 | buf[M41T94_REG_WDAY] = BIN2BCD(tm->tm_wday + 1); | 47 | buf[M41T94_REG_WDAY] = bin2bcd(tm->tm_wday + 1); |
48 | buf[M41T94_REG_DAY] = BIN2BCD(tm->tm_mday); | 48 | buf[M41T94_REG_DAY] = bin2bcd(tm->tm_mday); |
49 | buf[M41T94_REG_MONTH] = BIN2BCD(tm->tm_mon + 1); | 49 | buf[M41T94_REG_MONTH] = bin2bcd(tm->tm_mon + 1); |
50 | 50 | ||
51 | buf[M41T94_REG_HOURS] |= M41T94_BIT_CEB; | 51 | buf[M41T94_REG_HOURS] |= M41T94_BIT_CEB; |
52 | if (tm->tm_year >= 100) | 52 | if (tm->tm_year >= 100) |
53 | buf[M41T94_REG_HOURS] |= M41T94_BIT_CB; | 53 | buf[M41T94_REG_HOURS] |= M41T94_BIT_CB; |
54 | buf[M41T94_REG_YEAR] = BIN2BCD(tm->tm_year % 100); | 54 | buf[M41T94_REG_YEAR] = bin2bcd(tm->tm_year % 100); |
55 | 55 | ||
56 | return spi_write(spi, buf, 8); | 56 | return spi_write(spi, buf, 8); |
57 | } | 57 | } |
@@ -82,14 +82,14 @@ static int m41t94_read_time(struct device *dev, struct rtc_time *tm) | |||
82 | spi_write(spi, buf, 2); | 82 | spi_write(spi, buf, 2); |
83 | } | 83 | } |
84 | 84 | ||
85 | tm->tm_sec = BCD2BIN(spi_w8r8(spi, M41T94_REG_SECONDS)); | 85 | tm->tm_sec = bcd2bin(spi_w8r8(spi, M41T94_REG_SECONDS)); |
86 | tm->tm_min = BCD2BIN(spi_w8r8(spi, M41T94_REG_MINUTES)); | 86 | tm->tm_min = bcd2bin(spi_w8r8(spi, M41T94_REG_MINUTES)); |
87 | hour = spi_w8r8(spi, M41T94_REG_HOURS); | 87 | hour = spi_w8r8(spi, M41T94_REG_HOURS); |
88 | tm->tm_hour = BCD2BIN(hour & 0x3f); | 88 | tm->tm_hour = bcd2bin(hour & 0x3f); |
89 | tm->tm_wday = BCD2BIN(spi_w8r8(spi, M41T94_REG_WDAY)) - 1; | 89 | tm->tm_wday = bcd2bin(spi_w8r8(spi, M41T94_REG_WDAY)) - 1; |
90 | tm->tm_mday = BCD2BIN(spi_w8r8(spi, M41T94_REG_DAY)); | 90 | tm->tm_mday = bcd2bin(spi_w8r8(spi, M41T94_REG_DAY)); |
91 | tm->tm_mon = BCD2BIN(spi_w8r8(spi, M41T94_REG_MONTH)) - 1; | 91 | tm->tm_mon = bcd2bin(spi_w8r8(spi, M41T94_REG_MONTH)) - 1; |
92 | tm->tm_year = BCD2BIN(spi_w8r8(spi, M41T94_REG_YEAR)); | 92 | tm->tm_year = bcd2bin(spi_w8r8(spi, M41T94_REG_YEAR)); |
93 | if ((hour & M41T94_BIT_CB) || !(hour & M41T94_BIT_CEB)) | 93 | if ((hour & M41T94_BIT_CB) || !(hour & M41T94_BIT_CEB)) |
94 | tm->tm_year += 100; | 94 | tm->tm_year += 100; |
95 | 95 | ||
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index ce4eff6a8d51..04b63dab6932 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c | |||
@@ -76,10 +76,10 @@ static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
76 | /* Issue the READ command */ | 76 | /* Issue the READ command */ |
77 | M48T59_SET_BITS(M48T59_CNTL_READ, M48T59_CNTL); | 77 | M48T59_SET_BITS(M48T59_CNTL_READ, M48T59_CNTL); |
78 | 78 | ||
79 | tm->tm_year = BCD2BIN(M48T59_READ(M48T59_YEAR)); | 79 | tm->tm_year = bcd2bin(M48T59_READ(M48T59_YEAR)); |
80 | /* tm_mon is 0-11 */ | 80 | /* tm_mon is 0-11 */ |
81 | tm->tm_mon = BCD2BIN(M48T59_READ(M48T59_MONTH)) - 1; | 81 | tm->tm_mon = bcd2bin(M48T59_READ(M48T59_MONTH)) - 1; |
82 | tm->tm_mday = BCD2BIN(M48T59_READ(M48T59_MDAY)); | 82 | tm->tm_mday = bcd2bin(M48T59_READ(M48T59_MDAY)); |
83 | 83 | ||
84 | val = M48T59_READ(M48T59_WDAY); | 84 | val = M48T59_READ(M48T59_WDAY); |
85 | if ((pdata->type == M48T59RTC_TYPE_M48T59) && | 85 | if ((pdata->type == M48T59RTC_TYPE_M48T59) && |
@@ -88,10 +88,10 @@ static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
88 | tm->tm_year += 100; /* one century */ | 88 | tm->tm_year += 100; /* one century */ |
89 | } | 89 | } |
90 | 90 | ||
91 | tm->tm_wday = BCD2BIN(val & 0x07); | 91 | tm->tm_wday = bcd2bin(val & 0x07); |
92 | tm->tm_hour = BCD2BIN(M48T59_READ(M48T59_HOUR) & 0x3F); | 92 | tm->tm_hour = bcd2bin(M48T59_READ(M48T59_HOUR) & 0x3F); |
93 | tm->tm_min = BCD2BIN(M48T59_READ(M48T59_MIN) & 0x7F); | 93 | tm->tm_min = bcd2bin(M48T59_READ(M48T59_MIN) & 0x7F); |
94 | tm->tm_sec = BCD2BIN(M48T59_READ(M48T59_SEC) & 0x7F); | 94 | tm->tm_sec = bcd2bin(M48T59_READ(M48T59_SEC) & 0x7F); |
95 | 95 | ||
96 | /* Clear the READ bit */ | 96 | /* Clear the READ bit */ |
97 | M48T59_CLEAR_BITS(M48T59_CNTL_READ, M48T59_CNTL); | 97 | M48T59_CLEAR_BITS(M48T59_CNTL_READ, M48T59_CNTL); |
@@ -119,17 +119,17 @@ static int m48t59_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
119 | /* Issue the WRITE command */ | 119 | /* Issue the WRITE command */ |
120 | M48T59_SET_BITS(M48T59_CNTL_WRITE, M48T59_CNTL); | 120 | M48T59_SET_BITS(M48T59_CNTL_WRITE, M48T59_CNTL); |
121 | 121 | ||
122 | M48T59_WRITE((BIN2BCD(tm->tm_sec) & 0x7F), M48T59_SEC); | 122 | M48T59_WRITE((bin2bcd(tm->tm_sec) & 0x7F), M48T59_SEC); |
123 | M48T59_WRITE((BIN2BCD(tm->tm_min) & 0x7F), M48T59_MIN); | 123 | M48T59_WRITE((bin2bcd(tm->tm_min) & 0x7F), M48T59_MIN); |
124 | M48T59_WRITE((BIN2BCD(tm->tm_hour) & 0x3F), M48T59_HOUR); | 124 | M48T59_WRITE((bin2bcd(tm->tm_hour) & 0x3F), M48T59_HOUR); |
125 | M48T59_WRITE((BIN2BCD(tm->tm_mday) & 0x3F), M48T59_MDAY); | 125 | M48T59_WRITE((bin2bcd(tm->tm_mday) & 0x3F), M48T59_MDAY); |
126 | /* tm_mon is 0-11 */ | 126 | /* tm_mon is 0-11 */ |
127 | M48T59_WRITE((BIN2BCD(tm->tm_mon + 1) & 0x1F), M48T59_MONTH); | 127 | M48T59_WRITE((bin2bcd(tm->tm_mon + 1) & 0x1F), M48T59_MONTH); |
128 | M48T59_WRITE(BIN2BCD(tm->tm_year % 100), M48T59_YEAR); | 128 | M48T59_WRITE(bin2bcd(tm->tm_year % 100), M48T59_YEAR); |
129 | 129 | ||
130 | if (pdata->type == M48T59RTC_TYPE_M48T59 && (tm->tm_year / 100)) | 130 | if (pdata->type == M48T59RTC_TYPE_M48T59 && (tm->tm_year / 100)) |
131 | val = (M48T59_WDAY_CEB | M48T59_WDAY_CB); | 131 | val = (M48T59_WDAY_CEB | M48T59_WDAY_CB); |
132 | val |= (BIN2BCD(tm->tm_wday) & 0x07); | 132 | val |= (bin2bcd(tm->tm_wday) & 0x07); |
133 | M48T59_WRITE(val, M48T59_WDAY); | 133 | M48T59_WRITE(val, M48T59_WDAY); |
134 | 134 | ||
135 | /* Clear the WRITE bit */ | 135 | /* Clear the WRITE bit */ |
@@ -158,18 +158,18 @@ static int m48t59_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
158 | /* Issue the READ command */ | 158 | /* Issue the READ command */ |
159 | M48T59_SET_BITS(M48T59_CNTL_READ, M48T59_CNTL); | 159 | M48T59_SET_BITS(M48T59_CNTL_READ, M48T59_CNTL); |
160 | 160 | ||
161 | tm->tm_year = BCD2BIN(M48T59_READ(M48T59_YEAR)); | 161 | tm->tm_year = bcd2bin(M48T59_READ(M48T59_YEAR)); |
162 | /* tm_mon is 0-11 */ | 162 | /* tm_mon is 0-11 */ |
163 | tm->tm_mon = BCD2BIN(M48T59_READ(M48T59_MONTH)) - 1; | 163 | tm->tm_mon = bcd2bin(M48T59_READ(M48T59_MONTH)) - 1; |
164 | 164 | ||
165 | val = M48T59_READ(M48T59_WDAY); | 165 | val = M48T59_READ(M48T59_WDAY); |
166 | if ((val & M48T59_WDAY_CEB) && (val & M48T59_WDAY_CB)) | 166 | if ((val & M48T59_WDAY_CEB) && (val & M48T59_WDAY_CB)) |
167 | tm->tm_year += 100; /* one century */ | 167 | tm->tm_year += 100; /* one century */ |
168 | 168 | ||
169 | tm->tm_mday = BCD2BIN(M48T59_READ(M48T59_ALARM_DATE)); | 169 | tm->tm_mday = bcd2bin(M48T59_READ(M48T59_ALARM_DATE)); |
170 | tm->tm_hour = BCD2BIN(M48T59_READ(M48T59_ALARM_HOUR)); | 170 | tm->tm_hour = bcd2bin(M48T59_READ(M48T59_ALARM_HOUR)); |
171 | tm->tm_min = BCD2BIN(M48T59_READ(M48T59_ALARM_MIN)); | 171 | tm->tm_min = bcd2bin(M48T59_READ(M48T59_ALARM_MIN)); |
172 | tm->tm_sec = BCD2BIN(M48T59_READ(M48T59_ALARM_SEC)); | 172 | tm->tm_sec = bcd2bin(M48T59_READ(M48T59_ALARM_SEC)); |
173 | 173 | ||
174 | /* Clear the READ bit */ | 174 | /* Clear the READ bit */ |
175 | M48T59_CLEAR_BITS(M48T59_CNTL_READ, M48T59_CNTL); | 175 | M48T59_CLEAR_BITS(M48T59_CNTL_READ, M48T59_CNTL); |
@@ -201,18 +201,18 @@ static int m48t59_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
201 | * 0xff means "always match" | 201 | * 0xff means "always match" |
202 | */ | 202 | */ |
203 | mday = tm->tm_mday; | 203 | mday = tm->tm_mday; |
204 | mday = (mday >= 1 && mday <= 31) ? BIN2BCD(mday) : 0xff; | 204 | mday = (mday >= 1 && mday <= 31) ? bin2bcd(mday) : 0xff; |
205 | if (mday == 0xff) | 205 | if (mday == 0xff) |
206 | mday = M48T59_READ(M48T59_MDAY); | 206 | mday = M48T59_READ(M48T59_MDAY); |
207 | 207 | ||
208 | hour = tm->tm_hour; | 208 | hour = tm->tm_hour; |
209 | hour = (hour < 24) ? BIN2BCD(hour) : 0x00; | 209 | hour = (hour < 24) ? bin2bcd(hour) : 0x00; |
210 | 210 | ||
211 | min = tm->tm_min; | 211 | min = tm->tm_min; |
212 | min = (min < 60) ? BIN2BCD(min) : 0x00; | 212 | min = (min < 60) ? bin2bcd(min) : 0x00; |
213 | 213 | ||
214 | sec = tm->tm_sec; | 214 | sec = tm->tm_sec; |
215 | sec = (sec < 60) ? BIN2BCD(sec) : 0x00; | 215 | sec = (sec < 60) ? bin2bcd(sec) : 0x00; |
216 | 216 | ||
217 | spin_lock_irqsave(&m48t59->lock, flags); | 217 | spin_lock_irqsave(&m48t59->lock, flags); |
218 | /* Issue the WRITE command */ | 218 | /* Issue the WRITE command */ |
@@ -360,7 +360,6 @@ static struct bin_attribute m48t59_nvram_attr = { | |||
360 | .attr = { | 360 | .attr = { |
361 | .name = "nvram", | 361 | .name = "nvram", |
362 | .mode = S_IRUGO | S_IWUSR, | 362 | .mode = S_IRUGO | S_IWUSR, |
363 | .owner = THIS_MODULE, | ||
364 | }, | 363 | }, |
365 | .read = m48t59_nvram_read, | 364 | .read = m48t59_nvram_read, |
366 | .write = m48t59_nvram_write, | 365 | .write = m48t59_nvram_write, |
diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c index 3f7f99a5d96a..7c045cffa9ff 100644 --- a/drivers/rtc/rtc-m48t86.c +++ b/drivers/rtc/rtc-m48t86.c | |||
@@ -62,14 +62,14 @@ static int m48t86_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
62 | tm->tm_wday = ops->readbyte(M48T86_REG_DOW); | 62 | tm->tm_wday = ops->readbyte(M48T86_REG_DOW); |
63 | } else { | 63 | } else { |
64 | /* bcd mode */ | 64 | /* bcd mode */ |
65 | tm->tm_sec = BCD2BIN(ops->readbyte(M48T86_REG_SEC)); | 65 | tm->tm_sec = bcd2bin(ops->readbyte(M48T86_REG_SEC)); |
66 | tm->tm_min = BCD2BIN(ops->readbyte(M48T86_REG_MIN)); | 66 | tm->tm_min = bcd2bin(ops->readbyte(M48T86_REG_MIN)); |
67 | tm->tm_hour = BCD2BIN(ops->readbyte(M48T86_REG_HOUR) & 0x3F); | 67 | tm->tm_hour = bcd2bin(ops->readbyte(M48T86_REG_HOUR) & 0x3F); |
68 | tm->tm_mday = BCD2BIN(ops->readbyte(M48T86_REG_DOM)); | 68 | tm->tm_mday = bcd2bin(ops->readbyte(M48T86_REG_DOM)); |
69 | /* tm_mon is 0-11 */ | 69 | /* tm_mon is 0-11 */ |
70 | tm->tm_mon = BCD2BIN(ops->readbyte(M48T86_REG_MONTH)) - 1; | 70 | tm->tm_mon = bcd2bin(ops->readbyte(M48T86_REG_MONTH)) - 1; |
71 | tm->tm_year = BCD2BIN(ops->readbyte(M48T86_REG_YEAR)) + 100; | 71 | tm->tm_year = bcd2bin(ops->readbyte(M48T86_REG_YEAR)) + 100; |
72 | tm->tm_wday = BCD2BIN(ops->readbyte(M48T86_REG_DOW)); | 72 | tm->tm_wday = bcd2bin(ops->readbyte(M48T86_REG_DOW)); |
73 | } | 73 | } |
74 | 74 | ||
75 | /* correct the hour if the clock is in 12h mode */ | 75 | /* correct the hour if the clock is in 12h mode */ |
@@ -103,13 +103,13 @@ static int m48t86_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
103 | ops->writebyte(tm->tm_wday, M48T86_REG_DOW); | 103 | ops->writebyte(tm->tm_wday, M48T86_REG_DOW); |
104 | } else { | 104 | } else { |
105 | /* bcd mode */ | 105 | /* bcd mode */ |
106 | ops->writebyte(BIN2BCD(tm->tm_sec), M48T86_REG_SEC); | 106 | ops->writebyte(bin2bcd(tm->tm_sec), M48T86_REG_SEC); |
107 | ops->writebyte(BIN2BCD(tm->tm_min), M48T86_REG_MIN); | 107 | ops->writebyte(bin2bcd(tm->tm_min), M48T86_REG_MIN); |
108 | ops->writebyte(BIN2BCD(tm->tm_hour), M48T86_REG_HOUR); | 108 | ops->writebyte(bin2bcd(tm->tm_hour), M48T86_REG_HOUR); |
109 | ops->writebyte(BIN2BCD(tm->tm_mday), M48T86_REG_DOM); | 109 | ops->writebyte(bin2bcd(tm->tm_mday), M48T86_REG_DOM); |
110 | ops->writebyte(BIN2BCD(tm->tm_mon + 1), M48T86_REG_MONTH); | 110 | ops->writebyte(bin2bcd(tm->tm_mon + 1), M48T86_REG_MONTH); |
111 | ops->writebyte(BIN2BCD(tm->tm_year % 100), M48T86_REG_YEAR); | 111 | ops->writebyte(bin2bcd(tm->tm_year % 100), M48T86_REG_YEAR); |
112 | ops->writebyte(BIN2BCD(tm->tm_wday), M48T86_REG_DOW); | 112 | ops->writebyte(bin2bcd(tm->tm_wday), M48T86_REG_DOW); |
113 | } | 113 | } |
114 | 114 | ||
115 | /* update ended */ | 115 | /* update ended */ |
diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c index 12c9cd25cad8..80782798763f 100644 --- a/drivers/rtc/rtc-max6900.c +++ b/drivers/rtc/rtc-max6900.c | |||
@@ -150,14 +150,14 @@ static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm) | |||
150 | if (rc < 0) | 150 | if (rc < 0) |
151 | return rc; | 151 | return rc; |
152 | 152 | ||
153 | tm->tm_sec = BCD2BIN(regs[MAX6900_REG_SC]); | 153 | tm->tm_sec = bcd2bin(regs[MAX6900_REG_SC]); |
154 | tm->tm_min = BCD2BIN(regs[MAX6900_REG_MN]); | 154 | tm->tm_min = bcd2bin(regs[MAX6900_REG_MN]); |
155 | tm->tm_hour = BCD2BIN(regs[MAX6900_REG_HR] & 0x3f); | 155 | tm->tm_hour = bcd2bin(regs[MAX6900_REG_HR] & 0x3f); |
156 | tm->tm_mday = BCD2BIN(regs[MAX6900_REG_DT]); | 156 | tm->tm_mday = bcd2bin(regs[MAX6900_REG_DT]); |
157 | tm->tm_mon = BCD2BIN(regs[MAX6900_REG_MO]) - 1; | 157 | tm->tm_mon = bcd2bin(regs[MAX6900_REG_MO]) - 1; |
158 | tm->tm_year = BCD2BIN(regs[MAX6900_REG_YR]) + | 158 | tm->tm_year = bcd2bin(regs[MAX6900_REG_YR]) + |
159 | BCD2BIN(regs[MAX6900_REG_CENTURY]) * 100 - 1900; | 159 | bcd2bin(regs[MAX6900_REG_CENTURY]) * 100 - 1900; |
160 | tm->tm_wday = BCD2BIN(regs[MAX6900_REG_DW]); | 160 | tm->tm_wday = bcd2bin(regs[MAX6900_REG_DW]); |
161 | 161 | ||
162 | return 0; | 162 | return 0; |
163 | } | 163 | } |
@@ -184,14 +184,14 @@ max6900_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm) | |||
184 | if (rc < 0) | 184 | if (rc < 0) |
185 | return rc; | 185 | return rc; |
186 | 186 | ||
187 | regs[MAX6900_REG_SC] = BIN2BCD(tm->tm_sec); | 187 | regs[MAX6900_REG_SC] = bin2bcd(tm->tm_sec); |
188 | regs[MAX6900_REG_MN] = BIN2BCD(tm->tm_min); | 188 | regs[MAX6900_REG_MN] = bin2bcd(tm->tm_min); |
189 | regs[MAX6900_REG_HR] = BIN2BCD(tm->tm_hour); | 189 | regs[MAX6900_REG_HR] = bin2bcd(tm->tm_hour); |
190 | regs[MAX6900_REG_DT] = BIN2BCD(tm->tm_mday); | 190 | regs[MAX6900_REG_DT] = bin2bcd(tm->tm_mday); |
191 | regs[MAX6900_REG_MO] = BIN2BCD(tm->tm_mon + 1); | 191 | regs[MAX6900_REG_MO] = bin2bcd(tm->tm_mon + 1); |
192 | regs[MAX6900_REG_DW] = BIN2BCD(tm->tm_wday); | 192 | regs[MAX6900_REG_DW] = bin2bcd(tm->tm_wday); |
193 | regs[MAX6900_REG_YR] = BIN2BCD(tm->tm_year % 100); | 193 | regs[MAX6900_REG_YR] = bin2bcd(tm->tm_year % 100); |
194 | regs[MAX6900_REG_CENTURY] = BIN2BCD((tm->tm_year + 1900) / 100); | 194 | regs[MAX6900_REG_CENTURY] = bin2bcd((tm->tm_year + 1900) / 100); |
195 | /* set write protect */ | 195 | /* set write protect */ |
196 | regs[MAX6900_REG_CT] = MAX6900_REG_CT_WP; | 196 | regs[MAX6900_REG_CT] = MAX6900_REG_CT_WP; |
197 | 197 | ||
diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c index 78b2551fb19d..2f6507df7b49 100644 --- a/drivers/rtc/rtc-max6902.c +++ b/drivers/rtc/rtc-max6902.c | |||
@@ -124,15 +124,15 @@ static int max6902_get_datetime(struct device *dev, struct rtc_time *dt) | |||
124 | 124 | ||
125 | /* The chip sends data in this order: | 125 | /* The chip sends data in this order: |
126 | * Seconds, Minutes, Hours, Date, Month, Day, Year */ | 126 | * Seconds, Minutes, Hours, Date, Month, Day, Year */ |
127 | dt->tm_sec = BCD2BIN(chip->buf[1]); | 127 | dt->tm_sec = bcd2bin(chip->buf[1]); |
128 | dt->tm_min = BCD2BIN(chip->buf[2]); | 128 | dt->tm_min = bcd2bin(chip->buf[2]); |
129 | dt->tm_hour = BCD2BIN(chip->buf[3]); | 129 | dt->tm_hour = bcd2bin(chip->buf[3]); |
130 | dt->tm_mday = BCD2BIN(chip->buf[4]); | 130 | dt->tm_mday = bcd2bin(chip->buf[4]); |
131 | dt->tm_mon = BCD2BIN(chip->buf[5]) - 1; | 131 | dt->tm_mon = bcd2bin(chip->buf[5]) - 1; |
132 | dt->tm_wday = BCD2BIN(chip->buf[6]); | 132 | dt->tm_wday = bcd2bin(chip->buf[6]); |
133 | dt->tm_year = BCD2BIN(chip->buf[7]); | 133 | dt->tm_year = bcd2bin(chip->buf[7]); |
134 | 134 | ||
135 | century = BCD2BIN(tmp) * 100; | 135 | century = bcd2bin(tmp) * 100; |
136 | 136 | ||
137 | dt->tm_year += century; | 137 | dt->tm_year += century; |
138 | dt->tm_year -= 1900; | 138 | dt->tm_year -= 1900; |
@@ -168,15 +168,15 @@ static int max6902_set_datetime(struct device *dev, struct rtc_time *dt) | |||
168 | /* Remove write protection */ | 168 | /* Remove write protection */ |
169 | max6902_set_reg(dev, 0xF, 0); | 169 | max6902_set_reg(dev, 0xF, 0); |
170 | 170 | ||
171 | max6902_set_reg(dev, 0x01, BIN2BCD(dt->tm_sec)); | 171 | max6902_set_reg(dev, 0x01, bin2bcd(dt->tm_sec)); |
172 | max6902_set_reg(dev, 0x03, BIN2BCD(dt->tm_min)); | 172 | max6902_set_reg(dev, 0x03, bin2bcd(dt->tm_min)); |
173 | max6902_set_reg(dev, 0x05, BIN2BCD(dt->tm_hour)); | 173 | max6902_set_reg(dev, 0x05, bin2bcd(dt->tm_hour)); |
174 | 174 | ||
175 | max6902_set_reg(dev, 0x07, BIN2BCD(dt->tm_mday)); | 175 | max6902_set_reg(dev, 0x07, bin2bcd(dt->tm_mday)); |
176 | max6902_set_reg(dev, 0x09, BIN2BCD(dt->tm_mon+1)); | 176 | max6902_set_reg(dev, 0x09, bin2bcd(dt->tm_mon+1)); |
177 | max6902_set_reg(dev, 0x0B, BIN2BCD(dt->tm_wday)); | 177 | max6902_set_reg(dev, 0x0B, bin2bcd(dt->tm_wday)); |
178 | max6902_set_reg(dev, 0x0D, BIN2BCD(dt->tm_year%100)); | 178 | max6902_set_reg(dev, 0x0D, bin2bcd(dt->tm_year%100)); |
179 | max6902_set_reg(dev, 0x13, BIN2BCD(dt->tm_year/100)); | 179 | max6902_set_reg(dev, 0x13, bin2bcd(dt->tm_year/100)); |
180 | 180 | ||
181 | /* Compulab used a delay here. However, the datasheet | 181 | /* Compulab used a delay here. However, the datasheet |
182 | * does not mention a delay being required anywhere... */ | 182 | * does not mention a delay being required anywhere... */ |
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 8876605d4d4b..2cbeb0794f14 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c | |||
@@ -186,30 +186,30 @@ static int tm2bcd(struct rtc_time *tm) | |||
186 | if (rtc_valid_tm(tm) != 0) | 186 | if (rtc_valid_tm(tm) != 0) |
187 | return -EINVAL; | 187 | return -EINVAL; |
188 | 188 | ||
189 | tm->tm_sec = BIN2BCD(tm->tm_sec); | 189 | tm->tm_sec = bin2bcd(tm->tm_sec); |
190 | tm->tm_min = BIN2BCD(tm->tm_min); | 190 | tm->tm_min = bin2bcd(tm->tm_min); |
191 | tm->tm_hour = BIN2BCD(tm->tm_hour); | 191 | tm->tm_hour = bin2bcd(tm->tm_hour); |
192 | tm->tm_mday = BIN2BCD(tm->tm_mday); | 192 | tm->tm_mday = bin2bcd(tm->tm_mday); |
193 | 193 | ||
194 | tm->tm_mon = BIN2BCD(tm->tm_mon + 1); | 194 | tm->tm_mon = bin2bcd(tm->tm_mon + 1); |
195 | 195 | ||
196 | /* epoch == 1900 */ | 196 | /* epoch == 1900 */ |
197 | if (tm->tm_year < 100 || tm->tm_year > 199) | 197 | if (tm->tm_year < 100 || tm->tm_year > 199) |
198 | return -EINVAL; | 198 | return -EINVAL; |
199 | tm->tm_year = BIN2BCD(tm->tm_year - 100); | 199 | tm->tm_year = bin2bcd(tm->tm_year - 100); |
200 | 200 | ||
201 | return 0; | 201 | return 0; |
202 | } | 202 | } |
203 | 203 | ||
204 | static void bcd2tm(struct rtc_time *tm) | 204 | static void bcd2tm(struct rtc_time *tm) |
205 | { | 205 | { |
206 | tm->tm_sec = BCD2BIN(tm->tm_sec); | 206 | tm->tm_sec = bcd2bin(tm->tm_sec); |
207 | tm->tm_min = BCD2BIN(tm->tm_min); | 207 | tm->tm_min = bcd2bin(tm->tm_min); |
208 | tm->tm_hour = BCD2BIN(tm->tm_hour); | 208 | tm->tm_hour = bcd2bin(tm->tm_hour); |
209 | tm->tm_mday = BCD2BIN(tm->tm_mday); | 209 | tm->tm_mday = bcd2bin(tm->tm_mday); |
210 | tm->tm_mon = BCD2BIN(tm->tm_mon) - 1; | 210 | tm->tm_mon = bcd2bin(tm->tm_mon) - 1; |
211 | /* epoch == 1900 */ | 211 | /* epoch == 1900 */ |
212 | tm->tm_year = BCD2BIN(tm->tm_year) + 100; | 212 | tm->tm_year = bcd2bin(tm->tm_year) + 100; |
213 | } | 213 | } |
214 | 214 | ||
215 | 215 | ||
diff --git a/drivers/rtc/rtc-parisc.c b/drivers/rtc/rtc-parisc.c new file mode 100644 index 000000000000..346d633655e7 --- /dev/null +++ b/drivers/rtc/rtc-parisc.c | |||
@@ -0,0 +1,111 @@ | |||
1 | /* rtc-parisc: RTC for HP PA-RISC firmware | ||
2 | * | ||
3 | * Copyright (C) 2008 Kyle McMartin <kyle@mcmartin.ca> | ||
4 | */ | ||
5 | |||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/module.h> | ||
8 | #include <linux/time.h> | ||
9 | #include <linux/platform_device.h> | ||
10 | |||
11 | #include <asm/rtc.h> | ||
12 | |||
13 | /* as simple as can be, and no simpler. */ | ||
14 | struct parisc_rtc { | ||
15 | struct rtc_device *rtc; | ||
16 | spinlock_t lock; | ||
17 | }; | ||
18 | |||
19 | static int parisc_get_time(struct device *dev, struct rtc_time *tm) | ||
20 | { | ||
21 | struct parisc_rtc *p = dev_get_drvdata(dev); | ||
22 | unsigned long flags, ret; | ||
23 | |||
24 | spin_lock_irqsave(&p->lock, flags); | ||
25 | ret = get_rtc_time(tm); | ||
26 | spin_unlock_irqrestore(&p->lock, flags); | ||
27 | |||
28 | if (ret & RTC_BATT_BAD) | ||
29 | return -EOPNOTSUPP; | ||
30 | |||
31 | return 0; | ||
32 | } | ||
33 | |||
34 | static int parisc_set_time(struct device *dev, struct rtc_time *tm) | ||
35 | { | ||
36 | struct parisc_rtc *p = dev_get_drvdata(dev); | ||
37 | unsigned long flags, ret; | ||
38 | |||
39 | spin_lock_irqsave(&p->lock, flags); | ||
40 | ret = set_rtc_time(tm); | ||
41 | spin_unlock_irqrestore(&p->lock, flags); | ||
42 | |||
43 | if (ret < 0) | ||
44 | return -EOPNOTSUPP; | ||
45 | |||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | static const struct rtc_class_ops parisc_rtc_ops = { | ||
50 | .read_time = parisc_get_time, | ||
51 | .set_time = parisc_set_time, | ||
52 | }; | ||
53 | |||
54 | static int __devinit parisc_rtc_probe(struct platform_device *dev) | ||
55 | { | ||
56 | struct parisc_rtc *p; | ||
57 | |||
58 | p = kzalloc(sizeof (*p), GFP_KERNEL); | ||
59 | if (!p) | ||
60 | return -ENOMEM; | ||
61 | |||
62 | spin_lock_init(&p->lock); | ||
63 | |||
64 | p->rtc = rtc_device_register("rtc-parisc", &dev->dev, &parisc_rtc_ops, | ||
65 | THIS_MODULE); | ||
66 | if (IS_ERR(p->rtc)) { | ||
67 | int err = PTR_ERR(p->rtc); | ||
68 | kfree(p); | ||
69 | return err; | ||
70 | } | ||
71 | |||
72 | platform_set_drvdata(dev, p); | ||
73 | |||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static int __devexit parisc_rtc_remove(struct platform_device *dev) | ||
78 | { | ||
79 | struct parisc_rtc *p = platform_get_drvdata(dev); | ||
80 | |||
81 | rtc_device_unregister(p->rtc); | ||
82 | kfree(p); | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static struct platform_driver parisc_rtc_driver = { | ||
88 | .driver = { | ||
89 | .name = "rtc-parisc", | ||
90 | .owner = THIS_MODULE, | ||
91 | }, | ||
92 | .probe = parisc_rtc_probe, | ||
93 | .remove = __devexit_p(parisc_rtc_remove), | ||
94 | }; | ||
95 | |||
96 | static int __init parisc_rtc_init(void) | ||
97 | { | ||
98 | return platform_driver_register(&parisc_rtc_driver); | ||
99 | } | ||
100 | |||
101 | static void __exit parisc_rtc_fini(void) | ||
102 | { | ||
103 | platform_driver_unregister(&parisc_rtc_driver); | ||
104 | } | ||
105 | |||
106 | module_init(parisc_rtc_init); | ||
107 | module_exit(parisc_rtc_fini); | ||
108 | |||
109 | MODULE_AUTHOR("Kyle McMartin <kyle@mcmartin.ca>"); | ||
110 | MODULE_LICENSE("GPL"); | ||
111 | MODULE_DESCRIPTION("HP PA-RISC RTC driver"); | ||
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index a829f20ad6d6..b725913ccbe8 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c | |||
@@ -97,13 +97,13 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
97 | buf[8]); | 97 | buf[8]); |
98 | 98 | ||
99 | 99 | ||
100 | tm->tm_sec = BCD2BIN(buf[PCF8563_REG_SC] & 0x7F); | 100 | tm->tm_sec = bcd2bin(buf[PCF8563_REG_SC] & 0x7F); |
101 | tm->tm_min = BCD2BIN(buf[PCF8563_REG_MN] & 0x7F); | 101 | tm->tm_min = bcd2bin(buf[PCF8563_REG_MN] & 0x7F); |
102 | tm->tm_hour = BCD2BIN(buf[PCF8563_REG_HR] & 0x3F); /* rtc hr 0-23 */ | 102 | tm->tm_hour = bcd2bin(buf[PCF8563_REG_HR] & 0x3F); /* rtc hr 0-23 */ |
103 | tm->tm_mday = BCD2BIN(buf[PCF8563_REG_DM] & 0x3F); | 103 | tm->tm_mday = bcd2bin(buf[PCF8563_REG_DM] & 0x3F); |
104 | tm->tm_wday = buf[PCF8563_REG_DW] & 0x07; | 104 | tm->tm_wday = buf[PCF8563_REG_DW] & 0x07; |
105 | tm->tm_mon = BCD2BIN(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */ | 105 | tm->tm_mon = bcd2bin(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */ |
106 | tm->tm_year = BCD2BIN(buf[PCF8563_REG_YR]); | 106 | tm->tm_year = bcd2bin(buf[PCF8563_REG_YR]); |
107 | if (tm->tm_year < 70) | 107 | if (tm->tm_year < 70) |
108 | tm->tm_year += 100; /* assume we are in 1970...2069 */ | 108 | tm->tm_year += 100; /* assume we are in 1970...2069 */ |
109 | /* detect the polarity heuristically. see note above. */ | 109 | /* detect the polarity heuristically. see note above. */ |
@@ -138,17 +138,17 @@ static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
138 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | 138 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); |
139 | 139 | ||
140 | /* hours, minutes and seconds */ | 140 | /* hours, minutes and seconds */ |
141 | buf[PCF8563_REG_SC] = BIN2BCD(tm->tm_sec); | 141 | buf[PCF8563_REG_SC] = bin2bcd(tm->tm_sec); |
142 | buf[PCF8563_REG_MN] = BIN2BCD(tm->tm_min); | 142 | buf[PCF8563_REG_MN] = bin2bcd(tm->tm_min); |
143 | buf[PCF8563_REG_HR] = BIN2BCD(tm->tm_hour); | 143 | buf[PCF8563_REG_HR] = bin2bcd(tm->tm_hour); |
144 | 144 | ||
145 | buf[PCF8563_REG_DM] = BIN2BCD(tm->tm_mday); | 145 | buf[PCF8563_REG_DM] = bin2bcd(tm->tm_mday); |
146 | 146 | ||
147 | /* month, 1 - 12 */ | 147 | /* month, 1 - 12 */ |
148 | buf[PCF8563_REG_MO] = BIN2BCD(tm->tm_mon + 1); | 148 | buf[PCF8563_REG_MO] = bin2bcd(tm->tm_mon + 1); |
149 | 149 | ||
150 | /* year and century */ | 150 | /* year and century */ |
151 | buf[PCF8563_REG_YR] = BIN2BCD(tm->tm_year % 100); | 151 | buf[PCF8563_REG_YR] = bin2bcd(tm->tm_year % 100); |
152 | if (pcf8563->c_polarity ? (tm->tm_year >= 100) : (tm->tm_year < 100)) | 152 | if (pcf8563->c_polarity ? (tm->tm_year >= 100) : (tm->tm_year < 100)) |
153 | buf[PCF8563_REG_MO] |= PCF8563_MO_C; | 153 | buf[PCF8563_REG_MO] |= PCF8563_MO_C; |
154 | 154 | ||
diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c index d388c662bf4b..7d33cda3f8f6 100644 --- a/drivers/rtc/rtc-pcf8583.c +++ b/drivers/rtc/rtc-pcf8583.c | |||
@@ -76,11 +76,11 @@ static int pcf8583_get_datetime(struct i2c_client *client, struct rtc_time *dt) | |||
76 | buf[4] &= 0x3f; | 76 | buf[4] &= 0x3f; |
77 | buf[5] &= 0x1f; | 77 | buf[5] &= 0x1f; |
78 | 78 | ||
79 | dt->tm_sec = BCD2BIN(buf[1]); | 79 | dt->tm_sec = bcd2bin(buf[1]); |
80 | dt->tm_min = BCD2BIN(buf[2]); | 80 | dt->tm_min = bcd2bin(buf[2]); |
81 | dt->tm_hour = BCD2BIN(buf[3]); | 81 | dt->tm_hour = bcd2bin(buf[3]); |
82 | dt->tm_mday = BCD2BIN(buf[4]); | 82 | dt->tm_mday = bcd2bin(buf[4]); |
83 | dt->tm_mon = BCD2BIN(buf[5]) - 1; | 83 | dt->tm_mon = bcd2bin(buf[5]) - 1; |
84 | } | 84 | } |
85 | 85 | ||
86 | return ret == 2 ? 0 : -EIO; | 86 | return ret == 2 ? 0 : -EIO; |
@@ -94,14 +94,14 @@ static int pcf8583_set_datetime(struct i2c_client *client, struct rtc_time *dt, | |||
94 | buf[0] = 0; | 94 | buf[0] = 0; |
95 | buf[1] = get_ctrl(client) | 0x80; | 95 | buf[1] = get_ctrl(client) | 0x80; |
96 | buf[2] = 0; | 96 | buf[2] = 0; |
97 | buf[3] = BIN2BCD(dt->tm_sec); | 97 | buf[3] = bin2bcd(dt->tm_sec); |
98 | buf[4] = BIN2BCD(dt->tm_min); | 98 | buf[4] = bin2bcd(dt->tm_min); |
99 | buf[5] = BIN2BCD(dt->tm_hour); | 99 | buf[5] = bin2bcd(dt->tm_hour); |
100 | 100 | ||
101 | if (datetoo) { | 101 | if (datetoo) { |
102 | len = 8; | 102 | len = 8; |
103 | buf[6] = BIN2BCD(dt->tm_mday) | (dt->tm_year << 6); | 103 | buf[6] = bin2bcd(dt->tm_mday) | (dt->tm_year << 6); |
104 | buf[7] = BIN2BCD(dt->tm_mon + 1) | (dt->tm_wday << 5); | 104 | buf[7] = bin2bcd(dt->tm_mon + 1) | (dt->tm_wday << 5); |
105 | } | 105 | } |
106 | 106 | ||
107 | ret = i2c_master_send(client, (char *)buf, len); | 107 | ret = i2c_master_send(client, (char *)buf, len); |
diff --git a/drivers/rtc/rtc-r9701.c b/drivers/rtc/rtc-r9701.c index 395985b339c9..42028f233bef 100644 --- a/drivers/rtc/rtc-r9701.c +++ b/drivers/rtc/rtc-r9701.c | |||
@@ -80,13 +80,13 @@ static int r9701_get_datetime(struct device *dev, struct rtc_time *dt) | |||
80 | 80 | ||
81 | memset(dt, 0, sizeof(*dt)); | 81 | memset(dt, 0, sizeof(*dt)); |
82 | 82 | ||
83 | dt->tm_sec = BCD2BIN(buf[0]); /* RSECCNT */ | 83 | dt->tm_sec = bcd2bin(buf[0]); /* RSECCNT */ |
84 | dt->tm_min = BCD2BIN(buf[1]); /* RMINCNT */ | 84 | dt->tm_min = bcd2bin(buf[1]); /* RMINCNT */ |
85 | dt->tm_hour = BCD2BIN(buf[2]); /* RHRCNT */ | 85 | dt->tm_hour = bcd2bin(buf[2]); /* RHRCNT */ |
86 | 86 | ||
87 | dt->tm_mday = BCD2BIN(buf[3]); /* RDAYCNT */ | 87 | dt->tm_mday = bcd2bin(buf[3]); /* RDAYCNT */ |
88 | dt->tm_mon = BCD2BIN(buf[4]) - 1; /* RMONCNT */ | 88 | dt->tm_mon = bcd2bin(buf[4]) - 1; /* RMONCNT */ |
89 | dt->tm_year = BCD2BIN(buf[5]) + 100; /* RYRCNT */ | 89 | dt->tm_year = bcd2bin(buf[5]) + 100; /* RYRCNT */ |
90 | 90 | ||
91 | /* the rtc device may contain illegal values on power up | 91 | /* the rtc device may contain illegal values on power up |
92 | * according to the data sheet. make sure they are valid. | 92 | * according to the data sheet. make sure they are valid. |
@@ -103,12 +103,12 @@ static int r9701_set_datetime(struct device *dev, struct rtc_time *dt) | |||
103 | if (year >= 2100 || year < 2000) | 103 | if (year >= 2100 || year < 2000) |
104 | return -EINVAL; | 104 | return -EINVAL; |
105 | 105 | ||
106 | ret = write_reg(dev, RHRCNT, BIN2BCD(dt->tm_hour)); | 106 | ret = write_reg(dev, RHRCNT, bin2bcd(dt->tm_hour)); |
107 | ret = ret ? ret : write_reg(dev, RMINCNT, BIN2BCD(dt->tm_min)); | 107 | ret = ret ? ret : write_reg(dev, RMINCNT, bin2bcd(dt->tm_min)); |
108 | ret = ret ? ret : write_reg(dev, RSECCNT, BIN2BCD(dt->tm_sec)); | 108 | ret = ret ? ret : write_reg(dev, RSECCNT, bin2bcd(dt->tm_sec)); |
109 | ret = ret ? ret : write_reg(dev, RDAYCNT, BIN2BCD(dt->tm_mday)); | 109 | ret = ret ? ret : write_reg(dev, RDAYCNT, bin2bcd(dt->tm_mday)); |
110 | ret = ret ? ret : write_reg(dev, RMONCNT, BIN2BCD(dt->tm_mon + 1)); | 110 | ret = ret ? ret : write_reg(dev, RMONCNT, bin2bcd(dt->tm_mon + 1)); |
111 | ret = ret ? ret : write_reg(dev, RYRCNT, BIN2BCD(dt->tm_year - 100)); | 111 | ret = ret ? ret : write_reg(dev, RYRCNT, bin2bcd(dt->tm_year - 100)); |
112 | ret = ret ? ret : write_reg(dev, RWKCNT, 1 << dt->tm_wday); | 112 | ret = ret ? ret : write_reg(dev, RWKCNT, 1 << dt->tm_wday); |
113 | 113 | ||
114 | return ret; | 114 | return ret; |
diff --git a/drivers/rtc/rtc-rs5c313.c b/drivers/rtc/rtc-rs5c313.c index 1c14d4497c4d..e6ea3f5ee1eb 100644 --- a/drivers/rtc/rtc-rs5c313.c +++ b/drivers/rtc/rtc-rs5c313.c | |||
@@ -235,33 +235,33 @@ static int rs5c313_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
235 | 235 | ||
236 | data = rs5c313_read_reg(RS5C313_ADDR_SEC); | 236 | data = rs5c313_read_reg(RS5C313_ADDR_SEC); |
237 | data |= (rs5c313_read_reg(RS5C313_ADDR_SEC10) << 4); | 237 | data |= (rs5c313_read_reg(RS5C313_ADDR_SEC10) << 4); |
238 | tm->tm_sec = BCD2BIN(data); | 238 | tm->tm_sec = bcd2bin(data); |
239 | 239 | ||
240 | data = rs5c313_read_reg(RS5C313_ADDR_MIN); | 240 | data = rs5c313_read_reg(RS5C313_ADDR_MIN); |
241 | data |= (rs5c313_read_reg(RS5C313_ADDR_MIN10) << 4); | 241 | data |= (rs5c313_read_reg(RS5C313_ADDR_MIN10) << 4); |
242 | tm->tm_min = BCD2BIN(data); | 242 | tm->tm_min = bcd2bin(data); |
243 | 243 | ||
244 | data = rs5c313_read_reg(RS5C313_ADDR_HOUR); | 244 | data = rs5c313_read_reg(RS5C313_ADDR_HOUR); |
245 | data |= (rs5c313_read_reg(RS5C313_ADDR_HOUR10) << 4); | 245 | data |= (rs5c313_read_reg(RS5C313_ADDR_HOUR10) << 4); |
246 | tm->tm_hour = BCD2BIN(data); | 246 | tm->tm_hour = bcd2bin(data); |
247 | 247 | ||
248 | data = rs5c313_read_reg(RS5C313_ADDR_DAY); | 248 | data = rs5c313_read_reg(RS5C313_ADDR_DAY); |
249 | data |= (rs5c313_read_reg(RS5C313_ADDR_DAY10) << 4); | 249 | data |= (rs5c313_read_reg(RS5C313_ADDR_DAY10) << 4); |
250 | tm->tm_mday = BCD2BIN(data); | 250 | tm->tm_mday = bcd2bin(data); |
251 | 251 | ||
252 | data = rs5c313_read_reg(RS5C313_ADDR_MON); | 252 | data = rs5c313_read_reg(RS5C313_ADDR_MON); |
253 | data |= (rs5c313_read_reg(RS5C313_ADDR_MON10) << 4); | 253 | data |= (rs5c313_read_reg(RS5C313_ADDR_MON10) << 4); |
254 | tm->tm_mon = BCD2BIN(data) - 1; | 254 | tm->tm_mon = bcd2bin(data) - 1; |
255 | 255 | ||
256 | data = rs5c313_read_reg(RS5C313_ADDR_YEAR); | 256 | data = rs5c313_read_reg(RS5C313_ADDR_YEAR); |
257 | data |= (rs5c313_read_reg(RS5C313_ADDR_YEAR10) << 4); | 257 | data |= (rs5c313_read_reg(RS5C313_ADDR_YEAR10) << 4); |
258 | tm->tm_year = BCD2BIN(data); | 258 | tm->tm_year = bcd2bin(data); |
259 | 259 | ||
260 | if (tm->tm_year < 70) | 260 | if (tm->tm_year < 70) |
261 | tm->tm_year += 100; | 261 | tm->tm_year += 100; |
262 | 262 | ||
263 | data = rs5c313_read_reg(RS5C313_ADDR_WEEK); | 263 | data = rs5c313_read_reg(RS5C313_ADDR_WEEK); |
264 | tm->tm_wday = BCD2BIN(data); | 264 | tm->tm_wday = bcd2bin(data); |
265 | 265 | ||
266 | RS5C313_CEDISABLE; | 266 | RS5C313_CEDISABLE; |
267 | ndelay(700); /* CE:L */ | 267 | ndelay(700); /* CE:L */ |
@@ -294,31 +294,31 @@ static int rs5c313_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
294 | } | 294 | } |
295 | } | 295 | } |
296 | 296 | ||
297 | data = BIN2BCD(tm->tm_sec); | 297 | data = bin2bcd(tm->tm_sec); |
298 | rs5c313_write_reg(RS5C313_ADDR_SEC, data); | 298 | rs5c313_write_reg(RS5C313_ADDR_SEC, data); |
299 | rs5c313_write_reg(RS5C313_ADDR_SEC10, (data >> 4)); | 299 | rs5c313_write_reg(RS5C313_ADDR_SEC10, (data >> 4)); |
300 | 300 | ||
301 | data = BIN2BCD(tm->tm_min); | 301 | data = bin2bcd(tm->tm_min); |
302 | rs5c313_write_reg(RS5C313_ADDR_MIN, data ); | 302 | rs5c313_write_reg(RS5C313_ADDR_MIN, data ); |
303 | rs5c313_write_reg(RS5C313_ADDR_MIN10, (data >> 4)); | 303 | rs5c313_write_reg(RS5C313_ADDR_MIN10, (data >> 4)); |
304 | 304 | ||
305 | data = BIN2BCD(tm->tm_hour); | 305 | data = bin2bcd(tm->tm_hour); |
306 | rs5c313_write_reg(RS5C313_ADDR_HOUR, data); | 306 | rs5c313_write_reg(RS5C313_ADDR_HOUR, data); |
307 | rs5c313_write_reg(RS5C313_ADDR_HOUR10, (data >> 4)); | 307 | rs5c313_write_reg(RS5C313_ADDR_HOUR10, (data >> 4)); |
308 | 308 | ||
309 | data = BIN2BCD(tm->tm_mday); | 309 | data = bin2bcd(tm->tm_mday); |
310 | rs5c313_write_reg(RS5C313_ADDR_DAY, data); | 310 | rs5c313_write_reg(RS5C313_ADDR_DAY, data); |
311 | rs5c313_write_reg(RS5C313_ADDR_DAY10, (data>> 4)); | 311 | rs5c313_write_reg(RS5C313_ADDR_DAY10, (data>> 4)); |
312 | 312 | ||
313 | data = BIN2BCD(tm->tm_mon + 1); | 313 | data = bin2bcd(tm->tm_mon + 1); |
314 | rs5c313_write_reg(RS5C313_ADDR_MON, data); | 314 | rs5c313_write_reg(RS5C313_ADDR_MON, data); |
315 | rs5c313_write_reg(RS5C313_ADDR_MON10, (data >> 4)); | 315 | rs5c313_write_reg(RS5C313_ADDR_MON10, (data >> 4)); |
316 | 316 | ||
317 | data = BIN2BCD(tm->tm_year % 100); | 317 | data = bin2bcd(tm->tm_year % 100); |
318 | rs5c313_write_reg(RS5C313_ADDR_YEAR, data); | 318 | rs5c313_write_reg(RS5C313_ADDR_YEAR, data); |
319 | rs5c313_write_reg(RS5C313_ADDR_YEAR10, (data >> 4)); | 319 | rs5c313_write_reg(RS5C313_ADDR_YEAR10, (data >> 4)); |
320 | 320 | ||
321 | data = BIN2BCD(tm->tm_wday); | 321 | data = bin2bcd(tm->tm_wday); |
322 | rs5c313_write_reg(RS5C313_ADDR_WEEK, data); | 322 | rs5c313_write_reg(RS5C313_ADDR_WEEK, data); |
323 | 323 | ||
324 | RS5C313_CEDISABLE; /* CE:H */ | 324 | RS5C313_CEDISABLE; /* CE:H */ |
diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c index 839462659afa..dd1e2bc7a472 100644 --- a/drivers/rtc/rtc-rs5c348.c +++ b/drivers/rtc/rtc-rs5c348.c | |||
@@ -74,20 +74,20 @@ rs5c348_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
74 | txbuf[3] = 0; /* dummy */ | 74 | txbuf[3] = 0; /* dummy */ |
75 | txbuf[4] = RS5C348_CMD_MW(RS5C348_REG_SECS); /* cmd, sec, ... */ | 75 | txbuf[4] = RS5C348_CMD_MW(RS5C348_REG_SECS); /* cmd, sec, ... */ |
76 | txp = &txbuf[5]; | 76 | txp = &txbuf[5]; |
77 | txp[RS5C348_REG_SECS] = BIN2BCD(tm->tm_sec); | 77 | txp[RS5C348_REG_SECS] = bin2bcd(tm->tm_sec); |
78 | txp[RS5C348_REG_MINS] = BIN2BCD(tm->tm_min); | 78 | txp[RS5C348_REG_MINS] = bin2bcd(tm->tm_min); |
79 | if (pdata->rtc_24h) { | 79 | if (pdata->rtc_24h) { |
80 | txp[RS5C348_REG_HOURS] = BIN2BCD(tm->tm_hour); | 80 | txp[RS5C348_REG_HOURS] = bin2bcd(tm->tm_hour); |
81 | } else { | 81 | } else { |
82 | /* hour 0 is AM12, noon is PM12 */ | 82 | /* hour 0 is AM12, noon is PM12 */ |
83 | txp[RS5C348_REG_HOURS] = BIN2BCD((tm->tm_hour + 11) % 12 + 1) | | 83 | txp[RS5C348_REG_HOURS] = bin2bcd((tm->tm_hour + 11) % 12 + 1) | |
84 | (tm->tm_hour >= 12 ? RS5C348_BIT_PM : 0); | 84 | (tm->tm_hour >= 12 ? RS5C348_BIT_PM : 0); |
85 | } | 85 | } |
86 | txp[RS5C348_REG_WDAY] = BIN2BCD(tm->tm_wday); | 86 | txp[RS5C348_REG_WDAY] = bin2bcd(tm->tm_wday); |
87 | txp[RS5C348_REG_DAY] = BIN2BCD(tm->tm_mday); | 87 | txp[RS5C348_REG_DAY] = bin2bcd(tm->tm_mday); |
88 | txp[RS5C348_REG_MONTH] = BIN2BCD(tm->tm_mon + 1) | | 88 | txp[RS5C348_REG_MONTH] = bin2bcd(tm->tm_mon + 1) | |
89 | (tm->tm_year >= 100 ? RS5C348_BIT_Y2K : 0); | 89 | (tm->tm_year >= 100 ? RS5C348_BIT_Y2K : 0); |
90 | txp[RS5C348_REG_YEAR] = BIN2BCD(tm->tm_year % 100); | 90 | txp[RS5C348_REG_YEAR] = bin2bcd(tm->tm_year % 100); |
91 | /* write in one transfer to avoid data inconsistency */ | 91 | /* write in one transfer to avoid data inconsistency */ |
92 | ret = spi_write_then_read(spi, txbuf, sizeof(txbuf), NULL, 0); | 92 | ret = spi_write_then_read(spi, txbuf, sizeof(txbuf), NULL, 0); |
93 | udelay(62); /* Tcsr 62us */ | 93 | udelay(62); /* Tcsr 62us */ |
@@ -116,20 +116,20 @@ rs5c348_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
116 | if (ret < 0) | 116 | if (ret < 0) |
117 | return ret; | 117 | return ret; |
118 | 118 | ||
119 | tm->tm_sec = BCD2BIN(rxbuf[RS5C348_REG_SECS] & RS5C348_SECS_MASK); | 119 | tm->tm_sec = bcd2bin(rxbuf[RS5C348_REG_SECS] & RS5C348_SECS_MASK); |
120 | tm->tm_min = BCD2BIN(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK); | 120 | tm->tm_min = bcd2bin(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK); |
121 | tm->tm_hour = BCD2BIN(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK); | 121 | tm->tm_hour = bcd2bin(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK); |
122 | if (!pdata->rtc_24h) { | 122 | if (!pdata->rtc_24h) { |
123 | tm->tm_hour %= 12; | 123 | tm->tm_hour %= 12; |
124 | if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) | 124 | if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) |
125 | tm->tm_hour += 12; | 125 | tm->tm_hour += 12; |
126 | } | 126 | } |
127 | tm->tm_wday = BCD2BIN(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK); | 127 | tm->tm_wday = bcd2bin(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK); |
128 | tm->tm_mday = BCD2BIN(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK); | 128 | tm->tm_mday = bcd2bin(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK); |
129 | tm->tm_mon = | 129 | tm->tm_mon = |
130 | BCD2BIN(rxbuf[RS5C348_REG_MONTH] & RS5C348_MONTH_MASK) - 1; | 130 | bcd2bin(rxbuf[RS5C348_REG_MONTH] & RS5C348_MONTH_MASK) - 1; |
131 | /* year is 1900 + tm->tm_year */ | 131 | /* year is 1900 + tm->tm_year */ |
132 | tm->tm_year = BCD2BIN(rxbuf[RS5C348_REG_YEAR]) + | 132 | tm->tm_year = bcd2bin(rxbuf[RS5C348_REG_YEAR]) + |
133 | ((rxbuf[RS5C348_REG_MONTH] & RS5C348_BIT_Y2K) ? 100 : 0); | 133 | ((rxbuf[RS5C348_REG_MONTH] & RS5C348_BIT_Y2K) ? 100 : 0); |
134 | 134 | ||
135 | if (rtc_valid_tm(tm) < 0) { | 135 | if (rtc_valid_tm(tm) < 0) { |
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index 8b561958fb1e..2f2c68d476da 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c | |||
@@ -148,9 +148,9 @@ static unsigned rs5c_reg2hr(struct rs5c372 *rs5c, unsigned reg) | |||
148 | unsigned hour; | 148 | unsigned hour; |
149 | 149 | ||
150 | if (rs5c->time24) | 150 | if (rs5c->time24) |
151 | return BCD2BIN(reg & 0x3f); | 151 | return bcd2bin(reg & 0x3f); |
152 | 152 | ||
153 | hour = BCD2BIN(reg & 0x1f); | 153 | hour = bcd2bin(reg & 0x1f); |
154 | if (hour == 12) | 154 | if (hour == 12) |
155 | hour = 0; | 155 | hour = 0; |
156 | if (reg & 0x20) | 156 | if (reg & 0x20) |
@@ -161,15 +161,15 @@ static unsigned rs5c_reg2hr(struct rs5c372 *rs5c, unsigned reg) | |||
161 | static unsigned rs5c_hr2reg(struct rs5c372 *rs5c, unsigned hour) | 161 | static unsigned rs5c_hr2reg(struct rs5c372 *rs5c, unsigned hour) |
162 | { | 162 | { |
163 | if (rs5c->time24) | 163 | if (rs5c->time24) |
164 | return BIN2BCD(hour); | 164 | return bin2bcd(hour); |
165 | 165 | ||
166 | if (hour > 12) | 166 | if (hour > 12) |
167 | return 0x20 | BIN2BCD(hour - 12); | 167 | return 0x20 | bin2bcd(hour - 12); |
168 | if (hour == 12) | 168 | if (hour == 12) |
169 | return 0x20 | BIN2BCD(12); | 169 | return 0x20 | bin2bcd(12); |
170 | if (hour == 0) | 170 | if (hour == 0) |
171 | return BIN2BCD(12); | 171 | return bin2bcd(12); |
172 | return BIN2BCD(hour); | 172 | return bin2bcd(hour); |
173 | } | 173 | } |
174 | 174 | ||
175 | static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm) | 175 | static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm) |
@@ -180,18 +180,18 @@ static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
180 | if (status < 0) | 180 | if (status < 0) |
181 | return status; | 181 | return status; |
182 | 182 | ||
183 | tm->tm_sec = BCD2BIN(rs5c->regs[RS5C372_REG_SECS] & 0x7f); | 183 | tm->tm_sec = bcd2bin(rs5c->regs[RS5C372_REG_SECS] & 0x7f); |
184 | tm->tm_min = BCD2BIN(rs5c->regs[RS5C372_REG_MINS] & 0x7f); | 184 | tm->tm_min = bcd2bin(rs5c->regs[RS5C372_REG_MINS] & 0x7f); |
185 | tm->tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C372_REG_HOURS]); | 185 | tm->tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C372_REG_HOURS]); |
186 | 186 | ||
187 | tm->tm_wday = BCD2BIN(rs5c->regs[RS5C372_REG_WDAY] & 0x07); | 187 | tm->tm_wday = bcd2bin(rs5c->regs[RS5C372_REG_WDAY] & 0x07); |
188 | tm->tm_mday = BCD2BIN(rs5c->regs[RS5C372_REG_DAY] & 0x3f); | 188 | tm->tm_mday = bcd2bin(rs5c->regs[RS5C372_REG_DAY] & 0x3f); |
189 | 189 | ||
190 | /* tm->tm_mon is zero-based */ | 190 | /* tm->tm_mon is zero-based */ |
191 | tm->tm_mon = BCD2BIN(rs5c->regs[RS5C372_REG_MONTH] & 0x1f) - 1; | 191 | tm->tm_mon = bcd2bin(rs5c->regs[RS5C372_REG_MONTH] & 0x1f) - 1; |
192 | 192 | ||
193 | /* year is 1900 + tm->tm_year */ | 193 | /* year is 1900 + tm->tm_year */ |
194 | tm->tm_year = BCD2BIN(rs5c->regs[RS5C372_REG_YEAR]) + 100; | 194 | tm->tm_year = bcd2bin(rs5c->regs[RS5C372_REG_YEAR]) + 100; |
195 | 195 | ||
196 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " | 196 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " |
197 | "mday=%d, mon=%d, year=%d, wday=%d\n", | 197 | "mday=%d, mon=%d, year=%d, wday=%d\n", |
@@ -216,13 +216,13 @@ static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
216 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | 216 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); |
217 | 217 | ||
218 | addr = RS5C_ADDR(RS5C372_REG_SECS); | 218 | addr = RS5C_ADDR(RS5C372_REG_SECS); |
219 | buf[0] = BIN2BCD(tm->tm_sec); | 219 | buf[0] = bin2bcd(tm->tm_sec); |
220 | buf[1] = BIN2BCD(tm->tm_min); | 220 | buf[1] = bin2bcd(tm->tm_min); |
221 | buf[2] = rs5c_hr2reg(rs5c, tm->tm_hour); | 221 | buf[2] = rs5c_hr2reg(rs5c, tm->tm_hour); |
222 | buf[3] = BIN2BCD(tm->tm_wday); | 222 | buf[3] = bin2bcd(tm->tm_wday); |
223 | buf[4] = BIN2BCD(tm->tm_mday); | 223 | buf[4] = bin2bcd(tm->tm_mday); |
224 | buf[5] = BIN2BCD(tm->tm_mon + 1); | 224 | buf[5] = bin2bcd(tm->tm_mon + 1); |
225 | buf[6] = BIN2BCD(tm->tm_year - 100); | 225 | buf[6] = bin2bcd(tm->tm_year - 100); |
226 | 226 | ||
227 | if (i2c_smbus_write_i2c_block_data(client, addr, sizeof(buf), buf) < 0) { | 227 | if (i2c_smbus_write_i2c_block_data(client, addr, sizeof(buf), buf) < 0) { |
228 | dev_err(&client->dev, "%s: write error\n", __func__); | 228 | dev_err(&client->dev, "%s: write error\n", __func__); |
@@ -367,7 +367,7 @@ static int rs5c_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
367 | 367 | ||
368 | /* report alarm time */ | 368 | /* report alarm time */ |
369 | t->time.tm_sec = 0; | 369 | t->time.tm_sec = 0; |
370 | t->time.tm_min = BCD2BIN(rs5c->regs[RS5C_REG_ALARM_A_MIN] & 0x7f); | 370 | t->time.tm_min = bcd2bin(rs5c->regs[RS5C_REG_ALARM_A_MIN] & 0x7f); |
371 | t->time.tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C_REG_ALARM_A_HOURS]); | 371 | t->time.tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C_REG_ALARM_A_HOURS]); |
372 | t->time.tm_mday = -1; | 372 | t->time.tm_mday = -1; |
373 | t->time.tm_mon = -1; | 373 | t->time.tm_mon = -1; |
@@ -413,7 +413,7 @@ static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
413 | } | 413 | } |
414 | 414 | ||
415 | /* set alarm */ | 415 | /* set alarm */ |
416 | buf[0] = BIN2BCD(t->time.tm_min); | 416 | buf[0] = bin2bcd(t->time.tm_min); |
417 | buf[1] = rs5c_hr2reg(rs5c, t->time.tm_hour); | 417 | buf[1] = rs5c_hr2reg(rs5c, t->time.tm_hour); |
418 | buf[2] = 0x7f; /* any/all days */ | 418 | buf[2] = 0x7f; /* any/all days */ |
419 | 419 | ||
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index a6fa1f2f2ca6..def4d396d0b0 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c | |||
@@ -104,12 +104,12 @@ static int s35390a_disable_test_mode(struct s35390a *s35390a) | |||
104 | static char s35390a_hr2reg(struct s35390a *s35390a, int hour) | 104 | static char s35390a_hr2reg(struct s35390a *s35390a, int hour) |
105 | { | 105 | { |
106 | if (s35390a->twentyfourhour) | 106 | if (s35390a->twentyfourhour) |
107 | return BIN2BCD(hour); | 107 | return bin2bcd(hour); |
108 | 108 | ||
109 | if (hour < 12) | 109 | if (hour < 12) |
110 | return BIN2BCD(hour); | 110 | return bin2bcd(hour); |
111 | 111 | ||
112 | return 0x40 | BIN2BCD(hour - 12); | 112 | return 0x40 | bin2bcd(hour - 12); |
113 | } | 113 | } |
114 | 114 | ||
115 | static int s35390a_reg2hr(struct s35390a *s35390a, char reg) | 115 | static int s35390a_reg2hr(struct s35390a *s35390a, char reg) |
@@ -117,9 +117,9 @@ static int s35390a_reg2hr(struct s35390a *s35390a, char reg) | |||
117 | unsigned hour; | 117 | unsigned hour; |
118 | 118 | ||
119 | if (s35390a->twentyfourhour) | 119 | if (s35390a->twentyfourhour) |
120 | return BCD2BIN(reg & 0x3f); | 120 | return bcd2bin(reg & 0x3f); |
121 | 121 | ||
122 | hour = BCD2BIN(reg & 0x3f); | 122 | hour = bcd2bin(reg & 0x3f); |
123 | if (reg & 0x40) | 123 | if (reg & 0x40) |
124 | hour += 12; | 124 | hour += 12; |
125 | 125 | ||
@@ -137,13 +137,13 @@ static int s35390a_set_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
137 | tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, | 137 | tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, |
138 | tm->tm_wday); | 138 | tm->tm_wday); |
139 | 139 | ||
140 | buf[S35390A_BYTE_YEAR] = BIN2BCD(tm->tm_year - 100); | 140 | buf[S35390A_BYTE_YEAR] = bin2bcd(tm->tm_year - 100); |
141 | buf[S35390A_BYTE_MONTH] = BIN2BCD(tm->tm_mon + 1); | 141 | buf[S35390A_BYTE_MONTH] = bin2bcd(tm->tm_mon + 1); |
142 | buf[S35390A_BYTE_DAY] = BIN2BCD(tm->tm_mday); | 142 | buf[S35390A_BYTE_DAY] = bin2bcd(tm->tm_mday); |
143 | buf[S35390A_BYTE_WDAY] = BIN2BCD(tm->tm_wday); | 143 | buf[S35390A_BYTE_WDAY] = bin2bcd(tm->tm_wday); |
144 | buf[S35390A_BYTE_HOURS] = s35390a_hr2reg(s35390a, tm->tm_hour); | 144 | buf[S35390A_BYTE_HOURS] = s35390a_hr2reg(s35390a, tm->tm_hour); |
145 | buf[S35390A_BYTE_MINS] = BIN2BCD(tm->tm_min); | 145 | buf[S35390A_BYTE_MINS] = bin2bcd(tm->tm_min); |
146 | buf[S35390A_BYTE_SECS] = BIN2BCD(tm->tm_sec); | 146 | buf[S35390A_BYTE_SECS] = bin2bcd(tm->tm_sec); |
147 | 147 | ||
148 | /* This chip expects the bits of each byte to be in reverse order */ | 148 | /* This chip expects the bits of each byte to be in reverse order */ |
149 | for (i = 0; i < 7; ++i) | 149 | for (i = 0; i < 7; ++i) |
@@ -168,13 +168,13 @@ static int s35390a_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
168 | for (i = 0; i < 7; ++i) | 168 | for (i = 0; i < 7; ++i) |
169 | buf[i] = bitrev8(buf[i]); | 169 | buf[i] = bitrev8(buf[i]); |
170 | 170 | ||
171 | tm->tm_sec = BCD2BIN(buf[S35390A_BYTE_SECS]); | 171 | tm->tm_sec = bcd2bin(buf[S35390A_BYTE_SECS]); |
172 | tm->tm_min = BCD2BIN(buf[S35390A_BYTE_MINS]); | 172 | tm->tm_min = bcd2bin(buf[S35390A_BYTE_MINS]); |
173 | tm->tm_hour = s35390a_reg2hr(s35390a, buf[S35390A_BYTE_HOURS]); | 173 | tm->tm_hour = s35390a_reg2hr(s35390a, buf[S35390A_BYTE_HOURS]); |
174 | tm->tm_wday = BCD2BIN(buf[S35390A_BYTE_WDAY]); | 174 | tm->tm_wday = bcd2bin(buf[S35390A_BYTE_WDAY]); |
175 | tm->tm_mday = BCD2BIN(buf[S35390A_BYTE_DAY]); | 175 | tm->tm_mday = bcd2bin(buf[S35390A_BYTE_DAY]); |
176 | tm->tm_mon = BCD2BIN(buf[S35390A_BYTE_MONTH]) - 1; | 176 | tm->tm_mon = bcd2bin(buf[S35390A_BYTE_MONTH]) - 1; |
177 | tm->tm_year = BCD2BIN(buf[S35390A_BYTE_YEAR]) + 100; | 177 | tm->tm_year = bcd2bin(buf[S35390A_BYTE_YEAR]) + 100; |
178 | 178 | ||
179 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, mday=%d, " | 179 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, mday=%d, " |
180 | "mon=%d, year=%d, wday=%d\n", __func__, tm->tm_sec, | 180 | "mon=%d, year=%d, wday=%d\n", __func__, tm->tm_sec, |
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index e7d19b6c265a..910bc704939c 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -134,12 +134,12 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) | |||
134 | rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday, | 134 | rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday, |
135 | rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec); | 135 | rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec); |
136 | 136 | ||
137 | BCD_TO_BIN(rtc_tm->tm_sec); | 137 | rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec); |
138 | BCD_TO_BIN(rtc_tm->tm_min); | 138 | rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min); |
139 | BCD_TO_BIN(rtc_tm->tm_hour); | 139 | rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour); |
140 | BCD_TO_BIN(rtc_tm->tm_mday); | 140 | rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday); |
141 | BCD_TO_BIN(rtc_tm->tm_mon); | 141 | rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon); |
142 | BCD_TO_BIN(rtc_tm->tm_year); | 142 | rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year); |
143 | 143 | ||
144 | rtc_tm->tm_year += 100; | 144 | rtc_tm->tm_year += 100; |
145 | rtc_tm->tm_mon -= 1; | 145 | rtc_tm->tm_mon -= 1; |
@@ -163,12 +163,12 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
163 | return -EINVAL; | 163 | return -EINVAL; |
164 | } | 164 | } |
165 | 165 | ||
166 | writeb(BIN2BCD(tm->tm_sec), base + S3C2410_RTCSEC); | 166 | writeb(bin2bcd(tm->tm_sec), base + S3C2410_RTCSEC); |
167 | writeb(BIN2BCD(tm->tm_min), base + S3C2410_RTCMIN); | 167 | writeb(bin2bcd(tm->tm_min), base + S3C2410_RTCMIN); |
168 | writeb(BIN2BCD(tm->tm_hour), base + S3C2410_RTCHOUR); | 168 | writeb(bin2bcd(tm->tm_hour), base + S3C2410_RTCHOUR); |
169 | writeb(BIN2BCD(tm->tm_mday), base + S3C2410_RTCDATE); | 169 | writeb(bin2bcd(tm->tm_mday), base + S3C2410_RTCDATE); |
170 | writeb(BIN2BCD(tm->tm_mon + 1), base + S3C2410_RTCMON); | 170 | writeb(bin2bcd(tm->tm_mon + 1), base + S3C2410_RTCMON); |
171 | writeb(BIN2BCD(year), base + S3C2410_RTCYEAR); | 171 | writeb(bin2bcd(year), base + S3C2410_RTCYEAR); |
172 | 172 | ||
173 | return 0; | 173 | return 0; |
174 | } | 174 | } |
@@ -199,34 +199,34 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
199 | /* decode the alarm enable field */ | 199 | /* decode the alarm enable field */ |
200 | 200 | ||
201 | if (alm_en & S3C2410_RTCALM_SECEN) | 201 | if (alm_en & S3C2410_RTCALM_SECEN) |
202 | BCD_TO_BIN(alm_tm->tm_sec); | 202 | alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec); |
203 | else | 203 | else |
204 | alm_tm->tm_sec = 0xff; | 204 | alm_tm->tm_sec = 0xff; |
205 | 205 | ||
206 | if (alm_en & S3C2410_RTCALM_MINEN) | 206 | if (alm_en & S3C2410_RTCALM_MINEN) |
207 | BCD_TO_BIN(alm_tm->tm_min); | 207 | alm_tm->tm_min = bcd2bin(alm_tm->tm_min); |
208 | else | 208 | else |
209 | alm_tm->tm_min = 0xff; | 209 | alm_tm->tm_min = 0xff; |
210 | 210 | ||
211 | if (alm_en & S3C2410_RTCALM_HOUREN) | 211 | if (alm_en & S3C2410_RTCALM_HOUREN) |
212 | BCD_TO_BIN(alm_tm->tm_hour); | 212 | alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour); |
213 | else | 213 | else |
214 | alm_tm->tm_hour = 0xff; | 214 | alm_tm->tm_hour = 0xff; |
215 | 215 | ||
216 | if (alm_en & S3C2410_RTCALM_DAYEN) | 216 | if (alm_en & S3C2410_RTCALM_DAYEN) |
217 | BCD_TO_BIN(alm_tm->tm_mday); | 217 | alm_tm->tm_mday = bcd2bin(alm_tm->tm_mday); |
218 | else | 218 | else |
219 | alm_tm->tm_mday = 0xff; | 219 | alm_tm->tm_mday = 0xff; |
220 | 220 | ||
221 | if (alm_en & S3C2410_RTCALM_MONEN) { | 221 | if (alm_en & S3C2410_RTCALM_MONEN) { |
222 | BCD_TO_BIN(alm_tm->tm_mon); | 222 | alm_tm->tm_mon = bcd2bin(alm_tm->tm_mon); |
223 | alm_tm->tm_mon -= 1; | 223 | alm_tm->tm_mon -= 1; |
224 | } else { | 224 | } else { |
225 | alm_tm->tm_mon = 0xff; | 225 | alm_tm->tm_mon = 0xff; |
226 | } | 226 | } |
227 | 227 | ||
228 | if (alm_en & S3C2410_RTCALM_YEAREN) | 228 | if (alm_en & S3C2410_RTCALM_YEAREN) |
229 | BCD_TO_BIN(alm_tm->tm_year); | 229 | alm_tm->tm_year = bcd2bin(alm_tm->tm_year); |
230 | else | 230 | else |
231 | alm_tm->tm_year = 0xffff; | 231 | alm_tm->tm_year = 0xffff; |
232 | 232 | ||
@@ -250,17 +250,17 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
250 | 250 | ||
251 | if (tm->tm_sec < 60 && tm->tm_sec >= 0) { | 251 | if (tm->tm_sec < 60 && tm->tm_sec >= 0) { |
252 | alrm_en |= S3C2410_RTCALM_SECEN; | 252 | alrm_en |= S3C2410_RTCALM_SECEN; |
253 | writeb(BIN2BCD(tm->tm_sec), base + S3C2410_ALMSEC); | 253 | writeb(bin2bcd(tm->tm_sec), base + S3C2410_ALMSEC); |
254 | } | 254 | } |
255 | 255 | ||
256 | if (tm->tm_min < 60 && tm->tm_min >= 0) { | 256 | if (tm->tm_min < 60 && tm->tm_min >= 0) { |
257 | alrm_en |= S3C2410_RTCALM_MINEN; | 257 | alrm_en |= S3C2410_RTCALM_MINEN; |
258 | writeb(BIN2BCD(tm->tm_min), base + S3C2410_ALMMIN); | 258 | writeb(bin2bcd(tm->tm_min), base + S3C2410_ALMMIN); |
259 | } | 259 | } |
260 | 260 | ||
261 | if (tm->tm_hour < 24 && tm->tm_hour >= 0) { | 261 | if (tm->tm_hour < 24 && tm->tm_hour >= 0) { |
262 | alrm_en |= S3C2410_RTCALM_HOUREN; | 262 | alrm_en |= S3C2410_RTCALM_HOUREN; |
263 | writeb(BIN2BCD(tm->tm_hour), base + S3C2410_ALMHOUR); | 263 | writeb(bin2bcd(tm->tm_hour), base + S3C2410_ALMHOUR); |
264 | } | 264 | } |
265 | 265 | ||
266 | pr_debug("setting S3C2410_RTCALM to %08x\n", alrm_en); | 266 | pr_debug("setting S3C2410_RTCALM to %08x\n", alrm_en); |
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index fcead4c4cd1f..aaf9d6a337cc 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c | |||
@@ -324,23 +324,23 @@ static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
324 | 324 | ||
325 | sec128 = readb(rtc->regbase + R64CNT); | 325 | sec128 = readb(rtc->regbase + R64CNT); |
326 | 326 | ||
327 | tm->tm_sec = BCD2BIN(readb(rtc->regbase + RSECCNT)); | 327 | tm->tm_sec = bcd2bin(readb(rtc->regbase + RSECCNT)); |
328 | tm->tm_min = BCD2BIN(readb(rtc->regbase + RMINCNT)); | 328 | tm->tm_min = bcd2bin(readb(rtc->regbase + RMINCNT)); |
329 | tm->tm_hour = BCD2BIN(readb(rtc->regbase + RHRCNT)); | 329 | tm->tm_hour = bcd2bin(readb(rtc->regbase + RHRCNT)); |
330 | tm->tm_wday = BCD2BIN(readb(rtc->regbase + RWKCNT)); | 330 | tm->tm_wday = bcd2bin(readb(rtc->regbase + RWKCNT)); |
331 | tm->tm_mday = BCD2BIN(readb(rtc->regbase + RDAYCNT)); | 331 | tm->tm_mday = bcd2bin(readb(rtc->regbase + RDAYCNT)); |
332 | tm->tm_mon = BCD2BIN(readb(rtc->regbase + RMONCNT)) - 1; | 332 | tm->tm_mon = bcd2bin(readb(rtc->regbase + RMONCNT)) - 1; |
333 | 333 | ||
334 | if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) { | 334 | if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) { |
335 | yr = readw(rtc->regbase + RYRCNT); | 335 | yr = readw(rtc->regbase + RYRCNT); |
336 | yr100 = BCD2BIN(yr >> 8); | 336 | yr100 = bcd2bin(yr >> 8); |
337 | yr &= 0xff; | 337 | yr &= 0xff; |
338 | } else { | 338 | } else { |
339 | yr = readb(rtc->regbase + RYRCNT); | 339 | yr = readb(rtc->regbase + RYRCNT); |
340 | yr100 = BCD2BIN((yr == 0x99) ? 0x19 : 0x20); | 340 | yr100 = bcd2bin((yr == 0x99) ? 0x19 : 0x20); |
341 | } | 341 | } |
342 | 342 | ||
343 | tm->tm_year = (yr100 * 100 + BCD2BIN(yr)) - 1900; | 343 | tm->tm_year = (yr100 * 100 + bcd2bin(yr)) - 1900; |
344 | 344 | ||
345 | sec2 = readb(rtc->regbase + R64CNT); | 345 | sec2 = readb(rtc->regbase + R64CNT); |
346 | cf_bit = readb(rtc->regbase + RCR1) & RCR1_CF; | 346 | cf_bit = readb(rtc->regbase + RCR1) & RCR1_CF; |
@@ -382,20 +382,20 @@ static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
382 | tmp &= ~RCR2_START; | 382 | tmp &= ~RCR2_START; |
383 | writeb(tmp, rtc->regbase + RCR2); | 383 | writeb(tmp, rtc->regbase + RCR2); |
384 | 384 | ||
385 | writeb(BIN2BCD(tm->tm_sec), rtc->regbase + RSECCNT); | 385 | writeb(bin2bcd(tm->tm_sec), rtc->regbase + RSECCNT); |
386 | writeb(BIN2BCD(tm->tm_min), rtc->regbase + RMINCNT); | 386 | writeb(bin2bcd(tm->tm_min), rtc->regbase + RMINCNT); |
387 | writeb(BIN2BCD(tm->tm_hour), rtc->regbase + RHRCNT); | 387 | writeb(bin2bcd(tm->tm_hour), rtc->regbase + RHRCNT); |
388 | writeb(BIN2BCD(tm->tm_wday), rtc->regbase + RWKCNT); | 388 | writeb(bin2bcd(tm->tm_wday), rtc->regbase + RWKCNT); |
389 | writeb(BIN2BCD(tm->tm_mday), rtc->regbase + RDAYCNT); | 389 | writeb(bin2bcd(tm->tm_mday), rtc->regbase + RDAYCNT); |
390 | writeb(BIN2BCD(tm->tm_mon + 1), rtc->regbase + RMONCNT); | 390 | writeb(bin2bcd(tm->tm_mon + 1), rtc->regbase + RMONCNT); |
391 | 391 | ||
392 | if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) { | 392 | if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) { |
393 | year = (BIN2BCD((tm->tm_year + 1900) / 100) << 8) | | 393 | year = (bin2bcd((tm->tm_year + 1900) / 100) << 8) | |
394 | BIN2BCD(tm->tm_year % 100); | 394 | bin2bcd(tm->tm_year % 100); |
395 | writew(year, rtc->regbase + RYRCNT); | 395 | writew(year, rtc->regbase + RYRCNT); |
396 | } else { | 396 | } else { |
397 | year = tm->tm_year % 100; | 397 | year = tm->tm_year % 100; |
398 | writeb(BIN2BCD(year), rtc->regbase + RYRCNT); | 398 | writeb(bin2bcd(year), rtc->regbase + RYRCNT); |
399 | } | 399 | } |
400 | 400 | ||
401 | /* Start RTC */ | 401 | /* Start RTC */ |
@@ -417,7 +417,7 @@ static inline int sh_rtc_read_alarm_value(struct sh_rtc *rtc, int reg_off) | |||
417 | byte = readb(rtc->regbase + reg_off); | 417 | byte = readb(rtc->regbase + reg_off); |
418 | if (byte & AR_ENB) { | 418 | if (byte & AR_ENB) { |
419 | byte &= ~AR_ENB; /* strip the enable bit */ | 419 | byte &= ~AR_ENB; /* strip the enable bit */ |
420 | value = BCD2BIN(byte); | 420 | value = bcd2bin(byte); |
421 | } | 421 | } |
422 | 422 | ||
423 | return value; | 423 | return value; |
@@ -455,7 +455,7 @@ static inline void sh_rtc_write_alarm_value(struct sh_rtc *rtc, | |||
455 | if (value < 0) | 455 | if (value < 0) |
456 | writeb(0, rtc->regbase + reg_off); | 456 | writeb(0, rtc->regbase + reg_off); |
457 | else | 457 | else |
458 | writeb(BIN2BCD(value) | AR_ENB, rtc->regbase + reg_off); | 458 | writeb(bin2bcd(value) | AR_ENB, rtc->regbase + reg_off); |
459 | } | 459 | } |
460 | 460 | ||
461 | static int sh_rtc_check_alarm(struct rtc_time *tm) | 461 | static int sh_rtc_check_alarm(struct rtc_time *tm) |
@@ -568,7 +568,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
568 | struct sh_rtc *rtc; | 568 | struct sh_rtc *rtc; |
569 | struct resource *res; | 569 | struct resource *res; |
570 | unsigned int tmp; | 570 | unsigned int tmp; |
571 | int ret = -ENOENT; | 571 | int ret; |
572 | 572 | ||
573 | rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL); | 573 | rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL); |
574 | if (unlikely(!rtc)) | 574 | if (unlikely(!rtc)) |
@@ -577,26 +577,33 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
577 | spin_lock_init(&rtc->lock); | 577 | spin_lock_init(&rtc->lock); |
578 | 578 | ||
579 | /* get periodic/carry/alarm irqs */ | 579 | /* get periodic/carry/alarm irqs */ |
580 | rtc->periodic_irq = platform_get_irq(pdev, 0); | 580 | ret = platform_get_irq(pdev, 0); |
581 | if (unlikely(rtc->periodic_irq < 0)) { | 581 | if (unlikely(ret < 0)) { |
582 | ret = -ENOENT; | ||
582 | dev_err(&pdev->dev, "No IRQ for period\n"); | 583 | dev_err(&pdev->dev, "No IRQ for period\n"); |
583 | goto err_badres; | 584 | goto err_badres; |
584 | } | 585 | } |
586 | rtc->periodic_irq = ret; | ||
585 | 587 | ||
586 | rtc->carry_irq = platform_get_irq(pdev, 1); | 588 | ret = platform_get_irq(pdev, 1); |
587 | if (unlikely(rtc->carry_irq < 0)) { | 589 | if (unlikely(ret < 0)) { |
590 | ret = -ENOENT; | ||
588 | dev_err(&pdev->dev, "No IRQ for carry\n"); | 591 | dev_err(&pdev->dev, "No IRQ for carry\n"); |
589 | goto err_badres; | 592 | goto err_badres; |
590 | } | 593 | } |
594 | rtc->carry_irq = ret; | ||
591 | 595 | ||
592 | rtc->alarm_irq = platform_get_irq(pdev, 2); | 596 | ret = platform_get_irq(pdev, 2); |
593 | if (unlikely(rtc->alarm_irq < 0)) { | 597 | if (unlikely(ret < 0)) { |
598 | ret = -ENOENT; | ||
594 | dev_err(&pdev->dev, "No IRQ for alarm\n"); | 599 | dev_err(&pdev->dev, "No IRQ for alarm\n"); |
595 | goto err_badres; | 600 | goto err_badres; |
596 | } | 601 | } |
602 | rtc->alarm_irq = ret; | ||
597 | 603 | ||
598 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 604 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
599 | if (unlikely(res == NULL)) { | 605 | if (unlikely(res == NULL)) { |
606 | ret = -ENOENT; | ||
600 | dev_err(&pdev->dev, "No IO resource\n"); | 607 | dev_err(&pdev->dev, "No IO resource\n"); |
601 | goto err_badres; | 608 | goto err_badres; |
602 | } | 609 | } |
diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index 9a7e920315fa..f4cd46e15af9 100644 --- a/drivers/rtc/rtc-stk17ta8.c +++ b/drivers/rtc/rtc-stk17ta8.c | |||
@@ -82,14 +82,14 @@ static int stk17ta8_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
82 | flags = readb(pdata->ioaddr + RTC_FLAGS); | 82 | flags = readb(pdata->ioaddr + RTC_FLAGS); |
83 | writeb(flags | RTC_WRITE, pdata->ioaddr + RTC_FLAGS); | 83 | writeb(flags | RTC_WRITE, pdata->ioaddr + RTC_FLAGS); |
84 | 84 | ||
85 | writeb(BIN2BCD(tm->tm_year % 100), ioaddr + RTC_YEAR); | 85 | writeb(bin2bcd(tm->tm_year % 100), ioaddr + RTC_YEAR); |
86 | writeb(BIN2BCD(tm->tm_mon + 1), ioaddr + RTC_MONTH); | 86 | writeb(bin2bcd(tm->tm_mon + 1), ioaddr + RTC_MONTH); |
87 | writeb(BIN2BCD(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY); | 87 | writeb(bin2bcd(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY); |
88 | writeb(BIN2BCD(tm->tm_mday), ioaddr + RTC_DATE); | 88 | writeb(bin2bcd(tm->tm_mday), ioaddr + RTC_DATE); |
89 | writeb(BIN2BCD(tm->tm_hour), ioaddr + RTC_HOURS); | 89 | writeb(bin2bcd(tm->tm_hour), ioaddr + RTC_HOURS); |
90 | writeb(BIN2BCD(tm->tm_min), ioaddr + RTC_MINUTES); | 90 | writeb(bin2bcd(tm->tm_min), ioaddr + RTC_MINUTES); |
91 | writeb(BIN2BCD(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS); | 91 | writeb(bin2bcd(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS); |
92 | writeb(BIN2BCD((tm->tm_year + 1900) / 100), ioaddr + RTC_CENTURY); | 92 | writeb(bin2bcd((tm->tm_year + 1900) / 100), ioaddr + RTC_CENTURY); |
93 | 93 | ||
94 | writeb(flags & ~RTC_WRITE, pdata->ioaddr + RTC_FLAGS); | 94 | writeb(flags & ~RTC_WRITE, pdata->ioaddr + RTC_FLAGS); |
95 | return 0; | 95 | return 0; |
@@ -120,14 +120,14 @@ static int stk17ta8_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
120 | year = readb(ioaddr + RTC_YEAR); | 120 | year = readb(ioaddr + RTC_YEAR); |
121 | century = readb(ioaddr + RTC_CENTURY); | 121 | century = readb(ioaddr + RTC_CENTURY); |
122 | writeb(flags & ~RTC_READ, ioaddr + RTC_FLAGS); | 122 | writeb(flags & ~RTC_READ, ioaddr + RTC_FLAGS); |
123 | tm->tm_sec = BCD2BIN(second); | 123 | tm->tm_sec = bcd2bin(second); |
124 | tm->tm_min = BCD2BIN(minute); | 124 | tm->tm_min = bcd2bin(minute); |
125 | tm->tm_hour = BCD2BIN(hour); | 125 | tm->tm_hour = bcd2bin(hour); |
126 | tm->tm_mday = BCD2BIN(day); | 126 | tm->tm_mday = bcd2bin(day); |
127 | tm->tm_wday = BCD2BIN(week); | 127 | tm->tm_wday = bcd2bin(week); |
128 | tm->tm_mon = BCD2BIN(month) - 1; | 128 | tm->tm_mon = bcd2bin(month) - 1; |
129 | /* year is 1900 + tm->tm_year */ | 129 | /* year is 1900 + tm->tm_year */ |
130 | tm->tm_year = BCD2BIN(year) + BCD2BIN(century) * 100 - 1900; | 130 | tm->tm_year = bcd2bin(year) + bcd2bin(century) * 100 - 1900; |
131 | 131 | ||
132 | if (rtc_valid_tm(tm) < 0) { | 132 | if (rtc_valid_tm(tm) < 0) { |
133 | dev_err(dev, "retrieved date/time is not valid.\n"); | 133 | dev_err(dev, "retrieved date/time is not valid.\n"); |
@@ -148,16 +148,16 @@ static void stk17ta8_rtc_update_alarm(struct rtc_plat_data *pdata) | |||
148 | writeb(flags | RTC_WRITE, ioaddr + RTC_FLAGS); | 148 | writeb(flags | RTC_WRITE, ioaddr + RTC_FLAGS); |
149 | 149 | ||
150 | writeb(pdata->alrm_mday < 0 || (pdata->irqen & RTC_UF) ? | 150 | writeb(pdata->alrm_mday < 0 || (pdata->irqen & RTC_UF) ? |
151 | 0x80 : BIN2BCD(pdata->alrm_mday), | 151 | 0x80 : bin2bcd(pdata->alrm_mday), |
152 | ioaddr + RTC_DATE_ALARM); | 152 | ioaddr + RTC_DATE_ALARM); |
153 | writeb(pdata->alrm_hour < 0 || (pdata->irqen & RTC_UF) ? | 153 | writeb(pdata->alrm_hour < 0 || (pdata->irqen & RTC_UF) ? |
154 | 0x80 : BIN2BCD(pdata->alrm_hour), | 154 | 0x80 : bin2bcd(pdata->alrm_hour), |
155 | ioaddr + RTC_HOURS_ALARM); | 155 | ioaddr + RTC_HOURS_ALARM); |
156 | writeb(pdata->alrm_min < 0 || (pdata->irqen & RTC_UF) ? | 156 | writeb(pdata->alrm_min < 0 || (pdata->irqen & RTC_UF) ? |
157 | 0x80 : BIN2BCD(pdata->alrm_min), | 157 | 0x80 : bin2bcd(pdata->alrm_min), |
158 | ioaddr + RTC_MINUTES_ALARM); | 158 | ioaddr + RTC_MINUTES_ALARM); |
159 | writeb(pdata->alrm_sec < 0 || (pdata->irqen & RTC_UF) ? | 159 | writeb(pdata->alrm_sec < 0 || (pdata->irqen & RTC_UF) ? |
160 | 0x80 : BIN2BCD(pdata->alrm_sec), | 160 | 0x80 : bin2bcd(pdata->alrm_sec), |
161 | ioaddr + RTC_SECONDS_ALARM); | 161 | ioaddr + RTC_SECONDS_ALARM); |
162 | writeb(pdata->irqen ? RTC_INTS_AIE : 0, ioaddr + RTC_INTERRUPTS); | 162 | writeb(pdata->irqen ? RTC_INTS_AIE : 0, ioaddr + RTC_INTERRUPTS); |
163 | readb(ioaddr + RTC_FLAGS); /* clear interrupts */ | 163 | readb(ioaddr + RTC_FLAGS); /* clear interrupts */ |
@@ -280,7 +280,6 @@ static struct bin_attribute stk17ta8_nvram_attr = { | |||
280 | .attr = { | 280 | .attr = { |
281 | .name = "nvram", | 281 | .name = "nvram", |
282 | .mode = S_IRUGO | S_IWUSR, | 282 | .mode = S_IRUGO | S_IWUSR, |
283 | .owner = THIS_MODULE, | ||
284 | }, | 283 | }, |
285 | .size = RTC_OFFSET, | 284 | .size = RTC_OFFSET, |
286 | .read = stk17ta8_nvram_read, | 285 | .read = stk17ta8_nvram_read, |
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c index 10025d840268..14d4f036a768 100644 --- a/drivers/rtc/rtc-v3020.c +++ b/drivers/rtc/rtc-v3020.c | |||
@@ -92,19 +92,19 @@ static int v3020_read_time(struct device *dev, struct rtc_time *dt) | |||
92 | 92 | ||
93 | /* ...and then read constant values. */ | 93 | /* ...and then read constant values. */ |
94 | tmp = v3020_get_reg(chip, V3020_SECONDS); | 94 | tmp = v3020_get_reg(chip, V3020_SECONDS); |
95 | dt->tm_sec = BCD2BIN(tmp); | 95 | dt->tm_sec = bcd2bin(tmp); |
96 | tmp = v3020_get_reg(chip, V3020_MINUTES); | 96 | tmp = v3020_get_reg(chip, V3020_MINUTES); |
97 | dt->tm_min = BCD2BIN(tmp); | 97 | dt->tm_min = bcd2bin(tmp); |
98 | tmp = v3020_get_reg(chip, V3020_HOURS); | 98 | tmp = v3020_get_reg(chip, V3020_HOURS); |
99 | dt->tm_hour = BCD2BIN(tmp); | 99 | dt->tm_hour = bcd2bin(tmp); |
100 | tmp = v3020_get_reg(chip, V3020_MONTH_DAY); | 100 | tmp = v3020_get_reg(chip, V3020_MONTH_DAY); |
101 | dt->tm_mday = BCD2BIN(tmp); | 101 | dt->tm_mday = bcd2bin(tmp); |
102 | tmp = v3020_get_reg(chip, V3020_MONTH); | 102 | tmp = v3020_get_reg(chip, V3020_MONTH); |
103 | dt->tm_mon = BCD2BIN(tmp) - 1; | 103 | dt->tm_mon = bcd2bin(tmp) - 1; |
104 | tmp = v3020_get_reg(chip, V3020_WEEK_DAY); | 104 | tmp = v3020_get_reg(chip, V3020_WEEK_DAY); |
105 | dt->tm_wday = BCD2BIN(tmp); | 105 | dt->tm_wday = bcd2bin(tmp); |
106 | tmp = v3020_get_reg(chip, V3020_YEAR); | 106 | tmp = v3020_get_reg(chip, V3020_YEAR); |
107 | dt->tm_year = BCD2BIN(tmp)+100; | 107 | dt->tm_year = bcd2bin(tmp)+100; |
108 | 108 | ||
109 | #ifdef DEBUG | 109 | #ifdef DEBUG |
110 | printk("\n%s : Read RTC values\n",__func__); | 110 | printk("\n%s : Read RTC values\n",__func__); |
@@ -136,13 +136,13 @@ static int v3020_set_time(struct device *dev, struct rtc_time *dt) | |||
136 | #endif | 136 | #endif |
137 | 137 | ||
138 | /* Write all the values to ram... */ | 138 | /* Write all the values to ram... */ |
139 | v3020_set_reg(chip, V3020_SECONDS, BIN2BCD(dt->tm_sec)); | 139 | v3020_set_reg(chip, V3020_SECONDS, bin2bcd(dt->tm_sec)); |
140 | v3020_set_reg(chip, V3020_MINUTES, BIN2BCD(dt->tm_min)); | 140 | v3020_set_reg(chip, V3020_MINUTES, bin2bcd(dt->tm_min)); |
141 | v3020_set_reg(chip, V3020_HOURS, BIN2BCD(dt->tm_hour)); | 141 | v3020_set_reg(chip, V3020_HOURS, bin2bcd(dt->tm_hour)); |
142 | v3020_set_reg(chip, V3020_MONTH_DAY, BIN2BCD(dt->tm_mday)); | 142 | v3020_set_reg(chip, V3020_MONTH_DAY, bin2bcd(dt->tm_mday)); |
143 | v3020_set_reg(chip, V3020_MONTH, BIN2BCD(dt->tm_mon + 1)); | 143 | v3020_set_reg(chip, V3020_MONTH, bin2bcd(dt->tm_mon + 1)); |
144 | v3020_set_reg(chip, V3020_WEEK_DAY, BIN2BCD(dt->tm_wday)); | 144 | v3020_set_reg(chip, V3020_WEEK_DAY, bin2bcd(dt->tm_wday)); |
145 | v3020_set_reg(chip, V3020_YEAR, BIN2BCD(dt->tm_year % 100)); | 145 | v3020_set_reg(chip, V3020_YEAR, bin2bcd(dt->tm_year % 100)); |
146 | 146 | ||
147 | /* ...and set the clock. */ | 147 | /* ...and set the clock. */ |
148 | v3020_set_reg(chip, V3020_CMD_RAM2CLOCK, 0); | 148 | v3020_set_reg(chip, V3020_CMD_RAM2CLOCK, 0); |
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index 884b635f028b..834dcc6d785f 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c | |||
@@ -360,7 +360,7 @@ static int __devinit rtc_probe(struct platform_device *pdev) | |||
360 | spin_unlock_irq(&rtc_lock); | 360 | spin_unlock_irq(&rtc_lock); |
361 | 361 | ||
362 | aie_irq = platform_get_irq(pdev, 0); | 362 | aie_irq = platform_get_irq(pdev, 0); |
363 | if (aie_irq < 0 || aie_irq >= NR_IRQS) { | 363 | if (aie_irq < 0 || aie_irq >= nr_irqs) { |
364 | retval = -EBUSY; | 364 | retval = -EBUSY; |
365 | goto err_device_unregister; | 365 | goto err_device_unregister; |
366 | } | 366 | } |
@@ -371,7 +371,7 @@ static int __devinit rtc_probe(struct platform_device *pdev) | |||
371 | goto err_device_unregister; | 371 | goto err_device_unregister; |
372 | 372 | ||
373 | pie_irq = platform_get_irq(pdev, 1); | 373 | pie_irq = platform_get_irq(pdev, 1); |
374 | if (pie_irq < 0 || pie_irq >= NR_IRQS) | 374 | if (pie_irq < 0 || pie_irq >= nr_irqs) |
375 | goto err_free_irq; | 375 | goto err_free_irq; |
376 | 376 | ||
377 | retval = request_irq(pie_irq, rtclong1_interrupt, IRQF_DISABLED, | 377 | retval = request_irq(pie_irq, rtclong1_interrupt, IRQF_DISABLED, |
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index 7dcfba1bbfe1..310c10795e9a 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c | |||
@@ -118,13 +118,13 @@ static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm, | |||
118 | for (i = 0; i <= 4; i++) | 118 | for (i = 0; i <= 4; i++) |
119 | buf[i] &= 0x7F; | 119 | buf[i] &= 0x7F; |
120 | 120 | ||
121 | tm->tm_sec = BCD2BIN(buf[CCR_SEC]); | 121 | tm->tm_sec = bcd2bin(buf[CCR_SEC]); |
122 | tm->tm_min = BCD2BIN(buf[CCR_MIN]); | 122 | tm->tm_min = bcd2bin(buf[CCR_MIN]); |
123 | tm->tm_hour = BCD2BIN(buf[CCR_HOUR] & 0x3F); /* hr is 0-23 */ | 123 | tm->tm_hour = bcd2bin(buf[CCR_HOUR] & 0x3F); /* hr is 0-23 */ |
124 | tm->tm_mday = BCD2BIN(buf[CCR_MDAY]); | 124 | tm->tm_mday = bcd2bin(buf[CCR_MDAY]); |
125 | tm->tm_mon = BCD2BIN(buf[CCR_MONTH]) - 1; /* mon is 0-11 */ | 125 | tm->tm_mon = bcd2bin(buf[CCR_MONTH]) - 1; /* mon is 0-11 */ |
126 | tm->tm_year = BCD2BIN(buf[CCR_YEAR]) | 126 | tm->tm_year = bcd2bin(buf[CCR_YEAR]) |
127 | + (BCD2BIN(buf[CCR_Y2K]) * 100) - 1900; | 127 | + (bcd2bin(buf[CCR_Y2K]) * 100) - 1900; |
128 | tm->tm_wday = buf[CCR_WDAY]; | 128 | tm->tm_wday = buf[CCR_WDAY]; |
129 | 129 | ||
130 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " | 130 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " |
@@ -174,11 +174,11 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, | |||
174 | __func__, | 174 | __func__, |
175 | tm->tm_sec, tm->tm_min, tm->tm_hour); | 175 | tm->tm_sec, tm->tm_min, tm->tm_hour); |
176 | 176 | ||
177 | buf[CCR_SEC] = BIN2BCD(tm->tm_sec); | 177 | buf[CCR_SEC] = bin2bcd(tm->tm_sec); |
178 | buf[CCR_MIN] = BIN2BCD(tm->tm_min); | 178 | buf[CCR_MIN] = bin2bcd(tm->tm_min); |
179 | 179 | ||
180 | /* set hour and 24hr bit */ | 180 | /* set hour and 24hr bit */ |
181 | buf[CCR_HOUR] = BIN2BCD(tm->tm_hour) | X1205_HR_MIL; | 181 | buf[CCR_HOUR] = bin2bcd(tm->tm_hour) | X1205_HR_MIL; |
182 | 182 | ||
183 | /* should we also set the date? */ | 183 | /* should we also set the date? */ |
184 | if (datetoo) { | 184 | if (datetoo) { |
@@ -187,15 +187,15 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, | |||
187 | __func__, | 187 | __func__, |
188 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | 188 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); |
189 | 189 | ||
190 | buf[CCR_MDAY] = BIN2BCD(tm->tm_mday); | 190 | buf[CCR_MDAY] = bin2bcd(tm->tm_mday); |
191 | 191 | ||
192 | /* month, 1 - 12 */ | 192 | /* month, 1 - 12 */ |
193 | buf[CCR_MONTH] = BIN2BCD(tm->tm_mon + 1); | 193 | buf[CCR_MONTH] = bin2bcd(tm->tm_mon + 1); |
194 | 194 | ||
195 | /* year, since the rtc epoch*/ | 195 | /* year, since the rtc epoch*/ |
196 | buf[CCR_YEAR] = BIN2BCD(tm->tm_year % 100); | 196 | buf[CCR_YEAR] = bin2bcd(tm->tm_year % 100); |
197 | buf[CCR_WDAY] = tm->tm_wday & 0x07; | 197 | buf[CCR_WDAY] = tm->tm_wday & 0x07; |
198 | buf[CCR_Y2K] = BIN2BCD(tm->tm_year / 100); | 198 | buf[CCR_Y2K] = bin2bcd(tm->tm_year / 100); |
199 | } | 199 | } |
200 | 200 | ||
201 | /* If writing alarm registers, set compare bits on registers 0-4 */ | 201 | /* If writing alarm registers, set compare bits on registers 0-4 */ |
@@ -437,7 +437,7 @@ static int x1205_validate_client(struct i2c_client *client) | |||
437 | return -EIO; | 437 | return -EIO; |
438 | } | 438 | } |
439 | 439 | ||
440 | value = BCD2BIN(reg & probe_limits_pattern[i].mask); | 440 | value = bcd2bin(reg & probe_limits_pattern[i].mask); |
441 | 441 | ||
442 | if (value > probe_limits_pattern[i].max || | 442 | if (value > probe_limits_pattern[i].max || |
443 | value < probe_limits_pattern[i].min) { | 443 | value < probe_limits_pattern[i].min) { |
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index b5a868d85eb4..1e5478abd90e 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c | |||
@@ -337,7 +337,7 @@ CMD_INC_RESID(struct scsi_cmnd *cmd, int inc) | |||
337 | #else | 337 | #else |
338 | #define IRQ_MIN 9 | 338 | #define IRQ_MIN 9 |
339 | #if defined(__PPC) | 339 | #if defined(__PPC) |
340 | #define IRQ_MAX (NR_IRQS-1) | 340 | #define IRQ_MAX (nr_irqs-1) |
341 | #else | 341 | #else |
342 | #define IRQ_MAX 12 | 342 | #define IRQ_MAX 12 |
343 | #endif | 343 | #endif |
diff --git a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c index 69f8346aa288..5877f29a6005 100644 --- a/drivers/scsi/arcmsr/arcmsr_attr.c +++ b/drivers/scsi/arcmsr/arcmsr_attr.c | |||
@@ -189,7 +189,6 @@ static struct bin_attribute arcmsr_sysfs_message_read_attr = { | |||
189 | .attr = { | 189 | .attr = { |
190 | .name = "mu_read", | 190 | .name = "mu_read", |
191 | .mode = S_IRUSR , | 191 | .mode = S_IRUSR , |
192 | .owner = THIS_MODULE, | ||
193 | }, | 192 | }, |
194 | .size = 1032, | 193 | .size = 1032, |
195 | .read = arcmsr_sysfs_iop_message_read, | 194 | .read = arcmsr_sysfs_iop_message_read, |
@@ -199,7 +198,6 @@ static struct bin_attribute arcmsr_sysfs_message_write_attr = { | |||
199 | .attr = { | 198 | .attr = { |
200 | .name = "mu_write", | 199 | .name = "mu_write", |
201 | .mode = S_IWUSR, | 200 | .mode = S_IWUSR, |
202 | .owner = THIS_MODULE, | ||
203 | }, | 201 | }, |
204 | .size = 1032, | 202 | .size = 1032, |
205 | .write = arcmsr_sysfs_iop_message_write, | 203 | .write = arcmsr_sysfs_iop_message_write, |
@@ -209,7 +207,6 @@ static struct bin_attribute arcmsr_sysfs_message_clear_attr = { | |||
209 | .attr = { | 207 | .attr = { |
210 | .name = "mu_clear", | 208 | .name = "mu_clear", |
211 | .mode = S_IWUSR, | 209 | .mode = S_IWUSR, |
212 | .owner = THIS_MODULE, | ||
213 | }, | 210 | }, |
214 | .size = 1, | 211 | .size = 1, |
215 | .write = arcmsr_sysfs_iop_message_clear, | 212 | .write = arcmsr_sysfs_iop_message_clear, |
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 740bad435995..afc96e844a25 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c | |||
@@ -343,6 +343,11 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r | |||
343 | } | 343 | } |
344 | 344 | ||
345 | #ifdef CONFIG_IDE_PROC_FS | 345 | #ifdef CONFIG_IDE_PROC_FS |
346 | static ide_proc_entry_t idescsi_proc[] = { | ||
347 | { "capacity", S_IFREG|S_IRUGO, proc_ide_read_capacity, NULL }, | ||
348 | { NULL, 0, NULL, NULL } | ||
349 | }; | ||
350 | |||
346 | #define ide_scsi_devset_get(name, field) \ | 351 | #define ide_scsi_devset_get(name, field) \ |
347 | static int get_##name(ide_drive_t *drive) \ | 352 | static int get_##name(ide_drive_t *drive) \ |
348 | { \ | 353 | { \ |
@@ -378,6 +383,16 @@ static const struct ide_proc_devset idescsi_settings[] = { | |||
378 | IDE_PROC_DEVSET(transform, 0, 3), | 383 | IDE_PROC_DEVSET(transform, 0, 3), |
379 | { 0 }, | 384 | { 0 }, |
380 | }; | 385 | }; |
386 | |||
387 | static ide_proc_entry_t *ide_scsi_proc_entries(ide_drive_t *drive) | ||
388 | { | ||
389 | return idescsi_proc; | ||
390 | } | ||
391 | |||
392 | static const struct ide_proc_devset *ide_scsi_proc_devsets(ide_drive_t *drive) | ||
393 | { | ||
394 | return idescsi_settings; | ||
395 | } | ||
381 | #endif | 396 | #endif |
382 | 397 | ||
383 | /* | 398 | /* |
@@ -419,13 +434,6 @@ static void ide_scsi_remove(ide_drive_t *drive) | |||
419 | 434 | ||
420 | static int ide_scsi_probe(ide_drive_t *); | 435 | static int ide_scsi_probe(ide_drive_t *); |
421 | 436 | ||
422 | #ifdef CONFIG_IDE_PROC_FS | ||
423 | static ide_proc_entry_t idescsi_proc[] = { | ||
424 | { "capacity", S_IFREG|S_IRUGO, proc_ide_read_capacity, NULL }, | ||
425 | { NULL, 0, NULL, NULL } | ||
426 | }; | ||
427 | #endif | ||
428 | |||
429 | static ide_driver_t idescsi_driver = { | 437 | static ide_driver_t idescsi_driver = { |
430 | .gen_driver = { | 438 | .gen_driver = { |
431 | .owner = THIS_MODULE, | 439 | .owner = THIS_MODULE, |
@@ -439,8 +447,8 @@ static ide_driver_t idescsi_driver = { | |||
439 | .end_request = idescsi_end_request, | 447 | .end_request = idescsi_end_request, |
440 | .error = idescsi_atapi_error, | 448 | .error = idescsi_atapi_error, |
441 | #ifdef CONFIG_IDE_PROC_FS | 449 | #ifdef CONFIG_IDE_PROC_FS |
442 | .proc = idescsi_proc, | 450 | .proc_entries = ide_scsi_proc_entries, |
443 | .settings = idescsi_settings, | 451 | .proc_devsets = ide_scsi_proc_devsets, |
444 | #endif | 452 | #endif |
445 | }; | 453 | }; |
446 | 454 | ||
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index d30eb7ba018e..098739deb02e 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
@@ -7859,7 +7859,6 @@ static struct pci_driver ipr_driver = { | |||
7859 | .remove = ipr_remove, | 7859 | .remove = ipr_remove, |
7860 | .shutdown = ipr_shutdown, | 7860 | .shutdown = ipr_shutdown, |
7861 | .err_handler = &ipr_err_handler, | 7861 | .err_handler = &ipr_err_handler, |
7862 | .dynids.use_driver_data = 1 | ||
7863 | }; | 7862 | }; |
7864 | 7863 | ||
7865 | /** | 7864 | /** |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 83c819216771..f25f41a499e5 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2108,7 +2108,7 @@ struct scsi_qla_host; | |||
2108 | 2108 | ||
2109 | struct qla_msix_entry { | 2109 | struct qla_msix_entry { |
2110 | int have_irq; | 2110 | int have_irq; |
2111 | uint16_t msix_vector; | 2111 | uint32_t msix_vector; |
2112 | uint16_t msix_entry; | 2112 | uint16_t msix_entry; |
2113 | }; | 2113 | }; |
2114 | 2114 | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 2aed4721c0d0..21dd182ad512 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -1566,9 +1566,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1566 | goto probe_out; | 1566 | goto probe_out; |
1567 | } | 1567 | } |
1568 | 1568 | ||
1569 | if (pci_find_aer_capability(pdev)) | 1569 | /* This may fail but that's ok */ |
1570 | if (pci_enable_pcie_error_reporting(pdev)) | 1570 | pci_enable_pcie_error_reporting(pdev); |
1571 | goto probe_out; | ||
1572 | 1571 | ||
1573 | host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t)); | 1572 | host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t)); |
1574 | if (host == NULL) { | 1573 | if (host == NULL) { |
diff --git a/drivers/scsi/sr_vendor.c b/drivers/scsi/sr_vendor.c index 4eb3da996b36..4ad3e017213f 100644 --- a/drivers/scsi/sr_vendor.c +++ b/drivers/scsi/sr_vendor.c | |||
@@ -223,9 +223,9 @@ int sr_cd_check(struct cdrom_device_info *cdi) | |||
223 | no_multi = 1; | 223 | no_multi = 1; |
224 | break; | 224 | break; |
225 | } | 225 | } |
226 | min = BCD2BIN(buffer[15]); | 226 | min = bcd2bin(buffer[15]); |
227 | sec = BCD2BIN(buffer[16]); | 227 | sec = bcd2bin(buffer[16]); |
228 | frame = BCD2BIN(buffer[17]); | 228 | frame = bcd2bin(buffer[17]); |
229 | sector = min * CD_SECS * CD_FRAMES + sec * CD_FRAMES + frame; | 229 | sector = min * CD_SECS * CD_FRAMES + sec * CD_FRAMES + frame; |
230 | break; | 230 | break; |
231 | } | 231 | } |
@@ -252,9 +252,9 @@ int sr_cd_check(struct cdrom_device_info *cdi) | |||
252 | } | 252 | } |
253 | if (rc != 0) | 253 | if (rc != 0) |
254 | break; | 254 | break; |
255 | min = BCD2BIN(buffer[1]); | 255 | min = bcd2bin(buffer[1]); |
256 | sec = BCD2BIN(buffer[2]); | 256 | sec = bcd2bin(buffer[2]); |
257 | frame = BCD2BIN(buffer[3]); | 257 | frame = bcd2bin(buffer[3]); |
258 | sector = min * CD_SECS * CD_FRAMES + sec * CD_FRAMES + frame; | 258 | sector = min * CD_SECS * CD_FRAMES + sec * CD_FRAMES + frame; |
259 | if (sector) | 259 | if (sector) |
260 | sector -= CD_MSF_OFFSET; | 260 | sector -= CD_MSF_OFFSET; |
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index 381b12ac20e0..d935b2d04f93 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c | |||
@@ -66,7 +66,6 @@ | |||
66 | #endif | 66 | #endif |
67 | 67 | ||
68 | static struct m68k_serial m68k_soft[NR_PORTS]; | 68 | static struct m68k_serial m68k_soft[NR_PORTS]; |
69 | struct m68k_serial *IRQ_ports[NR_IRQS]; | ||
70 | 69 | ||
71 | static unsigned int uart_irqs[NR_PORTS] = UART_IRQ_DEFNS; | 70 | static unsigned int uart_irqs[NR_PORTS] = UART_IRQ_DEFNS; |
72 | 71 | ||
@@ -375,15 +374,11 @@ clear_and_return: | |||
375 | */ | 374 | */ |
376 | irqreturn_t rs_interrupt(int irq, void *dev_id) | 375 | irqreturn_t rs_interrupt(int irq, void *dev_id) |
377 | { | 376 | { |
378 | struct m68k_serial * info; | 377 | struct m68k_serial *info = dev_id; |
379 | m68328_uart *uart; | 378 | m68328_uart *uart; |
380 | unsigned short rx; | 379 | unsigned short rx; |
381 | unsigned short tx; | 380 | unsigned short tx; |
382 | 381 | ||
383 | info = IRQ_ports[irq]; | ||
384 | if(!info) | ||
385 | return IRQ_NONE; | ||
386 | |||
387 | uart = &uart_addr[info->line]; | 382 | uart = &uart_addr[info->line]; |
388 | rx = uart->urx.w; | 383 | rx = uart->urx.w; |
389 | 384 | ||
@@ -1383,8 +1378,6 @@ rs68328_init(void) | |||
1383 | info->port, info->irq); | 1378 | info->port, info->irq); |
1384 | printk(" is a builtin MC68328 UART\n"); | 1379 | printk(" is a builtin MC68328 UART\n"); |
1385 | 1380 | ||
1386 | IRQ_ports[info->irq] = info; /* waste of space */ | ||
1387 | |||
1388 | #ifdef CONFIG_M68VZ328 | 1381 | #ifdef CONFIG_M68VZ328 |
1389 | if (i > 0 ) | 1382 | if (i > 0 ) |
1390 | PJSEL &= 0xCF; /* PSW enable second port output */ | 1383 | PJSEL &= 0xCF; /* PSW enable second port output */ |
@@ -1393,7 +1386,7 @@ rs68328_init(void) | |||
1393 | if (request_irq(uart_irqs[i], | 1386 | if (request_irq(uart_irqs[i], |
1394 | rs_interrupt, | 1387 | rs_interrupt, |
1395 | IRQF_DISABLED, | 1388 | IRQF_DISABLED, |
1396 | "M68328_UART", NULL)) | 1389 | "M68328_UART", info)) |
1397 | panic("Unable to attach 68328 serial interrupt\n"); | 1390 | panic("Unable to attach 68328 serial interrupt\n"); |
1398 | } | 1391 | } |
1399 | local_irq_restore(flags); | 1392 | local_irq_restore(flags); |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 1528de23a650..303272af386e 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -156,11 +156,15 @@ struct uart_8250_port { | |||
156 | }; | 156 | }; |
157 | 157 | ||
158 | struct irq_info { | 158 | struct irq_info { |
159 | spinlock_t lock; | 159 | struct hlist_node node; |
160 | int irq; | ||
161 | spinlock_t lock; /* Protects list not the hash */ | ||
160 | struct list_head *head; | 162 | struct list_head *head; |
161 | }; | 163 | }; |
162 | 164 | ||
163 | static struct irq_info irq_lists[NR_IRQS]; | 165 | #define NR_IRQ_HASH 32 /* Can be adjusted later */ |
166 | static struct hlist_head irq_lists[NR_IRQ_HASH]; | ||
167 | static DEFINE_MUTEX(hash_mutex); /* Used to walk the hash */ | ||
164 | 168 | ||
165 | /* | 169 | /* |
166 | * Here we define the default xmit fifo size used for each type of UART. | 170 | * Here we define the default xmit fifo size used for each type of UART. |
@@ -1545,15 +1549,43 @@ static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up) | |||
1545 | BUG_ON(i->head != &up->list); | 1549 | BUG_ON(i->head != &up->list); |
1546 | i->head = NULL; | 1550 | i->head = NULL; |
1547 | } | 1551 | } |
1548 | |||
1549 | spin_unlock_irq(&i->lock); | 1552 | spin_unlock_irq(&i->lock); |
1553 | /* List empty so throw away the hash node */ | ||
1554 | if (i->head == NULL) { | ||
1555 | hlist_del(&i->node); | ||
1556 | kfree(i); | ||
1557 | } | ||
1550 | } | 1558 | } |
1551 | 1559 | ||
1552 | static int serial_link_irq_chain(struct uart_8250_port *up) | 1560 | static int serial_link_irq_chain(struct uart_8250_port *up) |
1553 | { | 1561 | { |
1554 | struct irq_info *i = irq_lists + up->port.irq; | 1562 | struct hlist_head *h; |
1563 | struct hlist_node *n; | ||
1564 | struct irq_info *i; | ||
1555 | int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0; | 1565 | int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0; |
1556 | 1566 | ||
1567 | mutex_lock(&hash_mutex); | ||
1568 | |||
1569 | h = &irq_lists[up->port.irq % NR_IRQ_HASH]; | ||
1570 | |||
1571 | hlist_for_each(n, h) { | ||
1572 | i = hlist_entry(n, struct irq_info, node); | ||
1573 | if (i->irq == up->port.irq) | ||
1574 | break; | ||
1575 | } | ||
1576 | |||
1577 | if (n == NULL) { | ||
1578 | i = kzalloc(sizeof(struct irq_info), GFP_KERNEL); | ||
1579 | if (i == NULL) { | ||
1580 | mutex_unlock(&hash_mutex); | ||
1581 | return -ENOMEM; | ||
1582 | } | ||
1583 | spin_lock_init(&i->lock); | ||
1584 | i->irq = up->port.irq; | ||
1585 | hlist_add_head(&i->node, h); | ||
1586 | } | ||
1587 | mutex_unlock(&hash_mutex); | ||
1588 | |||
1557 | spin_lock_irq(&i->lock); | 1589 | spin_lock_irq(&i->lock); |
1558 | 1590 | ||
1559 | if (i->head) { | 1591 | if (i->head) { |
@@ -1577,14 +1609,28 @@ static int serial_link_irq_chain(struct uart_8250_port *up) | |||
1577 | 1609 | ||
1578 | static void serial_unlink_irq_chain(struct uart_8250_port *up) | 1610 | static void serial_unlink_irq_chain(struct uart_8250_port *up) |
1579 | { | 1611 | { |
1580 | struct irq_info *i = irq_lists + up->port.irq; | 1612 | struct irq_info *i; |
1613 | struct hlist_node *n; | ||
1614 | struct hlist_head *h; | ||
1581 | 1615 | ||
1616 | mutex_lock(&hash_mutex); | ||
1617 | |||
1618 | h = &irq_lists[up->port.irq % NR_IRQ_HASH]; | ||
1619 | |||
1620 | hlist_for_each(n, h) { | ||
1621 | i = hlist_entry(n, struct irq_info, node); | ||
1622 | if (i->irq == up->port.irq) | ||
1623 | break; | ||
1624 | } | ||
1625 | |||
1626 | BUG_ON(n == NULL); | ||
1582 | BUG_ON(i->head == NULL); | 1627 | BUG_ON(i->head == NULL); |
1583 | 1628 | ||
1584 | if (list_empty(i->head)) | 1629 | if (list_empty(i->head)) |
1585 | free_irq(up->port.irq, i); | 1630 | free_irq(up->port.irq, i); |
1586 | 1631 | ||
1587 | serial_do_unlink(i, up); | 1632 | serial_do_unlink(i, up); |
1633 | mutex_unlock(&hash_mutex); | ||
1588 | } | 1634 | } |
1589 | 1635 | ||
1590 | /* Base timer interval for polling */ | 1636 | /* Base timer interval for polling */ |
@@ -2447,7 +2493,7 @@ static void serial8250_config_port(struct uart_port *port, int flags) | |||
2447 | static int | 2493 | static int |
2448 | serial8250_verify_port(struct uart_port *port, struct serial_struct *ser) | 2494 | serial8250_verify_port(struct uart_port *port, struct serial_struct *ser) |
2449 | { | 2495 | { |
2450 | if (ser->irq >= NR_IRQS || ser->irq < 0 || | 2496 | if (ser->irq >= nr_irqs || ser->irq < 0 || |
2451 | ser->baud_base < 9600 || ser->type < PORT_UNKNOWN || | 2497 | ser->baud_base < 9600 || ser->type < PORT_UNKNOWN || |
2452 | ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS || | 2498 | ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS || |
2453 | ser->type == PORT_STARTECH) | 2499 | ser->type == PORT_STARTECH) |
@@ -2967,7 +3013,7 @@ EXPORT_SYMBOL(serial8250_unregister_port); | |||
2967 | 3013 | ||
2968 | static int __init serial8250_init(void) | 3014 | static int __init serial8250_init(void) |
2969 | { | 3015 | { |
2970 | int ret, i; | 3016 | int ret; |
2971 | 3017 | ||
2972 | if (nr_uarts > UART_NR) | 3018 | if (nr_uarts > UART_NR) |
2973 | nr_uarts = UART_NR; | 3019 | nr_uarts = UART_NR; |
@@ -2976,9 +3022,6 @@ static int __init serial8250_init(void) | |||
2976 | "%d ports, IRQ sharing %sabled\n", nr_uarts, | 3022 | "%d ports, IRQ sharing %sabled\n", nr_uarts, |
2977 | share_irqs ? "en" : "dis"); | 3023 | share_irqs ? "en" : "dis"); |
2978 | 3024 | ||
2979 | for (i = 0; i < NR_IRQS; i++) | ||
2980 | spin_lock_init(&irq_lists[i].lock); | ||
2981 | |||
2982 | #ifdef CONFIG_SPARC | 3025 | #ifdef CONFIG_SPARC |
2983 | ret = sunserial_register_minors(&serial8250_reg, UART_NR); | 3026 | ret = sunserial_register_minors(&serial8250_reg, UART_NR); |
2984 | #else | 3027 | #else |
@@ -3006,15 +3049,15 @@ static int __init serial8250_init(void) | |||
3006 | goto out; | 3049 | goto out; |
3007 | 3050 | ||
3008 | platform_device_del(serial8250_isa_devs); | 3051 | platform_device_del(serial8250_isa_devs); |
3009 | put_dev: | 3052 | put_dev: |
3010 | platform_device_put(serial8250_isa_devs); | 3053 | platform_device_put(serial8250_isa_devs); |
3011 | unreg_uart_drv: | 3054 | unreg_uart_drv: |
3012 | #ifdef CONFIG_SPARC | 3055 | #ifdef CONFIG_SPARC |
3013 | sunserial_unregister_minors(&serial8250_reg, UART_NR); | 3056 | sunserial_unregister_minors(&serial8250_reg, UART_NR); |
3014 | #else | 3057 | #else |
3015 | uart_unregister_driver(&serial8250_reg); | 3058 | uart_unregister_driver(&serial8250_reg); |
3016 | #endif | 3059 | #endif |
3017 | out: | 3060 | out: |
3018 | return ret; | 3061 | return ret; |
3019 | } | 3062 | } |
3020 | 3063 | ||
diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c index 0416ad3bc127..418b4fe9a0a1 100644 --- a/drivers/serial/8250_gsc.c +++ b/drivers/serial/8250_gsc.c | |||
@@ -111,7 +111,7 @@ static struct parisc_driver serial_driver = { | |||
111 | .probe = serial_init_chip, | 111 | .probe = serial_init_chip, |
112 | }; | 112 | }; |
113 | 113 | ||
114 | int __init probe_serial_gsc(void) | 114 | static int __init probe_serial_gsc(void) |
115 | { | 115 | { |
116 | register_parisc_driver(&lasi_driver); | 116 | register_parisc_driver(&lasi_driver); |
117 | register_parisc_driver(&serial_driver); | 117 | register_parisc_driver(&serial_driver); |
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index 90b56c2c31e2..71562689116f 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c | |||
@@ -512,7 +512,7 @@ static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
512 | int ret = 0; | 512 | int ret = 0; |
513 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA) | 513 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA) |
514 | ret = -EINVAL; | 514 | ret = -EINVAL; |
515 | if (ser->irq < 0 || ser->irq >= NR_IRQS) | 515 | if (ser->irq < 0 || ser->irq >= nr_irqs) |
516 | ret = -EINVAL; | 516 | ret = -EINVAL; |
517 | if (ser->baud_base < 9600) | 517 | if (ser->baud_base < 9600) |
518 | ret = -EINVAL; | 518 | ret = -EINVAL; |
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index 9d08f27208a1..b7180046f8db 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c | |||
@@ -572,7 +572,7 @@ static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
572 | int ret = 0; | 572 | int ret = 0; |
573 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA) | 573 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA) |
574 | ret = -EINVAL; | 574 | ret = -EINVAL; |
575 | if (ser->irq < 0 || ser->irq >= NR_IRQS) | 575 | if (ser->irq < 0 || ser->irq >= nr_irqs) |
576 | ret = -EINVAL; | 576 | ret = -EINVAL; |
577 | if (ser->baud_base < 9600) | 577 | if (ser->baud_base < 9600) |
578 | ret = -EINVAL; | 578 | ret = -EINVAL; |
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index a6c4d744495e..bde4b4b0b80f 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |||
@@ -623,7 +623,7 @@ static int cpm_uart_verify_port(struct uart_port *port, | |||
623 | 623 | ||
624 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM) | 624 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM) |
625 | ret = -EINVAL; | 625 | ret = -EINVAL; |
626 | if (ser->irq < 0 || ser->irq >= NR_IRQS) | 626 | if (ser->irq < 0 || ser->irq >= nr_irqs) |
627 | ret = -EINVAL; | 627 | ret = -EINVAL; |
628 | if (ser->baud_base < 9600) | 628 | if (ser->baud_base < 9600) |
629 | ret = -EINVAL; | 629 | ret = -EINVAL; |
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c index 23d030511019..611c97a15654 100644 --- a/drivers/serial/m32r_sio.c +++ b/drivers/serial/m32r_sio.c | |||
@@ -922,7 +922,7 @@ static void m32r_sio_config_port(struct uart_port *port, int flags) | |||
922 | static int | 922 | static int |
923 | m32r_sio_verify_port(struct uart_port *port, struct serial_struct *ser) | 923 | m32r_sio_verify_port(struct uart_port *port, struct serial_struct *ser) |
924 | { | 924 | { |
925 | if (ser->irq >= NR_IRQS || ser->irq < 0 || | 925 | if (ser->irq >= nr_irqs || ser->irq < 0 || |
926 | ser->baud_base < 9600 || ser->type < PORT_UNKNOWN || | 926 | ser->baud_base < 9600 || ser->type < PORT_UNKNOWN || |
927 | ser->type >= ARRAY_SIZE(uart_config)) | 927 | ser->type >= ARRAY_SIZE(uart_config)) |
928 | return -EINVAL; | 928 | return -EINVAL; |
@@ -1162,7 +1162,7 @@ static int __init m32r_sio_init(void) | |||
1162 | 1162 | ||
1163 | printk(KERN_INFO "Serial: M32R SIO driver\n"); | 1163 | printk(KERN_INFO "Serial: M32R SIO driver\n"); |
1164 | 1164 | ||
1165 | for (i = 0; i < NR_IRQS; i++) | 1165 | for (i = 0; i < nr_irqs; i++) |
1166 | spin_lock_init(&irq_lists[i].lock); | 1166 | spin_lock_init(&irq_lists[i].lock); |
1167 | 1167 | ||
1168 | ret = uart_register_driver(&m32r_sio_reg); | 1168 | ret = uart_register_driver(&m32r_sio_reg); |
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 6bdf3362e3b1..874786a11fe9 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -741,7 +741,7 @@ static int uart_set_info(struct uart_state *state, | |||
741 | if (port->ops->verify_port) | 741 | if (port->ops->verify_port) |
742 | retval = port->ops->verify_port(port, &new_serial); | 742 | retval = port->ops->verify_port(port, &new_serial); |
743 | 743 | ||
744 | if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || | 744 | if ((new_serial.irq >= nr_irqs) || (new_serial.irq < 0) || |
745 | (new_serial.baud_base < 9600)) | 745 | (new_serial.baud_base < 9600)) |
746 | retval = -EINVAL; | 746 | retval = -EINVAL; |
747 | 747 | ||
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c index cb49a5ac022f..61dc8b3daa26 100644 --- a/drivers/serial/serial_lh7a40x.c +++ b/drivers/serial/serial_lh7a40x.c | |||
@@ -460,7 +460,7 @@ static int lh7a40xuart_verify_port (struct uart_port* port, | |||
460 | 460 | ||
461 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_LH7A40X) | 461 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_LH7A40X) |
462 | ret = -EINVAL; | 462 | ret = -EINVAL; |
463 | if (ser->irq < 0 || ser->irq >= NR_IRQS) | 463 | if (ser->irq < 0 || ser->irq >= nr_irqs) |
464 | ret = -EINVAL; | 464 | ret = -EINVAL; |
465 | if (ser->baud_base < 9600) /* *** FIXME: is this true? */ | 465 | if (ser->baud_base < 9600) /* *** FIXME: is this true? */ |
466 | ret = -EINVAL; | 466 | ret = -EINVAL; |
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index 8fcb4c5b9a26..7313c2edcb83 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c | |||
@@ -1039,7 +1039,7 @@ static int __devinit serial_txx9_probe(struct platform_device *dev) | |||
1039 | ret = serial_txx9_register_port(&port); | 1039 | ret = serial_txx9_register_port(&port); |
1040 | if (ret < 0) { | 1040 | if (ret < 0) { |
1041 | dev_err(&dev->dev, "unable to register port at index %d " | 1041 | dev_err(&dev->dev, "unable to register port at index %d " |
1042 | "(IO%x MEM%llx IRQ%d): %d\n", i, | 1042 | "(IO%lx MEM%llx IRQ%d): %d\n", i, |
1043 | p->iobase, (unsigned long long)p->mapbase, | 1043 | p->iobase, (unsigned long long)p->mapbase, |
1044 | p->irq, ret); | 1044 | p->irq, ret); |
1045 | } | 1045 | } |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 3df2aaec829f..f0658d2c45b2 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SuperH on-chip serial module support. (SCI with no FIFO / with FIFO) | 4 | * SuperH on-chip serial module support. (SCI with no FIFO / with FIFO) |
5 | * | 5 | * |
6 | * Copyright (C) 2002 - 2006 Paul Mundt | 6 | * Copyright (C) 2002 - 2008 Paul Mundt |
7 | * Modified to support SH7720 SCIF. Markus Brunner, Mark Jonas (Jul 2007). | 7 | * Modified to support SH7720 SCIF. Markus Brunner, Mark Jonas (Jul 2007). |
8 | * | 8 | * |
9 | * based off of the old drivers/char/sh-sci.c by: | 9 | * based off of the old drivers/char/sh-sci.c by: |
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/cpufreq.h> | 46 | #include <linux/cpufreq.h> |
47 | #include <linux/clk.h> | 47 | #include <linux/clk.h> |
48 | #include <linux/ctype.h> | 48 | #include <linux/ctype.h> |
49 | #include <linux/err.h> | ||
49 | 50 | ||
50 | #ifdef CONFIG_SUPERH | 51 | #ifdef CONFIG_SUPERH |
51 | #include <asm/clock.h> | 52 | #include <asm/clock.h> |
@@ -78,7 +79,7 @@ struct sci_port { | |||
78 | struct timer_list break_timer; | 79 | struct timer_list break_timer; |
79 | int break_flag; | 80 | int break_flag; |
80 | 81 | ||
81 | #ifdef CONFIG_SUPERH | 82 | #ifdef CONFIG_HAVE_CLK |
82 | /* Port clock */ | 83 | /* Port clock */ |
83 | struct clk *clk; | 84 | struct clk *clk; |
84 | #endif | 85 | #endif |
@@ -831,7 +832,7 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) | |||
831 | return IRQ_HANDLED; | 832 | return IRQ_HANDLED; |
832 | } | 833 | } |
833 | 834 | ||
834 | #ifdef CONFIG_CPU_FREQ | 835 | #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_HAVE_CLK) |
835 | /* | 836 | /* |
836 | * Here we define a transistion notifier so that we can update all of our | 837 | * Here we define a transistion notifier so that we can update all of our |
837 | * ports' baud rate when the peripheral clock changes. | 838 | * ports' baud rate when the peripheral clock changes. |
@@ -860,7 +861,7 @@ static int sci_notifier(struct notifier_block *self, | |||
860 | * Clean this up later.. | 861 | * Clean this up later.. |
861 | */ | 862 | */ |
862 | clk = clk_get(NULL, "module_clk"); | 863 | clk = clk_get(NULL, "module_clk"); |
863 | port->uartclk = clk_get_rate(clk) * 16; | 864 | port->uartclk = clk_get_rate(clk); |
864 | clk_put(clk); | 865 | clk_put(clk); |
865 | } | 866 | } |
866 | 867 | ||
@@ -873,7 +874,7 @@ static int sci_notifier(struct notifier_block *self, | |||
873 | } | 874 | } |
874 | 875 | ||
875 | static struct notifier_block sci_nb = { &sci_notifier, NULL, 0 }; | 876 | static struct notifier_block sci_nb = { &sci_notifier, NULL, 0 }; |
876 | #endif /* CONFIG_CPU_FREQ */ | 877 | #endif /* CONFIG_CPU_FREQ && CONFIG_HAVE_CLK */ |
877 | 878 | ||
878 | static int sci_request_irq(struct sci_port *port) | 879 | static int sci_request_irq(struct sci_port *port) |
879 | { | 880 | { |
@@ -1008,7 +1009,7 @@ static int sci_startup(struct uart_port *port) | |||
1008 | if (s->enable) | 1009 | if (s->enable) |
1009 | s->enable(port); | 1010 | s->enable(port); |
1010 | 1011 | ||
1011 | #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) | 1012 | #ifdef CONFIG_HAVE_CLK |
1012 | s->clk = clk_get(NULL, "module_clk"); | 1013 | s->clk = clk_get(NULL, "module_clk"); |
1013 | #endif | 1014 | #endif |
1014 | 1015 | ||
@@ -1030,7 +1031,7 @@ static void sci_shutdown(struct uart_port *port) | |||
1030 | if (s->disable) | 1031 | if (s->disable) |
1031 | s->disable(port); | 1032 | s->disable(port); |
1032 | 1033 | ||
1033 | #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) | 1034 | #ifdef CONFIG_HAVE_CLK |
1034 | clk_put(s->clk); | 1035 | clk_put(s->clk); |
1035 | s->clk = NULL; | 1036 | s->clk = NULL; |
1036 | #endif | 1037 | #endif |
@@ -1041,24 +1042,11 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1041 | { | 1042 | { |
1042 | struct sci_port *s = &sci_ports[port->line]; | 1043 | struct sci_port *s = &sci_ports[port->line]; |
1043 | unsigned int status, baud, smr_val; | 1044 | unsigned int status, baud, smr_val; |
1044 | int t; | 1045 | int t = -1; |
1045 | 1046 | ||
1046 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | 1047 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); |
1047 | 1048 | if (likely(baud)) | |
1048 | switch (baud) { | 1049 | t = SCBRR_VALUE(baud, port->uartclk); |
1049 | case 0: | ||
1050 | t = -1; | ||
1051 | break; | ||
1052 | default: | ||
1053 | { | ||
1054 | #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) | ||
1055 | t = SCBRR_VALUE(baud, clk_get_rate(s->clk)); | ||
1056 | #else | ||
1057 | t = SCBRR_VALUE(baud); | ||
1058 | #endif | ||
1059 | break; | ||
1060 | } | ||
1061 | } | ||
1062 | 1050 | ||
1063 | do { | 1051 | do { |
1064 | status = sci_in(port, SCxSR); | 1052 | status = sci_in(port, SCxSR); |
@@ -1113,7 +1101,7 @@ static const char *sci_type(struct uart_port *port) | |||
1113 | case PORT_IRDA: return "irda"; | 1101 | case PORT_IRDA: return "irda"; |
1114 | } | 1102 | } |
1115 | 1103 | ||
1116 | return 0; | 1104 | return NULL; |
1117 | } | 1105 | } |
1118 | 1106 | ||
1119 | static void sci_release_port(struct uart_port *port) | 1107 | static void sci_release_port(struct uart_port *port) |
@@ -1145,19 +1133,23 @@ static void sci_config_port(struct uart_port *port, int flags) | |||
1145 | break; | 1133 | break; |
1146 | } | 1134 | } |
1147 | 1135 | ||
1148 | #if defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) | 1136 | if (port->flags & UPF_IOREMAP && !port->membase) { |
1149 | if (port->mapbase == 0) | 1137 | #if defined(CONFIG_SUPERH64) |
1150 | port->mapbase = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF"); | 1138 | port->mapbase = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF"); |
1151 | 1139 | port->membase = (void __iomem *)port->mapbase; | |
1152 | port->membase = (void __iomem *)port->mapbase; | 1140 | #else |
1141 | port->membase = ioremap_nocache(port->mapbase, 0x40); | ||
1153 | #endif | 1142 | #endif |
1143 | |||
1144 | printk(KERN_ERR "sci: can't remap port#%d\n", port->line); | ||
1145 | } | ||
1154 | } | 1146 | } |
1155 | 1147 | ||
1156 | static int sci_verify_port(struct uart_port *port, struct serial_struct *ser) | 1148 | static int sci_verify_port(struct uart_port *port, struct serial_struct *ser) |
1157 | { | 1149 | { |
1158 | struct sci_port *s = &sci_ports[port->line]; | 1150 | struct sci_port *s = &sci_ports[port->line]; |
1159 | 1151 | ||
1160 | if (ser->irq != s->irqs[SCIx_TXI_IRQ] || ser->irq > NR_IRQS) | 1152 | if (ser->irq != s->irqs[SCIx_TXI_IRQ] || ser->irq > nr_irqs) |
1161 | return -EINVAL; | 1153 | return -EINVAL; |
1162 | if (ser->baud_base < 2400) | 1154 | if (ser->baud_base < 2400) |
1163 | /* No paper tape reader for Mitch.. */ | 1155 | /* No paper tape reader for Mitch.. */ |
@@ -1207,17 +1199,17 @@ static void __init sci_init_ports(void) | |||
1207 | sci_ports[i].disable = h8300_sci_disable; | 1199 | sci_ports[i].disable = h8300_sci_disable; |
1208 | #endif | 1200 | #endif |
1209 | sci_ports[i].port.uartclk = CONFIG_CPU_CLOCK; | 1201 | sci_ports[i].port.uartclk = CONFIG_CPU_CLOCK; |
1210 | #elif defined(CONFIG_SUPERH64) | 1202 | #elif defined(CONFIG_HAVE_CLK) |
1211 | sci_ports[i].port.uartclk = current_cpu_data.module_clock * 16; | ||
1212 | #else | ||
1213 | /* | 1203 | /* |
1214 | * XXX: We should use a proper SCI/SCIF clock | 1204 | * XXX: We should use a proper SCI/SCIF clock |
1215 | */ | 1205 | */ |
1216 | { | 1206 | { |
1217 | struct clk *clk = clk_get(NULL, "module_clk"); | 1207 | struct clk *clk = clk_get(NULL, "module_clk"); |
1218 | sci_ports[i].port.uartclk = clk_get_rate(clk) * 16; | 1208 | sci_ports[i].port.uartclk = clk_get_rate(clk); |
1219 | clk_put(clk); | 1209 | clk_put(clk); |
1220 | } | 1210 | } |
1211 | #else | ||
1212 | #error "Need a valid uartclk" | ||
1221 | #endif | 1213 | #endif |
1222 | 1214 | ||
1223 | sci_ports[i].break_timer.data = (unsigned long)&sci_ports[i]; | 1215 | sci_ports[i].break_timer.data = (unsigned long)&sci_ports[i]; |
@@ -1285,7 +1277,7 @@ static int __init serial_console_setup(struct console *co, char *options) | |||
1285 | 1277 | ||
1286 | port->type = serial_console_port->type; | 1278 | port->type = serial_console_port->type; |
1287 | 1279 | ||
1288 | #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) | 1280 | #ifdef CONFIG_HAVE_CLK |
1289 | if (!serial_console_port->clk) | 1281 | if (!serial_console_port->clk) |
1290 | serial_console_port->clk = clk_get(NULL, "module_clk"); | 1282 | serial_console_port->clk = clk_get(NULL, "module_clk"); |
1291 | #endif | 1283 | #endif |
@@ -1436,7 +1428,7 @@ static struct uart_driver sci_uart_driver = { | |||
1436 | static int __devinit sci_probe(struct platform_device *dev) | 1428 | static int __devinit sci_probe(struct platform_device *dev) |
1437 | { | 1429 | { |
1438 | struct plat_sci_port *p = dev->dev.platform_data; | 1430 | struct plat_sci_port *p = dev->dev.platform_data; |
1439 | int i; | 1431 | int i, ret = -EINVAL; |
1440 | 1432 | ||
1441 | for (i = 0; p && p->flags != 0; p++, i++) { | 1433 | for (i = 0; p && p->flags != 0; p++, i++) { |
1442 | struct sci_port *sciport = &sci_ports[i]; | 1434 | struct sci_port *sciport = &sci_ports[i]; |
@@ -1453,12 +1445,22 @@ static int __devinit sci_probe(struct platform_device *dev) | |||
1453 | 1445 | ||
1454 | sciport->port.mapbase = p->mapbase; | 1446 | sciport->port.mapbase = p->mapbase; |
1455 | 1447 | ||
1456 | /* | 1448 | if (p->mapbase && !p->membase) { |
1457 | * For the simple (and majority of) cases where we don't need | 1449 | if (p->flags & UPF_IOREMAP) { |
1458 | * to do any remapping, just cast the cookie directly. | 1450 | p->membase = ioremap_nocache(p->mapbase, 0x40); |
1459 | */ | 1451 | if (IS_ERR(p->membase)) { |
1460 | if (p->mapbase && !p->membase && !(p->flags & UPF_IOREMAP)) | 1452 | ret = PTR_ERR(p->membase); |
1461 | p->membase = (void __iomem *)p->mapbase; | 1453 | goto err_unreg; |
1454 | } | ||
1455 | } else { | ||
1456 | /* | ||
1457 | * For the simple (and majority of) cases | ||
1458 | * where we don't need to do any remapping, | ||
1459 | * just cast the cookie directly. | ||
1460 | */ | ||
1461 | p->membase = (void __iomem *)p->mapbase; | ||
1462 | } | ||
1463 | } | ||
1462 | 1464 | ||
1463 | sciport->port.membase = p->membase; | 1465 | sciport->port.membase = p->membase; |
1464 | 1466 | ||
@@ -1479,7 +1481,7 @@ static int __devinit sci_probe(struct platform_device *dev) | |||
1479 | kgdb_putchar = kgdb_sci_putchar; | 1481 | kgdb_putchar = kgdb_sci_putchar; |
1480 | #endif | 1482 | #endif |
1481 | 1483 | ||
1482 | #ifdef CONFIG_CPU_FREQ | 1484 | #if defined(CONFIG_CPU_FREQ) && defined(CONFIG_HAVE_CLK) |
1483 | cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER); | 1485 | cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER); |
1484 | dev_info(&dev->dev, "CPU frequency notifier registered\n"); | 1486 | dev_info(&dev->dev, "CPU frequency notifier registered\n"); |
1485 | #endif | 1487 | #endif |
@@ -1489,6 +1491,12 @@ static int __devinit sci_probe(struct platform_device *dev) | |||
1489 | #endif | 1491 | #endif |
1490 | 1492 | ||
1491 | return 0; | 1493 | return 0; |
1494 | |||
1495 | err_unreg: | ||
1496 | for (i = i - 1; i >= 0; i--) | ||
1497 | uart_remove_one_port(&sci_uart_driver, &sci_ports[i].port); | ||
1498 | |||
1499 | return ret; | ||
1492 | } | 1500 | } |
1493 | 1501 | ||
1494 | static int __devexit sci_remove(struct platform_device *dev) | 1502 | static int __devexit sci_remove(struct platform_device *dev) |
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 8a0749e34ca3..7cd28b226800 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h | |||
@@ -320,18 +320,16 @@ | |||
320 | #define SCI_EVENT_WRITE_WAKEUP 0 | 320 | #define SCI_EVENT_WRITE_WAKEUP 0 |
321 | 321 | ||
322 | #define SCI_IN(size, offset) \ | 322 | #define SCI_IN(size, offset) \ |
323 | unsigned int addr = port->mapbase + (offset); \ | ||
324 | if ((size) == 8) { \ | 323 | if ((size) == 8) { \ |
325 | return ctrl_inb(addr); \ | 324 | return ioread8(port->membase + (offset)); \ |
326 | } else { \ | 325 | } else { \ |
327 | return ctrl_inw(addr); \ | 326 | return ioread16(port->membase + (offset)); \ |
328 | } | 327 | } |
329 | #define SCI_OUT(size, offset, value) \ | 328 | #define SCI_OUT(size, offset, value) \ |
330 | unsigned int addr = port->mapbase + (offset); \ | ||
331 | if ((size) == 8) { \ | 329 | if ((size) == 8) { \ |
332 | ctrl_outb(value, addr); \ | 330 | iowrite8(value, port->membase + (offset)); \ |
333 | } else if ((size) == 16) { \ | 331 | } else if ((size) == 16) { \ |
334 | ctrl_outw(value, addr); \ | 332 | iowrite16(value, port->membase + (offset)); \ |
335 | } | 333 | } |
336 | 334 | ||
337 | #define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\ | 335 | #define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\ |
@@ -791,11 +789,16 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
791 | defined(CONFIG_CPU_SUBTYPE_SH7721) | 789 | defined(CONFIG_CPU_SUBTYPE_SH7721) |
792 | #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1) | 790 | #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1) |
793 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) | 791 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) |
794 | #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(16*bps)-1) | 792 | static inline int scbrr_calc(struct uart_port *port, int bps, int clk) |
793 | { | ||
794 | if (port->type == PORT_SCIF) | ||
795 | return (clk+16*bps)/(32*bps)-1; | ||
796 | else | ||
797 | return ((clk*2)+16*bps)/(16*bps)-1; | ||
798 | } | ||
799 | #define SCBRR_VALUE(bps, clk) scbrr_calc(port, bps, clk) | ||
795 | #elif defined(__H8300H__) || defined(__H8300S__) | 800 | #elif defined(__H8300H__) || defined(__H8300S__) |
796 | #define SCBRR_VALUE(bps) (((CONFIG_CPU_CLOCK*1000/32)/bps)-1) | 801 | #define SCBRR_VALUE(bps, clk) (((clk*1000/32)/bps)-1) |
797 | #elif defined(CONFIG_SUPERH64) | ||
798 | #define SCBRR_VALUE(bps) ((current_cpu_data.module_clock+16*bps)/(32*bps)-1) | ||
799 | #else /* Generic SH */ | 802 | #else /* Generic SH */ |
800 | #define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(32*bps)-1) | 803 | #define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(32*bps)-1) |
801 | #endif | 804 | #endif |
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c index b73e3c0056cd..d5276c012f78 100644 --- a/drivers/serial/sn_console.c +++ b/drivers/serial/sn_console.c | |||
@@ -61,7 +61,7 @@ | |||
61 | #define SN_SAL_BUFFER_SIZE (64 * (1 << 10)) | 61 | #define SN_SAL_BUFFER_SIZE (64 * (1 << 10)) |
62 | 62 | ||
63 | #define SN_SAL_UART_FIFO_DEPTH 16 | 63 | #define SN_SAL_UART_FIFO_DEPTH 16 |
64 | #define SN_SAL_UART_FIFO_SPEED_CPS 9600/10 | 64 | #define SN_SAL_UART_FIFO_SPEED_CPS (9600/10) |
65 | 65 | ||
66 | /* sn_transmit_chars() calling args */ | 66 | /* sn_transmit_chars() calling args */ |
67 | #define TRANSMIT_BUFFERED 0 | 67 | #define TRANSMIT_BUFFERED 0 |
diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c index 539c933b335f..315a9333ca3c 100644 --- a/drivers/serial/ucc_uart.c +++ b/drivers/serial/ucc_uart.c | |||
@@ -1066,7 +1066,7 @@ static int qe_uart_verify_port(struct uart_port *port, | |||
1066 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM) | 1066 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM) |
1067 | return -EINVAL; | 1067 | return -EINVAL; |
1068 | 1068 | ||
1069 | if (ser->irq < 0 || ser->irq >= NR_IRQS) | 1069 | if (ser->irq < 0 || ser->irq >= nr_irqs) |
1070 | return -EINVAL; | 1070 | return -EINVAL; |
1071 | 1071 | ||
1072 | if (ser->baud_base < 9600) | 1072 | if (ser->baud_base < 9600) |
diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile index a96f4a8cfeb8..6a025cefe6dc 100644 --- a/drivers/sh/Makefile +++ b/drivers/sh/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Makefile for the SuperH specific drivers. | 2 | # Makefile for the SuperH specific drivers. |
3 | # | 3 | # |
4 | |||
5 | obj-$(CONFIG_SUPERHYWAY) += superhyway/ | 4 | obj-$(CONFIG_SUPERHYWAY) += superhyway/ |
6 | obj-$(CONFIG_MAPLE) += maple/ | 5 | obj-$(CONFIG_MAPLE) += maple/ |
6 | obj-y += intc.o | ||
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c new file mode 100644 index 000000000000..58d24c5a76ce --- /dev/null +++ b/drivers/sh/intc.c | |||
@@ -0,0 +1,713 @@ | |||
1 | /* | ||
2 | * Shared interrupt handling code for IPR and INTC2 types of IRQs. | ||
3 | * | ||
4 | * Copyright (C) 2007, 2008 Magnus Damm | ||
5 | * | ||
6 | * Based on intc2.c and ipr.c | ||
7 | * | ||
8 | * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi | ||
9 | * Copyright (C) 2000 Kazumoto Kojima | ||
10 | * Copyright (C) 2001 David J. Mckay (david.mckay@st.com) | ||
11 | * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp> | ||
12 | * Copyright (C) 2005, 2006 Paul Mundt | ||
13 | * | ||
14 | * This file is subject to the terms and conditions of the GNU General Public | ||
15 | * License. See the file "COPYING" in the main directory of this archive | ||
16 | * for more details. | ||
17 | */ | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/irq.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/bootmem.h> | ||
24 | #include <linux/sh_intc.h> | ||
25 | |||
26 | #define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \ | ||
27 | ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \ | ||
28 | ((addr_e) << 16) | ((addr_d << 24))) | ||
29 | |||
30 | #define _INTC_SHIFT(h) (h & 0x1f) | ||
31 | #define _INTC_WIDTH(h) ((h >> 5) & 0xf) | ||
32 | #define _INTC_FN(h) ((h >> 9) & 0xf) | ||
33 | #define _INTC_MODE(h) ((h >> 13) & 0x7) | ||
34 | #define _INTC_ADDR_E(h) ((h >> 16) & 0xff) | ||
35 | #define _INTC_ADDR_D(h) ((h >> 24) & 0xff) | ||
36 | |||
37 | struct intc_handle_int { | ||
38 | unsigned int irq; | ||
39 | unsigned long handle; | ||
40 | }; | ||
41 | |||
42 | struct intc_desc_int { | ||
43 | unsigned long *reg; | ||
44 | #ifdef CONFIG_SMP | ||
45 | unsigned long *smp; | ||
46 | #endif | ||
47 | unsigned int nr_reg; | ||
48 | struct intc_handle_int *prio; | ||
49 | unsigned int nr_prio; | ||
50 | struct intc_handle_int *sense; | ||
51 | unsigned int nr_sense; | ||
52 | struct irq_chip chip; | ||
53 | }; | ||
54 | |||
55 | #ifdef CONFIG_SMP | ||
56 | #define IS_SMP(x) x.smp | ||
57 | #define INTC_REG(d, x, c) (d->reg[(x)] + ((d->smp[(x)] & 0xff) * c)) | ||
58 | #define SMP_NR(d, x) ((d->smp[(x)] >> 8) ? (d->smp[(x)] >> 8) : 1) | ||
59 | #else | ||
60 | #define IS_SMP(x) 0 | ||
61 | #define INTC_REG(d, x, c) (d->reg[(x)]) | ||
62 | #define SMP_NR(d, x) 1 | ||
63 | #endif | ||
64 | |||
65 | static unsigned int intc_prio_level[NR_IRQS]; /* for now */ | ||
66 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) | ||
67 | static unsigned long ack_handle[NR_IRQS]; | ||
68 | #endif | ||
69 | |||
70 | static inline struct intc_desc_int *get_intc_desc(unsigned int irq) | ||
71 | { | ||
72 | struct irq_chip *chip = get_irq_chip(irq); | ||
73 | return (void *)((char *)chip - offsetof(struct intc_desc_int, chip)); | ||
74 | } | ||
75 | |||
76 | static inline unsigned int set_field(unsigned int value, | ||
77 | unsigned int field_value, | ||
78 | unsigned int handle) | ||
79 | { | ||
80 | unsigned int width = _INTC_WIDTH(handle); | ||
81 | unsigned int shift = _INTC_SHIFT(handle); | ||
82 | |||
83 | value &= ~(((1 << width) - 1) << shift); | ||
84 | value |= field_value << shift; | ||
85 | return value; | ||
86 | } | ||
87 | |||
88 | static void write_8(unsigned long addr, unsigned long h, unsigned long data) | ||
89 | { | ||
90 | __raw_writeb(set_field(0, data, h), addr); | ||
91 | } | ||
92 | |||
93 | static void write_16(unsigned long addr, unsigned long h, unsigned long data) | ||
94 | { | ||
95 | __raw_writew(set_field(0, data, h), addr); | ||
96 | } | ||
97 | |||
98 | static void write_32(unsigned long addr, unsigned long h, unsigned long data) | ||
99 | { | ||
100 | __raw_writel(set_field(0, data, h), addr); | ||
101 | } | ||
102 | |||
103 | static void modify_8(unsigned long addr, unsigned long h, unsigned long data) | ||
104 | { | ||
105 | unsigned long flags; | ||
106 | local_irq_save(flags); | ||
107 | __raw_writeb(set_field(__raw_readb(addr), data, h), addr); | ||
108 | local_irq_restore(flags); | ||
109 | } | ||
110 | |||
111 | static void modify_16(unsigned long addr, unsigned long h, unsigned long data) | ||
112 | { | ||
113 | unsigned long flags; | ||
114 | local_irq_save(flags); | ||
115 | __raw_writew(set_field(__raw_readw(addr), data, h), addr); | ||
116 | local_irq_restore(flags); | ||
117 | } | ||
118 | |||
119 | static void modify_32(unsigned long addr, unsigned long h, unsigned long data) | ||
120 | { | ||
121 | unsigned long flags; | ||
122 | local_irq_save(flags); | ||
123 | __raw_writel(set_field(__raw_readl(addr), data, h), addr); | ||
124 | local_irq_restore(flags); | ||
125 | } | ||
126 | |||
127 | enum { REG_FN_ERR = 0, REG_FN_WRITE_BASE = 1, REG_FN_MODIFY_BASE = 5 }; | ||
128 | |||
129 | static void (*intc_reg_fns[])(unsigned long addr, | ||
130 | unsigned long h, | ||
131 | unsigned long data) = { | ||
132 | [REG_FN_WRITE_BASE + 0] = write_8, | ||
133 | [REG_FN_WRITE_BASE + 1] = write_16, | ||
134 | [REG_FN_WRITE_BASE + 3] = write_32, | ||
135 | [REG_FN_MODIFY_BASE + 0] = modify_8, | ||
136 | [REG_FN_MODIFY_BASE + 1] = modify_16, | ||
137 | [REG_FN_MODIFY_BASE + 3] = modify_32, | ||
138 | }; | ||
139 | |||
140 | enum { MODE_ENABLE_REG = 0, /* Bit(s) set -> interrupt enabled */ | ||
141 | MODE_MASK_REG, /* Bit(s) set -> interrupt disabled */ | ||
142 | MODE_DUAL_REG, /* Two registers, set bit to enable / disable */ | ||
143 | MODE_PRIO_REG, /* Priority value written to enable interrupt */ | ||
144 | MODE_PCLR_REG, /* Above plus all bits set to disable interrupt */ | ||
145 | }; | ||
146 | |||
147 | static void intc_mode_field(unsigned long addr, | ||
148 | unsigned long handle, | ||
149 | void (*fn)(unsigned long, | ||
150 | unsigned long, | ||
151 | unsigned long), | ||
152 | unsigned int irq) | ||
153 | { | ||
154 | fn(addr, handle, ((1 << _INTC_WIDTH(handle)) - 1)); | ||
155 | } | ||
156 | |||
157 | static void intc_mode_zero(unsigned long addr, | ||
158 | unsigned long handle, | ||
159 | void (*fn)(unsigned long, | ||
160 | unsigned long, | ||
161 | unsigned long), | ||
162 | unsigned int irq) | ||
163 | { | ||
164 | fn(addr, handle, 0); | ||
165 | } | ||
166 | |||
167 | static void intc_mode_prio(unsigned long addr, | ||
168 | unsigned long handle, | ||
169 | void (*fn)(unsigned long, | ||
170 | unsigned long, | ||
171 | unsigned long), | ||
172 | unsigned int irq) | ||
173 | { | ||
174 | fn(addr, handle, intc_prio_level[irq]); | ||
175 | } | ||
176 | |||
177 | static void (*intc_enable_fns[])(unsigned long addr, | ||
178 | unsigned long handle, | ||
179 | void (*fn)(unsigned long, | ||
180 | unsigned long, | ||
181 | unsigned long), | ||
182 | unsigned int irq) = { | ||
183 | [MODE_ENABLE_REG] = intc_mode_field, | ||
184 | [MODE_MASK_REG] = intc_mode_zero, | ||
185 | [MODE_DUAL_REG] = intc_mode_field, | ||
186 | [MODE_PRIO_REG] = intc_mode_prio, | ||
187 | [MODE_PCLR_REG] = intc_mode_prio, | ||
188 | }; | ||
189 | |||
190 | static void (*intc_disable_fns[])(unsigned long addr, | ||
191 | unsigned long handle, | ||
192 | void (*fn)(unsigned long, | ||
193 | unsigned long, | ||
194 | unsigned long), | ||
195 | unsigned int irq) = { | ||
196 | [MODE_ENABLE_REG] = intc_mode_zero, | ||
197 | [MODE_MASK_REG] = intc_mode_field, | ||
198 | [MODE_DUAL_REG] = intc_mode_field, | ||
199 | [MODE_PRIO_REG] = intc_mode_zero, | ||
200 | [MODE_PCLR_REG] = intc_mode_field, | ||
201 | }; | ||
202 | |||
203 | static inline void _intc_enable(unsigned int irq, unsigned long handle) | ||
204 | { | ||
205 | struct intc_desc_int *d = get_intc_desc(irq); | ||
206 | unsigned long addr; | ||
207 | unsigned int cpu; | ||
208 | |||
209 | for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) { | ||
210 | addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu); | ||
211 | intc_enable_fns[_INTC_MODE(handle)](addr, handle, intc_reg_fns\ | ||
212 | [_INTC_FN(handle)], irq); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | static void intc_enable(unsigned int irq) | ||
217 | { | ||
218 | _intc_enable(irq, (unsigned long)get_irq_chip_data(irq)); | ||
219 | } | ||
220 | |||
221 | static void intc_disable(unsigned int irq) | ||
222 | { | ||
223 | struct intc_desc_int *d = get_intc_desc(irq); | ||
224 | unsigned long handle = (unsigned long) get_irq_chip_data(irq); | ||
225 | unsigned long addr; | ||
226 | unsigned int cpu; | ||
227 | |||
228 | for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) { | ||
229 | addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu); | ||
230 | intc_disable_fns[_INTC_MODE(handle)](addr, handle,intc_reg_fns\ | ||
231 | [_INTC_FN(handle)], irq); | ||
232 | } | ||
233 | } | ||
234 | |||
235 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) | ||
236 | static void intc_mask_ack(unsigned int irq) | ||
237 | { | ||
238 | struct intc_desc_int *d = get_intc_desc(irq); | ||
239 | unsigned long handle = ack_handle[irq]; | ||
240 | unsigned long addr; | ||
241 | |||
242 | intc_disable(irq); | ||
243 | |||
244 | /* read register and write zero only to the assocaited bit */ | ||
245 | |||
246 | if (handle) { | ||
247 | addr = INTC_REG(d, _INTC_ADDR_D(handle), 0); | ||
248 | switch (_INTC_FN(handle)) { | ||
249 | case REG_FN_MODIFY_BASE + 0: /* 8bit */ | ||
250 | __raw_readb(addr); | ||
251 | __raw_writeb(0xff ^ set_field(0, 1, handle), addr); | ||
252 | break; | ||
253 | case REG_FN_MODIFY_BASE + 1: /* 16bit */ | ||
254 | __raw_readw(addr); | ||
255 | __raw_writew(0xffff ^ set_field(0, 1, handle), addr); | ||
256 | break; | ||
257 | case REG_FN_MODIFY_BASE + 3: /* 32bit */ | ||
258 | __raw_readl(addr); | ||
259 | __raw_writel(0xffffffff ^ set_field(0, 1, handle), addr); | ||
260 | break; | ||
261 | default: | ||
262 | BUG(); | ||
263 | break; | ||
264 | } | ||
265 | } | ||
266 | } | ||
267 | #endif | ||
268 | |||
269 | static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp, | ||
270 | unsigned int nr_hp, | ||
271 | unsigned int irq) | ||
272 | { | ||
273 | int i; | ||
274 | |||
275 | /* this doesn't scale well, but... | ||
276 | * | ||
277 | * this function should only be used for cerain uncommon | ||
278 | * operations such as intc_set_priority() and intc_set_sense() | ||
279 | * and in those rare cases performance doesn't matter that much. | ||
280 | * keeping the memory footprint low is more important. | ||
281 | * | ||
282 | * one rather simple way to speed this up and still keep the | ||
283 | * memory footprint down is to make sure the array is sorted | ||
284 | * and then perform a bisect to lookup the irq. | ||
285 | */ | ||
286 | |||
287 | for (i = 0; i < nr_hp; i++) { | ||
288 | if ((hp + i)->irq != irq) | ||
289 | continue; | ||
290 | |||
291 | return hp + i; | ||
292 | } | ||
293 | |||
294 | return NULL; | ||
295 | } | ||
296 | |||
297 | int intc_set_priority(unsigned int irq, unsigned int prio) | ||
298 | { | ||
299 | struct intc_desc_int *d = get_intc_desc(irq); | ||
300 | struct intc_handle_int *ihp; | ||
301 | |||
302 | if (!intc_prio_level[irq] || prio <= 1) | ||
303 | return -EINVAL; | ||
304 | |||
305 | ihp = intc_find_irq(d->prio, d->nr_prio, irq); | ||
306 | if (ihp) { | ||
307 | if (prio >= (1 << _INTC_WIDTH(ihp->handle))) | ||
308 | return -EINVAL; | ||
309 | |||
310 | intc_prio_level[irq] = prio; | ||
311 | |||
312 | /* | ||
313 | * only set secondary masking method directly | ||
314 | * primary masking method is using intc_prio_level[irq] | ||
315 | * priority level will be set during next enable() | ||
316 | */ | ||
317 | |||
318 | if (_INTC_FN(ihp->handle) != REG_FN_ERR) | ||
319 | _intc_enable(irq, ihp->handle); | ||
320 | } | ||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | #define VALID(x) (x | 0x80) | ||
325 | |||
326 | static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = { | ||
327 | [IRQ_TYPE_EDGE_FALLING] = VALID(0), | ||
328 | [IRQ_TYPE_EDGE_RISING] = VALID(1), | ||
329 | [IRQ_TYPE_LEVEL_LOW] = VALID(2), | ||
330 | /* SH7706, SH7707 and SH7709 do not support high level triggered */ | ||
331 | #if !defined(CONFIG_CPU_SUBTYPE_SH7706) && \ | ||
332 | !defined(CONFIG_CPU_SUBTYPE_SH7707) && \ | ||
333 | !defined(CONFIG_CPU_SUBTYPE_SH7709) | ||
334 | [IRQ_TYPE_LEVEL_HIGH] = VALID(3), | ||
335 | #endif | ||
336 | }; | ||
337 | |||
338 | static int intc_set_sense(unsigned int irq, unsigned int type) | ||
339 | { | ||
340 | struct intc_desc_int *d = get_intc_desc(irq); | ||
341 | unsigned char value = intc_irq_sense_table[type & IRQ_TYPE_SENSE_MASK]; | ||
342 | struct intc_handle_int *ihp; | ||
343 | unsigned long addr; | ||
344 | |||
345 | if (!value) | ||
346 | return -EINVAL; | ||
347 | |||
348 | ihp = intc_find_irq(d->sense, d->nr_sense, irq); | ||
349 | if (ihp) { | ||
350 | addr = INTC_REG(d, _INTC_ADDR_E(ihp->handle), 0); | ||
351 | intc_reg_fns[_INTC_FN(ihp->handle)](addr, ihp->handle, value); | ||
352 | } | ||
353 | return 0; | ||
354 | } | ||
355 | |||
356 | static unsigned int __init intc_get_reg(struct intc_desc_int *d, | ||
357 | unsigned long address) | ||
358 | { | ||
359 | unsigned int k; | ||
360 | |||
361 | for (k = 0; k < d->nr_reg; k++) { | ||
362 | if (d->reg[k] == address) | ||
363 | return k; | ||
364 | } | ||
365 | |||
366 | BUG(); | ||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | static intc_enum __init intc_grp_id(struct intc_desc *desc, | ||
371 | intc_enum enum_id) | ||
372 | { | ||
373 | struct intc_group *g = desc->groups; | ||
374 | unsigned int i, j; | ||
375 | |||
376 | for (i = 0; g && enum_id && i < desc->nr_groups; i++) { | ||
377 | g = desc->groups + i; | ||
378 | |||
379 | for (j = 0; g->enum_ids[j]; j++) { | ||
380 | if (g->enum_ids[j] != enum_id) | ||
381 | continue; | ||
382 | |||
383 | return g->enum_id; | ||
384 | } | ||
385 | } | ||
386 | |||
387 | return 0; | ||
388 | } | ||
389 | |||
390 | static unsigned int __init intc_mask_data(struct intc_desc *desc, | ||
391 | struct intc_desc_int *d, | ||
392 | intc_enum enum_id, int do_grps) | ||
393 | { | ||
394 | struct intc_mask_reg *mr = desc->mask_regs; | ||
395 | unsigned int i, j, fn, mode; | ||
396 | unsigned long reg_e, reg_d; | ||
397 | |||
398 | for (i = 0; mr && enum_id && i < desc->nr_mask_regs; i++) { | ||
399 | mr = desc->mask_regs + i; | ||
400 | |||
401 | for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) { | ||
402 | if (mr->enum_ids[j] != enum_id) | ||
403 | continue; | ||
404 | |||
405 | if (mr->set_reg && mr->clr_reg) { | ||
406 | fn = REG_FN_WRITE_BASE; | ||
407 | mode = MODE_DUAL_REG; | ||
408 | reg_e = mr->clr_reg; | ||
409 | reg_d = mr->set_reg; | ||
410 | } else { | ||
411 | fn = REG_FN_MODIFY_BASE; | ||
412 | if (mr->set_reg) { | ||
413 | mode = MODE_ENABLE_REG; | ||
414 | reg_e = mr->set_reg; | ||
415 | reg_d = mr->set_reg; | ||
416 | } else { | ||
417 | mode = MODE_MASK_REG; | ||
418 | reg_e = mr->clr_reg; | ||
419 | reg_d = mr->clr_reg; | ||
420 | } | ||
421 | } | ||
422 | |||
423 | fn += (mr->reg_width >> 3) - 1; | ||
424 | return _INTC_MK(fn, mode, | ||
425 | intc_get_reg(d, reg_e), | ||
426 | intc_get_reg(d, reg_d), | ||
427 | 1, | ||
428 | (mr->reg_width - 1) - j); | ||
429 | } | ||
430 | } | ||
431 | |||
432 | if (do_grps) | ||
433 | return intc_mask_data(desc, d, intc_grp_id(desc, enum_id), 0); | ||
434 | |||
435 | return 0; | ||
436 | } | ||
437 | |||
438 | static unsigned int __init intc_prio_data(struct intc_desc *desc, | ||
439 | struct intc_desc_int *d, | ||
440 | intc_enum enum_id, int do_grps) | ||
441 | { | ||
442 | struct intc_prio_reg *pr = desc->prio_regs; | ||
443 | unsigned int i, j, fn, mode, bit; | ||
444 | unsigned long reg_e, reg_d; | ||
445 | |||
446 | for (i = 0; pr && enum_id && i < desc->nr_prio_regs; i++) { | ||
447 | pr = desc->prio_regs + i; | ||
448 | |||
449 | for (j = 0; j < ARRAY_SIZE(pr->enum_ids); j++) { | ||
450 | if (pr->enum_ids[j] != enum_id) | ||
451 | continue; | ||
452 | |||
453 | if (pr->set_reg && pr->clr_reg) { | ||
454 | fn = REG_FN_WRITE_BASE; | ||
455 | mode = MODE_PCLR_REG; | ||
456 | reg_e = pr->set_reg; | ||
457 | reg_d = pr->clr_reg; | ||
458 | } else { | ||
459 | fn = REG_FN_MODIFY_BASE; | ||
460 | mode = MODE_PRIO_REG; | ||
461 | if (!pr->set_reg) | ||
462 | BUG(); | ||
463 | reg_e = pr->set_reg; | ||
464 | reg_d = pr->set_reg; | ||
465 | } | ||
466 | |||
467 | fn += (pr->reg_width >> 3) - 1; | ||
468 | |||
469 | BUG_ON((j + 1) * pr->field_width > pr->reg_width); | ||
470 | |||
471 | bit = pr->reg_width - ((j + 1) * pr->field_width); | ||
472 | |||
473 | return _INTC_MK(fn, mode, | ||
474 | intc_get_reg(d, reg_e), | ||
475 | intc_get_reg(d, reg_d), | ||
476 | pr->field_width, bit); | ||
477 | } | ||
478 | } | ||
479 | |||
480 | if (do_grps) | ||
481 | return intc_prio_data(desc, d, intc_grp_id(desc, enum_id), 0); | ||
482 | |||
483 | return 0; | ||
484 | } | ||
485 | |||
486 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) | ||
487 | static unsigned int __init intc_ack_data(struct intc_desc *desc, | ||
488 | struct intc_desc_int *d, | ||
489 | intc_enum enum_id) | ||
490 | { | ||
491 | struct intc_mask_reg *mr = desc->ack_regs; | ||
492 | unsigned int i, j, fn, mode; | ||
493 | unsigned long reg_e, reg_d; | ||
494 | |||
495 | for (i = 0; mr && enum_id && i < desc->nr_ack_regs; i++) { | ||
496 | mr = desc->ack_regs + i; | ||
497 | |||
498 | for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) { | ||
499 | if (mr->enum_ids[j] != enum_id) | ||
500 | continue; | ||
501 | |||
502 | fn = REG_FN_MODIFY_BASE; | ||
503 | mode = MODE_ENABLE_REG; | ||
504 | reg_e = mr->set_reg; | ||
505 | reg_d = mr->set_reg; | ||
506 | |||
507 | fn += (mr->reg_width >> 3) - 1; | ||
508 | return _INTC_MK(fn, mode, | ||
509 | intc_get_reg(d, reg_e), | ||
510 | intc_get_reg(d, reg_d), | ||
511 | 1, | ||
512 | (mr->reg_width - 1) - j); | ||
513 | } | ||
514 | } | ||
515 | |||
516 | return 0; | ||
517 | } | ||
518 | #endif | ||
519 | |||
520 | static unsigned int __init intc_sense_data(struct intc_desc *desc, | ||
521 | struct intc_desc_int *d, | ||
522 | intc_enum enum_id) | ||
523 | { | ||
524 | struct intc_sense_reg *sr = desc->sense_regs; | ||
525 | unsigned int i, j, fn, bit; | ||
526 | |||
527 | for (i = 0; sr && enum_id && i < desc->nr_sense_regs; i++) { | ||
528 | sr = desc->sense_regs + i; | ||
529 | |||
530 | for (j = 0; j < ARRAY_SIZE(sr->enum_ids); j++) { | ||
531 | if (sr->enum_ids[j] != enum_id) | ||
532 | continue; | ||
533 | |||
534 | fn = REG_FN_MODIFY_BASE; | ||
535 | fn += (sr->reg_width >> 3) - 1; | ||
536 | |||
537 | BUG_ON((j + 1) * sr->field_width > sr->reg_width); | ||
538 | |||
539 | bit = sr->reg_width - ((j + 1) * sr->field_width); | ||
540 | |||
541 | return _INTC_MK(fn, 0, intc_get_reg(d, sr->reg), | ||
542 | 0, sr->field_width, bit); | ||
543 | } | ||
544 | } | ||
545 | |||
546 | return 0; | ||
547 | } | ||
548 | |||
549 | static void __init intc_register_irq(struct intc_desc *desc, | ||
550 | struct intc_desc_int *d, | ||
551 | intc_enum enum_id, | ||
552 | unsigned int irq) | ||
553 | { | ||
554 | struct intc_handle_int *hp; | ||
555 | unsigned int data[2], primary; | ||
556 | |||
557 | /* Prefer single interrupt source bitmap over other combinations: | ||
558 | * 1. bitmap, single interrupt source | ||
559 | * 2. priority, single interrupt source | ||
560 | * 3. bitmap, multiple interrupt sources (groups) | ||
561 | * 4. priority, multiple interrupt sources (groups) | ||
562 | */ | ||
563 | |||
564 | data[0] = intc_mask_data(desc, d, enum_id, 0); | ||
565 | data[1] = intc_prio_data(desc, d, enum_id, 0); | ||
566 | |||
567 | primary = 0; | ||
568 | if (!data[0] && data[1]) | ||
569 | primary = 1; | ||
570 | |||
571 | data[0] = data[0] ? data[0] : intc_mask_data(desc, d, enum_id, 1); | ||
572 | data[1] = data[1] ? data[1] : intc_prio_data(desc, d, enum_id, 1); | ||
573 | |||
574 | if (!data[primary]) | ||
575 | primary ^= 1; | ||
576 | |||
577 | BUG_ON(!data[primary]); /* must have primary masking method */ | ||
578 | |||
579 | disable_irq_nosync(irq); | ||
580 | set_irq_chip_and_handler_name(irq, &d->chip, | ||
581 | handle_level_irq, "level"); | ||
582 | set_irq_chip_data(irq, (void *)data[primary]); | ||
583 | |||
584 | /* set priority level | ||
585 | * - this needs to be at least 2 for 5-bit priorities on 7780 | ||
586 | */ | ||
587 | intc_prio_level[irq] = 2; | ||
588 | |||
589 | /* enable secondary masking method if present */ | ||
590 | if (data[!primary]) | ||
591 | _intc_enable(irq, data[!primary]); | ||
592 | |||
593 | /* add irq to d->prio list if priority is available */ | ||
594 | if (data[1]) { | ||
595 | hp = d->prio + d->nr_prio; | ||
596 | hp->irq = irq; | ||
597 | hp->handle = data[1]; | ||
598 | |||
599 | if (primary) { | ||
600 | /* | ||
601 | * only secondary priority should access registers, so | ||
602 | * set _INTC_FN(h) = REG_FN_ERR for intc_set_priority() | ||
603 | */ | ||
604 | |||
605 | hp->handle &= ~_INTC_MK(0x0f, 0, 0, 0, 0, 0); | ||
606 | hp->handle |= _INTC_MK(REG_FN_ERR, 0, 0, 0, 0, 0); | ||
607 | } | ||
608 | d->nr_prio++; | ||
609 | } | ||
610 | |||
611 | /* add irq to d->sense list if sense is available */ | ||
612 | data[0] = intc_sense_data(desc, d, enum_id); | ||
613 | if (data[0]) { | ||
614 | (d->sense + d->nr_sense)->irq = irq; | ||
615 | (d->sense + d->nr_sense)->handle = data[0]; | ||
616 | d->nr_sense++; | ||
617 | } | ||
618 | |||
619 | /* irq should be disabled by default */ | ||
620 | d->chip.mask(irq); | ||
621 | |||
622 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) | ||
623 | if (desc->ack_regs) | ||
624 | ack_handle[irq] = intc_ack_data(desc, d, enum_id); | ||
625 | #endif | ||
626 | } | ||
627 | |||
628 | static unsigned int __init save_reg(struct intc_desc_int *d, | ||
629 | unsigned int cnt, | ||
630 | unsigned long value, | ||
631 | unsigned int smp) | ||
632 | { | ||
633 | if (value) { | ||
634 | d->reg[cnt] = value; | ||
635 | #ifdef CONFIG_SMP | ||
636 | d->smp[cnt] = smp; | ||
637 | #endif | ||
638 | return 1; | ||
639 | } | ||
640 | |||
641 | return 0; | ||
642 | } | ||
643 | |||
644 | |||
645 | void __init register_intc_controller(struct intc_desc *desc) | ||
646 | { | ||
647 | unsigned int i, k, smp; | ||
648 | struct intc_desc_int *d; | ||
649 | |||
650 | d = alloc_bootmem(sizeof(*d)); | ||
651 | |||
652 | d->nr_reg = desc->mask_regs ? desc->nr_mask_regs * 2 : 0; | ||
653 | d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0; | ||
654 | d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0; | ||
655 | |||
656 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) | ||
657 | d->nr_reg += desc->ack_regs ? desc->nr_ack_regs : 0; | ||
658 | #endif | ||
659 | d->reg = alloc_bootmem(d->nr_reg * sizeof(*d->reg)); | ||
660 | #ifdef CONFIG_SMP | ||
661 | d->smp = alloc_bootmem(d->nr_reg * sizeof(*d->smp)); | ||
662 | #endif | ||
663 | k = 0; | ||
664 | |||
665 | if (desc->mask_regs) { | ||
666 | for (i = 0; i < desc->nr_mask_regs; i++) { | ||
667 | smp = IS_SMP(desc->mask_regs[i]); | ||
668 | k += save_reg(d, k, desc->mask_regs[i].set_reg, smp); | ||
669 | k += save_reg(d, k, desc->mask_regs[i].clr_reg, smp); | ||
670 | } | ||
671 | } | ||
672 | |||
673 | if (desc->prio_regs) { | ||
674 | d->prio = alloc_bootmem(desc->nr_vectors * sizeof(*d->prio)); | ||
675 | |||
676 | for (i = 0; i < desc->nr_prio_regs; i++) { | ||
677 | smp = IS_SMP(desc->prio_regs[i]); | ||
678 | k += save_reg(d, k, desc->prio_regs[i].set_reg, smp); | ||
679 | k += save_reg(d, k, desc->prio_regs[i].clr_reg, smp); | ||
680 | } | ||
681 | } | ||
682 | |||
683 | if (desc->sense_regs) { | ||
684 | d->sense = alloc_bootmem(desc->nr_vectors * sizeof(*d->sense)); | ||
685 | |||
686 | for (i = 0; i < desc->nr_sense_regs; i++) { | ||
687 | k += save_reg(d, k, desc->sense_regs[i].reg, 0); | ||
688 | } | ||
689 | } | ||
690 | |||
691 | d->chip.name = desc->name; | ||
692 | d->chip.mask = intc_disable; | ||
693 | d->chip.unmask = intc_enable; | ||
694 | d->chip.mask_ack = intc_disable; | ||
695 | d->chip.set_type = intc_set_sense; | ||
696 | |||
697 | #if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) | ||
698 | if (desc->ack_regs) { | ||
699 | for (i = 0; i < desc->nr_ack_regs; i++) | ||
700 | k += save_reg(d, k, desc->ack_regs[i].set_reg, 0); | ||
701 | |||
702 | d->chip.mask_ack = intc_mask_ack; | ||
703 | } | ||
704 | #endif | ||
705 | |||
706 | BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */ | ||
707 | |||
708 | for (i = 0; i < desc->nr_vectors; i++) { | ||
709 | struct intc_vect *vect = desc->vectors + i; | ||
710 | |||
711 | intc_register_irq(desc, d, vect->enum_id, evt2irq(vect->vect)); | ||
712 | } | ||
713 | } | ||
diff --git a/drivers/staging/go7007/Kconfig b/drivers/staging/go7007/Kconfig index 57a121c338c4..593fdb767aad 100644 --- a/drivers/staging/go7007/Kconfig +++ b/drivers/staging/go7007/Kconfig | |||
@@ -1,10 +1,12 @@ | |||
1 | config VIDEO_GO7007 | 1 | config VIDEO_GO7007 |
2 | tristate "Go 7007 support" | 2 | tristate "Go 7007 support" |
3 | depends on VIDEO_DEV && PCI && I2C && INPUT | 3 | depends on VIDEO_DEV && PCI && I2C && INPUT |
4 | depends on SND | ||
4 | select VIDEOBUF_DMA_SG | 5 | select VIDEOBUF_DMA_SG |
5 | select VIDEO_IR | 6 | select VIDEO_IR |
6 | select VIDEO_TUNER | 7 | select VIDEO_TUNER |
7 | select VIDEO_TVEEPROM | 8 | select VIDEO_TVEEPROM |
9 | select SND_PCM | ||
8 | select CRC32 | 10 | select CRC32 |
9 | default N | 11 | default N |
10 | ---help--- | 12 | ---help--- |
diff --git a/drivers/staging/sxg/Kconfig b/drivers/staging/sxg/Kconfig index 1ae350806600..6e6cf0b9ef99 100644 --- a/drivers/staging/sxg/Kconfig +++ b/drivers/staging/sxg/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | config SXG | 1 | config SXG |
2 | tristate "Alacritech SLIC Technology Non-Accelerated 10Gbe support" | 2 | tristate "Alacritech SLIC Technology Non-Accelerated 10Gbe support" |
3 | depends on PCI && NETDEV_10000 | 3 | depends on PCI && NETDEV_10000 |
4 | depends on X86 | ||
4 | default n | 5 | default n |
5 | help | 6 | help |
6 | This driver supports the Alacritech SLIC Technology Non-Accelerated | 7 | This driver supports the Alacritech SLIC Technology Non-Accelerated |
diff --git a/drivers/telephony/phonedev.c b/drivers/telephony/phonedev.c index 4d74ba36c3a1..37caf4d69037 100644 --- a/drivers/telephony/phonedev.c +++ b/drivers/telephony/phonedev.c | |||
@@ -54,7 +54,6 @@ static int phone_open(struct inode *inode, struct file *file) | |||
54 | if (minor >= PHONE_NUM_DEVICES) | 54 | if (minor >= PHONE_NUM_DEVICES) |
55 | return -ENODEV; | 55 | return -ENODEV; |
56 | 56 | ||
57 | lock_kernel(); | ||
58 | mutex_lock(&phone_lock); | 57 | mutex_lock(&phone_lock); |
59 | p = phone_device[minor]; | 58 | p = phone_device[minor]; |
60 | if (p) | 59 | if (p) |
@@ -81,7 +80,6 @@ static int phone_open(struct inode *inode, struct file *file) | |||
81 | fops_put(old_fops); | 80 | fops_put(old_fops); |
82 | end: | 81 | end: |
83 | mutex_unlock(&phone_lock); | 82 | mutex_unlock(&phone_lock); |
84 | unlock_kernel(); | ||
85 | return err; | 83 | return err; |
86 | } | 84 | } |
87 | 85 | ||
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 5dccf057a7dd..f9b4647255aa 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c | |||
@@ -47,6 +47,9 @@ static struct uio_class { | |||
47 | struct class *class; | 47 | struct class *class; |
48 | } *uio_class; | 48 | } *uio_class; |
49 | 49 | ||
50 | /* Protect idr accesses */ | ||
51 | static DEFINE_MUTEX(minor_lock); | ||
52 | |||
50 | /* | 53 | /* |
51 | * attributes | 54 | * attributes |
52 | */ | 55 | */ |
@@ -239,7 +242,6 @@ static void uio_dev_del_attributes(struct uio_device *idev) | |||
239 | 242 | ||
240 | static int uio_get_minor(struct uio_device *idev) | 243 | static int uio_get_minor(struct uio_device *idev) |
241 | { | 244 | { |
242 | static DEFINE_MUTEX(minor_lock); | ||
243 | int retval = -ENOMEM; | 245 | int retval = -ENOMEM; |
244 | int id; | 246 | int id; |
245 | 247 | ||
@@ -261,7 +263,9 @@ exit: | |||
261 | 263 | ||
262 | static void uio_free_minor(struct uio_device *idev) | 264 | static void uio_free_minor(struct uio_device *idev) |
263 | { | 265 | { |
266 | mutex_lock(&minor_lock); | ||
264 | idr_remove(&uio_idr, idev->minor); | 267 | idr_remove(&uio_idr, idev->minor); |
268 | mutex_unlock(&minor_lock); | ||
265 | } | 269 | } |
266 | 270 | ||
267 | /** | 271 | /** |
@@ -305,8 +309,9 @@ static int uio_open(struct inode *inode, struct file *filep) | |||
305 | struct uio_listener *listener; | 309 | struct uio_listener *listener; |
306 | int ret = 0; | 310 | int ret = 0; |
307 | 311 | ||
308 | lock_kernel(); | 312 | mutex_lock(&minor_lock); |
309 | idev = idr_find(&uio_idr, iminor(inode)); | 313 | idev = idr_find(&uio_idr, iminor(inode)); |
314 | mutex_unlock(&minor_lock); | ||
310 | if (!idev) { | 315 | if (!idev) { |
311 | ret = -ENODEV; | 316 | ret = -ENODEV; |
312 | goto out; | 317 | goto out; |
@@ -332,18 +337,15 @@ static int uio_open(struct inode *inode, struct file *filep) | |||
332 | if (ret) | 337 | if (ret) |
333 | goto err_infoopen; | 338 | goto err_infoopen; |
334 | } | 339 | } |
335 | unlock_kernel(); | ||
336 | return 0; | 340 | return 0; |
337 | 341 | ||
338 | err_infoopen: | 342 | err_infoopen: |
339 | |||
340 | kfree(listener); | 343 | kfree(listener); |
341 | err_alloc_listener: | ||
342 | 344 | ||
345 | err_alloc_listener: | ||
343 | module_put(idev->owner); | 346 | module_put(idev->owner); |
344 | 347 | ||
345 | out: | 348 | out: |
346 | unlock_kernel(); | ||
347 | return ret; | 349 | return ret; |
348 | } | 350 | } |
349 | 351 | ||
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index d343afacb0b0..15a803b206b8 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -1111,8 +1111,8 @@ clean0: | |||
1111 | #ifdef DEBUG | 1111 | #ifdef DEBUG |
1112 | debugfs_remove(ehci_debug_root); | 1112 | debugfs_remove(ehci_debug_root); |
1113 | ehci_debug_root = NULL; | 1113 | ehci_debug_root = NULL; |
1114 | #endif | ||
1115 | err_debug: | 1114 | err_debug: |
1115 | #endif | ||
1116 | clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded); | 1116 | clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded); |
1117 | return retval; | 1117 | return retval; |
1118 | } | 1118 | } |
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c index 6fa0b9d5559a..d4cfed0b26d5 100644 --- a/drivers/video/backlight/hp680_bl.c +++ b/drivers/video/backlight/hp680_bl.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <linux/backlight.h> | 19 | #include <linux/backlight.h> |
20 | 20 | ||
21 | #include <cpu/dac.h> | 21 | #include <cpu/dac.h> |
22 | #include <asm/hp6xx.h> | 22 | #include <mach/hp6xx.h> |
23 | #include <asm/hd64461.h> | 23 | #include <asm/hd64461.h> |
24 | 24 | ||
25 | #define HP680_MAX_INTENSITY 255 | 25 | #define HP680_MAX_INTENSITY 255 |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 217c5118ae9e..cd5f20da738a 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -1002,101 +1002,132 @@ fb_blank(struct fb_info *info, int blank) | |||
1002 | return ret; | 1002 | return ret; |
1003 | } | 1003 | } |
1004 | 1004 | ||
1005 | static int | 1005 | static long |
1006 | fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 1006 | fb_ioctl(struct file *file, unsigned int cmd, |
1007 | unsigned long arg) | 1007 | unsigned long arg) |
1008 | { | 1008 | { |
1009 | struct inode *inode = file->f_path.dentry->d_inode; | ||
1009 | int fbidx = iminor(inode); | 1010 | int fbidx = iminor(inode); |
1010 | struct fb_info *info = registered_fb[fbidx]; | 1011 | struct fb_info *info; |
1011 | struct fb_ops *fb = info->fbops; | 1012 | struct fb_ops *fb; |
1012 | struct fb_var_screeninfo var; | 1013 | struct fb_var_screeninfo var; |
1013 | struct fb_fix_screeninfo fix; | 1014 | struct fb_fix_screeninfo fix; |
1014 | struct fb_con2fbmap con2fb; | 1015 | struct fb_con2fbmap con2fb; |
1015 | struct fb_cmap_user cmap; | 1016 | struct fb_cmap_user cmap; |
1016 | struct fb_event event; | 1017 | struct fb_event event; |
1017 | void __user *argp = (void __user *)arg; | 1018 | void __user *argp = (void __user *)arg; |
1018 | int i; | 1019 | long ret = 0; |
1019 | 1020 | ||
1020 | if (!fb) | 1021 | info = registered_fb[fbidx]; |
1022 | mutex_lock(&info->lock); | ||
1023 | fb = info->fbops; | ||
1024 | |||
1025 | if (!fb) { | ||
1026 | mutex_unlock(&info->lock); | ||
1021 | return -ENODEV; | 1027 | return -ENODEV; |
1028 | } | ||
1022 | switch (cmd) { | 1029 | switch (cmd) { |
1023 | case FBIOGET_VSCREENINFO: | 1030 | case FBIOGET_VSCREENINFO: |
1024 | return copy_to_user(argp, &info->var, | 1031 | ret = copy_to_user(argp, &info->var, |
1025 | sizeof(var)) ? -EFAULT : 0; | 1032 | sizeof(var)) ? -EFAULT : 0; |
1033 | break; | ||
1026 | case FBIOPUT_VSCREENINFO: | 1034 | case FBIOPUT_VSCREENINFO: |
1027 | if (copy_from_user(&var, argp, sizeof(var))) | 1035 | if (copy_from_user(&var, argp, sizeof(var))) { |
1028 | return -EFAULT; | 1036 | ret = -EFAULT; |
1037 | break; | ||
1038 | } | ||
1029 | acquire_console_sem(); | 1039 | acquire_console_sem(); |
1030 | info->flags |= FBINFO_MISC_USEREVENT; | 1040 | info->flags |= FBINFO_MISC_USEREVENT; |
1031 | i = fb_set_var(info, &var); | 1041 | ret = fb_set_var(info, &var); |
1032 | info->flags &= ~FBINFO_MISC_USEREVENT; | 1042 | info->flags &= ~FBINFO_MISC_USEREVENT; |
1033 | release_console_sem(); | 1043 | release_console_sem(); |
1034 | if (i) return i; | 1044 | if (ret == 0 && copy_to_user(argp, &var, sizeof(var))) |
1035 | if (copy_to_user(argp, &var, sizeof(var))) | 1045 | ret = -EFAULT; |
1036 | return -EFAULT; | 1046 | break; |
1037 | return 0; | ||
1038 | case FBIOGET_FSCREENINFO: | 1047 | case FBIOGET_FSCREENINFO: |
1039 | return copy_to_user(argp, &info->fix, | 1048 | ret = copy_to_user(argp, &info->fix, |
1040 | sizeof(fix)) ? -EFAULT : 0; | 1049 | sizeof(fix)) ? -EFAULT : 0; |
1050 | break; | ||
1041 | case FBIOPUTCMAP: | 1051 | case FBIOPUTCMAP: |
1042 | if (copy_from_user(&cmap, argp, sizeof(cmap))) | 1052 | if (copy_from_user(&cmap, argp, sizeof(cmap))) |
1043 | return -EFAULT; | 1053 | ret = -EFAULT; |
1044 | return (fb_set_user_cmap(&cmap, info)); | 1054 | else |
1055 | ret = fb_set_user_cmap(&cmap, info); | ||
1056 | break; | ||
1045 | case FBIOGETCMAP: | 1057 | case FBIOGETCMAP: |
1046 | if (copy_from_user(&cmap, argp, sizeof(cmap))) | 1058 | if (copy_from_user(&cmap, argp, sizeof(cmap))) |
1047 | return -EFAULT; | 1059 | ret = -EFAULT; |
1048 | return fb_cmap_to_user(&info->cmap, &cmap); | 1060 | else |
1061 | ret = fb_cmap_to_user(&info->cmap, &cmap); | ||
1062 | break; | ||
1049 | case FBIOPAN_DISPLAY: | 1063 | case FBIOPAN_DISPLAY: |
1050 | if (copy_from_user(&var, argp, sizeof(var))) | 1064 | if (copy_from_user(&var, argp, sizeof(var))) { |
1051 | return -EFAULT; | 1065 | ret = -EFAULT; |
1066 | break; | ||
1067 | } | ||
1052 | acquire_console_sem(); | 1068 | acquire_console_sem(); |
1053 | i = fb_pan_display(info, &var); | 1069 | ret = fb_pan_display(info, &var); |
1054 | release_console_sem(); | 1070 | release_console_sem(); |
1055 | if (i) | 1071 | if (ret == 0 && copy_to_user(argp, &var, sizeof(var))) |
1056 | return i; | 1072 | ret = -EFAULT; |
1057 | if (copy_to_user(argp, &var, sizeof(var))) | 1073 | break; |
1058 | return -EFAULT; | ||
1059 | return 0; | ||
1060 | case FBIO_CURSOR: | 1074 | case FBIO_CURSOR: |
1061 | return -EINVAL; | 1075 | ret = -EINVAL; |
1076 | break; | ||
1062 | case FBIOGET_CON2FBMAP: | 1077 | case FBIOGET_CON2FBMAP: |
1063 | if (copy_from_user(&con2fb, argp, sizeof(con2fb))) | 1078 | if (copy_from_user(&con2fb, argp, sizeof(con2fb))) |
1064 | return -EFAULT; | 1079 | ret = -EFAULT; |
1065 | if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) | 1080 | else if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) |
1066 | return -EINVAL; | 1081 | ret = -EINVAL; |
1067 | con2fb.framebuffer = -1; | 1082 | else { |
1068 | event.info = info; | 1083 | con2fb.framebuffer = -1; |
1069 | event.data = &con2fb; | 1084 | event.info = info; |
1070 | fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event); | 1085 | event.data = &con2fb; |
1071 | return copy_to_user(argp, &con2fb, | 1086 | fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, |
1087 | &event); | ||
1088 | ret = copy_to_user(argp, &con2fb, | ||
1072 | sizeof(con2fb)) ? -EFAULT : 0; | 1089 | sizeof(con2fb)) ? -EFAULT : 0; |
1090 | } | ||
1091 | break; | ||
1073 | case FBIOPUT_CON2FBMAP: | 1092 | case FBIOPUT_CON2FBMAP: |
1074 | if (copy_from_user(&con2fb, argp, sizeof(con2fb))) | 1093 | if (copy_from_user(&con2fb, argp, sizeof(con2fb))) { |
1075 | return - EFAULT; | 1094 | ret = -EFAULT; |
1076 | if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) | 1095 | break; |
1077 | return -EINVAL; | 1096 | } |
1078 | if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) | 1097 | if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) { |
1079 | return -EINVAL; | 1098 | ret = -EINVAL; |
1080 | if (!registered_fb[con2fb.framebuffer]) | 1099 | break; |
1081 | request_module("fb%d", con2fb.framebuffer); | 1100 | } |
1101 | if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) { | ||
1102 | ret = -EINVAL; | ||
1103 | break; | ||
1104 | } | ||
1082 | if (!registered_fb[con2fb.framebuffer]) | 1105 | if (!registered_fb[con2fb.framebuffer]) |
1083 | return -EINVAL; | 1106 | request_module("fb%d", con2fb.framebuffer); |
1107 | if (!registered_fb[con2fb.framebuffer]) { | ||
1108 | ret = -EINVAL; | ||
1109 | break; | ||
1110 | } | ||
1084 | event.info = info; | 1111 | event.info = info; |
1085 | event.data = &con2fb; | 1112 | event.data = &con2fb; |
1086 | return fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, | 1113 | ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, |
1087 | &event); | 1114 | &event); |
1115 | break; | ||
1088 | case FBIOBLANK: | 1116 | case FBIOBLANK: |
1089 | acquire_console_sem(); | 1117 | acquire_console_sem(); |
1090 | info->flags |= FBINFO_MISC_USEREVENT; | 1118 | info->flags |= FBINFO_MISC_USEREVENT; |
1091 | i = fb_blank(info, arg); | 1119 | ret = fb_blank(info, arg); |
1092 | info->flags &= ~FBINFO_MISC_USEREVENT; | 1120 | info->flags &= ~FBINFO_MISC_USEREVENT; |
1093 | release_console_sem(); | 1121 | release_console_sem(); |
1094 | return i; | 1122 | break;; |
1095 | default: | 1123 | default: |
1096 | if (fb->fb_ioctl == NULL) | 1124 | if (fb->fb_ioctl == NULL) |
1097 | return -EINVAL; | 1125 | ret = -ENOTTY; |
1098 | return fb->fb_ioctl(info, cmd, arg); | 1126 | else |
1127 | ret = fb->fb_ioctl(info, cmd, arg); | ||
1099 | } | 1128 | } |
1129 | mutex_unlock(&info->lock); | ||
1130 | return ret; | ||
1100 | } | 1131 | } |
1101 | 1132 | ||
1102 | #ifdef CONFIG_COMPAT | 1133 | #ifdef CONFIG_COMPAT |
@@ -1150,7 +1181,7 @@ static int fb_getput_cmap(struct inode *inode, struct file *file, | |||
1150 | put_user(compat_ptr(data), &cmap->transp)) | 1181 | put_user(compat_ptr(data), &cmap->transp)) |
1151 | return -EFAULT; | 1182 | return -EFAULT; |
1152 | 1183 | ||
1153 | err = fb_ioctl(inode, file, cmd, (unsigned long) cmap); | 1184 | err = fb_ioctl(file, cmd, (unsigned long) cmap); |
1154 | 1185 | ||
1155 | if (!err) { | 1186 | if (!err) { |
1156 | if (copy_in_user(&cmap32->start, | 1187 | if (copy_in_user(&cmap32->start, |
@@ -1204,7 +1235,7 @@ static int fb_get_fscreeninfo(struct inode *inode, struct file *file, | |||
1204 | 1235 | ||
1205 | old_fs = get_fs(); | 1236 | old_fs = get_fs(); |
1206 | set_fs(KERNEL_DS); | 1237 | set_fs(KERNEL_DS); |
1207 | err = fb_ioctl(inode, file, cmd, (unsigned long) &fix); | 1238 | err = fb_ioctl(file, cmd, (unsigned long) &fix); |
1208 | set_fs(old_fs); | 1239 | set_fs(old_fs); |
1209 | 1240 | ||
1210 | if (!err) | 1241 | if (!err) |
@@ -1222,7 +1253,7 @@ fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1222 | struct fb_ops *fb = info->fbops; | 1253 | struct fb_ops *fb = info->fbops; |
1223 | long ret = -ENOIOCTLCMD; | 1254 | long ret = -ENOIOCTLCMD; |
1224 | 1255 | ||
1225 | lock_kernel(); | 1256 | mutex_lock(&info->lock); |
1226 | switch(cmd) { | 1257 | switch(cmd) { |
1227 | case FBIOGET_VSCREENINFO: | 1258 | case FBIOGET_VSCREENINFO: |
1228 | case FBIOPUT_VSCREENINFO: | 1259 | case FBIOPUT_VSCREENINFO: |
@@ -1231,7 +1262,7 @@ fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1231 | case FBIOPUT_CON2FBMAP: | 1262 | case FBIOPUT_CON2FBMAP: |
1232 | arg = (unsigned long) compat_ptr(arg); | 1263 | arg = (unsigned long) compat_ptr(arg); |
1233 | case FBIOBLANK: | 1264 | case FBIOBLANK: |
1234 | ret = fb_ioctl(inode, file, cmd, arg); | 1265 | ret = fb_ioctl(file, cmd, arg); |
1235 | break; | 1266 | break; |
1236 | 1267 | ||
1237 | case FBIOGET_FSCREENINFO: | 1268 | case FBIOGET_FSCREENINFO: |
@@ -1248,7 +1279,7 @@ fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1248 | ret = fb->fb_compat_ioctl(info, cmd, arg); | 1279 | ret = fb->fb_compat_ioctl(info, cmd, arg); |
1249 | break; | 1280 | break; |
1250 | } | 1281 | } |
1251 | unlock_kernel(); | 1282 | mutex_unlock(&info->lock); |
1252 | return ret; | 1283 | return ret; |
1253 | } | 1284 | } |
1254 | #endif | 1285 | #endif |
@@ -1270,13 +1301,13 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) | |||
1270 | return -ENODEV; | 1301 | return -ENODEV; |
1271 | if (fb->fb_mmap) { | 1302 | if (fb->fb_mmap) { |
1272 | int res; | 1303 | int res; |
1273 | lock_kernel(); | 1304 | mutex_lock(&info->lock); |
1274 | res = fb->fb_mmap(info, vma); | 1305 | res = fb->fb_mmap(info, vma); |
1275 | unlock_kernel(); | 1306 | mutex_unlock(&info->lock); |
1276 | return res; | 1307 | return res; |
1277 | } | 1308 | } |
1278 | 1309 | ||
1279 | lock_kernel(); | 1310 | mutex_lock(&info->lock); |
1280 | 1311 | ||
1281 | /* frame buffer memory */ | 1312 | /* frame buffer memory */ |
1282 | start = info->fix.smem_start; | 1313 | start = info->fix.smem_start; |
@@ -1285,13 +1316,13 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) | |||
1285 | /* memory mapped io */ | 1316 | /* memory mapped io */ |
1286 | off -= len; | 1317 | off -= len; |
1287 | if (info->var.accel_flags) { | 1318 | if (info->var.accel_flags) { |
1288 | unlock_kernel(); | 1319 | mutex_unlock(&info->lock); |
1289 | return -EINVAL; | 1320 | return -EINVAL; |
1290 | } | 1321 | } |
1291 | start = info->fix.mmio_start; | 1322 | start = info->fix.mmio_start; |
1292 | len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); | 1323 | len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); |
1293 | } | 1324 | } |
1294 | unlock_kernel(); | 1325 | mutex_unlock(&info->lock); |
1295 | start &= PAGE_MASK; | 1326 | start &= PAGE_MASK; |
1296 | if ((vma->vm_end - vma->vm_start + off) > len) | 1327 | if ((vma->vm_end - vma->vm_start + off) > len) |
1297 | return -EINVAL; | 1328 | return -EINVAL; |
@@ -1315,13 +1346,13 @@ fb_open(struct inode *inode, struct file *file) | |||
1315 | 1346 | ||
1316 | if (fbidx >= FB_MAX) | 1347 | if (fbidx >= FB_MAX) |
1317 | return -ENODEV; | 1348 | return -ENODEV; |
1318 | lock_kernel(); | 1349 | info = registered_fb[fbidx]; |
1319 | if (!(info = registered_fb[fbidx])) | 1350 | if (!info) |
1320 | request_module("fb%d", fbidx); | 1351 | request_module("fb%d", fbidx); |
1321 | if (!(info = registered_fb[fbidx])) { | 1352 | info = registered_fb[fbidx]; |
1322 | res = -ENODEV; | 1353 | if (!info) |
1323 | goto out; | 1354 | return -ENODEV; |
1324 | } | 1355 | mutex_lock(&info->lock); |
1325 | if (!try_module_get(info->fbops->owner)) { | 1356 | if (!try_module_get(info->fbops->owner)) { |
1326 | res = -ENODEV; | 1357 | res = -ENODEV; |
1327 | goto out; | 1358 | goto out; |
@@ -1337,7 +1368,7 @@ fb_open(struct inode *inode, struct file *file) | |||
1337 | fb_deferred_io_open(info, inode, file); | 1368 | fb_deferred_io_open(info, inode, file); |
1338 | #endif | 1369 | #endif |
1339 | out: | 1370 | out: |
1340 | unlock_kernel(); | 1371 | mutex_unlock(&info->lock); |
1341 | return res; | 1372 | return res; |
1342 | } | 1373 | } |
1343 | 1374 | ||
@@ -1346,11 +1377,11 @@ fb_release(struct inode *inode, struct file *file) | |||
1346 | { | 1377 | { |
1347 | struct fb_info * const info = file->private_data; | 1378 | struct fb_info * const info = file->private_data; |
1348 | 1379 | ||
1349 | lock_kernel(); | 1380 | mutex_lock(&info->lock); |
1350 | if (info->fbops->fb_release) | 1381 | if (info->fbops->fb_release) |
1351 | info->fbops->fb_release(info,1); | 1382 | info->fbops->fb_release(info,1); |
1352 | module_put(info->fbops->owner); | 1383 | module_put(info->fbops->owner); |
1353 | unlock_kernel(); | 1384 | mutex_unlock(&info->lock); |
1354 | return 0; | 1385 | return 0; |
1355 | } | 1386 | } |
1356 | 1387 | ||
@@ -1358,7 +1389,7 @@ static const struct file_operations fb_fops = { | |||
1358 | .owner = THIS_MODULE, | 1389 | .owner = THIS_MODULE, |
1359 | .read = fb_read, | 1390 | .read = fb_read, |
1360 | .write = fb_write, | 1391 | .write = fb_write, |
1361 | .ioctl = fb_ioctl, | 1392 | .unlocked_ioctl = fb_ioctl, |
1362 | #ifdef CONFIG_COMPAT | 1393 | #ifdef CONFIG_COMPAT |
1363 | .compat_ioctl = fb_compat_ioctl, | 1394 | .compat_ioctl = fb_compat_ioctl, |
1364 | #endif | 1395 | #endif |
@@ -1429,6 +1460,7 @@ register_framebuffer(struct fb_info *fb_info) | |||
1429 | if (!registered_fb[i]) | 1460 | if (!registered_fb[i]) |
1430 | break; | 1461 | break; |
1431 | fb_info->node = i; | 1462 | fb_info->node = i; |
1463 | mutex_init(&fb_info->lock); | ||
1432 | 1464 | ||
1433 | fb_info->dev = device_create(fb_class, fb_info->device, | 1465 | fb_info->dev = device_create(fb_class, fb_info->device, |
1434 | MKDEV(FB_MAJOR, i), NULL, "fb%d", i); | 1466 | MKDEV(FB_MAJOR, i), NULL, "fb%d", i); |
diff --git a/drivers/video/imacfb.c b/drivers/video/imacfb.c deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/drivers/video/imacfb.c +++ /dev/null | |||
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index 4c32c06579a0..efff672fd7b8 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/dma-mapping.h> | 18 | #include <linux/dma-mapping.h> |
19 | #include <asm/sh_mobile_lcdc.h> | 19 | #include <video/sh_mobile_lcdc.h> |
20 | 20 | ||
21 | #define PALETTE_NR 16 | 21 | #define PALETTE_NR 16 |
22 | 22 | ||
@@ -34,7 +34,9 @@ struct sh_mobile_lcdc_chan { | |||
34 | 34 | ||
35 | struct sh_mobile_lcdc_priv { | 35 | struct sh_mobile_lcdc_priv { |
36 | void __iomem *base; | 36 | void __iomem *base; |
37 | #ifdef CONFIG_HAVE_CLK | ||
37 | struct clk *clk; | 38 | struct clk *clk; |
39 | #endif | ||
38 | unsigned long lddckr; | 40 | unsigned long lddckr; |
39 | struct sh_mobile_lcdc_chan ch[2]; | 41 | struct sh_mobile_lcdc_chan ch[2]; |
40 | }; | 42 | }; |
@@ -260,6 +262,11 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) | |||
260 | tmp = ch->ldmt1r_value; | 262 | tmp = ch->ldmt1r_value; |
261 | tmp |= (lcd_cfg->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1 << 28; | 263 | tmp |= (lcd_cfg->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1 << 28; |
262 | tmp |= (lcd_cfg->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1 << 27; | 264 | tmp |= (lcd_cfg->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1 << 27; |
265 | tmp |= (ch->cfg.flags & LCDC_FLAGS_DWPOL) ? 1 << 26 : 0; | ||
266 | tmp |= (ch->cfg.flags & LCDC_FLAGS_DIPOL) ? 1 << 25 : 0; | ||
267 | tmp |= (ch->cfg.flags & LCDC_FLAGS_DAPOL) ? 1 << 24 : 0; | ||
268 | tmp |= (ch->cfg.flags & LCDC_FLAGS_HSCNT) ? 1 << 17 : 0; | ||
269 | tmp |= (ch->cfg.flags & LCDC_FLAGS_DWCNT) ? 1 << 16 : 0; | ||
263 | lcdc_write_chan(ch, LDMT1R, tmp); | 270 | lcdc_write_chan(ch, LDMT1R, tmp); |
264 | 271 | ||
265 | /* setup SYS bus */ | 272 | /* setup SYS bus */ |
@@ -422,6 +429,7 @@ static int sh_mobile_lcdc_setup_clocks(struct device *dev, int clock_source, | |||
422 | 429 | ||
423 | priv->lddckr = icksel << 16; | 430 | priv->lddckr = icksel << 16; |
424 | 431 | ||
432 | #ifdef CONFIG_HAVE_CLK | ||
425 | if (str) { | 433 | if (str) { |
426 | priv->clk = clk_get(dev, str); | 434 | priv->clk = clk_get(dev, str); |
427 | if (IS_ERR(priv->clk)) { | 435 | if (IS_ERR(priv->clk)) { |
@@ -431,6 +439,7 @@ static int sh_mobile_lcdc_setup_clocks(struct device *dev, int clock_source, | |||
431 | 439 | ||
432 | clk_enable(priv->clk); | 440 | clk_enable(priv->clk); |
433 | } | 441 | } |
442 | #endif | ||
434 | 443 | ||
435 | return 0; | 444 | return 0; |
436 | } | 445 | } |
@@ -585,7 +594,6 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
585 | goto err1; | 594 | goto err1; |
586 | } | 595 | } |
587 | 596 | ||
588 | priv->lddckr = pdata->lddckr; | ||
589 | priv->base = ioremap_nocache(res->start, (res->end - res->start) + 1); | 597 | priv->base = ioremap_nocache(res->start, (res->end - res->start) + 1); |
590 | 598 | ||
591 | for (i = 0; i < j; i++) { | 599 | for (i = 0; i < j; i++) { |
@@ -688,10 +696,12 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev) | |||
688 | fb_dealloc_cmap(&info->cmap); | 696 | fb_dealloc_cmap(&info->cmap); |
689 | } | 697 | } |
690 | 698 | ||
699 | #ifdef CONFIG_HAVE_CLK | ||
691 | if (priv->clk) { | 700 | if (priv->clk) { |
692 | clk_disable(priv->clk); | 701 | clk_disable(priv->clk); |
693 | clk_put(priv->clk); | 702 | clk_put(priv->clk); |
694 | } | 703 | } |
704 | #endif | ||
695 | 705 | ||
696 | if (priv->base) | 706 | if (priv->base) |
697 | iounmap(priv->base); | 707 | iounmap(priv->base); |
diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c index ed6b0576208c..1f09d4e4144c 100644 --- a/drivers/w1/slaves/w1_ds2760.c +++ b/drivers/w1/slaves/w1_ds2760.c | |||
@@ -80,7 +80,6 @@ static struct bin_attribute w1_ds2760_bin_attr = { | |||
80 | .attr = { | 80 | .attr = { |
81 | .name = "w1_slave", | 81 | .name = "w1_slave", |
82 | .mode = S_IRUGO, | 82 | .mode = S_IRUGO, |
83 | .owner = THIS_MODULE, | ||
84 | }, | 83 | }, |
85 | .size = DS2760_DATA_SIZE, | 84 | .size = DS2760_DATA_SIZE, |
86 | .read = w1_ds2760_read_bin, | 85 | .read = w1_ds2760_read_bin, |
diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c index 05a28106e8eb..8782ec1f5aa0 100644 --- a/drivers/watchdog/ib700wdt.c +++ b/drivers/watchdog/ib700wdt.c | |||
@@ -154,7 +154,7 @@ static int ibwdt_set_heartbeat(int t) | |||
154 | return -EINVAL; | 154 | return -EINVAL; |
155 | 155 | ||
156 | for (i = 0x0F; i > -1; i--) | 156 | for (i = 0x0F; i > -1; i--) |
157 | if (wd_times[i] > t) | 157 | if (wd_times[i] >= t) |
158 | break; | 158 | break; |
159 | wd_margin = i; | 159 | wd_margin = i; |
160 | return 0; | 160 | return 0; |
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index c3290bc186a0..9ce1ab6c268d 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -125,7 +125,7 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) | |||
125 | 125 | ||
126 | BUG_ON(irq == -1); | 126 | BUG_ON(irq == -1); |
127 | #ifdef CONFIG_SMP | 127 | #ifdef CONFIG_SMP |
128 | irq_desc[irq].affinity = cpumask_of_cpu(cpu); | 128 | irq_to_desc(irq)->affinity = cpumask_of_cpu(cpu); |
129 | #endif | 129 | #endif |
130 | 130 | ||
131 | __clear_bit(chn, cpu_evtchn_mask[cpu_evtchn[chn]]); | 131 | __clear_bit(chn, cpu_evtchn_mask[cpu_evtchn[chn]]); |
@@ -137,10 +137,12 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) | |||
137 | static void init_evtchn_cpu_bindings(void) | 137 | static void init_evtchn_cpu_bindings(void) |
138 | { | 138 | { |
139 | #ifdef CONFIG_SMP | 139 | #ifdef CONFIG_SMP |
140 | struct irq_desc *desc; | ||
140 | int i; | 141 | int i; |
142 | |||
141 | /* By default all event channels notify CPU#0. */ | 143 | /* By default all event channels notify CPU#0. */ |
142 | for (i = 0; i < NR_IRQS; i++) | 144 | for_each_irq_desc(i, desc) |
143 | irq_desc[i].affinity = cpumask_of_cpu(0); | 145 | desc->affinity = cpumask_of_cpu(0); |
144 | #endif | 146 | #endif |
145 | 147 | ||
146 | memset(cpu_evtchn, 0, sizeof(cpu_evtchn)); | 148 | memset(cpu_evtchn, 0, sizeof(cpu_evtchn)); |
@@ -229,12 +231,12 @@ static int find_unbound_irq(void) | |||
229 | int irq; | 231 | int irq; |
230 | 232 | ||
231 | /* Only allocate from dynirq range */ | 233 | /* Only allocate from dynirq range */ |
232 | for (irq = 0; irq < NR_IRQS; irq++) | 234 | for_each_irq_nr(irq) |
233 | if (irq_bindcount[irq] == 0) | 235 | if (irq_bindcount[irq] == 0) |
234 | break; | 236 | break; |
235 | 237 | ||
236 | if (irq == NR_IRQS) | 238 | if (irq == nr_irqs) |
237 | panic("No available IRQ to bind to: increase NR_IRQS!\n"); | 239 | panic("No available IRQ to bind to: increase nr_irqs!\n"); |
238 | 240 | ||
239 | return irq; | 241 | return irq; |
240 | } | 242 | } |
@@ -790,7 +792,7 @@ void xen_irq_resume(void) | |||
790 | mask_evtchn(evtchn); | 792 | mask_evtchn(evtchn); |
791 | 793 | ||
792 | /* No IRQ <-> event-channel mappings. */ | 794 | /* No IRQ <-> event-channel mappings. */ |
793 | for (irq = 0; irq < NR_IRQS; irq++) | 795 | for_each_irq_nr(irq) |
794 | irq_info[irq].evtchn = 0; /* zap event-channel binding */ | 796 | irq_info[irq].evtchn = 0; /* zap event-channel binding */ |
795 | 797 | ||
796 | for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++) | 798 | for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++) |
@@ -822,7 +824,7 @@ void __init xen_init_IRQ(void) | |||
822 | mask_evtchn(i); | 824 | mask_evtchn(i); |
823 | 825 | ||
824 | /* Dynamic IRQ space is currently unbound. Zero the refcnts. */ | 826 | /* Dynamic IRQ space is currently unbound. Zero the refcnts. */ |
825 | for (i = 0; i < NR_IRQS; i++) | 827 | for_each_irq_nr(i) |
826 | irq_bindcount[i] = 0; | 828 | irq_bindcount[i] = 0; |
827 | 829 | ||
828 | irq_ctx_init(smp_processor_id()); | 830 | irq_ctx_init(smp_processor_id()); |