From 42c25013ca95ce79b4ed192188ca843ae48f8c71 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 12 Apr 2016 10:00:34 +0200 Subject: [PATCH 1/3] Revert "gpio: rcar: Add Runtime PM handling for interrupts" This reverts commit b26a719bdba9aa926ceaadecc66e07623d2b8a53. --- drivers/gpio/gpio-rcar.c | 42 ---------------------------------------- 1 file changed, 42 deletions(-) diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index d9ab0cd1d205..cf41440aff91 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -196,44 +196,6 @@ static int gpio_rcar_irq_set_wake(struct irq_data *d, unsigned int on) return 0; } -static void gpio_rcar_irq_bus_lock(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct gpio_rcar_priv *p = gpiochip_get_data(gc); - - pm_runtime_get_sync(&p->pdev->dev); -} - -static void gpio_rcar_irq_bus_sync_unlock(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct gpio_rcar_priv *p = gpiochip_get_data(gc); - - pm_runtime_put(&p->pdev->dev); -} - - -static int gpio_rcar_irq_request_resources(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct gpio_rcar_priv *p = gpiochip_get_data(gc); - int error; - - error = pm_runtime_get_sync(&p->pdev->dev); - if (error < 0) - return error; - - return 0; -} - -static void gpio_rcar_irq_release_resources(struct irq_data *d) -{ - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct gpio_rcar_priv *p = gpiochip_get_data(gc); - - pm_runtime_put(&p->pdev->dev); -} - static irqreturn_t gpio_rcar_irq_handler(int irq, void *dev_id) { struct gpio_rcar_priv *p = dev_id; @@ -488,10 +450,6 @@ static int gpio_rcar_probe(struct platform_device *pdev) irq_chip->irq_unmask = gpio_rcar_irq_enable; irq_chip->irq_set_type = gpio_rcar_irq_set_type; irq_chip->irq_set_wake = gpio_rcar_irq_set_wake; - irq_chip->irq_bus_lock = gpio_rcar_irq_bus_lock; - irq_chip->irq_bus_sync_unlock = gpio_rcar_irq_bus_sync_unlock; - irq_chip->irq_request_resources = gpio_rcar_irq_request_resources; - irq_chip->irq_release_resources = gpio_rcar_irq_release_resources; irq_chip->flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_MASK_ON_SUSPEND; ret = gpiochip_add_data(gpio_chip, p); From ce0e2c60e69e5f87ab4ac10c935d8bd85d4d11f7 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 12 Apr 2016 10:05:22 +0200 Subject: [PATCH 2/3] Revert "gpio: rcar: Fine-grained Runtime PM support" This reverts commit 65194cb174b873448b208eb6e04ecb72237af76e. --- drivers/gpio/gpio-rcar.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index cf41440aff91..4d9a315cfd43 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -242,32 +242,18 @@ static void gpio_rcar_config_general_input_output_mode(struct gpio_chip *chip, static int gpio_rcar_request(struct gpio_chip *chip, unsigned offset) { - struct gpio_rcar_priv *p = gpiochip_get_data(chip); - int error; - - error = pm_runtime_get_sync(&p->pdev->dev); - if (error < 0) - return error; - - error = pinctrl_request_gpio(chip->base + offset); - if (error) - pm_runtime_put(&p->pdev->dev); - - return error; + return pinctrl_request_gpio(chip->base + offset); } static void gpio_rcar_free(struct gpio_chip *chip, unsigned offset) { - struct gpio_rcar_priv *p = gpiochip_get_data(chip); - pinctrl_free_gpio(chip->base + offset); - /* Set the GPIO as an input to ensure that the next GPIO request won't + /* + * Set the GPIO as an input to ensure that the next GPIO request won't * drive the GPIO pin as an output. */ gpio_rcar_config_general_input_output_mode(chip, offset, false); - - pm_runtime_put(&p->pdev->dev); } static int gpio_rcar_direction_input(struct gpio_chip *chip, unsigned offset) @@ -414,6 +400,7 @@ static int gpio_rcar_probe(struct platform_device *pdev) } pm_runtime_enable(dev); + pm_runtime_get_sync(dev); io = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); @@ -480,6 +467,7 @@ static int gpio_rcar_probe(struct platform_device *pdev) err1: gpiochip_remove(gpio_chip); err0: + pm_runtime_put(dev); pm_runtime_disable(dev); return ret; } @@ -490,6 +478,7 @@ static int gpio_rcar_remove(struct platform_device *pdev) gpiochip_remove(&p->gpio_chip); + pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); return 0; } From 7df89e92a56a3d2c8f84aa76c61471e4a7bc24f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 25 Apr 2016 16:01:19 +0300 Subject: [PATCH 3/3] gpiolib-acpi: Duplicate con_id string when adding it to the crs lookup list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Calling gpiod_get() from a module and then unloading the module leads to an oops due to acpi_can_fallback_to_crs() storing the pointer to the passed 'con_id' string onto acpi_crs_lookup_list. The next guy to come along will then try to access the string but the memory may now be gone with the module. Make a copy of the passed string instead, and store the copy on the list. BUG: unable to handle kernel paging request at ffffffffa03e7855 IP: [] strcmp+0x12/0x30 PGD 2a07067 PUD 2a08063 PMD 74720067 PTE 0 Oops: 0000 [#1] PREEMPT SMP Modules linked in: i915(+) drm_kms_helper drm intel_gtt snd_hda_codec snd_hda_core i2c_algo_bit syscopya rea sysfillrect sysimgblt fb_sys_fops agpgart snd_soc_sst_bytcr_rt5640 coretemp hwmon intel_rapl intel_soc_dts_thermal punit_atom_debug snd_soc_rt5640 snd_soc_rl6231 serio snd_intel_sst_acpi snd_intel_sst_core video snd_soc_sst_mfld_platf orm snd_soc_sst_match backlight int3402_thermal processor_thermal_device int3403_thermal int3400_thermal acpi_thermal_r el snd_soc_core intel_soc_dts_iosf int340x_thermal_zone snd_compress i2c_hid hid snd_pcm snd_timer snd soundcore evdev sch_fq_codel efivarfs ipv6 autofs4 [last unloaded: drm] CPU: 2 PID: 3064 Comm: modprobe Tainted: G U W 4.6.0-rc3-ffrd-ipvr+ #302 Hardware name: Intel Corp. VALLEYVIEW C0 PLATFORM/BYT-T FFD8, BIOS BLAKFF81.X64.0088.R10.1403240443 FFD8 _X64_R_2014_13_1_00 03/24/2014 task: ffff8800701cd200 ti: ffff880070034000 task.ti: ffff880070034000 RIP: 0010:[] [] strcmp+0x12/0x30 RSP: 0000:ffff880070037748 EFLAGS: 00010286 RAX: 0000000080000000 RBX: ffff88007a342800 RCX: 0000000000000006 RDX: 0000000000000006 RSI: ffffffffa054f856 RDI: ffffffffa03e7856 RBP: ffff880070037748 R08: 0000000000000000 R09: 0000000000000001 R10: 0000000000000000 R11: 0000000000000000 R12: ffffffffa054f855 R13: ffff88007281cae0 R14: 0000000000000010 R15: ffffffffffffffea FS: 00007faa51447700(0000) GS:ffff880079300000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffffffa03e7855 CR3: 0000000041eba000 CR4: 00000000001006e0 Stack: ffff880070037770 ffffffff8136ad28 ffffffffa054f855 0000000000000000 ffff88007a0a2098 ffff8800700377e8 ffffffff8136852e ffff88007a342800 00000007700377a0 ffff8800700377a0 ffffffff81412442 70672d6c656e6170 Call Trace: [] acpi_can_fallback_to_crs+0x88/0x100 [] gpiod_get_index+0x25e/0x310 [] ? mipi_dsi_attach+0x22/0x30 [] gpiod_get+0x12/0x20 [] intel_dsi_init+0x421/0x480 [i915] [] intel_modeset_init+0x853/0x16b0 [i915] [] ? intel_setup_gmbus+0x214/0x260 [i915] [] i915_driver_load+0xdc8/0x19b0 [i915] [] ? _raw_spin_unlock_irqrestore+0x43/0x70 [] drm_dev_register+0xab/0xc0 [drm] [] drm_get_pci_dev+0x93/0x1f0 [drm] [] ? _raw_spin_unlock_irqrestore+0x43/0x70 [] i915_pci_probe+0x34/0x50 [i915] [] pci_device_probe+0x91/0x100 [] driver_probe_device+0x20a/0x2d0 [] __driver_attach+0x9e/0xb0 [] ? driver_probe_device+0x2d0/0x2d0 [] bus_for_each_dev+0x69/0xa0 [] driver_attach+0x1e/0x20 [] bus_add_driver+0x1c0/0x240 [] driver_register+0x60/0xe0 [] __pci_register_driver+0x60/0x70 [] drm_pci_init+0xe4/0x110 [drm] [] ? trace_hardirqs_on+0xe/0x10 [] ? 0xffffffffa02f1000 [] i915_init+0x94/0x9b [i915] [] do_one_initcall+0x8b/0x1c0 [] ? rcu_read_lock_sched_held+0x86/0x90 [] ? kmem_cache_alloc_trace+0x1f6/0x270 [] do_init_module+0x60/0x1dc [] load_module+0x1d0d/0x2390 [] ? __symbol_put+0x70/0x70 [] ? kernel_read_file+0x92/0x120 [] SYSC_finit_module+0xa4/0xb0 [] SyS_finit_module+0xe/0x10 [] do_syscall_64+0x63/0x350 [] entry_SYSCALL64_slow_path+0x25/0x25 Code: f7 48 8d 76 01 48 8d 52 01 0f b6 4e ff 84 c9 88 4a ff 75 ed 5d c3 0f 1f 00 55 48 89 e5 eb 04 84 c0 74 18 48 8d 7f 01 48 8d 76 01 <0f> b6 47 ff 3a 46 ff 74 eb 19 c0 83 c8 01 5d c3 31 c0 5d c3 66 RIP [] strcmp+0x12/0x30 RSP CR2: ffffffffa03e7855 v2: Make the copied con_id const Cc: Dmitry Torokhov Cc: Mika Westerberg Cc: Alexandre Courbot Cc: stable@vger.kernel.org Fixes: 10cf4899f8af ("gpiolib: tighten up ACPI legacy gpio lookups") Signed-off-by: Ville Syrjälä Acked-by: Mika Westerberg Reviewed-by: Dmitry Torokhov Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 682070d20f00..2dc52585e3f2 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -977,7 +977,7 @@ bool acpi_can_fallback_to_crs(struct acpi_device *adev, const char *con_id) lookup = kmalloc(sizeof(*lookup), GFP_KERNEL); if (lookup) { lookup->adev = adev; - lookup->con_id = con_id; + lookup->con_id = kstrdup(con_id, GFP_KERNEL); list_add_tail(&lookup->node, &acpi_crs_lookup_list); } }