aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/feature-removal-schedule.txt20
-rw-r--r--arch/x86/xen/enlighten.c21
-rw-r--r--arch/x86/xen/mmu.c4
-rw-r--r--drivers/base/platform.c1
-rw-r--r--drivers/mfd/mfd-core.c16
-rw-r--r--drivers/platform/x86/Kconfig3
-rw-r--r--drivers/platform/x86/acer-wmi.c2
-rw-r--r--drivers/platform/x86/asus-wmi.c4
-rw-r--r--drivers/platform/x86/eeepc-wmi.c2
-rw-r--r--drivers/platform/x86/intel_pmic_gpio.c43
-rw-r--r--drivers/platform/x86/samsung-laptop.c17
-rw-r--r--drivers/platform/x86/sony-laptop.c65
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c3
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/samsung-laptop/Kconfig10
-rw-r--r--drivers/staging/samsung-laptop/Makefile1
-rw-r--r--drivers/staging/samsung-laptop/TODO5
-rw-r--r--drivers/staging/samsung-laptop/samsung-laptop.c843
-rw-r--r--drivers/xen/events.c6
-rw-r--r--fs/namespace.c16
-rw-r--r--fs/nfs/write.c6
-rw-r--r--include/linux/mfd/core.h13
-rw-r--r--include/linux/platform_device.h5
-rw-r--r--mm/memory.c26
-rw-r--r--mm/mlock.c13
26 files changed, 178 insertions, 970 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 274b32d1253..492e81df296 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -387,26 +387,6 @@ Who: Tejun Heo <tj@kernel.org>
387 387
388---------------------------- 388----------------------------
389 389
390What: Support for lcd_switch and display_get in asus-laptop driver
391When: March 2010
392Why: These two features use non-standard interfaces. There are the
393 only features that really need multiple path to guess what's
394 the right method name on a specific laptop.
395
396 Removing them will allow to remove a lot of code an significantly
397 clean the drivers.
398
399 This will affect the backlight code which won't be able to know
400 if the backlight is on or off. The platform display file will also be
401 write only (like the one in eeepc-laptop).
402
403 This should'nt affect a lot of user because they usually know
404 when their display is on or off.
405
406Who: Corentin Chary <corentin.chary@gmail.com>
407
408----------------------------
409
410What: sysfs-class-rfkill state file 390What: sysfs-class-rfkill state file
411When: Feb 2014 391When: Feb 2014
412Files: net/rfkill/core.c 392Files: net/rfkill/core.c
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 49dbd78ec3c..e3c6a06cf72 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -238,6 +238,7 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
238static __init void xen_init_cpuid_mask(void) 238static __init void xen_init_cpuid_mask(void)
239{ 239{
240 unsigned int ax, bx, cx, dx; 240 unsigned int ax, bx, cx, dx;
241 unsigned int xsave_mask;
241 242
242 cpuid_leaf1_edx_mask = 243 cpuid_leaf1_edx_mask =
243 ~((1 << X86_FEATURE_MCE) | /* disable MCE */ 244 ~((1 << X86_FEATURE_MCE) | /* disable MCE */
@@ -249,24 +250,16 @@ static __init void xen_init_cpuid_mask(void)
249 cpuid_leaf1_edx_mask &= 250 cpuid_leaf1_edx_mask &=
250 ~((1 << X86_FEATURE_APIC) | /* disable local APIC */ 251 ~((1 << X86_FEATURE_APIC) | /* disable local APIC */
251 (1 << X86_FEATURE_ACPI)); /* disable ACPI */ 252 (1 << X86_FEATURE_ACPI)); /* disable ACPI */
252
253 ax = 1; 253 ax = 1;
254 cx = 0;
255 xen_cpuid(&ax, &bx, &cx, &dx); 254 xen_cpuid(&ax, &bx, &cx, &dx);
256 255
257 /* cpuid claims we support xsave; try enabling it to see what happens */ 256 xsave_mask =
258 if (cx & (1 << (X86_FEATURE_XSAVE % 32))) { 257 (1 << (X86_FEATURE_XSAVE % 32)) |
259 unsigned long cr4; 258 (1 << (X86_FEATURE_OSXSAVE % 32));
260
261 set_in_cr4(X86_CR4_OSXSAVE);
262
263 cr4 = read_cr4();
264 259
265 if ((cr4 & X86_CR4_OSXSAVE) == 0) 260 /* Xen will set CR4.OSXSAVE if supported and not disabled by force */
266 cpuid_leaf1_ecx_mask &= ~(1 << (X86_FEATURE_XSAVE % 32)); 261 if ((cx & xsave_mask) != xsave_mask)
267 262 cpuid_leaf1_ecx_mask &= ~xsave_mask; /* disable XSAVE & OSXSAVE */
268 clear_in_cr4(X86_CR4_OSXSAVE);
269 }
270} 263}
271 264
272static void xen_set_debugreg(int reg, unsigned long val) 265static void xen_set_debugreg(int reg, unsigned long val)
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index c82df6c9c0f..a991b57f91f 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -565,13 +565,13 @@ pte_t xen_make_pte_debug(pteval_t pte)
565 if (io_page && 565 if (io_page &&
566 (xen_initial_domain() || addr >= ISA_END_ADDRESS)) { 566 (xen_initial_domain() || addr >= ISA_END_ADDRESS)) {
567 other_addr = pfn_to_mfn(addr >> PAGE_SHIFT) << PAGE_SHIFT; 567 other_addr = pfn_to_mfn(addr >> PAGE_SHIFT) << PAGE_SHIFT;
568 WARN(addr != other_addr, 568 WARN_ONCE(addr != other_addr,
569 "0x%lx is using VM_IO, but it is 0x%lx!\n", 569 "0x%lx is using VM_IO, but it is 0x%lx!\n",
570 (unsigned long)addr, (unsigned long)other_addr); 570 (unsigned long)addr, (unsigned long)other_addr);
571 } else { 571 } else {
572 pteval_t iomap_set = (_pte.pte & PTE_FLAGS_MASK) & _PAGE_IOMAP; 572 pteval_t iomap_set = (_pte.pte & PTE_FLAGS_MASK) & _PAGE_IOMAP;
573 other_addr = (_pte.pte & PTE_PFN_MASK); 573 other_addr = (_pte.pte & PTE_PFN_MASK);
574 WARN((addr == other_addr) && (!io_page) && (!iomap_set), 574 WARN_ONCE((addr == other_addr) && (!io_page) && (!iomap_set),
575 "0x%lx is missing VM_IO (and wasn't fixed)!\n", 575 "0x%lx is missing VM_IO (and wasn't fixed)!\n",
576 (unsigned long)addr); 576 (unsigned long)addr);
577 } 577 }
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index f051cfff18a..6c3a2bdc527 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -149,6 +149,7 @@ static void platform_device_release(struct device *dev)
149 149
150 of_device_node_put(&pa->pdev.dev); 150 of_device_node_put(&pa->pdev.dev);
151 kfree(pa->pdev.dev.platform_data); 151 kfree(pa->pdev.dev.platform_data);
152 kfree(pa->pdev.mfd_cell);
152 kfree(pa->pdev.resource); 153 kfree(pa->pdev.resource);
153 kfree(pa); 154 kfree(pa);
154} 155}
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index d01574d9887..f4c8c844b91 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -55,6 +55,19 @@ int mfd_cell_disable(struct platform_device *pdev)
55} 55}
56EXPORT_SYMBOL(mfd_cell_disable); 56EXPORT_SYMBOL(mfd_cell_disable);
57 57
58static int mfd_platform_add_cell(struct platform_device *pdev,
59 const struct mfd_cell *cell)
60{
61 if (!cell)
62 return 0;
63
64 pdev->mfd_cell = kmemdup(cell, sizeof(*cell), GFP_KERNEL);
65 if (!pdev->mfd_cell)
66 return -ENOMEM;
67
68 return 0;
69}
70
58static int mfd_add_device(struct device *parent, int id, 71static int mfd_add_device(struct device *parent, int id,
59 const struct mfd_cell *cell, 72 const struct mfd_cell *cell,
60 struct resource *mem_base, 73 struct resource *mem_base,
@@ -75,7 +88,7 @@ static int mfd_add_device(struct device *parent, int id,
75 88
76 pdev->dev.parent = parent; 89 pdev->dev.parent = parent;
77 90
78 ret = platform_device_add_data(pdev, cell, sizeof(*cell)); 91 ret = mfd_platform_add_cell(pdev, cell);
79 if (ret) 92 if (ret)
80 goto fail_res; 93 goto fail_res;
81 94
@@ -123,7 +136,6 @@ static int mfd_add_device(struct device *parent, int id,
123 136
124 return 0; 137 return 0;
125 138
126/* platform_device_del(pdev); */
127fail_res: 139fail_res:
128 kfree(res); 140 kfree(res);
129fail_device: 141fail_device:
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 2ee442c2a5d..0485e394712 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -187,7 +187,8 @@ config MSI_LAPTOP
187 depends on ACPI 187 depends on ACPI
188 depends on BACKLIGHT_CLASS_DEVICE 188 depends on BACKLIGHT_CLASS_DEVICE
189 depends on RFKILL 189 depends on RFKILL
190 depends on SERIO_I8042 190 depends on INPUT && SERIO_I8042
191 select INPUT_SPARSEKMAP
191 ---help--- 192 ---help---
192 This is a driver for laptops built by MSI (MICRO-STAR 193 This is a driver for laptops built by MSI (MICRO-STAR
193 INTERNATIONAL): 194 INTERNATIONAL):
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 5ea6c3477d1..ac4e7f83ce6 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -89,7 +89,7 @@ MODULE_LICENSE("GPL");
89#define ACERWMID_EVENT_GUID "676AA15E-6A47-4D9F-A2CC-1E6D18D14026" 89#define ACERWMID_EVENT_GUID "676AA15E-6A47-4D9F-A2CC-1E6D18D14026"
90 90
91MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB"); 91MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB");
92MODULE_ALIAS("wmi:6AF4F258-B401-42Fd-BE91-3D4AC2D7C0D3"); 92MODULE_ALIAS("wmi:6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3");
93MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026"); 93MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026");
94 94
95enum acer_wmi_event_ids { 95enum acer_wmi_event_ids {
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index efc776cb0c6..832a3fd7c1c 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -201,8 +201,8 @@ static int asus_wmi_input_init(struct asus_wmi *asus)
201 if (!asus->inputdev) 201 if (!asus->inputdev)
202 return -ENOMEM; 202 return -ENOMEM;
203 203
204 asus->inputdev->name = asus->driver->input_phys; 204 asus->inputdev->name = asus->driver->input_name;
205 asus->inputdev->phys = asus->driver->input_name; 205 asus->inputdev->phys = asus->driver->input_phys;
206 asus->inputdev->id.bustype = BUS_HOST; 206 asus->inputdev->id.bustype = BUS_HOST;
207 asus->inputdev->dev.parent = &asus->platform_device->dev; 207 asus->inputdev->dev.parent = &asus->platform_device->dev;
208 208
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 0ddc434fb93..649dcadd8ea 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -67,9 +67,11 @@ static const struct key_entry eeepc_wmi_keymap[] = {
67 { KE_KEY, 0x82, { KEY_CAMERA } }, 67 { KE_KEY, 0x82, { KEY_CAMERA } },
68 { KE_KEY, 0x83, { KEY_CAMERA_ZOOMIN } }, 68 { KE_KEY, 0x83, { KEY_CAMERA_ZOOMIN } },
69 { KE_KEY, 0x88, { KEY_WLAN } }, 69 { KE_KEY, 0x88, { KEY_WLAN } },
70 { KE_KEY, 0xbd, { KEY_CAMERA } },
70 { KE_KEY, 0xcc, { KEY_SWITCHVIDEOMODE } }, 71 { KE_KEY, 0xcc, { KEY_SWITCHVIDEOMODE } },
71 { KE_KEY, 0xe0, { KEY_PROG1 } }, /* Task Manager */ 72 { KE_KEY, 0xe0, { KEY_PROG1 } }, /* Task Manager */
72 { KE_KEY, 0xe1, { KEY_F14 } }, /* Change Resolution */ 73 { KE_KEY, 0xe1, { KEY_F14 } }, /* Change Resolution */
74 { KE_KEY, 0xe8, { KEY_SCREENLOCK } },
73 { KE_KEY, 0xe9, { KEY_BRIGHTNESS_ZERO } }, 75 { KE_KEY, 0xe9, { KEY_BRIGHTNESS_ZERO } },
74 { KE_KEY, 0xeb, { KEY_CAMERA_ZOOMOUT } }, 76 { KE_KEY, 0xeb, { KEY_CAMERA_ZOOMOUT } },
75 { KE_KEY, 0xec, { KEY_CAMERA_UP } }, 77 { KE_KEY, 0xec, { KEY_CAMERA_UP } },
diff --git a/drivers/platform/x86/intel_pmic_gpio.c b/drivers/platform/x86/intel_pmic_gpio.c
index d653104b59c..7bbb5388e56 100644
--- a/drivers/platform/x86/intel_pmic_gpio.c
+++ b/drivers/platform/x86/intel_pmic_gpio.c
@@ -74,6 +74,19 @@ struct pmic_gpio {
74 u32 trigger_type; 74 u32 trigger_type;
75}; 75};
76 76
77static void pmic_program_irqtype(int gpio, int type)
78{
79 if (type & IRQ_TYPE_EDGE_RISING)
80 intel_scu_ipc_update_register(GPIO0 + gpio, 0x20, 0x20);
81 else
82 intel_scu_ipc_update_register(GPIO0 + gpio, 0x00, 0x20);
83
84 if (type & IRQ_TYPE_EDGE_FALLING)
85 intel_scu_ipc_update_register(GPIO0 + gpio, 0x10, 0x10);
86 else
87 intel_scu_ipc_update_register(GPIO0 + gpio, 0x00, 0x10);
88};
89
77static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned offset) 90static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
78{ 91{
79 if (offset > 8) { 92 if (offset > 8) {
@@ -166,16 +179,38 @@ static int pmic_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
166 return pg->irq_base + offset; 179 return pg->irq_base + offset;
167} 180}
168 181
182static void pmic_bus_lock(struct irq_data *data)
183{
184 struct pmic_gpio *pg = irq_data_get_irq_chip_data(data);
185
186 mutex_lock(&pg->buslock);
187}
188
189static void pmic_bus_sync_unlock(struct irq_data *data)
190{
191 struct pmic_gpio *pg = irq_data_get_irq_chip_data(data);
192
193 if (pg->update_type) {
194 unsigned int gpio = pg->update_type & ~GPIO_UPDATE_TYPE;
195
196 pmic_program_irqtype(gpio, pg->trigger_type);
197 pg->update_type = 0;
198 }
199 mutex_unlock(&pg->buslock);
200}
201
169/* the gpiointr register is read-clear, so just do nothing. */ 202/* the gpiointr register is read-clear, so just do nothing. */
170static void pmic_irq_unmask(struct irq_data *data) { } 203static void pmic_irq_unmask(struct irq_data *data) { }
171 204
172static void pmic_irq_mask(struct irq_data *data) { } 205static void pmic_irq_mask(struct irq_data *data) { }
173 206
174static struct irq_chip pmic_irqchip = { 207static struct irq_chip pmic_irqchip = {
175 .name = "PMIC-GPIO", 208 .name = "PMIC-GPIO",
176 .irq_mask = pmic_irq_mask, 209 .irq_mask = pmic_irq_mask,
177 .irq_unmask = pmic_irq_unmask, 210 .irq_unmask = pmic_irq_unmask,
178 .irq_set_type = pmic_irq_type, 211 .irq_set_type = pmic_irq_type,
212 .irq_bus_lock = pmic_irq_buslock,
213 .irq_bus_sync_unlock = pmic_bus_sync_unlock,
179}; 214};
180 215
181static irqreturn_t pmic_irq_handler(int irq, void *data) 216static irqreturn_t pmic_irq_handler(int irq, void *data)
diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c
index de434c6dc2d..d347116d150 100644
--- a/drivers/platform/x86/samsung-laptop.c
+++ b/drivers/platform/x86/samsung-laptop.c
@@ -571,6 +571,16 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = {
571 .callback = dmi_check_cb, 571 .callback = dmi_check_cb,
572 }, 572 },
573 { 573 {
574 .ident = "R410 Plus",
575 .matches = {
576 DMI_MATCH(DMI_SYS_VENDOR,
577 "SAMSUNG ELECTRONICS CO., LTD."),
578 DMI_MATCH(DMI_PRODUCT_NAME, "R410P"),
579 DMI_MATCH(DMI_BOARD_NAME, "R460"),
580 },
581 .callback = dmi_check_cb,
582 },
583 {
574 .ident = "R518", 584 .ident = "R518",
575 .matches = { 585 .matches = {
576 DMI_MATCH(DMI_SYS_VENDOR, 586 DMI_MATCH(DMI_SYS_VENDOR,
@@ -591,12 +601,12 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = {
591 .callback = dmi_check_cb, 601 .callback = dmi_check_cb,
592 }, 602 },
593 { 603 {
594 .ident = "N150/N210/N220", 604 .ident = "N150/N210/N220/N230",
595 .matches = { 605 .matches = {
596 DMI_MATCH(DMI_SYS_VENDOR, 606 DMI_MATCH(DMI_SYS_VENDOR,
597 "SAMSUNG ELECTRONICS CO., LTD."), 607 "SAMSUNG ELECTRONICS CO., LTD."),
598 DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220"), 608 DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220/N230"),
599 DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220"), 609 DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220/N230"),
600 }, 610 },
601 .callback = dmi_check_cb, 611 .callback = dmi_check_cb,
602 }, 612 },
@@ -771,6 +781,7 @@ static int __init samsung_init(void)
771 781
772 /* create a backlight device to talk to this one */ 782 /* create a backlight device to talk to this one */
773 memset(&props, 0, sizeof(struct backlight_properties)); 783 memset(&props, 0, sizeof(struct backlight_properties));
784 props.type = BACKLIGHT_PLATFORM;
774 props.max_brightness = sabi_config->max_brightness; 785 props.max_brightness = sabi_config->max_brightness;
775 backlight_device = backlight_device_register("samsung", &sdev->dev, 786 backlight_device = backlight_device_register("samsung", &sdev->dev,
776 NULL, &backlight_ops, 787 NULL, &backlight_ops,
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index e642f5f2950..8f709aec4da 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -138,6 +138,8 @@ MODULE_PARM_DESC(kbd_backlight_timeout,
138 "1 for 30 seconds, 2 for 60 seconds and 3 to disable timeout " 138 "1 for 30 seconds, 2 for 60 seconds and 3 to disable timeout "
139 "(default: 0)"); 139 "(default: 0)");
140 140
141static void sony_nc_kbd_backlight_resume(void);
142
141enum sony_nc_rfkill { 143enum sony_nc_rfkill {
142 SONY_WIFI, 144 SONY_WIFI,
143 SONY_BLUETOOTH, 145 SONY_BLUETOOTH,
@@ -771,11 +773,6 @@ static int sony_nc_handles_setup(struct platform_device *pd)
771 if (!handles) 773 if (!handles)
772 return -ENOMEM; 774 return -ENOMEM;
773 775
774 sysfs_attr_init(&handles->devattr.attr);
775 handles->devattr.attr.name = "handles";
776 handles->devattr.attr.mode = S_IRUGO;
777 handles->devattr.show = sony_nc_handles_show;
778
779 for (i = 0; i < ARRAY_SIZE(handles->cap); i++) { 776 for (i = 0; i < ARRAY_SIZE(handles->cap); i++) {
780 if (!acpi_callsetfunc(sony_nc_acpi_handle, 777 if (!acpi_callsetfunc(sony_nc_acpi_handle,
781 "SN00", i + 0x20, &result)) { 778 "SN00", i + 0x20, &result)) {
@@ -785,11 +782,18 @@ static int sony_nc_handles_setup(struct platform_device *pd)
785 } 782 }
786 } 783 }
787 784
788 /* allow reading capabilities via sysfs */ 785 if (debug) {
789 if (device_create_file(&pd->dev, &handles->devattr)) { 786 sysfs_attr_init(&handles->devattr.attr);
790 kfree(handles); 787 handles->devattr.attr.name = "handles";
791 handles = NULL; 788 handles->devattr.attr.mode = S_IRUGO;
792 return -1; 789 handles->devattr.show = sony_nc_handles_show;
790
791 /* allow reading capabilities via sysfs */
792 if (device_create_file(&pd->dev, &handles->devattr)) {
793 kfree(handles);
794 handles = NULL;
795 return -1;
796 }
793 } 797 }
794 798
795 return 0; 799 return 0;
@@ -798,7 +802,8 @@ static int sony_nc_handles_setup(struct platform_device *pd)
798static int sony_nc_handles_cleanup(struct platform_device *pd) 802static int sony_nc_handles_cleanup(struct platform_device *pd)
799{ 803{
800 if (handles) { 804 if (handles) {
801 device_remove_file(&pd->dev, &handles->devattr); 805 if (debug)
806 device_remove_file(&pd->dev, &handles->devattr);
802 kfree(handles); 807 kfree(handles);
803 handles = NULL; 808 handles = NULL;
804 } 809 }
@@ -808,6 +813,11 @@ static int sony_nc_handles_cleanup(struct platform_device *pd)
808static int sony_find_snc_handle(int handle) 813static int sony_find_snc_handle(int handle)
809{ 814{
810 int i; 815 int i;
816
817 /* not initialized yet, return early */
818 if (!handles)
819 return -1;
820
811 for (i = 0; i < 0x10; i++) { 821 for (i = 0; i < 0x10; i++) {
812 if (handles->cap[i] == handle) { 822 if (handles->cap[i] == handle) {
813 dprintk("found handle 0x%.4x (offset: 0x%.2x)\n", 823 dprintk("found handle 0x%.4x (offset: 0x%.2x)\n",
@@ -1168,6 +1178,9 @@ static int sony_nc_resume(struct acpi_device *device)
1168 /* re-read rfkill state */ 1178 /* re-read rfkill state */
1169 sony_nc_rfkill_update(); 1179 sony_nc_rfkill_update();
1170 1180
1181 /* restore kbd backlight states */
1182 sony_nc_kbd_backlight_resume();
1183
1171 return 0; 1184 return 0;
1172} 1185}
1173 1186
@@ -1355,6 +1368,7 @@ out_no_enum:
1355#define KBDBL_HANDLER 0x137 1368#define KBDBL_HANDLER 0x137
1356#define KBDBL_PRESENT 0xB00 1369#define KBDBL_PRESENT 0xB00
1357#define SET_MODE 0xC00 1370#define SET_MODE 0xC00
1371#define SET_STATE 0xD00
1358#define SET_TIMEOUT 0xE00 1372#define SET_TIMEOUT 0xE00
1359 1373
1360struct kbd_backlight { 1374struct kbd_backlight {
@@ -1377,6 +1391,10 @@ static ssize_t __sony_nc_kbd_backlight_mode_set(u8 value)
1377 (value << 0x10) | SET_MODE, &result)) 1391 (value << 0x10) | SET_MODE, &result))
1378 return -EIO; 1392 return -EIO;
1379 1393
1394 /* Try to turn the light on/off immediately */
1395 sony_call_snc_handle(KBDBL_HANDLER, (value << 0x10) | SET_STATE,
1396 &result);
1397
1380 kbdbl_handle->mode = value; 1398 kbdbl_handle->mode = value;
1381 1399
1382 return 0; 1400 return 0;
@@ -1458,7 +1476,7 @@ static int sony_nc_kbd_backlight_setup(struct platform_device *pd)
1458{ 1476{
1459 int result; 1477 int result;
1460 1478
1461 if (sony_call_snc_handle(0x137, KBDBL_PRESENT, &result)) 1479 if (sony_call_snc_handle(KBDBL_HANDLER, KBDBL_PRESENT, &result))
1462 return 0; 1480 return 0;
1463 if (!(result & 0x02)) 1481 if (!(result & 0x02))
1464 return 0; 1482 return 0;
@@ -1501,13 +1519,36 @@ outkzalloc:
1501static int sony_nc_kbd_backlight_cleanup(struct platform_device *pd) 1519static int sony_nc_kbd_backlight_cleanup(struct platform_device *pd)
1502{ 1520{
1503 if (kbdbl_handle) { 1521 if (kbdbl_handle) {
1522 int result;
1523
1504 device_remove_file(&pd->dev, &kbdbl_handle->mode_attr); 1524 device_remove_file(&pd->dev, &kbdbl_handle->mode_attr);
1505 device_remove_file(&pd->dev, &kbdbl_handle->timeout_attr); 1525 device_remove_file(&pd->dev, &kbdbl_handle->timeout_attr);
1526
1527 /* restore the default hw behaviour */
1528 sony_call_snc_handle(KBDBL_HANDLER, 0x1000 | SET_MODE, &result);
1529 sony_call_snc_handle(KBDBL_HANDLER, SET_TIMEOUT, &result);
1530
1506 kfree(kbdbl_handle); 1531 kfree(kbdbl_handle);
1507 } 1532 }
1508 return 0; 1533 return 0;
1509} 1534}
1510 1535
1536static void sony_nc_kbd_backlight_resume(void)
1537{
1538 int ignore = 0;
1539
1540 if (!kbdbl_handle)
1541 return;
1542
1543 if (kbdbl_handle->mode == 0)
1544 sony_call_snc_handle(KBDBL_HANDLER, SET_MODE, &ignore);
1545
1546 if (kbdbl_handle->timeout != 0)
1547 sony_call_snc_handle(KBDBL_HANDLER,
1548 (kbdbl_handle->timeout << 0x10) | SET_TIMEOUT,
1549 &ignore);
1550}
1551
1511static void sony_nc_backlight_setup(void) 1552static void sony_nc_backlight_setup(void)
1512{ 1553{
1513 acpi_handle unused; 1554 acpi_handle unused;
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index a08561f5349..efb3b6b9bcd 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -8618,8 +8618,7 @@ static bool __pure __init tpacpi_is_valid_fw_id(const char* const s,
8618 tpacpi_is_fw_digit(s[1]) && 8618 tpacpi_is_fw_digit(s[1]) &&
8619 s[2] == t && s[3] == 'T' && 8619 s[2] == t && s[3] == 'T' &&
8620 tpacpi_is_fw_digit(s[4]) && 8620 tpacpi_is_fw_digit(s[4]) &&
8621 tpacpi_is_fw_digit(s[5]) && 8621 tpacpi_is_fw_digit(s[5]);
8622 s[6] == 'W' && s[7] == 'W';
8623} 8622}
8624 8623
8625/* returns 0 - probe ok, or < 0 - probe error. 8624/* returns 0 - probe ok, or < 0 - probe error.
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index dca4a0bb6ca..e3786f161bc 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -131,8 +131,6 @@ source "drivers/staging/wlags49_h2/Kconfig"
131 131
132source "drivers/staging/wlags49_h25/Kconfig" 132source "drivers/staging/wlags49_h25/Kconfig"
133 133
134source "drivers/staging/samsung-laptop/Kconfig"
135
136source "drivers/staging/sm7xx/Kconfig" 134source "drivers/staging/sm7xx/Kconfig"
137 135
138source "drivers/staging/dt3155v4l/Kconfig" 136source "drivers/staging/dt3155v4l/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index eb93012b6f5..f0d5c531561 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -48,7 +48,6 @@ obj-$(CONFIG_XVMALLOC) += zram/
48obj-$(CONFIG_ZCACHE) += zcache/ 48obj-$(CONFIG_ZCACHE) += zcache/
49obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ 49obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/
50obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/ 50obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/
51obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop/
52obj-$(CONFIG_FB_SM7XX) += sm7xx/ 51obj-$(CONFIG_FB_SM7XX) += sm7xx/
53obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/ 52obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/
54obj-$(CONFIG_CRYSTALHD) += crystalhd/ 53obj-$(CONFIG_CRYSTALHD) += crystalhd/
diff --git a/drivers/staging/samsung-laptop/Kconfig b/drivers/staging/samsung-laptop/Kconfig
deleted file mode 100644
index f27c60864c2..00000000000
--- a/drivers/staging/samsung-laptop/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
1config SAMSUNG_LAPTOP
2 tristate "Samsung Laptop driver"
3 default n
4 depends on RFKILL && BACKLIGHT_CLASS_DEVICE && X86
5 help
6 This module implements a driver for the N128 Samsung Laptop
7 providing control over the Wireless LED and the LCD backlight
8
9 To compile this driver as a module, choose
10 M here: the module will be called samsung-laptop.
diff --git a/drivers/staging/samsung-laptop/Makefile b/drivers/staging/samsung-laptop/Makefile
deleted file mode 100644
index 3c6f4204521..00000000000
--- a/drivers/staging/samsung-laptop/Makefile
+++ /dev/null
@@ -1 +0,0 @@
1obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop.o
diff --git a/drivers/staging/samsung-laptop/TODO b/drivers/staging/samsung-laptop/TODO
deleted file mode 100644
index f7a6d589916..00000000000
--- a/drivers/staging/samsung-laptop/TODO
+++ /dev/null
@@ -1,5 +0,0 @@
1TODO:
2 - review from other developers
3 - figure out ACPI video issues
4
5Please send patches to Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c
deleted file mode 100644
index 25294462b8b..00000000000
--- a/drivers/staging/samsung-laptop/samsung-laptop.c
+++ /dev/null
@@ -1,843 +0,0 @@
1/*
2 * Samsung Laptop driver
3 *
4 * Copyright (C) 2009,2011 Greg Kroah-Hartman (gregkh@suse.de)
5 * Copyright (C) 2009,2011 Novell Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 *
11 */
12#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/delay.h>
18#include <linux/pci.h>
19#include <linux/backlight.h>
20#include <linux/fb.h>
21#include <linux/dmi.h>
22#include <linux/platform_device.h>
23#include <linux/rfkill.h>
24
25/*
26 * This driver is needed because a number of Samsung laptops do not hook
27 * their control settings through ACPI. So we have to poke around in the
28 * BIOS to do things like brightness values, and "special" key controls.
29 */
30
31/*
32 * We have 0 - 8 as valid brightness levels. The specs say that level 0 should
33 * be reserved by the BIOS (which really doesn't make much sense), we tell
34 * userspace that the value is 0 - 7 and then just tell the hardware 1 - 8
35 */
36#define MAX_BRIGHT 0x07
37
38
39#define SABI_IFACE_MAIN 0x00
40#define SABI_IFACE_SUB 0x02
41#define SABI_IFACE_COMPLETE 0x04
42#define SABI_IFACE_DATA 0x05
43
44/* Structure to get data back to the calling function */
45struct sabi_retval {
46 u8 retval[20];
47};
48
49struct sabi_header_offsets {
50 u8 port;
51 u8 re_mem;
52 u8 iface_func;
53 u8 en_mem;
54 u8 data_offset;
55 u8 data_segment;
56};
57
58struct sabi_commands {
59 /*
60 * Brightness is 0 - 8, as described above.
61 * Value 0 is for the BIOS to use
62 */
63 u8 get_brightness;
64 u8 set_brightness;
65
66 /*
67 * first byte:
68 * 0x00 - wireless is off
69 * 0x01 - wireless is on
70 * second byte:
71 * 0x02 - 3G is off
72 * 0x03 - 3G is on
73 * TODO, verify 3G is correct, that doesn't seem right...
74 */
75 u8 get_wireless_button;
76 u8 set_wireless_button;
77
78 /* 0 is off, 1 is on */
79 u8 get_backlight;
80 u8 set_backlight;
81
82 /*
83 * 0x80 or 0x00 - no action
84 * 0x81 - recovery key pressed
85 */
86 u8 get_recovery_mode;
87 u8 set_recovery_mode;
88
89 /*
90 * on seclinux: 0 is low, 1 is high,
91 * on swsmi: 0 is normal, 1 is silent, 2 is turbo
92 */
93 u8 get_performance_level;
94 u8 set_performance_level;
95
96 /*
97 * Tell the BIOS that Linux is running on this machine.
98 * 81 is on, 80 is off
99 */
100 u8 set_linux;
101};
102
103struct sabi_performance_level {
104 const char *name;
105 u8 value;
106};
107
108struct sabi_config {
109 const char *test_string;
110 u16 main_function;
111 const struct sabi_header_offsets header_offsets;
112 const struct sabi_commands commands;
113 const struct sabi_performance_level performance_levels[4];
114 u8 min_brightness;
115 u8 max_brightness;
116};
117
118static const struct sabi_config sabi_configs[] = {
119 {
120 .test_string = "SECLINUX",
121
122 .main_function = 0x4c49,
123
124 .header_offsets = {
125 .port = 0x00,
126 .re_mem = 0x02,
127 .iface_func = 0x03,
128 .en_mem = 0x04,
129 .data_offset = 0x05,
130 .data_segment = 0x07,
131 },
132
133 .commands = {
134 .get_brightness = 0x00,
135 .set_brightness = 0x01,
136
137 .get_wireless_button = 0x02,
138 .set_wireless_button = 0x03,
139
140 .get_backlight = 0x04,
141 .set_backlight = 0x05,
142
143 .get_recovery_mode = 0x06,
144 .set_recovery_mode = 0x07,
145
146 .get_performance_level = 0x08,
147 .set_performance_level = 0x09,
148
149 .set_linux = 0x0a,
150 },
151
152 .performance_levels = {
153 {
154 .name = "silent",
155 .value = 0,
156 },
157 {
158 .name = "normal",
159 .value = 1,
160 },
161 { },
162 },
163 .min_brightness = 1,
164 .max_brightness = 8,
165 },
166 {
167 .test_string = "SwSmi@",
168
169 .main_function = 0x5843,
170
171 .header_offsets = {
172 .port = 0x00,
173 .re_mem = 0x04,
174 .iface_func = 0x02,
175 .en_mem = 0x03,
176 .data_offset = 0x05,
177 .data_segment = 0x07,
178 },
179
180 .commands = {
181 .get_brightness = 0x10,
182 .set_brightness = 0x11,
183
184 .get_wireless_button = 0x12,
185 .set_wireless_button = 0x13,
186
187 .get_backlight = 0x2d,
188 .set_backlight = 0x2e,
189
190 .get_recovery_mode = 0xff,
191 .set_recovery_mode = 0xff,
192
193 .get_performance_level = 0x31,
194 .set_performance_level = 0x32,
195
196 .set_linux = 0xff,
197 },
198
199 .performance_levels = {
200 {
201 .name = "normal",
202 .value = 0,
203 },
204 {
205 .name = "silent",
206 .value = 1,
207 },
208 {
209 .name = "overclock",
210 .value = 2,
211 },
212 { },
213 },
214 .min_brightness = 0,
215 .max_brightness = 8,
216 },
217 { },
218};
219
220static const struct sabi_config *sabi_config;
221
222static void __iomem *sabi;
223static void __iomem *sabi_iface;
224static void __iomem *f0000_segment;
225static struct backlight_device *backlight_device;
226static struct mutex sabi_mutex;
227static struct platform_device *sdev;
228static struct rfkill *rfk;
229
230static int force;
231module_param(force, bool, 0);
232MODULE_PARM_DESC(force,
233 "Disable the DMI check and forces the driver to be loaded");
234
235static int debug;
236module_param(debug, bool, S_IRUGO | S_IWUSR);
237MODULE_PARM_DESC(debug, "Debug enabled or not");
238
239static int sabi_get_command(u8 command, struct sabi_retval *sretval)
240{
241 int retval = 0;
242 u16 port = readw(sabi + sabi_config->header_offsets.port);
243 u8 complete, iface_data;
244
245 mutex_lock(&sabi_mutex);
246
247 /* enable memory to be able to write to it */
248 outb(readb(sabi + sabi_config->header_offsets.en_mem), port);
249
250 /* write out the command */
251 writew(sabi_config->main_function, sabi_iface + SABI_IFACE_MAIN);
252 writew(command, sabi_iface + SABI_IFACE_SUB);
253 writeb(0, sabi_iface + SABI_IFACE_COMPLETE);
254 outb(readb(sabi + sabi_config->header_offsets.iface_func), port);
255
256 /* write protect memory to make it safe */
257 outb(readb(sabi + sabi_config->header_offsets.re_mem), port);
258
259 /* see if the command actually succeeded */
260 complete = readb(sabi_iface + SABI_IFACE_COMPLETE);
261 iface_data = readb(sabi_iface + SABI_IFACE_DATA);
262 if (complete != 0xaa || iface_data == 0xff) {
263 pr_warn("SABI get command 0x%02x failed with completion flag 0x%02x and data 0x%02x\n",
264 command, complete, iface_data);
265 retval = -EINVAL;
266 goto exit;
267 }
268 /*
269 * Save off the data into a structure so the caller use it.
270 * Right now we only want the first 4 bytes,
271 * There are commands that need more, but not for the ones we
272 * currently care about.
273 */
274 sretval->retval[0] = readb(sabi_iface + SABI_IFACE_DATA);
275 sretval->retval[1] = readb(sabi_iface + SABI_IFACE_DATA + 1);
276 sretval->retval[2] = readb(sabi_iface + SABI_IFACE_DATA + 2);
277 sretval->retval[3] = readb(sabi_iface + SABI_IFACE_DATA + 3);
278
279exit:
280 mutex_unlock(&sabi_mutex);
281 return retval;
282
283}
284
285static int sabi_set_command(u8 command, u8 data)
286{
287 int retval = 0;
288 u16 port = readw(sabi + sabi_config->header_offsets.port);
289 u8 complete, iface_data;
290
291 mutex_lock(&sabi_mutex);
292
293 /* enable memory to be able to write to it */
294 outb(readb(sabi + sabi_config->header_offsets.en_mem), port);
295
296 /* write out the command */
297 writew(sabi_config->main_function, sabi_iface + SABI_IFACE_MAIN);
298 writew(command, sabi_iface + SABI_IFACE_SUB);
299 writeb(0, sabi_iface + SABI_IFACE_COMPLETE);
300 writeb(data, sabi_iface + SABI_IFACE_DATA);
301 outb(readb(sabi + sabi_config->header_offsets.iface_func), port);
302
303 /* write protect memory to make it safe */
304 outb(readb(sabi + sabi_config->header_offsets.re_mem), port);
305
306 /* see if the command actually succeeded */
307 complete = readb(sabi_iface + SABI_IFACE_COMPLETE);
308 iface_data = readb(sabi_iface + SABI_IFACE_DATA);
309 if (complete != 0xaa || iface_data == 0xff) {
310 pr_warn("SABI set command 0x%02x failed with completion flag 0x%02x and data 0x%02x\n",
311 command, complete, iface_data);
312 retval = -EINVAL;
313 }
314
315 mutex_unlock(&sabi_mutex);
316 return retval;
317}
318
319static void test_backlight(void)
320{
321 struct sabi_retval sretval;
322
323 sabi_get_command(sabi_config->commands.get_backlight, &sretval);
324 printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]);
325
326 sabi_set_command(sabi_config->commands.set_backlight, 0);
327 printk(KERN_DEBUG "backlight should be off\n");
328
329 sabi_get_command(sabi_config->commands.get_backlight, &sretval);
330 printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]);
331
332 msleep(1000);
333
334 sabi_set_command(sabi_config->commands.set_backlight, 1);
335 printk(KERN_DEBUG "backlight should be on\n");
336
337 sabi_get_command(sabi_config->commands.get_backlight, &sretval);
338 printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]);
339}
340
341static void test_wireless(void)
342{
343 struct sabi_retval sretval;
344
345 sabi_get_command(sabi_config->commands.get_wireless_button, &sretval);
346 printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]);
347
348 sabi_set_command(sabi_config->commands.set_wireless_button, 0);
349 printk(KERN_DEBUG "wireless led should be off\n");
350
351 sabi_get_command(sabi_config->commands.get_wireless_button, &sretval);
352 printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]);
353
354 msleep(1000);
355
356 sabi_set_command(sabi_config->commands.set_wireless_button, 1);
357 printk(KERN_DEBUG "wireless led should be on\n");
358
359 sabi_get_command(sabi_config->commands.get_wireless_button, &sretval);
360 printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]);
361}
362
363static u8 read_brightness(void)
364{
365 struct sabi_retval sretval;
366 int user_brightness = 0;
367 int retval;
368
369 retval = sabi_get_command(sabi_config->commands.get_brightness,
370 &sretval);
371 if (!retval) {
372 user_brightness = sretval.retval[0];
373 if (user_brightness != 0)
374 user_brightness -= sabi_config->min_brightness;
375 }
376 return user_brightness;
377}
378
379static void set_brightness(u8 user_brightness)
380{
381 u8 user_level = user_brightness - sabi_config->min_brightness;
382
383 sabi_set_command(sabi_config->commands.set_brightness, user_level);
384}
385
386static int get_brightness(struct backlight_device *bd)
387{
388 return (int)read_brightness();
389}
390
391static int update_status(struct backlight_device *bd)
392{
393 set_brightness(bd->props.brightness);
394
395 if (bd->props.power == FB_BLANK_UNBLANK)
396 sabi_set_command(sabi_config->commands.set_backlight, 1);
397 else
398 sabi_set_command(sabi_config->commands.set_backlight, 0);
399 return 0;
400}
401
402static const struct backlight_ops backlight_ops = {
403 .get_brightness = get_brightness,
404 .update_status = update_status,
405};
406
407static int rfkill_set(void *data, bool blocked)
408{
409 /* Do something with blocked...*/
410 /*
411 * blocked == false is on
412 * blocked == true is off
413 */
414 if (blocked)
415 sabi_set_command(sabi_config->commands.set_wireless_button, 0);
416 else
417 sabi_set_command(sabi_config->commands.set_wireless_button, 1);
418
419 return 0;
420}
421
422static struct rfkill_ops rfkill_ops = {
423 .set_block = rfkill_set,
424};
425
426static int init_wireless(struct platform_device *sdev)
427{
428 int retval;
429
430 rfk = rfkill_alloc("samsung-wifi", &sdev->dev, RFKILL_TYPE_WLAN,
431 &rfkill_ops, NULL);
432 if (!rfk)
433 return -ENOMEM;
434
435 retval = rfkill_register(rfk);
436 if (retval) {
437 rfkill_destroy(rfk);
438 return -ENODEV;
439 }
440
441 return 0;
442}
443
444static void destroy_wireless(void)
445{
446 rfkill_unregister(rfk);
447 rfkill_destroy(rfk);
448}
449
450static ssize_t get_performance_level(struct device *dev,
451 struct device_attribute *attr, char *buf)
452{
453 struct sabi_retval sretval;
454 int retval;
455 int i;
456
457 /* Read the state */
458 retval = sabi_get_command(sabi_config->commands.get_performance_level,
459 &sretval);
460 if (retval)
461 return retval;
462
463 /* The logic is backwards, yeah, lots of fun... */
464 for (i = 0; sabi_config->performance_levels[i].name; ++i) {
465 if (sretval.retval[0] == sabi_config->performance_levels[i].value)
466 return sprintf(buf, "%s\n", sabi_config->performance_levels[i].name);
467 }
468 return sprintf(buf, "%s\n", "unknown");
469}
470
471static ssize_t set_performance_level(struct device *dev,
472 struct device_attribute *attr, const char *buf,
473 size_t count)
474{
475 if (count >= 1) {
476 int i;
477 for (i = 0; sabi_config->performance_levels[i].name; ++i) {
478 const struct sabi_performance_level *level =
479 &sabi_config->performance_levels[i];
480 if (!strncasecmp(level->name, buf, strlen(level->name))) {
481 sabi_set_command(sabi_config->commands.set_performance_level,
482 level->value);
483 break;
484 }
485 }
486 if (!sabi_config->performance_levels[i].name)
487 return -EINVAL;
488 }
489 return count;
490}
491static DEVICE_ATTR(performance_level, S_IWUSR | S_IRUGO,
492 get_performance_level, set_performance_level);
493
494
495static int __init dmi_check_cb(const struct dmi_system_id *id)
496{
497 pr_info("found laptop model '%s'\n",
498 id->ident);
499 return 0;
500}
501
502static struct dmi_system_id __initdata samsung_dmi_table[] = {
503 {
504 .ident = "N128",
505 .matches = {
506 DMI_MATCH(DMI_SYS_VENDOR,
507 "SAMSUNG ELECTRONICS CO., LTD."),
508 DMI_MATCH(DMI_PRODUCT_NAME, "N128"),
509 DMI_MATCH(DMI_BOARD_NAME, "N128"),
510 },
511 .callback = dmi_check_cb,
512 },
513 {
514 .ident = "N130",
515 .matches = {
516 DMI_MATCH(DMI_SYS_VENDOR,
517 "SAMSUNG ELECTRONICS CO., LTD."),
518 DMI_MATCH(DMI_PRODUCT_NAME, "N130"),
519 DMI_MATCH(DMI_BOARD_NAME, "N130"),
520 },
521 .callback = dmi_check_cb,
522 },
523 {
524 .ident = "X125",
525 .matches = {
526 DMI_MATCH(DMI_SYS_VENDOR,
527 "SAMSUNG ELECTRONICS CO., LTD."),
528 DMI_MATCH(DMI_PRODUCT_NAME, "X125"),
529 DMI_MATCH(DMI_BOARD_NAME, "X125"),
530 },
531 .callback = dmi_check_cb,
532 },
533 {
534 .ident = "X120/X170",
535 .matches = {
536 DMI_MATCH(DMI_SYS_VENDOR,
537 "SAMSUNG ELECTRONICS CO., LTD."),
538 DMI_MATCH(DMI_PRODUCT_NAME, "X120/X170"),
539 DMI_MATCH(DMI_BOARD_NAME, "X120/X170"),
540 },
541 .callback = dmi_check_cb,
542 },
543 {
544 .ident = "NC10",
545 .matches = {
546 DMI_MATCH(DMI_SYS_VENDOR,
547 "SAMSUNG ELECTRONICS CO., LTD."),
548 DMI_MATCH(DMI_PRODUCT_NAME, "NC10"),
549 DMI_MATCH(DMI_BOARD_NAME, "NC10"),
550 },
551 .callback = dmi_check_cb,
552 },
553 {
554 .ident = "NP-Q45",
555 .matches = {
556 DMI_MATCH(DMI_SYS_VENDOR,
557 "SAMSUNG ELECTRONICS CO., LTD."),
558 DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"),
559 DMI_MATCH(DMI_BOARD_NAME, "SQ45S70S"),
560 },
561 .callback = dmi_check_cb,
562 },
563 {
564 .ident = "X360",
565 .matches = {
566 DMI_MATCH(DMI_SYS_VENDOR,
567 "SAMSUNG ELECTRONICS CO., LTD."),
568 DMI_MATCH(DMI_PRODUCT_NAME, "X360"),
569 DMI_MATCH(DMI_BOARD_NAME, "X360"),
570 },
571 .callback = dmi_check_cb,
572 },
573 {
574 .ident = "R410 Plus",
575 .matches = {
576 DMI_MATCH(DMI_SYS_VENDOR,
577 "SAMSUNG ELECTRONICS CO., LTD."),
578 DMI_MATCH(DMI_PRODUCT_NAME, "R410P"),
579 DMI_MATCH(DMI_BOARD_NAME, "R460"),
580 },
581 .callback = dmi_check_cb,
582 },
583 {
584 .ident = "R518",
585 .matches = {
586 DMI_MATCH(DMI_SYS_VENDOR,
587 "SAMSUNG ELECTRONICS CO., LTD."),
588 DMI_MATCH(DMI_PRODUCT_NAME, "R518"),
589 DMI_MATCH(DMI_BOARD_NAME, "R518"),
590 },
591 .callback = dmi_check_cb,
592 },
593 {
594 .ident = "R519/R719",
595 .matches = {
596 DMI_MATCH(DMI_SYS_VENDOR,
597 "SAMSUNG ELECTRONICS CO., LTD."),
598 DMI_MATCH(DMI_PRODUCT_NAME, "R519/R719"),
599 DMI_MATCH(DMI_BOARD_NAME, "R519/R719"),
600 },
601 .callback = dmi_check_cb,
602 },
603 {
604 .ident = "N150/N210/N220/N230",
605 .matches = {
606 DMI_MATCH(DMI_SYS_VENDOR,
607 "SAMSUNG ELECTRONICS CO., LTD."),
608 DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220/N230"),
609 DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220/N230"),
610 },
611 .callback = dmi_check_cb,
612 },
613 {
614 .ident = "N150P/N210P/N220P",
615 .matches = {
616 DMI_MATCH(DMI_SYS_VENDOR,
617 "SAMSUNG ELECTRONICS CO., LTD."),
618 DMI_MATCH(DMI_PRODUCT_NAME, "N150P/N210P/N220P"),
619 DMI_MATCH(DMI_BOARD_NAME, "N150P/N210P/N220P"),
620 },
621 .callback = dmi_check_cb,
622 },
623 {
624 .ident = "R530/R730",
625 .matches = {
626 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
627 DMI_MATCH(DMI_PRODUCT_NAME, "R530/R730"),
628 DMI_MATCH(DMI_BOARD_NAME, "R530/R730"),
629 },
630 .callback = dmi_check_cb,
631 },
632 {
633 .ident = "NF110/NF210/NF310",
634 .matches = {
635 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
636 DMI_MATCH(DMI_PRODUCT_NAME, "NF110/NF210/NF310"),
637 DMI_MATCH(DMI_BOARD_NAME, "NF110/NF210/NF310"),
638 },
639 .callback = dmi_check_cb,
640 },
641 {
642 .ident = "N145P/N250P/N260P",
643 .matches = {
644 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
645 DMI_MATCH(DMI_PRODUCT_NAME, "N145P/N250P/N260P"),
646 DMI_MATCH(DMI_BOARD_NAME, "N145P/N250P/N260P"),
647 },
648 .callback = dmi_check_cb,
649 },
650 {
651 .ident = "R70/R71",
652 .matches = {
653 DMI_MATCH(DMI_SYS_VENDOR,
654 "SAMSUNG ELECTRONICS CO., LTD."),
655 DMI_MATCH(DMI_PRODUCT_NAME, "R70/R71"),
656 DMI_MATCH(DMI_BOARD_NAME, "R70/R71"),
657 },
658 .callback = dmi_check_cb,
659 },
660 {
661 .ident = "P460",
662 .matches = {
663 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
664 DMI_MATCH(DMI_PRODUCT_NAME, "P460"),
665 DMI_MATCH(DMI_BOARD_NAME, "P460"),
666 },
667 .callback = dmi_check_cb,
668 },
669 { },
670};
671MODULE_DEVICE_TABLE(dmi, samsung_dmi_table);
672
673static int find_signature(void __iomem *memcheck, const char *testStr)
674{
675 int i = 0;
676 int loca;
677
678 for (loca = 0; loca < 0xffff; loca++) {
679 char temp = readb(memcheck + loca);
680
681 if (temp == testStr[i]) {
682 if (i == strlen(testStr)-1)
683 break;
684 ++i;
685 } else {
686 i = 0;
687 }
688 }
689 return loca;
690}
691
692static int __init samsung_init(void)
693{
694 struct backlight_properties props;
695 struct sabi_retval sretval;
696 unsigned int ifaceP;
697 int i;
698 int loca;
699 int retval;
700
701 mutex_init(&sabi_mutex);
702
703 if (!force && !dmi_check_system(samsung_dmi_table))
704 return -ENODEV;
705
706 f0000_segment = ioremap_nocache(0xf0000, 0xffff);
707 if (!f0000_segment) {
708 pr_err("Can't map the segment at 0xf0000\n");
709 return -EINVAL;
710 }
711
712 /* Try to find one of the signatures in memory to find the header */
713 for (i = 0; sabi_configs[i].test_string != 0; ++i) {
714 sabi_config = &sabi_configs[i];
715 loca = find_signature(f0000_segment, sabi_config->test_string);
716 if (loca != 0xffff)
717 break;
718 }
719
720 if (loca == 0xffff) {
721 pr_err("This computer does not support SABI\n");
722 goto error_no_signature;
723 }
724
725 /* point to the SMI port Number */
726 loca += 1;
727 sabi = (f0000_segment + loca);
728
729 if (debug) {
730 printk(KERN_DEBUG "This computer supports SABI==%x\n",
731 loca + 0xf0000 - 6);
732 printk(KERN_DEBUG "SABI header:\n");
733 printk(KERN_DEBUG " SMI Port Number = 0x%04x\n",
734 readw(sabi + sabi_config->header_offsets.port));
735 printk(KERN_DEBUG " SMI Interface Function = 0x%02x\n",
736 readb(sabi + sabi_config->header_offsets.iface_func));
737 printk(KERN_DEBUG " SMI enable memory buffer = 0x%02x\n",
738 readb(sabi + sabi_config->header_offsets.en_mem));
739 printk(KERN_DEBUG " SMI restore memory buffer = 0x%02x\n",
740 readb(sabi + sabi_config->header_offsets.re_mem));
741 printk(KERN_DEBUG " SABI data offset = 0x%04x\n",
742 readw(sabi + sabi_config->header_offsets.data_offset));
743 printk(KERN_DEBUG " SABI data segment = 0x%04x\n",
744 readw(sabi + sabi_config->header_offsets.data_segment));
745 }
746
747 /* Get a pointer to the SABI Interface */
748 ifaceP = (readw(sabi + sabi_config->header_offsets.data_segment) & 0x0ffff) << 4;
749 ifaceP += readw(sabi + sabi_config->header_offsets.data_offset) & 0x0ffff;
750 sabi_iface = ioremap_nocache(ifaceP, 16);
751 if (!sabi_iface) {
752 pr_err("Can't remap %x\n", ifaceP);
753 goto exit;
754 }
755 if (debug) {
756 printk(KERN_DEBUG "ifaceP = 0x%08x\n", ifaceP);
757 printk(KERN_DEBUG "sabi_iface = %p\n", sabi_iface);
758
759 test_backlight();
760 test_wireless();
761
762 retval = sabi_get_command(sabi_config->commands.get_brightness,
763 &sretval);
764 printk(KERN_DEBUG "brightness = 0x%02x\n", sretval.retval[0]);
765 }
766
767 /* Turn on "Linux" mode in the BIOS */
768 if (sabi_config->commands.set_linux != 0xff) {
769 retval = sabi_set_command(sabi_config->commands.set_linux,
770 0x81);
771 if (retval) {
772 pr_warn("Linux mode was not set!\n");
773 goto error_no_platform;
774 }
775 }
776
777 /* knock up a platform device to hang stuff off of */
778 sdev = platform_device_register_simple("samsung", -1, NULL, 0);
779 if (IS_ERR(sdev))
780 goto error_no_platform;
781
782 /* create a backlight device to talk to this one */
783 memset(&props, 0, sizeof(struct backlight_properties));
784 props.type = BACKLIGHT_PLATFORM;
785 props.max_brightness = sabi_config->max_brightness;
786 backlight_device = backlight_device_register("samsung", &sdev->dev,
787 NULL, &backlight_ops,
788 &props);
789 if (IS_ERR(backlight_device))
790 goto error_no_backlight;
791
792 backlight_device->props.brightness = read_brightness();
793 backlight_device->props.power = FB_BLANK_UNBLANK;
794 backlight_update_status(backlight_device);
795
796 retval = init_wireless(sdev);
797 if (retval)
798 goto error_no_rfk;
799
800 retval = device_create_file(&sdev->dev, &dev_attr_performance_level);
801 if (retval)
802 goto error_file_create;
803
804exit:
805 return 0;
806
807error_file_create:
808 destroy_wireless();
809
810error_no_rfk:
811 backlight_device_unregister(backlight_device);
812
813error_no_backlight:
814 platform_device_unregister(sdev);
815
816error_no_platform:
817 iounmap(sabi_iface);
818
819error_no_signature:
820 iounmap(f0000_segment);
821 return -EINVAL;
822}
823
824static void __exit samsung_exit(void)
825{
826 /* Turn off "Linux" mode in the BIOS */
827 if (sabi_config->commands.set_linux != 0xff)
828 sabi_set_command(sabi_config->commands.set_linux, 0x80);
829
830 device_remove_file(&sdev->dev, &dev_attr_performance_level);
831 backlight_device_unregister(backlight_device);
832 destroy_wireless();
833 iounmap(sabi_iface);
834 iounmap(f0000_segment);
835 platform_device_unregister(sdev);
836}
837
838module_init(samsung_init);
839module_exit(samsung_exit);
840
841MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@suse.de>");
842MODULE_DESCRIPTION("Samsung Backlight driver");
843MODULE_LICENSE("GPL");
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 42d6c930cc8..33167b43ac7 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -912,8 +912,7 @@ int bind_evtchn_to_irqhandler(unsigned int evtchn,
912 unsigned long irqflags, 912 unsigned long irqflags,
913 const char *devname, void *dev_id) 913 const char *devname, void *dev_id)
914{ 914{
915 unsigned int irq; 915 int irq, retval;
916 int retval;
917 916
918 irq = bind_evtchn_to_irq(evtchn); 917 irq = bind_evtchn_to_irq(evtchn);
919 if (irq < 0) 918 if (irq < 0)
@@ -955,8 +954,7 @@ int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu,
955 irq_handler_t handler, 954 irq_handler_t handler,
956 unsigned long irqflags, const char *devname, void *dev_id) 955 unsigned long irqflags, const char *devname, void *dev_id)
957{ 956{
958 unsigned int irq; 957 int irq, retval;
959 int retval;
960 958
961 irq = bind_virq_to_irq(virq, cpu); 959 irq = bind_virq_to_irq(virq, cpu);
962 if (irq < 0) 960 if (irq < 0)
diff --git a/fs/namespace.c b/fs/namespace.c
index 7dba2ed0342..d99bcf59e4c 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1030,18 +1030,6 @@ const struct seq_operations mounts_op = {
1030 .show = show_vfsmnt 1030 .show = show_vfsmnt
1031}; 1031};
1032 1032
1033static int uuid_is_nil(u8 *uuid)
1034{
1035 int i;
1036 u8 *cp = (u8 *)uuid;
1037
1038 for (i = 0; i < 16; i++) {
1039 if (*cp++)
1040 return 0;
1041 }
1042 return 1;
1043}
1044
1045static int show_mountinfo(struct seq_file *m, void *v) 1033static int show_mountinfo(struct seq_file *m, void *v)
1046{ 1034{
1047 struct proc_mounts *p = m->private; 1035 struct proc_mounts *p = m->private;
@@ -1085,10 +1073,6 @@ static int show_mountinfo(struct seq_file *m, void *v)
1085 if (IS_MNT_UNBINDABLE(mnt)) 1073 if (IS_MNT_UNBINDABLE(mnt))
1086 seq_puts(m, " unbindable"); 1074 seq_puts(m, " unbindable");
1087 1075
1088 if (!uuid_is_nil(mnt->mnt_sb->s_uuid))
1089 /* print the uuid */
1090 seq_printf(m, " uuid:%pU", mnt->mnt_sb->s_uuid);
1091
1092 /* Filesystem specific data */ 1076 /* Filesystem specific data */
1093 seq_puts(m, " - "); 1077 seq_puts(m, " - ");
1094 show_type(m, sb); 1078 show_type(m, sb);
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index af0c6279a4a..e4cbc11a74a 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -542,11 +542,15 @@ nfs_scan_commit(struct inode *inode, struct list_head *dst, pgoff_t idx_start, u
542 if (!nfs_need_commit(nfsi)) 542 if (!nfs_need_commit(nfsi))
543 return 0; 543 return 0;
544 544
545 spin_lock(&inode->i_lock);
545 ret = nfs_scan_list(nfsi, dst, idx_start, npages, NFS_PAGE_TAG_COMMIT); 546 ret = nfs_scan_list(nfsi, dst, idx_start, npages, NFS_PAGE_TAG_COMMIT);
546 if (ret > 0) 547 if (ret > 0)
547 nfsi->ncommit -= ret; 548 nfsi->ncommit -= ret;
549 spin_unlock(&inode->i_lock);
550
548 if (nfs_need_commit(NFS_I(inode))) 551 if (nfs_need_commit(NFS_I(inode)))
549 __mark_inode_dirty(inode, I_DIRTY_DATASYNC); 552 __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
553
550 return ret; 554 return ret;
551} 555}
552#else 556#else
@@ -1483,9 +1487,7 @@ int nfs_commit_inode(struct inode *inode, int how)
1483 res = nfs_commit_set_lock(NFS_I(inode), may_wait); 1487 res = nfs_commit_set_lock(NFS_I(inode), may_wait);
1484 if (res <= 0) 1488 if (res <= 0)
1485 goto out_mark_dirty; 1489 goto out_mark_dirty;
1486 spin_lock(&inode->i_lock);
1487 res = nfs_scan_commit(inode, &head, 0, 0); 1490 res = nfs_scan_commit(inode, &head, 0, 0);
1488 spin_unlock(&inode->i_lock);
1489 if (res) { 1491 if (res) {
1490 int error; 1492 int error;
1491 1493
diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h
index ad1b19aa650..aef23309a74 100644
--- a/include/linux/mfd/core.h
+++ b/include/linux/mfd/core.h
@@ -86,16 +86,25 @@ extern int mfd_clone_cell(const char *cell, const char **clones,
86 */ 86 */
87static inline const struct mfd_cell *mfd_get_cell(struct platform_device *pdev) 87static inline const struct mfd_cell *mfd_get_cell(struct platform_device *pdev)
88{ 88{
89 return pdev->dev.platform_data; 89 return pdev->mfd_cell;
90} 90}
91 91
92/* 92/*
93 * Given a platform device that's been created by mfd_add_devices(), fetch 93 * Given a platform device that's been created by mfd_add_devices(), fetch
94 * the .mfd_data entry from the mfd_cell that created it. 94 * the .mfd_data entry from the mfd_cell that created it.
95 * Otherwise just return the platform_data pointer.
96 * This maintains compatibility with platform drivers whose devices aren't
97 * created by the mfd layer, and expect platform_data to contain what would've
98 * otherwise been in mfd_data.
95 */ 99 */
96static inline void *mfd_get_data(struct platform_device *pdev) 100static inline void *mfd_get_data(struct platform_device *pdev)
97{ 101{
98 return mfd_get_cell(pdev)->mfd_data; 102 const struct mfd_cell *cell = mfd_get_cell(pdev);
103
104 if (cell)
105 return cell->mfd_data;
106 else
107 return pdev->dev.platform_data;
99} 108}
100 109
101extern int mfd_add_devices(struct device *parent, int id, 110extern int mfd_add_devices(struct device *parent, int id,
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index d96db982570..744942c95fe 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -14,6 +14,8 @@
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/mod_devicetable.h> 15#include <linux/mod_devicetable.h>
16 16
17struct mfd_cell;
18
17struct platform_device { 19struct platform_device {
18 const char * name; 20 const char * name;
19 int id; 21 int id;
@@ -23,6 +25,9 @@ struct platform_device {
23 25
24 const struct platform_device_id *id_entry; 26 const struct platform_device_id *id_entry;
25 27
28 /* MFD cell pointer */
29 struct mfd_cell *mfd_cell;
30
26 /* arch specific additions */ 31 /* arch specific additions */
27 struct pdev_archdata archdata; 32 struct pdev_archdata archdata;
28}; 33};
diff --git a/mm/memory.c b/mm/memory.c
index 9da8cab1b1b..b623a249918 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1410,6 +1410,13 @@ no_page_table:
1410 return page; 1410 return page;
1411} 1411}
1412 1412
1413static inline int stack_guard_page(struct vm_area_struct *vma, unsigned long addr)
1414{
1415 return (vma->vm_flags & VM_GROWSDOWN) &&
1416 (vma->vm_start == addr) &&
1417 !vma_stack_continue(vma->vm_prev, addr);
1418}
1419
1413/** 1420/**
1414 * __get_user_pages() - pin user pages in memory 1421 * __get_user_pages() - pin user pages in memory
1415 * @tsk: task_struct of target task 1422 * @tsk: task_struct of target task
@@ -1488,7 +1495,6 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
1488 vma = find_extend_vma(mm, start); 1495 vma = find_extend_vma(mm, start);
1489 if (!vma && in_gate_area(mm, start)) { 1496 if (!vma && in_gate_area(mm, start)) {
1490 unsigned long pg = start & PAGE_MASK; 1497 unsigned long pg = start & PAGE_MASK;
1491 struct vm_area_struct *gate_vma = get_gate_vma(mm);
1492 pgd_t *pgd; 1498 pgd_t *pgd;
1493 pud_t *pud; 1499 pud_t *pud;
1494 pmd_t *pmd; 1500 pmd_t *pmd;
@@ -1513,10 +1519,11 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
1513 pte_unmap(pte); 1519 pte_unmap(pte);
1514 return i ? : -EFAULT; 1520 return i ? : -EFAULT;
1515 } 1521 }
1522 vma = get_gate_vma(mm);
1516 if (pages) { 1523 if (pages) {
1517 struct page *page; 1524 struct page *page;
1518 1525
1519 page = vm_normal_page(gate_vma, start, *pte); 1526 page = vm_normal_page(vma, start, *pte);
1520 if (!page) { 1527 if (!page) {
1521 if (!(gup_flags & FOLL_DUMP) && 1528 if (!(gup_flags & FOLL_DUMP) &&
1522 is_zero_pfn(pte_pfn(*pte))) 1529 is_zero_pfn(pte_pfn(*pte)))
@@ -1530,12 +1537,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
1530 get_page(page); 1537 get_page(page);
1531 } 1538 }
1532 pte_unmap(pte); 1539 pte_unmap(pte);
1533 if (vmas) 1540 goto next_page;
1534 vmas[i] = gate_vma;
1535 i++;
1536 start += PAGE_SIZE;
1537 nr_pages--;
1538 continue;
1539 } 1541 }
1540 1542
1541 if (!vma || 1543 if (!vma ||
@@ -1549,6 +1551,13 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
1549 continue; 1551 continue;
1550 } 1552 }
1551 1553
1554 /*
1555 * If we don't actually want the page itself,
1556 * and it's the stack guard page, just skip it.
1557 */
1558 if (!pages && stack_guard_page(vma, start))
1559 goto next_page;
1560
1552 do { 1561 do {
1553 struct page *page; 1562 struct page *page;
1554 unsigned int foll_flags = gup_flags; 1563 unsigned int foll_flags = gup_flags;
@@ -1631,6 +1640,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
1631 flush_anon_page(vma, page, start); 1640 flush_anon_page(vma, page, start);
1632 flush_dcache_page(page); 1641 flush_dcache_page(page);
1633 } 1642 }
1643next_page:
1634 if (vmas) 1644 if (vmas)
1635 vmas[i] = vma; 1645 vmas[i] = vma;
1636 i++; 1646 i++;
diff --git a/mm/mlock.c b/mm/mlock.c
index 2689a08c79a..6b55e3efe0d 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -135,13 +135,6 @@ void munlock_vma_page(struct page *page)
135 } 135 }
136} 136}
137 137
138static inline int stack_guard_page(struct vm_area_struct *vma, unsigned long addr)
139{
140 return (vma->vm_flags & VM_GROWSDOWN) &&
141 (vma->vm_start == addr) &&
142 !vma_stack_continue(vma->vm_prev, addr);
143}
144
145/** 138/**
146 * __mlock_vma_pages_range() - mlock a range of pages in the vma. 139 * __mlock_vma_pages_range() - mlock a range of pages in the vma.
147 * @vma: target vma 140 * @vma: target vma
@@ -188,12 +181,6 @@ static long __mlock_vma_pages_range(struct vm_area_struct *vma,
188 if (vma->vm_flags & VM_LOCKED) 181 if (vma->vm_flags & VM_LOCKED)
189 gup_flags |= FOLL_MLOCK; 182 gup_flags |= FOLL_MLOCK;
190 183
191 /* We don't try to access the guard page of a stack vma */
192 if (stack_guard_page(vma, start)) {
193 addr += PAGE_SIZE;
194 nr_pages--;
195 }
196
197 return __get_user_pages(current, mm, addr, nr_pages, gup_flags, 184 return __get_user_pages(current, mm, addr, nr_pages, gup_flags,
198 NULL, NULL, nonblocking); 185 NULL, NULL, nonblocking);
199} 186}