diff options
Diffstat (limited to 'drivers/char')
92 files changed, 2293 insertions, 1790 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 3d44ec724c17..43d3395325c5 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -493,6 +493,21 @@ config LEGACY_PTY_COUNT | |||
493 | When not in use, each legacy PTY occupies 12 bytes on 32-bit | 493 | When not in use, each legacy PTY occupies 12 bytes on 32-bit |
494 | architectures and 24 bytes on 64-bit architectures. | 494 | architectures and 24 bytes on 64-bit architectures. |
495 | 495 | ||
496 | config TTY_PRINTK | ||
497 | bool "TTY driver to output user messages via printk" | ||
498 | depends on EMBEDDED | ||
499 | default n | ||
500 | ---help--- | ||
501 | If you say Y here, the support for writing user messages (i.e. | ||
502 | console messages) via printk is available. | ||
503 | |||
504 | The feature is useful to inline user messages with kernel | ||
505 | messages. | ||
506 | In order to use this feature, you should output user messages | ||
507 | to /dev/ttyprintk or redirect console to this TTY. | ||
508 | |||
509 | If unsure, say N. | ||
510 | |||
496 | config BRIQ_PANEL | 511 | config BRIQ_PANEL |
497 | tristate 'Total Impact briQ front panel driver' | 512 | tristate 'Total Impact briQ front panel driver' |
498 | depends on PPC_CHRP | 513 | depends on PPC_CHRP |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index dc9641660605..3a9c01416839 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -12,6 +12,7 @@ obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o tty_buffer.o t | |||
12 | obj-y += tty_mutex.o | 12 | obj-y += tty_mutex.o |
13 | obj-$(CONFIG_LEGACY_PTYS) += pty.o | 13 | obj-$(CONFIG_LEGACY_PTYS) += pty.o |
14 | obj-$(CONFIG_UNIX98_PTYS) += pty.o | 14 | obj-$(CONFIG_UNIX98_PTYS) += pty.o |
15 | obj-$(CONFIG_TTY_PRINTK) += ttyprintk.o | ||
15 | obj-y += misc.o | 16 | obj-y += misc.o |
16 | obj-$(CONFIG_VT) += vt_ioctl.o vc_screen.o selection.o keyboard.o | 17 | obj-$(CONFIG_VT) += vt_ioctl.o vc_screen.o selection.o keyboard.o |
17 | obj-$(CONFIG_BFIN_JTAG_COMM) += bfin_jtag_comm.o | 18 | obj-$(CONFIG_BFIN_JTAG_COMM) += bfin_jtag_comm.o |
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig index 5ddf67e76f8b..fcd867d923ba 100644 --- a/drivers/char/agp/Kconfig +++ b/drivers/char/agp/Kconfig | |||
@@ -34,7 +34,7 @@ config AGP_ALI | |||
34 | X on the following ALi chipsets. The supported chipsets | 34 | X on the following ALi chipsets. The supported chipsets |
35 | include M1541, M1621, M1631, M1632, M1641,M1647,and M1651. | 35 | include M1541, M1621, M1631, M1632, M1641,M1647,and M1651. |
36 | For the ALi-chipset question, ALi suggests you refer to | 36 | For the ALi-chipset question, ALi suggests you refer to |
37 | <http://www.ali.com.tw/eng/support/index.shtml>. | 37 | <http://www.ali.com.tw/>. |
38 | 38 | ||
39 | The M1541 chipset can do AGP 1x and 2x, but note that there is an | 39 | The M1541 chipset can do AGP 1x and 2x, but note that there is an |
40 | acknowledged incompatibility with Matrox G200 cards. Due to | 40 | acknowledged incompatibility with Matrox G200 cards. Due to |
diff --git a/drivers/char/agp/Makefile b/drivers/char/agp/Makefile index 627f542827c7..8eb56e273e75 100644 --- a/drivers/char/agp/Makefile +++ b/drivers/char/agp/Makefile | |||
@@ -13,6 +13,7 @@ obj-$(CONFIG_AGP_HP_ZX1) += hp-agp.o | |||
13 | obj-$(CONFIG_AGP_PARISC) += parisc-agp.o | 13 | obj-$(CONFIG_AGP_PARISC) += parisc-agp.o |
14 | obj-$(CONFIG_AGP_I460) += i460-agp.o | 14 | obj-$(CONFIG_AGP_I460) += i460-agp.o |
15 | obj-$(CONFIG_AGP_INTEL) += intel-agp.o | 15 | obj-$(CONFIG_AGP_INTEL) += intel-agp.o |
16 | obj-$(CONFIG_AGP_INTEL) += intel-gtt.o | ||
16 | obj-$(CONFIG_AGP_NVIDIA) += nvidia-agp.o | 17 | obj-$(CONFIG_AGP_NVIDIA) += nvidia-agp.o |
17 | obj-$(CONFIG_AGP_SGI_TIOCA) += sgi-agp.o | 18 | obj-$(CONFIG_AGP_SGI_TIOCA) += sgi-agp.o |
18 | obj-$(CONFIG_AGP_SIS) += sis-agp.o | 19 | obj-$(CONFIG_AGP_SIS) += sis-agp.o |
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index 120490949997..5259065f3c79 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h | |||
@@ -121,11 +121,6 @@ struct agp_bridge_driver { | |||
121 | void (*agp_destroy_pages)(struct agp_memory *); | 121 | void (*agp_destroy_pages)(struct agp_memory *); |
122 | int (*agp_type_to_mask_type) (struct agp_bridge_data *, int); | 122 | int (*agp_type_to_mask_type) (struct agp_bridge_data *, int); |
123 | void (*chipset_flush)(struct agp_bridge_data *); | 123 | void (*chipset_flush)(struct agp_bridge_data *); |
124 | |||
125 | int (*agp_map_page)(struct page *page, dma_addr_t *ret); | ||
126 | void (*agp_unmap_page)(struct page *page, dma_addr_t dma); | ||
127 | int (*agp_map_memory)(struct agp_memory *mem); | ||
128 | void (*agp_unmap_memory)(struct agp_memory *mem); | ||
129 | }; | 124 | }; |
130 | 125 | ||
131 | struct agp_bridge_data { | 126 | struct agp_bridge_data { |
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index b6b1568314c8..b1b4362bc648 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c | |||
@@ -309,7 +309,8 @@ static int amd_insert_memory(struct agp_memory *mem, off_t pg_start, int type) | |||
309 | 309 | ||
310 | num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries; | 310 | num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries; |
311 | 311 | ||
312 | if (type != 0 || mem->type != 0) | 312 | if (type != mem->type || |
313 | agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type)) | ||
313 | return -EINVAL; | 314 | return -EINVAL; |
314 | 315 | ||
315 | if ((pg_start + mem->page_count) > num_entries) | 316 | if ((pg_start + mem->page_count) > num_entries) |
@@ -348,7 +349,8 @@ static int amd_remove_memory(struct agp_memory *mem, off_t pg_start, int type) | |||
348 | unsigned long __iomem *cur_gatt; | 349 | unsigned long __iomem *cur_gatt; |
349 | unsigned long addr; | 350 | unsigned long addr; |
350 | 351 | ||
351 | if (type != 0 || mem->type != 0) | 352 | if (type != mem->type || |
353 | agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type)) | ||
352 | return -EINVAL; | 354 | return -EINVAL; |
353 | 355 | ||
354 | for (i = pg_start; i < (mem->page_count + pg_start); i++) { | 356 | for (i = pg_start; i < (mem->page_count + pg_start); i++) { |
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index ee4f855611b6..f27d0d0816d3 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c | |||
@@ -151,17 +151,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) | |||
151 | } | 151 | } |
152 | 152 | ||
153 | bridge->scratch_page_page = page; | 153 | bridge->scratch_page_page = page; |
154 | if (bridge->driver->agp_map_page) { | 154 | bridge->scratch_page_dma = page_to_phys(page); |
155 | if (bridge->driver->agp_map_page(page, | ||
156 | &bridge->scratch_page_dma)) { | ||
157 | dev_err(&bridge->dev->dev, | ||
158 | "unable to dma-map scratch page\n"); | ||
159 | rc = -ENOMEM; | ||
160 | goto err_out_nounmap; | ||
161 | } | ||
162 | } else { | ||
163 | bridge->scratch_page_dma = page_to_phys(page); | ||
164 | } | ||
165 | 155 | ||
166 | bridge->scratch_page = bridge->driver->mask_memory(bridge, | 156 | bridge->scratch_page = bridge->driver->mask_memory(bridge, |
167 | bridge->scratch_page_dma, 0); | 157 | bridge->scratch_page_dma, 0); |
@@ -204,12 +194,6 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) | |||
204 | return 0; | 194 | return 0; |
205 | 195 | ||
206 | err_out: | 196 | err_out: |
207 | if (bridge->driver->needs_scratch_page && | ||
208 | bridge->driver->agp_unmap_page) { | ||
209 | bridge->driver->agp_unmap_page(bridge->scratch_page_page, | ||
210 | bridge->scratch_page_dma); | ||
211 | } | ||
212 | err_out_nounmap: | ||
213 | if (bridge->driver->needs_scratch_page) { | 197 | if (bridge->driver->needs_scratch_page) { |
214 | void *va = page_address(bridge->scratch_page_page); | 198 | void *va = page_address(bridge->scratch_page_page); |
215 | 199 | ||
@@ -240,10 +224,6 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge) | |||
240 | bridge->driver->needs_scratch_page) { | 224 | bridge->driver->needs_scratch_page) { |
241 | void *va = page_address(bridge->scratch_page_page); | 225 | void *va = page_address(bridge->scratch_page_page); |
242 | 226 | ||
243 | if (bridge->driver->agp_unmap_page) | ||
244 | bridge->driver->agp_unmap_page(bridge->scratch_page_page, | ||
245 | bridge->scratch_page_dma); | ||
246 | |||
247 | bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP); | 227 | bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP); |
248 | bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE); | 228 | bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE); |
249 | } | 229 | } |
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index 64255cef8a7d..4956f1c8f9d5 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c | |||
@@ -437,11 +437,6 @@ int agp_bind_memory(struct agp_memory *curr, off_t pg_start) | |||
437 | curr->is_flushed = true; | 437 | curr->is_flushed = true; |
438 | } | 438 | } |
439 | 439 | ||
440 | if (curr->bridge->driver->agp_map_memory) { | ||
441 | ret_val = curr->bridge->driver->agp_map_memory(curr); | ||
442 | if (ret_val) | ||
443 | return ret_val; | ||
444 | } | ||
445 | ret_val = curr->bridge->driver->insert_memory(curr, pg_start, curr->type); | 440 | ret_val = curr->bridge->driver->insert_memory(curr, pg_start, curr->type); |
446 | 441 | ||
447 | if (ret_val != 0) | 442 | if (ret_val != 0) |
@@ -483,9 +478,6 @@ int agp_unbind_memory(struct agp_memory *curr) | |||
483 | if (ret_val != 0) | 478 | if (ret_val != 0) |
484 | return ret_val; | 479 | return ret_val; |
485 | 480 | ||
486 | if (curr->bridge->driver->agp_unmap_memory) | ||
487 | curr->bridge->driver->agp_unmap_memory(curr); | ||
488 | |||
489 | curr->is_bound = false; | 481 | curr->is_bound = false; |
490 | curr->pg_start = 0; | 482 | curr->pg_start = 0; |
491 | spin_lock(&curr->bridge->mapped_lock); | 483 | spin_lock(&curr->bridge->mapped_lock); |
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c index e763d3312ce7..75b763cb3ea1 100644 --- a/drivers/char/agp/i460-agp.c +++ b/drivers/char/agp/i460-agp.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * For documentation on the i460 AGP interface, see Chapter 7 (AGP Subsystem) of | 2 | * For documentation on the i460 AGP interface, see Chapter 7 (AGP Subsystem) of |
3 | * the "Intel 460GTX Chipset Software Developer's Manual": | 3 | * the "Intel 460GTX Chipset Software Developer's Manual": |
4 | * http://developer.intel.com/design/itanium/downloads/24870401s.htm | 4 | * http://www.intel.com/design/archives/itanium/downloads/248704.htm |
5 | */ | 5 | */ |
6 | /* | 6 | /* |
7 | * 460GX support by Chris Ahna <christopher.j.ahna@intel.com> | 7 | * 460GX support by Chris Ahna <christopher.j.ahna@intel.com> |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index cd18493c9527..e72f49d52202 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -12,9 +12,6 @@ | |||
12 | #include <asm/smp.h> | 12 | #include <asm/smp.h> |
13 | #include "agp.h" | 13 | #include "agp.h" |
14 | #include "intel-agp.h" | 14 | #include "intel-agp.h" |
15 | #include <linux/intel-gtt.h> | ||
16 | |||
17 | #include "intel-gtt.c" | ||
18 | 15 | ||
19 | int intel_agp_enabled; | 16 | int intel_agp_enabled; |
20 | EXPORT_SYMBOL(intel_agp_enabled); | 17 | EXPORT_SYMBOL(intel_agp_enabled); |
@@ -703,179 +700,37 @@ static const struct agp_bridge_driver intel_7505_driver = { | |||
703 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 700 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
704 | }; | 701 | }; |
705 | 702 | ||
706 | static int find_gmch(u16 device) | ||
707 | { | ||
708 | struct pci_dev *gmch_device; | ||
709 | |||
710 | gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL); | ||
711 | if (gmch_device && PCI_FUNC(gmch_device->devfn) != 0) { | ||
712 | gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL, | ||
713 | device, gmch_device); | ||
714 | } | ||
715 | |||
716 | if (!gmch_device) | ||
717 | return 0; | ||
718 | |||
719 | intel_private.pcidev = gmch_device; | ||
720 | return 1; | ||
721 | } | ||
722 | |||
723 | /* Table to describe Intel GMCH and AGP/PCIE GART drivers. At least one of | 703 | /* Table to describe Intel GMCH and AGP/PCIE GART drivers. At least one of |
724 | * driver and gmch_driver must be non-null, and find_gmch will determine | 704 | * driver and gmch_driver must be non-null, and find_gmch will determine |
725 | * which one should be used if a gmch_chip_id is present. | 705 | * which one should be used if a gmch_chip_id is present. |
726 | */ | 706 | */ |
727 | static const struct intel_driver_description { | 707 | static const struct intel_agp_driver_description { |
728 | unsigned int chip_id; | 708 | unsigned int chip_id; |
729 | unsigned int gmch_chip_id; | ||
730 | char *name; | 709 | char *name; |
731 | const struct agp_bridge_driver *driver; | 710 | const struct agp_bridge_driver *driver; |
732 | const struct agp_bridge_driver *gmch_driver; | ||
733 | } intel_agp_chipsets[] = { | 711 | } intel_agp_chipsets[] = { |
734 | { PCI_DEVICE_ID_INTEL_82443LX_0, 0, "440LX", &intel_generic_driver, NULL }, | 712 | { PCI_DEVICE_ID_INTEL_82443LX_0, "440LX", &intel_generic_driver }, |
735 | { PCI_DEVICE_ID_INTEL_82443BX_0, 0, "440BX", &intel_generic_driver, NULL }, | 713 | { PCI_DEVICE_ID_INTEL_82443BX_0, "440BX", &intel_generic_driver }, |
736 | { PCI_DEVICE_ID_INTEL_82443GX_0, 0, "440GX", &intel_generic_driver, NULL }, | 714 | { PCI_DEVICE_ID_INTEL_82443GX_0, "440GX", &intel_generic_driver }, |
737 | { PCI_DEVICE_ID_INTEL_82810_MC1, PCI_DEVICE_ID_INTEL_82810_IG1, "i810", | 715 | { PCI_DEVICE_ID_INTEL_82815_MC, "i815", &intel_815_driver }, |
738 | NULL, &intel_810_driver }, | 716 | { PCI_DEVICE_ID_INTEL_82820_HB, "i820", &intel_820_driver }, |
739 | { PCI_DEVICE_ID_INTEL_82810_MC3, PCI_DEVICE_ID_INTEL_82810_IG3, "i810", | 717 | { PCI_DEVICE_ID_INTEL_82820_UP_HB, "i820", &intel_820_driver }, |
740 | NULL, &intel_810_driver }, | 718 | { PCI_DEVICE_ID_INTEL_82830_HB, "830M", &intel_830mp_driver }, |
741 | { PCI_DEVICE_ID_INTEL_82810E_MC, PCI_DEVICE_ID_INTEL_82810E_IG, "i810", | 719 | { PCI_DEVICE_ID_INTEL_82840_HB, "i840", &intel_840_driver }, |
742 | NULL, &intel_810_driver }, | 720 | { PCI_DEVICE_ID_INTEL_82845_HB, "845G", &intel_845_driver }, |
743 | { PCI_DEVICE_ID_INTEL_82815_MC, PCI_DEVICE_ID_INTEL_82815_CGC, "i815", | 721 | { PCI_DEVICE_ID_INTEL_82845G_HB, "830M", &intel_845_driver }, |
744 | &intel_815_driver, &intel_810_driver }, | 722 | { PCI_DEVICE_ID_INTEL_82850_HB, "i850", &intel_850_driver }, |
745 | { PCI_DEVICE_ID_INTEL_82820_HB, 0, "i820", &intel_820_driver, NULL }, | 723 | { PCI_DEVICE_ID_INTEL_82854_HB, "854", &intel_845_driver }, |
746 | { PCI_DEVICE_ID_INTEL_82820_UP_HB, 0, "i820", &intel_820_driver, NULL }, | 724 | { PCI_DEVICE_ID_INTEL_82855PM_HB, "855PM", &intel_845_driver }, |
747 | { PCI_DEVICE_ID_INTEL_82830_HB, PCI_DEVICE_ID_INTEL_82830_CGC, "830M", | 725 | { PCI_DEVICE_ID_INTEL_82855GM_HB, "855GM", &intel_845_driver }, |
748 | &intel_830mp_driver, &intel_830_driver }, | 726 | { PCI_DEVICE_ID_INTEL_82860_HB, "i860", &intel_860_driver }, |
749 | { PCI_DEVICE_ID_INTEL_82840_HB, 0, "i840", &intel_840_driver, NULL }, | 727 | { PCI_DEVICE_ID_INTEL_82865_HB, "865", &intel_845_driver }, |
750 | { PCI_DEVICE_ID_INTEL_82845_HB, 0, "845G", &intel_845_driver, NULL }, | 728 | { PCI_DEVICE_ID_INTEL_82875_HB, "i875", &intel_845_driver }, |
751 | { PCI_DEVICE_ID_INTEL_82845G_HB, PCI_DEVICE_ID_INTEL_82845G_IG, "830M", | 729 | { PCI_DEVICE_ID_INTEL_7505_0, "E7505", &intel_7505_driver }, |
752 | &intel_845_driver, &intel_830_driver }, | 730 | { PCI_DEVICE_ID_INTEL_7205_0, "E7205", &intel_7505_driver }, |
753 | { PCI_DEVICE_ID_INTEL_82850_HB, 0, "i850", &intel_850_driver, NULL }, | 731 | { 0, NULL, NULL } |
754 | { PCI_DEVICE_ID_INTEL_82854_HB, PCI_DEVICE_ID_INTEL_82854_IG, "854", | ||
755 | &intel_845_driver, &intel_830_driver }, | ||
756 | { PCI_DEVICE_ID_INTEL_82855PM_HB, 0, "855PM", &intel_845_driver, NULL }, | ||
757 | { PCI_DEVICE_ID_INTEL_82855GM_HB, PCI_DEVICE_ID_INTEL_82855GM_IG, "855GM", | ||
758 | &intel_845_driver, &intel_830_driver }, | ||
759 | { PCI_DEVICE_ID_INTEL_82860_HB, 0, "i860", &intel_860_driver, NULL }, | ||
760 | { PCI_DEVICE_ID_INTEL_82865_HB, PCI_DEVICE_ID_INTEL_82865_IG, "865", | ||
761 | &intel_845_driver, &intel_830_driver }, | ||
762 | { PCI_DEVICE_ID_INTEL_82875_HB, 0, "i875", &intel_845_driver, NULL }, | ||
763 | { PCI_DEVICE_ID_INTEL_E7221_HB, PCI_DEVICE_ID_INTEL_E7221_IG, "E7221 (i915)", | ||
764 | NULL, &intel_915_driver }, | ||
765 | { PCI_DEVICE_ID_INTEL_82915G_HB, PCI_DEVICE_ID_INTEL_82915G_IG, "915G", | ||
766 | NULL, &intel_915_driver }, | ||
767 | { PCI_DEVICE_ID_INTEL_82915GM_HB, PCI_DEVICE_ID_INTEL_82915GM_IG, "915GM", | ||
768 | NULL, &intel_915_driver }, | ||
769 | { PCI_DEVICE_ID_INTEL_82945G_HB, PCI_DEVICE_ID_INTEL_82945G_IG, "945G", | ||
770 | NULL, &intel_915_driver }, | ||
771 | { PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GM_IG, "945GM", | ||
772 | NULL, &intel_915_driver }, | ||
773 | { PCI_DEVICE_ID_INTEL_82945GME_HB, PCI_DEVICE_ID_INTEL_82945GME_IG, "945GME", | ||
774 | NULL, &intel_915_driver }, | ||
775 | { PCI_DEVICE_ID_INTEL_82946GZ_HB, PCI_DEVICE_ID_INTEL_82946GZ_IG, "946GZ", | ||
776 | NULL, &intel_i965_driver }, | ||
777 | { PCI_DEVICE_ID_INTEL_82G35_HB, PCI_DEVICE_ID_INTEL_82G35_IG, "G35", | ||
778 | NULL, &intel_i965_driver }, | ||
779 | { PCI_DEVICE_ID_INTEL_82965Q_HB, PCI_DEVICE_ID_INTEL_82965Q_IG, "965Q", | ||
780 | NULL, &intel_i965_driver }, | ||
781 | { PCI_DEVICE_ID_INTEL_82965G_HB, PCI_DEVICE_ID_INTEL_82965G_IG, "965G", | ||
782 | NULL, &intel_i965_driver }, | ||
783 | { PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GM_IG, "965GM", | ||
784 | NULL, &intel_i965_driver }, | ||
785 | { PCI_DEVICE_ID_INTEL_82965GME_HB, PCI_DEVICE_ID_INTEL_82965GME_IG, "965GME/GLE", | ||
786 | NULL, &intel_i965_driver }, | ||
787 | { PCI_DEVICE_ID_INTEL_7505_0, 0, "E7505", &intel_7505_driver, NULL }, | ||
788 | { PCI_DEVICE_ID_INTEL_7205_0, 0, "E7205", &intel_7505_driver, NULL }, | ||
789 | { PCI_DEVICE_ID_INTEL_G33_HB, PCI_DEVICE_ID_INTEL_G33_IG, "G33", | ||
790 | NULL, &intel_g33_driver }, | ||
791 | { PCI_DEVICE_ID_INTEL_Q35_HB, PCI_DEVICE_ID_INTEL_Q35_IG, "Q35", | ||
792 | NULL, &intel_g33_driver }, | ||
793 | { PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, "Q33", | ||
794 | NULL, &intel_g33_driver }, | ||
795 | { PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_M_IG, "GMA3150", | ||
796 | NULL, &intel_g33_driver }, | ||
797 | { PCI_DEVICE_ID_INTEL_PINEVIEW_HB, PCI_DEVICE_ID_INTEL_PINEVIEW_IG, "GMA3150", | ||
798 | NULL, &intel_g33_driver }, | ||
799 | { PCI_DEVICE_ID_INTEL_GM45_HB, PCI_DEVICE_ID_INTEL_GM45_IG, | ||
800 | "GM45", NULL, &intel_i965_driver }, | ||
801 | { PCI_DEVICE_ID_INTEL_EAGLELAKE_HB, PCI_DEVICE_ID_INTEL_EAGLELAKE_IG, | ||
802 | "Eaglelake", NULL, &intel_i965_driver }, | ||
803 | { PCI_DEVICE_ID_INTEL_Q45_HB, PCI_DEVICE_ID_INTEL_Q45_IG, | ||
804 | "Q45/Q43", NULL, &intel_i965_driver }, | ||
805 | { PCI_DEVICE_ID_INTEL_G45_HB, PCI_DEVICE_ID_INTEL_G45_IG, | ||
806 | "G45/G43", NULL, &intel_i965_driver }, | ||
807 | { PCI_DEVICE_ID_INTEL_B43_HB, PCI_DEVICE_ID_INTEL_B43_IG, | ||
808 | "B43", NULL, &intel_i965_driver }, | ||
809 | { PCI_DEVICE_ID_INTEL_B43_1_HB, PCI_DEVICE_ID_INTEL_B43_1_IG, | ||
810 | "B43", NULL, &intel_i965_driver }, | ||
811 | { PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG, | ||
812 | "G41", NULL, &intel_i965_driver }, | ||
813 | { PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG, | ||
814 | "HD Graphics", NULL, &intel_i965_driver }, | ||
815 | { PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, | ||
816 | "HD Graphics", NULL, &intel_i965_driver }, | ||
817 | { PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, | ||
818 | "HD Graphics", NULL, &intel_i965_driver }, | ||
819 | { PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB, PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, | ||
820 | "HD Graphics", NULL, &intel_i965_driver }, | ||
821 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT1_IG, | ||
822 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
823 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_IG, | ||
824 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
825 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_PLUS_IG, | ||
826 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
827 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT1_IG, | ||
828 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
829 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_IG, | ||
830 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
831 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_PLUS_IG, | ||
832 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
833 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG, | ||
834 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
835 | { 0, 0, NULL, NULL, NULL } | ||
836 | }; | 732 | }; |
837 | 733 | ||
838 | static int __devinit intel_gmch_probe(struct pci_dev *pdev, | ||
839 | struct agp_bridge_data *bridge) | ||
840 | { | ||
841 | int i, mask; | ||
842 | |||
843 | bridge->driver = NULL; | ||
844 | |||
845 | for (i = 0; intel_agp_chipsets[i].name != NULL; i++) { | ||
846 | if ((intel_agp_chipsets[i].gmch_chip_id != 0) && | ||
847 | find_gmch(intel_agp_chipsets[i].gmch_chip_id)) { | ||
848 | bridge->driver = | ||
849 | intel_agp_chipsets[i].gmch_driver; | ||
850 | break; | ||
851 | } | ||
852 | } | ||
853 | |||
854 | if (!bridge->driver) | ||
855 | return 0; | ||
856 | |||
857 | bridge->dev_private_data = &intel_private; | ||
858 | bridge->dev = pdev; | ||
859 | |||
860 | dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name); | ||
861 | |||
862 | if (bridge->driver->mask_memory == intel_gen6_mask_memory) | ||
863 | mask = 40; | ||
864 | else if (bridge->driver->mask_memory == intel_i965_mask_memory) | ||
865 | mask = 36; | ||
866 | else | ||
867 | mask = 32; | ||
868 | |||
869 | if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(mask))) | ||
870 | dev_err(&intel_private.pcidev->dev, | ||
871 | "set gfx device dma mask %d-bit failed!\n", mask); | ||
872 | else | ||
873 | pci_set_consistent_dma_mask(intel_private.pcidev, | ||
874 | DMA_BIT_MASK(mask)); | ||
875 | |||
876 | return 1; | ||
877 | } | ||
878 | |||
879 | static int __devinit agp_intel_probe(struct pci_dev *pdev, | 734 | static int __devinit agp_intel_probe(struct pci_dev *pdev, |
880 | const struct pci_device_id *ent) | 735 | const struct pci_device_id *ent) |
881 | { | 736 | { |
@@ -905,7 +760,7 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
905 | } | 760 | } |
906 | } | 761 | } |
907 | 762 | ||
908 | if (intel_agp_chipsets[i].name == NULL) { | 763 | if (!bridge->driver) { |
909 | if (cap_ptr) | 764 | if (cap_ptr) |
910 | dev_warn(&pdev->dev, "unsupported Intel chipset [%04x/%04x]\n", | 765 | dev_warn(&pdev->dev, "unsupported Intel chipset [%04x/%04x]\n", |
911 | pdev->vendor, pdev->device); | 766 | pdev->vendor, pdev->device); |
@@ -913,14 +768,6 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, | |||
913 | return -ENODEV; | 768 | return -ENODEV; |
914 | } | 769 | } |
915 | 770 | ||
916 | if (!bridge->driver) { | ||
917 | if (cap_ptr) | ||
918 | dev_warn(&pdev->dev, "can't find bridge device (chip_id: %04x)\n", | ||
919 | intel_agp_chipsets[i].gmch_chip_id); | ||
920 | agp_put_bridge(bridge); | ||
921 | return -ENODEV; | ||
922 | } | ||
923 | |||
924 | bridge->dev = pdev; | 771 | bridge->dev = pdev; |
925 | bridge->dev_private_data = NULL; | 772 | bridge->dev_private_data = NULL; |
926 | 773 | ||
@@ -972,8 +819,7 @@ static void __devexit agp_intel_remove(struct pci_dev *pdev) | |||
972 | 819 | ||
973 | agp_remove_bridge(bridge); | 820 | agp_remove_bridge(bridge); |
974 | 821 | ||
975 | if (intel_private.pcidev) | 822 | intel_gmch_remove(pdev); |
976 | pci_dev_put(intel_private.pcidev); | ||
977 | 823 | ||
978 | agp_put_bridge(bridge); | 824 | agp_put_bridge(bridge); |
979 | } | 825 | } |
@@ -1049,6 +895,7 @@ static struct pci_device_id agp_intel_pci_table[] = { | |||
1049 | ID(PCI_DEVICE_ID_INTEL_G45_HB), | 895 | ID(PCI_DEVICE_ID_INTEL_G45_HB), |
1050 | ID(PCI_DEVICE_ID_INTEL_G41_HB), | 896 | ID(PCI_DEVICE_ID_INTEL_G41_HB), |
1051 | ID(PCI_DEVICE_ID_INTEL_B43_HB), | 897 | ID(PCI_DEVICE_ID_INTEL_B43_HB), |
898 | ID(PCI_DEVICE_ID_INTEL_B43_1_HB), | ||
1052 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB), | 899 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB), |
1053 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB), | 900 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB), |
1054 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB), | 901 | ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB), |
diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h index d09b1ab7e8ab..90539df02504 100644 --- a/drivers/char/agp/intel-agp.h +++ b/drivers/char/agp/intel-agp.h | |||
@@ -215,44 +215,7 @@ | |||
215 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB 0x0108 /* Server */ | 215 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB 0x0108 /* Server */ |
216 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG 0x010A | 216 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG 0x010A |
217 | 217 | ||
218 | /* cover 915 and 945 variants */ | 218 | int intel_gmch_probe(struct pci_dev *pdev, |
219 | #define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \ | 219 | struct agp_bridge_data *bridge); |
220 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB || \ | 220 | void intel_gmch_remove(struct pci_dev *pdev); |
221 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || \ | ||
222 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB || \ | ||
223 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB || \ | ||
224 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB) | ||
225 | |||
226 | #define IS_I965 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82946GZ_HB || \ | ||
227 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82G35_HB || \ | ||
228 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \ | ||
229 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \ | ||
230 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \ | ||
231 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB) | ||
232 | |||
233 | #define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \ | ||
234 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \ | ||
235 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB || \ | ||
236 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB || \ | ||
237 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB) | ||
238 | |||
239 | #define IS_PINEVIEW (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB || \ | ||
240 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_PINEVIEW_HB) | ||
241 | |||
242 | #define IS_SNB (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB || \ | ||
243 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB || \ | ||
244 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB) | ||
245 | |||
246 | #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_EAGLELAKE_HB || \ | ||
247 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \ | ||
248 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \ | ||
249 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB || \ | ||
250 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G41_HB || \ | ||
251 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_B43_HB || \ | ||
252 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB || \ | ||
253 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB || \ | ||
254 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB || \ | ||
255 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB || \ | ||
256 | IS_SNB) | ||
257 | |||
258 | #endif | 221 | #endif |
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 75e0a3497888..6b6760ea2435 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
@@ -15,6 +15,18 @@ | |||
15 | * /fairy-tale-mode off | 15 | * /fairy-tale-mode off |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/pci.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/pagemap.h> | ||
23 | #include <linux/agp_backend.h> | ||
24 | #include <asm/smp.h> | ||
25 | #include "agp.h" | ||
26 | #include "intel-agp.h" | ||
27 | #include <linux/intel-gtt.h> | ||
28 | #include <drm/intel-gtt.h> | ||
29 | |||
18 | /* | 30 | /* |
19 | * If we have Intel graphics, we're not going to have anything other than | 31 | * If we have Intel graphics, we're not going to have anything other than |
20 | * an Intel IOMMU. So make the correct use of the PCI DMA API contingent | 32 | * an Intel IOMMU. So make the correct use of the PCI DMA API contingent |
@@ -23,11 +35,12 @@ | |||
23 | */ | 35 | */ |
24 | #ifdef CONFIG_DMAR | 36 | #ifdef CONFIG_DMAR |
25 | #define USE_PCI_DMA_API 1 | 37 | #define USE_PCI_DMA_API 1 |
38 | #else | ||
39 | #define USE_PCI_DMA_API 0 | ||
26 | #endif | 40 | #endif |
27 | 41 | ||
28 | /* Max amount of stolen space, anything above will be returned to Linux */ | 42 | /* Max amount of stolen space, anything above will be returned to Linux */ |
29 | int intel_max_stolen = 32 * 1024 * 1024; | 43 | int intel_max_stolen = 32 * 1024 * 1024; |
30 | EXPORT_SYMBOL(intel_max_stolen); | ||
31 | 44 | ||
32 | static const struct aper_size_info_fixed intel_i810_sizes[] = | 45 | static const struct aper_size_info_fixed intel_i810_sizes[] = |
33 | { | 46 | { |
@@ -55,32 +68,36 @@ static struct gatt_mask intel_i810_masks[] = | |||
55 | #define INTEL_AGP_CACHED_MEMORY_LLC_MLC 3 | 68 | #define INTEL_AGP_CACHED_MEMORY_LLC_MLC 3 |
56 | #define INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT 4 | 69 | #define INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT 4 |
57 | 70 | ||
58 | static struct gatt_mask intel_gen6_masks[] = | 71 | struct intel_gtt_driver { |
59 | { | 72 | unsigned int gen : 8; |
60 | {.mask = I810_PTE_VALID | GEN6_PTE_UNCACHED, | 73 | unsigned int is_g33 : 1; |
61 | .type = INTEL_AGP_UNCACHED_MEMORY }, | 74 | unsigned int is_pineview : 1; |
62 | {.mask = I810_PTE_VALID | GEN6_PTE_LLC, | 75 | unsigned int is_ironlake : 1; |
63 | .type = INTEL_AGP_CACHED_MEMORY_LLC }, | 76 | unsigned int dma_mask_size : 8; |
64 | {.mask = I810_PTE_VALID | GEN6_PTE_LLC | GEN6_PTE_GFDT, | 77 | /* Chipset specific GTT setup */ |
65 | .type = INTEL_AGP_CACHED_MEMORY_LLC_GFDT }, | 78 | int (*setup)(void); |
66 | {.mask = I810_PTE_VALID | GEN6_PTE_LLC_MLC, | 79 | /* This should undo anything done in ->setup() save the unmapping |
67 | .type = INTEL_AGP_CACHED_MEMORY_LLC_MLC }, | 80 | * of the mmio register file, that's done in the generic code. */ |
68 | {.mask = I810_PTE_VALID | GEN6_PTE_LLC_MLC | GEN6_PTE_GFDT, | 81 | void (*cleanup)(void); |
69 | .type = INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT }, | 82 | void (*write_entry)(dma_addr_t addr, unsigned int entry, unsigned int flags); |
83 | /* Flags is a more or less chipset specific opaque value. | ||
84 | * For chipsets that need to support old ums (non-gem) code, this | ||
85 | * needs to be identical to the various supported agp memory types! */ | ||
86 | bool (*check_flags)(unsigned int flags); | ||
87 | void (*chipset_flush)(void); | ||
70 | }; | 88 | }; |
71 | 89 | ||
72 | static struct _intel_private { | 90 | static struct _intel_private { |
91 | struct intel_gtt base; | ||
92 | const struct intel_gtt_driver *driver; | ||
73 | struct pci_dev *pcidev; /* device one */ | 93 | struct pci_dev *pcidev; /* device one */ |
94 | struct pci_dev *bridge_dev; | ||
74 | u8 __iomem *registers; | 95 | u8 __iomem *registers; |
96 | phys_addr_t gtt_bus_addr; | ||
97 | phys_addr_t gma_bus_addr; | ||
98 | phys_addr_t pte_bus_addr; | ||
75 | u32 __iomem *gtt; /* I915G */ | 99 | u32 __iomem *gtt; /* I915G */ |
76 | int num_dcache_entries; | 100 | int num_dcache_entries; |
77 | /* gtt_entries is the number of gtt entries that are already mapped | ||
78 | * to stolen memory. Stolen memory is larger than the memory mapped | ||
79 | * through gtt_entries, as it includes some reserved space for the BIOS | ||
80 | * popup and for the GTT. | ||
81 | */ | ||
82 | int gtt_entries; /* i830+ */ | ||
83 | int gtt_total_size; | ||
84 | union { | 101 | union { |
85 | void __iomem *i9xx_flush_page; | 102 | void __iomem *i9xx_flush_page; |
86 | void *i8xx_flush_page; | 103 | void *i8xx_flush_page; |
@@ -88,23 +105,14 @@ static struct _intel_private { | |||
88 | struct page *i8xx_page; | 105 | struct page *i8xx_page; |
89 | struct resource ifp_resource; | 106 | struct resource ifp_resource; |
90 | int resource_valid; | 107 | int resource_valid; |
108 | struct page *scratch_page; | ||
109 | dma_addr_t scratch_page_dma; | ||
91 | } intel_private; | 110 | } intel_private; |
92 | 111 | ||
93 | #ifdef USE_PCI_DMA_API | 112 | #define INTEL_GTT_GEN intel_private.driver->gen |
94 | static int intel_agp_map_page(struct page *page, dma_addr_t *ret) | 113 | #define IS_G33 intel_private.driver->is_g33 |
95 | { | 114 | #define IS_PINEVIEW intel_private.driver->is_pineview |
96 | *ret = pci_map_page(intel_private.pcidev, page, 0, | 115 | #define IS_IRONLAKE intel_private.driver->is_ironlake |
97 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | ||
98 | if (pci_dma_mapping_error(intel_private.pcidev, *ret)) | ||
99 | return -EINVAL; | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static void intel_agp_unmap_page(struct page *page, dma_addr_t dma) | ||
104 | { | ||
105 | pci_unmap_page(intel_private.pcidev, dma, | ||
106 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | ||
107 | } | ||
108 | 116 | ||
109 | static void intel_agp_free_sglist(struct agp_memory *mem) | 117 | static void intel_agp_free_sglist(struct agp_memory *mem) |
110 | { | 118 | { |
@@ -125,6 +133,9 @@ static int intel_agp_map_memory(struct agp_memory *mem) | |||
125 | struct scatterlist *sg; | 133 | struct scatterlist *sg; |
126 | int i; | 134 | int i; |
127 | 135 | ||
136 | if (mem->sg_list) | ||
137 | return 0; /* already mapped (for e.g. resume */ | ||
138 | |||
128 | DBG("try mapping %lu pages\n", (unsigned long)mem->page_count); | 139 | DBG("try mapping %lu pages\n", (unsigned long)mem->page_count); |
129 | 140 | ||
130 | if (sg_alloc_table(&st, mem->page_count, GFP_KERNEL)) | 141 | if (sg_alloc_table(&st, mem->page_count, GFP_KERNEL)) |
@@ -156,70 +167,17 @@ static void intel_agp_unmap_memory(struct agp_memory *mem) | |||
156 | intel_agp_free_sglist(mem); | 167 | intel_agp_free_sglist(mem); |
157 | } | 168 | } |
158 | 169 | ||
159 | static void intel_agp_insert_sg_entries(struct agp_memory *mem, | ||
160 | off_t pg_start, int mask_type) | ||
161 | { | ||
162 | struct scatterlist *sg; | ||
163 | int i, j; | ||
164 | |||
165 | j = pg_start; | ||
166 | |||
167 | WARN_ON(!mem->num_sg); | ||
168 | |||
169 | if (mem->num_sg == mem->page_count) { | ||
170 | for_each_sg(mem->sg_list, sg, mem->page_count, i) { | ||
171 | writel(agp_bridge->driver->mask_memory(agp_bridge, | ||
172 | sg_dma_address(sg), mask_type), | ||
173 | intel_private.gtt+j); | ||
174 | j++; | ||
175 | } | ||
176 | } else { | ||
177 | /* sg may merge pages, but we have to separate | ||
178 | * per-page addr for GTT */ | ||
179 | unsigned int len, m; | ||
180 | |||
181 | for_each_sg(mem->sg_list, sg, mem->num_sg, i) { | ||
182 | len = sg_dma_len(sg) / PAGE_SIZE; | ||
183 | for (m = 0; m < len; m++) { | ||
184 | writel(agp_bridge->driver->mask_memory(agp_bridge, | ||
185 | sg_dma_address(sg) + m * PAGE_SIZE, | ||
186 | mask_type), | ||
187 | intel_private.gtt+j); | ||
188 | j++; | ||
189 | } | ||
190 | } | ||
191 | } | ||
192 | readl(intel_private.gtt+j-1); | ||
193 | } | ||
194 | |||
195 | #else | ||
196 | |||
197 | static void intel_agp_insert_sg_entries(struct agp_memory *mem, | ||
198 | off_t pg_start, int mask_type) | ||
199 | { | ||
200 | int i, j; | ||
201 | |||
202 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | ||
203 | writel(agp_bridge->driver->mask_memory(agp_bridge, | ||
204 | page_to_phys(mem->pages[i]), mask_type), | ||
205 | intel_private.gtt+j); | ||
206 | } | ||
207 | |||
208 | readl(intel_private.gtt+j-1); | ||
209 | } | ||
210 | |||
211 | #endif | ||
212 | |||
213 | static int intel_i810_fetch_size(void) | 170 | static int intel_i810_fetch_size(void) |
214 | { | 171 | { |
215 | u32 smram_miscc; | 172 | u32 smram_miscc; |
216 | struct aper_size_info_fixed *values; | 173 | struct aper_size_info_fixed *values; |
217 | 174 | ||
218 | pci_read_config_dword(agp_bridge->dev, I810_SMRAM_MISCC, &smram_miscc); | 175 | pci_read_config_dword(intel_private.bridge_dev, |
176 | I810_SMRAM_MISCC, &smram_miscc); | ||
219 | values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes); | 177 | values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes); |
220 | 178 | ||
221 | if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) { | 179 | if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) { |
222 | dev_warn(&agp_bridge->dev->dev, "i810 is disabled\n"); | 180 | dev_warn(&intel_private.bridge_dev->dev, "i810 is disabled\n"); |
223 | return 0; | 181 | return 0; |
224 | } | 182 | } |
225 | if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) { | 183 | if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) { |
@@ -284,7 +242,7 @@ static void intel_i810_cleanup(void) | |||
284 | iounmap(intel_private.registers); | 242 | iounmap(intel_private.registers); |
285 | } | 243 | } |
286 | 244 | ||
287 | static void intel_i810_agp_enable(struct agp_bridge_data *bridge, u32 mode) | 245 | static void intel_fake_agp_enable(struct agp_bridge_data *bridge, u32 mode) |
288 | { | 246 | { |
289 | return; | 247 | return; |
290 | } | 248 | } |
@@ -319,34 +277,6 @@ static void i8xx_destroy_pages(struct page *page) | |||
319 | atomic_dec(&agp_bridge->current_memory_agp); | 277 | atomic_dec(&agp_bridge->current_memory_agp); |
320 | } | 278 | } |
321 | 279 | ||
322 | static int intel_i830_type_to_mask_type(struct agp_bridge_data *bridge, | ||
323 | int type) | ||
324 | { | ||
325 | if (type < AGP_USER_TYPES) | ||
326 | return type; | ||
327 | else if (type == AGP_USER_CACHED_MEMORY) | ||
328 | return INTEL_AGP_CACHED_MEMORY; | ||
329 | else | ||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | static int intel_gen6_type_to_mask_type(struct agp_bridge_data *bridge, | ||
334 | int type) | ||
335 | { | ||
336 | unsigned int type_mask = type & ~AGP_USER_CACHED_MEMORY_GFDT; | ||
337 | unsigned int gfdt = type & AGP_USER_CACHED_MEMORY_GFDT; | ||
338 | |||
339 | if (type_mask == AGP_USER_UNCACHED_MEMORY) | ||
340 | return INTEL_AGP_UNCACHED_MEMORY; | ||
341 | else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC) | ||
342 | return gfdt ? INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT : | ||
343 | INTEL_AGP_CACHED_MEMORY_LLC_MLC; | ||
344 | else /* set 'normal'/'cached' to LLC by default */ | ||
345 | return gfdt ? INTEL_AGP_CACHED_MEMORY_LLC_GFDT : | ||
346 | INTEL_AGP_CACHED_MEMORY_LLC; | ||
347 | } | ||
348 | |||
349 | |||
350 | static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start, | 280 | static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start, |
351 | int type) | 281 | int type) |
352 | { | 282 | { |
@@ -514,8 +444,33 @@ static unsigned long intel_i810_mask_memory(struct agp_bridge_data *bridge, | |||
514 | return addr | bridge->driver->masks[type].mask; | 444 | return addr | bridge->driver->masks[type].mask; |
515 | } | 445 | } |
516 | 446 | ||
517 | static struct aper_size_info_fixed intel_i830_sizes[] = | 447 | static int intel_gtt_setup_scratch_page(void) |
518 | { | 448 | { |
449 | struct page *page; | ||
450 | dma_addr_t dma_addr; | ||
451 | |||
452 | page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); | ||
453 | if (page == NULL) | ||
454 | return -ENOMEM; | ||
455 | get_page(page); | ||
456 | set_pages_uc(page, 1); | ||
457 | |||
458 | if (USE_PCI_DMA_API && INTEL_GTT_GEN > 2) { | ||
459 | dma_addr = pci_map_page(intel_private.pcidev, page, 0, | ||
460 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | ||
461 | if (pci_dma_mapping_error(intel_private.pcidev, dma_addr)) | ||
462 | return -EINVAL; | ||
463 | |||
464 | intel_private.scratch_page_dma = dma_addr; | ||
465 | } else | ||
466 | intel_private.scratch_page_dma = page_to_phys(page); | ||
467 | |||
468 | intel_private.scratch_page = page; | ||
469 | |||
470 | return 0; | ||
471 | } | ||
472 | |||
473 | static const struct aper_size_info_fixed const intel_fake_agp_sizes[] = { | ||
519 | {128, 32768, 5}, | 474 | {128, 32768, 5}, |
520 | /* The 64M mode still requires a 128k gatt */ | 475 | /* The 64M mode still requires a 128k gatt */ |
521 | {64, 16384, 5}, | 476 | {64, 16384, 5}, |
@@ -523,102 +478,49 @@ static struct aper_size_info_fixed intel_i830_sizes[] = | |||
523 | {512, 131072, 7}, | 478 | {512, 131072, 7}, |
524 | }; | 479 | }; |
525 | 480 | ||
526 | static void intel_i830_init_gtt_entries(void) | 481 | static unsigned int intel_gtt_stolen_entries(void) |
527 | { | 482 | { |
528 | u16 gmch_ctrl; | 483 | u16 gmch_ctrl; |
529 | int gtt_entries = 0; | ||
530 | u8 rdct; | 484 | u8 rdct; |
531 | int local = 0; | 485 | int local = 0; |
532 | static const int ddt[4] = { 0, 16, 32, 64 }; | 486 | static const int ddt[4] = { 0, 16, 32, 64 }; |
533 | int size; /* reserved space (in kb) at the top of stolen memory */ | 487 | unsigned int overhead_entries, stolen_entries; |
488 | unsigned int stolen_size = 0; | ||
534 | 489 | ||
535 | pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); | 490 | pci_read_config_word(intel_private.bridge_dev, |
491 | I830_GMCH_CTRL, &gmch_ctrl); | ||
536 | 492 | ||
537 | if (IS_I965) { | 493 | if (INTEL_GTT_GEN > 4 || IS_PINEVIEW) |
538 | u32 pgetbl_ctl; | 494 | overhead_entries = 0; |
539 | pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL); | 495 | else |
496 | overhead_entries = intel_private.base.gtt_mappable_entries | ||
497 | / 1024; | ||
540 | 498 | ||
541 | /* The 965 has a field telling us the size of the GTT, | 499 | overhead_entries += 1; /* BIOS popup */ |
542 | * which may be larger than what is necessary to map the | ||
543 | * aperture. | ||
544 | */ | ||
545 | switch (pgetbl_ctl & I965_PGETBL_SIZE_MASK) { | ||
546 | case I965_PGETBL_SIZE_128KB: | ||
547 | size = 128; | ||
548 | break; | ||
549 | case I965_PGETBL_SIZE_256KB: | ||
550 | size = 256; | ||
551 | break; | ||
552 | case I965_PGETBL_SIZE_512KB: | ||
553 | size = 512; | ||
554 | break; | ||
555 | case I965_PGETBL_SIZE_1MB: | ||
556 | size = 1024; | ||
557 | break; | ||
558 | case I965_PGETBL_SIZE_2MB: | ||
559 | size = 2048; | ||
560 | break; | ||
561 | case I965_PGETBL_SIZE_1_5MB: | ||
562 | size = 1024 + 512; | ||
563 | break; | ||
564 | default: | ||
565 | dev_info(&intel_private.pcidev->dev, | ||
566 | "unknown page table size, assuming 512KB\n"); | ||
567 | size = 512; | ||
568 | } | ||
569 | size += 4; /* add in BIOS popup space */ | ||
570 | } else if (IS_G33 && !IS_PINEVIEW) { | ||
571 | /* G33's GTT size defined in gmch_ctrl */ | ||
572 | switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) { | ||
573 | case G33_PGETBL_SIZE_1M: | ||
574 | size = 1024; | ||
575 | break; | ||
576 | case G33_PGETBL_SIZE_2M: | ||
577 | size = 2048; | ||
578 | break; | ||
579 | default: | ||
580 | dev_info(&agp_bridge->dev->dev, | ||
581 | "unknown page table size 0x%x, assuming 512KB\n", | ||
582 | (gmch_ctrl & G33_PGETBL_SIZE_MASK)); | ||
583 | size = 512; | ||
584 | } | ||
585 | size += 4; | ||
586 | } else if (IS_G4X || IS_PINEVIEW) { | ||
587 | /* On 4 series hardware, GTT stolen is separate from graphics | ||
588 | * stolen, ignore it in stolen gtt entries counting. However, | ||
589 | * 4KB of the stolen memory doesn't get mapped to the GTT. | ||
590 | */ | ||
591 | size = 4; | ||
592 | } else { | ||
593 | /* On previous hardware, the GTT size was just what was | ||
594 | * required to map the aperture. | ||
595 | */ | ||
596 | size = agp_bridge->driver->fetch_size() + 4; | ||
597 | } | ||
598 | 500 | ||
599 | if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82830_HB || | 501 | if (intel_private.bridge_dev->device == PCI_DEVICE_ID_INTEL_82830_HB || |
600 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) { | 502 | intel_private.bridge_dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) { |
601 | switch (gmch_ctrl & I830_GMCH_GMS_MASK) { | 503 | switch (gmch_ctrl & I830_GMCH_GMS_MASK) { |
602 | case I830_GMCH_GMS_STOLEN_512: | 504 | case I830_GMCH_GMS_STOLEN_512: |
603 | gtt_entries = KB(512) - KB(size); | 505 | stolen_size = KB(512); |
604 | break; | 506 | break; |
605 | case I830_GMCH_GMS_STOLEN_1024: | 507 | case I830_GMCH_GMS_STOLEN_1024: |
606 | gtt_entries = MB(1) - KB(size); | 508 | stolen_size = MB(1); |
607 | break; | 509 | break; |
608 | case I830_GMCH_GMS_STOLEN_8192: | 510 | case I830_GMCH_GMS_STOLEN_8192: |
609 | gtt_entries = MB(8) - KB(size); | 511 | stolen_size = MB(8); |
610 | break; | 512 | break; |
611 | case I830_GMCH_GMS_LOCAL: | 513 | case I830_GMCH_GMS_LOCAL: |
612 | rdct = readb(intel_private.registers+I830_RDRAM_CHANNEL_TYPE); | 514 | rdct = readb(intel_private.registers+I830_RDRAM_CHANNEL_TYPE); |
613 | gtt_entries = (I830_RDRAM_ND(rdct) + 1) * | 515 | stolen_size = (I830_RDRAM_ND(rdct) + 1) * |
614 | MB(ddt[I830_RDRAM_DDT(rdct)]); | 516 | MB(ddt[I830_RDRAM_DDT(rdct)]); |
615 | local = 1; | 517 | local = 1; |
616 | break; | 518 | break; |
617 | default: | 519 | default: |
618 | gtt_entries = 0; | 520 | stolen_size = 0; |
619 | break; | 521 | break; |
620 | } | 522 | } |
621 | } else if (IS_SNB) { | 523 | } else if (INTEL_GTT_GEN == 6) { |
622 | /* | 524 | /* |
623 | * SandyBridge has new memory control reg at 0x50.w | 525 | * SandyBridge has new memory control reg at 0x50.w |
624 | */ | 526 | */ |
@@ -626,149 +528,292 @@ static void intel_i830_init_gtt_entries(void) | |||
626 | pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl); | 528 | pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl); |
627 | switch (snb_gmch_ctl & SNB_GMCH_GMS_STOLEN_MASK) { | 529 | switch (snb_gmch_ctl & SNB_GMCH_GMS_STOLEN_MASK) { |
628 | case SNB_GMCH_GMS_STOLEN_32M: | 530 | case SNB_GMCH_GMS_STOLEN_32M: |
629 | gtt_entries = MB(32) - KB(size); | 531 | stolen_size = MB(32); |
630 | break; | 532 | break; |
631 | case SNB_GMCH_GMS_STOLEN_64M: | 533 | case SNB_GMCH_GMS_STOLEN_64M: |
632 | gtt_entries = MB(64) - KB(size); | 534 | stolen_size = MB(64); |
633 | break; | 535 | break; |
634 | case SNB_GMCH_GMS_STOLEN_96M: | 536 | case SNB_GMCH_GMS_STOLEN_96M: |
635 | gtt_entries = MB(96) - KB(size); | 537 | stolen_size = MB(96); |
636 | break; | 538 | break; |
637 | case SNB_GMCH_GMS_STOLEN_128M: | 539 | case SNB_GMCH_GMS_STOLEN_128M: |
638 | gtt_entries = MB(128) - KB(size); | 540 | stolen_size = MB(128); |
639 | break; | 541 | break; |
640 | case SNB_GMCH_GMS_STOLEN_160M: | 542 | case SNB_GMCH_GMS_STOLEN_160M: |
641 | gtt_entries = MB(160) - KB(size); | 543 | stolen_size = MB(160); |
642 | break; | 544 | break; |
643 | case SNB_GMCH_GMS_STOLEN_192M: | 545 | case SNB_GMCH_GMS_STOLEN_192M: |
644 | gtt_entries = MB(192) - KB(size); | 546 | stolen_size = MB(192); |
645 | break; | 547 | break; |
646 | case SNB_GMCH_GMS_STOLEN_224M: | 548 | case SNB_GMCH_GMS_STOLEN_224M: |
647 | gtt_entries = MB(224) - KB(size); | 549 | stolen_size = MB(224); |
648 | break; | 550 | break; |
649 | case SNB_GMCH_GMS_STOLEN_256M: | 551 | case SNB_GMCH_GMS_STOLEN_256M: |
650 | gtt_entries = MB(256) - KB(size); | 552 | stolen_size = MB(256); |
651 | break; | 553 | break; |
652 | case SNB_GMCH_GMS_STOLEN_288M: | 554 | case SNB_GMCH_GMS_STOLEN_288M: |
653 | gtt_entries = MB(288) - KB(size); | 555 | stolen_size = MB(288); |
654 | break; | 556 | break; |
655 | case SNB_GMCH_GMS_STOLEN_320M: | 557 | case SNB_GMCH_GMS_STOLEN_320M: |
656 | gtt_entries = MB(320) - KB(size); | 558 | stolen_size = MB(320); |
657 | break; | 559 | break; |
658 | case SNB_GMCH_GMS_STOLEN_352M: | 560 | case SNB_GMCH_GMS_STOLEN_352M: |
659 | gtt_entries = MB(352) - KB(size); | 561 | stolen_size = MB(352); |
660 | break; | 562 | break; |
661 | case SNB_GMCH_GMS_STOLEN_384M: | 563 | case SNB_GMCH_GMS_STOLEN_384M: |
662 | gtt_entries = MB(384) - KB(size); | 564 | stolen_size = MB(384); |
663 | break; | 565 | break; |
664 | case SNB_GMCH_GMS_STOLEN_416M: | 566 | case SNB_GMCH_GMS_STOLEN_416M: |
665 | gtt_entries = MB(416) - KB(size); | 567 | stolen_size = MB(416); |
666 | break; | 568 | break; |
667 | case SNB_GMCH_GMS_STOLEN_448M: | 569 | case SNB_GMCH_GMS_STOLEN_448M: |
668 | gtt_entries = MB(448) - KB(size); | 570 | stolen_size = MB(448); |
669 | break; | 571 | break; |
670 | case SNB_GMCH_GMS_STOLEN_480M: | 572 | case SNB_GMCH_GMS_STOLEN_480M: |
671 | gtt_entries = MB(480) - KB(size); | 573 | stolen_size = MB(480); |
672 | break; | 574 | break; |
673 | case SNB_GMCH_GMS_STOLEN_512M: | 575 | case SNB_GMCH_GMS_STOLEN_512M: |
674 | gtt_entries = MB(512) - KB(size); | 576 | stolen_size = MB(512); |
675 | break; | 577 | break; |
676 | } | 578 | } |
677 | } else { | 579 | } else { |
678 | switch (gmch_ctrl & I855_GMCH_GMS_MASK) { | 580 | switch (gmch_ctrl & I855_GMCH_GMS_MASK) { |
679 | case I855_GMCH_GMS_STOLEN_1M: | 581 | case I855_GMCH_GMS_STOLEN_1M: |
680 | gtt_entries = MB(1) - KB(size); | 582 | stolen_size = MB(1); |
681 | break; | 583 | break; |
682 | case I855_GMCH_GMS_STOLEN_4M: | 584 | case I855_GMCH_GMS_STOLEN_4M: |
683 | gtt_entries = MB(4) - KB(size); | 585 | stolen_size = MB(4); |
684 | break; | 586 | break; |
685 | case I855_GMCH_GMS_STOLEN_8M: | 587 | case I855_GMCH_GMS_STOLEN_8M: |
686 | gtt_entries = MB(8) - KB(size); | 588 | stolen_size = MB(8); |
687 | break; | 589 | break; |
688 | case I855_GMCH_GMS_STOLEN_16M: | 590 | case I855_GMCH_GMS_STOLEN_16M: |
689 | gtt_entries = MB(16) - KB(size); | 591 | stolen_size = MB(16); |
690 | break; | 592 | break; |
691 | case I855_GMCH_GMS_STOLEN_32M: | 593 | case I855_GMCH_GMS_STOLEN_32M: |
692 | gtt_entries = MB(32) - KB(size); | 594 | stolen_size = MB(32); |
693 | break; | 595 | break; |
694 | case I915_GMCH_GMS_STOLEN_48M: | 596 | case I915_GMCH_GMS_STOLEN_48M: |
695 | /* Check it's really I915G */ | 597 | stolen_size = MB(48); |
696 | if (IS_I915 || IS_I965 || IS_G33 || IS_G4X) | ||
697 | gtt_entries = MB(48) - KB(size); | ||
698 | else | ||
699 | gtt_entries = 0; | ||
700 | break; | 598 | break; |
701 | case I915_GMCH_GMS_STOLEN_64M: | 599 | case I915_GMCH_GMS_STOLEN_64M: |
702 | /* Check it's really I915G */ | 600 | stolen_size = MB(64); |
703 | if (IS_I915 || IS_I965 || IS_G33 || IS_G4X) | ||
704 | gtt_entries = MB(64) - KB(size); | ||
705 | else | ||
706 | gtt_entries = 0; | ||
707 | break; | 601 | break; |
708 | case G33_GMCH_GMS_STOLEN_128M: | 602 | case G33_GMCH_GMS_STOLEN_128M: |
709 | if (IS_G33 || IS_I965 || IS_G4X) | 603 | stolen_size = MB(128); |
710 | gtt_entries = MB(128) - KB(size); | ||
711 | else | ||
712 | gtt_entries = 0; | ||
713 | break; | 604 | break; |
714 | case G33_GMCH_GMS_STOLEN_256M: | 605 | case G33_GMCH_GMS_STOLEN_256M: |
715 | if (IS_G33 || IS_I965 || IS_G4X) | 606 | stolen_size = MB(256); |
716 | gtt_entries = MB(256) - KB(size); | ||
717 | else | ||
718 | gtt_entries = 0; | ||
719 | break; | 607 | break; |
720 | case INTEL_GMCH_GMS_STOLEN_96M: | 608 | case INTEL_GMCH_GMS_STOLEN_96M: |
721 | if (IS_I965 || IS_G4X) | 609 | stolen_size = MB(96); |
722 | gtt_entries = MB(96) - KB(size); | ||
723 | else | ||
724 | gtt_entries = 0; | ||
725 | break; | 610 | break; |
726 | case INTEL_GMCH_GMS_STOLEN_160M: | 611 | case INTEL_GMCH_GMS_STOLEN_160M: |
727 | if (IS_I965 || IS_G4X) | 612 | stolen_size = MB(160); |
728 | gtt_entries = MB(160) - KB(size); | ||
729 | else | ||
730 | gtt_entries = 0; | ||
731 | break; | 613 | break; |
732 | case INTEL_GMCH_GMS_STOLEN_224M: | 614 | case INTEL_GMCH_GMS_STOLEN_224M: |
733 | if (IS_I965 || IS_G4X) | 615 | stolen_size = MB(224); |
734 | gtt_entries = MB(224) - KB(size); | ||
735 | else | ||
736 | gtt_entries = 0; | ||
737 | break; | 616 | break; |
738 | case INTEL_GMCH_GMS_STOLEN_352M: | 617 | case INTEL_GMCH_GMS_STOLEN_352M: |
739 | if (IS_I965 || IS_G4X) | 618 | stolen_size = MB(352); |
740 | gtt_entries = MB(352) - KB(size); | ||
741 | else | ||
742 | gtt_entries = 0; | ||
743 | break; | 619 | break; |
744 | default: | 620 | default: |
745 | gtt_entries = 0; | 621 | stolen_size = 0; |
746 | break; | 622 | break; |
747 | } | 623 | } |
748 | } | 624 | } |
749 | if (!local && gtt_entries > intel_max_stolen) { | 625 | |
750 | dev_info(&agp_bridge->dev->dev, | 626 | if (!local && stolen_size > intel_max_stolen) { |
627 | dev_info(&intel_private.bridge_dev->dev, | ||
751 | "detected %dK stolen memory, trimming to %dK\n", | 628 | "detected %dK stolen memory, trimming to %dK\n", |
752 | gtt_entries / KB(1), intel_max_stolen / KB(1)); | 629 | stolen_size / KB(1), intel_max_stolen / KB(1)); |
753 | gtt_entries = intel_max_stolen / KB(4); | 630 | stolen_size = intel_max_stolen; |
754 | } else if (gtt_entries > 0) { | 631 | } else if (stolen_size > 0) { |
755 | dev_info(&agp_bridge->dev->dev, "detected %dK %s memory\n", | 632 | dev_info(&intel_private.bridge_dev->dev, "detected %dK %s memory\n", |
756 | gtt_entries / KB(1), local ? "local" : "stolen"); | 633 | stolen_size / KB(1), local ? "local" : "stolen"); |
757 | gtt_entries /= KB(4); | ||
758 | } else { | 634 | } else { |
759 | dev_info(&agp_bridge->dev->dev, | 635 | dev_info(&intel_private.bridge_dev->dev, |
760 | "no pre-allocated video memory detected\n"); | 636 | "no pre-allocated video memory detected\n"); |
761 | gtt_entries = 0; | 637 | stolen_size = 0; |
638 | } | ||
639 | |||
640 | stolen_entries = stolen_size/KB(4) - overhead_entries; | ||
641 | |||
642 | return stolen_entries; | ||
643 | } | ||
644 | |||
645 | static unsigned int intel_gtt_total_entries(void) | ||
646 | { | ||
647 | int size; | ||
648 | |||
649 | if (IS_G33 || INTEL_GTT_GEN == 4 || INTEL_GTT_GEN == 5) { | ||
650 | u32 pgetbl_ctl; | ||
651 | pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL); | ||
652 | |||
653 | switch (pgetbl_ctl & I965_PGETBL_SIZE_MASK) { | ||
654 | case I965_PGETBL_SIZE_128KB: | ||
655 | size = KB(128); | ||
656 | break; | ||
657 | case I965_PGETBL_SIZE_256KB: | ||
658 | size = KB(256); | ||
659 | break; | ||
660 | case I965_PGETBL_SIZE_512KB: | ||
661 | size = KB(512); | ||
662 | break; | ||
663 | case I965_PGETBL_SIZE_1MB: | ||
664 | size = KB(1024); | ||
665 | break; | ||
666 | case I965_PGETBL_SIZE_2MB: | ||
667 | size = KB(2048); | ||
668 | break; | ||
669 | case I965_PGETBL_SIZE_1_5MB: | ||
670 | size = KB(1024 + 512); | ||
671 | break; | ||
672 | default: | ||
673 | dev_info(&intel_private.pcidev->dev, | ||
674 | "unknown page table size, assuming 512KB\n"); | ||
675 | size = KB(512); | ||
676 | } | ||
677 | |||
678 | return size/4; | ||
679 | } else if (INTEL_GTT_GEN == 6) { | ||
680 | u16 snb_gmch_ctl; | ||
681 | |||
682 | pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl); | ||
683 | switch (snb_gmch_ctl & SNB_GTT_SIZE_MASK) { | ||
684 | default: | ||
685 | case SNB_GTT_SIZE_0M: | ||
686 | printk(KERN_ERR "Bad GTT size mask: 0x%04x.\n", snb_gmch_ctl); | ||
687 | size = MB(0); | ||
688 | break; | ||
689 | case SNB_GTT_SIZE_1M: | ||
690 | size = MB(1); | ||
691 | break; | ||
692 | case SNB_GTT_SIZE_2M: | ||
693 | size = MB(2); | ||
694 | break; | ||
695 | } | ||
696 | return size/4; | ||
697 | } else { | ||
698 | /* On previous hardware, the GTT size was just what was | ||
699 | * required to map the aperture. | ||
700 | */ | ||
701 | return intel_private.base.gtt_mappable_entries; | ||
702 | } | ||
703 | } | ||
704 | |||
705 | static unsigned int intel_gtt_mappable_entries(void) | ||
706 | { | ||
707 | unsigned int aperture_size; | ||
708 | |||
709 | if (INTEL_GTT_GEN == 2) { | ||
710 | u16 gmch_ctrl; | ||
711 | |||
712 | pci_read_config_word(intel_private.bridge_dev, | ||
713 | I830_GMCH_CTRL, &gmch_ctrl); | ||
714 | |||
715 | if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_64M) | ||
716 | aperture_size = MB(64); | ||
717 | else | ||
718 | aperture_size = MB(128); | ||
719 | } else { | ||
720 | /* 9xx supports large sizes, just look at the length */ | ||
721 | aperture_size = pci_resource_len(intel_private.pcidev, 2); | ||
762 | } | 722 | } |
763 | 723 | ||
764 | intel_private.gtt_entries = gtt_entries; | 724 | return aperture_size >> PAGE_SHIFT; |
765 | } | 725 | } |
766 | 726 | ||
767 | static void intel_i830_fini_flush(void) | 727 | static void intel_gtt_teardown_scratch_page(void) |
728 | { | ||
729 | set_pages_wb(intel_private.scratch_page, 1); | ||
730 | pci_unmap_page(intel_private.pcidev, intel_private.scratch_page_dma, | ||
731 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | ||
732 | put_page(intel_private.scratch_page); | ||
733 | __free_page(intel_private.scratch_page); | ||
734 | } | ||
735 | |||
736 | static void intel_gtt_cleanup(void) | ||
737 | { | ||
738 | intel_private.driver->cleanup(); | ||
739 | |||
740 | iounmap(intel_private.gtt); | ||
741 | iounmap(intel_private.registers); | ||
742 | |||
743 | intel_gtt_teardown_scratch_page(); | ||
744 | } | ||
745 | |||
746 | static int intel_gtt_init(void) | ||
747 | { | ||
748 | u32 gtt_map_size; | ||
749 | int ret; | ||
750 | |||
751 | ret = intel_private.driver->setup(); | ||
752 | if (ret != 0) | ||
753 | return ret; | ||
754 | |||
755 | intel_private.base.gtt_mappable_entries = intel_gtt_mappable_entries(); | ||
756 | intel_private.base.gtt_total_entries = intel_gtt_total_entries(); | ||
757 | |||
758 | dev_info(&intel_private.bridge_dev->dev, | ||
759 | "detected gtt size: %dK total, %dK mappable\n", | ||
760 | intel_private.base.gtt_total_entries * 4, | ||
761 | intel_private.base.gtt_mappable_entries * 4); | ||
762 | |||
763 | gtt_map_size = intel_private.base.gtt_total_entries * 4; | ||
764 | |||
765 | intel_private.gtt = ioremap(intel_private.gtt_bus_addr, | ||
766 | gtt_map_size); | ||
767 | if (!intel_private.gtt) { | ||
768 | intel_private.driver->cleanup(); | ||
769 | iounmap(intel_private.registers); | ||
770 | return -ENOMEM; | ||
771 | } | ||
772 | |||
773 | global_cache_flush(); /* FIXME: ? */ | ||
774 | |||
775 | /* we have to call this as early as possible after the MMIO base address is known */ | ||
776 | intel_private.base.gtt_stolen_entries = intel_gtt_stolen_entries(); | ||
777 | if (intel_private.base.gtt_stolen_entries == 0) { | ||
778 | intel_private.driver->cleanup(); | ||
779 | iounmap(intel_private.registers); | ||
780 | iounmap(intel_private.gtt); | ||
781 | return -ENOMEM; | ||
782 | } | ||
783 | |||
784 | ret = intel_gtt_setup_scratch_page(); | ||
785 | if (ret != 0) { | ||
786 | intel_gtt_cleanup(); | ||
787 | return ret; | ||
788 | } | ||
789 | |||
790 | return 0; | ||
791 | } | ||
792 | |||
793 | static int intel_fake_agp_fetch_size(void) | ||
794 | { | ||
795 | int num_sizes = ARRAY_SIZE(intel_fake_agp_sizes); | ||
796 | unsigned int aper_size; | ||
797 | int i; | ||
798 | |||
799 | aper_size = (intel_private.base.gtt_mappable_entries << PAGE_SHIFT) | ||
800 | / MB(1); | ||
801 | |||
802 | for (i = 0; i < num_sizes; i++) { | ||
803 | if (aper_size == intel_fake_agp_sizes[i].size) { | ||
804 | agp_bridge->current_size = | ||
805 | (void *) (intel_fake_agp_sizes + i); | ||
806 | return aper_size; | ||
807 | } | ||
808 | } | ||
809 | |||
810 | return 0; | ||
811 | } | ||
812 | |||
813 | static void i830_cleanup(void) | ||
768 | { | 814 | { |
769 | kunmap(intel_private.i8xx_page); | 815 | kunmap(intel_private.i8xx_page); |
770 | intel_private.i8xx_flush_page = NULL; | 816 | intel_private.i8xx_flush_page = NULL; |
771 | unmap_page_from_agp(intel_private.i8xx_page); | ||
772 | 817 | ||
773 | __free_page(intel_private.i8xx_page); | 818 | __free_page(intel_private.i8xx_page); |
774 | intel_private.i8xx_page = NULL; | 819 | intel_private.i8xx_page = NULL; |
@@ -780,13 +825,13 @@ static void intel_i830_setup_flush(void) | |||
780 | if (intel_private.i8xx_page) | 825 | if (intel_private.i8xx_page) |
781 | return; | 826 | return; |
782 | 827 | ||
783 | intel_private.i8xx_page = alloc_page(GFP_KERNEL | __GFP_ZERO | GFP_DMA32); | 828 | intel_private.i8xx_page = alloc_page(GFP_KERNEL); |
784 | if (!intel_private.i8xx_page) | 829 | if (!intel_private.i8xx_page) |
785 | return; | 830 | return; |
786 | 831 | ||
787 | intel_private.i8xx_flush_page = kmap(intel_private.i8xx_page); | 832 | intel_private.i8xx_flush_page = kmap(intel_private.i8xx_page); |
788 | if (!intel_private.i8xx_flush_page) | 833 | if (!intel_private.i8xx_flush_page) |
789 | intel_i830_fini_flush(); | 834 | i830_cleanup(); |
790 | } | 835 | } |
791 | 836 | ||
792 | /* The chipset_flush interface needs to get data that has already been | 837 | /* The chipset_flush interface needs to get data that has already been |
@@ -799,7 +844,7 @@ static void intel_i830_setup_flush(void) | |||
799 | * that buffer out, we just fill 1KB and clflush it out, on the assumption | 844 | * that buffer out, we just fill 1KB and clflush it out, on the assumption |
800 | * that it'll push whatever was in there out. It appears to work. | 845 | * that it'll push whatever was in there out. It appears to work. |
801 | */ | 846 | */ |
802 | static void intel_i830_chipset_flush(struct agp_bridge_data *bridge) | 847 | static void i830_chipset_flush(void) |
803 | { | 848 | { |
804 | unsigned int *pg = intel_private.i8xx_flush_page; | 849 | unsigned int *pg = intel_private.i8xx_flush_page; |
805 | 850 | ||
@@ -811,169 +856,184 @@ static void intel_i830_chipset_flush(struct agp_bridge_data *bridge) | |||
811 | printk(KERN_ERR "Timed out waiting for cache flush.\n"); | 856 | printk(KERN_ERR "Timed out waiting for cache flush.\n"); |
812 | } | 857 | } |
813 | 858 | ||
814 | /* The intel i830 automatically initializes the agp aperture during POST. | 859 | static void i830_write_entry(dma_addr_t addr, unsigned int entry, |
815 | * Use the memory already set aside for in the GTT. | 860 | unsigned int flags) |
816 | */ | ||
817 | static int intel_i830_create_gatt_table(struct agp_bridge_data *bridge) | ||
818 | { | 861 | { |
819 | int page_order; | 862 | u32 pte_flags = I810_PTE_VALID; |
820 | struct aper_size_info_fixed *size; | 863 | |
821 | int num_entries; | 864 | switch (flags) { |
822 | u32 temp; | 865 | case AGP_DCACHE_MEMORY: |
866 | pte_flags |= I810_PTE_LOCAL; | ||
867 | break; | ||
868 | case AGP_USER_CACHED_MEMORY: | ||
869 | pte_flags |= I830_PTE_SYSTEM_CACHED; | ||
870 | break; | ||
871 | } | ||
823 | 872 | ||
824 | size = agp_bridge->current_size; | 873 | writel(addr | pte_flags, intel_private.gtt + entry); |
825 | page_order = size->page_order; | 874 | } |
826 | num_entries = size->num_entries; | ||
827 | agp_bridge->gatt_table_real = NULL; | ||
828 | 875 | ||
829 | pci_read_config_dword(intel_private.pcidev, I810_MMADDR, &temp); | 876 | static void intel_enable_gtt(void) |
830 | temp &= 0xfff80000; | 877 | { |
878 | u32 gma_addr; | ||
879 | u16 gmch_ctrl; | ||
831 | 880 | ||
832 | intel_private.registers = ioremap(temp, 128 * 4096); | 881 | if (INTEL_GTT_GEN == 2) |
833 | if (!intel_private.registers) | 882 | pci_read_config_dword(intel_private.pcidev, I810_GMADDR, |
834 | return -ENOMEM; | 883 | &gma_addr); |
884 | else | ||
885 | pci_read_config_dword(intel_private.pcidev, I915_GMADDR, | ||
886 | &gma_addr); | ||
835 | 887 | ||
836 | temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; | 888 | intel_private.gma_bus_addr = (gma_addr & PCI_BASE_ADDRESS_MEM_MASK); |
837 | global_cache_flush(); /* FIXME: ?? */ | ||
838 | 889 | ||
839 | /* we have to call this as early as possible after the MMIO base address is known */ | 890 | pci_read_config_word(intel_private.bridge_dev, I830_GMCH_CTRL, &gmch_ctrl); |
840 | intel_i830_init_gtt_entries(); | 891 | gmch_ctrl |= I830_GMCH_ENABLED; |
841 | if (intel_private.gtt_entries == 0) { | 892 | pci_write_config_word(intel_private.bridge_dev, I830_GMCH_CTRL, gmch_ctrl); |
842 | iounmap(intel_private.registers); | 893 | |
894 | writel(intel_private.pte_bus_addr|I810_PGETBL_ENABLED, | ||
895 | intel_private.registers+I810_PGETBL_CTL); | ||
896 | readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */ | ||
897 | } | ||
898 | |||
899 | static int i830_setup(void) | ||
900 | { | ||
901 | u32 reg_addr; | ||
902 | |||
903 | pci_read_config_dword(intel_private.pcidev, I810_MMADDR, ®_addr); | ||
904 | reg_addr &= 0xfff80000; | ||
905 | |||
906 | intel_private.registers = ioremap(reg_addr, KB(64)); | ||
907 | if (!intel_private.registers) | ||
843 | return -ENOMEM; | 908 | return -ENOMEM; |
844 | } | ||
845 | 909 | ||
846 | agp_bridge->gatt_table = NULL; | 910 | intel_private.gtt_bus_addr = reg_addr + I810_PTE_BASE; |
911 | intel_private.pte_bus_addr = | ||
912 | readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; | ||
847 | 913 | ||
848 | agp_bridge->gatt_bus_addr = temp; | 914 | intel_i830_setup_flush(); |
849 | 915 | ||
850 | return 0; | 916 | return 0; |
851 | } | 917 | } |
852 | 918 | ||
853 | /* Return the gatt table to a sane state. Use the top of stolen | 919 | static int intel_fake_agp_create_gatt_table(struct agp_bridge_data *bridge) |
854 | * memory for the GTT. | ||
855 | */ | ||
856 | static int intel_i830_free_gatt_table(struct agp_bridge_data *bridge) | ||
857 | { | 920 | { |
921 | agp_bridge->gatt_table_real = NULL; | ||
922 | agp_bridge->gatt_table = NULL; | ||
923 | agp_bridge->gatt_bus_addr = 0; | ||
924 | |||
858 | return 0; | 925 | return 0; |
859 | } | 926 | } |
860 | 927 | ||
861 | static int intel_i830_fetch_size(void) | 928 | static int intel_fake_agp_free_gatt_table(struct agp_bridge_data *bridge) |
862 | { | 929 | { |
863 | u16 gmch_ctrl; | ||
864 | struct aper_size_info_fixed *values; | ||
865 | |||
866 | values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes); | ||
867 | |||
868 | if (agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82830_HB && | ||
869 | agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82845G_HB) { | ||
870 | /* 855GM/852GM/865G has 128MB aperture size */ | ||
871 | agp_bridge->current_size = (void *) values; | ||
872 | agp_bridge->aperture_size_idx = 0; | ||
873 | return values[0].size; | ||
874 | } | ||
875 | |||
876 | pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); | ||
877 | |||
878 | if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { | ||
879 | agp_bridge->current_size = (void *) values; | ||
880 | agp_bridge->aperture_size_idx = 0; | ||
881 | return values[0].size; | ||
882 | } else { | ||
883 | agp_bridge->current_size = (void *) (values + 1); | ||
884 | agp_bridge->aperture_size_idx = 1; | ||
885 | return values[1].size; | ||
886 | } | ||
887 | |||
888 | return 0; | 930 | return 0; |
889 | } | 931 | } |
890 | 932 | ||
891 | static int intel_i830_configure(void) | 933 | static int intel_fake_agp_configure(void) |
892 | { | 934 | { |
893 | struct aper_size_info_fixed *current_size; | ||
894 | u32 temp; | ||
895 | u16 gmch_ctrl; | ||
896 | int i; | 935 | int i; |
897 | 936 | ||
898 | current_size = A_SIZE_FIX(agp_bridge->current_size); | 937 | intel_enable_gtt(); |
899 | |||
900 | pci_read_config_dword(intel_private.pcidev, I810_GMADDR, &temp); | ||
901 | agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); | ||
902 | |||
903 | pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); | ||
904 | gmch_ctrl |= I830_GMCH_ENABLED; | ||
905 | pci_write_config_word(agp_bridge->dev, I830_GMCH_CTRL, gmch_ctrl); | ||
906 | 938 | ||
907 | writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL); | 939 | agp_bridge->gart_bus_addr = intel_private.gma_bus_addr; |
908 | readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */ | ||
909 | 940 | ||
910 | if (agp_bridge->driver->needs_scratch_page) { | 941 | for (i = intel_private.base.gtt_stolen_entries; |
911 | for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) { | 942 | i < intel_private.base.gtt_total_entries; i++) { |
912 | writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4)); | 943 | intel_private.driver->write_entry(intel_private.scratch_page_dma, |
913 | } | 944 | i, 0); |
914 | readl(intel_private.registers+I810_PTE_BASE+((i-1)*4)); /* PCI Posting. */ | ||
915 | } | 945 | } |
946 | readl(intel_private.gtt+i-1); /* PCI Posting. */ | ||
916 | 947 | ||
917 | global_cache_flush(); | 948 | global_cache_flush(); |
918 | 949 | ||
919 | intel_i830_setup_flush(); | ||
920 | return 0; | 950 | return 0; |
921 | } | 951 | } |
922 | 952 | ||
923 | static void intel_i830_cleanup(void) | 953 | static bool i830_check_flags(unsigned int flags) |
924 | { | 954 | { |
925 | iounmap(intel_private.registers); | 955 | switch (flags) { |
956 | case 0: | ||
957 | case AGP_PHYS_MEMORY: | ||
958 | case AGP_USER_CACHED_MEMORY: | ||
959 | case AGP_USER_MEMORY: | ||
960 | return true; | ||
961 | } | ||
962 | |||
963 | return false; | ||
926 | } | 964 | } |
927 | 965 | ||
928 | static int intel_i830_insert_entries(struct agp_memory *mem, off_t pg_start, | 966 | static void intel_gtt_insert_sg_entries(struct scatterlist *sg_list, |
929 | int type) | 967 | unsigned int sg_len, |
968 | unsigned int pg_start, | ||
969 | unsigned int flags) | ||
930 | { | 970 | { |
931 | int i, j, num_entries; | 971 | struct scatterlist *sg; |
932 | void *temp; | 972 | unsigned int len, m; |
973 | int i, j; | ||
974 | |||
975 | j = pg_start; | ||
976 | |||
977 | /* sg may merge pages, but we have to separate | ||
978 | * per-page addr for GTT */ | ||
979 | for_each_sg(sg_list, sg, sg_len, i) { | ||
980 | len = sg_dma_len(sg) >> PAGE_SHIFT; | ||
981 | for (m = 0; m < len; m++) { | ||
982 | dma_addr_t addr = sg_dma_address(sg) + (m << PAGE_SHIFT); | ||
983 | intel_private.driver->write_entry(addr, | ||
984 | j, flags); | ||
985 | j++; | ||
986 | } | ||
987 | } | ||
988 | readl(intel_private.gtt+j-1); | ||
989 | } | ||
990 | |||
991 | static int intel_fake_agp_insert_entries(struct agp_memory *mem, | ||
992 | off_t pg_start, int type) | ||
993 | { | ||
994 | int i, j; | ||
933 | int ret = -EINVAL; | 995 | int ret = -EINVAL; |
934 | int mask_type; | ||
935 | 996 | ||
936 | if (mem->page_count == 0) | 997 | if (mem->page_count == 0) |
937 | goto out; | 998 | goto out; |
938 | 999 | ||
939 | temp = agp_bridge->current_size; | 1000 | if (pg_start < intel_private.base.gtt_stolen_entries) { |
940 | num_entries = A_SIZE_FIX(temp)->num_entries; | ||
941 | |||
942 | if (pg_start < intel_private.gtt_entries) { | ||
943 | dev_printk(KERN_DEBUG, &intel_private.pcidev->dev, | 1001 | dev_printk(KERN_DEBUG, &intel_private.pcidev->dev, |
944 | "pg_start == 0x%.8lx, intel_private.gtt_entries == 0x%.8x\n", | 1002 | "pg_start == 0x%.8lx, gtt_stolen_entries == 0x%.8x\n", |
945 | pg_start, intel_private.gtt_entries); | 1003 | pg_start, intel_private.base.gtt_stolen_entries); |
946 | 1004 | ||
947 | dev_info(&intel_private.pcidev->dev, | 1005 | dev_info(&intel_private.pcidev->dev, |
948 | "trying to insert into local/stolen memory\n"); | 1006 | "trying to insert into local/stolen memory\n"); |
949 | goto out_err; | 1007 | goto out_err; |
950 | } | 1008 | } |
951 | 1009 | ||
952 | if ((pg_start + mem->page_count) > num_entries) | 1010 | if ((pg_start + mem->page_count) > intel_private.base.gtt_total_entries) |
953 | goto out_err; | 1011 | goto out_err; |
954 | 1012 | ||
955 | /* The i830 can't check the GTT for entries since its read only, | ||
956 | * depend on the caller to make the correct offset decisions. | ||
957 | */ | ||
958 | |||
959 | if (type != mem->type) | 1013 | if (type != mem->type) |
960 | goto out_err; | 1014 | goto out_err; |
961 | 1015 | ||
962 | mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type); | 1016 | if (!intel_private.driver->check_flags(type)) |
963 | |||
964 | if (mask_type != 0 && mask_type != AGP_PHYS_MEMORY && | ||
965 | mask_type != INTEL_AGP_CACHED_MEMORY) | ||
966 | goto out_err; | 1017 | goto out_err; |
967 | 1018 | ||
968 | if (!mem->is_flushed) | 1019 | if (!mem->is_flushed) |
969 | global_cache_flush(); | 1020 | global_cache_flush(); |
970 | 1021 | ||
971 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 1022 | if (USE_PCI_DMA_API && INTEL_GTT_GEN > 2) { |
972 | writel(agp_bridge->driver->mask_memory(agp_bridge, | 1023 | ret = intel_agp_map_memory(mem); |
973 | page_to_phys(mem->pages[i]), mask_type), | 1024 | if (ret != 0) |
974 | intel_private.registers+I810_PTE_BASE+(j*4)); | 1025 | return ret; |
1026 | |||
1027 | intel_gtt_insert_sg_entries(mem->sg_list, mem->num_sg, | ||
1028 | pg_start, type); | ||
1029 | } else { | ||
1030 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | ||
1031 | dma_addr_t addr = page_to_phys(mem->pages[i]); | ||
1032 | intel_private.driver->write_entry(addr, | ||
1033 | j, type); | ||
1034 | } | ||
1035 | readl(intel_private.gtt+j-1); | ||
975 | } | 1036 | } |
976 | readl(intel_private.registers+I810_PTE_BASE+((j-1)*4)); | ||
977 | 1037 | ||
978 | out: | 1038 | out: |
979 | ret = 0; | 1039 | ret = 0; |
@@ -982,29 +1042,39 @@ out_err: | |||
982 | return ret; | 1042 | return ret; |
983 | } | 1043 | } |
984 | 1044 | ||
985 | static int intel_i830_remove_entries(struct agp_memory *mem, off_t pg_start, | 1045 | static int intel_fake_agp_remove_entries(struct agp_memory *mem, |
986 | int type) | 1046 | off_t pg_start, int type) |
987 | { | 1047 | { |
988 | int i; | 1048 | int i; |
989 | 1049 | ||
990 | if (mem->page_count == 0) | 1050 | if (mem->page_count == 0) |
991 | return 0; | 1051 | return 0; |
992 | 1052 | ||
993 | if (pg_start < intel_private.gtt_entries) { | 1053 | if (pg_start < intel_private.base.gtt_stolen_entries) { |
994 | dev_info(&intel_private.pcidev->dev, | 1054 | dev_info(&intel_private.pcidev->dev, |
995 | "trying to disable local/stolen memory\n"); | 1055 | "trying to disable local/stolen memory\n"); |
996 | return -EINVAL; | 1056 | return -EINVAL; |
997 | } | 1057 | } |
998 | 1058 | ||
1059 | if (USE_PCI_DMA_API && INTEL_GTT_GEN > 2) | ||
1060 | intel_agp_unmap_memory(mem); | ||
1061 | |||
999 | for (i = pg_start; i < (mem->page_count + pg_start); i++) { | 1062 | for (i = pg_start; i < (mem->page_count + pg_start); i++) { |
1000 | writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4)); | 1063 | intel_private.driver->write_entry(intel_private.scratch_page_dma, |
1064 | i, 0); | ||
1001 | } | 1065 | } |
1002 | readl(intel_private.registers+I810_PTE_BASE+((i-1)*4)); | 1066 | readl(intel_private.gtt+i-1); |
1003 | 1067 | ||
1004 | return 0; | 1068 | return 0; |
1005 | } | 1069 | } |
1006 | 1070 | ||
1007 | static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count, int type) | 1071 | static void intel_fake_agp_chipset_flush(struct agp_bridge_data *bridge) |
1072 | { | ||
1073 | intel_private.driver->chipset_flush(); | ||
1074 | } | ||
1075 | |||
1076 | static struct agp_memory *intel_fake_agp_alloc_by_type(size_t pg_count, | ||
1077 | int type) | ||
1008 | { | 1078 | { |
1009 | if (type == AGP_PHYS_MEMORY) | 1079 | if (type == AGP_PHYS_MEMORY) |
1010 | return alloc_agpphysmem_i8xx(pg_count, type); | 1080 | return alloc_agpphysmem_i8xx(pg_count, type); |
@@ -1015,9 +1085,9 @@ static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count, int type) | |||
1015 | static int intel_alloc_chipset_flush_resource(void) | 1085 | static int intel_alloc_chipset_flush_resource(void) |
1016 | { | 1086 | { |
1017 | int ret; | 1087 | int ret; |
1018 | ret = pci_bus_alloc_resource(agp_bridge->dev->bus, &intel_private.ifp_resource, PAGE_SIZE, | 1088 | ret = pci_bus_alloc_resource(intel_private.bridge_dev->bus, &intel_private.ifp_resource, PAGE_SIZE, |
1019 | PAGE_SIZE, PCIBIOS_MIN_MEM, 0, | 1089 | PAGE_SIZE, PCIBIOS_MIN_MEM, 0, |
1020 | pcibios_align_resource, agp_bridge->dev); | 1090 | pcibios_align_resource, intel_private.bridge_dev); |
1021 | 1091 | ||
1022 | return ret; | 1092 | return ret; |
1023 | } | 1093 | } |
@@ -1027,11 +1097,11 @@ static void intel_i915_setup_chipset_flush(void) | |||
1027 | int ret; | 1097 | int ret; |
1028 | u32 temp; | 1098 | u32 temp; |
1029 | 1099 | ||
1030 | pci_read_config_dword(agp_bridge->dev, I915_IFPADDR, &temp); | 1100 | pci_read_config_dword(intel_private.bridge_dev, I915_IFPADDR, &temp); |
1031 | if (!(temp & 0x1)) { | 1101 | if (!(temp & 0x1)) { |
1032 | intel_alloc_chipset_flush_resource(); | 1102 | intel_alloc_chipset_flush_resource(); |
1033 | intel_private.resource_valid = 1; | 1103 | intel_private.resource_valid = 1; |
1034 | pci_write_config_dword(agp_bridge->dev, I915_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1); | 1104 | pci_write_config_dword(intel_private.bridge_dev, I915_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1); |
1035 | } else { | 1105 | } else { |
1036 | temp &= ~1; | 1106 | temp &= ~1; |
1037 | 1107 | ||
@@ -1050,17 +1120,17 @@ static void intel_i965_g33_setup_chipset_flush(void) | |||
1050 | u32 temp_hi, temp_lo; | 1120 | u32 temp_hi, temp_lo; |
1051 | int ret; | 1121 | int ret; |
1052 | 1122 | ||
1053 | pci_read_config_dword(agp_bridge->dev, I965_IFPADDR + 4, &temp_hi); | 1123 | pci_read_config_dword(intel_private.bridge_dev, I965_IFPADDR + 4, &temp_hi); |
1054 | pci_read_config_dword(agp_bridge->dev, I965_IFPADDR, &temp_lo); | 1124 | pci_read_config_dword(intel_private.bridge_dev, I965_IFPADDR, &temp_lo); |
1055 | 1125 | ||
1056 | if (!(temp_lo & 0x1)) { | 1126 | if (!(temp_lo & 0x1)) { |
1057 | 1127 | ||
1058 | intel_alloc_chipset_flush_resource(); | 1128 | intel_alloc_chipset_flush_resource(); |
1059 | 1129 | ||
1060 | intel_private.resource_valid = 1; | 1130 | intel_private.resource_valid = 1; |
1061 | pci_write_config_dword(agp_bridge->dev, I965_IFPADDR + 4, | 1131 | pci_write_config_dword(intel_private.bridge_dev, I965_IFPADDR + 4, |
1062 | upper_32_bits(intel_private.ifp_resource.start)); | 1132 | upper_32_bits(intel_private.ifp_resource.start)); |
1063 | pci_write_config_dword(agp_bridge->dev, I965_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1); | 1133 | pci_write_config_dword(intel_private.bridge_dev, I965_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1); |
1064 | } else { | 1134 | } else { |
1065 | u64 l64; | 1135 | u64 l64; |
1066 | 1136 | ||
@@ -1083,7 +1153,7 @@ static void intel_i9xx_setup_flush(void) | |||
1083 | if (intel_private.ifp_resource.start) | 1153 | if (intel_private.ifp_resource.start) |
1084 | return; | 1154 | return; |
1085 | 1155 | ||
1086 | if (IS_SNB) | 1156 | if (INTEL_GTT_GEN == 6) |
1087 | return; | 1157 | return; |
1088 | 1158 | ||
1089 | /* setup a resource for this object */ | 1159 | /* setup a resource for this object */ |
@@ -1091,7 +1161,7 @@ static void intel_i9xx_setup_flush(void) | |||
1091 | intel_private.ifp_resource.flags = IORESOURCE_MEM; | 1161 | intel_private.ifp_resource.flags = IORESOURCE_MEM; |
1092 | 1162 | ||
1093 | /* Setup chipset flush for 915 */ | 1163 | /* Setup chipset flush for 915 */ |
1094 | if (IS_I965 || IS_G33 || IS_G4X) { | 1164 | if (IS_G33 || INTEL_GTT_GEN >= 4) { |
1095 | intel_i965_g33_setup_chipset_flush(); | 1165 | intel_i965_g33_setup_chipset_flush(); |
1096 | } else { | 1166 | } else { |
1097 | intel_i915_setup_chipset_flush(); | 1167 | intel_i915_setup_chipset_flush(); |
@@ -1104,41 +1174,7 @@ static void intel_i9xx_setup_flush(void) | |||
1104 | "can't ioremap flush page - no chipset flushing\n"); | 1174 | "can't ioremap flush page - no chipset flushing\n"); |
1105 | } | 1175 | } |
1106 | 1176 | ||
1107 | static int intel_i9xx_configure(void) | 1177 | static void i9xx_cleanup(void) |
1108 | { | ||
1109 | struct aper_size_info_fixed *current_size; | ||
1110 | u32 temp; | ||
1111 | u16 gmch_ctrl; | ||
1112 | int i; | ||
1113 | |||
1114 | current_size = A_SIZE_FIX(agp_bridge->current_size); | ||
1115 | |||
1116 | pci_read_config_dword(intel_private.pcidev, I915_GMADDR, &temp); | ||
1117 | |||
1118 | agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); | ||
1119 | |||
1120 | pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); | ||
1121 | gmch_ctrl |= I830_GMCH_ENABLED; | ||
1122 | pci_write_config_word(agp_bridge->dev, I830_GMCH_CTRL, gmch_ctrl); | ||
1123 | |||
1124 | writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL); | ||
1125 | readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */ | ||
1126 | |||
1127 | if (agp_bridge->driver->needs_scratch_page) { | ||
1128 | for (i = intel_private.gtt_entries; i < intel_private.gtt_total_size; i++) { | ||
1129 | writel(agp_bridge->scratch_page, intel_private.gtt+i); | ||
1130 | } | ||
1131 | readl(intel_private.gtt+i-1); /* PCI Posting. */ | ||
1132 | } | ||
1133 | |||
1134 | global_cache_flush(); | ||
1135 | |||
1136 | intel_i9xx_setup_flush(); | ||
1137 | |||
1138 | return 0; | ||
1139 | } | ||
1140 | |||
1141 | static void intel_i915_cleanup(void) | ||
1142 | { | 1178 | { |
1143 | if (intel_private.i9xx_flush_page) | 1179 | if (intel_private.i9xx_flush_page) |
1144 | iounmap(intel_private.i9xx_flush_page); | 1180 | iounmap(intel_private.i9xx_flush_page); |
@@ -1146,320 +1182,93 @@ static void intel_i915_cleanup(void) | |||
1146 | release_resource(&intel_private.ifp_resource); | 1182 | release_resource(&intel_private.ifp_resource); |
1147 | intel_private.ifp_resource.start = 0; | 1183 | intel_private.ifp_resource.start = 0; |
1148 | intel_private.resource_valid = 0; | 1184 | intel_private.resource_valid = 0; |
1149 | iounmap(intel_private.gtt); | ||
1150 | iounmap(intel_private.registers); | ||
1151 | } | 1185 | } |
1152 | 1186 | ||
1153 | static void intel_i915_chipset_flush(struct agp_bridge_data *bridge) | 1187 | static void i9xx_chipset_flush(void) |
1154 | { | 1188 | { |
1155 | if (intel_private.i9xx_flush_page) | 1189 | if (intel_private.i9xx_flush_page) |
1156 | writel(1, intel_private.i9xx_flush_page); | 1190 | writel(1, intel_private.i9xx_flush_page); |
1157 | } | 1191 | } |
1158 | 1192 | ||
1159 | static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start, | 1193 | static void i965_write_entry(dma_addr_t addr, unsigned int entry, |
1160 | int type) | 1194 | unsigned int flags) |
1161 | { | 1195 | { |
1162 | int num_entries; | 1196 | /* Shift high bits down */ |
1163 | void *temp; | 1197 | addr |= (addr >> 28) & 0xf0; |
1164 | int ret = -EINVAL; | 1198 | writel(addr | I810_PTE_VALID, intel_private.gtt + entry); |
1165 | int mask_type; | ||
1166 | |||
1167 | if (mem->page_count == 0) | ||
1168 | goto out; | ||
1169 | |||
1170 | temp = agp_bridge->current_size; | ||
1171 | num_entries = A_SIZE_FIX(temp)->num_entries; | ||
1172 | |||
1173 | if (pg_start < intel_private.gtt_entries) { | ||
1174 | dev_printk(KERN_DEBUG, &intel_private.pcidev->dev, | ||
1175 | "pg_start == 0x%.8lx, intel_private.gtt_entries == 0x%.8x\n", | ||
1176 | pg_start, intel_private.gtt_entries); | ||
1177 | |||
1178 | dev_info(&intel_private.pcidev->dev, | ||
1179 | "trying to insert into local/stolen memory\n"); | ||
1180 | goto out_err; | ||
1181 | } | ||
1182 | |||
1183 | if ((pg_start + mem->page_count) > num_entries) | ||
1184 | goto out_err; | ||
1185 | |||
1186 | /* The i915 can't check the GTT for entries since it's read only; | ||
1187 | * depend on the caller to make the correct offset decisions. | ||
1188 | */ | ||
1189 | |||
1190 | if (type != mem->type) | ||
1191 | goto out_err; | ||
1192 | |||
1193 | mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type); | ||
1194 | |||
1195 | if (!IS_SNB && mask_type != 0 && mask_type != AGP_PHYS_MEMORY && | ||
1196 | mask_type != INTEL_AGP_CACHED_MEMORY) | ||
1197 | goto out_err; | ||
1198 | |||
1199 | if (!mem->is_flushed) | ||
1200 | global_cache_flush(); | ||
1201 | |||
1202 | intel_agp_insert_sg_entries(mem, pg_start, mask_type); | ||
1203 | |||
1204 | out: | ||
1205 | ret = 0; | ||
1206 | out_err: | ||
1207 | mem->is_flushed = true; | ||
1208 | return ret; | ||
1209 | } | 1199 | } |
1210 | 1200 | ||
1211 | static int intel_i915_remove_entries(struct agp_memory *mem, off_t pg_start, | 1201 | static bool gen6_check_flags(unsigned int flags) |
1212 | int type) | ||
1213 | { | 1202 | { |
1214 | int i; | 1203 | return true; |
1215 | |||
1216 | if (mem->page_count == 0) | ||
1217 | return 0; | ||
1218 | |||
1219 | if (pg_start < intel_private.gtt_entries) { | ||
1220 | dev_info(&intel_private.pcidev->dev, | ||
1221 | "trying to disable local/stolen memory\n"); | ||
1222 | return -EINVAL; | ||
1223 | } | ||
1224 | |||
1225 | for (i = pg_start; i < (mem->page_count + pg_start); i++) | ||
1226 | writel(agp_bridge->scratch_page, intel_private.gtt+i); | ||
1227 | |||
1228 | readl(intel_private.gtt+i-1); | ||
1229 | |||
1230 | return 0; | ||
1231 | } | 1204 | } |
1232 | 1205 | ||
1233 | /* Return the aperture size by just checking the resource length. The effect | 1206 | static void gen6_write_entry(dma_addr_t addr, unsigned int entry, |
1234 | * described in the spec of the MSAC registers is just changing of the | 1207 | unsigned int flags) |
1235 | * resource size. | ||
1236 | */ | ||
1237 | static int intel_i9xx_fetch_size(void) | ||
1238 | { | 1208 | { |
1239 | int num_sizes = ARRAY_SIZE(intel_i830_sizes); | 1209 | unsigned int type_mask = flags & ~AGP_USER_CACHED_MEMORY_GFDT; |
1240 | int aper_size; /* size in megabytes */ | 1210 | unsigned int gfdt = flags & AGP_USER_CACHED_MEMORY_GFDT; |
1241 | int i; | 1211 | u32 pte_flags; |
1242 | |||
1243 | aper_size = pci_resource_len(intel_private.pcidev, 2) / MB(1); | ||
1244 | 1212 | ||
1245 | for (i = 0; i < num_sizes; i++) { | 1213 | if (type_mask == AGP_USER_UNCACHED_MEMORY) |
1246 | if (aper_size == intel_i830_sizes[i].size) { | 1214 | pte_flags = GEN6_PTE_UNCACHED | I810_PTE_VALID; |
1247 | agp_bridge->current_size = intel_i830_sizes + i; | 1215 | else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC) { |
1248 | return aper_size; | 1216 | pte_flags = GEN6_PTE_LLC | I810_PTE_VALID; |
1249 | } | 1217 | if (gfdt) |
1218 | pte_flags |= GEN6_PTE_GFDT; | ||
1219 | } else { /* set 'normal'/'cached' to LLC by default */ | ||
1220 | pte_flags = GEN6_PTE_LLC_MLC | I810_PTE_VALID; | ||
1221 | if (gfdt) | ||
1222 | pte_flags |= GEN6_PTE_GFDT; | ||
1250 | } | 1223 | } |
1251 | 1224 | ||
1252 | return 0; | 1225 | /* gen6 has bit11-4 for physical addr bit39-32 */ |
1226 | addr |= (addr >> 28) & 0xff0; | ||
1227 | writel(addr | pte_flags, intel_private.gtt + entry); | ||
1253 | } | 1228 | } |
1254 | 1229 | ||
1255 | static int intel_i915_get_gtt_size(void) | 1230 | static void gen6_cleanup(void) |
1256 | { | 1231 | { |
1257 | int size; | ||
1258 | |||
1259 | if (IS_G33) { | ||
1260 | u16 gmch_ctrl; | ||
1261 | |||
1262 | /* G33's GTT size defined in gmch_ctrl */ | ||
1263 | pci_read_config_word(agp_bridge->dev, I830_GMCH_CTRL, &gmch_ctrl); | ||
1264 | switch (gmch_ctrl & I830_GMCH_GMS_MASK) { | ||
1265 | case I830_GMCH_GMS_STOLEN_512: | ||
1266 | size = 512; | ||
1267 | break; | ||
1268 | case I830_GMCH_GMS_STOLEN_1024: | ||
1269 | size = 1024; | ||
1270 | break; | ||
1271 | case I830_GMCH_GMS_STOLEN_8192: | ||
1272 | size = 8*1024; | ||
1273 | break; | ||
1274 | default: | ||
1275 | dev_info(&agp_bridge->dev->dev, | ||
1276 | "unknown page table size 0x%x, assuming 512KB\n", | ||
1277 | (gmch_ctrl & I830_GMCH_GMS_MASK)); | ||
1278 | size = 512; | ||
1279 | } | ||
1280 | } else { | ||
1281 | /* On previous hardware, the GTT size was just what was | ||
1282 | * required to map the aperture. | ||
1283 | */ | ||
1284 | size = agp_bridge->driver->fetch_size(); | ||
1285 | } | ||
1286 | |||
1287 | return KB(size); | ||
1288 | } | 1232 | } |
1289 | 1233 | ||
1290 | /* The intel i915 automatically initializes the agp aperture during POST. | 1234 | static int i9xx_setup(void) |
1291 | * Use the memory already set aside for in the GTT. | ||
1292 | */ | ||
1293 | static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) | ||
1294 | { | 1235 | { |
1295 | int page_order; | 1236 | u32 reg_addr; |
1296 | struct aper_size_info_fixed *size; | ||
1297 | int num_entries; | ||
1298 | u32 temp, temp2; | ||
1299 | int gtt_map_size; | ||
1300 | |||
1301 | size = agp_bridge->current_size; | ||
1302 | page_order = size->page_order; | ||
1303 | num_entries = size->num_entries; | ||
1304 | agp_bridge->gatt_table_real = NULL; | ||
1305 | |||
1306 | pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); | ||
1307 | pci_read_config_dword(intel_private.pcidev, I915_PTEADDR, &temp2); | ||
1308 | 1237 | ||
1309 | gtt_map_size = intel_i915_get_gtt_size(); | 1238 | pci_read_config_dword(intel_private.pcidev, I915_MMADDR, ®_addr); |
1310 | |||
1311 | intel_private.gtt = ioremap(temp2, gtt_map_size); | ||
1312 | if (!intel_private.gtt) | ||
1313 | return -ENOMEM; | ||
1314 | |||
1315 | intel_private.gtt_total_size = gtt_map_size / 4; | ||
1316 | |||
1317 | temp &= 0xfff80000; | ||
1318 | |||
1319 | intel_private.registers = ioremap(temp, 128 * 4096); | ||
1320 | if (!intel_private.registers) { | ||
1321 | iounmap(intel_private.gtt); | ||
1322 | return -ENOMEM; | ||
1323 | } | ||
1324 | 1239 | ||
1325 | temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; | 1240 | reg_addr &= 0xfff80000; |
1326 | global_cache_flush(); /* FIXME: ? */ | ||
1327 | 1241 | ||
1328 | /* we have to call this as early as possible after the MMIO base address is known */ | 1242 | intel_private.registers = ioremap(reg_addr, 128 * 4096); |
1329 | intel_i830_init_gtt_entries(); | 1243 | if (!intel_private.registers) |
1330 | if (intel_private.gtt_entries == 0) { | ||
1331 | iounmap(intel_private.gtt); | ||
1332 | iounmap(intel_private.registers); | ||
1333 | return -ENOMEM; | 1244 | return -ENOMEM; |
1334 | } | ||
1335 | |||
1336 | agp_bridge->gatt_table = NULL; | ||
1337 | |||
1338 | agp_bridge->gatt_bus_addr = temp; | ||
1339 | |||
1340 | return 0; | ||
1341 | } | ||
1342 | |||
1343 | /* | ||
1344 | * The i965 supports 36-bit physical addresses, but to keep | ||
1345 | * the format of the GTT the same, the bits that don't fit | ||
1346 | * in a 32-bit word are shifted down to bits 4..7. | ||
1347 | * | ||
1348 | * Gcc is smart enough to notice that "(addr >> 28) & 0xf0" | ||
1349 | * is always zero on 32-bit architectures, so no need to make | ||
1350 | * this conditional. | ||
1351 | */ | ||
1352 | static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge, | ||
1353 | dma_addr_t addr, int type) | ||
1354 | { | ||
1355 | /* Shift high bits down */ | ||
1356 | addr |= (addr >> 28) & 0xf0; | ||
1357 | |||
1358 | /* Type checking must be done elsewhere */ | ||
1359 | return addr | bridge->driver->masks[type].mask; | ||
1360 | } | ||
1361 | 1245 | ||
1362 | static unsigned long intel_gen6_mask_memory(struct agp_bridge_data *bridge, | 1246 | if (INTEL_GTT_GEN == 3) { |
1363 | dma_addr_t addr, int type) | 1247 | u32 gtt_addr; |
1364 | { | ||
1365 | /* gen6 has bit11-4 for physical addr bit39-32 */ | ||
1366 | addr |= (addr >> 28) & 0xff0; | ||
1367 | 1248 | ||
1368 | /* Type checking must be done elsewhere */ | 1249 | pci_read_config_dword(intel_private.pcidev, |
1369 | return addr | bridge->driver->masks[type].mask; | 1250 | I915_PTEADDR, >t_addr); |
1370 | } | 1251 | intel_private.gtt_bus_addr = gtt_addr; |
1371 | 1252 | } else { | |
1372 | static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) | 1253 | u32 gtt_offset; |
1373 | { | ||
1374 | u16 snb_gmch_ctl; | ||
1375 | |||
1376 | switch (agp_bridge->dev->device) { | ||
1377 | case PCI_DEVICE_ID_INTEL_GM45_HB: | ||
1378 | case PCI_DEVICE_ID_INTEL_EAGLELAKE_HB: | ||
1379 | case PCI_DEVICE_ID_INTEL_Q45_HB: | ||
1380 | case PCI_DEVICE_ID_INTEL_G45_HB: | ||
1381 | case PCI_DEVICE_ID_INTEL_G41_HB: | ||
1382 | case PCI_DEVICE_ID_INTEL_B43_HB: | ||
1383 | case PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB: | ||
1384 | case PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB: | ||
1385 | case PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB: | ||
1386 | case PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB: | ||
1387 | *gtt_offset = *gtt_size = MB(2); | ||
1388 | break; | ||
1389 | case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB: | ||
1390 | case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB: | ||
1391 | case PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB: | ||
1392 | *gtt_offset = MB(2); | ||
1393 | 1254 | ||
1394 | pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl); | 1255 | switch (INTEL_GTT_GEN) { |
1395 | switch (snb_gmch_ctl & SNB_GTT_SIZE_MASK) { | 1256 | case 5: |
1396 | default: | 1257 | case 6: |
1397 | case SNB_GTT_SIZE_0M: | 1258 | gtt_offset = MB(2); |
1398 | printk(KERN_ERR "Bad GTT size mask: 0x%04x.\n", snb_gmch_ctl); | ||
1399 | *gtt_size = MB(0); | ||
1400 | break; | 1259 | break; |
1401 | case SNB_GTT_SIZE_1M: | 1260 | case 4: |
1402 | *gtt_size = MB(1); | 1261 | default: |
1403 | break; | 1262 | gtt_offset = KB(512); |
1404 | case SNB_GTT_SIZE_2M: | ||
1405 | *gtt_size = MB(2); | ||
1406 | break; | 1263 | break; |
1407 | } | 1264 | } |
1408 | break; | 1265 | intel_private.gtt_bus_addr = reg_addr + gtt_offset; |
1409 | default: | ||
1410 | *gtt_offset = *gtt_size = KB(512); | ||
1411 | } | 1266 | } |
1412 | } | ||
1413 | |||
1414 | /* The intel i965 automatically initializes the agp aperture during POST. | ||
1415 | * Use the memory already set aside for in the GTT. | ||
1416 | */ | ||
1417 | static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge) | ||
1418 | { | ||
1419 | int page_order; | ||
1420 | struct aper_size_info_fixed *size; | ||
1421 | int num_entries; | ||
1422 | u32 temp; | ||
1423 | int gtt_offset, gtt_size; | ||
1424 | |||
1425 | size = agp_bridge->current_size; | ||
1426 | page_order = size->page_order; | ||
1427 | num_entries = size->num_entries; | ||
1428 | agp_bridge->gatt_table_real = NULL; | ||
1429 | |||
1430 | pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); | ||
1431 | |||
1432 | temp &= 0xfff00000; | ||
1433 | |||
1434 | intel_i965_get_gtt_range(>t_offset, >t_size); | ||
1435 | 1267 | ||
1436 | intel_private.gtt = ioremap((temp + gtt_offset) , gtt_size); | 1268 | intel_private.pte_bus_addr = |
1269 | readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; | ||
1437 | 1270 | ||
1438 | if (!intel_private.gtt) | 1271 | intel_i9xx_setup_flush(); |
1439 | return -ENOMEM; | ||
1440 | |||
1441 | intel_private.gtt_total_size = gtt_size / 4; | ||
1442 | |||
1443 | intel_private.registers = ioremap(temp, 128 * 4096); | ||
1444 | if (!intel_private.registers) { | ||
1445 | iounmap(intel_private.gtt); | ||
1446 | return -ENOMEM; | ||
1447 | } | ||
1448 | |||
1449 | temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; | ||
1450 | global_cache_flush(); /* FIXME: ? */ | ||
1451 | |||
1452 | /* we have to call this as early as possible after the MMIO base address is known */ | ||
1453 | intel_i830_init_gtt_entries(); | ||
1454 | if (intel_private.gtt_entries == 0) { | ||
1455 | iounmap(intel_private.gtt); | ||
1456 | iounmap(intel_private.registers); | ||
1457 | return -ENOMEM; | ||
1458 | } | ||
1459 | |||
1460 | agp_bridge->gatt_table = NULL; | ||
1461 | |||
1462 | agp_bridge->gatt_bus_addr = temp; | ||
1463 | 1272 | ||
1464 | return 0; | 1273 | return 0; |
1465 | } | 1274 | } |
@@ -1475,7 +1284,7 @@ static const struct agp_bridge_driver intel_810_driver = { | |||
1475 | .cleanup = intel_i810_cleanup, | 1284 | .cleanup = intel_i810_cleanup, |
1476 | .mask_memory = intel_i810_mask_memory, | 1285 | .mask_memory = intel_i810_mask_memory, |
1477 | .masks = intel_i810_masks, | 1286 | .masks = intel_i810_masks, |
1478 | .agp_enable = intel_i810_agp_enable, | 1287 | .agp_enable = intel_fake_agp_enable, |
1479 | .cache_flush = global_cache_flush, | 1288 | .cache_flush = global_cache_flush, |
1480 | .create_gatt_table = agp_generic_create_gatt_table, | 1289 | .create_gatt_table = agp_generic_create_gatt_table, |
1481 | .free_gatt_table = agp_generic_free_gatt_table, | 1290 | .free_gatt_table = agp_generic_free_gatt_table, |
@@ -1490,161 +1299,282 @@ static const struct agp_bridge_driver intel_810_driver = { | |||
1490 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, | 1299 | .agp_type_to_mask_type = agp_generic_type_to_mask_type, |
1491 | }; | 1300 | }; |
1492 | 1301 | ||
1493 | static const struct agp_bridge_driver intel_830_driver = { | 1302 | static const struct agp_bridge_driver intel_fake_agp_driver = { |
1494 | .owner = THIS_MODULE, | 1303 | .owner = THIS_MODULE, |
1495 | .aperture_sizes = intel_i830_sizes, | ||
1496 | .size_type = FIXED_APER_SIZE, | 1304 | .size_type = FIXED_APER_SIZE, |
1497 | .num_aperture_sizes = 4, | 1305 | .aperture_sizes = intel_fake_agp_sizes, |
1498 | .needs_scratch_page = true, | 1306 | .num_aperture_sizes = ARRAY_SIZE(intel_fake_agp_sizes), |
1499 | .configure = intel_i830_configure, | 1307 | .configure = intel_fake_agp_configure, |
1500 | .fetch_size = intel_i830_fetch_size, | 1308 | .fetch_size = intel_fake_agp_fetch_size, |
1501 | .cleanup = intel_i830_cleanup, | 1309 | .cleanup = intel_gtt_cleanup, |
1502 | .mask_memory = intel_i810_mask_memory, | 1310 | .agp_enable = intel_fake_agp_enable, |
1503 | .masks = intel_i810_masks, | ||
1504 | .agp_enable = intel_i810_agp_enable, | ||
1505 | .cache_flush = global_cache_flush, | 1311 | .cache_flush = global_cache_flush, |
1506 | .create_gatt_table = intel_i830_create_gatt_table, | 1312 | .create_gatt_table = intel_fake_agp_create_gatt_table, |
1507 | .free_gatt_table = intel_i830_free_gatt_table, | 1313 | .free_gatt_table = intel_fake_agp_free_gatt_table, |
1508 | .insert_memory = intel_i830_insert_entries, | 1314 | .insert_memory = intel_fake_agp_insert_entries, |
1509 | .remove_memory = intel_i830_remove_entries, | 1315 | .remove_memory = intel_fake_agp_remove_entries, |
1510 | .alloc_by_type = intel_i830_alloc_by_type, | 1316 | .alloc_by_type = intel_fake_agp_alloc_by_type, |
1511 | .free_by_type = intel_i810_free_by_type, | 1317 | .free_by_type = intel_i810_free_by_type, |
1512 | .agp_alloc_page = agp_generic_alloc_page, | 1318 | .agp_alloc_page = agp_generic_alloc_page, |
1513 | .agp_alloc_pages = agp_generic_alloc_pages, | 1319 | .agp_alloc_pages = agp_generic_alloc_pages, |
1514 | .agp_destroy_page = agp_generic_destroy_page, | 1320 | .agp_destroy_page = agp_generic_destroy_page, |
1515 | .agp_destroy_pages = agp_generic_destroy_pages, | 1321 | .agp_destroy_pages = agp_generic_destroy_pages, |
1516 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 1322 | .chipset_flush = intel_fake_agp_chipset_flush, |
1517 | .chipset_flush = intel_i830_chipset_flush, | ||
1518 | }; | 1323 | }; |
1519 | 1324 | ||
1520 | static const struct agp_bridge_driver intel_915_driver = { | 1325 | static const struct intel_gtt_driver i81x_gtt_driver = { |
1521 | .owner = THIS_MODULE, | 1326 | .gen = 1, |
1522 | .aperture_sizes = intel_i830_sizes, | 1327 | .dma_mask_size = 32, |
1523 | .size_type = FIXED_APER_SIZE, | ||
1524 | .num_aperture_sizes = 4, | ||
1525 | .needs_scratch_page = true, | ||
1526 | .configure = intel_i9xx_configure, | ||
1527 | .fetch_size = intel_i9xx_fetch_size, | ||
1528 | .cleanup = intel_i915_cleanup, | ||
1529 | .mask_memory = intel_i810_mask_memory, | ||
1530 | .masks = intel_i810_masks, | ||
1531 | .agp_enable = intel_i810_agp_enable, | ||
1532 | .cache_flush = global_cache_flush, | ||
1533 | .create_gatt_table = intel_i915_create_gatt_table, | ||
1534 | .free_gatt_table = intel_i830_free_gatt_table, | ||
1535 | .insert_memory = intel_i915_insert_entries, | ||
1536 | .remove_memory = intel_i915_remove_entries, | ||
1537 | .alloc_by_type = intel_i830_alloc_by_type, | ||
1538 | .free_by_type = intel_i810_free_by_type, | ||
1539 | .agp_alloc_page = agp_generic_alloc_page, | ||
1540 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1541 | .agp_destroy_page = agp_generic_destroy_page, | ||
1542 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1543 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | ||
1544 | .chipset_flush = intel_i915_chipset_flush, | ||
1545 | #ifdef USE_PCI_DMA_API | ||
1546 | .agp_map_page = intel_agp_map_page, | ||
1547 | .agp_unmap_page = intel_agp_unmap_page, | ||
1548 | .agp_map_memory = intel_agp_map_memory, | ||
1549 | .agp_unmap_memory = intel_agp_unmap_memory, | ||
1550 | #endif | ||
1551 | }; | 1328 | }; |
1552 | 1329 | static const struct intel_gtt_driver i8xx_gtt_driver = { | |
1553 | static const struct agp_bridge_driver intel_i965_driver = { | 1330 | .gen = 2, |
1554 | .owner = THIS_MODULE, | 1331 | .setup = i830_setup, |
1555 | .aperture_sizes = intel_i830_sizes, | 1332 | .cleanup = i830_cleanup, |
1556 | .size_type = FIXED_APER_SIZE, | 1333 | .write_entry = i830_write_entry, |
1557 | .num_aperture_sizes = 4, | 1334 | .dma_mask_size = 32, |
1558 | .needs_scratch_page = true, | 1335 | .check_flags = i830_check_flags, |
1559 | .configure = intel_i9xx_configure, | 1336 | .chipset_flush = i830_chipset_flush, |
1560 | .fetch_size = intel_i9xx_fetch_size, | ||
1561 | .cleanup = intel_i915_cleanup, | ||
1562 | .mask_memory = intel_i965_mask_memory, | ||
1563 | .masks = intel_i810_masks, | ||
1564 | .agp_enable = intel_i810_agp_enable, | ||
1565 | .cache_flush = global_cache_flush, | ||
1566 | .create_gatt_table = intel_i965_create_gatt_table, | ||
1567 | .free_gatt_table = intel_i830_free_gatt_table, | ||
1568 | .insert_memory = intel_i915_insert_entries, | ||
1569 | .remove_memory = intel_i915_remove_entries, | ||
1570 | .alloc_by_type = intel_i830_alloc_by_type, | ||
1571 | .free_by_type = intel_i810_free_by_type, | ||
1572 | .agp_alloc_page = agp_generic_alloc_page, | ||
1573 | .agp_alloc_pages = agp_generic_alloc_pages, | ||
1574 | .agp_destroy_page = agp_generic_destroy_page, | ||
1575 | .agp_destroy_pages = agp_generic_destroy_pages, | ||
1576 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | ||
1577 | .chipset_flush = intel_i915_chipset_flush, | ||
1578 | #ifdef USE_PCI_DMA_API | ||
1579 | .agp_map_page = intel_agp_map_page, | ||
1580 | .agp_unmap_page = intel_agp_unmap_page, | ||
1581 | .agp_map_memory = intel_agp_map_memory, | ||
1582 | .agp_unmap_memory = intel_agp_unmap_memory, | ||
1583 | #endif | ||
1584 | }; | 1337 | }; |
1585 | 1338 | static const struct intel_gtt_driver i915_gtt_driver = { | |
1586 | static const struct agp_bridge_driver intel_gen6_driver = { | 1339 | .gen = 3, |
1587 | .owner = THIS_MODULE, | 1340 | .setup = i9xx_setup, |
1588 | .aperture_sizes = intel_i830_sizes, | 1341 | .cleanup = i9xx_cleanup, |
1589 | .size_type = FIXED_APER_SIZE, | 1342 | /* i945 is the last gpu to need phys mem (for overlay and cursors). */ |
1590 | .num_aperture_sizes = 4, | 1343 | .write_entry = i830_write_entry, |
1591 | .needs_scratch_page = true, | 1344 | .dma_mask_size = 32, |
1592 | .configure = intel_i9xx_configure, | 1345 | .check_flags = i830_check_flags, |
1593 | .fetch_size = intel_i9xx_fetch_size, | 1346 | .chipset_flush = i9xx_chipset_flush, |
1594 | .cleanup = intel_i915_cleanup, | 1347 | }; |
1595 | .mask_memory = intel_gen6_mask_memory, | 1348 | static const struct intel_gtt_driver g33_gtt_driver = { |
1596 | .masks = intel_gen6_masks, | 1349 | .gen = 3, |
1597 | .agp_enable = intel_i810_agp_enable, | 1350 | .is_g33 = 1, |
1598 | .cache_flush = global_cache_flush, | 1351 | .setup = i9xx_setup, |
1599 | .create_gatt_table = intel_i965_create_gatt_table, | 1352 | .cleanup = i9xx_cleanup, |
1600 | .free_gatt_table = intel_i830_free_gatt_table, | 1353 | .write_entry = i965_write_entry, |
1601 | .insert_memory = intel_i915_insert_entries, | 1354 | .dma_mask_size = 36, |
1602 | .remove_memory = intel_i915_remove_entries, | 1355 | .check_flags = i830_check_flags, |
1603 | .alloc_by_type = intel_i830_alloc_by_type, | 1356 | .chipset_flush = i9xx_chipset_flush, |
1604 | .free_by_type = intel_i810_free_by_type, | 1357 | }; |
1605 | .agp_alloc_page = agp_generic_alloc_page, | 1358 | static const struct intel_gtt_driver pineview_gtt_driver = { |
1606 | .agp_alloc_pages = agp_generic_alloc_pages, | 1359 | .gen = 3, |
1607 | .agp_destroy_page = agp_generic_destroy_page, | 1360 | .is_pineview = 1, .is_g33 = 1, |
1608 | .agp_destroy_pages = agp_generic_destroy_pages, | 1361 | .setup = i9xx_setup, |
1609 | .agp_type_to_mask_type = intel_gen6_type_to_mask_type, | 1362 | .cleanup = i9xx_cleanup, |
1610 | .chipset_flush = intel_i915_chipset_flush, | 1363 | .write_entry = i965_write_entry, |
1611 | #ifdef USE_PCI_DMA_API | 1364 | .dma_mask_size = 36, |
1612 | .agp_map_page = intel_agp_map_page, | 1365 | .check_flags = i830_check_flags, |
1613 | .agp_unmap_page = intel_agp_unmap_page, | 1366 | .chipset_flush = i9xx_chipset_flush, |
1614 | .agp_map_memory = intel_agp_map_memory, | 1367 | }; |
1615 | .agp_unmap_memory = intel_agp_unmap_memory, | 1368 | static const struct intel_gtt_driver i965_gtt_driver = { |
1616 | #endif | 1369 | .gen = 4, |
1370 | .setup = i9xx_setup, | ||
1371 | .cleanup = i9xx_cleanup, | ||
1372 | .write_entry = i965_write_entry, | ||
1373 | .dma_mask_size = 36, | ||
1374 | .check_flags = i830_check_flags, | ||
1375 | .chipset_flush = i9xx_chipset_flush, | ||
1376 | }; | ||
1377 | static const struct intel_gtt_driver g4x_gtt_driver = { | ||
1378 | .gen = 5, | ||
1379 | .setup = i9xx_setup, | ||
1380 | .cleanup = i9xx_cleanup, | ||
1381 | .write_entry = i965_write_entry, | ||
1382 | .dma_mask_size = 36, | ||
1383 | .check_flags = i830_check_flags, | ||
1384 | .chipset_flush = i9xx_chipset_flush, | ||
1385 | }; | ||
1386 | static const struct intel_gtt_driver ironlake_gtt_driver = { | ||
1387 | .gen = 5, | ||
1388 | .is_ironlake = 1, | ||
1389 | .setup = i9xx_setup, | ||
1390 | .cleanup = i9xx_cleanup, | ||
1391 | .write_entry = i965_write_entry, | ||
1392 | .dma_mask_size = 36, | ||
1393 | .check_flags = i830_check_flags, | ||
1394 | .chipset_flush = i9xx_chipset_flush, | ||
1395 | }; | ||
1396 | static const struct intel_gtt_driver sandybridge_gtt_driver = { | ||
1397 | .gen = 6, | ||
1398 | .setup = i9xx_setup, | ||
1399 | .cleanup = gen6_cleanup, | ||
1400 | .write_entry = gen6_write_entry, | ||
1401 | .dma_mask_size = 40, | ||
1402 | .check_flags = gen6_check_flags, | ||
1403 | .chipset_flush = i9xx_chipset_flush, | ||
1617 | }; | 1404 | }; |
1618 | 1405 | ||
1619 | static const struct agp_bridge_driver intel_g33_driver = { | 1406 | /* Table to describe Intel GMCH and AGP/PCIE GART drivers. At least one of |
1620 | .owner = THIS_MODULE, | 1407 | * driver and gmch_driver must be non-null, and find_gmch will determine |
1621 | .aperture_sizes = intel_i830_sizes, | 1408 | * which one should be used if a gmch_chip_id is present. |
1622 | .size_type = FIXED_APER_SIZE, | 1409 | */ |
1623 | .num_aperture_sizes = 4, | 1410 | static const struct intel_gtt_driver_description { |
1624 | .needs_scratch_page = true, | 1411 | unsigned int gmch_chip_id; |
1625 | .configure = intel_i9xx_configure, | 1412 | char *name; |
1626 | .fetch_size = intel_i9xx_fetch_size, | 1413 | const struct agp_bridge_driver *gmch_driver; |
1627 | .cleanup = intel_i915_cleanup, | 1414 | const struct intel_gtt_driver *gtt_driver; |
1628 | .mask_memory = intel_i965_mask_memory, | 1415 | } intel_gtt_chipsets[] = { |
1629 | .masks = intel_i810_masks, | 1416 | { PCI_DEVICE_ID_INTEL_82810_IG1, "i810", &intel_810_driver, |
1630 | .agp_enable = intel_i810_agp_enable, | 1417 | &i81x_gtt_driver}, |
1631 | .cache_flush = global_cache_flush, | 1418 | { PCI_DEVICE_ID_INTEL_82810_IG3, "i810", &intel_810_driver, |
1632 | .create_gatt_table = intel_i915_create_gatt_table, | 1419 | &i81x_gtt_driver}, |
1633 | .free_gatt_table = intel_i830_free_gatt_table, | 1420 | { PCI_DEVICE_ID_INTEL_82810E_IG, "i810", &intel_810_driver, |
1634 | .insert_memory = intel_i915_insert_entries, | 1421 | &i81x_gtt_driver}, |
1635 | .remove_memory = intel_i915_remove_entries, | 1422 | { PCI_DEVICE_ID_INTEL_82815_CGC, "i815", &intel_810_driver, |
1636 | .alloc_by_type = intel_i830_alloc_by_type, | 1423 | &i81x_gtt_driver}, |
1637 | .free_by_type = intel_i810_free_by_type, | 1424 | { PCI_DEVICE_ID_INTEL_82830_CGC, "830M", |
1638 | .agp_alloc_page = agp_generic_alloc_page, | 1425 | &intel_fake_agp_driver, &i8xx_gtt_driver}, |
1639 | .agp_alloc_pages = agp_generic_alloc_pages, | 1426 | { PCI_DEVICE_ID_INTEL_82845G_IG, "830M", |
1640 | .agp_destroy_page = agp_generic_destroy_page, | 1427 | &intel_fake_agp_driver, &i8xx_gtt_driver}, |
1641 | .agp_destroy_pages = agp_generic_destroy_pages, | 1428 | { PCI_DEVICE_ID_INTEL_82854_IG, "854", |
1642 | .agp_type_to_mask_type = intel_i830_type_to_mask_type, | 1429 | &intel_fake_agp_driver, &i8xx_gtt_driver}, |
1643 | .chipset_flush = intel_i915_chipset_flush, | 1430 | { PCI_DEVICE_ID_INTEL_82855GM_IG, "855GM", |
1644 | #ifdef USE_PCI_DMA_API | 1431 | &intel_fake_agp_driver, &i8xx_gtt_driver}, |
1645 | .agp_map_page = intel_agp_map_page, | 1432 | { PCI_DEVICE_ID_INTEL_82865_IG, "865", |
1646 | .agp_unmap_page = intel_agp_unmap_page, | 1433 | &intel_fake_agp_driver, &i8xx_gtt_driver}, |
1647 | .agp_map_memory = intel_agp_map_memory, | 1434 | { PCI_DEVICE_ID_INTEL_E7221_IG, "E7221 (i915)", |
1648 | .agp_unmap_memory = intel_agp_unmap_memory, | 1435 | &intel_fake_agp_driver, &i915_gtt_driver }, |
1649 | #endif | 1436 | { PCI_DEVICE_ID_INTEL_82915G_IG, "915G", |
1437 | &intel_fake_agp_driver, &i915_gtt_driver }, | ||
1438 | { PCI_DEVICE_ID_INTEL_82915GM_IG, "915GM", | ||
1439 | &intel_fake_agp_driver, &i915_gtt_driver }, | ||
1440 | { PCI_DEVICE_ID_INTEL_82945G_IG, "945G", | ||
1441 | &intel_fake_agp_driver, &i915_gtt_driver }, | ||
1442 | { PCI_DEVICE_ID_INTEL_82945GM_IG, "945GM", | ||
1443 | &intel_fake_agp_driver, &i915_gtt_driver }, | ||
1444 | { PCI_DEVICE_ID_INTEL_82945GME_IG, "945GME", | ||
1445 | &intel_fake_agp_driver, &i915_gtt_driver }, | ||
1446 | { PCI_DEVICE_ID_INTEL_82946GZ_IG, "946GZ", | ||
1447 | &intel_fake_agp_driver, &i965_gtt_driver }, | ||
1448 | { PCI_DEVICE_ID_INTEL_82G35_IG, "G35", | ||
1449 | &intel_fake_agp_driver, &i965_gtt_driver }, | ||
1450 | { PCI_DEVICE_ID_INTEL_82965Q_IG, "965Q", | ||
1451 | &intel_fake_agp_driver, &i965_gtt_driver }, | ||
1452 | { PCI_DEVICE_ID_INTEL_82965G_IG, "965G", | ||
1453 | &intel_fake_agp_driver, &i965_gtt_driver }, | ||
1454 | { PCI_DEVICE_ID_INTEL_82965GM_IG, "965GM", | ||
1455 | &intel_fake_agp_driver, &i965_gtt_driver }, | ||
1456 | { PCI_DEVICE_ID_INTEL_82965GME_IG, "965GME/GLE", | ||
1457 | &intel_fake_agp_driver, &i965_gtt_driver }, | ||
1458 | { PCI_DEVICE_ID_INTEL_G33_IG, "G33", | ||
1459 | &intel_fake_agp_driver, &g33_gtt_driver }, | ||
1460 | { PCI_DEVICE_ID_INTEL_Q35_IG, "Q35", | ||
1461 | &intel_fake_agp_driver, &g33_gtt_driver }, | ||
1462 | { PCI_DEVICE_ID_INTEL_Q33_IG, "Q33", | ||
1463 | &intel_fake_agp_driver, &g33_gtt_driver }, | ||
1464 | { PCI_DEVICE_ID_INTEL_PINEVIEW_M_IG, "GMA3150", | ||
1465 | &intel_fake_agp_driver, &pineview_gtt_driver }, | ||
1466 | { PCI_DEVICE_ID_INTEL_PINEVIEW_IG, "GMA3150", | ||
1467 | &intel_fake_agp_driver, &pineview_gtt_driver }, | ||
1468 | { PCI_DEVICE_ID_INTEL_GM45_IG, "GM45", | ||
1469 | &intel_fake_agp_driver, &g4x_gtt_driver }, | ||
1470 | { PCI_DEVICE_ID_INTEL_EAGLELAKE_IG, "Eaglelake", | ||
1471 | &intel_fake_agp_driver, &g4x_gtt_driver }, | ||
1472 | { PCI_DEVICE_ID_INTEL_Q45_IG, "Q45/Q43", | ||
1473 | &intel_fake_agp_driver, &g4x_gtt_driver }, | ||
1474 | { PCI_DEVICE_ID_INTEL_G45_IG, "G45/G43", | ||
1475 | &intel_fake_agp_driver, &g4x_gtt_driver }, | ||
1476 | { PCI_DEVICE_ID_INTEL_B43_IG, "B43", | ||
1477 | &intel_fake_agp_driver, &g4x_gtt_driver }, | ||
1478 | { PCI_DEVICE_ID_INTEL_B43_1_IG, "B43", | ||
1479 | &intel_fake_agp_driver, &g4x_gtt_driver }, | ||
1480 | { PCI_DEVICE_ID_INTEL_G41_IG, "G41", | ||
1481 | &intel_fake_agp_driver, &g4x_gtt_driver }, | ||
1482 | { PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG, | ||
1483 | "HD Graphics", &intel_fake_agp_driver, &ironlake_gtt_driver }, | ||
1484 | { PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, | ||
1485 | "HD Graphics", &intel_fake_agp_driver, &ironlake_gtt_driver }, | ||
1486 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT1_IG, | ||
1487 | "Sandybridge", &intel_fake_agp_driver, &sandybridge_gtt_driver }, | ||
1488 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_IG, | ||
1489 | "Sandybridge", &intel_fake_agp_driver, &sandybridge_gtt_driver }, | ||
1490 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_PLUS_IG, | ||
1491 | "Sandybridge", &intel_fake_agp_driver, &sandybridge_gtt_driver }, | ||
1492 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT1_IG, | ||
1493 | "Sandybridge", &intel_fake_agp_driver, &sandybridge_gtt_driver }, | ||
1494 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_IG, | ||
1495 | "Sandybridge", &intel_fake_agp_driver, &sandybridge_gtt_driver }, | ||
1496 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_PLUS_IG, | ||
1497 | "Sandybridge", &intel_fake_agp_driver, &sandybridge_gtt_driver }, | ||
1498 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG, | ||
1499 | "Sandybridge", &intel_fake_agp_driver, &sandybridge_gtt_driver }, | ||
1500 | { 0, NULL, NULL } | ||
1650 | }; | 1501 | }; |
1502 | |||
1503 | static int find_gmch(u16 device) | ||
1504 | { | ||
1505 | struct pci_dev *gmch_device; | ||
1506 | |||
1507 | gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL); | ||
1508 | if (gmch_device && PCI_FUNC(gmch_device->devfn) != 0) { | ||
1509 | gmch_device = pci_get_device(PCI_VENDOR_ID_INTEL, | ||
1510 | device, gmch_device); | ||
1511 | } | ||
1512 | |||
1513 | if (!gmch_device) | ||
1514 | return 0; | ||
1515 | |||
1516 | intel_private.pcidev = gmch_device; | ||
1517 | return 1; | ||
1518 | } | ||
1519 | |||
1520 | int intel_gmch_probe(struct pci_dev *pdev, | ||
1521 | struct agp_bridge_data *bridge) | ||
1522 | { | ||
1523 | int i, mask; | ||
1524 | bridge->driver = NULL; | ||
1525 | |||
1526 | for (i = 0; intel_gtt_chipsets[i].name != NULL; i++) { | ||
1527 | if (find_gmch(intel_gtt_chipsets[i].gmch_chip_id)) { | ||
1528 | bridge->driver = | ||
1529 | intel_gtt_chipsets[i].gmch_driver; | ||
1530 | intel_private.driver = | ||
1531 | intel_gtt_chipsets[i].gtt_driver; | ||
1532 | break; | ||
1533 | } | ||
1534 | } | ||
1535 | |||
1536 | if (!bridge->driver) | ||
1537 | return 0; | ||
1538 | |||
1539 | bridge->dev_private_data = &intel_private; | ||
1540 | bridge->dev = pdev; | ||
1541 | |||
1542 | intel_private.bridge_dev = pci_dev_get(pdev); | ||
1543 | |||
1544 | dev_info(&pdev->dev, "Intel %s Chipset\n", intel_gtt_chipsets[i].name); | ||
1545 | |||
1546 | mask = intel_private.driver->dma_mask_size; | ||
1547 | if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(mask))) | ||
1548 | dev_err(&intel_private.pcidev->dev, | ||
1549 | "set gfx device dma mask %d-bit failed!\n", mask); | ||
1550 | else | ||
1551 | pci_set_consistent_dma_mask(intel_private.pcidev, | ||
1552 | DMA_BIT_MASK(mask)); | ||
1553 | |||
1554 | if (bridge->driver == &intel_810_driver) | ||
1555 | return 1; | ||
1556 | |||
1557 | if (intel_gtt_init() != 0) | ||
1558 | return 0; | ||
1559 | |||
1560 | return 1; | ||
1561 | } | ||
1562 | EXPORT_SYMBOL(intel_gmch_probe); | ||
1563 | |||
1564 | struct intel_gtt *intel_gtt_get(void) | ||
1565 | { | ||
1566 | return &intel_private.base; | ||
1567 | } | ||
1568 | EXPORT_SYMBOL(intel_gtt_get); | ||
1569 | |||
1570 | void intel_gmch_remove(struct pci_dev *pdev) | ||
1571 | { | ||
1572 | if (intel_private.pcidev) | ||
1573 | pci_dev_put(intel_private.pcidev); | ||
1574 | if (intel_private.bridge_dev) | ||
1575 | pci_dev_put(intel_private.bridge_dev); | ||
1576 | } | ||
1577 | EXPORT_SYMBOL(intel_gmch_remove); | ||
1578 | |||
1579 | MODULE_AUTHOR("Dave Jones <davej@redhat.com>"); | ||
1580 | MODULE_LICENSE("GPL and additional rights"); | ||
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index a11c8c9ca3d4..b0a70461a12c 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
@@ -1263,6 +1263,36 @@ static int rs_break(struct tty_struct *tty, int break_state) | |||
1263 | return 0; | 1263 | return 0; |
1264 | } | 1264 | } |
1265 | 1265 | ||
1266 | /* | ||
1267 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
1268 | * Return: write counters to the user passed counter struct | ||
1269 | * NB: both 1->0 and 0->1 transitions are counted except for | ||
1270 | * RI where only 0->1 is counted. | ||
1271 | */ | ||
1272 | static int rs_get_icount(struct tty_struct *tty, | ||
1273 | struct serial_icounter_struct *icount) | ||
1274 | { | ||
1275 | struct async_struct *info = tty->driver_data; | ||
1276 | struct async_icount cnow; | ||
1277 | unsigned long flags; | ||
1278 | |||
1279 | local_irq_save(flags); | ||
1280 | cnow = info->state->icount; | ||
1281 | local_irq_restore(flags); | ||
1282 | icount->cts = cnow.cts; | ||
1283 | icount->dsr = cnow.dsr; | ||
1284 | icount->rng = cnow.rng; | ||
1285 | icount->dcd = cnow.dcd; | ||
1286 | icount->rx = cnow.rx; | ||
1287 | icount->tx = cnow.tx; | ||
1288 | icount->frame = cnow.frame; | ||
1289 | icount->overrun = cnow.overrun; | ||
1290 | icount->parity = cnow.parity; | ||
1291 | icount->brk = cnow.brk; | ||
1292 | icount->buf_overrun = cnow.buf_overrun; | ||
1293 | |||
1294 | return 0; | ||
1295 | } | ||
1266 | 1296 | ||
1267 | static int rs_ioctl(struct tty_struct *tty, struct file * file, | 1297 | static int rs_ioctl(struct tty_struct *tty, struct file * file, |
1268 | unsigned int cmd, unsigned long arg) | 1298 | unsigned int cmd, unsigned long arg) |
@@ -1332,31 +1362,6 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, | |||
1332 | } | 1362 | } |
1333 | /* NOTREACHED */ | 1363 | /* NOTREACHED */ |
1334 | 1364 | ||
1335 | /* | ||
1336 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
1337 | * Return: write counters to the user passed counter struct | ||
1338 | * NB: both 1->0 and 0->1 transitions are counted except for | ||
1339 | * RI where only 0->1 is counted. | ||
1340 | */ | ||
1341 | case TIOCGICOUNT: | ||
1342 | local_irq_save(flags); | ||
1343 | cnow = info->state->icount; | ||
1344 | local_irq_restore(flags); | ||
1345 | icount.cts = cnow.cts; | ||
1346 | icount.dsr = cnow.dsr; | ||
1347 | icount.rng = cnow.rng; | ||
1348 | icount.dcd = cnow.dcd; | ||
1349 | icount.rx = cnow.rx; | ||
1350 | icount.tx = cnow.tx; | ||
1351 | icount.frame = cnow.frame; | ||
1352 | icount.overrun = cnow.overrun; | ||
1353 | icount.parity = cnow.parity; | ||
1354 | icount.brk = cnow.brk; | ||
1355 | icount.buf_overrun = cnow.buf_overrun; | ||
1356 | |||
1357 | if (copy_to_user(argp, &icount, sizeof(icount))) | ||
1358 | return -EFAULT; | ||
1359 | return 0; | ||
1360 | case TIOCSERGWILD: | 1365 | case TIOCSERGWILD: |
1361 | case TIOCSERSWILD: | 1366 | case TIOCSERSWILD: |
1362 | /* "setserial -W" is called in Debian boot */ | 1367 | /* "setserial -W" is called in Debian boot */ |
@@ -1958,6 +1963,7 @@ static const struct tty_operations serial_ops = { | |||
1958 | .wait_until_sent = rs_wait_until_sent, | 1963 | .wait_until_sent = rs_wait_until_sent, |
1959 | .tiocmget = rs_tiocmget, | 1964 | .tiocmget = rs_tiocmget, |
1960 | .tiocmset = rs_tiocmset, | 1965 | .tiocmset = rs_tiocmset, |
1966 | .get_icount = rs_get_icount, | ||
1961 | .proc_fops = &rs_proc_fops, | 1967 | .proc_fops = &rs_proc_fops, |
1962 | }; | 1968 | }; |
1963 | 1969 | ||
diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c index 033e1505fca9..45b987c9889e 100644 --- a/drivers/char/apm-emulation.c +++ b/drivers/char/apm-emulation.c | |||
@@ -7,13 +7,13 @@ | |||
7 | * Intel Corporation, Microsoft Corporation. Advanced Power Management | 7 | * Intel Corporation, Microsoft Corporation. Advanced Power Management |
8 | * (APM) BIOS Interface Specification, Revision 1.2, February 1996. | 8 | * (APM) BIOS Interface Specification, Revision 1.2, February 1996. |
9 | * | 9 | * |
10 | * [This document is available from Microsoft at: | 10 | * This document is available from Microsoft at: |
11 | * http://www.microsoft.com/hwdev/busbios/amp_12.htm] | 11 | * http://www.microsoft.com/whdc/archive/amp_12.mspx |
12 | */ | 12 | */ |
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/poll.h> | 14 | #include <linux/poll.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/smp_lock.h> | 16 | #include <linux/mutex.h> |
17 | #include <linux/proc_fs.h> | 17 | #include <linux/proc_fs.h> |
18 | #include <linux/seq_file.h> | 18 | #include <linux/seq_file.h> |
19 | #include <linux/miscdevice.h> | 19 | #include <linux/miscdevice.h> |
@@ -126,6 +126,7 @@ struct apm_user { | |||
126 | /* | 126 | /* |
127 | * Local variables | 127 | * Local variables |
128 | */ | 128 | */ |
129 | static DEFINE_MUTEX(apm_mutex); | ||
129 | static atomic_t suspend_acks_pending = ATOMIC_INIT(0); | 130 | static atomic_t suspend_acks_pending = ATOMIC_INIT(0); |
130 | static atomic_t userspace_notification_inhibit = ATOMIC_INIT(0); | 131 | static atomic_t userspace_notification_inhibit = ATOMIC_INIT(0); |
131 | static int apm_disabled; | 132 | static int apm_disabled; |
@@ -274,7 +275,7 @@ apm_ioctl(struct file *filp, u_int cmd, u_long arg) | |||
274 | if (!as->suser || !as->writer) | 275 | if (!as->suser || !as->writer) |
275 | return -EPERM; | 276 | return -EPERM; |
276 | 277 | ||
277 | lock_kernel(); | 278 | mutex_lock(&apm_mutex); |
278 | switch (cmd) { | 279 | switch (cmd) { |
279 | case APM_IOC_SUSPEND: | 280 | case APM_IOC_SUSPEND: |
280 | mutex_lock(&state_lock); | 281 | mutex_lock(&state_lock); |
@@ -335,7 +336,7 @@ apm_ioctl(struct file *filp, u_int cmd, u_long arg) | |||
335 | mutex_unlock(&state_lock); | 336 | mutex_unlock(&state_lock); |
336 | break; | 337 | break; |
337 | } | 338 | } |
338 | unlock_kernel(); | 339 | mutex_unlock(&apm_mutex); |
339 | 340 | ||
340 | return err; | 341 | return err; |
341 | } | 342 | } |
@@ -370,7 +371,7 @@ static int apm_open(struct inode * inode, struct file * filp) | |||
370 | { | 371 | { |
371 | struct apm_user *as; | 372 | struct apm_user *as; |
372 | 373 | ||
373 | lock_kernel(); | 374 | mutex_lock(&apm_mutex); |
374 | as = kzalloc(sizeof(*as), GFP_KERNEL); | 375 | as = kzalloc(sizeof(*as), GFP_KERNEL); |
375 | if (as) { | 376 | if (as) { |
376 | /* | 377 | /* |
@@ -390,7 +391,7 @@ static int apm_open(struct inode * inode, struct file * filp) | |||
390 | 391 | ||
391 | filp->private_data = as; | 392 | filp->private_data = as; |
392 | } | 393 | } |
393 | unlock_kernel(); | 394 | mutex_unlock(&apm_mutex); |
394 | 395 | ||
395 | return as ? 0 : -ENOMEM; | 396 | return as ? 0 : -ENOMEM; |
396 | } | 397 | } |
@@ -402,6 +403,7 @@ static const struct file_operations apm_bios_fops = { | |||
402 | .unlocked_ioctl = apm_ioctl, | 403 | .unlocked_ioctl = apm_ioctl, |
403 | .open = apm_open, | 404 | .open = apm_open, |
404 | .release = apm_release, | 405 | .release = apm_release, |
406 | .llseek = noop_llseek, | ||
405 | }; | 407 | }; |
406 | 408 | ||
407 | static struct miscdevice apm_device = { | 409 | static struct miscdevice apm_device = { |
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index f4ae0e0fb631..25373df1dcf8 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
29 | #include <linux/smp_lock.h> | 29 | #include <linux/mutex.h> |
30 | #include <linux/miscdevice.h> | 30 | #include <linux/miscdevice.h> |
31 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
32 | #include <linux/wait.h> | 32 | #include <linux/wait.h> |
@@ -60,6 +60,7 @@ | |||
60 | #define PCI_DEVICE_ID_APPLICOM_PCI2000PFB 0x0003 | 60 | #define PCI_DEVICE_ID_APPLICOM_PCI2000PFB 0x0003 |
61 | #endif | 61 | #endif |
62 | 62 | ||
63 | static DEFINE_MUTEX(ac_mutex); | ||
63 | static char *applicom_pci_devnames[] = { | 64 | static char *applicom_pci_devnames[] = { |
64 | "PCI board", | 65 | "PCI board", |
65 | "PCI2000IBS / PCI2000CAN", | 66 | "PCI2000IBS / PCI2000CAN", |
@@ -565,6 +566,7 @@ static ssize_t ac_read (struct file *filp, char __user *buf, size_t count, loff_ | |||
565 | struct mailbox mailbox; | 566 | struct mailbox mailbox; |
566 | 567 | ||
567 | /* Got a packet for us */ | 568 | /* Got a packet for us */ |
569 | memset(&st_loc, 0, sizeof(st_loc)); | ||
568 | ret = do_ac_read(i, buf, &st_loc, &mailbox); | 570 | ret = do_ac_read(i, buf, &st_loc, &mailbox); |
569 | spin_unlock_irqrestore(&apbs[i].mutex, flags); | 571 | spin_unlock_irqrestore(&apbs[i].mutex, flags); |
570 | set_current_state(TASK_RUNNING); | 572 | set_current_state(TASK_RUNNING); |
@@ -707,7 +709,7 @@ static long ac_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
707 | if (IS_ERR(adgl)) | 709 | if (IS_ERR(adgl)) |
708 | return PTR_ERR(adgl); | 710 | return PTR_ERR(adgl); |
709 | 711 | ||
710 | lock_kernel(); | 712 | mutex_lock(&ac_mutex); |
711 | IndexCard = adgl->num_card-1; | 713 | IndexCard = adgl->num_card-1; |
712 | 714 | ||
713 | if(cmd != 6 && ((IndexCard >= MAX_BOARD) || !apbs[IndexCard].RamIO)) { | 715 | if(cmd != 6 && ((IndexCard >= MAX_BOARD) || !apbs[IndexCard].RamIO)) { |
@@ -717,7 +719,7 @@ static long ac_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
717 | warncount--; | 719 | warncount--; |
718 | } | 720 | } |
719 | kfree(adgl); | 721 | kfree(adgl); |
720 | unlock_kernel(); | 722 | mutex_unlock(&ac_mutex); |
721 | return -EINVAL; | 723 | return -EINVAL; |
722 | } | 724 | } |
723 | 725 | ||
@@ -835,7 +837,7 @@ static long ac_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
835 | } | 837 | } |
836 | Dummy = readb(apbs[IndexCard].RamIO + VERS); | 838 | Dummy = readb(apbs[IndexCard].RamIO + VERS); |
837 | kfree(adgl); | 839 | kfree(adgl); |
838 | unlock_kernel(); | 840 | mutex_unlock(&ac_mutex); |
839 | return 0; | 841 | return 0; |
840 | } | 842 | } |
841 | 843 | ||
diff --git a/drivers/char/bfin-otp.c b/drivers/char/bfin-otp.c index 836d4f0a876f..44660f1c4849 100644 --- a/drivers/char/bfin-otp.c +++ b/drivers/char/bfin-otp.c | |||
@@ -222,6 +222,7 @@ static const struct file_operations bfin_otp_fops = { | |||
222 | .unlocked_ioctl = bfin_otp_ioctl, | 222 | .unlocked_ioctl = bfin_otp_ioctl, |
223 | .read = bfin_otp_read, | 223 | .read = bfin_otp_read, |
224 | .write = bfin_otp_write, | 224 | .write = bfin_otp_write, |
225 | .llseek = default_llseek, | ||
225 | }; | 226 | }; |
226 | 227 | ||
227 | static struct miscdevice bfin_otp_misc_device = { | 228 | static struct miscdevice bfin_otp_misc_device = { |
diff --git a/drivers/char/briq_panel.c b/drivers/char/briq_panel.c index d5fa113afe37..f6718f05dad4 100644 --- a/drivers/char/briq_panel.c +++ b/drivers/char/briq_panel.c | |||
@@ -186,6 +186,7 @@ static const struct file_operations briq_panel_fops = { | |||
186 | .write = briq_panel_write, | 186 | .write = briq_panel_write, |
187 | .open = briq_panel_open, | 187 | .open = briq_panel_open, |
188 | .release = briq_panel_release, | 188 | .release = briq_panel_release, |
189 | .llseek = noop_llseek, | ||
189 | }; | 190 | }; |
190 | 191 | ||
191 | static struct miscdevice briq_panel_miscdev = { | 192 | static struct miscdevice briq_panel_miscdev = { |
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c index 91917133ae0a..a4a6c2f044b5 100644 --- a/drivers/char/bsr.c +++ b/drivers/char/bsr.c | |||
@@ -155,6 +155,7 @@ static const struct file_operations bsr_fops = { | |||
155 | .owner = THIS_MODULE, | 155 | .owner = THIS_MODULE, |
156 | .mmap = bsr_mmap, | 156 | .mmap = bsr_mmap, |
157 | .open = bsr_open, | 157 | .open = bsr_open, |
158 | .llseek = noop_llseek, | ||
158 | }; | 159 | }; |
159 | 160 | ||
160 | static void bsr_cleanup_devs(void) | 161 | static void bsr_cleanup_devs(void) |
diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c index 4d830dc482ef..0cf1e5fad9ab 100644 --- a/drivers/char/cs5535_gpio.c +++ b/drivers/char/cs5535_gpio.c | |||
@@ -169,7 +169,8 @@ static const struct file_operations cs5535_gpio_fops = { | |||
169 | .owner = THIS_MODULE, | 169 | .owner = THIS_MODULE, |
170 | .write = cs5535_gpio_write, | 170 | .write = cs5535_gpio_write, |
171 | .read = cs5535_gpio_read, | 171 | .read = cs5535_gpio_read, |
172 | .open = cs5535_gpio_open | 172 | .open = cs5535_gpio_open, |
173 | .llseek = no_llseek, | ||
173 | }; | 174 | }; |
174 | 175 | ||
175 | static int __init cs5535_gpio_init(void) | 176 | static int __init cs5535_gpio_init(void) |
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 27aad9422332..4f152c28f40e 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -2790,29 +2790,6 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
2790 | * NB: both 1->0 and 0->1 transitions are counted except for | 2790 | * NB: both 1->0 and 0->1 transitions are counted except for |
2791 | * RI where only 0->1 is counted. | 2791 | * RI where only 0->1 is counted. |
2792 | */ | 2792 | */ |
2793 | case TIOCGICOUNT: { | ||
2794 | struct serial_icounter_struct sic = { }; | ||
2795 | |||
2796 | spin_lock_irqsave(&info->card->card_lock, flags); | ||
2797 | cnow = info->icount; | ||
2798 | spin_unlock_irqrestore(&info->card->card_lock, flags); | ||
2799 | |||
2800 | sic.cts = cnow.cts; | ||
2801 | sic.dsr = cnow.dsr; | ||
2802 | sic.rng = cnow.rng; | ||
2803 | sic.dcd = cnow.dcd; | ||
2804 | sic.rx = cnow.rx; | ||
2805 | sic.tx = cnow.tx; | ||
2806 | sic.frame = cnow.frame; | ||
2807 | sic.overrun = cnow.overrun; | ||
2808 | sic.parity = cnow.parity; | ||
2809 | sic.brk = cnow.brk; | ||
2810 | sic.buf_overrun = cnow.buf_overrun; | ||
2811 | |||
2812 | if (copy_to_user(argp, &sic, sizeof(sic))) | ||
2813 | ret_val = -EFAULT; | ||
2814 | break; | ||
2815 | } | ||
2816 | default: | 2793 | default: |
2817 | ret_val = -ENOIOCTLCMD; | 2794 | ret_val = -ENOIOCTLCMD; |
2818 | } | 2795 | } |
@@ -2823,6 +2800,31 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
2823 | return ret_val; | 2800 | return ret_val; |
2824 | } /* cy_ioctl */ | 2801 | } /* cy_ioctl */ |
2825 | 2802 | ||
2803 | static int cy_get_icount(struct tty_struct *tty, | ||
2804 | struct serial_icounter_struct *sic) | ||
2805 | { | ||
2806 | struct cyclades_port *info = tty->driver_data; | ||
2807 | struct cyclades_icount cnow; /* Used to snapshot */ | ||
2808 | unsigned long flags; | ||
2809 | |||
2810 | spin_lock_irqsave(&info->card->card_lock, flags); | ||
2811 | cnow = info->icount; | ||
2812 | spin_unlock_irqrestore(&info->card->card_lock, flags); | ||
2813 | |||
2814 | sic->cts = cnow.cts; | ||
2815 | sic->dsr = cnow.dsr; | ||
2816 | sic->rng = cnow.rng; | ||
2817 | sic->dcd = cnow.dcd; | ||
2818 | sic->rx = cnow.rx; | ||
2819 | sic->tx = cnow.tx; | ||
2820 | sic->frame = cnow.frame; | ||
2821 | sic->overrun = cnow.overrun; | ||
2822 | sic->parity = cnow.parity; | ||
2823 | sic->brk = cnow.brk; | ||
2824 | sic->buf_overrun = cnow.buf_overrun; | ||
2825 | return 0; | ||
2826 | } | ||
2827 | |||
2826 | /* | 2828 | /* |
2827 | * This routine allows the tty driver to be notified when | 2829 | * This routine allows the tty driver to be notified when |
2828 | * device's termios settings have changed. Note that a | 2830 | * device's termios settings have changed. Note that a |
@@ -4084,6 +4086,7 @@ static const struct tty_operations cy_ops = { | |||
4084 | .wait_until_sent = cy_wait_until_sent, | 4086 | .wait_until_sent = cy_wait_until_sent, |
4085 | .tiocmget = cy_tiocmget, | 4087 | .tiocmget = cy_tiocmget, |
4086 | .tiocmset = cy_tiocmset, | 4088 | .tiocmset = cy_tiocmset, |
4089 | .get_icount = cy_get_icount, | ||
4087 | .proc_fops = &cyclades_proc_fops, | 4090 | .proc_fops = &cyclades_proc_fops, |
4088 | }; | 4091 | }; |
4089 | 4092 | ||
diff --git a/drivers/char/ds1302.c b/drivers/char/ds1302.c index 170693c93c73..ed8303f9890c 100644 --- a/drivers/char/ds1302.c +++ b/drivers/char/ds1302.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/miscdevice.h> | 20 | #include <linux/miscdevice.h> |
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/bcd.h> | 22 | #include <linux/bcd.h> |
23 | #include <linux/smp_lock.h> | 23 | #include <linux/mutex.h> |
24 | #include <linux/uaccess.h> | 24 | #include <linux/uaccess.h> |
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | 26 | ||
@@ -32,6 +32,7 @@ | |||
32 | 32 | ||
33 | #define RTC_MAJOR_NR 121 /* local major, change later */ | 33 | #define RTC_MAJOR_NR 121 /* local major, change later */ |
34 | 34 | ||
35 | static DEFINE_MUTEX(rtc_mutex); | ||
35 | static const char ds1302_name[] = "ds1302"; | 36 | static const char ds1302_name[] = "ds1302"; |
36 | 37 | ||
37 | /* Send 8 bits. */ | 38 | /* Send 8 bits. */ |
@@ -164,9 +165,9 @@ static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
164 | struct rtc_time rtc_tm; | 165 | struct rtc_time rtc_tm; |
165 | 166 | ||
166 | memset(&rtc_tm, 0, sizeof (struct rtc_time)); | 167 | memset(&rtc_tm, 0, sizeof (struct rtc_time)); |
167 | lock_kernel(); | 168 | mutex_lock(&rtc_mutex); |
168 | get_rtc_time(&rtc_tm); | 169 | get_rtc_time(&rtc_tm); |
169 | unlock_kernel(); | 170 | mutex_unlock(&rtc_mutex); |
170 | if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time))) | 171 | if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time))) |
171 | return -EFAULT; | 172 | return -EFAULT; |
172 | return 0; | 173 | return 0; |
@@ -218,7 +219,7 @@ static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
218 | mon = bin2bcd(mon); | 219 | mon = bin2bcd(mon); |
219 | yrs = bin2bcd(yrs); | 220 | yrs = bin2bcd(yrs); |
220 | 221 | ||
221 | lock_kernel(); | 222 | mutex_lock(&rtc_mutex); |
222 | local_irq_save(flags); | 223 | local_irq_save(flags); |
223 | CMOS_WRITE(yrs, RTC_YEAR); | 224 | CMOS_WRITE(yrs, RTC_YEAR); |
224 | CMOS_WRITE(mon, RTC_MONTH); | 225 | CMOS_WRITE(mon, RTC_MONTH); |
@@ -227,7 +228,7 @@ static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
227 | CMOS_WRITE(min, RTC_MINUTES); | 228 | CMOS_WRITE(min, RTC_MINUTES); |
228 | CMOS_WRITE(sec, RTC_SECONDS); | 229 | CMOS_WRITE(sec, RTC_SECONDS); |
229 | local_irq_restore(flags); | 230 | local_irq_restore(flags); |
230 | unlock_kernel(); | 231 | mutex_unlock(&rtc_mutex); |
231 | 232 | ||
232 | /* Notice that at this point, the RTC is updated but | 233 | /* Notice that at this point, the RTC is updated but |
233 | * the kernel is still running with the old time. | 234 | * the kernel is still running with the old time. |
@@ -247,10 +248,10 @@ static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
247 | if(copy_from_user(&tcs_val, (int*)arg, sizeof(int))) | 248 | if(copy_from_user(&tcs_val, (int*)arg, sizeof(int))) |
248 | return -EFAULT; | 249 | return -EFAULT; |
249 | 250 | ||
250 | lock_kernel(); | 251 | mutex_lock(&rtc_mutex); |
251 | tcs_val = RTC_TCR_PATTERN | (tcs_val & 0x0F); | 252 | tcs_val = RTC_TCR_PATTERN | (tcs_val & 0x0F); |
252 | ds1302_writereg(RTC_TRICKLECHARGER, tcs_val); | 253 | ds1302_writereg(RTC_TRICKLECHARGER, tcs_val); |
253 | unlock_kernel(); | 254 | mutex_unlock(&rtc_mutex); |
254 | return 0; | 255 | return 0; |
255 | } | 256 | } |
256 | default: | 257 | default: |
@@ -288,6 +289,7 @@ get_rtc_status(char *buf) | |||
288 | static const struct file_operations rtc_fops = { | 289 | static const struct file_operations rtc_fops = { |
289 | .owner = THIS_MODULE, | 290 | .owner = THIS_MODULE, |
290 | .unlocked_ioctl = rtc_ioctl, | 291 | .unlocked_ioctl = rtc_ioctl, |
292 | .llseek = noop_llseek, | ||
291 | }; | 293 | }; |
292 | 294 | ||
293 | /* Probe for the chip by writing something to its RAM and try reading it back. */ | 295 | /* Probe for the chip by writing something to its RAM and try reading it back. */ |
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c index dbee8688f75c..aab9605f0b43 100644 --- a/drivers/char/ds1620.c +++ b/drivers/char/ds1620.c | |||
@@ -8,7 +8,7 @@ | |||
8 | #include <linux/proc_fs.h> | 8 | #include <linux/proc_fs.h> |
9 | #include <linux/capability.h> | 9 | #include <linux/capability.h> |
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/smp_lock.h> | 11 | #include <linux/mutex.h> |
12 | 12 | ||
13 | #include <mach/hardware.h> | 13 | #include <mach/hardware.h> |
14 | #include <asm/mach-types.h> | 14 | #include <asm/mach-types.h> |
@@ -34,6 +34,7 @@ | |||
34 | #define CFG_CPU 2 | 34 | #define CFG_CPU 2 |
35 | #define CFG_1SHOT 1 | 35 | #define CFG_1SHOT 1 |
36 | 36 | ||
37 | static DEFINE_MUTEX(ds1620_mutex); | ||
37 | static const char *fan_state[] = { "off", "on", "on (hardwired)" }; | 38 | static const char *fan_state[] = { "off", "on", "on (hardwired)" }; |
38 | 39 | ||
39 | /* | 40 | /* |
@@ -210,7 +211,6 @@ static void ds1620_read_state(struct therm *therm) | |||
210 | 211 | ||
211 | static int ds1620_open(struct inode *inode, struct file *file) | 212 | static int ds1620_open(struct inode *inode, struct file *file) |
212 | { | 213 | { |
213 | cycle_kernel_lock(); | ||
214 | return nonseekable_open(inode, file); | 214 | return nonseekable_open(inode, file); |
215 | } | 215 | } |
216 | 216 | ||
@@ -321,9 +321,9 @@ ds1620_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
321 | { | 321 | { |
322 | int ret; | 322 | int ret; |
323 | 323 | ||
324 | lock_kernel(); | 324 | mutex_lock(&ds1620_mutex); |
325 | ret = ds1620_ioctl(file, cmd, arg); | 325 | ret = ds1620_ioctl(file, cmd, arg); |
326 | unlock_kernel(); | 326 | mutex_unlock(&ds1620_mutex); |
327 | 327 | ||
328 | return ret; | 328 | return ret; |
329 | } | 329 | } |
@@ -357,6 +357,7 @@ static const struct file_operations ds1620_fops = { | |||
357 | .open = ds1620_open, | 357 | .open = ds1620_open, |
358 | .read = ds1620_read, | 358 | .read = ds1620_read, |
359 | .unlocked_ioctl = ds1620_unlocked_ioctl, | 359 | .unlocked_ioctl = ds1620_unlocked_ioctl, |
360 | .llseek = no_llseek, | ||
360 | }; | 361 | }; |
361 | 362 | ||
362 | static struct miscdevice ds1620_miscdev = { | 363 | static struct miscdevice ds1620_miscdev = { |
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c index 8a1b28a10ef0..052797b32bd3 100644 --- a/drivers/char/dsp56k.c +++ b/drivers/char/dsp56k.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <linux/mm.h> | 32 | #include <linux/mm.h> |
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/device.h> | 34 | #include <linux/device.h> |
35 | #include <linux/smp_lock.h> | 35 | #include <linux/mutex.h> |
36 | #include <linux/firmware.h> | 36 | #include <linux/firmware.h> |
37 | #include <linux/platform_device.h> | 37 | #include <linux/platform_device.h> |
38 | #include <linux/uaccess.h> /* For put_user and get_user */ | 38 | #include <linux/uaccess.h> /* For put_user and get_user */ |
@@ -94,6 +94,7 @@ | |||
94 | } \ | 94 | } \ |
95 | } | 95 | } |
96 | 96 | ||
97 | static DEFINE_MUTEX(dsp56k_mutex); | ||
97 | static struct dsp56k_device { | 98 | static struct dsp56k_device { |
98 | unsigned long in_use; | 99 | unsigned long in_use; |
99 | long maxio, timeout; | 100 | long maxio, timeout; |
@@ -330,9 +331,9 @@ static long dsp56k_ioctl(struct file *file, unsigned int cmd, | |||
330 | if (len > DSP56K_MAX_BINARY_LENGTH) { | 331 | if (len > DSP56K_MAX_BINARY_LENGTH) { |
331 | return -EINVAL; | 332 | return -EINVAL; |
332 | } | 333 | } |
333 | lock_kernel(); | 334 | mutex_lock(&dsp56k_mutex); |
334 | r = dsp56k_upload(bin, len); | 335 | r = dsp56k_upload(bin, len); |
335 | unlock_kernel(); | 336 | mutex_unlock(&dsp56k_mutex); |
336 | if (r < 0) { | 337 | if (r < 0) { |
337 | return r; | 338 | return r; |
338 | } | 339 | } |
@@ -342,16 +343,16 @@ static long dsp56k_ioctl(struct file *file, unsigned int cmd, | |||
342 | case DSP56K_SET_TX_WSIZE: | 343 | case DSP56K_SET_TX_WSIZE: |
343 | if (arg > 4 || arg < 1) | 344 | if (arg > 4 || arg < 1) |
344 | return -EINVAL; | 345 | return -EINVAL; |
345 | lock_kernel(); | 346 | mutex_lock(&dsp56k_mutex); |
346 | dsp56k.tx_wsize = (int) arg; | 347 | dsp56k.tx_wsize = (int) arg; |
347 | unlock_kernel(); | 348 | mutex_unlock(&dsp56k_mutex); |
348 | break; | 349 | break; |
349 | case DSP56K_SET_RX_WSIZE: | 350 | case DSP56K_SET_RX_WSIZE: |
350 | if (arg > 4 || arg < 1) | 351 | if (arg > 4 || arg < 1) |
351 | return -EINVAL; | 352 | return -EINVAL; |
352 | lock_kernel(); | 353 | mutex_lock(&dsp56k_mutex); |
353 | dsp56k.rx_wsize = (int) arg; | 354 | dsp56k.rx_wsize = (int) arg; |
354 | unlock_kernel(); | 355 | mutex_unlock(&dsp56k_mutex); |
355 | break; | 356 | break; |
356 | case DSP56K_HOST_FLAGS: | 357 | case DSP56K_HOST_FLAGS: |
357 | { | 358 | { |
@@ -363,7 +364,7 @@ static long dsp56k_ioctl(struct file *file, unsigned int cmd, | |||
363 | if(get_user(out, &hf->out) < 0) | 364 | if(get_user(out, &hf->out) < 0) |
364 | return -EFAULT; | 365 | return -EFAULT; |
365 | 366 | ||
366 | lock_kernel(); | 367 | mutex_lock(&dsp56k_mutex); |
367 | if ((dir & 0x1) && (out & 0x1)) | 368 | if ((dir & 0x1) && (out & 0x1)) |
368 | dsp56k_host_interface.icr |= DSP56K_ICR_HF0; | 369 | dsp56k_host_interface.icr |= DSP56K_ICR_HF0; |
369 | else if (dir & 0x1) | 370 | else if (dir & 0x1) |
@@ -378,16 +379,16 @@ static long dsp56k_ioctl(struct file *file, unsigned int cmd, | |||
378 | if (dsp56k_host_interface.icr & DSP56K_ICR_HF1) status |= 0x2; | 379 | if (dsp56k_host_interface.icr & DSP56K_ICR_HF1) status |= 0x2; |
379 | if (dsp56k_host_interface.isr & DSP56K_ISR_HF2) status |= 0x4; | 380 | if (dsp56k_host_interface.isr & DSP56K_ISR_HF2) status |= 0x4; |
380 | if (dsp56k_host_interface.isr & DSP56K_ISR_HF3) status |= 0x8; | 381 | if (dsp56k_host_interface.isr & DSP56K_ISR_HF3) status |= 0x8; |
381 | unlock_kernel(); | 382 | mutex_unlock(&dsp56k_mutex); |
382 | return put_user(status, &hf->status); | 383 | return put_user(status, &hf->status); |
383 | } | 384 | } |
384 | case DSP56K_HOST_CMD: | 385 | case DSP56K_HOST_CMD: |
385 | if (arg > 31 || arg < 0) | 386 | if (arg > 31 || arg < 0) |
386 | return -EINVAL; | 387 | return -EINVAL; |
387 | lock_kernel(); | 388 | mutex_lock(&dsp56k_mutex); |
388 | dsp56k_host_interface.cvr = (u_char)((arg & DSP56K_CVR_HV_MASK) | | 389 | dsp56k_host_interface.cvr = (u_char)((arg & DSP56K_CVR_HV_MASK) | |
389 | DSP56K_CVR_HC); | 390 | DSP56K_CVR_HC); |
390 | unlock_kernel(); | 391 | mutex_unlock(&dsp56k_mutex); |
391 | break; | 392 | break; |
392 | default: | 393 | default: |
393 | return -EINVAL; | 394 | return -EINVAL; |
@@ -427,7 +428,7 @@ static int dsp56k_open(struct inode *inode, struct file *file) | |||
427 | int dev = iminor(inode) & 0x0f; | 428 | int dev = iminor(inode) & 0x0f; |
428 | int ret = 0; | 429 | int ret = 0; |
429 | 430 | ||
430 | lock_kernel(); | 431 | mutex_lock(&dsp56k_mutex); |
431 | switch(dev) | 432 | switch(dev) |
432 | { | 433 | { |
433 | case DSP56K_DEV_56001: | 434 | case DSP56K_DEV_56001: |
@@ -454,7 +455,7 @@ static int dsp56k_open(struct inode *inode, struct file *file) | |||
454 | ret = -ENODEV; | 455 | ret = -ENODEV; |
455 | } | 456 | } |
456 | out: | 457 | out: |
457 | unlock_kernel(); | 458 | mutex_unlock(&dsp56k_mutex); |
458 | return ret; | 459 | return ret; |
459 | } | 460 | } |
460 | 461 | ||
@@ -482,6 +483,7 @@ static const struct file_operations dsp56k_fops = { | |||
482 | .unlocked_ioctl = dsp56k_ioctl, | 483 | .unlocked_ioctl = dsp56k_ioctl, |
483 | .open = dsp56k_open, | 484 | .open = dsp56k_open, |
484 | .release = dsp56k_release, | 485 | .release = dsp56k_release, |
486 | .llseek = noop_llseek, | ||
485 | }; | 487 | }; |
486 | 488 | ||
487 | 489 | ||
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c index e3859d4eaead..85156dd0caee 100644 --- a/drivers/char/dtlk.c +++ b/drivers/char/dtlk.c | |||
@@ -57,7 +57,7 @@ | |||
57 | #include <linux/ioport.h> /* for request_region */ | 57 | #include <linux/ioport.h> /* for request_region */ |
58 | #include <linux/delay.h> /* for loops_per_jiffy */ | 58 | #include <linux/delay.h> /* for loops_per_jiffy */ |
59 | #include <linux/sched.h> | 59 | #include <linux/sched.h> |
60 | #include <linux/smp_lock.h> /* cycle_kernel_lock() */ | 60 | #include <linux/mutex.h> |
61 | #include <asm/io.h> /* for inb_p, outb_p, inb, outb, etc. */ | 61 | #include <asm/io.h> /* for inb_p, outb_p, inb, outb, etc. */ |
62 | #include <asm/uaccess.h> /* for get_user, etc. */ | 62 | #include <asm/uaccess.h> /* for get_user, etc. */ |
63 | #include <linux/wait.h> /* for wait_queue */ | 63 | #include <linux/wait.h> /* for wait_queue */ |
@@ -73,6 +73,7 @@ | |||
73 | #define TRACE_RET ((void) 0) | 73 | #define TRACE_RET ((void) 0) |
74 | #endif /* TRACING */ | 74 | #endif /* TRACING */ |
75 | 75 | ||
76 | static DEFINE_MUTEX(dtlk_mutex); | ||
76 | static void dtlk_timer_tick(unsigned long data); | 77 | static void dtlk_timer_tick(unsigned long data); |
77 | 78 | ||
78 | static int dtlk_major; | 79 | static int dtlk_major; |
@@ -105,6 +106,7 @@ static const struct file_operations dtlk_fops = | |||
105 | .unlocked_ioctl = dtlk_ioctl, | 106 | .unlocked_ioctl = dtlk_ioctl, |
106 | .open = dtlk_open, | 107 | .open = dtlk_open, |
107 | .release = dtlk_release, | 108 | .release = dtlk_release, |
109 | .llseek = no_llseek, | ||
108 | }; | 110 | }; |
109 | 111 | ||
110 | /* local prototypes */ | 112 | /* local prototypes */ |
@@ -275,9 +277,9 @@ static long dtlk_ioctl(struct file *file, | |||
275 | switch (cmd) { | 277 | switch (cmd) { |
276 | 278 | ||
277 | case DTLK_INTERROGATE: | 279 | case DTLK_INTERROGATE: |
278 | lock_kernel(); | 280 | mutex_lock(&dtlk_mutex); |
279 | sp = dtlk_interrogate(); | 281 | sp = dtlk_interrogate(); |
280 | unlock_kernel(); | 282 | mutex_unlock(&dtlk_mutex); |
281 | if (copy_to_user(argp, sp, sizeof(struct dtlk_settings))) | 283 | if (copy_to_user(argp, sp, sizeof(struct dtlk_settings))) |
282 | return -EINVAL; | 284 | return -EINVAL; |
283 | return 0; | 285 | return 0; |
@@ -296,7 +298,6 @@ static int dtlk_open(struct inode *inode, struct file *file) | |||
296 | { | 298 | { |
297 | TRACE_TEXT("(dtlk_open"); | 299 | TRACE_TEXT("(dtlk_open"); |
298 | 300 | ||
299 | cycle_kernel_lock(); | ||
300 | nonseekable_open(inode, file); | 301 | nonseekable_open(inode, file); |
301 | switch (iminor(inode)) { | 302 | switch (iminor(inode)) { |
302 | case DTLK_MINOR: | 303 | case DTLK_MINOR: |
diff --git a/drivers/char/generic_nvram.c b/drivers/char/generic_nvram.c index 82b5a88a82d7..0e941b57482e 100644 --- a/drivers/char/generic_nvram.c +++ b/drivers/char/generic_nvram.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <linux/miscdevice.h> | 19 | #include <linux/miscdevice.h> |
20 | #include <linux/fcntl.h> | 20 | #include <linux/fcntl.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/smp_lock.h> | 22 | #include <linux/mutex.h> |
23 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
24 | #include <asm/nvram.h> | 24 | #include <asm/nvram.h> |
25 | #ifdef CONFIG_PPC_PMAC | 25 | #ifdef CONFIG_PPC_PMAC |
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | #define NVRAM_SIZE 8192 | 29 | #define NVRAM_SIZE 8192 |
30 | 30 | ||
31 | static DEFINE_MUTEX(nvram_mutex); | ||
31 | static ssize_t nvram_len; | 32 | static ssize_t nvram_len; |
32 | 33 | ||
33 | static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) | 34 | static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) |
@@ -120,9 +121,9 @@ static long nvram_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned l | |||
120 | { | 121 | { |
121 | int ret; | 122 | int ret; |
122 | 123 | ||
123 | lock_kernel(); | 124 | mutex_lock(&nvram_mutex); |
124 | ret = nvram_ioctl(file, cmd, arg); | 125 | ret = nvram_ioctl(file, cmd, arg); |
125 | unlock_kernel(); | 126 | mutex_unlock(&nvram_mutex); |
126 | 127 | ||
127 | return ret; | 128 | return ret; |
128 | } | 129 | } |
diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c index b6c2cc167c11..f773a9dd14f3 100644 --- a/drivers/char/genrtc.c +++ b/drivers/char/genrtc.c | |||
@@ -52,7 +52,7 @@ | |||
52 | #include <linux/init.h> | 52 | #include <linux/init.h> |
53 | #include <linux/poll.h> | 53 | #include <linux/poll.h> |
54 | #include <linux/proc_fs.h> | 54 | #include <linux/proc_fs.h> |
55 | #include <linux/smp_lock.h> | 55 | #include <linux/mutex.h> |
56 | #include <linux/workqueue.h> | 56 | #include <linux/workqueue.h> |
57 | 57 | ||
58 | #include <asm/uaccess.h> | 58 | #include <asm/uaccess.h> |
@@ -66,6 +66,7 @@ | |||
66 | * ioctls. | 66 | * ioctls. |
67 | */ | 67 | */ |
68 | 68 | ||
69 | static DEFINE_MUTEX(gen_rtc_mutex); | ||
69 | static DECLARE_WAIT_QUEUE_HEAD(gen_rtc_wait); | 70 | static DECLARE_WAIT_QUEUE_HEAD(gen_rtc_wait); |
70 | 71 | ||
71 | /* | 72 | /* |
@@ -337,9 +338,9 @@ static long gen_rtc_unlocked_ioctl(struct file *file, unsigned int cmd, | |||
337 | { | 338 | { |
338 | int ret; | 339 | int ret; |
339 | 340 | ||
340 | lock_kernel(); | 341 | mutex_lock(&gen_rtc_mutex); |
341 | ret = gen_rtc_ioctl(file, cmd, arg); | 342 | ret = gen_rtc_ioctl(file, cmd, arg); |
342 | unlock_kernel(); | 343 | mutex_unlock(&gen_rtc_mutex); |
343 | 344 | ||
344 | return ret; | 345 | return ret; |
345 | } | 346 | } |
@@ -352,16 +353,16 @@ static long gen_rtc_unlocked_ioctl(struct file *file, unsigned int cmd, | |||
352 | 353 | ||
353 | static int gen_rtc_open(struct inode *inode, struct file *file) | 354 | static int gen_rtc_open(struct inode *inode, struct file *file) |
354 | { | 355 | { |
355 | lock_kernel(); | 356 | mutex_lock(&gen_rtc_mutex); |
356 | if (gen_rtc_status & RTC_IS_OPEN) { | 357 | if (gen_rtc_status & RTC_IS_OPEN) { |
357 | unlock_kernel(); | 358 | mutex_unlock(&gen_rtc_mutex); |
358 | return -EBUSY; | 359 | return -EBUSY; |
359 | } | 360 | } |
360 | 361 | ||
361 | gen_rtc_status |= RTC_IS_OPEN; | 362 | gen_rtc_status |= RTC_IS_OPEN; |
362 | gen_rtc_irq_data = 0; | 363 | gen_rtc_irq_data = 0; |
363 | irq_active = 0; | 364 | irq_active = 0; |
364 | unlock_kernel(); | 365 | mutex_unlock(&gen_rtc_mutex); |
365 | 366 | ||
366 | return 0; | 367 | return 0; |
367 | } | 368 | } |
@@ -497,6 +498,7 @@ static const struct file_operations gen_rtc_fops = { | |||
497 | .unlocked_ioctl = gen_rtc_unlocked_ioctl, | 498 | .unlocked_ioctl = gen_rtc_unlocked_ioctl, |
498 | .open = gen_rtc_open, | 499 | .open = gen_rtc_open, |
499 | .release = gen_rtc_release, | 500 | .release = gen_rtc_release, |
501 | .llseek = noop_llseek, | ||
500 | }; | 502 | }; |
501 | 503 | ||
502 | static struct miscdevice rtc_gen_dev = | 504 | static struct miscdevice rtc_gen_dev = |
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index a0a1829d3198..55b8667f739f 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -30,13 +30,14 @@ | |||
30 | #include <linux/bcd.h> | 30 | #include <linux/bcd.h> |
31 | #include <linux/seq_file.h> | 31 | #include <linux/seq_file.h> |
32 | #include <linux/bitops.h> | 32 | #include <linux/bitops.h> |
33 | #include <linux/compat.h> | ||
33 | #include <linux/clocksource.h> | 34 | #include <linux/clocksource.h> |
35 | #include <linux/uaccess.h> | ||
34 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
37 | #include <linux/io.h> | ||
35 | 38 | ||
36 | #include <asm/current.h> | 39 | #include <asm/current.h> |
37 | #include <asm/uaccess.h> | ||
38 | #include <asm/system.h> | 40 | #include <asm/system.h> |
39 | #include <asm/io.h> | ||
40 | #include <asm/irq.h> | 41 | #include <asm/irq.h> |
41 | #include <asm/div64.h> | 42 | #include <asm/div64.h> |
42 | 43 | ||
@@ -67,6 +68,7 @@ | |||
67 | #define read_counter(MC) readl(MC) | 68 | #define read_counter(MC) readl(MC) |
68 | #endif | 69 | #endif |
69 | 70 | ||
71 | static DEFINE_MUTEX(hpet_mutex); /* replaces BKL */ | ||
70 | static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ; | 72 | static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ; |
71 | 73 | ||
72 | /* This clocksource driver currently only works on ia64 */ | 74 | /* This clocksource driver currently only works on ia64 */ |
@@ -79,13 +81,13 @@ static cycle_t read_hpet(struct clocksource *cs) | |||
79 | } | 81 | } |
80 | 82 | ||
81 | static struct clocksource clocksource_hpet = { | 83 | static struct clocksource clocksource_hpet = { |
82 | .name = "hpet", | 84 | .name = "hpet", |
83 | .rating = 250, | 85 | .rating = 250, |
84 | .read = read_hpet, | 86 | .read = read_hpet, |
85 | .mask = CLOCKSOURCE_MASK(64), | 87 | .mask = CLOCKSOURCE_MASK(64), |
86 | .mult = 0, /* to be calculated */ | 88 | .mult = 0, /* to be calculated */ |
87 | .shift = 10, | 89 | .shift = 10, |
88 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 90 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
89 | }; | 91 | }; |
90 | static struct clocksource *hpet_clocksource; | 92 | static struct clocksource *hpet_clocksource; |
91 | #endif | 93 | #endif |
@@ -250,7 +252,7 @@ static int hpet_open(struct inode *inode, struct file *file) | |||
250 | if (file->f_mode & FMODE_WRITE) | 252 | if (file->f_mode & FMODE_WRITE) |
251 | return -EINVAL; | 253 | return -EINVAL; |
252 | 254 | ||
253 | lock_kernel(); | 255 | mutex_lock(&hpet_mutex); |
254 | spin_lock_irq(&hpet_lock); | 256 | spin_lock_irq(&hpet_lock); |
255 | 257 | ||
256 | for (devp = NULL, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next) | 258 | for (devp = NULL, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next) |
@@ -264,7 +266,7 @@ static int hpet_open(struct inode *inode, struct file *file) | |||
264 | 266 | ||
265 | if (!devp) { | 267 | if (!devp) { |
266 | spin_unlock_irq(&hpet_lock); | 268 | spin_unlock_irq(&hpet_lock); |
267 | unlock_kernel(); | 269 | mutex_unlock(&hpet_mutex); |
268 | return -EBUSY; | 270 | return -EBUSY; |
269 | } | 271 | } |
270 | 272 | ||
@@ -272,7 +274,7 @@ static int hpet_open(struct inode *inode, struct file *file) | |||
272 | devp->hd_irqdata = 0; | 274 | devp->hd_irqdata = 0; |
273 | devp->hd_flags |= HPET_OPEN; | 275 | devp->hd_flags |= HPET_OPEN; |
274 | spin_unlock_irq(&hpet_lock); | 276 | spin_unlock_irq(&hpet_lock); |
275 | unlock_kernel(); | 277 | mutex_unlock(&hpet_mutex); |
276 | 278 | ||
277 | hpet_timer_set_irq(devp); | 279 | hpet_timer_set_irq(devp); |
278 | 280 | ||
@@ -429,22 +431,6 @@ static int hpet_release(struct inode *inode, struct file *file) | |||
429 | return 0; | 431 | return 0; |
430 | } | 432 | } |
431 | 433 | ||
432 | static int hpet_ioctl_common(struct hpet_dev *, int, unsigned long, int); | ||
433 | |||
434 | static long hpet_ioctl(struct file *file, unsigned int cmd, | ||
435 | unsigned long arg) | ||
436 | { | ||
437 | struct hpet_dev *devp; | ||
438 | int ret; | ||
439 | |||
440 | devp = file->private_data; | ||
441 | lock_kernel(); | ||
442 | ret = hpet_ioctl_common(devp, cmd, arg, 0); | ||
443 | unlock_kernel(); | ||
444 | |||
445 | return ret; | ||
446 | } | ||
447 | |||
448 | static int hpet_ioctl_ieon(struct hpet_dev *devp) | 434 | static int hpet_ioctl_ieon(struct hpet_dev *devp) |
449 | { | 435 | { |
450 | struct hpet_timer __iomem *timer; | 436 | struct hpet_timer __iomem *timer; |
@@ -479,6 +465,21 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp) | |||
479 | if (irq) { | 465 | if (irq) { |
480 | unsigned long irq_flags; | 466 | unsigned long irq_flags; |
481 | 467 | ||
468 | if (devp->hd_flags & HPET_SHARED_IRQ) { | ||
469 | /* | ||
470 | * To prevent the interrupt handler from seeing an | ||
471 | * unwanted interrupt status bit, program the timer | ||
472 | * so that it will not fire in the near future ... | ||
473 | */ | ||
474 | writel(readl(&timer->hpet_config) & ~Tn_TYPE_CNF_MASK, | ||
475 | &timer->hpet_config); | ||
476 | write_counter(read_counter(&hpet->hpet_mc), | ||
477 | &timer->hpet_compare); | ||
478 | /* ... and clear any left-over status. */ | ||
479 | isr = 1 << (devp - devp->hd_hpets->hp_dev); | ||
480 | writel(isr, &hpet->hpet_isr); | ||
481 | } | ||
482 | |||
482 | sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev)); | 483 | sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev)); |
483 | irq_flags = devp->hd_flags & HPET_SHARED_IRQ | 484 | irq_flags = devp->hd_flags & HPET_SHARED_IRQ |
484 | ? IRQF_SHARED : IRQF_DISABLED; | 485 | ? IRQF_SHARED : IRQF_DISABLED; |
@@ -553,7 +554,8 @@ static inline unsigned long hpet_time_div(struct hpets *hpets, | |||
553 | } | 554 | } |
554 | 555 | ||
555 | static int | 556 | static int |
556 | hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel) | 557 | hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, |
558 | struct hpet_info *info) | ||
557 | { | 559 | { |
558 | struct hpet_timer __iomem *timer; | 560 | struct hpet_timer __iomem *timer; |
559 | struct hpet __iomem *hpet; | 561 | struct hpet __iomem *hpet; |
@@ -594,23 +596,14 @@ hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel) | |||
594 | break; | 596 | break; |
595 | case HPET_INFO: | 597 | case HPET_INFO: |
596 | { | 598 | { |
597 | struct hpet_info info; | 599 | memset(info, 0, sizeof(*info)); |
598 | |||
599 | if (devp->hd_ireqfreq) | 600 | if (devp->hd_ireqfreq) |
600 | info.hi_ireqfreq = | 601 | info->hi_ireqfreq = |
601 | hpet_time_div(hpetp, devp->hd_ireqfreq); | 602 | hpet_time_div(hpetp, devp->hd_ireqfreq); |
602 | else | 603 | info->hi_flags = |
603 | info.hi_ireqfreq = 0; | ||
604 | info.hi_flags = | ||
605 | readq(&timer->hpet_config) & Tn_PER_INT_CAP_MASK; | 604 | readq(&timer->hpet_config) & Tn_PER_INT_CAP_MASK; |
606 | info.hi_hpet = hpetp->hp_which; | 605 | info->hi_hpet = hpetp->hp_which; |
607 | info.hi_timer = devp - hpetp->hp_dev; | 606 | info->hi_timer = devp - hpetp->hp_dev; |
608 | if (kernel) | ||
609 | memcpy((void *)arg, &info, sizeof(info)); | ||
610 | else | ||
611 | if (copy_to_user((void __user *)arg, &info, | ||
612 | sizeof(info))) | ||
613 | err = -EFAULT; | ||
614 | break; | 607 | break; |
615 | } | 608 | } |
616 | case HPET_EPI: | 609 | case HPET_EPI: |
@@ -636,7 +629,7 @@ hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel) | |||
636 | devp->hd_flags &= ~HPET_PERIODIC; | 629 | devp->hd_flags &= ~HPET_PERIODIC; |
637 | break; | 630 | break; |
638 | case HPET_IRQFREQ: | 631 | case HPET_IRQFREQ: |
639 | if (!kernel && (arg > hpet_max_freq) && | 632 | if ((arg > hpet_max_freq) && |
640 | !capable(CAP_SYS_RESOURCE)) { | 633 | !capable(CAP_SYS_RESOURCE)) { |
641 | err = -EACCES; | 634 | err = -EACCES; |
642 | break; | 635 | break; |
@@ -653,12 +646,63 @@ hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel) | |||
653 | return err; | 646 | return err; |
654 | } | 647 | } |
655 | 648 | ||
649 | static long | ||
650 | hpet_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
651 | { | ||
652 | struct hpet_info info; | ||
653 | int err; | ||
654 | |||
655 | mutex_lock(&hpet_mutex); | ||
656 | err = hpet_ioctl_common(file->private_data, cmd, arg, &info); | ||
657 | mutex_unlock(&hpet_mutex); | ||
658 | |||
659 | if ((cmd == HPET_INFO) && !err && | ||
660 | (copy_to_user((void __user *)arg, &info, sizeof(info)))) | ||
661 | err = -EFAULT; | ||
662 | |||
663 | return err; | ||
664 | } | ||
665 | |||
666 | #ifdef CONFIG_COMPAT | ||
667 | struct compat_hpet_info { | ||
668 | compat_ulong_t hi_ireqfreq; /* Hz */ | ||
669 | compat_ulong_t hi_flags; /* information */ | ||
670 | unsigned short hi_hpet; | ||
671 | unsigned short hi_timer; | ||
672 | }; | ||
673 | |||
674 | static long | ||
675 | hpet_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
676 | { | ||
677 | struct hpet_info info; | ||
678 | int err; | ||
679 | |||
680 | mutex_lock(&hpet_mutex); | ||
681 | err = hpet_ioctl_common(file->private_data, cmd, arg, &info); | ||
682 | mutex_unlock(&hpet_mutex); | ||
683 | |||
684 | if ((cmd == HPET_INFO) && !err) { | ||
685 | struct compat_hpet_info __user *u = compat_ptr(arg); | ||
686 | if (put_user(info.hi_ireqfreq, &u->hi_ireqfreq) || | ||
687 | put_user(info.hi_flags, &u->hi_flags) || | ||
688 | put_user(info.hi_hpet, &u->hi_hpet) || | ||
689 | put_user(info.hi_timer, &u->hi_timer)) | ||
690 | err = -EFAULT; | ||
691 | } | ||
692 | |||
693 | return err; | ||
694 | } | ||
695 | #endif | ||
696 | |||
656 | static const struct file_operations hpet_fops = { | 697 | static const struct file_operations hpet_fops = { |
657 | .owner = THIS_MODULE, | 698 | .owner = THIS_MODULE, |
658 | .llseek = no_llseek, | 699 | .llseek = no_llseek, |
659 | .read = hpet_read, | 700 | .read = hpet_read, |
660 | .poll = hpet_poll, | 701 | .poll = hpet_poll, |
661 | .unlocked_ioctl = hpet_ioctl, | 702 | .unlocked_ioctl = hpet_ioctl, |
703 | #ifdef CONFIG_COMPAT | ||
704 | .compat_ioctl = hpet_compat_ioctl, | ||
705 | #endif | ||
662 | .open = hpet_open, | 706 | .open = hpet_open, |
663 | .release = hpet_release, | 707 | .release = hpet_release, |
664 | .fasync = hpet_fasync, | 708 | .fasync = hpet_fasync, |
@@ -781,7 +825,7 @@ int hpet_alloc(struct hpet_data *hdp) | |||
781 | struct hpets *hpetp; | 825 | struct hpets *hpetp; |
782 | size_t siz; | 826 | size_t siz; |
783 | struct hpet __iomem *hpet; | 827 | struct hpet __iomem *hpet; |
784 | static struct hpets *last = NULL; | 828 | static struct hpets *last; |
785 | unsigned long period; | 829 | unsigned long period; |
786 | unsigned long long temp; | 830 | unsigned long long temp; |
787 | u32 remainder; | 831 | u32 remainder; |
@@ -970,6 +1014,8 @@ static int hpet_acpi_add(struct acpi_device *device) | |||
970 | return -ENODEV; | 1014 | return -ENODEV; |
971 | 1015 | ||
972 | if (!data.hd_address || !data.hd_nirqs) { | 1016 | if (!data.hd_address || !data.hd_nirqs) { |
1017 | if (data.hd_address) | ||
1018 | iounmap(data.hd_address); | ||
973 | printk("%s: no address or irqs in _CRS\n", __func__); | 1019 | printk("%s: no address or irqs in _CRS\n", __func__); |
974 | return -ENODEV; | 1020 | return -ENODEV; |
975 | } | 1021 | } |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 3afd62e856eb..e9cba13ee800 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -713,7 +713,6 @@ static int khvcd(void *unused) | |||
713 | struct hvc_struct *hp; | 713 | struct hvc_struct *hp; |
714 | 714 | ||
715 | set_freezable(); | 715 | set_freezable(); |
716 | __set_current_state(TASK_RUNNING); | ||
717 | do { | 716 | do { |
718 | poll_mask = 0; | 717 | poll_mask = 0; |
719 | hvc_kicked = 0; | 718 | hvc_kicked = 0; |
diff --git a/drivers/char/hvc_iucv.c b/drivers/char/hvc_iucv.c index 7b01bc609de3..c3425bb3a1f6 100644 --- a/drivers/char/hvc_iucv.c +++ b/drivers/char/hvc_iucv.c | |||
@@ -1303,13 +1303,11 @@ static int __init hvc_iucv_init(void) | |||
1303 | if (rc) { | 1303 | if (rc) { |
1304 | pr_err("Registering IUCV handlers failed with error code=%d\n", | 1304 | pr_err("Registering IUCV handlers failed with error code=%d\n", |
1305 | rc); | 1305 | rc); |
1306 | goto out_error_iucv; | 1306 | goto out_error_hvc; |
1307 | } | 1307 | } |
1308 | 1308 | ||
1309 | return 0; | 1309 | return 0; |
1310 | 1310 | ||
1311 | out_error_iucv: | ||
1312 | iucv_unregister(&hvc_iucv_handler, 0); | ||
1313 | out_error_hvc: | 1311 | out_error_hvc: |
1314 | for (i = 0; i < hvc_iucv_devices; i++) | 1312 | for (i = 0; i < hvc_iucv_devices; i++) |
1315 | if (hvc_iucv_table[i]) | 1313 | if (hvc_iucv_table[i]) |
diff --git a/drivers/char/hvc_tile.c b/drivers/char/hvc_tile.c index c4efb55cbc03..7a84a0595477 100644 --- a/drivers/char/hvc_tile.c +++ b/drivers/char/hvc_tile.c | |||
@@ -61,7 +61,8 @@ console_initcall(hvc_tile_console_init); | |||
61 | 61 | ||
62 | static int __init hvc_tile_init(void) | 62 | static int __init hvc_tile_init(void) |
63 | { | 63 | { |
64 | hvc_alloc(0, 0, &hvc_tile_get_put_ops, 128); | 64 | struct hvc_struct *s; |
65 | return 0; | 65 | s = hvc_alloc(0, 0, &hvc_tile_get_put_ops, 128); |
66 | return IS_ERR(s) ? PTR_ERR(s) : 0; | ||
66 | } | 67 | } |
67 | device_initcall(hvc_tile_init); | 68 | device_initcall(hvc_tile_init); |
diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c index 60446f82a3fc..6b8e6d18a8e6 100644 --- a/drivers/char/hvc_xen.c +++ b/drivers/char/hvc_xen.c | |||
@@ -74,7 +74,8 @@ static int __write_console(const char *data, int len) | |||
74 | wmb(); /* write ring before updating pointer */ | 74 | wmb(); /* write ring before updating pointer */ |
75 | intf->out_prod = prod; | 75 | intf->out_prod = prod; |
76 | 76 | ||
77 | notify_daemon(); | 77 | if (sent) |
78 | notify_daemon(); | ||
78 | return sent; | 79 | return sent; |
79 | } | 80 | } |
80 | 81 | ||
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index 3d9c61e5acbf..788da05190cc 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c | |||
@@ -170,6 +170,7 @@ static const struct file_operations rng_chrdev_ops = { | |||
170 | .owner = THIS_MODULE, | 170 | .owner = THIS_MODULE, |
171 | .open = rng_dev_open, | 171 | .open = rng_dev_open, |
172 | .read = rng_dev_read, | 172 | .read = rng_dev_read, |
173 | .llseek = noop_llseek, | ||
173 | }; | 174 | }; |
174 | 175 | ||
175 | static struct miscdevice rng_miscdev = { | 176 | static struct miscdevice rng_miscdev = { |
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c index 4cd8b227c11f..3bc0eef88717 100644 --- a/drivers/char/i8k.c +++ b/drivers/char/i8k.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <linux/seq_file.h> | 23 | #include <linux/seq_file.h> |
24 | #include <linux/dmi.h> | 24 | #include <linux/dmi.h> |
25 | #include <linux/capability.h> | 25 | #include <linux/capability.h> |
26 | #include <linux/smp_lock.h> | 26 | #include <linux/mutex.h> |
27 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
28 | #include <asm/io.h> | 28 | #include <asm/io.h> |
29 | 29 | ||
@@ -56,6 +56,7 @@ | |||
56 | 56 | ||
57 | #define I8K_TEMPERATURE_BUG 1 | 57 | #define I8K_TEMPERATURE_BUG 1 |
58 | 58 | ||
59 | static DEFINE_MUTEX(i8k_mutex); | ||
59 | static char bios_version[4]; | 60 | static char bios_version[4]; |
60 | 61 | ||
61 | MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)"); | 62 | MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)"); |
@@ -399,9 +400,9 @@ static long i8k_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) | |||
399 | { | 400 | { |
400 | long ret; | 401 | long ret; |
401 | 402 | ||
402 | lock_kernel(); | 403 | mutex_lock(&i8k_mutex); |
403 | ret = i8k_ioctl_unlocked(fp, cmd, arg); | 404 | ret = i8k_ioctl_unlocked(fp, cmd, arg); |
404 | unlock_kernel(); | 405 | mutex_unlock(&i8k_mutex); |
405 | 406 | ||
406 | return ret; | 407 | return ret; |
407 | } | 408 | } |
diff --git a/drivers/char/ip2/Makefile b/drivers/char/ip2/Makefile index bc397d92b499..7b78e0dfc5b0 100644 --- a/drivers/char/ip2/Makefile +++ b/drivers/char/ip2/Makefile | |||
@@ -4,5 +4,5 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_COMPUTONE) += ip2.o | 5 | obj-$(CONFIG_COMPUTONE) += ip2.o |
6 | 6 | ||
7 | ip2-objs := ip2main.o | 7 | ip2-y := ip2main.o |
8 | 8 | ||
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index d4b71e8d0d23..fcd02baa7d65 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -98,7 +98,7 @@ | |||
98 | #include <linux/major.h> | 98 | #include <linux/major.h> |
99 | #include <linux/wait.h> | 99 | #include <linux/wait.h> |
100 | #include <linux/device.h> | 100 | #include <linux/device.h> |
101 | #include <linux/smp_lock.h> | 101 | #include <linux/mutex.h> |
102 | #include <linux/firmware.h> | 102 | #include <linux/firmware.h> |
103 | #include <linux/platform_device.h> | 103 | #include <linux/platform_device.h> |
104 | 104 | ||
@@ -138,6 +138,7 @@ | |||
138 | #include <linux/proc_fs.h> | 138 | #include <linux/proc_fs.h> |
139 | #include <linux/seq_file.h> | 139 | #include <linux/seq_file.h> |
140 | 140 | ||
141 | static DEFINE_MUTEX(ip2_mutex); | ||
141 | static const struct file_operations ip2mem_proc_fops; | 142 | static const struct file_operations ip2mem_proc_fops; |
142 | static const struct file_operations ip2_proc_fops; | 143 | static const struct file_operations ip2_proc_fops; |
143 | 144 | ||
@@ -183,6 +184,8 @@ static void ip2_hangup(PTTY); | |||
183 | static int ip2_tiocmget(struct tty_struct *tty, struct file *file); | 184 | static int ip2_tiocmget(struct tty_struct *tty, struct file *file); |
184 | static int ip2_tiocmset(struct tty_struct *tty, struct file *file, | 185 | static int ip2_tiocmset(struct tty_struct *tty, struct file *file, |
185 | unsigned int set, unsigned int clear); | 186 | unsigned int set, unsigned int clear); |
187 | static int ip2_get_icount(struct tty_struct *tty, | ||
188 | struct serial_icounter_struct *icount); | ||
186 | 189 | ||
187 | static void set_irq(int, int); | 190 | static void set_irq(int, int); |
188 | static void ip2_interrupt_bh(struct work_struct *work); | 191 | static void ip2_interrupt_bh(struct work_struct *work); |
@@ -236,6 +239,7 @@ static const struct file_operations ip2_ipl = { | |||
236 | .write = ip2_ipl_write, | 239 | .write = ip2_ipl_write, |
237 | .unlocked_ioctl = ip2_ipl_ioctl, | 240 | .unlocked_ioctl = ip2_ipl_ioctl, |
238 | .open = ip2_ipl_open, | 241 | .open = ip2_ipl_open, |
242 | .llseek = noop_llseek, | ||
239 | }; | 243 | }; |
240 | 244 | ||
241 | static unsigned long irq_counter; | 245 | static unsigned long irq_counter; |
@@ -454,6 +458,7 @@ static const struct tty_operations ip2_ops = { | |||
454 | .hangup = ip2_hangup, | 458 | .hangup = ip2_hangup, |
455 | .tiocmget = ip2_tiocmget, | 459 | .tiocmget = ip2_tiocmget, |
456 | .tiocmset = ip2_tiocmset, | 460 | .tiocmset = ip2_tiocmset, |
461 | .get_icount = ip2_get_icount, | ||
457 | .proc_fops = &ip2_proc_fops, | 462 | .proc_fops = &ip2_proc_fops, |
458 | }; | 463 | }; |
459 | 464 | ||
@@ -2128,7 +2133,6 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) | |||
2128 | i2ChanStrPtr pCh = DevTable[tty->index]; | 2133 | i2ChanStrPtr pCh = DevTable[tty->index]; |
2129 | i2eBordStrPtr pB; | 2134 | i2eBordStrPtr pB; |
2130 | struct async_icount cprev, cnow; /* kernel counter temps */ | 2135 | struct async_icount cprev, cnow; /* kernel counter temps */ |
2131 | struct serial_icounter_struct __user *p_cuser; | ||
2132 | int rc = 0; | 2136 | int rc = 0; |
2133 | unsigned long flags; | 2137 | unsigned long flags; |
2134 | void __user *argp = (void __user *)arg; | 2138 | void __user *argp = (void __user *)arg; |
@@ -2297,34 +2301,6 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) | |||
2297 | break; | 2301 | break; |
2298 | 2302 | ||
2299 | /* | 2303 | /* |
2300 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
2301 | * Return: write counters to the user passed counter struct | ||
2302 | * NB: both 1->0 and 0->1 transitions are counted except for RI where | ||
2303 | * only 0->1 is counted. The controller is quite capable of counting | ||
2304 | * both, but this done to preserve compatibility with the standard | ||
2305 | * serial driver. | ||
2306 | */ | ||
2307 | case TIOCGICOUNT: | ||
2308 | ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc ); | ||
2309 | |||
2310 | write_lock_irqsave(&pB->read_fifo_spinlock, flags); | ||
2311 | cnow = pCh->icount; | ||
2312 | write_unlock_irqrestore(&pB->read_fifo_spinlock, flags); | ||
2313 | p_cuser = argp; | ||
2314 | rc = put_user(cnow.cts, &p_cuser->cts); | ||
2315 | rc = put_user(cnow.dsr, &p_cuser->dsr); | ||
2316 | rc = put_user(cnow.rng, &p_cuser->rng); | ||
2317 | rc = put_user(cnow.dcd, &p_cuser->dcd); | ||
2318 | rc = put_user(cnow.rx, &p_cuser->rx); | ||
2319 | rc = put_user(cnow.tx, &p_cuser->tx); | ||
2320 | rc = put_user(cnow.frame, &p_cuser->frame); | ||
2321 | rc = put_user(cnow.overrun, &p_cuser->overrun); | ||
2322 | rc = put_user(cnow.parity, &p_cuser->parity); | ||
2323 | rc = put_user(cnow.brk, &p_cuser->brk); | ||
2324 | rc = put_user(cnow.buf_overrun, &p_cuser->buf_overrun); | ||
2325 | break; | ||
2326 | |||
2327 | /* | ||
2328 | * The rest are not supported by this driver. By returning -ENOIOCTLCMD they | 2304 | * The rest are not supported by this driver. By returning -ENOIOCTLCMD they |
2329 | * will be passed to the line discipline for it to handle. | 2305 | * will be passed to the line discipline for it to handle. |
2330 | */ | 2306 | */ |
@@ -2348,6 +2324,46 @@ ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg ) | |||
2348 | return rc; | 2324 | return rc; |
2349 | } | 2325 | } |
2350 | 2326 | ||
2327 | static int ip2_get_icount(struct tty_struct *tty, | ||
2328 | struct serial_icounter_struct *icount) | ||
2329 | { | ||
2330 | i2ChanStrPtr pCh = DevTable[tty->index]; | ||
2331 | i2eBordStrPtr pB; | ||
2332 | struct async_icount cnow; /* kernel counter temp */ | ||
2333 | unsigned long flags; | ||
2334 | |||
2335 | if ( pCh == NULL ) | ||
2336 | return -ENODEV; | ||
2337 | |||
2338 | pB = pCh->pMyBord; | ||
2339 | |||
2340 | /* | ||
2341 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
2342 | * Return: write counters to the user passed counter struct | ||
2343 | * NB: both 1->0 and 0->1 transitions are counted except for RI where | ||
2344 | * only 0->1 is counted. The controller is quite capable of counting | ||
2345 | * both, but this done to preserve compatibility with the standard | ||
2346 | * serial driver. | ||
2347 | */ | ||
2348 | |||
2349 | write_lock_irqsave(&pB->read_fifo_spinlock, flags); | ||
2350 | cnow = pCh->icount; | ||
2351 | write_unlock_irqrestore(&pB->read_fifo_spinlock, flags); | ||
2352 | |||
2353 | icount->cts = cnow.cts; | ||
2354 | icount->dsr = cnow.dsr; | ||
2355 | icount->rng = cnow.rng; | ||
2356 | icount->dcd = cnow.dcd; | ||
2357 | icount->rx = cnow.rx; | ||
2358 | icount->tx = cnow.tx; | ||
2359 | icount->frame = cnow.frame; | ||
2360 | icount->overrun = cnow.overrun; | ||
2361 | icount->parity = cnow.parity; | ||
2362 | icount->brk = cnow.brk; | ||
2363 | icount->buf_overrun = cnow.buf_overrun; | ||
2364 | return 0; | ||
2365 | } | ||
2366 | |||
2351 | /******************************************************************************/ | 2367 | /******************************************************************************/ |
2352 | /* Function: GetSerialInfo() */ | 2368 | /* Function: GetSerialInfo() */ |
2353 | /* Parameters: Pointer to channel structure */ | 2369 | /* Parameters: Pointer to channel structure */ |
@@ -2897,7 +2913,7 @@ ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg ) | |||
2897 | printk (KERN_DEBUG "IP2IPL: ioctl cmd %d, arg %ld\n", cmd, arg ); | 2913 | printk (KERN_DEBUG "IP2IPL: ioctl cmd %d, arg %ld\n", cmd, arg ); |
2898 | #endif | 2914 | #endif |
2899 | 2915 | ||
2900 | lock_kernel(); | 2916 | mutex_lock(&ip2_mutex); |
2901 | 2917 | ||
2902 | switch ( iplminor ) { | 2918 | switch ( iplminor ) { |
2903 | case 0: // IPL device | 2919 | case 0: // IPL device |
@@ -2961,7 +2977,7 @@ ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg ) | |||
2961 | rc = -ENODEV; | 2977 | rc = -ENODEV; |
2962 | break; | 2978 | break; |
2963 | } | 2979 | } |
2964 | unlock_kernel(); | 2980 | mutex_unlock(&ip2_mutex); |
2965 | return rc; | 2981 | return rc; |
2966 | } | 2982 | } |
2967 | 2983 | ||
@@ -2982,7 +2998,6 @@ ip2_ipl_open( struct inode *pInode, struct file *pFile ) | |||
2982 | #ifdef IP2DEBUG_IPL | 2998 | #ifdef IP2DEBUG_IPL |
2983 | printk (KERN_DEBUG "IP2IPL: open\n" ); | 2999 | printk (KERN_DEBUG "IP2IPL: open\n" ); |
2984 | #endif | 3000 | #endif |
2985 | cycle_kernel_lock(); | ||
2986 | return 0; | 3001 | return 0; |
2987 | } | 3002 | } |
2988 | 3003 | ||
diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile index eb8a1a8c188e..16a93648d54e 100644 --- a/drivers/char/ipmi/Makefile +++ b/drivers/char/ipmi/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the ipmi drivers. | 2 | # Makefile for the ipmi drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | ipmi_si-objs := ipmi_si_intf.o ipmi_kcs_sm.o ipmi_smic_sm.o ipmi_bt_sm.o | 5 | ipmi_si-y := ipmi_si_intf.o ipmi_kcs_sm.o ipmi_smic_sm.o ipmi_bt_sm.o |
6 | 6 | ||
7 | obj-$(CONFIG_IPMI_HANDLER) += ipmi_msghandler.o | 7 | obj-$(CONFIG_IPMI_HANDLER) += ipmi_msghandler.o |
8 | obj-$(CONFIG_IPMI_DEVICE_INTERFACE) += ipmi_devintf.o | 8 | obj-$(CONFIG_IPMI_DEVICE_INTERFACE) += ipmi_devintf.o |
diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c index 7b98c067190a..3ed20e8abc0d 100644 --- a/drivers/char/ipmi/ipmi_bt_sm.c +++ b/drivers/char/ipmi/ipmi_bt_sm.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * ipmi_bt_sm.c | 2 | * ipmi_bt_sm.c |
3 | * | 3 | * |
4 | * The state machine for an Open IPMI BT sub-driver under ipmi_si.c, part | 4 | * The state machine for an Open IPMI BT sub-driver under ipmi_si.c, part |
5 | * of the driver architecture at http://sourceforge.net/project/openipmi | 5 | * of the driver architecture at http://sourceforge.net/projects/openipmi |
6 | * | 6 | * |
7 | * Author: Rocky Craig <first.last@hp.com> | 7 | * Author: Rocky Craig <first.last@hp.com> |
8 | * | 8 | * |
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index d8ec92a38980..2aa3977aae5e 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c | |||
@@ -44,7 +44,6 @@ | |||
44 | #include <linux/init.h> | 44 | #include <linux/init.h> |
45 | #include <linux/device.h> | 45 | #include <linux/device.h> |
46 | #include <linux/compat.h> | 46 | #include <linux/compat.h> |
47 | #include <linux/smp_lock.h> | ||
48 | 47 | ||
49 | struct ipmi_file_private | 48 | struct ipmi_file_private |
50 | { | 49 | { |
@@ -59,6 +58,7 @@ struct ipmi_file_private | |||
59 | unsigned int default_retry_time_ms; | 58 | unsigned int default_retry_time_ms; |
60 | }; | 59 | }; |
61 | 60 | ||
61 | static DEFINE_MUTEX(ipmi_mutex); | ||
62 | static void file_receive_handler(struct ipmi_recv_msg *msg, | 62 | static void file_receive_handler(struct ipmi_recv_msg *msg, |
63 | void *handler_data) | 63 | void *handler_data) |
64 | { | 64 | { |
@@ -102,9 +102,9 @@ static int ipmi_fasync(int fd, struct file *file, int on) | |||
102 | struct ipmi_file_private *priv = file->private_data; | 102 | struct ipmi_file_private *priv = file->private_data; |
103 | int result; | 103 | int result; |
104 | 104 | ||
105 | lock_kernel(); /* could race against open() otherwise */ | 105 | mutex_lock(&ipmi_mutex); /* could race against open() otherwise */ |
106 | result = fasync_helper(fd, file, on, &priv->fasync_queue); | 106 | result = fasync_helper(fd, file, on, &priv->fasync_queue); |
107 | unlock_kernel(); | 107 | mutex_unlock(&ipmi_mutex); |
108 | 108 | ||
109 | return (result); | 109 | return (result); |
110 | } | 110 | } |
@@ -125,7 +125,7 @@ static int ipmi_open(struct inode *inode, struct file *file) | |||
125 | if (!priv) | 125 | if (!priv) |
126 | return -ENOMEM; | 126 | return -ENOMEM; |
127 | 127 | ||
128 | lock_kernel(); | 128 | mutex_lock(&ipmi_mutex); |
129 | priv->file = file; | 129 | priv->file = file; |
130 | 130 | ||
131 | rv = ipmi_create_user(if_num, | 131 | rv = ipmi_create_user(if_num, |
@@ -150,7 +150,7 @@ static int ipmi_open(struct inode *inode, struct file *file) | |||
150 | priv->default_retry_time_ms = 0; | 150 | priv->default_retry_time_ms = 0; |
151 | 151 | ||
152 | out: | 152 | out: |
153 | unlock_kernel(); | 153 | mutex_unlock(&ipmi_mutex); |
154 | return rv; | 154 | return rv; |
155 | } | 155 | } |
156 | 156 | ||
@@ -639,9 +639,9 @@ static long ipmi_unlocked_ioctl(struct file *file, | |||
639 | { | 639 | { |
640 | int ret; | 640 | int ret; |
641 | 641 | ||
642 | lock_kernel(); | 642 | mutex_lock(&ipmi_mutex); |
643 | ret = ipmi_ioctl(file, cmd, data); | 643 | ret = ipmi_ioctl(file, cmd, data); |
644 | unlock_kernel(); | 644 | mutex_unlock(&ipmi_mutex); |
645 | 645 | ||
646 | return ret; | 646 | return ret; |
647 | } | 647 | } |
@@ -850,6 +850,7 @@ static const struct file_operations ipmi_fops = { | |||
850 | .release = ipmi_release, | 850 | .release = ipmi_release, |
851 | .fasync = ipmi_fasync, | 851 | .fasync = ipmi_fasync, |
852 | .poll = ipmi_poll, | 852 | .poll = ipmi_poll, |
853 | .llseek = noop_llseek, | ||
853 | }; | 854 | }; |
854 | 855 | ||
855 | #define DEVICE_NAME "ipmidev" | 856 | #define DEVICE_NAME "ipmidev" |
@@ -915,7 +916,7 @@ static struct ipmi_smi_watcher smi_watcher = | |||
915 | .smi_gone = ipmi_smi_gone, | 916 | .smi_gone = ipmi_smi_gone, |
916 | }; | 917 | }; |
917 | 918 | ||
918 | static __init int init_ipmi_devintf(void) | 919 | static int __init init_ipmi_devintf(void) |
919 | { | 920 | { |
920 | int rv; | 921 | int rv; |
921 | 922 | ||
@@ -953,7 +954,7 @@ static __init int init_ipmi_devintf(void) | |||
953 | } | 954 | } |
954 | module_init(init_ipmi_devintf); | 955 | module_init(init_ipmi_devintf); |
955 | 956 | ||
956 | static __exit void cleanup_ipmi(void) | 957 | static void __exit cleanup_ipmi(void) |
957 | { | 958 | { |
958 | struct ipmi_reg_list *entry, *entry2; | 959 | struct ipmi_reg_list *entry, *entry2; |
959 | mutex_lock(®_list_mutex); | 960 | mutex_lock(®_list_mutex); |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 4f3f8c9ec262..2fe72f8edf44 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -4442,13 +4442,13 @@ static int ipmi_init_msghandler(void) | |||
4442 | return 0; | 4442 | return 0; |
4443 | } | 4443 | } |
4444 | 4444 | ||
4445 | static __init int ipmi_init_msghandler_mod(void) | 4445 | static int __init ipmi_init_msghandler_mod(void) |
4446 | { | 4446 | { |
4447 | ipmi_init_msghandler(); | 4447 | ipmi_init_msghandler(); |
4448 | return 0; | 4448 | return 0; |
4449 | } | 4449 | } |
4450 | 4450 | ||
4451 | static __exit void cleanup_ipmi(void) | 4451 | static void __exit cleanup_ipmi(void) |
4452 | { | 4452 | { |
4453 | int count; | 4453 | int count; |
4454 | 4454 | ||
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 7bd7c45b53ef..035da9e64a17 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -1665,6 +1665,17 @@ static int check_hotmod_int_op(const char *curr, const char *option, | |||
1665 | return 0; | 1665 | return 0; |
1666 | } | 1666 | } |
1667 | 1667 | ||
1668 | static struct smi_info *smi_info_alloc(void) | ||
1669 | { | ||
1670 | struct smi_info *info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
1671 | |||
1672 | if (info) { | ||
1673 | spin_lock_init(&info->si_lock); | ||
1674 | spin_lock_init(&info->msg_lock); | ||
1675 | } | ||
1676 | return info; | ||
1677 | } | ||
1678 | |||
1668 | static int hotmod_handler(const char *val, struct kernel_param *kp) | 1679 | static int hotmod_handler(const char *val, struct kernel_param *kp) |
1669 | { | 1680 | { |
1670 | char *str = kstrdup(val, GFP_KERNEL); | 1681 | char *str = kstrdup(val, GFP_KERNEL); |
@@ -1779,7 +1790,7 @@ static int hotmod_handler(const char *val, struct kernel_param *kp) | |||
1779 | } | 1790 | } |
1780 | 1791 | ||
1781 | if (op == HM_ADD) { | 1792 | if (op == HM_ADD) { |
1782 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 1793 | info = smi_info_alloc(); |
1783 | if (!info) { | 1794 | if (!info) { |
1784 | rv = -ENOMEM; | 1795 | rv = -ENOMEM; |
1785 | goto out; | 1796 | goto out; |
@@ -1835,7 +1846,7 @@ static int hotmod_handler(const char *val, struct kernel_param *kp) | |||
1835 | return rv; | 1846 | return rv; |
1836 | } | 1847 | } |
1837 | 1848 | ||
1838 | static __devinit void hardcode_find_bmc(void) | 1849 | static void __devinit hardcode_find_bmc(void) |
1839 | { | 1850 | { |
1840 | int i; | 1851 | int i; |
1841 | struct smi_info *info; | 1852 | struct smi_info *info; |
@@ -1844,7 +1855,7 @@ static __devinit void hardcode_find_bmc(void) | |||
1844 | if (!ports[i] && !addrs[i]) | 1855 | if (!ports[i] && !addrs[i]) |
1845 | continue; | 1856 | continue; |
1846 | 1857 | ||
1847 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 1858 | info = smi_info_alloc(); |
1848 | if (!info) | 1859 | if (!info) |
1849 | return; | 1860 | return; |
1850 | 1861 | ||
@@ -1974,8 +1985,7 @@ static int acpi_gpe_irq_setup(struct smi_info *info) | |||
1974 | 1985 | ||
1975 | /* | 1986 | /* |
1976 | * Defined at | 1987 | * Defined at |
1977 | * http://h21007.www2.hp.com/portal/download/files | 1988 | * http://h21007.www2.hp.com/portal/download/files/unprot/hpspmi.pdf |
1978 | * /unprot/hpspmi.pdf | ||
1979 | */ | 1989 | */ |
1980 | struct SPMITable { | 1990 | struct SPMITable { |
1981 | s8 Signature[4]; | 1991 | s8 Signature[4]; |
@@ -2019,7 +2029,7 @@ struct SPMITable { | |||
2019 | s8 spmi_id[1]; /* A '\0' terminated array starts here. */ | 2029 | s8 spmi_id[1]; /* A '\0' terminated array starts here. */ |
2020 | }; | 2030 | }; |
2021 | 2031 | ||
2022 | static __devinit int try_init_spmi(struct SPMITable *spmi) | 2032 | static int __devinit try_init_spmi(struct SPMITable *spmi) |
2023 | { | 2033 | { |
2024 | struct smi_info *info; | 2034 | struct smi_info *info; |
2025 | 2035 | ||
@@ -2028,7 +2038,7 @@ static __devinit int try_init_spmi(struct SPMITable *spmi) | |||
2028 | return -ENODEV; | 2038 | return -ENODEV; |
2029 | } | 2039 | } |
2030 | 2040 | ||
2031 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 2041 | info = smi_info_alloc(); |
2032 | if (!info) { | 2042 | if (!info) { |
2033 | printk(KERN_ERR PFX "Could not allocate SI data (3)\n"); | 2043 | printk(KERN_ERR PFX "Could not allocate SI data (3)\n"); |
2034 | return -ENOMEM; | 2044 | return -ENOMEM; |
@@ -2102,7 +2112,7 @@ static __devinit int try_init_spmi(struct SPMITable *spmi) | |||
2102 | return 0; | 2112 | return 0; |
2103 | } | 2113 | } |
2104 | 2114 | ||
2105 | static __devinit void spmi_find_bmc(void) | 2115 | static void __devinit spmi_find_bmc(void) |
2106 | { | 2116 | { |
2107 | acpi_status status; | 2117 | acpi_status status; |
2108 | struct SPMITable *spmi; | 2118 | struct SPMITable *spmi; |
@@ -2138,7 +2148,7 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, | |||
2138 | if (!acpi_dev) | 2148 | if (!acpi_dev) |
2139 | return -ENODEV; | 2149 | return -ENODEV; |
2140 | 2150 | ||
2141 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 2151 | info = smi_info_alloc(); |
2142 | if (!info) | 2152 | if (!info) |
2143 | return -ENOMEM; | 2153 | return -ENOMEM; |
2144 | 2154 | ||
@@ -2315,11 +2325,11 @@ static int __devinit decode_dmi(const struct dmi_header *dm, | |||
2315 | return 0; | 2325 | return 0; |
2316 | } | 2326 | } |
2317 | 2327 | ||
2318 | static __devinit void try_init_dmi(struct dmi_ipmi_data *ipmi_data) | 2328 | static void __devinit try_init_dmi(struct dmi_ipmi_data *ipmi_data) |
2319 | { | 2329 | { |
2320 | struct smi_info *info; | 2330 | struct smi_info *info; |
2321 | 2331 | ||
2322 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 2332 | info = smi_info_alloc(); |
2323 | if (!info) { | 2333 | if (!info) { |
2324 | printk(KERN_ERR PFX "Could not allocate SI data\n"); | 2334 | printk(KERN_ERR PFX "Could not allocate SI data\n"); |
2325 | return; | 2335 | return; |
@@ -2426,7 +2436,7 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, | |||
2426 | int class_type = pdev->class & PCI_ERMC_CLASSCODE_TYPE_MASK; | 2436 | int class_type = pdev->class & PCI_ERMC_CLASSCODE_TYPE_MASK; |
2427 | struct smi_info *info; | 2437 | struct smi_info *info; |
2428 | 2438 | ||
2429 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 2439 | info = smi_info_alloc(); |
2430 | if (!info) | 2440 | if (!info) |
2431 | return -ENOMEM; | 2441 | return -ENOMEM; |
2432 | 2442 | ||
@@ -2567,7 +2577,7 @@ static int __devinit ipmi_of_probe(struct platform_device *dev, | |||
2567 | return -EINVAL; | 2577 | return -EINVAL; |
2568 | } | 2578 | } |
2569 | 2579 | ||
2570 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 2580 | info = smi_info_alloc(); |
2571 | 2581 | ||
2572 | if (!info) { | 2582 | if (!info) { |
2573 | dev_err(&dev->dev, | 2583 | dev_err(&dev->dev, |
@@ -3002,7 +3012,7 @@ static __devinitdata struct ipmi_default_vals | |||
3002 | { .port = 0 } | 3012 | { .port = 0 } |
3003 | }; | 3013 | }; |
3004 | 3014 | ||
3005 | static __devinit void default_find_bmc(void) | 3015 | static void __devinit default_find_bmc(void) |
3006 | { | 3016 | { |
3007 | struct smi_info *info; | 3017 | struct smi_info *info; |
3008 | int i; | 3018 | int i; |
@@ -3014,7 +3024,7 @@ static __devinit void default_find_bmc(void) | |||
3014 | if (check_legacy_ioport(ipmi_defaults[i].port)) | 3024 | if (check_legacy_ioport(ipmi_defaults[i].port)) |
3015 | continue; | 3025 | continue; |
3016 | #endif | 3026 | #endif |
3017 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 3027 | info = smi_info_alloc(); |
3018 | if (!info) | 3028 | if (!info) |
3019 | return; | 3029 | return; |
3020 | 3030 | ||
@@ -3139,9 +3149,6 @@ static int try_smi_init(struct smi_info *new_smi) | |||
3139 | goto out_err; | 3149 | goto out_err; |
3140 | } | 3150 | } |
3141 | 3151 | ||
3142 | spin_lock_init(&(new_smi->si_lock)); | ||
3143 | spin_lock_init(&(new_smi->msg_lock)); | ||
3144 | |||
3145 | /* Do low-level detection first. */ | 3152 | /* Do low-level detection first. */ |
3146 | if (new_smi->handlers->detect(new_smi->si_sm)) { | 3153 | if (new_smi->handlers->detect(new_smi->si_sm)) { |
3147 | if (new_smi->addr_source) | 3154 | if (new_smi->addr_source) |
@@ -3305,7 +3312,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
3305 | return rv; | 3312 | return rv; |
3306 | } | 3313 | } |
3307 | 3314 | ||
3308 | static __devinit int init_ipmi_si(void) | 3315 | static int __devinit init_ipmi_si(void) |
3309 | { | 3316 | { |
3310 | int i; | 3317 | int i; |
3311 | char *str; | 3318 | char *str; |
@@ -3518,7 +3525,7 @@ static void cleanup_one_si(struct smi_info *to_clean) | |||
3518 | kfree(to_clean); | 3525 | kfree(to_clean); |
3519 | } | 3526 | } |
3520 | 3527 | ||
3521 | static __exit void cleanup_ipmi_si(void) | 3528 | static void __exit cleanup_ipmi_si(void) |
3522 | { | 3529 | { |
3523 | struct smi_info *e, *tmp_e; | 3530 | struct smi_info *e, *tmp_e; |
3524 | 3531 | ||
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 654d566ca57c..f4d334f2536e 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <linux/moduleparam.h> | 35 | #include <linux/moduleparam.h> |
36 | #include <linux/ipmi.h> | 36 | #include <linux/ipmi.h> |
37 | #include <linux/ipmi_smi.h> | 37 | #include <linux/ipmi_smi.h> |
38 | #include <linux/smp_lock.h> | 38 | #include <linux/mutex.h> |
39 | #include <linux/watchdog.h> | 39 | #include <linux/watchdog.h> |
40 | #include <linux/miscdevice.h> | 40 | #include <linux/miscdevice.h> |
41 | #include <linux/init.h> | 41 | #include <linux/init.h> |
@@ -149,6 +149,7 @@ | |||
149 | #define WDIOC_GET_PRETIMEOUT _IOW(WATCHDOG_IOCTL_BASE, 22, int) | 149 | #define WDIOC_GET_PRETIMEOUT _IOW(WATCHDOG_IOCTL_BASE, 22, int) |
150 | #endif | 150 | #endif |
151 | 151 | ||
152 | static DEFINE_MUTEX(ipmi_watchdog_mutex); | ||
152 | static int nowayout = WATCHDOG_NOWAYOUT; | 153 | static int nowayout = WATCHDOG_NOWAYOUT; |
153 | 154 | ||
154 | static ipmi_user_t watchdog_user; | 155 | static ipmi_user_t watchdog_user; |
@@ -748,9 +749,9 @@ static long ipmi_unlocked_ioctl(struct file *file, | |||
748 | { | 749 | { |
749 | int ret; | 750 | int ret; |
750 | 751 | ||
751 | lock_kernel(); | 752 | mutex_lock(&ipmi_watchdog_mutex); |
752 | ret = ipmi_ioctl(file, cmd, arg); | 753 | ret = ipmi_ioctl(file, cmd, arg); |
753 | unlock_kernel(); | 754 | mutex_unlock(&ipmi_watchdog_mutex); |
754 | 755 | ||
755 | return ret; | 756 | return ret; |
756 | } | 757 | } |
@@ -844,7 +845,6 @@ static int ipmi_open(struct inode *ino, struct file *filep) | |||
844 | if (test_and_set_bit(0, &ipmi_wdog_open)) | 845 | if (test_and_set_bit(0, &ipmi_wdog_open)) |
845 | return -EBUSY; | 846 | return -EBUSY; |
846 | 847 | ||
847 | cycle_kernel_lock(); | ||
848 | 848 | ||
849 | /* | 849 | /* |
850 | * Don't start the timer now, let it start on the | 850 | * Don't start the timer now, let it start on the |
@@ -909,6 +909,7 @@ static const struct file_operations ipmi_wdog_fops = { | |||
909 | .open = ipmi_open, | 909 | .open = ipmi_open, |
910 | .release = ipmi_close, | 910 | .release = ipmi_close, |
911 | .fasync = ipmi_fasync, | 911 | .fasync = ipmi_fasync, |
912 | .llseek = no_llseek, | ||
912 | }; | 913 | }; |
913 | 914 | ||
914 | static struct miscdevice ipmi_wdog_miscdev = { | 915 | static struct miscdevice ipmi_wdog_miscdev = { |
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index be28391adb79..667abd23ad6a 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -704,6 +704,7 @@ static const struct file_operations stli_fsiomem = { | |||
704 | .read = stli_memread, | 704 | .read = stli_memread, |
705 | .write = stli_memwrite, | 705 | .write = stli_memwrite, |
706 | .unlocked_ioctl = stli_memioctl, | 706 | .unlocked_ioctl = stli_memioctl, |
707 | .llseek = default_llseek, | ||
707 | }; | 708 | }; |
708 | 709 | ||
709 | /*****************************************************************************/ | 710 | /*****************************************************************************/ |
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index a7ca75212bfe..e95d7876ca6b 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -175,8 +175,7 @@ EXPORT_SYMBOL_GPL(unregister_keyboard_notifier); | |||
175 | */ | 175 | */ |
176 | 176 | ||
177 | struct getset_keycode_data { | 177 | struct getset_keycode_data { |
178 | unsigned int scancode; | 178 | struct input_keymap_entry ke; |
179 | unsigned int keycode; | ||
180 | int error; | 179 | int error; |
181 | }; | 180 | }; |
182 | 181 | ||
@@ -184,32 +183,50 @@ static int getkeycode_helper(struct input_handle *handle, void *data) | |||
184 | { | 183 | { |
185 | struct getset_keycode_data *d = data; | 184 | struct getset_keycode_data *d = data; |
186 | 185 | ||
187 | d->error = input_get_keycode(handle->dev, d->scancode, &d->keycode); | 186 | d->error = input_get_keycode(handle->dev, &d->ke); |
188 | 187 | ||
189 | return d->error == 0; /* stop as soon as we successfully get one */ | 188 | return d->error == 0; /* stop as soon as we successfully get one */ |
190 | } | 189 | } |
191 | 190 | ||
192 | int getkeycode(unsigned int scancode) | 191 | int getkeycode(unsigned int scancode) |
193 | { | 192 | { |
194 | struct getset_keycode_data d = { scancode, 0, -ENODEV }; | 193 | struct getset_keycode_data d = { |
194 | .ke = { | ||
195 | .flags = 0, | ||
196 | .len = sizeof(scancode), | ||
197 | .keycode = 0, | ||
198 | }, | ||
199 | .error = -ENODEV, | ||
200 | }; | ||
201 | |||
202 | memcpy(d.ke.scancode, &scancode, sizeof(scancode)); | ||
195 | 203 | ||
196 | input_handler_for_each_handle(&kbd_handler, &d, getkeycode_helper); | 204 | input_handler_for_each_handle(&kbd_handler, &d, getkeycode_helper); |
197 | 205 | ||
198 | return d.error ?: d.keycode; | 206 | return d.error ?: d.ke.keycode; |
199 | } | 207 | } |
200 | 208 | ||
201 | static int setkeycode_helper(struct input_handle *handle, void *data) | 209 | static int setkeycode_helper(struct input_handle *handle, void *data) |
202 | { | 210 | { |
203 | struct getset_keycode_data *d = data; | 211 | struct getset_keycode_data *d = data; |
204 | 212 | ||
205 | d->error = input_set_keycode(handle->dev, d->scancode, d->keycode); | 213 | d->error = input_set_keycode(handle->dev, &d->ke); |
206 | 214 | ||
207 | return d->error == 0; /* stop as soon as we successfully set one */ | 215 | return d->error == 0; /* stop as soon as we successfully set one */ |
208 | } | 216 | } |
209 | 217 | ||
210 | int setkeycode(unsigned int scancode, unsigned int keycode) | 218 | int setkeycode(unsigned int scancode, unsigned int keycode) |
211 | { | 219 | { |
212 | struct getset_keycode_data d = { scancode, keycode, -ENODEV }; | 220 | struct getset_keycode_data d = { |
221 | .ke = { | ||
222 | .flags = 0, | ||
223 | .len = sizeof(scancode), | ||
224 | .keycode = keycode, | ||
225 | }, | ||
226 | .error = -ENODEV, | ||
227 | }; | ||
228 | |||
229 | memcpy(d.ke.scancode, &scancode, sizeof(scancode)); | ||
213 | 230 | ||
214 | input_handler_for_each_handle(&kbd_handler, &d, setkeycode_helper); | 231 | input_handler_for_each_handle(&kbd_handler, &d, setkeycode_helper); |
215 | 232 | ||
diff --git a/drivers/char/lp.c b/drivers/char/lp.c index 938a3a273886..97c3edb95ae7 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c | |||
@@ -126,7 +126,7 @@ | |||
126 | #include <linux/device.h> | 126 | #include <linux/device.h> |
127 | #include <linux/wait.h> | 127 | #include <linux/wait.h> |
128 | #include <linux/jiffies.h> | 128 | #include <linux/jiffies.h> |
129 | #include <linux/smp_lock.h> | 129 | #include <linux/mutex.h> |
130 | #include <linux/compat.h> | 130 | #include <linux/compat.h> |
131 | 131 | ||
132 | #include <linux/parport.h> | 132 | #include <linux/parport.h> |
@@ -140,6 +140,7 @@ | |||
140 | /* if you have more than 8 printers, remember to increase LP_NO */ | 140 | /* if you have more than 8 printers, remember to increase LP_NO */ |
141 | #define LP_NO 8 | 141 | #define LP_NO 8 |
142 | 142 | ||
143 | static DEFINE_MUTEX(lp_mutex); | ||
143 | static struct lp_struct lp_table[LP_NO]; | 144 | static struct lp_struct lp_table[LP_NO]; |
144 | 145 | ||
145 | static unsigned int lp_count = 0; | 146 | static unsigned int lp_count = 0; |
@@ -493,7 +494,7 @@ static int lp_open(struct inode * inode, struct file * file) | |||
493 | unsigned int minor = iminor(inode); | 494 | unsigned int minor = iminor(inode); |
494 | int ret = 0; | 495 | int ret = 0; |
495 | 496 | ||
496 | lock_kernel(); | 497 | mutex_lock(&lp_mutex); |
497 | if (minor >= LP_NO) { | 498 | if (minor >= LP_NO) { |
498 | ret = -ENXIO; | 499 | ret = -ENXIO; |
499 | goto out; | 500 | goto out; |
@@ -554,7 +555,7 @@ static int lp_open(struct inode * inode, struct file * file) | |||
554 | lp_release_parport (&lp_table[minor]); | 555 | lp_release_parport (&lp_table[minor]); |
555 | lp_table[minor].current_mode = IEEE1284_MODE_COMPAT; | 556 | lp_table[minor].current_mode = IEEE1284_MODE_COMPAT; |
556 | out: | 557 | out: |
557 | unlock_kernel(); | 558 | mutex_unlock(&lp_mutex); |
558 | return ret; | 559 | return ret; |
559 | } | 560 | } |
560 | 561 | ||
@@ -680,7 +681,7 @@ static long lp_ioctl(struct file *file, unsigned int cmd, | |||
680 | int ret; | 681 | int ret; |
681 | 682 | ||
682 | minor = iminor(file->f_path.dentry->d_inode); | 683 | minor = iminor(file->f_path.dentry->d_inode); |
683 | lock_kernel(); | 684 | mutex_lock(&lp_mutex); |
684 | switch (cmd) { | 685 | switch (cmd) { |
685 | case LPSETTIMEOUT: | 686 | case LPSETTIMEOUT: |
686 | if (copy_from_user(&par_timeout, (void __user *)arg, | 687 | if (copy_from_user(&par_timeout, (void __user *)arg, |
@@ -694,7 +695,7 @@ static long lp_ioctl(struct file *file, unsigned int cmd, | |||
694 | ret = lp_do_ioctl(minor, cmd, arg, (void __user *)arg); | 695 | ret = lp_do_ioctl(minor, cmd, arg, (void __user *)arg); |
695 | break; | 696 | break; |
696 | } | 697 | } |
697 | unlock_kernel(); | 698 | mutex_unlock(&lp_mutex); |
698 | 699 | ||
699 | return ret; | 700 | return ret; |
700 | } | 701 | } |
@@ -709,7 +710,7 @@ static long lp_compat_ioctl(struct file *file, unsigned int cmd, | |||
709 | int ret; | 710 | int ret; |
710 | 711 | ||
711 | minor = iminor(file->f_path.dentry->d_inode); | 712 | minor = iminor(file->f_path.dentry->d_inode); |
712 | lock_kernel(); | 713 | mutex_lock(&lp_mutex); |
713 | switch (cmd) { | 714 | switch (cmd) { |
714 | case LPSETTIMEOUT: | 715 | case LPSETTIMEOUT: |
715 | tc = compat_ptr(arg); | 716 | tc = compat_ptr(arg); |
@@ -730,7 +731,7 @@ static long lp_compat_ioctl(struct file *file, unsigned int cmd, | |||
730 | ret = lp_do_ioctl(minor, cmd, arg, compat_ptr(arg)); | 731 | ret = lp_do_ioctl(minor, cmd, arg, compat_ptr(arg)); |
731 | break; | 732 | break; |
732 | } | 733 | } |
733 | unlock_kernel(); | 734 | mutex_unlock(&lp_mutex); |
734 | 735 | ||
735 | return ret; | 736 | return ret; |
736 | } | 737 | } |
@@ -748,6 +749,7 @@ static const struct file_operations lp_fops = { | |||
748 | #ifdef CONFIG_PARPORT_1284 | 749 | #ifdef CONFIG_PARPORT_1284 |
749 | .read = lp_read, | 750 | .read = lp_read, |
750 | #endif | 751 | #endif |
752 | .llseek = noop_llseek, | ||
751 | }; | 753 | }; |
752 | 754 | ||
753 | /* --- support for console on the line printer ----------------- */ | 755 | /* --- support for console on the line printer ----------------- */ |
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c index 83bef4efe376..1aeaaba680d2 100644 --- a/drivers/char/mbcs.c +++ b/drivers/char/mbcs.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/mm.h> | 25 | #include <linux/mm.h> |
26 | #include <linux/uio.h> | 26 | #include <linux/uio.h> |
27 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
28 | #include <linux/smp_lock.h> | ||
29 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
30 | #include <asm/io.h> | 29 | #include <asm/io.h> |
31 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
@@ -42,6 +41,7 @@ | |||
42 | #else | 41 | #else |
43 | #define DBG(fmt...) | 42 | #define DBG(fmt...) |
44 | #endif | 43 | #endif |
44 | static DEFINE_MUTEX(mbcs_mutex); | ||
45 | static int mbcs_major; | 45 | static int mbcs_major; |
46 | 46 | ||
47 | static LIST_HEAD(soft_list); | 47 | static LIST_HEAD(soft_list); |
@@ -385,19 +385,19 @@ static int mbcs_open(struct inode *ip, struct file *fp) | |||
385 | struct mbcs_soft *soft; | 385 | struct mbcs_soft *soft; |
386 | int minor; | 386 | int minor; |
387 | 387 | ||
388 | lock_kernel(); | 388 | mutex_lock(&mbcs_mutex); |
389 | minor = iminor(ip); | 389 | minor = iminor(ip); |
390 | 390 | ||
391 | /* Nothing protects access to this list... */ | 391 | /* Nothing protects access to this list... */ |
392 | list_for_each_entry(soft, &soft_list, list) { | 392 | list_for_each_entry(soft, &soft_list, list) { |
393 | if (soft->nasid == minor) { | 393 | if (soft->nasid == minor) { |
394 | fp->private_data = soft->cxdev; | 394 | fp->private_data = soft->cxdev; |
395 | unlock_kernel(); | 395 | mutex_unlock(&mbcs_mutex); |
396 | return 0; | 396 | return 0; |
397 | } | 397 | } |
398 | } | 398 | } |
399 | 399 | ||
400 | unlock_kernel(); | 400 | mutex_unlock(&mbcs_mutex); |
401 | return -ENODEV; | 401 | return -ENODEV; |
402 | } | 402 | } |
403 | 403 | ||
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 1f528fad3516..1256454b2d43 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -805,6 +805,7 @@ static const struct file_operations full_fops = { | |||
805 | static const struct file_operations oldmem_fops = { | 805 | static const struct file_operations oldmem_fops = { |
806 | .read = read_oldmem, | 806 | .read = read_oldmem, |
807 | .open = open_oldmem, | 807 | .open = open_oldmem, |
808 | .llseek = default_llseek, | ||
808 | }; | 809 | }; |
809 | #endif | 810 | #endif |
810 | 811 | ||
@@ -831,6 +832,7 @@ static ssize_t kmsg_write(struct file *file, const char __user *buf, | |||
831 | 832 | ||
832 | static const struct file_operations kmsg_fops = { | 833 | static const struct file_operations kmsg_fops = { |
833 | .write = kmsg_write, | 834 | .write = kmsg_write, |
835 | .llseek = noop_llseek, | ||
834 | }; | 836 | }; |
835 | 837 | ||
836 | static const struct memdev { | 838 | static const struct memdev { |
@@ -874,6 +876,10 @@ static int memory_open(struct inode *inode, struct file *filp) | |||
874 | if (dev->dev_info) | 876 | if (dev->dev_info) |
875 | filp->f_mapping->backing_dev_info = dev->dev_info; | 877 | filp->f_mapping->backing_dev_info = dev->dev_info; |
876 | 878 | ||
879 | /* Is /dev/mem or /dev/kmem ? */ | ||
880 | if (dev->dev_info == &directly_mappable_cdev_bdi) | ||
881 | filp->f_mode |= FMODE_UNSIGNED_OFFSET; | ||
882 | |||
877 | if (dev->fops->open) | 883 | if (dev->fops->open) |
878 | return dev->fops->open(inode, filp); | 884 | return dev->fops->open(inode, filp); |
879 | 885 | ||
@@ -882,6 +888,7 @@ static int memory_open(struct inode *inode, struct file *filp) | |||
882 | 888 | ||
883 | static const struct file_operations memory_fops = { | 889 | static const struct file_operations memory_fops = { |
884 | .open = memory_open, | 890 | .open = memory_open, |
891 | .llseek = noop_llseek, | ||
885 | }; | 892 | }; |
886 | 893 | ||
887 | static char *mem_devnode(struct device *dev, mode_t *mode) | 894 | static char *mem_devnode(struct device *dev, mode_t *mode) |
diff --git a/drivers/char/misc.c b/drivers/char/misc.c index abdafd488980..778273c93242 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c | |||
@@ -162,6 +162,7 @@ static struct class *misc_class; | |||
162 | static const struct file_operations misc_fops = { | 162 | static const struct file_operations misc_fops = { |
163 | .owner = THIS_MODULE, | 163 | .owner = THIS_MODULE, |
164 | .open = misc_open, | 164 | .open = misc_open, |
165 | .llseek = noop_llseek, | ||
165 | }; | 166 | }; |
166 | 167 | ||
167 | /** | 168 | /** |
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index ea7c99fa978f..e6d75627c6c8 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
33 | #include <linux/time.h> | 33 | #include <linux/time.h> |
34 | #include <linux/math64.h> | 34 | #include <linux/math64.h> |
35 | #include <linux/smp_lock.h> | 35 | #include <linux/mutex.h> |
36 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
37 | 37 | ||
38 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
@@ -59,6 +59,7 @@ extern unsigned long sn_rtc_cycles_per_second; | |||
59 | 59 | ||
60 | #define rtc_time() (*RTC_COUNTER_ADDR) | 60 | #define rtc_time() (*RTC_COUNTER_ADDR) |
61 | 61 | ||
62 | static DEFINE_MUTEX(mmtimer_mutex); | ||
62 | static long mmtimer_ioctl(struct file *file, unsigned int cmd, | 63 | static long mmtimer_ioctl(struct file *file, unsigned int cmd, |
63 | unsigned long arg); | 64 | unsigned long arg); |
64 | static int mmtimer_mmap(struct file *file, struct vm_area_struct *vma); | 65 | static int mmtimer_mmap(struct file *file, struct vm_area_struct *vma); |
@@ -72,6 +73,7 @@ static const struct file_operations mmtimer_fops = { | |||
72 | .owner = THIS_MODULE, | 73 | .owner = THIS_MODULE, |
73 | .mmap = mmtimer_mmap, | 74 | .mmap = mmtimer_mmap, |
74 | .unlocked_ioctl = mmtimer_ioctl, | 75 | .unlocked_ioctl = mmtimer_ioctl, |
76 | .llseek = noop_llseek, | ||
75 | }; | 77 | }; |
76 | 78 | ||
77 | /* | 79 | /* |
@@ -174,9 +176,9 @@ static void mmtimer_setup_int_2(int cpu, u64 expires) | |||
174 | * in order to insure that the setup succeeds in a deterministic time frame. | 176 | * in order to insure that the setup succeeds in a deterministic time frame. |
175 | * It will check if the interrupt setup succeeded. | 177 | * It will check if the interrupt setup succeeded. |
176 | */ | 178 | */ |
177 | static int mmtimer_setup(int cpu, int comparator, unsigned long expires) | 179 | static int mmtimer_setup(int cpu, int comparator, unsigned long expires, |
180 | u64 *set_completion_time) | ||
178 | { | 181 | { |
179 | |||
180 | switch (comparator) { | 182 | switch (comparator) { |
181 | case 0: | 183 | case 0: |
182 | mmtimer_setup_int_0(cpu, expires); | 184 | mmtimer_setup_int_0(cpu, expires); |
@@ -189,7 +191,8 @@ static int mmtimer_setup(int cpu, int comparator, unsigned long expires) | |||
189 | break; | 191 | break; |
190 | } | 192 | } |
191 | /* We might've missed our expiration time */ | 193 | /* We might've missed our expiration time */ |
192 | if (rtc_time() <= expires) | 194 | *set_completion_time = rtc_time(); |
195 | if (*set_completion_time <= expires) | ||
193 | return 1; | 196 | return 1; |
194 | 197 | ||
195 | /* | 198 | /* |
@@ -225,6 +228,8 @@ static int mmtimer_disable_int(long nasid, int comparator) | |||
225 | #define TIMER_OFF 0xbadcabLL /* Timer is not setup */ | 228 | #define TIMER_OFF 0xbadcabLL /* Timer is not setup */ |
226 | #define TIMER_SET 0 /* Comparator is set for this timer */ | 229 | #define TIMER_SET 0 /* Comparator is set for this timer */ |
227 | 230 | ||
231 | #define MMTIMER_INTERVAL_RETRY_INCREMENT_DEFAULT 40 | ||
232 | |||
228 | /* There is one of these for each timer */ | 233 | /* There is one of these for each timer */ |
229 | struct mmtimer { | 234 | struct mmtimer { |
230 | struct rb_node list; | 235 | struct rb_node list; |
@@ -240,6 +245,11 @@ struct mmtimer_node { | |||
240 | }; | 245 | }; |
241 | static struct mmtimer_node *timers; | 246 | static struct mmtimer_node *timers; |
242 | 247 | ||
248 | static unsigned mmtimer_interval_retry_increment = | ||
249 | MMTIMER_INTERVAL_RETRY_INCREMENT_DEFAULT; | ||
250 | module_param(mmtimer_interval_retry_increment, uint, 0644); | ||
251 | MODULE_PARM_DESC(mmtimer_interval_retry_increment, | ||
252 | "RTC ticks to add to expiration on interval retry (default 40)"); | ||
243 | 253 | ||
244 | /* | 254 | /* |
245 | * Add a new mmtimer struct to the node's mmtimer list. | 255 | * Add a new mmtimer struct to the node's mmtimer list. |
@@ -287,7 +297,8 @@ static void mmtimer_set_next_timer(int nodeid) | |||
287 | struct mmtimer_node *n = &timers[nodeid]; | 297 | struct mmtimer_node *n = &timers[nodeid]; |
288 | struct mmtimer *x; | 298 | struct mmtimer *x; |
289 | struct k_itimer *t; | 299 | struct k_itimer *t; |
290 | int o; | 300 | u64 expires, exp, set_completion_time; |
301 | int i; | ||
291 | 302 | ||
292 | restart: | 303 | restart: |
293 | if (n->next == NULL) | 304 | if (n->next == NULL) |
@@ -298,7 +309,8 @@ restart: | |||
298 | if (!t->it.mmtimer.incr) { | 309 | if (!t->it.mmtimer.incr) { |
299 | /* Not an interval timer */ | 310 | /* Not an interval timer */ |
300 | if (!mmtimer_setup(x->cpu, COMPARATOR, | 311 | if (!mmtimer_setup(x->cpu, COMPARATOR, |
301 | t->it.mmtimer.expires)) { | 312 | t->it.mmtimer.expires, |
313 | &set_completion_time)) { | ||
302 | /* Late setup, fire now */ | 314 | /* Late setup, fire now */ |
303 | tasklet_schedule(&n->tasklet); | 315 | tasklet_schedule(&n->tasklet); |
304 | } | 316 | } |
@@ -306,14 +318,23 @@ restart: | |||
306 | } | 318 | } |
307 | 319 | ||
308 | /* Interval timer */ | 320 | /* Interval timer */ |
309 | o = 0; | 321 | i = 0; |
310 | while (!mmtimer_setup(x->cpu, COMPARATOR, t->it.mmtimer.expires)) { | 322 | expires = exp = t->it.mmtimer.expires; |
311 | unsigned long e, e1; | 323 | while (!mmtimer_setup(x->cpu, COMPARATOR, expires, |
312 | struct rb_node *next; | 324 | &set_completion_time)) { |
313 | t->it.mmtimer.expires += t->it.mmtimer.incr << o; | 325 | int to; |
314 | t->it_overrun += 1 << o; | 326 | |
315 | o++; | 327 | i++; |
316 | if (o > 20) { | 328 | expires = set_completion_time + |
329 | mmtimer_interval_retry_increment + (1 << i); | ||
330 | /* Calculate overruns as we go. */ | ||
331 | to = ((u64)(expires - exp) / t->it.mmtimer.incr); | ||
332 | if (to) { | ||
333 | t->it_overrun += to; | ||
334 | t->it.mmtimer.expires += t->it.mmtimer.incr * to; | ||
335 | exp = t->it.mmtimer.expires; | ||
336 | } | ||
337 | if (i > 20) { | ||
317 | printk(KERN_ALERT "mmtimer: cannot reschedule timer\n"); | 338 | printk(KERN_ALERT "mmtimer: cannot reschedule timer\n"); |
318 | t->it.mmtimer.clock = TIMER_OFF; | 339 | t->it.mmtimer.clock = TIMER_OFF; |
319 | n->next = rb_next(&x->list); | 340 | n->next = rb_next(&x->list); |
@@ -321,21 +342,6 @@ restart: | |||
321 | kfree(x); | 342 | kfree(x); |
322 | goto restart; | 343 | goto restart; |
323 | } | 344 | } |
324 | |||
325 | e = t->it.mmtimer.expires; | ||
326 | next = rb_next(&x->list); | ||
327 | |||
328 | if (next == NULL) | ||
329 | continue; | ||
330 | |||
331 | e1 = rb_entry(next, struct mmtimer, list)-> | ||
332 | timer->it.mmtimer.expires; | ||
333 | if (e > e1) { | ||
334 | n->next = next; | ||
335 | rb_erase(&x->list, &n->timer_head); | ||
336 | mmtimer_add_list(x); | ||
337 | goto restart; | ||
338 | } | ||
339 | } | 345 | } |
340 | } | 346 | } |
341 | 347 | ||
@@ -371,7 +377,7 @@ static long mmtimer_ioctl(struct file *file, unsigned int cmd, | |||
371 | { | 377 | { |
372 | int ret = 0; | 378 | int ret = 0; |
373 | 379 | ||
374 | lock_kernel(); | 380 | mutex_lock(&mmtimer_mutex); |
375 | 381 | ||
376 | switch (cmd) { | 382 | switch (cmd) { |
377 | case MMTIMER_GETOFFSET: /* offset of the counter */ | 383 | case MMTIMER_GETOFFSET: /* offset of the counter */ |
@@ -414,7 +420,7 @@ static long mmtimer_ioctl(struct file *file, unsigned int cmd, | |||
414 | ret = -ENOTTY; | 420 | ret = -ENOTTY; |
415 | break; | 421 | break; |
416 | } | 422 | } |
417 | unlock_kernel(); | 423 | mutex_unlock(&mmtimer_mutex); |
418 | return ret; | 424 | return ret; |
419 | } | 425 | } |
420 | 426 | ||
diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c index ecb89d798e35..966a95bc974b 100644 --- a/drivers/char/mspec.c +++ b/drivers/char/mspec.c | |||
@@ -316,7 +316,8 @@ uncached_mmap(struct file *file, struct vm_area_struct *vma) | |||
316 | 316 | ||
317 | static const struct file_operations fetchop_fops = { | 317 | static const struct file_operations fetchop_fops = { |
318 | .owner = THIS_MODULE, | 318 | .owner = THIS_MODULE, |
319 | .mmap = fetchop_mmap | 319 | .mmap = fetchop_mmap, |
320 | .llseek = noop_llseek, | ||
320 | }; | 321 | }; |
321 | 322 | ||
322 | static struct miscdevice fetchop_miscdev = { | 323 | static struct miscdevice fetchop_miscdev = { |
@@ -327,7 +328,8 @@ static struct miscdevice fetchop_miscdev = { | |||
327 | 328 | ||
328 | static const struct file_operations cached_fops = { | 329 | static const struct file_operations cached_fops = { |
329 | .owner = THIS_MODULE, | 330 | .owner = THIS_MODULE, |
330 | .mmap = cached_mmap | 331 | .mmap = cached_mmap, |
332 | .llseek = noop_llseek, | ||
331 | }; | 333 | }; |
332 | 334 | ||
333 | static struct miscdevice cached_miscdev = { | 335 | static struct miscdevice cached_miscdev = { |
@@ -338,7 +340,8 @@ static struct miscdevice cached_miscdev = { | |||
338 | 340 | ||
339 | static const struct file_operations uncached_fops = { | 341 | static const struct file_operations uncached_fops = { |
340 | .owner = THIS_MODULE, | 342 | .owner = THIS_MODULE, |
341 | .mmap = uncached_mmap | 343 | .mmap = uncached_mmap, |
344 | .llseek = noop_llseek, | ||
342 | }; | 345 | }; |
343 | 346 | ||
344 | static struct miscdevice uncached_miscdev = { | 347 | static struct miscdevice uncached_miscdev = { |
diff --git a/drivers/char/mwave/Makefile b/drivers/char/mwave/Makefile index 754c9e2058ed..26b4fce217b6 100644 --- a/drivers/char/mwave/Makefile +++ b/drivers/char/mwave/Makefile | |||
@@ -6,10 +6,10 @@ | |||
6 | 6 | ||
7 | obj-$(CONFIG_MWAVE) += mwave.o | 7 | obj-$(CONFIG_MWAVE) += mwave.o |
8 | 8 | ||
9 | mwave-objs := mwavedd.o smapi.o tp3780i.o 3780i.o | 9 | mwave-y := mwavedd.o smapi.o tp3780i.o 3780i.o |
10 | 10 | ||
11 | # To have the mwave driver disable other uarts if necessary | 11 | # To have the mwave driver disable other uarts if necessary |
12 | # EXTRA_CFLAGS += -DMWAVE_FUTZ_WITH_OTHER_DEVICES | 12 | # EXTRA_CFLAGS += -DMWAVE_FUTZ_WITH_OTHER_DEVICES |
13 | 13 | ||
14 | # To compile in lots (~20 KiB) of run-time enablable printk()s for debugging: | 14 | # To compile in lots (~20 KiB) of run-time enablable printk()s for debugging: |
15 | EXTRA_CFLAGS += -DMW_TRACE | 15 | ccflags-y := -DMW_TRACE |
diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c index a4ec50c95072..1d82d5838f0c 100644 --- a/drivers/char/mwave/mwavedd.c +++ b/drivers/char/mwave/mwavedd.c | |||
@@ -56,7 +56,7 @@ | |||
56 | #include <linux/serial.h> | 56 | #include <linux/serial.h> |
57 | #include <linux/sched.h> | 57 | #include <linux/sched.h> |
58 | #include <linux/spinlock.h> | 58 | #include <linux/spinlock.h> |
59 | #include <linux/smp_lock.h> | 59 | #include <linux/mutex.h> |
60 | #include <linux/delay.h> | 60 | #include <linux/delay.h> |
61 | #include <linux/serial_8250.h> | 61 | #include <linux/serial_8250.h> |
62 | #include "smapi.h" | 62 | #include "smapi.h" |
@@ -73,6 +73,7 @@ MODULE_LICENSE("GPL"); | |||
73 | * checks are made against other devices (ie. superio) for conflicts. | 73 | * checks are made against other devices (ie. superio) for conflicts. |
74 | * We'll depend on users using the tpctl utility to do that for now | 74 | * We'll depend on users using the tpctl utility to do that for now |
75 | */ | 75 | */ |
76 | static DEFINE_MUTEX(mwave_mutex); | ||
76 | int mwave_debug = 0; | 77 | int mwave_debug = 0; |
77 | int mwave_3780i_irq = 0; | 78 | int mwave_3780i_irq = 0; |
78 | int mwave_3780i_io = 0; | 79 | int mwave_3780i_io = 0; |
@@ -101,7 +102,6 @@ static int mwave_open(struct inode *inode, struct file *file) | |||
101 | PRINTK_2(TRACE_MWAVE, | 102 | PRINTK_2(TRACE_MWAVE, |
102 | "mwavedd::mwave_open, exit return retval %x\n", retval); | 103 | "mwavedd::mwave_open, exit return retval %x\n", retval); |
103 | 104 | ||
104 | cycle_kernel_lock(); | ||
105 | return retval; | 105 | return retval; |
106 | } | 106 | } |
107 | 107 | ||
@@ -136,9 +136,9 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, | |||
136 | PRINTK_1(TRACE_MWAVE, | 136 | PRINTK_1(TRACE_MWAVE, |
137 | "mwavedd::mwave_ioctl, IOCTL_MW_RESET" | 137 | "mwavedd::mwave_ioctl, IOCTL_MW_RESET" |
138 | " calling tp3780I_ResetDSP\n"); | 138 | " calling tp3780I_ResetDSP\n"); |
139 | lock_kernel(); | 139 | mutex_lock(&mwave_mutex); |
140 | retval = tp3780I_ResetDSP(&pDrvData->rBDData); | 140 | retval = tp3780I_ResetDSP(&pDrvData->rBDData); |
141 | unlock_kernel(); | 141 | mutex_unlock(&mwave_mutex); |
142 | PRINTK_2(TRACE_MWAVE, | 142 | PRINTK_2(TRACE_MWAVE, |
143 | "mwavedd::mwave_ioctl, IOCTL_MW_RESET" | 143 | "mwavedd::mwave_ioctl, IOCTL_MW_RESET" |
144 | " retval %x from tp3780I_ResetDSP\n", | 144 | " retval %x from tp3780I_ResetDSP\n", |
@@ -149,9 +149,9 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, | |||
149 | PRINTK_1(TRACE_MWAVE, | 149 | PRINTK_1(TRACE_MWAVE, |
150 | "mwavedd::mwave_ioctl, IOCTL_MW_RUN" | 150 | "mwavedd::mwave_ioctl, IOCTL_MW_RUN" |
151 | " calling tp3780I_StartDSP\n"); | 151 | " calling tp3780I_StartDSP\n"); |
152 | lock_kernel(); | 152 | mutex_lock(&mwave_mutex); |
153 | retval = tp3780I_StartDSP(&pDrvData->rBDData); | 153 | retval = tp3780I_StartDSP(&pDrvData->rBDData); |
154 | unlock_kernel(); | 154 | mutex_unlock(&mwave_mutex); |
155 | PRINTK_2(TRACE_MWAVE, | 155 | PRINTK_2(TRACE_MWAVE, |
156 | "mwavedd::mwave_ioctl, IOCTL_MW_RUN" | 156 | "mwavedd::mwave_ioctl, IOCTL_MW_RUN" |
157 | " retval %x from tp3780I_StartDSP\n", | 157 | " retval %x from tp3780I_StartDSP\n", |
@@ -165,10 +165,10 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, | |||
165 | "mwavedd::mwave_ioctl," | 165 | "mwavedd::mwave_ioctl," |
166 | " IOCTL_MW_DSP_ABILITIES calling" | 166 | " IOCTL_MW_DSP_ABILITIES calling" |
167 | " tp3780I_QueryAbilities\n"); | 167 | " tp3780I_QueryAbilities\n"); |
168 | lock_kernel(); | 168 | mutex_lock(&mwave_mutex); |
169 | retval = tp3780I_QueryAbilities(&pDrvData->rBDData, | 169 | retval = tp3780I_QueryAbilities(&pDrvData->rBDData, |
170 | &rAbilities); | 170 | &rAbilities); |
171 | unlock_kernel(); | 171 | mutex_unlock(&mwave_mutex); |
172 | PRINTK_2(TRACE_MWAVE, | 172 | PRINTK_2(TRACE_MWAVE, |
173 | "mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES" | 173 | "mwavedd::mwave_ioctl, IOCTL_MW_DSP_ABILITIES" |
174 | " retval %x from tp3780I_QueryAbilities\n", | 174 | " retval %x from tp3780I_QueryAbilities\n", |
@@ -199,13 +199,13 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, | |||
199 | "mwavedd::mwave_ioctl IOCTL_MW_READ_DATA," | 199 | "mwavedd::mwave_ioctl IOCTL_MW_READ_DATA," |
200 | " size %lx, ioarg %lx pusBuffer %p\n", | 200 | " size %lx, ioarg %lx pusBuffer %p\n", |
201 | rReadData.ulDataLength, ioarg, pusBuffer); | 201 | rReadData.ulDataLength, ioarg, pusBuffer); |
202 | lock_kernel(); | 202 | mutex_lock(&mwave_mutex); |
203 | retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, | 203 | retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, |
204 | iocmd, | 204 | iocmd, |
205 | pusBuffer, | 205 | pusBuffer, |
206 | rReadData.ulDataLength, | 206 | rReadData.ulDataLength, |
207 | rReadData.usDspAddress); | 207 | rReadData.usDspAddress); |
208 | unlock_kernel(); | 208 | mutex_unlock(&mwave_mutex); |
209 | } | 209 | } |
210 | break; | 210 | break; |
211 | 211 | ||
@@ -223,12 +223,12 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, | |||
223 | " size %lx, ioarg %lx pusBuffer %p\n", | 223 | " size %lx, ioarg %lx pusBuffer %p\n", |
224 | rReadData.ulDataLength / 2, ioarg, | 224 | rReadData.ulDataLength / 2, ioarg, |
225 | pusBuffer); | 225 | pusBuffer); |
226 | lock_kernel(); | 226 | mutex_lock(&mwave_mutex); |
227 | retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, | 227 | retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, |
228 | iocmd, pusBuffer, | 228 | iocmd, pusBuffer, |
229 | rReadData.ulDataLength / 2, | 229 | rReadData.ulDataLength / 2, |
230 | rReadData.usDspAddress); | 230 | rReadData.usDspAddress); |
231 | unlock_kernel(); | 231 | mutex_unlock(&mwave_mutex); |
232 | } | 232 | } |
233 | break; | 233 | break; |
234 | 234 | ||
@@ -246,12 +246,12 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, | |||
246 | " size %lx, ioarg %lx pusBuffer %p\n", | 246 | " size %lx, ioarg %lx pusBuffer %p\n", |
247 | rWriteData.ulDataLength, ioarg, | 247 | rWriteData.ulDataLength, ioarg, |
248 | pusBuffer); | 248 | pusBuffer); |
249 | lock_kernel(); | 249 | mutex_lock(&mwave_mutex); |
250 | retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, | 250 | retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, |
251 | iocmd, pusBuffer, | 251 | iocmd, pusBuffer, |
252 | rWriteData.ulDataLength, | 252 | rWriteData.ulDataLength, |
253 | rWriteData.usDspAddress); | 253 | rWriteData.usDspAddress); |
254 | unlock_kernel(); | 254 | mutex_unlock(&mwave_mutex); |
255 | } | 255 | } |
256 | break; | 256 | break; |
257 | 257 | ||
@@ -269,12 +269,12 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, | |||
269 | " size %lx, ioarg %lx pusBuffer %p\n", | 269 | " size %lx, ioarg %lx pusBuffer %p\n", |
270 | rWriteData.ulDataLength, ioarg, | 270 | rWriteData.ulDataLength, ioarg, |
271 | pusBuffer); | 271 | pusBuffer); |
272 | lock_kernel(); | 272 | mutex_lock(&mwave_mutex); |
273 | retval = tp3780I_ReadWriteDspIStore(&pDrvData->rBDData, | 273 | retval = tp3780I_ReadWriteDspIStore(&pDrvData->rBDData, |
274 | iocmd, pusBuffer, | 274 | iocmd, pusBuffer, |
275 | rWriteData.ulDataLength, | 275 | rWriteData.ulDataLength, |
276 | rWriteData.usDspAddress); | 276 | rWriteData.usDspAddress); |
277 | unlock_kernel(); | 277 | mutex_unlock(&mwave_mutex); |
278 | } | 278 | } |
279 | break; | 279 | break; |
280 | 280 | ||
@@ -295,10 +295,10 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, | |||
295 | ipcnum, | 295 | ipcnum, |
296 | pDrvData->IPCs[ipcnum].usIntCount); | 296 | pDrvData->IPCs[ipcnum].usIntCount); |
297 | 297 | ||
298 | lock_kernel(); | 298 | mutex_lock(&mwave_mutex); |
299 | pDrvData->IPCs[ipcnum].bIsHere = FALSE; | 299 | pDrvData->IPCs[ipcnum].bIsHere = FALSE; |
300 | pDrvData->IPCs[ipcnum].bIsEnabled = TRUE; | 300 | pDrvData->IPCs[ipcnum].bIsEnabled = TRUE; |
301 | unlock_kernel(); | 301 | mutex_unlock(&mwave_mutex); |
302 | 302 | ||
303 | PRINTK_2(TRACE_MWAVE, | 303 | PRINTK_2(TRACE_MWAVE, |
304 | "mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC" | 304 | "mwavedd::mwave_ioctl IOCTL_MW_REGISTER_IPC" |
@@ -323,7 +323,7 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, | |||
323 | ipcnum, | 323 | ipcnum, |
324 | pDrvData->IPCs[ipcnum].usIntCount); | 324 | pDrvData->IPCs[ipcnum].usIntCount); |
325 | 325 | ||
326 | lock_kernel(); | 326 | mutex_lock(&mwave_mutex); |
327 | if (pDrvData->IPCs[ipcnum].bIsEnabled == TRUE) { | 327 | if (pDrvData->IPCs[ipcnum].bIsEnabled == TRUE) { |
328 | DECLARE_WAITQUEUE(wait, current); | 328 | DECLARE_WAITQUEUE(wait, current); |
329 | 329 | ||
@@ -364,7 +364,7 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, | |||
364 | " processing\n", | 364 | " processing\n", |
365 | ipcnum); | 365 | ipcnum); |
366 | } | 366 | } |
367 | unlock_kernel(); | 367 | mutex_unlock(&mwave_mutex); |
368 | } | 368 | } |
369 | break; | 369 | break; |
370 | 370 | ||
@@ -383,14 +383,14 @@ static long mwave_ioctl(struct file *file, unsigned int iocmd, | |||
383 | ipcnum); | 383 | ipcnum); |
384 | return -EINVAL; | 384 | return -EINVAL; |
385 | } | 385 | } |
386 | lock_kernel(); | 386 | mutex_lock(&mwave_mutex); |
387 | if (pDrvData->IPCs[ipcnum].bIsEnabled == TRUE) { | 387 | if (pDrvData->IPCs[ipcnum].bIsEnabled == TRUE) { |
388 | pDrvData->IPCs[ipcnum].bIsEnabled = FALSE; | 388 | pDrvData->IPCs[ipcnum].bIsEnabled = FALSE; |
389 | if (pDrvData->IPCs[ipcnum].bIsHere == TRUE) { | 389 | if (pDrvData->IPCs[ipcnum].bIsHere == TRUE) { |
390 | wake_up_interruptible(&pDrvData->IPCs[ipcnum].ipc_wait_queue); | 390 | wake_up_interruptible(&pDrvData->IPCs[ipcnum].ipc_wait_queue); |
391 | } | 391 | } |
392 | } | 392 | } |
393 | unlock_kernel(); | 393 | mutex_unlock(&mwave_mutex); |
394 | } | 394 | } |
395 | break; | 395 | break; |
396 | 396 | ||
@@ -479,7 +479,8 @@ static const struct file_operations mwave_fops = { | |||
479 | .write = mwave_write, | 479 | .write = mwave_write, |
480 | .unlocked_ioctl = mwave_ioctl, | 480 | .unlocked_ioctl = mwave_ioctl, |
481 | .open = mwave_open, | 481 | .open = mwave_open, |
482 | .release = mwave_close | 482 | .release = mwave_close, |
483 | .llseek = default_llseek, | ||
483 | }; | 484 | }; |
484 | 485 | ||
485 | 486 | ||
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 3fc89da856ae..dd9d75351cd6 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -303,6 +303,7 @@ static void mxser_enable_must_enchance_mode(unsigned long baseio) | |||
303 | outb(oldlcr, baseio + UART_LCR); | 303 | outb(oldlcr, baseio + UART_LCR); |
304 | } | 304 | } |
305 | 305 | ||
306 | #ifdef CONFIG_PCI | ||
306 | static void mxser_disable_must_enchance_mode(unsigned long baseio) | 307 | static void mxser_disable_must_enchance_mode(unsigned long baseio) |
307 | { | 308 | { |
308 | u8 oldlcr; | 309 | u8 oldlcr; |
@@ -317,6 +318,7 @@ static void mxser_disable_must_enchance_mode(unsigned long baseio) | |||
317 | outb(efr, baseio + MOXA_MUST_EFR_REGISTER); | 318 | outb(efr, baseio + MOXA_MUST_EFR_REGISTER); |
318 | outb(oldlcr, baseio + UART_LCR); | 319 | outb(oldlcr, baseio + UART_LCR); |
319 | } | 320 | } |
321 | #endif | ||
320 | 322 | ||
321 | static void mxser_set_must_xon1_value(unsigned long baseio, u8 value) | 323 | static void mxser_set_must_xon1_value(unsigned long baseio, u8 value) |
322 | { | 324 | { |
@@ -388,6 +390,7 @@ static void mxser_set_must_enum_value(unsigned long baseio, u8 value) | |||
388 | outb(oldlcr, baseio + UART_LCR); | 390 | outb(oldlcr, baseio + UART_LCR); |
389 | } | 391 | } |
390 | 392 | ||
393 | #ifdef CONFIG_PCI | ||
391 | static void mxser_get_must_hardware_id(unsigned long baseio, u8 *pId) | 394 | static void mxser_get_must_hardware_id(unsigned long baseio, u8 *pId) |
392 | { | 395 | { |
393 | u8 oldlcr; | 396 | u8 oldlcr; |
@@ -404,6 +407,7 @@ static void mxser_get_must_hardware_id(unsigned long baseio, u8 *pId) | |||
404 | *pId = inb(baseio + MOXA_MUST_HWID_REGISTER); | 407 | *pId = inb(baseio + MOXA_MUST_HWID_REGISTER); |
405 | outb(oldlcr, baseio + UART_LCR); | 408 | outb(oldlcr, baseio + UART_LCR); |
406 | } | 409 | } |
410 | #endif | ||
407 | 411 | ||
408 | static void SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(unsigned long baseio) | 412 | static void SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(unsigned long baseio) |
409 | { | 413 | { |
@@ -1700,7 +1704,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1700 | return 0; | 1704 | return 0; |
1701 | } | 1705 | } |
1702 | 1706 | ||
1703 | if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && cmd != TIOCGICOUNT && | 1707 | if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && |
1704 | test_bit(TTY_IO_ERROR, &tty->flags)) | 1708 | test_bit(TTY_IO_ERROR, &tty->flags)) |
1705 | return -EIO; | 1709 | return -EIO; |
1706 | 1710 | ||
@@ -1730,32 +1734,6 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1730 | 1734 | ||
1731 | return wait_event_interruptible(info->port.delta_msr_wait, | 1735 | return wait_event_interruptible(info->port.delta_msr_wait, |
1732 | mxser_cflags_changed(info, arg, &cnow)); | 1736 | mxser_cflags_changed(info, arg, &cnow)); |
1733 | /* | ||
1734 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
1735 | * Return: write counters to the user passed counter struct | ||
1736 | * NB: both 1->0 and 0->1 transitions are counted except for | ||
1737 | * RI where only 0->1 is counted. | ||
1738 | */ | ||
1739 | case TIOCGICOUNT: { | ||
1740 | struct serial_icounter_struct icnt = { 0 }; | ||
1741 | spin_lock_irqsave(&info->slock, flags); | ||
1742 | cnow = info->icount; | ||
1743 | spin_unlock_irqrestore(&info->slock, flags); | ||
1744 | |||
1745 | icnt.frame = cnow.frame; | ||
1746 | icnt.brk = cnow.brk; | ||
1747 | icnt.overrun = cnow.overrun; | ||
1748 | icnt.buf_overrun = cnow.buf_overrun; | ||
1749 | icnt.parity = cnow.parity; | ||
1750 | icnt.rx = cnow.rx; | ||
1751 | icnt.tx = cnow.tx; | ||
1752 | icnt.cts = cnow.cts; | ||
1753 | icnt.dsr = cnow.dsr; | ||
1754 | icnt.rng = cnow.rng; | ||
1755 | icnt.dcd = cnow.dcd; | ||
1756 | |||
1757 | return copy_to_user(argp, &icnt, sizeof(icnt)) ? -EFAULT : 0; | ||
1758 | } | ||
1759 | case MOXA_HighSpeedOn: | 1737 | case MOXA_HighSpeedOn: |
1760 | return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp); | 1738 | return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp); |
1761 | case MOXA_SDS_RSTICOUNTER: | 1739 | case MOXA_SDS_RSTICOUNTER: |
@@ -1828,6 +1806,39 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file, | |||
1828 | return 0; | 1806 | return 0; |
1829 | } | 1807 | } |
1830 | 1808 | ||
1809 | /* | ||
1810 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
1811 | * Return: write counters to the user passed counter struct | ||
1812 | * NB: both 1->0 and 0->1 transitions are counted except for | ||
1813 | * RI where only 0->1 is counted. | ||
1814 | */ | ||
1815 | |||
1816 | static int mxser_get_icount(struct tty_struct *tty, | ||
1817 | struct serial_icounter_struct *icount) | ||
1818 | |||
1819 | { | ||
1820 | struct mxser_port *info = tty->driver_data; | ||
1821 | struct async_icount cnow; | ||
1822 | unsigned long flags; | ||
1823 | |||
1824 | spin_lock_irqsave(&info->slock, flags); | ||
1825 | cnow = info->icount; | ||
1826 | spin_unlock_irqrestore(&info->slock, flags); | ||
1827 | |||
1828 | icount->frame = cnow.frame; | ||
1829 | icount->brk = cnow.brk; | ||
1830 | icount->overrun = cnow.overrun; | ||
1831 | icount->buf_overrun = cnow.buf_overrun; | ||
1832 | icount->parity = cnow.parity; | ||
1833 | icount->rx = cnow.rx; | ||
1834 | icount->tx = cnow.tx; | ||
1835 | icount->cts = cnow.cts; | ||
1836 | icount->dsr = cnow.dsr; | ||
1837 | icount->rng = cnow.rng; | ||
1838 | icount->dcd = cnow.dcd; | ||
1839 | return 0; | ||
1840 | } | ||
1841 | |||
1831 | static void mxser_stoprx(struct tty_struct *tty) | 1842 | static void mxser_stoprx(struct tty_struct *tty) |
1832 | { | 1843 | { |
1833 | struct mxser_port *info = tty->driver_data; | 1844 | struct mxser_port *info = tty->driver_data; |
@@ -2326,6 +2337,7 @@ static const struct tty_operations mxser_ops = { | |||
2326 | .wait_until_sent = mxser_wait_until_sent, | 2337 | .wait_until_sent = mxser_wait_until_sent, |
2327 | .tiocmget = mxser_tiocmget, | 2338 | .tiocmget = mxser_tiocmget, |
2328 | .tiocmset = mxser_tiocmset, | 2339 | .tiocmset = mxser_tiocmset, |
2340 | .get_icount = mxser_get_icount, | ||
2329 | }; | 2341 | }; |
2330 | 2342 | ||
2331 | struct tty_port_operations mxser_port_ops = { | 2343 | struct tty_port_operations mxser_port_ops = { |
@@ -2339,20 +2351,11 @@ struct tty_port_operations mxser_port_ops = { | |||
2339 | * The MOXA Smartio/Industio serial driver boot-time initialization code! | 2351 | * The MOXA Smartio/Industio serial driver boot-time initialization code! |
2340 | */ | 2352 | */ |
2341 | 2353 | ||
2342 | static void mxser_release_res(struct mxser_board *brd, struct pci_dev *pdev, | 2354 | static void mxser_release_ISA_res(struct mxser_board *brd) |
2343 | unsigned int irq) | ||
2344 | { | 2355 | { |
2345 | if (irq) | 2356 | free_irq(brd->irq, brd); |
2346 | free_irq(brd->irq, brd); | 2357 | release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); |
2347 | if (pdev != NULL) { /* PCI */ | 2358 | release_region(brd->vector, 1); |
2348 | #ifdef CONFIG_PCI | ||
2349 | pci_release_region(pdev, 2); | ||
2350 | pci_release_region(pdev, 3); | ||
2351 | #endif | ||
2352 | } else { | ||
2353 | release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); | ||
2354 | release_region(brd->vector, 1); | ||
2355 | } | ||
2356 | } | 2359 | } |
2357 | 2360 | ||
2358 | static int __devinit mxser_initbrd(struct mxser_board *brd, | 2361 | static int __devinit mxser_initbrd(struct mxser_board *brd, |
@@ -2397,13 +2400,11 @@ static int __devinit mxser_initbrd(struct mxser_board *brd, | |||
2397 | 2400 | ||
2398 | retval = request_irq(brd->irq, mxser_interrupt, IRQF_SHARED, "mxser", | 2401 | retval = request_irq(brd->irq, mxser_interrupt, IRQF_SHARED, "mxser", |
2399 | brd); | 2402 | brd); |
2400 | if (retval) { | 2403 | if (retval) |
2401 | printk(KERN_ERR "Board %s: Request irq failed, IRQ (%d) may " | 2404 | printk(KERN_ERR "Board %s: Request irq failed, IRQ (%d) may " |
2402 | "conflict with another device.\n", | 2405 | "conflict with another device.\n", |
2403 | brd->info->name, brd->irq); | 2406 | brd->info->name, brd->irq); |
2404 | /* We hold resources, we need to release them. */ | 2407 | |
2405 | mxser_release_res(brd, pdev, 0); | ||
2406 | } | ||
2407 | return retval; | 2408 | return retval; |
2408 | } | 2409 | } |
2409 | 2410 | ||
@@ -2555,7 +2556,7 @@ static int __devinit mxser_probe(struct pci_dev *pdev, | |||
2555 | ioaddress = pci_resource_start(pdev, 2); | 2556 | ioaddress = pci_resource_start(pdev, 2); |
2556 | retval = pci_request_region(pdev, 2, "mxser(IO)"); | 2557 | retval = pci_request_region(pdev, 2, "mxser(IO)"); |
2557 | if (retval) | 2558 | if (retval) |
2558 | goto err; | 2559 | goto err_dis; |
2559 | 2560 | ||
2560 | brd->info = &mxser_cards[ent->driver_data]; | 2561 | brd->info = &mxser_cards[ent->driver_data]; |
2561 | for (i = 0; i < brd->info->nports; i++) | 2562 | for (i = 0; i < brd->info->nports; i++) |
@@ -2565,7 +2566,7 @@ static int __devinit mxser_probe(struct pci_dev *pdev, | |||
2565 | ioaddress = pci_resource_start(pdev, 3); | 2566 | ioaddress = pci_resource_start(pdev, 3); |
2566 | retval = pci_request_region(pdev, 3, "mxser(vector)"); | 2567 | retval = pci_request_region(pdev, 3, "mxser(vector)"); |
2567 | if (retval) | 2568 | if (retval) |
2568 | goto err_relio; | 2569 | goto err_zero; |
2569 | brd->vector = ioaddress; | 2570 | brd->vector = ioaddress; |
2570 | 2571 | ||
2571 | /* irq */ | 2572 | /* irq */ |
@@ -2608,7 +2609,7 @@ static int __devinit mxser_probe(struct pci_dev *pdev, | |||
2608 | /* mxser_initbrd will hook ISR. */ | 2609 | /* mxser_initbrd will hook ISR. */ |
2609 | retval = mxser_initbrd(brd, pdev); | 2610 | retval = mxser_initbrd(brd, pdev); |
2610 | if (retval) | 2611 | if (retval) |
2611 | goto err_null; | 2612 | goto err_rel3; |
2612 | 2613 | ||
2613 | for (i = 0; i < brd->info->nports; i++) | 2614 | for (i = 0; i < brd->info->nports; i++) |
2614 | tty_register_device(mxvar_sdriver, brd->idx + i, &pdev->dev); | 2615 | tty_register_device(mxvar_sdriver, brd->idx + i, &pdev->dev); |
@@ -2616,10 +2617,13 @@ static int __devinit mxser_probe(struct pci_dev *pdev, | |||
2616 | pci_set_drvdata(pdev, brd); | 2617 | pci_set_drvdata(pdev, brd); |
2617 | 2618 | ||
2618 | return 0; | 2619 | return 0; |
2619 | err_relio: | 2620 | err_rel3: |
2620 | pci_release_region(pdev, 2); | 2621 | pci_release_region(pdev, 3); |
2621 | err_null: | 2622 | err_zero: |
2622 | brd->info = NULL; | 2623 | brd->info = NULL; |
2624 | pci_release_region(pdev, 2); | ||
2625 | err_dis: | ||
2626 | pci_disable_device(pdev); | ||
2623 | err: | 2627 | err: |
2624 | return retval; | 2628 | return retval; |
2625 | #else | 2629 | #else |
@@ -2629,14 +2633,19 @@ err: | |||
2629 | 2633 | ||
2630 | static void __devexit mxser_remove(struct pci_dev *pdev) | 2634 | static void __devexit mxser_remove(struct pci_dev *pdev) |
2631 | { | 2635 | { |
2636 | #ifdef CONFIG_PCI | ||
2632 | struct mxser_board *brd = pci_get_drvdata(pdev); | 2637 | struct mxser_board *brd = pci_get_drvdata(pdev); |
2633 | unsigned int i; | 2638 | unsigned int i; |
2634 | 2639 | ||
2635 | for (i = 0; i < brd->info->nports; i++) | 2640 | for (i = 0; i < brd->info->nports; i++) |
2636 | tty_unregister_device(mxvar_sdriver, brd->idx + i); | 2641 | tty_unregister_device(mxvar_sdriver, brd->idx + i); |
2637 | 2642 | ||
2638 | mxser_release_res(brd, pdev, 1); | 2643 | free_irq(pdev->irq, brd); |
2644 | pci_release_region(pdev, 2); | ||
2645 | pci_release_region(pdev, 3); | ||
2646 | pci_disable_device(pdev); | ||
2639 | brd->info = NULL; | 2647 | brd->info = NULL; |
2648 | #endif | ||
2640 | } | 2649 | } |
2641 | 2650 | ||
2642 | static struct pci_driver mxser_driver = { | 2651 | static struct pci_driver mxser_driver = { |
@@ -2741,7 +2750,7 @@ static void __exit mxser_module_exit(void) | |||
2741 | 2750 | ||
2742 | for (i = 0; i < MXSER_BOARDS; i++) | 2751 | for (i = 0; i < MXSER_BOARDS; i++) |
2743 | if (mxser_boards[i].info != NULL) | 2752 | if (mxser_boards[i].info != NULL) |
2744 | mxser_release_res(&mxser_boards[i], NULL, 1); | 2753 | mxser_release_ISA_res(&mxser_boards[i]); |
2745 | } | 2754 | } |
2746 | 2755 | ||
2747 | module_init(mxser_module_init); | 2756 | module_init(mxser_module_init); |
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c index a98290d7a2c5..88dda0c45ee0 100644 --- a/drivers/char/n_r3964.c +++ b/drivers/char/n_r3964.c | |||
@@ -4,7 +4,6 @@ | |||
4 | * Copyright by | 4 | * Copyright by |
5 | * Philips Automation Projects | 5 | * Philips Automation Projects |
6 | * Kassel (Germany) | 6 | * Kassel (Germany) |
7 | * http://www.pap-philips.de | ||
8 | * ----------------------------------------------------------- | 7 | * ----------------------------------------------------------- |
9 | * This software may be used and distributed according to the terms of | 8 | * This software may be used and distributed according to the terms of |
10 | * the GNU General Public License, incorporated herein by reference. | 9 | * the GNU General Public License, incorporated herein by reference. |
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c index 817169cbb245..dd3f9b1f11b4 100644 --- a/drivers/char/nozomi.c +++ b/drivers/char/nozomi.c | |||
@@ -1804,24 +1804,24 @@ static int ntty_cflags_changed(struct port *port, unsigned long flags, | |||
1804 | return ret; | 1804 | return ret; |
1805 | } | 1805 | } |
1806 | 1806 | ||
1807 | static int ntty_ioctl_tiocgicount(struct port *port, void __user *argp) | 1807 | static int ntty_tiocgicount(struct tty_struct *tty, |
1808 | struct serial_icounter_struct *icount) | ||
1808 | { | 1809 | { |
1810 | struct port *port = tty->driver_data; | ||
1809 | const struct async_icount cnow = port->tty_icount; | 1811 | const struct async_icount cnow = port->tty_icount; |
1810 | struct serial_icounter_struct icount; | 1812 | |
1811 | 1813 | icount->cts = cnow.cts; | |
1812 | icount.cts = cnow.cts; | 1814 | icount->dsr = cnow.dsr; |
1813 | icount.dsr = cnow.dsr; | 1815 | icount->rng = cnow.rng; |
1814 | icount.rng = cnow.rng; | 1816 | icount->dcd = cnow.dcd; |
1815 | icount.dcd = cnow.dcd; | 1817 | icount->rx = cnow.rx; |
1816 | icount.rx = cnow.rx; | 1818 | icount->tx = cnow.tx; |
1817 | icount.tx = cnow.tx; | 1819 | icount->frame = cnow.frame; |
1818 | icount.frame = cnow.frame; | 1820 | icount->overrun = cnow.overrun; |
1819 | icount.overrun = cnow.overrun; | 1821 | icount->parity = cnow.parity; |
1820 | icount.parity = cnow.parity; | 1822 | icount->brk = cnow.brk; |
1821 | icount.brk = cnow.brk; | 1823 | icount->buf_overrun = cnow.buf_overrun; |
1822 | icount.buf_overrun = cnow.buf_overrun; | 1824 | return 0; |
1823 | |||
1824 | return copy_to_user(argp, &icount, sizeof(icount)) ? -EFAULT : 0; | ||
1825 | } | 1825 | } |
1826 | 1826 | ||
1827 | static int ntty_ioctl(struct tty_struct *tty, struct file *file, | 1827 | static int ntty_ioctl(struct tty_struct *tty, struct file *file, |
@@ -1840,9 +1840,7 @@ static int ntty_ioctl(struct tty_struct *tty, struct file *file, | |||
1840 | rval = wait_event_interruptible(port->tty_wait, | 1840 | rval = wait_event_interruptible(port->tty_wait, |
1841 | ntty_cflags_changed(port, arg, &cprev)); | 1841 | ntty_cflags_changed(port, arg, &cprev)); |
1842 | break; | 1842 | break; |
1843 | } case TIOCGICOUNT: | 1843 | } |
1844 | rval = ntty_ioctl_tiocgicount(port, argp); | ||
1845 | break; | ||
1846 | default: | 1844 | default: |
1847 | DBG1("ERR: 0x%08X, %d", cmd, cmd); | 1845 | DBG1("ERR: 0x%08X, %d", cmd, cmd); |
1848 | break; | 1846 | break; |
@@ -1922,6 +1920,7 @@ static const struct tty_operations tty_ops = { | |||
1922 | .chars_in_buffer = ntty_chars_in_buffer, | 1920 | .chars_in_buffer = ntty_chars_in_buffer, |
1923 | .tiocmget = ntty_tiocmget, | 1921 | .tiocmget = ntty_tiocmget, |
1924 | .tiocmset = ntty_tiocmset, | 1922 | .tiocmset = ntty_tiocmset, |
1923 | .get_icount = ntty_tiocgicount, | ||
1925 | .install = ntty_install, | 1924 | .install = ntty_install, |
1926 | .cleanup = ntty_cleanup, | 1925 | .cleanup = ntty_cleanup, |
1927 | }; | 1926 | }; |
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c index 66d2917b003f..166f1e7aaa7e 100644 --- a/drivers/char/nvram.c +++ b/drivers/char/nvram.c | |||
@@ -109,10 +109,11 @@ | |||
109 | #include <linux/spinlock.h> | 109 | #include <linux/spinlock.h> |
110 | #include <linux/io.h> | 110 | #include <linux/io.h> |
111 | #include <linux/uaccess.h> | 111 | #include <linux/uaccess.h> |
112 | #include <linux/smp_lock.h> | 112 | #include <linux/mutex.h> |
113 | 113 | ||
114 | #include <asm/system.h> | 114 | #include <asm/system.h> |
115 | 115 | ||
116 | static DEFINE_MUTEX(nvram_mutex); | ||
116 | static DEFINE_SPINLOCK(nvram_state_lock); | 117 | static DEFINE_SPINLOCK(nvram_state_lock); |
117 | static int nvram_open_cnt; /* #times opened */ | 118 | static int nvram_open_cnt; /* #times opened */ |
118 | static int nvram_open_mode; /* special open modes */ | 119 | static int nvram_open_mode; /* special open modes */ |
@@ -308,7 +309,7 @@ static long nvram_ioctl(struct file *file, unsigned int cmd, | |||
308 | if (!capable(CAP_SYS_ADMIN)) | 309 | if (!capable(CAP_SYS_ADMIN)) |
309 | return -EACCES; | 310 | return -EACCES; |
310 | 311 | ||
311 | lock_kernel(); | 312 | mutex_lock(&nvram_mutex); |
312 | spin_lock_irq(&rtc_lock); | 313 | spin_lock_irq(&rtc_lock); |
313 | 314 | ||
314 | for (i = 0; i < NVRAM_BYTES; ++i) | 315 | for (i = 0; i < NVRAM_BYTES; ++i) |
@@ -316,7 +317,7 @@ static long nvram_ioctl(struct file *file, unsigned int cmd, | |||
316 | __nvram_set_checksum(); | 317 | __nvram_set_checksum(); |
317 | 318 | ||
318 | spin_unlock_irq(&rtc_lock); | 319 | spin_unlock_irq(&rtc_lock); |
319 | unlock_kernel(); | 320 | mutex_unlock(&nvram_mutex); |
320 | return 0; | 321 | return 0; |
321 | 322 | ||
322 | case NVRAM_SETCKS: | 323 | case NVRAM_SETCKS: |
@@ -325,11 +326,11 @@ static long nvram_ioctl(struct file *file, unsigned int cmd, | |||
325 | if (!capable(CAP_SYS_ADMIN)) | 326 | if (!capable(CAP_SYS_ADMIN)) |
326 | return -EACCES; | 327 | return -EACCES; |
327 | 328 | ||
328 | lock_kernel(); | 329 | mutex_lock(&nvram_mutex); |
329 | spin_lock_irq(&rtc_lock); | 330 | spin_lock_irq(&rtc_lock); |
330 | __nvram_set_checksum(); | 331 | __nvram_set_checksum(); |
331 | spin_unlock_irq(&rtc_lock); | 332 | spin_unlock_irq(&rtc_lock); |
332 | unlock_kernel(); | 333 | mutex_unlock(&nvram_mutex); |
333 | return 0; | 334 | return 0; |
334 | 335 | ||
335 | default: | 336 | default: |
diff --git a/drivers/char/nwbutton.c b/drivers/char/nwbutton.c index 2604246501e4..8994ce32e6c7 100644 --- a/drivers/char/nwbutton.c +++ b/drivers/char/nwbutton.c | |||
@@ -182,6 +182,7 @@ static int button_read (struct file *filp, char __user *buffer, | |||
182 | static const struct file_operations button_fops = { | 182 | static const struct file_operations button_fops = { |
183 | .owner = THIS_MODULE, | 183 | .owner = THIS_MODULE, |
184 | .read = button_read, | 184 | .read = button_read, |
185 | .llseek = noop_llseek, | ||
185 | }; | 186 | }; |
186 | 187 | ||
187 | /* | 188 | /* |
diff --git a/drivers/char/nwflash.c b/drivers/char/nwflash.c index 043a1c7b86be..a12f52400dbc 100644 --- a/drivers/char/nwflash.c +++ b/drivers/char/nwflash.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
26 | #include <linux/rwsem.h> | 26 | #include <linux/rwsem.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/smp_lock.h> | ||
29 | #include <linux/mutex.h> | 28 | #include <linux/mutex.h> |
30 | #include <linux/jiffies.h> | 29 | #include <linux/jiffies.h> |
31 | 30 | ||
@@ -41,6 +40,7 @@ | |||
41 | 40 | ||
42 | #define NWFLASH_VERSION "6.4" | 41 | #define NWFLASH_VERSION "6.4" |
43 | 42 | ||
43 | static DEFINE_MUTEX(flash_mutex); | ||
44 | static void kick_open(void); | 44 | static void kick_open(void); |
45 | static int get_flash_id(void); | 45 | static int get_flash_id(void); |
46 | static int erase_block(int nBlock); | 46 | static int erase_block(int nBlock); |
@@ -96,7 +96,7 @@ static int get_flash_id(void) | |||
96 | 96 | ||
97 | static long flash_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) | 97 | static long flash_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) |
98 | { | 98 | { |
99 | lock_kernel(); | 99 | mutex_lock(&flash_mutex); |
100 | switch (cmd) { | 100 | switch (cmd) { |
101 | case CMD_WRITE_DISABLE: | 101 | case CMD_WRITE_DISABLE: |
102 | gbWriteBase64Enable = 0; | 102 | gbWriteBase64Enable = 0; |
@@ -114,10 +114,10 @@ static long flash_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) | |||
114 | default: | 114 | default: |
115 | gbWriteBase64Enable = 0; | 115 | gbWriteBase64Enable = 0; |
116 | gbWriteEnable = 0; | 116 | gbWriteEnable = 0; |
117 | unlock_kernel(); | 117 | mutex_unlock(&flash_mutex); |
118 | return -EINVAL; | 118 | return -EINVAL; |
119 | } | 119 | } |
120 | unlock_kernel(); | 120 | mutex_unlock(&flash_mutex); |
121 | return 0; | 121 | return 0; |
122 | } | 122 | } |
123 | 123 | ||
@@ -282,7 +282,7 @@ static loff_t flash_llseek(struct file *file, loff_t offset, int orig) | |||
282 | { | 282 | { |
283 | loff_t ret; | 283 | loff_t ret; |
284 | 284 | ||
285 | lock_kernel(); | 285 | mutex_lock(&flash_mutex); |
286 | if (flashdebug) | 286 | if (flashdebug) |
287 | printk(KERN_DEBUG "flash_llseek: offset=0x%X, orig=0x%X.\n", | 287 | printk(KERN_DEBUG "flash_llseek: offset=0x%X, orig=0x%X.\n", |
288 | (unsigned int) offset, orig); | 288 | (unsigned int) offset, orig); |
@@ -317,7 +317,7 @@ static loff_t flash_llseek(struct file *file, loff_t offset, int orig) | |||
317 | default: | 317 | default: |
318 | ret = -EINVAL; | 318 | ret = -EINVAL; |
319 | } | 319 | } |
320 | unlock_kernel(); | 320 | mutex_unlock(&flash_mutex); |
321 | return ret; | 321 | return ret; |
322 | } | 322 | } |
323 | 323 | ||
diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c index 8ecbcc174c15..b304ec052501 100644 --- a/drivers/char/pc8736x_gpio.c +++ b/drivers/char/pc8736x_gpio.c | |||
@@ -234,6 +234,7 @@ static const struct file_operations pc8736x_gpio_fileops = { | |||
234 | .open = pc8736x_gpio_open, | 234 | .open = pc8736x_gpio_open, |
235 | .write = nsc_gpio_write, | 235 | .write = nsc_gpio_write, |
236 | .read = nsc_gpio_read, | 236 | .read = nsc_gpio_read, |
237 | .llseek = no_llseek, | ||
237 | }; | 238 | }; |
238 | 239 | ||
239 | static void __init pc8736x_init_shadow(void) | 240 | static void __init pc8736x_init_shadow(void) |
diff --git a/drivers/char/pcmcia/Kconfig b/drivers/char/pcmcia/Kconfig index ffa0efce0aed..6614416a8623 100644 --- a/drivers/char/pcmcia/Kconfig +++ b/drivers/char/pcmcia/Kconfig | |||
@@ -28,7 +28,7 @@ config CARDMAN_4000 | |||
28 | 28 | ||
29 | This kernel driver requires additional userspace support, either | 29 | This kernel driver requires additional userspace support, either |
30 | by the vendor-provided PC/SC ifd_handler (http://www.omnikey.com/), | 30 | by the vendor-provided PC/SC ifd_handler (http://www.omnikey.com/), |
31 | or via the cm4000 backend of OpenCT (http://www.opensc.com/). | 31 | or via the cm4000 backend of OpenCT (http://www.opensc-project.org/opensc). |
32 | 32 | ||
33 | config CARDMAN_4040 | 33 | config CARDMAN_4040 |
34 | tristate "Omnikey CardMan 4040 support" | 34 | tristate "Omnikey CardMan 4040 support" |
@@ -41,7 +41,7 @@ config CARDMAN_4040 | |||
41 | in I/O space. To use the kernel driver, you will need either the | 41 | in I/O space. To use the kernel driver, you will need either the |
42 | PC/SC ifdhandler provided from the Omnikey homepage | 42 | PC/SC ifdhandler provided from the Omnikey homepage |
43 | (http://www.omnikey.com/), or a current development version of OpenCT | 43 | (http://www.omnikey.com/), or a current development version of OpenCT |
44 | (http://www.opensc.org/). | 44 | (http://www.opensc-project.org/opensc). |
45 | 45 | ||
46 | config IPWIRELESS | 46 | config IPWIRELESS |
47 | tristate "IPWireless 3G UMTS PCMCIA card support" | 47 | tristate "IPWireless 3G UMTS PCMCIA card support" |
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index c7b482d15e2a..d962f25dcc2a 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <linux/fs.h> | 30 | #include <linux/fs.h> |
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <linux/bitrev.h> | 32 | #include <linux/bitrev.h> |
33 | #include <linux/smp_lock.h> | 33 | #include <linux/mutex.h> |
34 | #include <linux/uaccess.h> | 34 | #include <linux/uaccess.h> |
35 | #include <linux/io.h> | 35 | #include <linux/io.h> |
36 | 36 | ||
@@ -54,6 +54,8 @@ | |||
54 | __func__ , ## args); \ | 54 | __func__ , ## args); \ |
55 | } while (0) | 55 | } while (0) |
56 | 56 | ||
57 | static DEFINE_MUTEX(cmm_mutex); | ||
58 | |||
57 | #define T_1SEC (HZ) | 59 | #define T_1SEC (HZ) |
58 | #define T_10MSEC msecs_to_jiffies(10) | 60 | #define T_10MSEC msecs_to_jiffies(10) |
59 | #define T_20MSEC msecs_to_jiffies(20) | 61 | #define T_20MSEC msecs_to_jiffies(20) |
@@ -1415,7 +1417,7 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
1415 | iminor(inode), ioctl_names[_IOC_NR(cmd)]); | 1417 | iminor(inode), ioctl_names[_IOC_NR(cmd)]); |
1416 | #endif | 1418 | #endif |
1417 | 1419 | ||
1418 | lock_kernel(); | 1420 | mutex_lock(&cmm_mutex); |
1419 | rc = -ENODEV; | 1421 | rc = -ENODEV; |
1420 | link = dev_table[iminor(inode)]; | 1422 | link = dev_table[iminor(inode)]; |
1421 | if (!pcmcia_dev_present(link)) { | 1423 | if (!pcmcia_dev_present(link)) { |
@@ -1623,7 +1625,7 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
1623 | rc = -ENOTTY; | 1625 | rc = -ENOTTY; |
1624 | } | 1626 | } |
1625 | out: | 1627 | out: |
1626 | unlock_kernel(); | 1628 | mutex_unlock(&cmm_mutex); |
1627 | return rc; | 1629 | return rc; |
1628 | } | 1630 | } |
1629 | 1631 | ||
@@ -1637,7 +1639,7 @@ static int cmm_open(struct inode *inode, struct file *filp) | |||
1637 | if (minor >= CM4000_MAX_DEV) | 1639 | if (minor >= CM4000_MAX_DEV) |
1638 | return -ENODEV; | 1640 | return -ENODEV; |
1639 | 1641 | ||
1640 | lock_kernel(); | 1642 | mutex_lock(&cmm_mutex); |
1641 | link = dev_table[minor]; | 1643 | link = dev_table[minor]; |
1642 | if (link == NULL || !pcmcia_dev_present(link)) { | 1644 | if (link == NULL || !pcmcia_dev_present(link)) { |
1643 | ret = -ENODEV; | 1645 | ret = -ENODEV; |
@@ -1664,7 +1666,7 @@ static int cmm_open(struct inode *inode, struct file *filp) | |||
1664 | /* opening will always block since the | 1666 | /* opening will always block since the |
1665 | * monitor will be started by open, which | 1667 | * monitor will be started by open, which |
1666 | * means we have to wait for ATR becoming | 1668 | * means we have to wait for ATR becoming |
1667 | * vaild = block until valid (or card | 1669 | * valid = block until valid (or card |
1668 | * inserted) | 1670 | * inserted) |
1669 | */ | 1671 | */ |
1670 | if (filp->f_flags & O_NONBLOCK) { | 1672 | if (filp->f_flags & O_NONBLOCK) { |
@@ -1682,7 +1684,7 @@ static int cmm_open(struct inode *inode, struct file *filp) | |||
1682 | DEBUGP(2, dev, "<- cmm_open\n"); | 1684 | DEBUGP(2, dev, "<- cmm_open\n"); |
1683 | ret = nonseekable_open(inode, filp); | 1685 | ret = nonseekable_open(inode, filp); |
1684 | out: | 1686 | out: |
1685 | unlock_kernel(); | 1687 | mutex_unlock(&cmm_mutex); |
1686 | return ret; | 1688 | return ret; |
1687 | } | 1689 | } |
1688 | 1690 | ||
@@ -1864,6 +1866,7 @@ static const struct file_operations cm4000_fops = { | |||
1864 | .unlocked_ioctl = cmm_ioctl, | 1866 | .unlocked_ioctl = cmm_ioctl, |
1865 | .open = cmm_open, | 1867 | .open = cmm_open, |
1866 | .release= cmm_close, | 1868 | .release= cmm_close, |
1869 | .llseek = no_llseek, | ||
1867 | }; | 1870 | }; |
1868 | 1871 | ||
1869 | static struct pcmcia_device_id cm4000_ids[] = { | 1872 | static struct pcmcia_device_id cm4000_ids[] = { |
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index bf2f046fc2c1..5d8d59e865f4 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/fs.h> | 24 | #include <linux/fs.h> |
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/poll.h> | 26 | #include <linux/poll.h> |
27 | #include <linux/smp_lock.h> | 27 | #include <linux/mutex.h> |
28 | #include <linux/wait.h> | 28 | #include <linux/wait.h> |
29 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> |
30 | #include <asm/io.h> | 30 | #include <asm/io.h> |
@@ -48,6 +48,8 @@ | |||
48 | __func__ , ## args); \ | 48 | __func__ , ## args); \ |
49 | } while (0) | 49 | } while (0) |
50 | 50 | ||
51 | static DEFINE_MUTEX(cm4040_mutex); | ||
52 | |||
51 | #define CCID_DRIVER_BULK_DEFAULT_TIMEOUT (150*HZ) | 53 | #define CCID_DRIVER_BULK_DEFAULT_TIMEOUT (150*HZ) |
52 | #define CCID_DRIVER_ASYNC_POWERUP_TIMEOUT (35*HZ) | 54 | #define CCID_DRIVER_ASYNC_POWERUP_TIMEOUT (35*HZ) |
53 | #define CCID_DRIVER_MINIMUM_TIMEOUT (3*HZ) | 55 | #define CCID_DRIVER_MINIMUM_TIMEOUT (3*HZ) |
@@ -440,7 +442,7 @@ static int cm4040_open(struct inode *inode, struct file *filp) | |||
440 | if (minor >= CM_MAX_DEV) | 442 | if (minor >= CM_MAX_DEV) |
441 | return -ENODEV; | 443 | return -ENODEV; |
442 | 444 | ||
443 | lock_kernel(); | 445 | mutex_lock(&cm4040_mutex); |
444 | link = dev_table[minor]; | 446 | link = dev_table[minor]; |
445 | if (link == NULL || !pcmcia_dev_present(link)) { | 447 | if (link == NULL || !pcmcia_dev_present(link)) { |
446 | ret = -ENODEV; | 448 | ret = -ENODEV; |
@@ -469,7 +471,7 @@ static int cm4040_open(struct inode *inode, struct file *filp) | |||
469 | DEBUGP(2, dev, "<- cm4040_open (successfully)\n"); | 471 | DEBUGP(2, dev, "<- cm4040_open (successfully)\n"); |
470 | ret = nonseekable_open(inode, filp); | 472 | ret = nonseekable_open(inode, filp); |
471 | out: | 473 | out: |
472 | unlock_kernel(); | 474 | mutex_unlock(&cm4040_mutex); |
473 | return ret; | 475 | return ret; |
474 | } | 476 | } |
475 | 477 | ||
@@ -628,6 +630,7 @@ static const struct file_operations reader_fops = { | |||
628 | .open = cm4040_open, | 630 | .open = cm4040_open, |
629 | .release = cm4040_close, | 631 | .release = cm4040_close, |
630 | .poll = cm4040_poll, | 632 | .poll = cm4040_poll, |
633 | .llseek = no_llseek, | ||
631 | }; | 634 | }; |
632 | 635 | ||
633 | static struct pcmcia_device_id cm4040_ids[] = { | 636 | static struct pcmcia_device_id cm4040_ids[] = { |
diff --git a/drivers/char/pcmcia/ipwireless/Makefile b/drivers/char/pcmcia/ipwireless/Makefile index b71eb593643d..db80873d7f20 100644 --- a/drivers/char/pcmcia/ipwireless/Makefile +++ b/drivers/char/pcmcia/ipwireless/Makefile | |||
@@ -6,5 +6,5 @@ | |||
6 | 6 | ||
7 | obj-$(CONFIG_IPWIRELESS) += ipwireless.o | 7 | obj-$(CONFIG_IPWIRELESS) += ipwireless.o |
8 | 8 | ||
9 | ipwireless-objs := hardware.o main.o network.o tty.o | 9 | ipwireless-y := hardware.o main.o network.o tty.o |
10 | 10 | ||
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index be1810057607..bfc10f89d951 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -2191,6 +2191,32 @@ static int mgslpc_break(struct tty_struct *tty, int break_state) | |||
2191 | return 0; | 2191 | return 0; |
2192 | } | 2192 | } |
2193 | 2193 | ||
2194 | static int mgslpc_get_icount(struct tty_struct *tty, | ||
2195 | struct serial_icounter_struct *icount) | ||
2196 | { | ||
2197 | MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data; | ||
2198 | struct mgsl_icount cnow; /* kernel counter temps */ | ||
2199 | unsigned long flags; | ||
2200 | |||
2201 | spin_lock_irqsave(&info->lock,flags); | ||
2202 | cnow = info->icount; | ||
2203 | spin_unlock_irqrestore(&info->lock,flags); | ||
2204 | |||
2205 | icount->cts = cnow.cts; | ||
2206 | icount->dsr = cnow.dsr; | ||
2207 | icount->rng = cnow.rng; | ||
2208 | icount->dcd = cnow.dcd; | ||
2209 | icount->rx = cnow.rx; | ||
2210 | icount->tx = cnow.tx; | ||
2211 | icount->frame = cnow.frame; | ||
2212 | icount->overrun = cnow.overrun; | ||
2213 | icount->parity = cnow.parity; | ||
2214 | icount->brk = cnow.brk; | ||
2215 | icount->buf_overrun = cnow.buf_overrun; | ||
2216 | |||
2217 | return 0; | ||
2218 | } | ||
2219 | |||
2194 | /* Service an IOCTL request | 2220 | /* Service an IOCTL request |
2195 | * | 2221 | * |
2196 | * Arguments: | 2222 | * Arguments: |
@@ -2206,11 +2232,7 @@ static int mgslpc_ioctl(struct tty_struct *tty, struct file * file, | |||
2206 | unsigned int cmd, unsigned long arg) | 2232 | unsigned int cmd, unsigned long arg) |
2207 | { | 2233 | { |
2208 | MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data; | 2234 | MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data; |
2209 | int error; | ||
2210 | struct mgsl_icount cnow; /* kernel counter temps */ | ||
2211 | struct serial_icounter_struct __user *p_cuser; /* user space */ | ||
2212 | void __user *argp = (void __user *)arg; | 2235 | void __user *argp = (void __user *)arg; |
2213 | unsigned long flags; | ||
2214 | 2236 | ||
2215 | if (debug_level >= DEBUG_LEVEL_INFO) | 2237 | if (debug_level >= DEBUG_LEVEL_INFO) |
2216 | printk("%s(%d):mgslpc_ioctl %s cmd=%08X\n", __FILE__,__LINE__, | 2238 | printk("%s(%d):mgslpc_ioctl %s cmd=%08X\n", __FILE__,__LINE__, |
@@ -2220,7 +2242,7 @@ static int mgslpc_ioctl(struct tty_struct *tty, struct file * file, | |||
2220 | return -ENODEV; | 2242 | return -ENODEV; |
2221 | 2243 | ||
2222 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && | 2244 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && |
2223 | (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { | 2245 | (cmd != TIOCMIWAIT)) { |
2224 | if (tty->flags & (1 << TTY_IO_ERROR)) | 2246 | if (tty->flags & (1 << TTY_IO_ERROR)) |
2225 | return -EIO; | 2247 | return -EIO; |
2226 | } | 2248 | } |
@@ -2250,34 +2272,6 @@ static int mgslpc_ioctl(struct tty_struct *tty, struct file * file, | |||
2250 | return wait_events(info, argp); | 2272 | return wait_events(info, argp); |
2251 | case TIOCMIWAIT: | 2273 | case TIOCMIWAIT: |
2252 | return modem_input_wait(info,(int)arg); | 2274 | return modem_input_wait(info,(int)arg); |
2253 | case TIOCGICOUNT: | ||
2254 | spin_lock_irqsave(&info->lock,flags); | ||
2255 | cnow = info->icount; | ||
2256 | spin_unlock_irqrestore(&info->lock,flags); | ||
2257 | p_cuser = argp; | ||
2258 | PUT_USER(error,cnow.cts, &p_cuser->cts); | ||
2259 | if (error) return error; | ||
2260 | PUT_USER(error,cnow.dsr, &p_cuser->dsr); | ||
2261 | if (error) return error; | ||
2262 | PUT_USER(error,cnow.rng, &p_cuser->rng); | ||
2263 | if (error) return error; | ||
2264 | PUT_USER(error,cnow.dcd, &p_cuser->dcd); | ||
2265 | if (error) return error; | ||
2266 | PUT_USER(error,cnow.rx, &p_cuser->rx); | ||
2267 | if (error) return error; | ||
2268 | PUT_USER(error,cnow.tx, &p_cuser->tx); | ||
2269 | if (error) return error; | ||
2270 | PUT_USER(error,cnow.frame, &p_cuser->frame); | ||
2271 | if (error) return error; | ||
2272 | PUT_USER(error,cnow.overrun, &p_cuser->overrun); | ||
2273 | if (error) return error; | ||
2274 | PUT_USER(error,cnow.parity, &p_cuser->parity); | ||
2275 | if (error) return error; | ||
2276 | PUT_USER(error,cnow.brk, &p_cuser->brk); | ||
2277 | if (error) return error; | ||
2278 | PUT_USER(error,cnow.buf_overrun, &p_cuser->buf_overrun); | ||
2279 | if (error) return error; | ||
2280 | return 0; | ||
2281 | default: | 2275 | default: |
2282 | return -ENOIOCTLCMD; | 2276 | return -ENOIOCTLCMD; |
2283 | } | 2277 | } |
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index 02abfddce45a..f176dbaeb15a 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c | |||
@@ -67,7 +67,7 @@ | |||
67 | #include <linux/slab.h> | 67 | #include <linux/slab.h> |
68 | #include <linux/major.h> | 68 | #include <linux/major.h> |
69 | #include <linux/ppdev.h> | 69 | #include <linux/ppdev.h> |
70 | #include <linux/smp_lock.h> | 70 | #include <linux/mutex.h> |
71 | #include <linux/uaccess.h> | 71 | #include <linux/uaccess.h> |
72 | 72 | ||
73 | #define PP_VERSION "ppdev: user-space parallel port driver" | 73 | #define PP_VERSION "ppdev: user-space parallel port driver" |
@@ -97,6 +97,7 @@ struct pp_struct { | |||
97 | /* ROUND_UP macro from fs/select.c */ | 97 | /* ROUND_UP macro from fs/select.c */ |
98 | #define ROUND_UP(x,y) (((x)+(y)-1)/(y)) | 98 | #define ROUND_UP(x,y) (((x)+(y)-1)/(y)) |
99 | 99 | ||
100 | static DEFINE_MUTEX(pp_do_mutex); | ||
100 | static inline void pp_enable_irq (struct pp_struct *pp) | 101 | static inline void pp_enable_irq (struct pp_struct *pp) |
101 | { | 102 | { |
102 | struct parport *port = pp->pdev->port; | 103 | struct parport *port = pp->pdev->port; |
@@ -612,6 +613,7 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
612 | 613 | ||
613 | case PPGETTIME: | 614 | case PPGETTIME: |
614 | to_jiffies = pp->pdev->timeout; | 615 | to_jiffies = pp->pdev->timeout; |
616 | memset(&par_timeout, 0, sizeof(par_timeout)); | ||
615 | par_timeout.tv_sec = to_jiffies / HZ; | 617 | par_timeout.tv_sec = to_jiffies / HZ; |
616 | par_timeout.tv_usec = (to_jiffies % (long)HZ) * (1000000/HZ); | 618 | par_timeout.tv_usec = (to_jiffies % (long)HZ) * (1000000/HZ); |
617 | if (copy_to_user (argp, &par_timeout, sizeof(struct timeval))) | 619 | if (copy_to_user (argp, &par_timeout, sizeof(struct timeval))) |
@@ -630,9 +632,9 @@ static int pp_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
630 | static long pp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 632 | static long pp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
631 | { | 633 | { |
632 | long ret; | 634 | long ret; |
633 | lock_kernel(); | 635 | mutex_lock(&pp_do_mutex); |
634 | ret = pp_do_ioctl(file, cmd, arg); | 636 | ret = pp_do_ioctl(file, cmd, arg); |
635 | unlock_kernel(); | 637 | mutex_unlock(&pp_do_mutex); |
636 | return ret; | 638 | return ret; |
637 | } | 639 | } |
638 | 640 | ||
@@ -641,7 +643,6 @@ static int pp_open (struct inode * inode, struct file * file) | |||
641 | unsigned int minor = iminor(inode); | 643 | unsigned int minor = iminor(inode); |
642 | struct pp_struct *pp; | 644 | struct pp_struct *pp; |
643 | 645 | ||
644 | cycle_kernel_lock(); | ||
645 | if (minor >= PARPORT_MAX) | 646 | if (minor >= PARPORT_MAX) |
646 | return -ENXIO; | 647 | return -ENXIO; |
647 | 648 | ||
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index c350d01716bd..923a48585501 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -676,7 +676,9 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
676 | 676 | ||
677 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ | 677 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ |
678 | 678 | ||
679 | tty_add_file(tty, filp); | 679 | retval = tty_add_file(tty, filp); |
680 | if (retval) | ||
681 | goto out; | ||
680 | 682 | ||
681 | retval = devpts_pty_new(inode, tty->link); | 683 | retval = devpts_pty_new(inode, tty->link); |
682 | if (retval) | 684 | if (retval) |
diff --git a/drivers/char/ramoops.c b/drivers/char/ramoops.c index 74f00b5ffa36..73dcb0ee41fd 100644 --- a/drivers/char/ramoops.c +++ b/drivers/char/ramoops.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <linux/time.h> | 25 | #include <linux/time.h> |
26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
27 | #include <linux/ioport.h> | 27 | #include <linux/ioport.h> |
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/ramoops.h> | ||
28 | 30 | ||
29 | #define RAMOOPS_KERNMSG_HDR "====" | 31 | #define RAMOOPS_KERNMSG_HDR "====" |
30 | #define RAMOOPS_HEADER_SIZE (5 + sizeof(struct timeval)) | 32 | #define RAMOOPS_HEADER_SIZE (5 + sizeof(struct timeval)) |
@@ -91,11 +93,17 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper, | |||
91 | cxt->count = (cxt->count + 1) % cxt->max_count; | 93 | cxt->count = (cxt->count + 1) % cxt->max_count; |
92 | } | 94 | } |
93 | 95 | ||
94 | static int __init ramoops_init(void) | 96 | static int __init ramoops_probe(struct platform_device *pdev) |
95 | { | 97 | { |
98 | struct ramoops_platform_data *pdata = pdev->dev.platform_data; | ||
96 | struct ramoops_context *cxt = &oops_cxt; | 99 | struct ramoops_context *cxt = &oops_cxt; |
97 | int err = -EINVAL; | 100 | int err = -EINVAL; |
98 | 101 | ||
102 | if (pdata) { | ||
103 | mem_size = pdata->mem_size; | ||
104 | mem_address = pdata->mem_address; | ||
105 | } | ||
106 | |||
99 | if (!mem_size) { | 107 | if (!mem_size) { |
100 | printk(KERN_ERR "ramoops: invalid size specification"); | 108 | printk(KERN_ERR "ramoops: invalid size specification"); |
101 | goto fail3; | 109 | goto fail3; |
@@ -142,7 +150,7 @@ fail3: | |||
142 | return err; | 150 | return err; |
143 | } | 151 | } |
144 | 152 | ||
145 | static void __exit ramoops_exit(void) | 153 | static int __exit ramoops_remove(struct platform_device *pdev) |
146 | { | 154 | { |
147 | struct ramoops_context *cxt = &oops_cxt; | 155 | struct ramoops_context *cxt = &oops_cxt; |
148 | 156 | ||
@@ -151,8 +159,26 @@ static void __exit ramoops_exit(void) | |||
151 | 159 | ||
152 | iounmap(cxt->virt_addr); | 160 | iounmap(cxt->virt_addr); |
153 | release_mem_region(cxt->phys_addr, cxt->size); | 161 | release_mem_region(cxt->phys_addr, cxt->size); |
162 | return 0; | ||
154 | } | 163 | } |
155 | 164 | ||
165 | static struct platform_driver ramoops_driver = { | ||
166 | .remove = __exit_p(ramoops_remove), | ||
167 | .driver = { | ||
168 | .name = "ramoops", | ||
169 | .owner = THIS_MODULE, | ||
170 | }, | ||
171 | }; | ||
172 | |||
173 | static int __init ramoops_init(void) | ||
174 | { | ||
175 | return platform_driver_probe(&ramoops_driver, ramoops_probe); | ||
176 | } | ||
177 | |||
178 | static void __exit ramoops_exit(void) | ||
179 | { | ||
180 | platform_driver_unregister(&ramoops_driver); | ||
181 | } | ||
156 | 182 | ||
157 | module_init(ramoops_init); | 183 | module_init(ramoops_init); |
158 | module_exit(ramoops_exit); | 184 | module_exit(ramoops_exit); |
diff --git a/drivers/char/random.c b/drivers/char/random.c index caef35a46890..5a1aa64f4e76 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -1165,6 +1165,7 @@ const struct file_operations random_fops = { | |||
1165 | .poll = random_poll, | 1165 | .poll = random_poll, |
1166 | .unlocked_ioctl = random_ioctl, | 1166 | .unlocked_ioctl = random_ioctl, |
1167 | .fasync = random_fasync, | 1167 | .fasync = random_fasync, |
1168 | .llseek = noop_llseek, | ||
1168 | }; | 1169 | }; |
1169 | 1170 | ||
1170 | const struct file_operations urandom_fops = { | 1171 | const struct file_operations urandom_fops = { |
@@ -1172,6 +1173,7 @@ const struct file_operations urandom_fops = { | |||
1172 | .write = random_write, | 1173 | .write = random_write, |
1173 | .unlocked_ioctl = random_ioctl, | 1174 | .unlocked_ioctl = random_ioctl, |
1174 | .fasync = random_fasync, | 1175 | .fasync = random_fasync, |
1176 | .llseek = noop_llseek, | ||
1175 | }; | 1177 | }; |
1176 | 1178 | ||
1177 | /*************************************************************** | 1179 | /*************************************************************** |
diff --git a/drivers/char/raw.c b/drivers/char/raw.c index b38942f6bf31..bfe25ea9766b 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c | |||
@@ -19,8 +19,8 @@ | |||
19 | #include <linux/cdev.h> | 19 | #include <linux/cdev.h> |
20 | #include <linux/device.h> | 20 | #include <linux/device.h> |
21 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
22 | #include <linux/smp_lock.h> | ||
23 | #include <linux/gfp.h> | 22 | #include <linux/gfp.h> |
23 | #include <linux/compat.h> | ||
24 | 24 | ||
25 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
26 | 26 | ||
@@ -55,7 +55,6 @@ static int raw_open(struct inode *inode, struct file *filp) | |||
55 | return 0; | 55 | return 0; |
56 | } | 56 | } |
57 | 57 | ||
58 | lock_kernel(); | ||
59 | mutex_lock(&raw_mutex); | 58 | mutex_lock(&raw_mutex); |
60 | 59 | ||
61 | /* | 60 | /* |
@@ -82,7 +81,6 @@ static int raw_open(struct inode *inode, struct file *filp) | |||
82 | bdev->bd_inode->i_mapping; | 81 | bdev->bd_inode->i_mapping; |
83 | filp->private_data = bdev; | 82 | filp->private_data = bdev; |
84 | mutex_unlock(&raw_mutex); | 83 | mutex_unlock(&raw_mutex); |
85 | unlock_kernel(); | ||
86 | return 0; | 84 | return 0; |
87 | 85 | ||
88 | out2: | 86 | out2: |
@@ -91,7 +89,6 @@ out1: | |||
91 | blkdev_put(bdev, filp->f_mode); | 89 | blkdev_put(bdev, filp->f_mode); |
92 | out: | 90 | out: |
93 | mutex_unlock(&raw_mutex); | 91 | mutex_unlock(&raw_mutex); |
94 | unlock_kernel(); | ||
95 | return err; | 92 | return err; |
96 | } | 93 | } |
97 | 94 | ||
@@ -125,20 +122,84 @@ static long | |||
125 | raw_ioctl(struct file *filp, unsigned int command, unsigned long arg) | 122 | raw_ioctl(struct file *filp, unsigned int command, unsigned long arg) |
126 | { | 123 | { |
127 | struct block_device *bdev = filp->private_data; | 124 | struct block_device *bdev = filp->private_data; |
128 | int ret; | 125 | return blkdev_ioctl(bdev, 0, command, arg); |
126 | } | ||
127 | |||
128 | static int bind_set(int number, u64 major, u64 minor) | ||
129 | { | ||
130 | dev_t dev = MKDEV(major, minor); | ||
131 | struct raw_device_data *rawdev; | ||
132 | int err = 0; | ||
129 | 133 | ||
130 | lock_kernel(); | 134 | if (number <= 0 || number >= MAX_RAW_MINORS) |
131 | ret = blkdev_ioctl(bdev, 0, command, arg); | 135 | return -EINVAL; |
132 | unlock_kernel(); | ||
133 | 136 | ||
134 | return ret; | 137 | if (MAJOR(dev) != major || MINOR(dev) != minor) |
138 | return -EINVAL; | ||
139 | |||
140 | rawdev = &raw_devices[number]; | ||
141 | |||
142 | /* | ||
143 | * This is like making block devices, so demand the | ||
144 | * same capability | ||
145 | */ | ||
146 | if (!capable(CAP_SYS_ADMIN)) | ||
147 | return -EPERM; | ||
148 | |||
149 | /* | ||
150 | * For now, we don't need to check that the underlying | ||
151 | * block device is present or not: we can do that when | ||
152 | * the raw device is opened. Just check that the | ||
153 | * major/minor numbers make sense. | ||
154 | */ | ||
155 | |||
156 | if (MAJOR(dev) == 0 && dev != 0) | ||
157 | return -EINVAL; | ||
158 | |||
159 | mutex_lock(&raw_mutex); | ||
160 | if (rawdev->inuse) { | ||
161 | mutex_unlock(&raw_mutex); | ||
162 | return -EBUSY; | ||
163 | } | ||
164 | if (rawdev->binding) { | ||
165 | bdput(rawdev->binding); | ||
166 | module_put(THIS_MODULE); | ||
167 | } | ||
168 | if (!dev) { | ||
169 | /* unbind */ | ||
170 | rawdev->binding = NULL; | ||
171 | device_destroy(raw_class, MKDEV(RAW_MAJOR, number)); | ||
172 | } else { | ||
173 | rawdev->binding = bdget(dev); | ||
174 | if (rawdev->binding == NULL) { | ||
175 | err = -ENOMEM; | ||
176 | } else { | ||
177 | dev_t raw = MKDEV(RAW_MAJOR, number); | ||
178 | __module_get(THIS_MODULE); | ||
179 | device_destroy(raw_class, raw); | ||
180 | device_create(raw_class, NULL, raw, NULL, | ||
181 | "raw%d", number); | ||
182 | } | ||
183 | } | ||
184 | mutex_unlock(&raw_mutex); | ||
185 | return err; | ||
135 | } | 186 | } |
136 | 187 | ||
137 | static void bind_device(struct raw_config_request *rq) | 188 | static int bind_get(int number, dev_t *dev) |
138 | { | 189 | { |
139 | device_destroy(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor)); | 190 | struct raw_device_data *rawdev; |
140 | device_create(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor), NULL, | 191 | struct block_device *bdev; |
141 | "raw%d", rq->raw_minor); | 192 | |
193 | if (number <= 0 || number >= MAX_RAW_MINORS) | ||
194 | return -EINVAL; | ||
195 | |||
196 | rawdev = &raw_devices[number]; | ||
197 | |||
198 | mutex_lock(&raw_mutex); | ||
199 | bdev = rawdev->binding; | ||
200 | *dev = bdev ? bdev->bd_dev : 0; | ||
201 | mutex_unlock(&raw_mutex); | ||
202 | return 0; | ||
142 | } | 203 | } |
143 | 204 | ||
144 | /* | 205 | /* |
@@ -149,105 +210,78 @@ static long raw_ctl_ioctl(struct file *filp, unsigned int command, | |||
149 | unsigned long arg) | 210 | unsigned long arg) |
150 | { | 211 | { |
151 | struct raw_config_request rq; | 212 | struct raw_config_request rq; |
152 | struct raw_device_data *rawdev; | 213 | dev_t dev; |
153 | int err = 0; | 214 | int err; |
154 | 215 | ||
155 | lock_kernel(); | ||
156 | switch (command) { | 216 | switch (command) { |
157 | case RAW_SETBIND: | 217 | case RAW_SETBIND: |
218 | if (copy_from_user(&rq, (void __user *) arg, sizeof(rq))) | ||
219 | return -EFAULT; | ||
220 | |||
221 | return bind_set(rq.raw_minor, rq.block_major, rq.block_minor); | ||
222 | |||
158 | case RAW_GETBIND: | 223 | case RAW_GETBIND: |
224 | if (copy_from_user(&rq, (void __user *) arg, sizeof(rq))) | ||
225 | return -EFAULT; | ||
159 | 226 | ||
160 | /* First, find out which raw minor we want */ | 227 | err = bind_get(rq.raw_minor, &dev); |
228 | if (err) | ||
229 | return err; | ||
161 | 230 | ||
162 | if (copy_from_user(&rq, (void __user *) arg, sizeof(rq))) { | 231 | rq.block_major = MAJOR(dev); |
163 | err = -EFAULT; | 232 | rq.block_minor = MINOR(dev); |
164 | goto out; | ||
165 | } | ||
166 | 233 | ||
167 | if (rq.raw_minor <= 0 || rq.raw_minor >= MAX_RAW_MINORS) { | 234 | if (copy_to_user((void __user *)arg, &rq, sizeof(rq))) |
168 | err = -EINVAL; | 235 | return -EFAULT; |
169 | goto out; | 236 | |
170 | } | 237 | return 0; |
171 | rawdev = &raw_devices[rq.raw_minor]; | ||
172 | |||
173 | if (command == RAW_SETBIND) { | ||
174 | dev_t dev; | ||
175 | |||
176 | /* | ||
177 | * This is like making block devices, so demand the | ||
178 | * same capability | ||
179 | */ | ||
180 | if (!capable(CAP_SYS_ADMIN)) { | ||
181 | err = -EPERM; | ||
182 | goto out; | ||
183 | } | ||
184 | |||
185 | /* | ||
186 | * For now, we don't need to check that the underlying | ||
187 | * block device is present or not: we can do that when | ||
188 | * the raw device is opened. Just check that the | ||
189 | * major/minor numbers make sense. | ||
190 | */ | ||
191 | |||
192 | dev = MKDEV(rq.block_major, rq.block_minor); | ||
193 | if ((rq.block_major == 0 && rq.block_minor != 0) || | ||
194 | MAJOR(dev) != rq.block_major || | ||
195 | MINOR(dev) != rq.block_minor) { | ||
196 | err = -EINVAL; | ||
197 | goto out; | ||
198 | } | ||
199 | |||
200 | mutex_lock(&raw_mutex); | ||
201 | if (rawdev->inuse) { | ||
202 | mutex_unlock(&raw_mutex); | ||
203 | err = -EBUSY; | ||
204 | goto out; | ||
205 | } | ||
206 | if (rawdev->binding) { | ||
207 | bdput(rawdev->binding); | ||
208 | module_put(THIS_MODULE); | ||
209 | } | ||
210 | if (rq.block_major == 0 && rq.block_minor == 0) { | ||
211 | /* unbind */ | ||
212 | rawdev->binding = NULL; | ||
213 | device_destroy(raw_class, | ||
214 | MKDEV(RAW_MAJOR, rq.raw_minor)); | ||
215 | } else { | ||
216 | rawdev->binding = bdget(dev); | ||
217 | if (rawdev->binding == NULL) | ||
218 | err = -ENOMEM; | ||
219 | else { | ||
220 | __module_get(THIS_MODULE); | ||
221 | bind_device(&rq); | ||
222 | } | ||
223 | } | ||
224 | mutex_unlock(&raw_mutex); | ||
225 | } else { | ||
226 | struct block_device *bdev; | ||
227 | |||
228 | mutex_lock(&raw_mutex); | ||
229 | bdev = rawdev->binding; | ||
230 | if (bdev) { | ||
231 | rq.block_major = MAJOR(bdev->bd_dev); | ||
232 | rq.block_minor = MINOR(bdev->bd_dev); | ||
233 | } else { | ||
234 | rq.block_major = rq.block_minor = 0; | ||
235 | } | ||
236 | mutex_unlock(&raw_mutex); | ||
237 | if (copy_to_user((void __user *)arg, &rq, sizeof(rq))) { | ||
238 | err = -EFAULT; | ||
239 | goto out; | ||
240 | } | ||
241 | } | ||
242 | break; | ||
243 | default: | ||
244 | err = -EINVAL; | ||
245 | break; | ||
246 | } | 238 | } |
247 | out: | 239 | |
248 | unlock_kernel(); | 240 | return -EINVAL; |
249 | return err; | 241 | } |
242 | |||
243 | #ifdef CONFIG_COMPAT | ||
244 | struct raw32_config_request { | ||
245 | compat_int_t raw_minor; | ||
246 | compat_u64 block_major; | ||
247 | compat_u64 block_minor; | ||
248 | }; | ||
249 | |||
250 | static long raw_ctl_compat_ioctl(struct file *file, unsigned int cmd, | ||
251 | unsigned long arg) | ||
252 | { | ||
253 | struct raw32_config_request __user *user_req = compat_ptr(arg); | ||
254 | struct raw32_config_request rq; | ||
255 | dev_t dev; | ||
256 | int err = 0; | ||
257 | |||
258 | switch (cmd) { | ||
259 | case RAW_SETBIND: | ||
260 | if (copy_from_user(&rq, user_req, sizeof(rq))) | ||
261 | return -EFAULT; | ||
262 | |||
263 | return bind_set(rq.raw_minor, rq.block_major, rq.block_minor); | ||
264 | |||
265 | case RAW_GETBIND: | ||
266 | if (copy_from_user(&rq, user_req, sizeof(rq))) | ||
267 | return -EFAULT; | ||
268 | |||
269 | err = bind_get(rq.raw_minor, &dev); | ||
270 | if (err) | ||
271 | return err; | ||
272 | |||
273 | rq.block_major = MAJOR(dev); | ||
274 | rq.block_minor = MINOR(dev); | ||
275 | |||
276 | if (copy_to_user(user_req, &rq, sizeof(rq))) | ||
277 | return -EFAULT; | ||
278 | |||
279 | return 0; | ||
280 | } | ||
281 | |||
282 | return -EINVAL; | ||
250 | } | 283 | } |
284 | #endif | ||
251 | 285 | ||
252 | static const struct file_operations raw_fops = { | 286 | static const struct file_operations raw_fops = { |
253 | .read = do_sync_read, | 287 | .read = do_sync_read, |
@@ -258,13 +292,18 @@ static const struct file_operations raw_fops = { | |||
258 | .open = raw_open, | 292 | .open = raw_open, |
259 | .release = raw_release, | 293 | .release = raw_release, |
260 | .unlocked_ioctl = raw_ioctl, | 294 | .unlocked_ioctl = raw_ioctl, |
295 | .llseek = default_llseek, | ||
261 | .owner = THIS_MODULE, | 296 | .owner = THIS_MODULE, |
262 | }; | 297 | }; |
263 | 298 | ||
264 | static const struct file_operations raw_ctl_fops = { | 299 | static const struct file_operations raw_ctl_fops = { |
265 | .unlocked_ioctl = raw_ctl_ioctl, | 300 | .unlocked_ioctl = raw_ctl_ioctl, |
301 | #ifdef CONFIG_COMPAT | ||
302 | .compat_ioctl = raw_ctl_compat_ioctl, | ||
303 | #endif | ||
266 | .open = raw_open, | 304 | .open = raw_open, |
267 | .owner = THIS_MODULE, | 305 | .owner = THIS_MODULE, |
306 | .llseek = noop_llseek, | ||
268 | }; | 307 | }; |
269 | 308 | ||
270 | static struct cdev raw_cdev; | 309 | static struct cdev raw_cdev; |
diff --git a/drivers/char/rio/Makefile b/drivers/char/rio/Makefile index 2d1c5a7cba7d..1661875883fb 100644 --- a/drivers/char/rio/Makefile +++ b/drivers/char/rio/Makefile | |||
@@ -8,5 +8,5 @@ | |||
8 | 8 | ||
9 | obj-$(CONFIG_RIO) += rio.o | 9 | obj-$(CONFIG_RIO) += rio.o |
10 | 10 | ||
11 | rio-objs := rio_linux.o rioinit.o rioboot.o riocmd.o rioctrl.o riointr.o \ | 11 | rio-y := rio_linux.o rioinit.o rioboot.o riocmd.o rioctrl.o riointr.o \ |
12 | rioparam.o rioroute.o riotable.o riotty.o | 12 | rioparam.o rioroute.o riotable.o riotty.o |
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c index d58c2eb07f07..5e33293d24e3 100644 --- a/drivers/char/rio/rio_linux.c +++ b/drivers/char/rio/rio_linux.c | |||
@@ -44,7 +44,7 @@ | |||
44 | #include <linux/delay.h> | 44 | #include <linux/delay.h> |
45 | #include <linux/pci.h> | 45 | #include <linux/pci.h> |
46 | #include <linux/slab.h> | 46 | #include <linux/slab.h> |
47 | #include <linux/smp_lock.h> | 47 | #include <linux/mutex.h> |
48 | #include <linux/miscdevice.h> | 48 | #include <linux/miscdevice.h> |
49 | #include <linux/init.h> | 49 | #include <linux/init.h> |
50 | 50 | ||
@@ -122,6 +122,7 @@ more than 512 ports.... */ | |||
122 | 122 | ||
123 | 123 | ||
124 | /* These constants are derived from SCO Source */ | 124 | /* These constants are derived from SCO Source */ |
125 | static DEFINE_MUTEX(rio_fw_mutex); | ||
125 | static struct Conf | 126 | static struct Conf |
126 | RIOConf = { | 127 | RIOConf = { |
127 | /* locator */ "RIO Config here", | 128 | /* locator */ "RIO Config here", |
@@ -241,6 +242,7 @@ static struct real_driver rio_real_driver = { | |||
241 | static const struct file_operations rio_fw_fops = { | 242 | static const struct file_operations rio_fw_fops = { |
242 | .owner = THIS_MODULE, | 243 | .owner = THIS_MODULE, |
243 | .unlocked_ioctl = rio_fw_ioctl, | 244 | .unlocked_ioctl = rio_fw_ioctl, |
245 | .llseek = noop_llseek, | ||
244 | }; | 246 | }; |
245 | 247 | ||
246 | static struct miscdevice rio_fw_device = { | 248 | static struct miscdevice rio_fw_device = { |
@@ -566,9 +568,9 @@ static long rio_fw_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
566 | func_enter(); | 568 | func_enter(); |
567 | 569 | ||
568 | /* The "dev" argument isn't used. */ | 570 | /* The "dev" argument isn't used. */ |
569 | lock_kernel(); | 571 | mutex_lock(&rio_fw_mutex); |
570 | rc = riocontrol(p, 0, cmd, arg, capable(CAP_SYS_ADMIN)); | 572 | rc = riocontrol(p, 0, cmd, arg, capable(CAP_SYS_ADMIN)); |
571 | unlock_kernel(); | 573 | mutex_unlock(&rio_fw_mutex); |
572 | 574 | ||
573 | func_exit(); | 575 | func_exit(); |
574 | return rc; | 576 | return rc; |
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 7c79d243acc9..86308830ac42 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -2345,7 +2345,7 @@ static int __init rp_init(void) | |||
2345 | ret = tty_register_driver(rocket_driver); | 2345 | ret = tty_register_driver(rocket_driver); |
2346 | if (ret < 0) { | 2346 | if (ret < 0) { |
2347 | printk(KERN_ERR "Couldn't install tty RocketPort driver\n"); | 2347 | printk(KERN_ERR "Couldn't install tty RocketPort driver\n"); |
2348 | goto err_tty; | 2348 | goto err_controller; |
2349 | } | 2349 | } |
2350 | 2350 | ||
2351 | #ifdef ROCKET_DEBUG_OPEN | 2351 | #ifdef ROCKET_DEBUG_OPEN |
@@ -2380,6 +2380,9 @@ static int __init rp_init(void) | |||
2380 | return 0; | 2380 | return 0; |
2381 | err_ttyu: | 2381 | err_ttyu: |
2382 | tty_unregister_driver(rocket_driver); | 2382 | tty_unregister_driver(rocket_driver); |
2383 | err_controller: | ||
2384 | if (controller) | ||
2385 | release_region(controller, 4); | ||
2383 | err_tty: | 2386 | err_tty: |
2384 | put_tty_driver(rocket_driver); | 2387 | put_tty_driver(rocket_driver); |
2385 | err: | 2388 | err: |
diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c index 99e5272e3c53..0bc135b9b16f 100644 --- a/drivers/char/scx200_gpio.c +++ b/drivers/char/scx200_gpio.c | |||
@@ -67,6 +67,7 @@ static const struct file_operations scx200_gpio_fileops = { | |||
67 | .read = nsc_gpio_read, | 67 | .read = nsc_gpio_read, |
68 | .open = scx200_gpio_open, | 68 | .open = scx200_gpio_open, |
69 | .release = scx200_gpio_release, | 69 | .release = scx200_gpio_release, |
70 | .llseek = no_llseek, | ||
70 | }; | 71 | }; |
71 | 72 | ||
72 | static struct cdev scx200_gpio_cdev; /* use 1 cdev for all pins */ | 73 | static struct cdev scx200_gpio_cdev; /* use 1 cdev for all pins */ |
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c index 32b74de18f5f..5816b39ff5a9 100644 --- a/drivers/char/snsc.c +++ b/drivers/char/snsc.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/poll.h> | 21 | #include <linux/poll.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/smp_lock.h> | 24 | #include <linux/mutex.h> |
25 | #include <asm/sn/io.h> | 25 | #include <asm/sn/io.h> |
26 | #include <asm/sn/sn_sal.h> | 26 | #include <asm/sn/sn_sal.h> |
27 | #include <asm/sn/module.h> | 27 | #include <asm/sn/module.h> |
@@ -34,6 +34,7 @@ | |||
34 | #define SCDRV_BUFSZ 2048 | 34 | #define SCDRV_BUFSZ 2048 |
35 | #define SCDRV_TIMEOUT 1000 | 35 | #define SCDRV_TIMEOUT 1000 |
36 | 36 | ||
37 | static DEFINE_MUTEX(scdrv_mutex); | ||
37 | static irqreturn_t | 38 | static irqreturn_t |
38 | scdrv_interrupt(int irq, void *subch_data) | 39 | scdrv_interrupt(int irq, void *subch_data) |
39 | { | 40 | { |
@@ -105,7 +106,7 @@ scdrv_open(struct inode *inode, struct file *file) | |||
105 | file->private_data = sd; | 106 | file->private_data = sd; |
106 | 107 | ||
107 | /* hook this subchannel up to the system controller interrupt */ | 108 | /* hook this subchannel up to the system controller interrupt */ |
108 | lock_kernel(); | 109 | mutex_lock(&scdrv_mutex); |
109 | rv = request_irq(SGI_UART_VECTOR, scdrv_interrupt, | 110 | rv = request_irq(SGI_UART_VECTOR, scdrv_interrupt, |
110 | IRQF_SHARED | IRQF_DISABLED, | 111 | IRQF_SHARED | IRQF_DISABLED, |
111 | SYSCTL_BASENAME, sd); | 112 | SYSCTL_BASENAME, sd); |
@@ -113,10 +114,10 @@ scdrv_open(struct inode *inode, struct file *file) | |||
113 | ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch); | 114 | ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch); |
114 | kfree(sd); | 115 | kfree(sd); |
115 | printk("%s: irq request failed (%d)\n", __func__, rv); | 116 | printk("%s: irq request failed (%d)\n", __func__, rv); |
116 | unlock_kernel(); | 117 | mutex_unlock(&scdrv_mutex); |
117 | return -EBUSY; | 118 | return -EBUSY; |
118 | } | 119 | } |
119 | unlock_kernel(); | 120 | mutex_unlock(&scdrv_mutex); |
120 | return 0; | 121 | return 0; |
121 | } | 122 | } |
122 | 123 | ||
@@ -357,6 +358,7 @@ static const struct file_operations scdrv_fops = { | |||
357 | .poll = scdrv_poll, | 358 | .poll = scdrv_poll, |
358 | .open = scdrv_open, | 359 | .open = scdrv_open, |
359 | .release = scdrv_release, | 360 | .release = scdrv_release, |
361 | .llseek = noop_llseek, | ||
360 | }; | 362 | }; |
361 | 363 | ||
362 | static struct class *snsc_class; | 364 | static struct class *snsc_class; |
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index f2167f8e5aab..4bef6ab83622 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -608,6 +608,7 @@ static unsigned int sc26198_baudtable[] = { | |||
608 | static const struct file_operations stl_fsiomem = { | 608 | static const struct file_operations stl_fsiomem = { |
609 | .owner = THIS_MODULE, | 609 | .owner = THIS_MODULE, |
610 | .unlocked_ioctl = stl_memioctl, | 610 | .unlocked_ioctl = stl_memioctl, |
611 | .llseek = noop_llseek, | ||
611 | }; | 612 | }; |
612 | 613 | ||
613 | static struct class *stallion_class; | 614 | static struct class *stallion_class; |
@@ -3180,7 +3181,7 @@ static void stl_cd1400flush(struct stlport *portp) | |||
3180 | 3181 | ||
3181 | /* | 3182 | /* |
3182 | * Return the current state of data flow on this port. This is only | 3183 | * Return the current state of data flow on this port. This is only |
3183 | * really interresting when determining if data has fully completed | 3184 | * really interesting when determining if data has fully completed |
3184 | * transmission or not... This is easy for the cd1400, it accurately | 3185 | * transmission or not... This is easy for the cd1400, it accurately |
3185 | * maintains the busy port flag. | 3186 | * maintains the busy port flag. |
3186 | */ | 3187 | */ |
@@ -4130,7 +4131,7 @@ static void stl_sc26198flush(struct stlport *portp) | |||
4130 | 4131 | ||
4131 | /* | 4132 | /* |
4132 | * Return the current state of data flow on this port. This is only | 4133 | * Return the current state of data flow on this port. This is only |
4133 | * really interresting when determining if data has fully completed | 4134 | * really interesting when determining if data has fully completed |
4134 | * transmission or not... The sc26198 interrupt scheme cannot | 4135 | * transmission or not... The sc26198 interrupt scheme cannot |
4135 | * determine when all data has actually drained, so we need to | 4136 | * determine when all data has actually drained, so we need to |
4136 | * check the port statusy register to be sure. | 4137 | * check the port statusy register to be sure. |
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index 5b24db4ff7f1..e53f16865397 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c | |||
@@ -397,6 +397,7 @@ static struct real_driver sx_real_driver = { | |||
397 | static const struct file_operations sx_fw_fops = { | 397 | static const struct file_operations sx_fw_fops = { |
398 | .owner = THIS_MODULE, | 398 | .owner = THIS_MODULE, |
399 | .unlocked_ioctl = sx_fw_ioctl, | 399 | .unlocked_ioctl = sx_fw_ioctl, |
400 | .llseek = noop_llseek, | ||
400 | }; | 401 | }; |
401 | 402 | ||
402 | static struct miscdevice sx_fw_device = { | 403 | static struct miscdevice sx_fw_device = { |
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index a2a58004e188..3a6824f12be2 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c | |||
@@ -2925,6 +2925,38 @@ static int mgsl_break(struct tty_struct *tty, int break_state) | |||
2925 | 2925 | ||
2926 | } /* end of mgsl_break() */ | 2926 | } /* end of mgsl_break() */ |
2927 | 2927 | ||
2928 | /* | ||
2929 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
2930 | * Return: write counters to the user passed counter struct | ||
2931 | * NB: both 1->0 and 0->1 transitions are counted except for | ||
2932 | * RI where only 0->1 is counted. | ||
2933 | */ | ||
2934 | static int msgl_get_icount(struct tty_struct *tty, | ||
2935 | struct serial_icounter_struct *icount) | ||
2936 | |||
2937 | { | ||
2938 | struct mgsl_struct * info = tty->driver_data; | ||
2939 | struct mgsl_icount cnow; /* kernel counter temps */ | ||
2940 | unsigned long flags; | ||
2941 | |||
2942 | spin_lock_irqsave(&info->irq_spinlock,flags); | ||
2943 | cnow = info->icount; | ||
2944 | spin_unlock_irqrestore(&info->irq_spinlock,flags); | ||
2945 | |||
2946 | icount->cts = cnow.cts; | ||
2947 | icount->dsr = cnow.dsr; | ||
2948 | icount->rng = cnow.rng; | ||
2949 | icount->dcd = cnow.dcd; | ||
2950 | icount->rx = cnow.rx; | ||
2951 | icount->tx = cnow.tx; | ||
2952 | icount->frame = cnow.frame; | ||
2953 | icount->overrun = cnow.overrun; | ||
2954 | icount->parity = cnow.parity; | ||
2955 | icount->brk = cnow.brk; | ||
2956 | icount->buf_overrun = cnow.buf_overrun; | ||
2957 | return 0; | ||
2958 | } | ||
2959 | |||
2928 | /* mgsl_ioctl() Service an IOCTL request | 2960 | /* mgsl_ioctl() Service an IOCTL request |
2929 | * | 2961 | * |
2930 | * Arguments: | 2962 | * Arguments: |
@@ -2949,7 +2981,7 @@ static int mgsl_ioctl(struct tty_struct *tty, struct file * file, | |||
2949 | return -ENODEV; | 2981 | return -ENODEV; |
2950 | 2982 | ||
2951 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && | 2983 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && |
2952 | (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { | 2984 | (cmd != TIOCMIWAIT)) { |
2953 | if (tty->flags & (1 << TTY_IO_ERROR)) | 2985 | if (tty->flags & (1 << TTY_IO_ERROR)) |
2954 | return -EIO; | 2986 | return -EIO; |
2955 | } | 2987 | } |
@@ -2959,11 +2991,7 @@ static int mgsl_ioctl(struct tty_struct *tty, struct file * file, | |||
2959 | 2991 | ||
2960 | static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg) | 2992 | static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg) |
2961 | { | 2993 | { |
2962 | int error; | ||
2963 | struct mgsl_icount cnow; /* kernel counter temps */ | ||
2964 | void __user *argp = (void __user *)arg; | 2994 | void __user *argp = (void __user *)arg; |
2965 | struct serial_icounter_struct __user *p_cuser; /* user space */ | ||
2966 | unsigned long flags; | ||
2967 | 2995 | ||
2968 | switch (cmd) { | 2996 | switch (cmd) { |
2969 | case MGSL_IOCGPARAMS: | 2997 | case MGSL_IOCGPARAMS: |
@@ -2992,40 +3020,6 @@ static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigne | |||
2992 | case TIOCMIWAIT: | 3020 | case TIOCMIWAIT: |
2993 | return modem_input_wait(info,(int)arg); | 3021 | return modem_input_wait(info,(int)arg); |
2994 | 3022 | ||
2995 | /* | ||
2996 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
2997 | * Return: write counters to the user passed counter struct | ||
2998 | * NB: both 1->0 and 0->1 transitions are counted except for | ||
2999 | * RI where only 0->1 is counted. | ||
3000 | */ | ||
3001 | case TIOCGICOUNT: | ||
3002 | spin_lock_irqsave(&info->irq_spinlock,flags); | ||
3003 | cnow = info->icount; | ||
3004 | spin_unlock_irqrestore(&info->irq_spinlock,flags); | ||
3005 | p_cuser = argp; | ||
3006 | PUT_USER(error,cnow.cts, &p_cuser->cts); | ||
3007 | if (error) return error; | ||
3008 | PUT_USER(error,cnow.dsr, &p_cuser->dsr); | ||
3009 | if (error) return error; | ||
3010 | PUT_USER(error,cnow.rng, &p_cuser->rng); | ||
3011 | if (error) return error; | ||
3012 | PUT_USER(error,cnow.dcd, &p_cuser->dcd); | ||
3013 | if (error) return error; | ||
3014 | PUT_USER(error,cnow.rx, &p_cuser->rx); | ||
3015 | if (error) return error; | ||
3016 | PUT_USER(error,cnow.tx, &p_cuser->tx); | ||
3017 | if (error) return error; | ||
3018 | PUT_USER(error,cnow.frame, &p_cuser->frame); | ||
3019 | if (error) return error; | ||
3020 | PUT_USER(error,cnow.overrun, &p_cuser->overrun); | ||
3021 | if (error) return error; | ||
3022 | PUT_USER(error,cnow.parity, &p_cuser->parity); | ||
3023 | if (error) return error; | ||
3024 | PUT_USER(error,cnow.brk, &p_cuser->brk); | ||
3025 | if (error) return error; | ||
3026 | PUT_USER(error,cnow.buf_overrun, &p_cuser->buf_overrun); | ||
3027 | if (error) return error; | ||
3028 | return 0; | ||
3029 | default: | 3023 | default: |
3030 | return -ENOIOCTLCMD; | 3024 | return -ENOIOCTLCMD; |
3031 | } | 3025 | } |
@@ -4328,6 +4322,7 @@ static const struct tty_operations mgsl_ops = { | |||
4328 | .hangup = mgsl_hangup, | 4322 | .hangup = mgsl_hangup, |
4329 | .tiocmget = tiocmget, | 4323 | .tiocmget = tiocmget, |
4330 | .tiocmset = tiocmset, | 4324 | .tiocmset = tiocmset, |
4325 | .get_icount = msgl_get_icount, | ||
4331 | .proc_fops = &mgsl_proc_fops, | 4326 | .proc_fops = &mgsl_proc_fops, |
4332 | }; | 4327 | }; |
4333 | 4328 | ||
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index e63b830c86cc..d01fffeac951 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -301,6 +301,8 @@ struct slgt_info { | |||
301 | unsigned int rx_pio; | 301 | unsigned int rx_pio; |
302 | unsigned int if_mode; | 302 | unsigned int if_mode; |
303 | unsigned int base_clock; | 303 | unsigned int base_clock; |
304 | unsigned int xsync; | ||
305 | unsigned int xctrl; | ||
304 | 306 | ||
305 | /* device status */ | 307 | /* device status */ |
306 | 308 | ||
@@ -405,6 +407,8 @@ static MGSL_PARAMS default_params = { | |||
405 | #define TDCSR 0x94 /* tx DMA control/status */ | 407 | #define TDCSR 0x94 /* tx DMA control/status */ |
406 | #define RDDAR 0x98 /* rx DMA descriptor address */ | 408 | #define RDDAR 0x98 /* rx DMA descriptor address */ |
407 | #define TDDAR 0x9c /* tx DMA descriptor address */ | 409 | #define TDDAR 0x9c /* tx DMA descriptor address */ |
410 | #define XSR 0x40 /* extended sync pattern */ | ||
411 | #define XCR 0x44 /* extended control */ | ||
408 | 412 | ||
409 | #define RXIDLE BIT14 | 413 | #define RXIDLE BIT14 |
410 | #define RXBREAK BIT14 | 414 | #define RXBREAK BIT14 |
@@ -517,6 +521,10 @@ static int set_interface(struct slgt_info *info, int if_mode); | |||
517 | static int set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); | 521 | static int set_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); |
518 | static int get_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); | 522 | static int get_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); |
519 | static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); | 523 | static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *gpio); |
524 | static int get_xsync(struct slgt_info *info, int __user *if_mode); | ||
525 | static int set_xsync(struct slgt_info *info, int if_mode); | ||
526 | static int get_xctrl(struct slgt_info *info, int __user *if_mode); | ||
527 | static int set_xctrl(struct slgt_info *info, int if_mode); | ||
520 | 528 | ||
521 | /* | 529 | /* |
522 | * driver functions | 530 | * driver functions |
@@ -1032,9 +1040,6 @@ static int ioctl(struct tty_struct *tty, struct file *file, | |||
1032 | unsigned int cmd, unsigned long arg) | 1040 | unsigned int cmd, unsigned long arg) |
1033 | { | 1041 | { |
1034 | struct slgt_info *info = tty->driver_data; | 1042 | struct slgt_info *info = tty->driver_data; |
1035 | struct mgsl_icount cnow; /* kernel counter temps */ | ||
1036 | struct serial_icounter_struct __user *p_cuser; /* user space */ | ||
1037 | unsigned long flags; | ||
1038 | void __user *argp = (void __user *)arg; | 1043 | void __user *argp = (void __user *)arg; |
1039 | int ret; | 1044 | int ret; |
1040 | 1045 | ||
@@ -1043,7 +1048,7 @@ static int ioctl(struct tty_struct *tty, struct file *file, | |||
1043 | DBGINFO(("%s ioctl() cmd=%08X\n", info->device_name, cmd)); | 1048 | DBGINFO(("%s ioctl() cmd=%08X\n", info->device_name, cmd)); |
1044 | 1049 | ||
1045 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && | 1050 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && |
1046 | (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { | 1051 | (cmd != TIOCMIWAIT)) { |
1047 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1052 | if (tty->flags & (1 << TTY_IO_ERROR)) |
1048 | return -EIO; | 1053 | return -EIO; |
1049 | } | 1054 | } |
@@ -1053,30 +1058,20 @@ static int ioctl(struct tty_struct *tty, struct file *file, | |||
1053 | return wait_mgsl_event(info, argp); | 1058 | return wait_mgsl_event(info, argp); |
1054 | case TIOCMIWAIT: | 1059 | case TIOCMIWAIT: |
1055 | return modem_input_wait(info,(int)arg); | 1060 | return modem_input_wait(info,(int)arg); |
1056 | case TIOCGICOUNT: | ||
1057 | spin_lock_irqsave(&info->lock,flags); | ||
1058 | cnow = info->icount; | ||
1059 | spin_unlock_irqrestore(&info->lock,flags); | ||
1060 | p_cuser = argp; | ||
1061 | if (put_user(cnow.cts, &p_cuser->cts) || | ||
1062 | put_user(cnow.dsr, &p_cuser->dsr) || | ||
1063 | put_user(cnow.rng, &p_cuser->rng) || | ||
1064 | put_user(cnow.dcd, &p_cuser->dcd) || | ||
1065 | put_user(cnow.rx, &p_cuser->rx) || | ||
1066 | put_user(cnow.tx, &p_cuser->tx) || | ||
1067 | put_user(cnow.frame, &p_cuser->frame) || | ||
1068 | put_user(cnow.overrun, &p_cuser->overrun) || | ||
1069 | put_user(cnow.parity, &p_cuser->parity) || | ||
1070 | put_user(cnow.brk, &p_cuser->brk) || | ||
1071 | put_user(cnow.buf_overrun, &p_cuser->buf_overrun)) | ||
1072 | return -EFAULT; | ||
1073 | return 0; | ||
1074 | case MGSL_IOCSGPIO: | 1061 | case MGSL_IOCSGPIO: |
1075 | return set_gpio(info, argp); | 1062 | return set_gpio(info, argp); |
1076 | case MGSL_IOCGGPIO: | 1063 | case MGSL_IOCGGPIO: |
1077 | return get_gpio(info, argp); | 1064 | return get_gpio(info, argp); |
1078 | case MGSL_IOCWAITGPIO: | 1065 | case MGSL_IOCWAITGPIO: |
1079 | return wait_gpio(info, argp); | 1066 | return wait_gpio(info, argp); |
1067 | case MGSL_IOCGXSYNC: | ||
1068 | return get_xsync(info, argp); | ||
1069 | case MGSL_IOCSXSYNC: | ||
1070 | return set_xsync(info, (int)arg); | ||
1071 | case MGSL_IOCGXCTRL: | ||
1072 | return get_xctrl(info, argp); | ||
1073 | case MGSL_IOCSXCTRL: | ||
1074 | return set_xctrl(info, (int)arg); | ||
1080 | } | 1075 | } |
1081 | mutex_lock(&info->port.mutex); | 1076 | mutex_lock(&info->port.mutex); |
1082 | switch (cmd) { | 1077 | switch (cmd) { |
@@ -1117,6 +1112,33 @@ static int ioctl(struct tty_struct *tty, struct file *file, | |||
1117 | return ret; | 1112 | return ret; |
1118 | } | 1113 | } |
1119 | 1114 | ||
1115 | static int get_icount(struct tty_struct *tty, | ||
1116 | struct serial_icounter_struct *icount) | ||
1117 | |||
1118 | { | ||
1119 | struct slgt_info *info = tty->driver_data; | ||
1120 | struct mgsl_icount cnow; /* kernel counter temps */ | ||
1121 | unsigned long flags; | ||
1122 | |||
1123 | spin_lock_irqsave(&info->lock,flags); | ||
1124 | cnow = info->icount; | ||
1125 | spin_unlock_irqrestore(&info->lock,flags); | ||
1126 | |||
1127 | icount->cts = cnow.cts; | ||
1128 | icount->dsr = cnow.dsr; | ||
1129 | icount->rng = cnow.rng; | ||
1130 | icount->dcd = cnow.dcd; | ||
1131 | icount->rx = cnow.rx; | ||
1132 | icount->tx = cnow.tx; | ||
1133 | icount->frame = cnow.frame; | ||
1134 | icount->overrun = cnow.overrun; | ||
1135 | icount->parity = cnow.parity; | ||
1136 | icount->brk = cnow.brk; | ||
1137 | icount->buf_overrun = cnow.buf_overrun; | ||
1138 | |||
1139 | return 0; | ||
1140 | } | ||
1141 | |||
1120 | /* | 1142 | /* |
1121 | * support for 32 bit ioctl calls on 64 bit systems | 1143 | * support for 32 bit ioctl calls on 64 bit systems |
1122 | */ | 1144 | */ |
@@ -1126,6 +1148,7 @@ static long get_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user *us | |||
1126 | struct MGSL_PARAMS32 tmp_params; | 1148 | struct MGSL_PARAMS32 tmp_params; |
1127 | 1149 | ||
1128 | DBGINFO(("%s get_params32\n", info->device_name)); | 1150 | DBGINFO(("%s get_params32\n", info->device_name)); |
1151 | memset(&tmp_params, 0, sizeof(tmp_params)); | ||
1129 | tmp_params.mode = (compat_ulong_t)info->params.mode; | 1152 | tmp_params.mode = (compat_ulong_t)info->params.mode; |
1130 | tmp_params.loopback = info->params.loopback; | 1153 | tmp_params.loopback = info->params.loopback; |
1131 | tmp_params.flags = info->params.flags; | 1154 | tmp_params.flags = info->params.flags; |
@@ -1206,16 +1229,16 @@ static long slgt_compat_ioctl(struct tty_struct *tty, struct file *file, | |||
1206 | case MGSL_IOCSGPIO: | 1229 | case MGSL_IOCSGPIO: |
1207 | case MGSL_IOCGGPIO: | 1230 | case MGSL_IOCGGPIO: |
1208 | case MGSL_IOCWAITGPIO: | 1231 | case MGSL_IOCWAITGPIO: |
1209 | case TIOCGICOUNT: | 1232 | case MGSL_IOCGXSYNC: |
1210 | rc = ioctl(tty, file, cmd, (unsigned long)(compat_ptr(arg))); | 1233 | case MGSL_IOCGXCTRL: |
1211 | break; | ||
1212 | |||
1213 | case MGSL_IOCSTXIDLE: | 1234 | case MGSL_IOCSTXIDLE: |
1214 | case MGSL_IOCTXENABLE: | 1235 | case MGSL_IOCTXENABLE: |
1215 | case MGSL_IOCRXENABLE: | 1236 | case MGSL_IOCRXENABLE: |
1216 | case MGSL_IOCTXABORT: | 1237 | case MGSL_IOCTXABORT: |
1217 | case TIOCMIWAIT: | 1238 | case TIOCMIWAIT: |
1218 | case MGSL_IOCSIF: | 1239 | case MGSL_IOCSIF: |
1240 | case MGSL_IOCSXSYNC: | ||
1241 | case MGSL_IOCSXCTRL: | ||
1219 | rc = ioctl(tty, file, cmd, arg); | 1242 | rc = ioctl(tty, file, cmd, arg); |
1220 | break; | 1243 | break; |
1221 | } | 1244 | } |
@@ -1615,6 +1638,8 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
1615 | if (cmd != SIOCWANDEV) | 1638 | if (cmd != SIOCWANDEV) |
1616 | return hdlc_ioctl(dev, ifr, cmd); | 1639 | return hdlc_ioctl(dev, ifr, cmd); |
1617 | 1640 | ||
1641 | memset(&new_line, 0, sizeof(new_line)); | ||
1642 | |||
1618 | switch(ifr->ifr_settings.type) { | 1643 | switch(ifr->ifr_settings.type) { |
1619 | case IF_GET_IFACE: /* return current sync_serial_settings */ | 1644 | case IF_GET_IFACE: /* return current sync_serial_settings */ |
1620 | 1645 | ||
@@ -1956,6 +1981,7 @@ static void bh_handler(struct work_struct *work) | |||
1956 | case MGSL_MODE_RAW: | 1981 | case MGSL_MODE_RAW: |
1957 | case MGSL_MODE_MONOSYNC: | 1982 | case MGSL_MODE_MONOSYNC: |
1958 | case MGSL_MODE_BISYNC: | 1983 | case MGSL_MODE_BISYNC: |
1984 | case MGSL_MODE_XSYNC: | ||
1959 | while(rx_get_buf(info)); | 1985 | while(rx_get_buf(info)); |
1960 | break; | 1986 | break; |
1961 | } | 1987 | } |
@@ -2355,26 +2381,27 @@ static irqreturn_t slgt_interrupt(int dummy, void *dev_id) | |||
2355 | 2381 | ||
2356 | DBGISR(("slgt_interrupt irq=%d entry\n", info->irq_level)); | 2382 | DBGISR(("slgt_interrupt irq=%d entry\n", info->irq_level)); |
2357 | 2383 | ||
2358 | spin_lock(&info->lock); | ||
2359 | |||
2360 | while((gsr = rd_reg32(info, GSR) & 0xffffff00)) { | 2384 | while((gsr = rd_reg32(info, GSR) & 0xffffff00)) { |
2361 | DBGISR(("%s gsr=%08x\n", info->device_name, gsr)); | 2385 | DBGISR(("%s gsr=%08x\n", info->device_name, gsr)); |
2362 | info->irq_occurred = true; | 2386 | info->irq_occurred = true; |
2363 | for(i=0; i < info->port_count ; i++) { | 2387 | for(i=0; i < info->port_count ; i++) { |
2364 | if (info->port_array[i] == NULL) | 2388 | if (info->port_array[i] == NULL) |
2365 | continue; | 2389 | continue; |
2390 | spin_lock(&info->port_array[i]->lock); | ||
2366 | if (gsr & (BIT8 << i)) | 2391 | if (gsr & (BIT8 << i)) |
2367 | isr_serial(info->port_array[i]); | 2392 | isr_serial(info->port_array[i]); |
2368 | if (gsr & (BIT16 << (i*2))) | 2393 | if (gsr & (BIT16 << (i*2))) |
2369 | isr_rdma(info->port_array[i]); | 2394 | isr_rdma(info->port_array[i]); |
2370 | if (gsr & (BIT17 << (i*2))) | 2395 | if (gsr & (BIT17 << (i*2))) |
2371 | isr_tdma(info->port_array[i]); | 2396 | isr_tdma(info->port_array[i]); |
2397 | spin_unlock(&info->port_array[i]->lock); | ||
2372 | } | 2398 | } |
2373 | } | 2399 | } |
2374 | 2400 | ||
2375 | if (info->gpio_present) { | 2401 | if (info->gpio_present) { |
2376 | unsigned int state; | 2402 | unsigned int state; |
2377 | unsigned int changed; | 2403 | unsigned int changed; |
2404 | spin_lock(&info->lock); | ||
2378 | while ((changed = rd_reg32(info, IOSR)) != 0) { | 2405 | while ((changed = rd_reg32(info, IOSR)) != 0) { |
2379 | DBGISR(("%s iosr=%08x\n", info->device_name, changed)); | 2406 | DBGISR(("%s iosr=%08x\n", info->device_name, changed)); |
2380 | /* read latched state of GPIO signals */ | 2407 | /* read latched state of GPIO signals */ |
@@ -2386,22 +2413,24 @@ static irqreturn_t slgt_interrupt(int dummy, void *dev_id) | |||
2386 | isr_gpio(info->port_array[i], changed, state); | 2413 | isr_gpio(info->port_array[i], changed, state); |
2387 | } | 2414 | } |
2388 | } | 2415 | } |
2416 | spin_unlock(&info->lock); | ||
2389 | } | 2417 | } |
2390 | 2418 | ||
2391 | for(i=0; i < info->port_count ; i++) { | 2419 | for(i=0; i < info->port_count ; i++) { |
2392 | struct slgt_info *port = info->port_array[i]; | 2420 | struct slgt_info *port = info->port_array[i]; |
2393 | 2421 | if (port == NULL) | |
2394 | if (port && (port->port.count || port->netcount) && | 2422 | continue; |
2423 | spin_lock(&port->lock); | ||
2424 | if ((port->port.count || port->netcount) && | ||
2395 | port->pending_bh && !port->bh_running && | 2425 | port->pending_bh && !port->bh_running && |
2396 | !port->bh_requested) { | 2426 | !port->bh_requested) { |
2397 | DBGISR(("%s bh queued\n", port->device_name)); | 2427 | DBGISR(("%s bh queued\n", port->device_name)); |
2398 | schedule_work(&port->task); | 2428 | schedule_work(&port->task); |
2399 | port->bh_requested = true; | 2429 | port->bh_requested = true; |
2400 | } | 2430 | } |
2431 | spin_unlock(&port->lock); | ||
2401 | } | 2432 | } |
2402 | 2433 | ||
2403 | spin_unlock(&info->lock); | ||
2404 | |||
2405 | DBGISR(("slgt_interrupt irq=%d exit\n", info->irq_level)); | 2434 | DBGISR(("slgt_interrupt irq=%d exit\n", info->irq_level)); |
2406 | return IRQ_HANDLED; | 2435 | return IRQ_HANDLED; |
2407 | } | 2436 | } |
@@ -2881,6 +2910,69 @@ static int set_interface(struct slgt_info *info, int if_mode) | |||
2881 | return 0; | 2910 | return 0; |
2882 | } | 2911 | } |
2883 | 2912 | ||
2913 | static int get_xsync(struct slgt_info *info, int __user *xsync) | ||
2914 | { | ||
2915 | DBGINFO(("%s get_xsync=%x\n", info->device_name, info->xsync)); | ||
2916 | if (put_user(info->xsync, xsync)) | ||
2917 | return -EFAULT; | ||
2918 | return 0; | ||
2919 | } | ||
2920 | |||
2921 | /* | ||
2922 | * set extended sync pattern (1 to 4 bytes) for extended sync mode | ||
2923 | * | ||
2924 | * sync pattern is contained in least significant bytes of value | ||
2925 | * most significant byte of sync pattern is oldest (1st sent/detected) | ||
2926 | */ | ||
2927 | static int set_xsync(struct slgt_info *info, int xsync) | ||
2928 | { | ||
2929 | unsigned long flags; | ||
2930 | |||
2931 | DBGINFO(("%s set_xsync=%x)\n", info->device_name, xsync)); | ||
2932 | spin_lock_irqsave(&info->lock, flags); | ||
2933 | info->xsync = xsync; | ||
2934 | wr_reg32(info, XSR, xsync); | ||
2935 | spin_unlock_irqrestore(&info->lock, flags); | ||
2936 | return 0; | ||
2937 | } | ||
2938 | |||
2939 | static int get_xctrl(struct slgt_info *info, int __user *xctrl) | ||
2940 | { | ||
2941 | DBGINFO(("%s get_xctrl=%x\n", info->device_name, info->xctrl)); | ||
2942 | if (put_user(info->xctrl, xctrl)) | ||
2943 | return -EFAULT; | ||
2944 | return 0; | ||
2945 | } | ||
2946 | |||
2947 | /* | ||
2948 | * set extended control options | ||
2949 | * | ||
2950 | * xctrl[31:19] reserved, must be zero | ||
2951 | * xctrl[18:17] extended sync pattern length in bytes | ||
2952 | * 00 = 1 byte in xsr[7:0] | ||
2953 | * 01 = 2 bytes in xsr[15:0] | ||
2954 | * 10 = 3 bytes in xsr[23:0] | ||
2955 | * 11 = 4 bytes in xsr[31:0] | ||
2956 | * xctrl[16] 1 = enable terminal count, 0=disabled | ||
2957 | * xctrl[15:0] receive terminal count for fixed length packets | ||
2958 | * value is count minus one (0 = 1 byte packet) | ||
2959 | * when terminal count is reached, receiver | ||
2960 | * automatically returns to hunt mode and receive | ||
2961 | * FIFO contents are flushed to DMA buffers with | ||
2962 | * end of frame (EOF) status | ||
2963 | */ | ||
2964 | static int set_xctrl(struct slgt_info *info, int xctrl) | ||
2965 | { | ||
2966 | unsigned long flags; | ||
2967 | |||
2968 | DBGINFO(("%s set_xctrl=%x)\n", info->device_name, xctrl)); | ||
2969 | spin_lock_irqsave(&info->lock, flags); | ||
2970 | info->xctrl = xctrl; | ||
2971 | wr_reg32(info, XCR, xctrl); | ||
2972 | spin_unlock_irqrestore(&info->lock, flags); | ||
2973 | return 0; | ||
2974 | } | ||
2975 | |||
2884 | /* | 2976 | /* |
2885 | * set general purpose IO pin state and direction | 2977 | * set general purpose IO pin state and direction |
2886 | * | 2978 | * |
@@ -2904,7 +2996,7 @@ static int set_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio) | |||
2904 | info->device_name, gpio.state, gpio.smask, | 2996 | info->device_name, gpio.state, gpio.smask, |
2905 | gpio.dir, gpio.dmask)); | 2997 | gpio.dir, gpio.dmask)); |
2906 | 2998 | ||
2907 | spin_lock_irqsave(&info->lock,flags); | 2999 | spin_lock_irqsave(&info->port_array[0]->lock, flags); |
2908 | if (gpio.dmask) { | 3000 | if (gpio.dmask) { |
2909 | data = rd_reg32(info, IODR); | 3001 | data = rd_reg32(info, IODR); |
2910 | data |= gpio.dmask & gpio.dir; | 3002 | data |= gpio.dmask & gpio.dir; |
@@ -2917,7 +3009,7 @@ static int set_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio) | |||
2917 | data &= ~(gpio.smask & ~gpio.state); | 3009 | data &= ~(gpio.smask & ~gpio.state); |
2918 | wr_reg32(info, IOVR, data); | 3010 | wr_reg32(info, IOVR, data); |
2919 | } | 3011 | } |
2920 | spin_unlock_irqrestore(&info->lock,flags); | 3012 | spin_unlock_irqrestore(&info->port_array[0]->lock, flags); |
2921 | 3013 | ||
2922 | return 0; | 3014 | return 0; |
2923 | } | 3015 | } |
@@ -3018,7 +3110,7 @@ static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio) | |||
3018 | return -EINVAL; | 3110 | return -EINVAL; |
3019 | init_cond_wait(&wait, gpio.smask); | 3111 | init_cond_wait(&wait, gpio.smask); |
3020 | 3112 | ||
3021 | spin_lock_irqsave(&info->lock, flags); | 3113 | spin_lock_irqsave(&info->port_array[0]->lock, flags); |
3022 | /* enable interrupts for watched pins */ | 3114 | /* enable interrupts for watched pins */ |
3023 | wr_reg32(info, IOER, rd_reg32(info, IOER) | gpio.smask); | 3115 | wr_reg32(info, IOER, rd_reg32(info, IOER) | gpio.smask); |
3024 | /* get current pin states */ | 3116 | /* get current pin states */ |
@@ -3030,20 +3122,20 @@ static int wait_gpio(struct slgt_info *info, struct gpio_desc __user *user_gpio) | |||
3030 | } else { | 3122 | } else { |
3031 | /* wait for target state */ | 3123 | /* wait for target state */ |
3032 | add_cond_wait(&info->gpio_wait_q, &wait); | 3124 | add_cond_wait(&info->gpio_wait_q, &wait); |
3033 | spin_unlock_irqrestore(&info->lock, flags); | 3125 | spin_unlock_irqrestore(&info->port_array[0]->lock, flags); |
3034 | schedule(); | 3126 | schedule(); |
3035 | if (signal_pending(current)) | 3127 | if (signal_pending(current)) |
3036 | rc = -ERESTARTSYS; | 3128 | rc = -ERESTARTSYS; |
3037 | else | 3129 | else |
3038 | gpio.state = wait.data; | 3130 | gpio.state = wait.data; |
3039 | spin_lock_irqsave(&info->lock, flags); | 3131 | spin_lock_irqsave(&info->port_array[0]->lock, flags); |
3040 | remove_cond_wait(&info->gpio_wait_q, &wait); | 3132 | remove_cond_wait(&info->gpio_wait_q, &wait); |
3041 | } | 3133 | } |
3042 | 3134 | ||
3043 | /* disable all GPIO interrupts if no waiting processes */ | 3135 | /* disable all GPIO interrupts if no waiting processes */ |
3044 | if (info->gpio_wait_q == NULL) | 3136 | if (info->gpio_wait_q == NULL) |
3045 | wr_reg32(info, IOER, 0); | 3137 | wr_reg32(info, IOER, 0); |
3046 | spin_unlock_irqrestore(&info->lock,flags); | 3138 | spin_unlock_irqrestore(&info->port_array[0]->lock, flags); |
3047 | 3139 | ||
3048 | if ((rc == 0) && copy_to_user(user_gpio, &gpio, sizeof(gpio))) | 3140 | if ((rc == 0) && copy_to_user(user_gpio, &gpio, sizeof(gpio))) |
3049 | rc = -EFAULT; | 3141 | rc = -EFAULT; |
@@ -3576,7 +3668,6 @@ static void device_init(int adapter_num, struct pci_dev *pdev) | |||
3576 | 3668 | ||
3577 | /* copy resource information from first port to others */ | 3669 | /* copy resource information from first port to others */ |
3578 | for (i = 1; i < port_count; ++i) { | 3670 | for (i = 1; i < port_count; ++i) { |
3579 | port_array[i]->lock = port_array[0]->lock; | ||
3580 | port_array[i]->irq_level = port_array[0]->irq_level; | 3671 | port_array[i]->irq_level = port_array[0]->irq_level; |
3581 | port_array[i]->reg_addr = port_array[0]->reg_addr; | 3672 | port_array[i]->reg_addr = port_array[0]->reg_addr; |
3582 | alloc_dma_bufs(port_array[i]); | 3673 | alloc_dma_bufs(port_array[i]); |
@@ -3642,6 +3733,7 @@ static const struct tty_operations ops = { | |||
3642 | .hangup = hangup, | 3733 | .hangup = hangup, |
3643 | .tiocmget = tiocmget, | 3734 | .tiocmget = tiocmget, |
3644 | .tiocmset = tiocmset, | 3735 | .tiocmset = tiocmset, |
3736 | .get_icount = get_icount, | ||
3645 | .proc_fops = &synclink_gt_proc_fops, | 3737 | .proc_fops = &synclink_gt_proc_fops, |
3646 | }; | 3738 | }; |
3647 | 3739 | ||
@@ -3760,7 +3852,9 @@ module_exit(slgt_exit); | |||
3760 | #define CALC_REGADDR() \ | 3852 | #define CALC_REGADDR() \ |
3761 | unsigned long reg_addr = ((unsigned long)info->reg_addr) + addr; \ | 3853 | unsigned long reg_addr = ((unsigned long)info->reg_addr) + addr; \ |
3762 | if (addr >= 0x80) \ | 3854 | if (addr >= 0x80) \ |
3763 | reg_addr += (info->port_num) * 32; | 3855 | reg_addr += (info->port_num) * 32; \ |
3856 | else if (addr >= 0x40) \ | ||
3857 | reg_addr += (info->port_num) * 16; | ||
3764 | 3858 | ||
3765 | static __u8 rd_reg8(struct slgt_info *info, unsigned int addr) | 3859 | static __u8 rd_reg8(struct slgt_info *info, unsigned int addr) |
3766 | { | 3860 | { |
@@ -4179,7 +4273,13 @@ static void sync_mode(struct slgt_info *info) | |||
4179 | 4273 | ||
4180 | /* TCR (tx control) | 4274 | /* TCR (tx control) |
4181 | * | 4275 | * |
4182 | * 15..13 mode, 000=HDLC 001=raw 010=async 011=monosync 100=bisync | 4276 | * 15..13 mode |
4277 | * 000=HDLC/SDLC | ||
4278 | * 001=raw bit synchronous | ||
4279 | * 010=asynchronous/isochronous | ||
4280 | * 011=monosync byte synchronous | ||
4281 | * 100=bisync byte synchronous | ||
4282 | * 101=xsync byte synchronous | ||
4183 | * 12..10 encoding | 4283 | * 12..10 encoding |
4184 | * 09 CRC enable | 4284 | * 09 CRC enable |
4185 | * 08 CRC32 | 4285 | * 08 CRC32 |
@@ -4194,6 +4294,9 @@ static void sync_mode(struct slgt_info *info) | |||
4194 | val = BIT2; | 4294 | val = BIT2; |
4195 | 4295 | ||
4196 | switch(info->params.mode) { | 4296 | switch(info->params.mode) { |
4297 | case MGSL_MODE_XSYNC: | ||
4298 | val |= BIT15 + BIT13; | ||
4299 | break; | ||
4197 | case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; | 4300 | case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; |
4198 | case MGSL_MODE_BISYNC: val |= BIT15; break; | 4301 | case MGSL_MODE_BISYNC: val |= BIT15; break; |
4199 | case MGSL_MODE_RAW: val |= BIT13; break; | 4302 | case MGSL_MODE_RAW: val |= BIT13; break; |
@@ -4248,7 +4351,13 @@ static void sync_mode(struct slgt_info *info) | |||
4248 | 4351 | ||
4249 | /* RCR (rx control) | 4352 | /* RCR (rx control) |
4250 | * | 4353 | * |
4251 | * 15..13 mode, 000=HDLC 001=raw 010=async 011=monosync 100=bisync | 4354 | * 15..13 mode |
4355 | * 000=HDLC/SDLC | ||
4356 | * 001=raw bit synchronous | ||
4357 | * 010=asynchronous/isochronous | ||
4358 | * 011=monosync byte synchronous | ||
4359 | * 100=bisync byte synchronous | ||
4360 | * 101=xsync byte synchronous | ||
4252 | * 12..10 encoding | 4361 | * 12..10 encoding |
4253 | * 09 CRC enable | 4362 | * 09 CRC enable |
4254 | * 08 CRC32 | 4363 | * 08 CRC32 |
@@ -4260,6 +4369,9 @@ static void sync_mode(struct slgt_info *info) | |||
4260 | val = 0; | 4369 | val = 0; |
4261 | 4370 | ||
4262 | switch(info->params.mode) { | 4371 | switch(info->params.mode) { |
4372 | case MGSL_MODE_XSYNC: | ||
4373 | val |= BIT15 + BIT13; | ||
4374 | break; | ||
4263 | case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; | 4375 | case MGSL_MODE_MONOSYNC: val |= BIT14 + BIT13; break; |
4264 | case MGSL_MODE_BISYNC: val |= BIT15; break; | 4376 | case MGSL_MODE_BISYNC: val |= BIT15; break; |
4265 | case MGSL_MODE_RAW: val |= BIT13; break; | 4377 | case MGSL_MODE_RAW: val |= BIT13; break; |
@@ -4676,6 +4788,7 @@ static bool rx_get_buf(struct slgt_info *info) | |||
4676 | switch(info->params.mode) { | 4788 | switch(info->params.mode) { |
4677 | case MGSL_MODE_MONOSYNC: | 4789 | case MGSL_MODE_MONOSYNC: |
4678 | case MGSL_MODE_BISYNC: | 4790 | case MGSL_MODE_BISYNC: |
4791 | case MGSL_MODE_XSYNC: | ||
4679 | /* ignore residue in byte synchronous modes */ | 4792 | /* ignore residue in byte synchronous modes */ |
4680 | if (desc_residue(info->rbufs[i])) | 4793 | if (desc_residue(info->rbufs[i])) |
4681 | count--; | 4794 | count--; |
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index e56caf7d82aa..2f9eb4b0dec1 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c | |||
@@ -1258,10 +1258,6 @@ static int ioctl(struct tty_struct *tty, struct file *file, | |||
1258 | unsigned int cmd, unsigned long arg) | 1258 | unsigned int cmd, unsigned long arg) |
1259 | { | 1259 | { |
1260 | SLMP_INFO *info = tty->driver_data; | 1260 | SLMP_INFO *info = tty->driver_data; |
1261 | int error; | ||
1262 | struct mgsl_icount cnow; /* kernel counter temps */ | ||
1263 | struct serial_icounter_struct __user *p_cuser; /* user space */ | ||
1264 | unsigned long flags; | ||
1265 | void __user *argp = (void __user *)arg; | 1261 | void __user *argp = (void __user *)arg; |
1266 | 1262 | ||
1267 | if (debug_level >= DEBUG_LEVEL_INFO) | 1263 | if (debug_level >= DEBUG_LEVEL_INFO) |
@@ -1272,7 +1268,7 @@ static int ioctl(struct tty_struct *tty, struct file *file, | |||
1272 | return -ENODEV; | 1268 | return -ENODEV; |
1273 | 1269 | ||
1274 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && | 1270 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && |
1275 | (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { | 1271 | (cmd != TIOCMIWAIT)) { |
1276 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1272 | if (tty->flags & (1 << TTY_IO_ERROR)) |
1277 | return -EIO; | 1273 | return -EIO; |
1278 | } | 1274 | } |
@@ -1310,40 +1306,38 @@ static int ioctl(struct tty_struct *tty, struct file *file, | |||
1310 | * NB: both 1->0 and 0->1 transitions are counted except for | 1306 | * NB: both 1->0 and 0->1 transitions are counted except for |
1311 | * RI where only 0->1 is counted. | 1307 | * RI where only 0->1 is counted. |
1312 | */ | 1308 | */ |
1313 | case TIOCGICOUNT: | ||
1314 | spin_lock_irqsave(&info->lock,flags); | ||
1315 | cnow = info->icount; | ||
1316 | spin_unlock_irqrestore(&info->lock,flags); | ||
1317 | p_cuser = argp; | ||
1318 | PUT_USER(error,cnow.cts, &p_cuser->cts); | ||
1319 | if (error) return error; | ||
1320 | PUT_USER(error,cnow.dsr, &p_cuser->dsr); | ||
1321 | if (error) return error; | ||
1322 | PUT_USER(error,cnow.rng, &p_cuser->rng); | ||
1323 | if (error) return error; | ||
1324 | PUT_USER(error,cnow.dcd, &p_cuser->dcd); | ||
1325 | if (error) return error; | ||
1326 | PUT_USER(error,cnow.rx, &p_cuser->rx); | ||
1327 | if (error) return error; | ||
1328 | PUT_USER(error,cnow.tx, &p_cuser->tx); | ||
1329 | if (error) return error; | ||
1330 | PUT_USER(error,cnow.frame, &p_cuser->frame); | ||
1331 | if (error) return error; | ||
1332 | PUT_USER(error,cnow.overrun, &p_cuser->overrun); | ||
1333 | if (error) return error; | ||
1334 | PUT_USER(error,cnow.parity, &p_cuser->parity); | ||
1335 | if (error) return error; | ||
1336 | PUT_USER(error,cnow.brk, &p_cuser->brk); | ||
1337 | if (error) return error; | ||
1338 | PUT_USER(error,cnow.buf_overrun, &p_cuser->buf_overrun); | ||
1339 | if (error) return error; | ||
1340 | return 0; | ||
1341 | default: | 1309 | default: |
1342 | return -ENOIOCTLCMD; | 1310 | return -ENOIOCTLCMD; |
1343 | } | 1311 | } |
1344 | return 0; | 1312 | return 0; |
1345 | } | 1313 | } |
1346 | 1314 | ||
1315 | static int get_icount(struct tty_struct *tty, | ||
1316 | struct serial_icounter_struct *icount) | ||
1317 | { | ||
1318 | SLMP_INFO *info = tty->driver_data; | ||
1319 | struct mgsl_icount cnow; /* kernel counter temps */ | ||
1320 | unsigned long flags; | ||
1321 | |||
1322 | spin_lock_irqsave(&info->lock,flags); | ||
1323 | cnow = info->icount; | ||
1324 | spin_unlock_irqrestore(&info->lock,flags); | ||
1325 | |||
1326 | icount->cts = cnow.cts; | ||
1327 | icount->dsr = cnow.dsr; | ||
1328 | icount->rng = cnow.rng; | ||
1329 | icount->dcd = cnow.dcd; | ||
1330 | icount->rx = cnow.rx; | ||
1331 | icount->tx = cnow.tx; | ||
1332 | icount->frame = cnow.frame; | ||
1333 | icount->overrun = cnow.overrun; | ||
1334 | icount->parity = cnow.parity; | ||
1335 | icount->brk = cnow.brk; | ||
1336 | icount->buf_overrun = cnow.buf_overrun; | ||
1337 | |||
1338 | return 0; | ||
1339 | } | ||
1340 | |||
1347 | /* | 1341 | /* |
1348 | * /proc fs routines.... | 1342 | * /proc fs routines.... |
1349 | */ | 1343 | */ |
@@ -3909,6 +3903,7 @@ static const struct tty_operations ops = { | |||
3909 | .hangup = hangup, | 3903 | .hangup = hangup, |
3910 | .tiocmget = tiocmget, | 3904 | .tiocmget = tiocmget, |
3911 | .tiocmset = tiocmset, | 3905 | .tiocmset = tiocmset, |
3906 | .get_icount = get_icount, | ||
3912 | .proc_fops = &synclinkmp_proc_fops, | 3907 | .proc_fops = &synclinkmp_proc_fops, |
3913 | }; | 3908 | }; |
3914 | 3909 | ||
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index ef31bb81e843..eaa5d3efa79d 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -566,10 +566,16 @@ static const unsigned char sysrq_xlate[KEY_MAX + 1] = | |||
566 | static bool sysrq_down; | 566 | static bool sysrq_down; |
567 | static int sysrq_alt_use; | 567 | static int sysrq_alt_use; |
568 | static int sysrq_alt; | 568 | static int sysrq_alt; |
569 | static DEFINE_SPINLOCK(sysrq_event_lock); | ||
569 | 570 | ||
570 | static bool sysrq_filter(struct input_handle *handle, unsigned int type, | 571 | static bool sysrq_filter(struct input_handle *handle, unsigned int type, |
571 | unsigned int code, int value) | 572 | unsigned int code, int value) |
572 | { | 573 | { |
574 | bool suppress; | ||
575 | |||
576 | /* We are called with interrupts disabled, just take the lock */ | ||
577 | spin_lock(&sysrq_event_lock); | ||
578 | |||
573 | if (type != EV_KEY) | 579 | if (type != EV_KEY) |
574 | goto out; | 580 | goto out; |
575 | 581 | ||
@@ -601,7 +607,10 @@ static bool sysrq_filter(struct input_handle *handle, unsigned int type, | |||
601 | } | 607 | } |
602 | 608 | ||
603 | out: | 609 | out: |
604 | return sysrq_down; | 610 | suppress = sysrq_down; |
611 | spin_unlock(&sysrq_event_lock); | ||
612 | |||
613 | return suppress; | ||
605 | } | 614 | } |
606 | 615 | ||
607 | static int sysrq_connect(struct input_handler *handler, | 616 | static int sysrq_connect(struct input_handler *handler, |
@@ -652,8 +661,8 @@ static void sysrq_disconnect(struct input_handle *handle) | |||
652 | } | 661 | } |
653 | 662 | ||
654 | /* | 663 | /* |
655 | * We are matching on KEY_LEFTALT insteard of KEY_SYSRQ because not all | 664 | * We are matching on KEY_LEFTALT instead of KEY_SYSRQ because not all |
656 | * keyboards have SysRq ikey predefined and so user may add it to keymap | 665 | * keyboards have SysRq key predefined and so user may add it to keymap |
657 | * later, but we expect all such keyboards to have left alt. | 666 | * later, but we expect all such keyboards to have left alt. |
658 | */ | 667 | */ |
659 | static const struct input_device_id sysrq_ids[] = { | 668 | static const struct input_device_id sysrq_ids[] = { |
@@ -772,6 +781,7 @@ static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf, | |||
772 | 781 | ||
773 | static const struct file_operations proc_sysrq_trigger_operations = { | 782 | static const struct file_operations proc_sysrq_trigger_operations = { |
774 | .write = write_sysrq_trigger, | 783 | .write = write_sysrq_trigger, |
784 | .llseek = noop_llseek, | ||
775 | }; | 785 | }; |
776 | 786 | ||
777 | static void sysrq_init_procfs(void) | 787 | static void sysrq_init_procfs(void) |
diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c index cad4eb65f13d..ad264185eb10 100644 --- a/drivers/char/tb0219.c +++ b/drivers/char/tb0219.c | |||
@@ -261,6 +261,7 @@ static const struct file_operations tb0219_fops = { | |||
261 | .write = tanbac_tb0219_write, | 261 | .write = tanbac_tb0219_write, |
262 | .open = tanbac_tb0219_open, | 262 | .open = tanbac_tb0219_open, |
263 | .release = tanbac_tb0219_release, | 263 | .release = tanbac_tb0219_release, |
264 | .llseek = no_llseek, | ||
264 | }; | 265 | }; |
265 | 266 | ||
266 | static void tb0219_restart(char *command) | 267 | static void tb0219_restart(char *command) |
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c index 80ea6bcfffdc..0c964cdcc223 100644 --- a/drivers/char/tlclk.c +++ b/drivers/char/tlclk.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <linux/ioport.h> | 37 | #include <linux/ioport.h> |
38 | #include <linux/interrupt.h> | 38 | #include <linux/interrupt.h> |
39 | #include <linux/spinlock.h> | 39 | #include <linux/spinlock.h> |
40 | #include <linux/smp_lock.h> | 40 | #include <linux/mutex.h> |
41 | #include <linux/timer.h> | 41 | #include <linux/timer.h> |
42 | #include <linux/sysfs.h> | 42 | #include <linux/sysfs.h> |
43 | #include <linux/device.h> | 43 | #include <linux/device.h> |
@@ -206,7 +206,7 @@ static int tlclk_open(struct inode *inode, struct file *filp) | |||
206 | { | 206 | { |
207 | int result; | 207 | int result; |
208 | 208 | ||
209 | lock_kernel(); | 209 | mutex_lock(&tlclk_mutex); |
210 | if (test_and_set_bit(0, &useflags)) { | 210 | if (test_and_set_bit(0, &useflags)) { |
211 | result = -EBUSY; | 211 | result = -EBUSY; |
212 | /* this legacy device is always one per system and it doesn't | 212 | /* this legacy device is always one per system and it doesn't |
@@ -229,7 +229,7 @@ static int tlclk_open(struct inode *inode, struct file *filp) | |||
229 | inb(TLCLK_REG6); /* Clear interrupt events */ | 229 | inb(TLCLK_REG6); /* Clear interrupt events */ |
230 | 230 | ||
231 | out: | 231 | out: |
232 | unlock_kernel(); | 232 | mutex_unlock(&tlclk_mutex); |
233 | return result; | 233 | return result; |
234 | } | 234 | } |
235 | 235 | ||
@@ -267,6 +267,7 @@ static const struct file_operations tlclk_fops = { | |||
267 | .read = tlclk_read, | 267 | .read = tlclk_read, |
268 | .open = tlclk_open, | 268 | .open = tlclk_open, |
269 | .release = tlclk_release, | 269 | .release = tlclk_release, |
270 | .llseek = noop_llseek, | ||
270 | 271 | ||
271 | }; | 272 | }; |
272 | 273 | ||
diff --git a/drivers/char/toshiba.c b/drivers/char/toshiba.c index f8bc79f6de34..014c9d90d297 100644 --- a/drivers/char/toshiba.c +++ b/drivers/char/toshiba.c | |||
@@ -68,7 +68,7 @@ | |||
68 | #include <linux/stat.h> | 68 | #include <linux/stat.h> |
69 | #include <linux/proc_fs.h> | 69 | #include <linux/proc_fs.h> |
70 | #include <linux/seq_file.h> | 70 | #include <linux/seq_file.h> |
71 | #include <linux/smp_lock.h> | 71 | #include <linux/mutex.h> |
72 | #include <linux/toshiba.h> | 72 | #include <linux/toshiba.h> |
73 | 73 | ||
74 | #define TOSH_MINOR_DEV 181 | 74 | #define TOSH_MINOR_DEV 181 |
@@ -78,6 +78,7 @@ MODULE_AUTHOR("Jonathan Buzzard <jonathan@buzzard.org.uk>"); | |||
78 | MODULE_DESCRIPTION("Toshiba laptop SMM driver"); | 78 | MODULE_DESCRIPTION("Toshiba laptop SMM driver"); |
79 | MODULE_SUPPORTED_DEVICE("toshiba"); | 79 | MODULE_SUPPORTED_DEVICE("toshiba"); |
80 | 80 | ||
81 | static DEFINE_MUTEX(tosh_mutex); | ||
81 | static int tosh_fn; | 82 | static int tosh_fn; |
82 | module_param_named(fn, tosh_fn, int, 0); | 83 | module_param_named(fn, tosh_fn, int, 0); |
83 | MODULE_PARM_DESC(fn, "User specified Fn key detection port"); | 84 | MODULE_PARM_DESC(fn, "User specified Fn key detection port"); |
@@ -95,6 +96,7 @@ static long tosh_ioctl(struct file *, unsigned int, | |||
95 | static const struct file_operations tosh_fops = { | 96 | static const struct file_operations tosh_fops = { |
96 | .owner = THIS_MODULE, | 97 | .owner = THIS_MODULE, |
97 | .unlocked_ioctl = tosh_ioctl, | 98 | .unlocked_ioctl = tosh_ioctl, |
99 | .llseek = noop_llseek, | ||
98 | }; | 100 | }; |
99 | 101 | ||
100 | static struct miscdevice tosh_device = { | 102 | static struct miscdevice tosh_device = { |
@@ -274,16 +276,16 @@ static long tosh_ioctl(struct file *fp, unsigned int cmd, unsigned long arg) | |||
274 | return -EINVAL; | 276 | return -EINVAL; |
275 | 277 | ||
276 | /* do we need to emulate the fan ? */ | 278 | /* do we need to emulate the fan ? */ |
277 | lock_kernel(); | 279 | mutex_lock(&tosh_mutex); |
278 | if (tosh_fan==1) { | 280 | if (tosh_fan==1) { |
279 | if (((ax==0xf300) || (ax==0xf400)) && (bx==0x0004)) { | 281 | if (((ax==0xf300) || (ax==0xf400)) && (bx==0x0004)) { |
280 | err = tosh_emulate_fan(®s); | 282 | err = tosh_emulate_fan(®s); |
281 | unlock_kernel(); | 283 | mutex_unlock(&tosh_mutex); |
282 | break; | 284 | break; |
283 | } | 285 | } |
284 | } | 286 | } |
285 | err = tosh_smm(®s); | 287 | err = tosh_smm(®s); |
286 | unlock_kernel(); | 288 | mutex_unlock(&tosh_mutex); |
287 | break; | 289 | break; |
288 | default: | 290 | default: |
289 | return -EINVAL; | 291 | return -EINVAL; |
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig index 4dc338f3d1aa..f6595aba4f0f 100644 --- a/drivers/char/tpm/Kconfig +++ b/drivers/char/tpm/Kconfig | |||
@@ -58,6 +58,6 @@ config TCG_INFINEON | |||
58 | To compile this driver as a module, choose M here; the module | 58 | To compile this driver as a module, choose M here; the module |
59 | will be called tpm_infineon. | 59 | will be called tpm_infineon. |
60 | Further information on this driver and the supported hardware | 60 | Further information on this driver and the supported hardware |
61 | can be found at http://www.prosec.rub.de/tpm | 61 | can be found at http://www.trust.rub.de/projects/linux-device-driver-infineon-tpm/ |
62 | 62 | ||
63 | endif # TCG_TPM | 63 | endif # TCG_TPM |
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index f58440791e65..76da32e11f18 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * Copyright (C) 2005, Marcel Selhorst <m.selhorst@sirrix.com> | 7 | * Copyright (C) 2005, Marcel Selhorst <m.selhorst@sirrix.com> |
8 | * Sirrix AG - security technologies, http://www.sirrix.com and | 8 | * Sirrix AG - security technologies, http://www.sirrix.com and |
9 | * Applied Data Security Group, Ruhr-University Bochum, Germany | 9 | * Applied Data Security Group, Ruhr-University Bochum, Germany |
10 | * Project-Homepage: http://www.prosec.rub.de/tpm | 10 | * Project-Homepage: http://www.trust.rub.de/projects/linux-device-driver-infineon-tpm/ |
11 | * | 11 | * |
12 | * This program is free software; you can redistribute it and/or | 12 | * This program is free software; you can redistribute it and/or |
13 | * modify it under the terms of the GNU General Public License as | 13 | * modify it under the terms of the GNU General Public License as |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 613c852ee0fe..c05c5af5aa04 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -96,6 +96,7 @@ | |||
96 | #include <linux/bitops.h> | 96 | #include <linux/bitops.h> |
97 | #include <linux/delay.h> | 97 | #include <linux/delay.h> |
98 | #include <linux/seq_file.h> | 98 | #include <linux/seq_file.h> |
99 | #include <linux/serial.h> | ||
99 | 100 | ||
100 | #include <linux/uaccess.h> | 101 | #include <linux/uaccess.h> |
101 | #include <asm/system.h> | 102 | #include <asm/system.h> |
@@ -183,6 +184,8 @@ struct tty_struct *alloc_tty_struct(void) | |||
183 | 184 | ||
184 | void free_tty_struct(struct tty_struct *tty) | 185 | void free_tty_struct(struct tty_struct *tty) |
185 | { | 186 | { |
187 | if (tty->dev) | ||
188 | put_device(tty->dev); | ||
186 | kfree(tty->write_buf); | 189 | kfree(tty->write_buf); |
187 | tty_buffer_free_all(tty); | 190 | tty_buffer_free_all(tty); |
188 | kfree(tty); | 191 | kfree(tty); |
@@ -194,12 +197,13 @@ static inline struct tty_struct *file_tty(struct file *file) | |||
194 | } | 197 | } |
195 | 198 | ||
196 | /* Associate a new file with the tty structure */ | 199 | /* Associate a new file with the tty structure */ |
197 | void tty_add_file(struct tty_struct *tty, struct file *file) | 200 | int tty_add_file(struct tty_struct *tty, struct file *file) |
198 | { | 201 | { |
199 | struct tty_file_private *priv; | 202 | struct tty_file_private *priv; |
200 | 203 | ||
201 | /* XXX: must implement proper error handling in callers */ | 204 | priv = kmalloc(sizeof(*priv), GFP_KERNEL); |
202 | priv = kmalloc(sizeof(*priv), GFP_KERNEL|__GFP_NOFAIL); | 205 | if (!priv) |
206 | return -ENOMEM; | ||
203 | 207 | ||
204 | priv->tty = tty; | 208 | priv->tty = tty; |
205 | priv->file = file; | 209 | priv->file = file; |
@@ -208,6 +212,8 @@ void tty_add_file(struct tty_struct *tty, struct file *file) | |||
208 | spin_lock(&tty_files_lock); | 212 | spin_lock(&tty_files_lock); |
209 | list_add(&priv->list, &tty->tty_files); | 213 | list_add(&priv->list, &tty->tty_files); |
210 | spin_unlock(&tty_files_lock); | 214 | spin_unlock(&tty_files_lock); |
215 | |||
216 | return 0; | ||
211 | } | 217 | } |
212 | 218 | ||
213 | /* Delete file from its tty */ | 219 | /* Delete file from its tty */ |
@@ -1875,7 +1881,11 @@ got_driver: | |||
1875 | return PTR_ERR(tty); | 1881 | return PTR_ERR(tty); |
1876 | } | 1882 | } |
1877 | 1883 | ||
1878 | tty_add_file(tty, filp); | 1884 | retval = tty_add_file(tty, filp); |
1885 | if (retval) { | ||
1886 | tty_unlock(); | ||
1887 | return retval; | ||
1888 | } | ||
1879 | 1889 | ||
1880 | check_tty_count(tty, "tty_open"); | 1890 | check_tty_count(tty, "tty_open"); |
1881 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 1891 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
@@ -2502,6 +2512,20 @@ static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int | |||
2502 | return tty->ops->tiocmset(tty, file, set, clear); | 2512 | return tty->ops->tiocmset(tty, file, set, clear); |
2503 | } | 2513 | } |
2504 | 2514 | ||
2515 | static int tty_tiocgicount(struct tty_struct *tty, void __user *arg) | ||
2516 | { | ||
2517 | int retval = -EINVAL; | ||
2518 | struct serial_icounter_struct icount; | ||
2519 | memset(&icount, 0, sizeof(icount)); | ||
2520 | if (tty->ops->get_icount) | ||
2521 | retval = tty->ops->get_icount(tty, &icount); | ||
2522 | if (retval != 0) | ||
2523 | return retval; | ||
2524 | if (copy_to_user(arg, &icount, sizeof(icount))) | ||
2525 | return -EFAULT; | ||
2526 | return 0; | ||
2527 | } | ||
2528 | |||
2505 | struct tty_struct *tty_pair_get_tty(struct tty_struct *tty) | 2529 | struct tty_struct *tty_pair_get_tty(struct tty_struct *tty) |
2506 | { | 2530 | { |
2507 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 2531 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
@@ -2622,6 +2646,12 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
2622 | case TIOCMBIC: | 2646 | case TIOCMBIC: |
2623 | case TIOCMBIS: | 2647 | case TIOCMBIS: |
2624 | return tty_tiocmset(tty, file, cmd, p); | 2648 | return tty_tiocmset(tty, file, cmd, p); |
2649 | case TIOCGICOUNT: | ||
2650 | retval = tty_tiocgicount(tty, p); | ||
2651 | /* For the moment allow fall through to the old method */ | ||
2652 | if (retval != -EINVAL) | ||
2653 | return retval; | ||
2654 | break; | ||
2625 | case TCFLSH: | 2655 | case TCFLSH: |
2626 | switch (arg) { | 2656 | switch (arg) { |
2627 | case TCIFLUSH: | 2657 | case TCIFLUSH: |
@@ -2783,6 +2813,20 @@ void do_SAK(struct tty_struct *tty) | |||
2783 | 2813 | ||
2784 | EXPORT_SYMBOL(do_SAK); | 2814 | EXPORT_SYMBOL(do_SAK); |
2785 | 2815 | ||
2816 | static int dev_match_devt(struct device *dev, void *data) | ||
2817 | { | ||
2818 | dev_t *devt = data; | ||
2819 | return dev->devt == *devt; | ||
2820 | } | ||
2821 | |||
2822 | /* Must put_device() after it's unused! */ | ||
2823 | static struct device *tty_get_device(struct tty_struct *tty) | ||
2824 | { | ||
2825 | dev_t devt = tty_devnum(tty); | ||
2826 | return class_find_device(tty_class, NULL, &devt, dev_match_devt); | ||
2827 | } | ||
2828 | |||
2829 | |||
2786 | /** | 2830 | /** |
2787 | * initialize_tty_struct | 2831 | * initialize_tty_struct |
2788 | * @tty: tty to initialize | 2832 | * @tty: tty to initialize |
@@ -2823,6 +2867,7 @@ void initialize_tty_struct(struct tty_struct *tty, | |||
2823 | tty->ops = driver->ops; | 2867 | tty->ops = driver->ops; |
2824 | tty->index = idx; | 2868 | tty->index = idx; |
2825 | tty_line_name(driver, idx, tty->name); | 2869 | tty_line_name(driver, idx, tty->name); |
2870 | tty->dev = tty_get_device(tty); | ||
2826 | } | 2871 | } |
2827 | 2872 | ||
2828 | /** | 2873 | /** |
@@ -2980,6 +3025,7 @@ int tty_register_driver(struct tty_driver *driver) | |||
2980 | int i; | 3025 | int i; |
2981 | dev_t dev; | 3026 | dev_t dev; |
2982 | void **p = NULL; | 3027 | void **p = NULL; |
3028 | struct device *d; | ||
2983 | 3029 | ||
2984 | if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) { | 3030 | if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) { |
2985 | p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL); | 3031 | p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL); |
@@ -3027,12 +3073,31 @@ int tty_register_driver(struct tty_driver *driver) | |||
3027 | mutex_unlock(&tty_mutex); | 3073 | mutex_unlock(&tty_mutex); |
3028 | 3074 | ||
3029 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) { | 3075 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) { |
3030 | for (i = 0; i < driver->num; i++) | 3076 | for (i = 0; i < driver->num; i++) { |
3031 | tty_register_device(driver, i, NULL); | 3077 | d = tty_register_device(driver, i, NULL); |
3078 | if (IS_ERR(d)) { | ||
3079 | error = PTR_ERR(d); | ||
3080 | goto err; | ||
3081 | } | ||
3082 | } | ||
3032 | } | 3083 | } |
3033 | proc_tty_register_driver(driver); | 3084 | proc_tty_register_driver(driver); |
3034 | driver->flags |= TTY_DRIVER_INSTALLED; | 3085 | driver->flags |= TTY_DRIVER_INSTALLED; |
3035 | return 0; | 3086 | return 0; |
3087 | |||
3088 | err: | ||
3089 | for (i--; i >= 0; i--) | ||
3090 | tty_unregister_device(driver, i); | ||
3091 | |||
3092 | mutex_lock(&tty_mutex); | ||
3093 | list_del(&driver->tty_drivers); | ||
3094 | mutex_unlock(&tty_mutex); | ||
3095 | |||
3096 | unregister_chrdev_region(dev, driver->num); | ||
3097 | driver->ttys = NULL; | ||
3098 | driver->termios = NULL; | ||
3099 | kfree(p); | ||
3100 | return error; | ||
3036 | } | 3101 | } |
3037 | 3102 | ||
3038 | EXPORT_SYMBOL(tty_register_driver); | 3103 | EXPORT_SYMBOL(tty_register_driver); |
diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c new file mode 100644 index 000000000000..c40c1612c8a7 --- /dev/null +++ b/drivers/char/ttyprintk.c | |||
@@ -0,0 +1,225 @@ | |||
1 | /* | ||
2 | * linux/drivers/char/ttyprintk.c | ||
3 | * | ||
4 | * Copyright (C) 2010 Samo Pogacnik | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the smems of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; version 2 of the License. | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * This pseudo device allows user to make printk messages. It is possible | ||
13 | * to store "console" messages inline with kernel messages for better analyses | ||
14 | * of the boot process, for example. | ||
15 | */ | ||
16 | |||
17 | #include <linux/device.h> | ||
18 | #include <linux/serial.h> | ||
19 | #include <linux/tty.h> | ||
20 | |||
21 | struct ttyprintk_port { | ||
22 | struct tty_port port; | ||
23 | struct mutex port_write_mutex; | ||
24 | }; | ||
25 | |||
26 | static struct ttyprintk_port tpk_port; | ||
27 | |||
28 | /* | ||
29 | * Our simple preformatting supports transparent output of (time-stamped) | ||
30 | * printk messages (also suitable for logging service): | ||
31 | * - any cr is replaced by nl | ||
32 | * - adds a ttyprintk source tag in front of each line | ||
33 | * - too long message is fragmeted, with '\'nl between fragments | ||
34 | * - TPK_STR_SIZE isn't really the write_room limiting factor, bcause | ||
35 | * it is emptied on the fly during preformatting. | ||
36 | */ | ||
37 | #define TPK_STR_SIZE 508 /* should be bigger then max expected line length */ | ||
38 | #define TPK_MAX_ROOM 4096 /* we could assume 4K for instance */ | ||
39 | static const char *tpk_tag = "[U] "; /* U for User */ | ||
40 | static int tpk_curr; | ||
41 | |||
42 | static int tpk_printk(const unsigned char *buf, int count) | ||
43 | { | ||
44 | static char tmp[TPK_STR_SIZE + 4]; | ||
45 | int i = tpk_curr; | ||
46 | |||
47 | if (buf == NULL) { | ||
48 | /* flush tmp[] */ | ||
49 | if (tpk_curr > 0) { | ||
50 | /* non nl or cr terminated message - add nl */ | ||
51 | tmp[tpk_curr + 0] = '\n'; | ||
52 | tmp[tpk_curr + 1] = '\0'; | ||
53 | printk(KERN_INFO "%s%s", tpk_tag, tmp); | ||
54 | tpk_curr = 0; | ||
55 | } | ||
56 | return i; | ||
57 | } | ||
58 | |||
59 | for (i = 0; i < count; i++) { | ||
60 | tmp[tpk_curr] = buf[i]; | ||
61 | if (tpk_curr < TPK_STR_SIZE) { | ||
62 | switch (buf[i]) { | ||
63 | case '\r': | ||
64 | /* replace cr with nl */ | ||
65 | tmp[tpk_curr + 0] = '\n'; | ||
66 | tmp[tpk_curr + 1] = '\0'; | ||
67 | printk(KERN_INFO "%s%s", tpk_tag, tmp); | ||
68 | tpk_curr = 0; | ||
69 | if (buf[i + 1] == '\n') | ||
70 | i++; | ||
71 | break; | ||
72 | case '\n': | ||
73 | tmp[tpk_curr + 1] = '\0'; | ||
74 | printk(KERN_INFO "%s%s", tpk_tag, tmp); | ||
75 | tpk_curr = 0; | ||
76 | break; | ||
77 | default: | ||
78 | tpk_curr++; | ||
79 | } | ||
80 | } else { | ||
81 | /* end of tmp buffer reached: cut the message in two */ | ||
82 | tmp[tpk_curr + 1] = '\\'; | ||
83 | tmp[tpk_curr + 2] = '\n'; | ||
84 | tmp[tpk_curr + 3] = '\0'; | ||
85 | printk(KERN_INFO "%s%s", tpk_tag, tmp); | ||
86 | tpk_curr = 0; | ||
87 | } | ||
88 | } | ||
89 | |||
90 | return count; | ||
91 | } | ||
92 | |||
93 | /* | ||
94 | * TTY operations open function. | ||
95 | */ | ||
96 | static int tpk_open(struct tty_struct *tty, struct file *filp) | ||
97 | { | ||
98 | tty->driver_data = &tpk_port; | ||
99 | |||
100 | return tty_port_open(&tpk_port.port, tty, filp); | ||
101 | } | ||
102 | |||
103 | /* | ||
104 | * TTY operations close function. | ||
105 | */ | ||
106 | static void tpk_close(struct tty_struct *tty, struct file *filp) | ||
107 | { | ||
108 | struct ttyprintk_port *tpkp = tty->driver_data; | ||
109 | |||
110 | mutex_lock(&tpkp->port_write_mutex); | ||
111 | /* flush tpk_printk buffer */ | ||
112 | tpk_printk(NULL, 0); | ||
113 | mutex_unlock(&tpkp->port_write_mutex); | ||
114 | |||
115 | tty_port_close(&tpkp->port, tty, filp); | ||
116 | } | ||
117 | |||
118 | /* | ||
119 | * TTY operations write function. | ||
120 | */ | ||
121 | static int tpk_write(struct tty_struct *tty, | ||
122 | const unsigned char *buf, int count) | ||
123 | { | ||
124 | struct ttyprintk_port *tpkp = tty->driver_data; | ||
125 | int ret; | ||
126 | |||
127 | |||
128 | /* exclusive use of tpk_printk within this tty */ | ||
129 | mutex_lock(&tpkp->port_write_mutex); | ||
130 | ret = tpk_printk(buf, count); | ||
131 | mutex_unlock(&tpkp->port_write_mutex); | ||
132 | |||
133 | return ret; | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * TTY operations write_room function. | ||
138 | */ | ||
139 | static int tpk_write_room(struct tty_struct *tty) | ||
140 | { | ||
141 | return TPK_MAX_ROOM; | ||
142 | } | ||
143 | |||
144 | /* | ||
145 | * TTY operations ioctl function. | ||
146 | */ | ||
147 | static int tpk_ioctl(struct tty_struct *tty, struct file *file, | ||
148 | unsigned int cmd, unsigned long arg) | ||
149 | { | ||
150 | struct ttyprintk_port *tpkp = tty->driver_data; | ||
151 | |||
152 | if (!tpkp) | ||
153 | return -EINVAL; | ||
154 | |||
155 | switch (cmd) { | ||
156 | /* Stop TIOCCONS */ | ||
157 | case TIOCCONS: | ||
158 | return -EOPNOTSUPP; | ||
159 | default: | ||
160 | return -ENOIOCTLCMD; | ||
161 | } | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static const struct tty_operations ttyprintk_ops = { | ||
166 | .open = tpk_open, | ||
167 | .close = tpk_close, | ||
168 | .write = tpk_write, | ||
169 | .write_room = tpk_write_room, | ||
170 | .ioctl = tpk_ioctl, | ||
171 | }; | ||
172 | |||
173 | struct tty_port_operations null_ops = { }; | ||
174 | |||
175 | static struct tty_driver *ttyprintk_driver; | ||
176 | |||
177 | static int __init ttyprintk_init(void) | ||
178 | { | ||
179 | int ret = -ENOMEM; | ||
180 | void *rp; | ||
181 | |||
182 | ttyprintk_driver = alloc_tty_driver(1); | ||
183 | if (!ttyprintk_driver) | ||
184 | return ret; | ||
185 | |||
186 | ttyprintk_driver->owner = THIS_MODULE; | ||
187 | ttyprintk_driver->driver_name = "ttyprintk"; | ||
188 | ttyprintk_driver->name = "ttyprintk"; | ||
189 | ttyprintk_driver->major = TTYAUX_MAJOR; | ||
190 | ttyprintk_driver->minor_start = 3; | ||
191 | ttyprintk_driver->num = 1; | ||
192 | ttyprintk_driver->type = TTY_DRIVER_TYPE_CONSOLE; | ||
193 | ttyprintk_driver->init_termios = tty_std_termios; | ||
194 | ttyprintk_driver->init_termios.c_oflag = OPOST | OCRNL | ONOCR | ONLRET; | ||
195 | ttyprintk_driver->flags = TTY_DRIVER_RESET_TERMIOS | | ||
196 | TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | ||
197 | tty_set_operations(ttyprintk_driver, &ttyprintk_ops); | ||
198 | |||
199 | ret = tty_register_driver(ttyprintk_driver); | ||
200 | if (ret < 0) { | ||
201 | printk(KERN_ERR "Couldn't register ttyprintk driver\n"); | ||
202 | goto error; | ||
203 | } | ||
204 | |||
205 | /* create our unnumbered device */ | ||
206 | rp = device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 3), NULL, | ||
207 | ttyprintk_driver->name); | ||
208 | if (IS_ERR(rp)) { | ||
209 | printk(KERN_ERR "Couldn't create ttyprintk device\n"); | ||
210 | ret = PTR_ERR(rp); | ||
211 | goto error; | ||
212 | } | ||
213 | |||
214 | tty_port_init(&tpk_port.port); | ||
215 | tpk_port.port.ops = &null_ops; | ||
216 | mutex_init(&tpk_port.port_write_mutex); | ||
217 | |||
218 | return 0; | ||
219 | |||
220 | error: | ||
221 | put_tty_driver(ttyprintk_driver); | ||
222 | ttyprintk_driver = NULL; | ||
223 | return ret; | ||
224 | } | ||
225 | module_init(ttyprintk_init); | ||
diff --git a/drivers/char/uv_mmtimer.c b/drivers/char/uv_mmtimer.c index c7072ba14f48..493b47a0d511 100644 --- a/drivers/char/uv_mmtimer.c +++ b/drivers/char/uv_mmtimer.c | |||
@@ -52,6 +52,7 @@ static const struct file_operations uv_mmtimer_fops = { | |||
52 | .owner = THIS_MODULE, | 52 | .owner = THIS_MODULE, |
53 | .mmap = uv_mmtimer_mmap, | 53 | .mmap = uv_mmtimer_mmap, |
54 | .unlocked_ioctl = uv_mmtimer_ioctl, | 54 | .unlocked_ioctl = uv_mmtimer_ioctl, |
55 | .llseek = noop_llseek, | ||
55 | }; | 56 | }; |
56 | 57 | ||
57 | /** | 58 | /** |
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index bcce46c96b88..273ab44cc91d 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c | |||
@@ -35,6 +35,12 @@ | |||
35 | #include <linux/console.h> | 35 | #include <linux/console.h> |
36 | #include <linux/device.h> | 36 | #include <linux/device.h> |
37 | #include <linux/smp_lock.h> | 37 | #include <linux/smp_lock.h> |
38 | #include <linux/sched.h> | ||
39 | #include <linux/fs.h> | ||
40 | #include <linux/poll.h> | ||
41 | #include <linux/signal.h> | ||
42 | #include <linux/slab.h> | ||
43 | #include <linux/notifier.h> | ||
38 | 44 | ||
39 | #include <asm/uaccess.h> | 45 | #include <asm/uaccess.h> |
40 | #include <asm/byteorder.h> | 46 | #include <asm/byteorder.h> |
@@ -45,6 +51,86 @@ | |||
45 | #undef addr | 51 | #undef addr |
46 | #define HEADER_SIZE 4 | 52 | #define HEADER_SIZE 4 |
47 | 53 | ||
54 | struct vcs_poll_data { | ||
55 | struct notifier_block notifier; | ||
56 | unsigned int cons_num; | ||
57 | bool seen_last_update; | ||
58 | wait_queue_head_t waitq; | ||
59 | struct fasync_struct *fasync; | ||
60 | }; | ||
61 | |||
62 | static int | ||
63 | vcs_notifier(struct notifier_block *nb, unsigned long code, void *_param) | ||
64 | { | ||
65 | struct vt_notifier_param *param = _param; | ||
66 | struct vc_data *vc = param->vc; | ||
67 | struct vcs_poll_data *poll = | ||
68 | container_of(nb, struct vcs_poll_data, notifier); | ||
69 | int currcons = poll->cons_num; | ||
70 | |||
71 | if (code != VT_UPDATE) | ||
72 | return NOTIFY_DONE; | ||
73 | |||
74 | if (currcons == 0) | ||
75 | currcons = fg_console; | ||
76 | else | ||
77 | currcons--; | ||
78 | if (currcons != vc->vc_num) | ||
79 | return NOTIFY_DONE; | ||
80 | |||
81 | poll->seen_last_update = false; | ||
82 | wake_up_interruptible(&poll->waitq); | ||
83 | kill_fasync(&poll->fasync, SIGIO, POLL_IN); | ||
84 | return NOTIFY_OK; | ||
85 | } | ||
86 | |||
87 | static void | ||
88 | vcs_poll_data_free(struct vcs_poll_data *poll) | ||
89 | { | ||
90 | unregister_vt_notifier(&poll->notifier); | ||
91 | kfree(poll); | ||
92 | } | ||
93 | |||
94 | static struct vcs_poll_data * | ||
95 | vcs_poll_data_get(struct file *file) | ||
96 | { | ||
97 | struct vcs_poll_data *poll = file->private_data; | ||
98 | |||
99 | if (poll) | ||
100 | return poll; | ||
101 | |||
102 | poll = kzalloc(sizeof(*poll), GFP_KERNEL); | ||
103 | if (!poll) | ||
104 | return NULL; | ||
105 | poll->cons_num = iminor(file->f_path.dentry->d_inode) & 127; | ||
106 | init_waitqueue_head(&poll->waitq); | ||
107 | poll->notifier.notifier_call = vcs_notifier; | ||
108 | if (register_vt_notifier(&poll->notifier) != 0) { | ||
109 | kfree(poll); | ||
110 | return NULL; | ||
111 | } | ||
112 | |||
113 | /* | ||
114 | * This code may be called either through ->poll() or ->fasync(). | ||
115 | * If we have two threads using the same file descriptor, they could | ||
116 | * both enter this function, both notice that the structure hasn't | ||
117 | * been allocated yet and go ahead allocating it in parallel, but | ||
118 | * only one of them must survive and be shared otherwise we'd leak | ||
119 | * memory with a dangling notifier callback. | ||
120 | */ | ||
121 | spin_lock(&file->f_lock); | ||
122 | if (!file->private_data) { | ||
123 | file->private_data = poll; | ||
124 | } else { | ||
125 | /* someone else raced ahead of us */ | ||
126 | vcs_poll_data_free(poll); | ||
127 | poll = file->private_data; | ||
128 | } | ||
129 | spin_unlock(&file->f_lock); | ||
130 | |||
131 | return poll; | ||
132 | } | ||
133 | |||
48 | static int | 134 | static int |
49 | vcs_size(struct inode *inode) | 135 | vcs_size(struct inode *inode) |
50 | { | 136 | { |
@@ -102,6 +188,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
102 | struct inode *inode = file->f_path.dentry->d_inode; | 188 | struct inode *inode = file->f_path.dentry->d_inode; |
103 | unsigned int currcons = iminor(inode); | 189 | unsigned int currcons = iminor(inode); |
104 | struct vc_data *vc; | 190 | struct vc_data *vc; |
191 | struct vcs_poll_data *poll; | ||
105 | long pos; | 192 | long pos; |
106 | long viewed, attr, read; | 193 | long viewed, attr, read; |
107 | int col, maxcol; | 194 | int col, maxcol; |
@@ -134,6 +221,9 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
134 | ret = -EINVAL; | 221 | ret = -EINVAL; |
135 | if (pos < 0) | 222 | if (pos < 0) |
136 | goto unlock_out; | 223 | goto unlock_out; |
224 | poll = file->private_data; | ||
225 | if (count && poll) | ||
226 | poll->seen_last_update = true; | ||
137 | read = 0; | 227 | read = 0; |
138 | ret = 0; | 228 | ret = 0; |
139 | while (count) { | 229 | while (count) { |
@@ -448,6 +538,8 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
448 | } | 538 | } |
449 | *ppos += written; | 539 | *ppos += written; |
450 | ret = written; | 540 | ret = written; |
541 | if (written) | ||
542 | vcs_scr_updated(vc); | ||
451 | 543 | ||
452 | unlock_out: | 544 | unlock_out: |
453 | release_console_sem(); | 545 | release_console_sem(); |
@@ -457,6 +549,37 @@ unlock_out: | |||
457 | return ret; | 549 | return ret; |
458 | } | 550 | } |
459 | 551 | ||
552 | static unsigned int | ||
553 | vcs_poll(struct file *file, poll_table *wait) | ||
554 | { | ||
555 | struct vcs_poll_data *poll = vcs_poll_data_get(file); | ||
556 | int ret = 0; | ||
557 | |||
558 | if (poll) { | ||
559 | poll_wait(file, &poll->waitq, wait); | ||
560 | if (!poll->seen_last_update) | ||
561 | ret = POLLIN | POLLRDNORM; | ||
562 | } | ||
563 | return ret; | ||
564 | } | ||
565 | |||
566 | static int | ||
567 | vcs_fasync(int fd, struct file *file, int on) | ||
568 | { | ||
569 | struct vcs_poll_data *poll = file->private_data; | ||
570 | |||
571 | if (!poll) { | ||
572 | /* don't allocate anything if all we want is disable fasync */ | ||
573 | if (!on) | ||
574 | return 0; | ||
575 | poll = vcs_poll_data_get(file); | ||
576 | if (!poll) | ||
577 | return -ENOMEM; | ||
578 | } | ||
579 | |||
580 | return fasync_helper(fd, file, on, &poll->fasync); | ||
581 | } | ||
582 | |||
460 | static int | 583 | static int |
461 | vcs_open(struct inode *inode, struct file *filp) | 584 | vcs_open(struct inode *inode, struct file *filp) |
462 | { | 585 | { |
@@ -470,11 +593,23 @@ vcs_open(struct inode *inode, struct file *filp) | |||
470 | return ret; | 593 | return ret; |
471 | } | 594 | } |
472 | 595 | ||
596 | static int vcs_release(struct inode *inode, struct file *file) | ||
597 | { | ||
598 | struct vcs_poll_data *poll = file->private_data; | ||
599 | |||
600 | if (poll) | ||
601 | vcs_poll_data_free(poll); | ||
602 | return 0; | ||
603 | } | ||
604 | |||
473 | static const struct file_operations vcs_fops = { | 605 | static const struct file_operations vcs_fops = { |
474 | .llseek = vcs_lseek, | 606 | .llseek = vcs_lseek, |
475 | .read = vcs_read, | 607 | .read = vcs_read, |
476 | .write = vcs_write, | 608 | .write = vcs_write, |
609 | .poll = vcs_poll, | ||
610 | .fasync = vcs_fasync, | ||
477 | .open = vcs_open, | 611 | .open = vcs_open, |
612 | .release = vcs_release, | ||
478 | }; | 613 | }; |
479 | 614 | ||
480 | static struct class *vc_class; | 615 | static struct class *vc_class; |
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index 42f7fa442ff8..ad6e64a2912d 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c | |||
@@ -46,7 +46,7 @@ | |||
46 | #include <linux/completion.h> | 46 | #include <linux/completion.h> |
47 | #include <linux/proc_fs.h> | 47 | #include <linux/proc_fs.h> |
48 | #include <linux/seq_file.h> | 48 | #include <linux/seq_file.h> |
49 | #include <linux/smp_lock.h> | 49 | #include <linux/mutex.h> |
50 | #include <linux/slab.h> | 50 | #include <linux/slab.h> |
51 | 51 | ||
52 | #include <asm/uaccess.h> | 52 | #include <asm/uaccess.h> |
@@ -64,6 +64,7 @@ | |||
64 | #define VIOTAPE_KERN_WARN KERN_WARNING "viotape: " | 64 | #define VIOTAPE_KERN_WARN KERN_WARNING "viotape: " |
65 | #define VIOTAPE_KERN_INFO KERN_INFO "viotape: " | 65 | #define VIOTAPE_KERN_INFO KERN_INFO "viotape: " |
66 | 66 | ||
67 | static DEFINE_MUTEX(proc_viotape_mutex); | ||
67 | static int viotape_numdev; | 68 | static int viotape_numdev; |
68 | 69 | ||
69 | /* | 70 | /* |
@@ -684,9 +685,9 @@ static long viotap_unlocked_ioctl(struct file *file, | |||
684 | { | 685 | { |
685 | long rc; | 686 | long rc; |
686 | 687 | ||
687 | lock_kernel(); | 688 | mutex_lock(&proc_viotape_mutex); |
688 | rc = viotap_ioctl(file->f_path.dentry->d_inode, file, cmd, arg); | 689 | rc = viotap_ioctl(file->f_path.dentry->d_inode, file, cmd, arg); |
689 | unlock_kernel(); | 690 | mutex_unlock(&proc_viotape_mutex); |
690 | return rc; | 691 | return rc; |
691 | } | 692 | } |
692 | 693 | ||
@@ -700,7 +701,7 @@ static int viotap_open(struct inode *inode, struct file *file) | |||
700 | if (op == NULL) | 701 | if (op == NULL) |
701 | return -ENOMEM; | 702 | return -ENOMEM; |
702 | 703 | ||
703 | lock_kernel(); | 704 | mutex_lock(&proc_viotape_mutex); |
704 | get_dev_info(file->f_path.dentry->d_inode, &devi); | 705 | get_dev_info(file->f_path.dentry->d_inode, &devi); |
705 | 706 | ||
706 | /* Note: We currently only support one mode! */ | 707 | /* Note: We currently only support one mode! */ |
@@ -731,7 +732,7 @@ static int viotap_open(struct inode *inode, struct file *file) | |||
731 | 732 | ||
732 | free_op: | 733 | free_op: |
733 | free_op_struct(op); | 734 | free_op_struct(op); |
734 | unlock_kernel(); | 735 | mutex_unlock(&proc_viotape_mutex); |
735 | return ret; | 736 | return ret; |
736 | } | 737 | } |
737 | 738 | ||
@@ -804,6 +805,7 @@ const struct file_operations viotap_fops = { | |||
804 | .unlocked_ioctl = viotap_unlocked_ioctl, | 805 | .unlocked_ioctl = viotap_unlocked_ioctl, |
805 | .open = viotap_open, | 806 | .open = viotap_open, |
806 | .release = viotap_release, | 807 | .release = viotap_release, |
808 | .llseek = noop_llseek, | ||
807 | }; | 809 | }; |
808 | 810 | ||
809 | /* Handle interrupt events for tape */ | 811 | /* Handle interrupt events for tape */ |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 281aada7b4a1..a8ec48ed14d9 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -4182,6 +4182,11 @@ void vcs_scr_writew(struct vc_data *vc, u16 val, u16 *org) | |||
4182 | } | 4182 | } |
4183 | } | 4183 | } |
4184 | 4184 | ||
4185 | void vcs_scr_updated(struct vc_data *vc) | ||
4186 | { | ||
4187 | notify_update(vc); | ||
4188 | } | ||
4189 | |||
4185 | /* | 4190 | /* |
4186 | * Visible symbols for modules | 4191 | * Visible symbols for modules |
4187 | */ | 4192 | */ |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 38df8c19e74c..6b68a0fb4611 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -503,6 +503,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
503 | struct kbd_struct * kbd; | 503 | struct kbd_struct * kbd; |
504 | unsigned int console; | 504 | unsigned int console; |
505 | unsigned char ucval; | 505 | unsigned char ucval; |
506 | unsigned int uival; | ||
506 | void __user *up = (void __user *)arg; | 507 | void __user *up = (void __user *)arg; |
507 | int i, perm; | 508 | int i, perm; |
508 | int ret = 0; | 509 | int ret = 0; |
@@ -657,7 +658,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
657 | break; | 658 | break; |
658 | 659 | ||
659 | case KDGETMODE: | 660 | case KDGETMODE: |
660 | ucval = vc->vc_mode; | 661 | uival = vc->vc_mode; |
661 | goto setint; | 662 | goto setint; |
662 | 663 | ||
663 | case KDMAPDISP: | 664 | case KDMAPDISP: |
@@ -695,7 +696,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
695 | break; | 696 | break; |
696 | 697 | ||
697 | case KDGKBMODE: | 698 | case KDGKBMODE: |
698 | ucval = ((kbd->kbdmode == VC_RAW) ? K_RAW : | 699 | uival = ((kbd->kbdmode == VC_RAW) ? K_RAW : |
699 | (kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW : | 700 | (kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW : |
700 | (kbd->kbdmode == VC_UNICODE) ? K_UNICODE : | 701 | (kbd->kbdmode == VC_UNICODE) ? K_UNICODE : |
701 | K_XLATE); | 702 | K_XLATE); |
@@ -717,9 +718,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
717 | break; | 718 | break; |
718 | 719 | ||
719 | case KDGKBMETA: | 720 | case KDGKBMETA: |
720 | ucval = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT); | 721 | uival = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT); |
721 | setint: | 722 | setint: |
722 | ret = put_user(ucval, (int __user *)arg); | 723 | ret = put_user(uival, (int __user *)arg); |
723 | break; | 724 | break; |
724 | 725 | ||
725 | case KDGETKEYCODE: | 726 | case KDGETKEYCODE: |
@@ -949,7 +950,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
949 | for (i = 0; i < MAX_NR_CONSOLES; ++i) | 950 | for (i = 0; i < MAX_NR_CONSOLES; ++i) |
950 | if (! VT_IS_IN_USE(i)) | 951 | if (! VT_IS_IN_USE(i)) |
951 | break; | 952 | break; |
952 | ucval = i < MAX_NR_CONSOLES ? (i+1) : -1; | 953 | uival = i < MAX_NR_CONSOLES ? (i+1) : -1; |
953 | goto setint; | 954 | goto setint; |
954 | 955 | ||
955 | /* | 956 | /* |
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index b663d573aad9..9f2272e6de1c 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c | |||
@@ -81,7 +81,6 @@ | |||
81 | #include <linux/poll.h> | 81 | #include <linux/poll.h> |
82 | #include <linux/proc_fs.h> | 82 | #include <linux/proc_fs.h> |
83 | #include <linux/mutex.h> | 83 | #include <linux/mutex.h> |
84 | #include <linux/smp_lock.h> | ||
85 | #include <linux/sysctl.h> | 84 | #include <linux/sysctl.h> |
86 | #include <linux/fs.h> | 85 | #include <linux/fs.h> |
87 | #include <linux/cdev.h> | 86 | #include <linux/cdev.h> |
@@ -112,6 +111,7 @@ | |||
112 | #define HWICAP_DEVICES 1 | 111 | #define HWICAP_DEVICES 1 |
113 | 112 | ||
114 | /* An array, which is set to true when the device is registered. */ | 113 | /* An array, which is set to true when the device is registered. */ |
114 | static DEFINE_MUTEX(hwicap_mutex); | ||
115 | static bool probed_devices[HWICAP_DEVICES]; | 115 | static bool probed_devices[HWICAP_DEVICES]; |
116 | static struct mutex icap_sem; | 116 | static struct mutex icap_sem; |
117 | 117 | ||
@@ -502,7 +502,7 @@ static int hwicap_open(struct inode *inode, struct file *file) | |||
502 | struct hwicap_drvdata *drvdata; | 502 | struct hwicap_drvdata *drvdata; |
503 | int status; | 503 | int status; |
504 | 504 | ||
505 | lock_kernel(); | 505 | mutex_lock(&hwicap_mutex); |
506 | drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev); | 506 | drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev); |
507 | 507 | ||
508 | status = mutex_lock_interruptible(&drvdata->sem); | 508 | status = mutex_lock_interruptible(&drvdata->sem); |
@@ -528,7 +528,7 @@ static int hwicap_open(struct inode *inode, struct file *file) | |||
528 | error: | 528 | error: |
529 | mutex_unlock(&drvdata->sem); | 529 | mutex_unlock(&drvdata->sem); |
530 | out: | 530 | out: |
531 | unlock_kernel(); | 531 | mutex_unlock(&hwicap_mutex); |
532 | return status; | 532 | return status; |
533 | } | 533 | } |
534 | 534 | ||
@@ -567,6 +567,7 @@ static const struct file_operations hwicap_fops = { | |||
567 | .read = hwicap_read, | 567 | .read = hwicap_read, |
568 | .open = hwicap_open, | 568 | .open = hwicap_open, |
569 | .release = hwicap_release, | 569 | .release = hwicap_release, |
570 | .llseek = noop_llseek, | ||
570 | }; | 571 | }; |
571 | 572 | ||
572 | static int __devinit hwicap_setup(struct device *dev, int id, | 573 | static int __devinit hwicap_setup(struct device *dev, int id, |