diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-14 12:08:00 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-14 12:08:00 -0500 |
| commit | 822e5215f9eef86c1dd56d5696bf55a212b0e3f0 (patch) | |
| tree | 661de9888a0edef872e7366df09831bf7a5bc067 | |
| parent | c1e0d97d3d63d5173baf8c39a13dc5c25b031bd4 (diff) | |
| parent | 92d50a4132977b932ed830fa58c05deeb5c524f0 (diff) | |
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6
* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6: (59 commits)
mfd: ab8500-core chip version cut 2.0 support
mfd: Flag WM831x /IRQ as a wake source
mfd: Convert WM831x away from legacy I2C PM operations
regulator: Support MAX8998/LP3974 DVS-GPIO
mfd: Support LP3974 RTC
i2c: Convert SCx200 driver from using raw PCI to platform device
x86: OLPC: convert olpc-xo1 driver from pci device to platform device
mfd: MAX8998/LP3974 hibernation support
mfd/ab8500: remove spi support
mfd: Remove ARCH_U8500 dependency from AB8500
misc: Make AB8500_PWM driver depend on U8500 due to PWM breakage
mfd: Add __devexit annotation for vx855_remove
mfd: twl6030 irq_data conversion.
gpio: Fix cs5535 printk warnings
misc: Fix cs5535 printk warnings
mfd: Convert Wolfson MFD drivers to use irq_data accessor function
mfd: Convert TWL4030 to new irq_ APIs
mfd: Convert tps6586x driver to new irq_ API
mfd: Convert tc6393xb driver to new irq_ APIs
mfd: Convert t7166xb driver to new irq_ API
...
48 files changed, 1806 insertions, 1354 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 36ed2e2c896b..50aa81f2ffc4 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -2068,7 +2068,7 @@ config OLPC | |||
| 2068 | 2068 | ||
| 2069 | config OLPC_XO1 | 2069 | config OLPC_XO1 |
| 2070 | tristate "OLPC XO-1 support" | 2070 | tristate "OLPC XO-1 support" |
| 2071 | depends on OLPC && PCI | 2071 | depends on OLPC && MFD_CS5535 |
| 2072 | ---help--- | 2072 | ---help--- |
| 2073 | Add support for non-essential features of the OLPC XO-1 laptop. | 2073 | Add support for non-essential features of the OLPC XO-1 laptop. |
| 2074 | 2074 | ||
diff --git a/arch/x86/platform/olpc/olpc-xo1.c b/arch/x86/platform/olpc/olpc-xo1.c index f5442c03abc3..127775696d6c 100644 --- a/arch/x86/platform/olpc/olpc-xo1.c +++ b/arch/x86/platform/olpc/olpc-xo1.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Support for features of the OLPC XO-1 laptop | 2 | * Support for features of the OLPC XO-1 laptop |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2010 Andres Salomon <dilinger@queued.net> | ||
| 4 | * Copyright (C) 2010 One Laptop per Child | 5 | * Copyright (C) 2010 One Laptop per Child |
| 5 | * Copyright (C) 2006 Red Hat, Inc. | 6 | * Copyright (C) 2006 Red Hat, Inc. |
| 6 | * Copyright (C) 2006 Advanced Micro Devices, Inc. | 7 | * Copyright (C) 2006 Advanced Micro Devices, Inc. |
| @@ -12,8 +13,6 @@ | |||
| 12 | */ | 13 | */ |
| 13 | 14 | ||
| 14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 15 | #include <linux/pci.h> | ||
| 16 | #include <linux/pci_ids.h> | ||
| 17 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
| 18 | #include <linux/pm.h> | 17 | #include <linux/pm.h> |
| 19 | 18 | ||
| @@ -22,9 +21,6 @@ | |||
| 22 | 21 | ||
| 23 | #define DRV_NAME "olpc-xo1" | 22 | #define DRV_NAME "olpc-xo1" |
| 24 | 23 | ||
| 25 | #define PMS_BAR 4 | ||
| 26 | #define ACPI_BAR 5 | ||
| 27 | |||
| 28 | /* PMC registers (PMS block) */ | 24 | /* PMC registers (PMS block) */ |
| 29 | #define PM_SCLK 0x10 | 25 | #define PM_SCLK 0x10 |
| 30 | #define PM_IN_SLPCTL 0x20 | 26 | #define PM_IN_SLPCTL 0x20 |
| @@ -57,65 +53,67 @@ static void xo1_power_off(void) | |||
| 57 | outl(0x00002000, acpi_base + PM1_CNT); | 53 | outl(0x00002000, acpi_base + PM1_CNT); |
| 58 | } | 54 | } |
| 59 | 55 | ||
| 60 | /* Read the base addresses from the PCI BAR info */ | 56 | static int __devinit olpc_xo1_probe(struct platform_device *pdev) |
| 61 | static int __devinit setup_bases(struct pci_dev *pdev) | ||
| 62 | { | 57 | { |
| 63 | int r; | 58 | struct resource *res; |
| 64 | 59 | ||
| 65 | r = pci_enable_device_io(pdev); | 60 | /* don't run on non-XOs */ |
| 66 | if (r) { | 61 | if (!machine_is_olpc()) |
| 67 | dev_err(&pdev->dev, "can't enable device IO\n"); | 62 | return -ENODEV; |
| 68 | return r; | ||
| 69 | } | ||
| 70 | 63 | ||
| 71 | r = pci_request_region(pdev, ACPI_BAR, DRV_NAME); | 64 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 72 | if (r) { | 65 | if (!res) { |
| 73 | dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", ACPI_BAR); | 66 | dev_err(&pdev->dev, "can't fetch device resource info\n"); |
| 74 | return r; | 67 | return -EIO; |
| 75 | } | 68 | } |
| 76 | 69 | ||
| 77 | r = pci_request_region(pdev, PMS_BAR, DRV_NAME); | 70 | if (!request_region(res->start, resource_size(res), DRV_NAME)) { |
| 78 | if (r) { | 71 | dev_err(&pdev->dev, "can't request region\n"); |
| 79 | dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", PMS_BAR); | 72 | return -EIO; |
| 80 | pci_release_region(pdev, ACPI_BAR); | ||
| 81 | return r; | ||
| 82 | } | 73 | } |
| 83 | 74 | ||
| 84 | acpi_base = pci_resource_start(pdev, ACPI_BAR); | 75 | if (strcmp(pdev->name, "cs5535-pms") == 0) |
| 85 | pms_base = pci_resource_start(pdev, PMS_BAR); | 76 | pms_base = res->start; |
| 77 | else if (strcmp(pdev->name, "cs5535-acpi") == 0) | ||
| 78 | acpi_base = res->start; | ||
| 79 | |||
| 80 | /* If we have both addresses, we can override the poweroff hook */ | ||
| 81 | if (pms_base && acpi_base) { | ||
| 82 | pm_power_off = xo1_power_off; | ||
| 83 | printk(KERN_INFO "OLPC XO-1 support registered\n"); | ||
| 84 | } | ||
| 86 | 85 | ||
| 87 | return 0; | 86 | return 0; |
| 88 | } | 87 | } |
| 89 | 88 | ||
| 90 | static int __devinit olpc_xo1_probe(struct platform_device *pdev) | 89 | static int __devexit olpc_xo1_remove(struct platform_device *pdev) |
| 91 | { | 90 | { |
| 92 | struct pci_dev *pcidev; | 91 | struct resource *r; |
| 93 | int r; | ||
| 94 | |||
| 95 | pcidev = pci_get_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, | ||
| 96 | NULL); | ||
| 97 | if (!pdev) | ||
| 98 | return -ENODEV; | ||
| 99 | |||
| 100 | r = setup_bases(pcidev); | ||
| 101 | if (r) | ||
| 102 | return r; | ||
| 103 | 92 | ||
| 104 | pm_power_off = xo1_power_off; | 93 | r = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 94 | release_region(r->start, resource_size(r)); | ||
| 105 | 95 | ||
| 106 | printk(KERN_INFO "OLPC XO-1 support registered\n"); | 96 | if (strcmp(pdev->name, "cs5535-pms") == 0) |
| 107 | return 0; | 97 | pms_base = 0; |
| 108 | } | 98 | else if (strcmp(pdev->name, "cs5535-acpi") == 0) |
| 99 | acpi_base = 0; | ||
| 109 | 100 | ||
| 110 | static int __devexit olpc_xo1_remove(struct platform_device *pdev) | ||
| 111 | { | ||
| 112 | pm_power_off = NULL; | 101 | pm_power_off = NULL; |
| 113 | return 0; | 102 | return 0; |
| 114 | } | 103 | } |
| 115 | 104 | ||
| 116 | static struct platform_driver olpc_xo1_driver = { | 105 | static struct platform_driver cs5535_pms_drv = { |
| 106 | .driver = { | ||
| 107 | .name = "cs5535-pms", | ||
| 108 | .owner = THIS_MODULE, | ||
| 109 | }, | ||
| 110 | .probe = olpc_xo1_probe, | ||
| 111 | .remove = __devexit_p(olpc_xo1_remove), | ||
| 112 | }; | ||
| 113 | |||
| 114 | static struct platform_driver cs5535_acpi_drv = { | ||
| 117 | .driver = { | 115 | .driver = { |
| 118 | .name = DRV_NAME, | 116 | .name = "cs5535-acpi", |
| 119 | .owner = THIS_MODULE, | 117 | .owner = THIS_MODULE, |
| 120 | }, | 118 | }, |
| 121 | .probe = olpc_xo1_probe, | 119 | .probe = olpc_xo1_probe, |
| @@ -124,12 +122,23 @@ static struct platform_driver olpc_xo1_driver = { | |||
| 124 | 122 | ||
| 125 | static int __init olpc_xo1_init(void) | 123 | static int __init olpc_xo1_init(void) |
| 126 | { | 124 | { |
| 127 | return platform_driver_register(&olpc_xo1_driver); | 125 | int r; |
| 126 | |||
| 127 | r = platform_driver_register(&cs5535_pms_drv); | ||
| 128 | if (r) | ||
| 129 | return r; | ||
| 130 | |||
| 131 | r = platform_driver_register(&cs5535_acpi_drv); | ||
| 132 | if (r) | ||
| 133 | platform_driver_unregister(&cs5535_pms_drv); | ||
| 134 | |||
| 135 | return r; | ||
| 128 | } | 136 | } |
| 129 | 137 | ||
| 130 | static void __exit olpc_xo1_exit(void) | 138 | static void __exit olpc_xo1_exit(void) |
| 131 | { | 139 | { |
| 132 | platform_driver_unregister(&olpc_xo1_driver); | 140 | platform_driver_unregister(&cs5535_acpi_drv); |
| 141 | platform_driver_unregister(&cs5535_pms_drv); | ||
| 133 | } | 142 | } |
| 134 | 143 | ||
| 135 | MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>"); | 144 | MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>"); |
diff --git a/drivers/gpio/cs5535-gpio.c b/drivers/gpio/cs5535-gpio.c index 815d98b2c1ba..0d05ea7d499b 100644 --- a/drivers/gpio/cs5535-gpio.c +++ b/drivers/gpio/cs5535-gpio.c | |||
| @@ -11,14 +11,13 @@ | |||
| 11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
| 12 | #include <linux/spinlock.h> | 12 | #include <linux/spinlock.h> |
| 13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| 14 | #include <linux/pci.h> | 14 | #include <linux/platform_device.h> |
| 15 | #include <linux/gpio.h> | 15 | #include <linux/gpio.h> |
| 16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
| 17 | #include <linux/cs5535.h> | 17 | #include <linux/cs5535.h> |
| 18 | #include <asm/msr.h> | 18 | #include <asm/msr.h> |
| 19 | 19 | ||
| 20 | #define DRV_NAME "cs5535-gpio" | 20 | #define DRV_NAME "cs5535-gpio" |
| 21 | #define GPIO_BAR 1 | ||
| 22 | 21 | ||
| 23 | /* | 22 | /* |
| 24 | * Some GPIO pins | 23 | * Some GPIO pins |
| @@ -47,7 +46,7 @@ static struct cs5535_gpio_chip { | |||
| 47 | struct gpio_chip chip; | 46 | struct gpio_chip chip; |
| 48 | resource_size_t base; | 47 | resource_size_t base; |
| 49 | 48 | ||
| 50 | struct pci_dev *pdev; | 49 | struct platform_device *pdev; |
| 51 | spinlock_t lock; | 50 | spinlock_t lock; |
| 52 | } cs5535_gpio_chip; | 51 | } cs5535_gpio_chip; |
| 53 | 52 | ||
| @@ -301,10 +300,10 @@ static struct cs5535_gpio_chip cs5535_gpio_chip = { | |||
| 301 | }, | 300 | }, |
| 302 | }; | 301 | }; |
| 303 | 302 | ||
| 304 | static int __init cs5535_gpio_probe(struct pci_dev *pdev, | 303 | static int __devinit cs5535_gpio_probe(struct platform_device *pdev) |
| 305 | const struct pci_device_id *pci_id) | ||
| 306 | { | 304 | { |
| 307 | int err; | 305 | struct resource *res; |
| 306 | int err = -EIO; | ||
| 308 | ulong mask_orig = mask; | 307 | ulong mask_orig = mask; |
| 309 | 308 | ||
| 310 | /* There are two ways to get the GPIO base address; one is by | 309 | /* There are two ways to get the GPIO base address; one is by |
| @@ -314,25 +313,23 @@ static int __init cs5535_gpio_probe(struct pci_dev *pdev, | |||
| 314 | * it turns out to be unreliable in the face of crappy BIOSes, we | 313 | * it turns out to be unreliable in the face of crappy BIOSes, we |
| 315 | * can always go back to using MSRs.. */ | 314 | * can always go back to using MSRs.. */ |
| 316 | 315 | ||
| 317 | err = pci_enable_device_io(pdev); | 316 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 318 | if (err) { | 317 | if (!res) { |
| 319 | dev_err(&pdev->dev, "can't enable device IO\n"); | 318 | dev_err(&pdev->dev, "can't fetch device resource info\n"); |
| 320 | goto done; | 319 | goto done; |
| 321 | } | 320 | } |
| 322 | 321 | ||
| 323 | err = pci_request_region(pdev, GPIO_BAR, DRV_NAME); | 322 | if (!request_region(res->start, resource_size(res), pdev->name)) { |
| 324 | if (err) { | 323 | dev_err(&pdev->dev, "can't request region\n"); |
| 325 | dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", GPIO_BAR); | ||
| 326 | goto done; | 324 | goto done; |
| 327 | } | 325 | } |
| 328 | 326 | ||
| 329 | /* set up the driver-specific struct */ | 327 | /* set up the driver-specific struct */ |
| 330 | cs5535_gpio_chip.base = pci_resource_start(pdev, GPIO_BAR); | 328 | cs5535_gpio_chip.base = res->start; |
| 331 | cs5535_gpio_chip.pdev = pdev; | 329 | cs5535_gpio_chip.pdev = pdev; |
| 332 | spin_lock_init(&cs5535_gpio_chip.lock); | 330 | spin_lock_init(&cs5535_gpio_chip.lock); |
| 333 | 331 | ||
| 334 | dev_info(&pdev->dev, "allocated PCI BAR #%d: base 0x%llx\n", GPIO_BAR, | 332 | dev_info(&pdev->dev, "reserved resource region %pR\n", res); |
| 335 | (unsigned long long) cs5535_gpio_chip.base); | ||
| 336 | 333 | ||
| 337 | /* mask out reserved pins */ | 334 | /* mask out reserved pins */ |
| 338 | mask &= 0x1F7FFFFF; | 335 | mask &= 0x1F7FFFFF; |
| @@ -350,78 +347,49 @@ static int __init cs5535_gpio_probe(struct pci_dev *pdev, | |||
| 350 | if (err) | 347 | if (err) |
| 351 | goto release_region; | 348 | goto release_region; |
| 352 | 349 | ||
| 353 | dev_info(&pdev->dev, DRV_NAME ": GPIO support successfully loaded.\n"); | 350 | dev_info(&pdev->dev, "GPIO support successfully loaded.\n"); |
| 354 | return 0; | 351 | return 0; |
| 355 | 352 | ||
| 356 | release_region: | 353 | release_region: |
| 357 | pci_release_region(pdev, GPIO_BAR); | 354 | release_region(res->start, resource_size(res)); |
| 358 | done: | 355 | done: |
| 359 | return err; | 356 | return err; |
| 360 | } | 357 | } |
| 361 | 358 | ||
| 362 | static void __exit cs5535_gpio_remove(struct pci_dev *pdev) | 359 | static int __devexit cs5535_gpio_remove(struct platform_device *pdev) |
| 363 | { | 360 | { |
| 361 | struct resource *r; | ||
| 364 | int err; | 362 | int err; |
| 365 | 363 | ||
| 366 | err = gpiochip_remove(&cs5535_gpio_chip.chip); | 364 | err = gpiochip_remove(&cs5535_gpio_chip.chip); |
| 367 | if (err) { | 365 | if (err) { |
| 368 | /* uhh? */ | 366 | /* uhh? */ |
| 369 | dev_err(&pdev->dev, "unable to remove gpio_chip?\n"); | 367 | dev_err(&pdev->dev, "unable to remove gpio_chip?\n"); |
| 368 | return err; | ||
| 370 | } | 369 | } |
| 371 | pci_release_region(pdev, GPIO_BAR); | ||
| 372 | } | ||
| 373 | |||
| 374 | static struct pci_device_id cs5535_gpio_pci_tbl[] = { | ||
| 375 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, | ||
| 376 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, | ||
| 377 | { 0, }, | ||
| 378 | }; | ||
| 379 | MODULE_DEVICE_TABLE(pci, cs5535_gpio_pci_tbl); | ||
| 380 | 370 | ||
| 381 | /* | 371 | r = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 382 | * We can't use the standard PCI driver registration stuff here, since | 372 | release_region(r->start, resource_size(r)); |
| 383 | * that allows only one driver to bind to each PCI device (and we want | 373 | return 0; |
| 384 | * multiple drivers to be able to bind to the device). Instead, manually | ||
| 385 | * scan for the PCI device, request a single region, and keep track of the | ||
| 386 | * devices that we're using. | ||
| 387 | */ | ||
| 388 | |||
| 389 | static int __init cs5535_gpio_scan_pci(void) | ||
| 390 | { | ||
| 391 | struct pci_dev *pdev; | ||
| 392 | int err = -ENODEV; | ||
| 393 | int i; | ||
| 394 | |||
| 395 | for (i = 0; i < ARRAY_SIZE(cs5535_gpio_pci_tbl); i++) { | ||
| 396 | pdev = pci_get_device(cs5535_gpio_pci_tbl[i].vendor, | ||
| 397 | cs5535_gpio_pci_tbl[i].device, NULL); | ||
| 398 | if (pdev) { | ||
| 399 | err = cs5535_gpio_probe(pdev, &cs5535_gpio_pci_tbl[i]); | ||
| 400 | if (err) | ||
| 401 | pci_dev_put(pdev); | ||
| 402 | |||
| 403 | /* we only support a single CS5535/6 southbridge */ | ||
| 404 | break; | ||
| 405 | } | ||
| 406 | } | ||
| 407 | |||
| 408 | return err; | ||
| 409 | } | 374 | } |
| 410 | 375 | ||
| 411 | static void __exit cs5535_gpio_free_pci(void) | 376 | static struct platform_driver cs5535_gpio_drv = { |
| 412 | { | 377 | .driver = { |
| 413 | cs5535_gpio_remove(cs5535_gpio_chip.pdev); | 378 | .name = DRV_NAME, |
| 414 | pci_dev_put(cs5535_gpio_chip.pdev); | 379 | .owner = THIS_MODULE, |
| 415 | } | 380 | }, |
| 381 | .probe = cs5535_gpio_probe, | ||
| 382 | .remove = __devexit_p(cs5535_gpio_remove), | ||
| 383 | }; | ||
| 416 | 384 | ||
| 417 | static int __init cs5535_gpio_init(void) | 385 | static int __init cs5535_gpio_init(void) |
| 418 | { | 386 | { |
| 419 | return cs5535_gpio_scan_pci(); | 387 | return platform_driver_register(&cs5535_gpio_drv); |
| 420 | } | 388 | } |
| 421 | 389 | ||
| 422 | static void __exit cs5535_gpio_exit(void) | 390 | static void __exit cs5535_gpio_exit(void) |
| 423 | { | 391 | { |
| 424 | cs5535_gpio_free_pci(); | 392 | platform_driver_unregister(&cs5535_gpio_drv); |
| 425 | } | 393 | } |
| 426 | 394 | ||
| 427 | module_init(cs5535_gpio_init); | 395 | module_init(cs5535_gpio_init); |
| @@ -430,3 +398,4 @@ module_exit(cs5535_gpio_exit); | |||
| 430 | MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>"); | 398 | MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>"); |
| 431 | MODULE_DESCRIPTION("AMD CS5535/CS5536 GPIO driver"); | 399 | MODULE_DESCRIPTION("AMD CS5535/CS5536 GPIO driver"); |
| 432 | MODULE_LICENSE("GPL"); | 400 | MODULE_LICENSE("GPL"); |
| 401 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index 53fab518b3da..986e5f62debe 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
| 30 | #include <linux/i2c.h> | 30 | #include <linux/i2c.h> |
| 31 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
| 32 | #include <linux/platform_device.h> | ||
| 32 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
| 33 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
| 34 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
| @@ -40,6 +41,7 @@ | |||
| 40 | 41 | ||
| 41 | MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>"); | 42 | MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>"); |
| 42 | MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver"); | 43 | MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver"); |
| 44 | MODULE_ALIAS("platform:cs5535-smb"); | ||
| 43 | MODULE_LICENSE("GPL"); | 45 | MODULE_LICENSE("GPL"); |
| 44 | 46 | ||
| 45 | #define MAX_DEVICES 4 | 47 | #define MAX_DEVICES 4 |
| @@ -84,10 +86,6 @@ struct scx200_acb_iface { | |||
| 84 | u8 *ptr; | 86 | u8 *ptr; |
| 85 | char needs_reset; | 87 | char needs_reset; |
| 86 | unsigned len; | 88 | unsigned len; |
| 87 | |||
| 88 | /* PCI device info */ | ||
| 89 | struct pci_dev *pdev; | ||
| 90 | int bar; | ||
| 91 | }; | 89 | }; |
| 92 | 90 | ||
| 93 | /* Register Definitions */ | 91 | /* Register Definitions */ |
| @@ -391,7 +389,7 @@ static const struct i2c_algorithm scx200_acb_algorithm = { | |||
| 391 | static struct scx200_acb_iface *scx200_acb_list; | 389 | static struct scx200_acb_iface *scx200_acb_list; |
| 392 | static DEFINE_MUTEX(scx200_acb_list_mutex); | 390 | static DEFINE_MUTEX(scx200_acb_list_mutex); |
| 393 | 391 | ||
| 394 | static __init int scx200_acb_probe(struct scx200_acb_iface *iface) | 392 | static __devinit int scx200_acb_probe(struct scx200_acb_iface *iface) |
| 395 | { | 393 | { |
| 396 | u8 val; | 394 | u8 val; |
| 397 | 395 | ||
| @@ -427,7 +425,7 @@ static __init int scx200_acb_probe(struct scx200_acb_iface *iface) | |||
| 427 | return 0; | 425 | return 0; |
| 428 | } | 426 | } |
| 429 | 427 | ||
| 430 | static __init struct scx200_acb_iface *scx200_create_iface(const char *text, | 428 | static __devinit struct scx200_acb_iface *scx200_create_iface(const char *text, |
| 431 | struct device *dev, int index) | 429 | struct device *dev, int index) |
| 432 | { | 430 | { |
| 433 | struct scx200_acb_iface *iface; | 431 | struct scx200_acb_iface *iface; |
| @@ -452,7 +450,7 @@ static __init struct scx200_acb_iface *scx200_create_iface(const char *text, | |||
| 452 | return iface; | 450 | return iface; |
| 453 | } | 451 | } |
| 454 | 452 | ||
| 455 | static int __init scx200_acb_create(struct scx200_acb_iface *iface) | 453 | static int __devinit scx200_acb_create(struct scx200_acb_iface *iface) |
| 456 | { | 454 | { |
| 457 | struct i2c_adapter *adapter; | 455 | struct i2c_adapter *adapter; |
| 458 | int rc; | 456 | int rc; |
| @@ -472,183 +470,145 @@ static int __init scx200_acb_create(struct scx200_acb_iface *iface) | |||
| 472 | return -ENODEV; | 470 | return -ENODEV; |
| 473 | } | 471 | } |
| 474 | 472 | ||
| 475 | mutex_lock(&scx200_acb_list_mutex); | 473 | if (!adapter->dev.parent) { |
| 476 | iface->next = scx200_acb_list; | 474 | /* If there's no dev, we're tracking (ISA) ifaces manually */ |
| 477 | scx200_acb_list = iface; | 475 | mutex_lock(&scx200_acb_list_mutex); |
| 478 | mutex_unlock(&scx200_acb_list_mutex); | 476 | iface->next = scx200_acb_list; |
| 477 | scx200_acb_list = iface; | ||
| 478 | mutex_unlock(&scx200_acb_list_mutex); | ||
| 479 | } | ||
| 479 | 480 | ||
| 480 | return 0; | 481 | return 0; |
| 481 | } | 482 | } |
| 482 | 483 | ||
| 483 | static __init int scx200_create_pci(const char *text, struct pci_dev *pdev, | 484 | static struct scx200_acb_iface * __devinit scx200_create_dev(const char *text, |
| 484 | int bar) | 485 | unsigned long base, int index, struct device *dev) |
| 485 | { | 486 | { |
| 486 | struct scx200_acb_iface *iface; | 487 | struct scx200_acb_iface *iface; |
| 487 | int rc; | 488 | int rc; |
| 488 | 489 | ||
| 489 | iface = scx200_create_iface(text, &pdev->dev, 0); | 490 | iface = scx200_create_iface(text, dev, index); |
| 490 | 491 | ||
| 491 | if (iface == NULL) | 492 | if (iface == NULL) |
| 492 | return -ENOMEM; | 493 | return NULL; |
| 493 | |||
| 494 | iface->pdev = pdev; | ||
| 495 | iface->bar = bar; | ||
| 496 | |||
| 497 | rc = pci_enable_device_io(iface->pdev); | ||
| 498 | if (rc) | ||
| 499 | goto errout_free; | ||
| 500 | 494 | ||
| 501 | rc = pci_request_region(iface->pdev, iface->bar, iface->adapter.name); | 495 | if (!request_region(base, 8, iface->adapter.name)) { |
| 502 | if (rc) { | 496 | printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n", |
| 503 | printk(KERN_ERR NAME ": can't allocate PCI BAR %d\n", | 497 | base, base + 8 - 1); |
| 504 | iface->bar); | ||
| 505 | goto errout_free; | 498 | goto errout_free; |
| 506 | } | 499 | } |
| 507 | 500 | ||
| 508 | iface->base = pci_resource_start(iface->pdev, iface->bar); | 501 | iface->base = base; |
| 509 | rc = scx200_acb_create(iface); | 502 | rc = scx200_acb_create(iface); |
| 510 | 503 | ||
| 511 | if (rc == 0) | 504 | if (rc == 0) |
| 512 | return 0; | 505 | return iface; |
| 513 | 506 | ||
| 514 | pci_release_region(iface->pdev, iface->bar); | 507 | release_region(base, 8); |
| 515 | pci_dev_put(iface->pdev); | ||
| 516 | errout_free: | 508 | errout_free: |
| 517 | kfree(iface); | 509 | kfree(iface); |
| 518 | return rc; | 510 | return NULL; |
| 519 | } | 511 | } |
| 520 | 512 | ||
| 521 | static int __init scx200_create_isa(const char *text, unsigned long base, | 513 | static int __devinit scx200_probe(struct platform_device *pdev) |
| 522 | int index) | ||
| 523 | { | 514 | { |
| 524 | struct scx200_acb_iface *iface; | 515 | struct scx200_acb_iface *iface; |
| 525 | int rc; | 516 | struct resource *res; |
| 526 | |||
| 527 | iface = scx200_create_iface(text, NULL, index); | ||
| 528 | |||
| 529 | if (iface == NULL) | ||
| 530 | return -ENOMEM; | ||
| 531 | 517 | ||
| 532 | if (!request_region(base, 8, iface->adapter.name)) { | 518 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 533 | printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n", | 519 | if (!res) { |
| 534 | base, base + 8 - 1); | 520 | dev_err(&pdev->dev, "can't fetch device resource info\n"); |
| 535 | rc = -EBUSY; | 521 | return -ENODEV; |
| 536 | goto errout_free; | ||
| 537 | } | 522 | } |
| 538 | 523 | ||
| 539 | iface->base = base; | 524 | iface = scx200_create_dev("CS5535", res->start, 0, &pdev->dev); |
| 540 | rc = scx200_acb_create(iface); | 525 | if (!iface) |
| 526 | return -EIO; | ||
| 541 | 527 | ||
| 542 | if (rc == 0) | 528 | dev_info(&pdev->dev, "SCx200 device '%s' registered\n", |
| 543 | return 0; | 529 | iface->adapter.name); |
| 530 | platform_set_drvdata(pdev, iface); | ||
| 544 | 531 | ||
| 545 | release_region(base, 8); | 532 | return 0; |
| 546 | errout_free: | ||
| 547 | kfree(iface); | ||
| 548 | return rc; | ||
| 549 | } | 533 | } |
| 550 | 534 | ||
| 551 | /* Driver data is an index into the scx200_data array that indicates | 535 | static void __devexit scx200_cleanup_iface(struct scx200_acb_iface *iface) |
| 552 | * the name and the BAR where the I/O address resource is located. ISA | 536 | { |
| 553 | * devices are flagged with a bar value of -1 */ | 537 | i2c_del_adapter(&iface->adapter); |
| 554 | 538 | release_region(iface->base, 8); | |
| 555 | static const struct pci_device_id scx200_pci[] __initconst = { | 539 | kfree(iface); |
| 556 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE), | 540 | } |
| 557 | .driver_data = 0 }, | ||
| 558 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE), | ||
| 559 | .driver_data = 0 }, | ||
| 560 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA), | ||
| 561 | .driver_data = 1 }, | ||
| 562 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA), | ||
| 563 | .driver_data = 2 }, | ||
| 564 | { 0, } | ||
| 565 | }; | ||
| 566 | |||
| 567 | static struct { | ||
| 568 | const char *name; | ||
| 569 | int bar; | ||
| 570 | } scx200_data[] = { | ||
| 571 | { "SCx200", -1 }, | ||
| 572 | { "CS5535", 0 }, | ||
| 573 | { "CS5536", 0 } | ||
| 574 | }; | ||
| 575 | 541 | ||
| 576 | static __init int scx200_scan_pci(void) | 542 | static int __devexit scx200_remove(struct platform_device *pdev) |
| 577 | { | 543 | { |
| 578 | int data, dev; | 544 | struct scx200_acb_iface *iface; |
| 579 | int rc = -ENODEV; | ||
| 580 | struct pci_dev *pdev; | ||
| 581 | 545 | ||
| 582 | for(dev = 0; dev < ARRAY_SIZE(scx200_pci); dev++) { | 546 | iface = platform_get_drvdata(pdev); |
| 583 | pdev = pci_get_device(scx200_pci[dev].vendor, | 547 | platform_set_drvdata(pdev, NULL); |
| 584 | scx200_pci[dev].device, NULL); | 548 | scx200_cleanup_iface(iface); |
| 585 | 549 | ||
| 586 | if (pdev == NULL) | 550 | return 0; |
| 587 | continue; | 551 | } |
| 588 | 552 | ||
| 589 | data = scx200_pci[dev].driver_data; | 553 | static struct platform_driver scx200_pci_drv = { |
| 554 | .driver = { | ||
| 555 | .name = "cs5535-smb", | ||
| 556 | .owner = THIS_MODULE, | ||
| 557 | }, | ||
| 558 | .probe = scx200_probe, | ||
| 559 | .remove = __devexit_p(scx200_remove), | ||
| 560 | }; | ||
| 590 | 561 | ||
| 591 | /* if .bar is greater or equal to zero, this is a | 562 | static const struct pci_device_id scx200_isa[] __initconst = { |
| 592 | * PCI device - otherwise, we assume | 563 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) }, |
| 593 | that the ports are ISA based | 564 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) }, |
| 594 | */ | 565 | { 0, } |
| 566 | }; | ||
| 595 | 567 | ||
| 596 | if (scx200_data[data].bar >= 0) | 568 | static __init void scx200_scan_isa(void) |
| 597 | rc = scx200_create_pci(scx200_data[data].name, pdev, | 569 | { |
| 598 | scx200_data[data].bar); | 570 | int i; |
| 599 | else { | ||
| 600 | int i; | ||
| 601 | 571 | ||
| 602 | pci_dev_put(pdev); | 572 | if (!pci_dev_present(scx200_isa)) |
| 603 | for (i = 0; i < MAX_DEVICES; ++i) { | 573 | return; |
| 604 | if (base[i] == 0) | ||
| 605 | continue; | ||
| 606 | 574 | ||
| 607 | rc = scx200_create_isa(scx200_data[data].name, | 575 | for (i = 0; i < MAX_DEVICES; ++i) { |
| 608 | base[i], | 576 | if (base[i] == 0) |
| 609 | i); | 577 | continue; |
| 610 | } | ||
| 611 | } | ||
| 612 | 578 | ||
| 613 | break; | 579 | /* XXX: should we care about failures? */ |
| 580 | scx200_create_dev("SCx200", base[i], i, NULL); | ||
| 614 | } | 581 | } |
| 615 | |||
| 616 | return rc; | ||
| 617 | } | 582 | } |
| 618 | 583 | ||
| 619 | static int __init scx200_acb_init(void) | 584 | static int __init scx200_acb_init(void) |
| 620 | { | 585 | { |
| 621 | int rc; | ||
| 622 | |||
| 623 | pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n"); | 586 | pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n"); |
| 624 | 587 | ||
| 625 | rc = scx200_scan_pci(); | 588 | /* First scan for ISA-based devices */ |
| 589 | scx200_scan_isa(); /* XXX: should we care about errors? */ | ||
| 626 | 590 | ||
| 627 | /* If at least one bus was created, init must succeed */ | 591 | /* If at least one bus was created, init must succeed */ |
| 628 | if (scx200_acb_list) | 592 | if (scx200_acb_list) |
| 629 | return 0; | 593 | return 0; |
| 630 | return rc; | 594 | |
| 595 | /* No ISA devices; register the platform driver for PCI-based devices */ | ||
| 596 | return platform_driver_register(&scx200_pci_drv); | ||
| 631 | } | 597 | } |
| 632 | 598 | ||
| 633 | static void __exit scx200_acb_cleanup(void) | 599 | static void __exit scx200_acb_cleanup(void) |
| 634 | { | 600 | { |
| 635 | struct scx200_acb_iface *iface; | 601 | struct scx200_acb_iface *iface; |
| 636 | 602 | ||
| 603 | platform_driver_unregister(&scx200_pci_drv); | ||
| 604 | |||
| 637 | mutex_lock(&scx200_acb_list_mutex); | 605 | mutex_lock(&scx200_acb_list_mutex); |
| 638 | while ((iface = scx200_acb_list) != NULL) { | 606 | while ((iface = scx200_acb_list) != NULL) { |
| 639 | scx200_acb_list = iface->next; | 607 | scx200_acb_list = iface->next; |
| 640 | mutex_unlock(&scx200_acb_list_mutex); | 608 | mutex_unlock(&scx200_acb_list_mutex); |
| 641 | 609 | ||
| 642 | i2c_del_adapter(&iface->adapter); | 610 | scx200_cleanup_iface(iface); |
| 643 | |||
| 644 | if (iface->pdev) { | ||
| 645 | pci_release_region(iface->pdev, iface->bar); | ||
| 646 | pci_dev_put(iface->pdev); | ||
| 647 | } | ||
| 648 | else | ||
| 649 | release_region(iface->base, 8); | ||
| 650 | 611 | ||
| 651 | kfree(iface); | ||
| 652 | mutex_lock(&scx200_acb_list_mutex); | 612 | mutex_lock(&scx200_acb_list_mutex); |
| 653 | } | 613 | } |
| 654 | mutex_unlock(&scx200_acb_list_mutex); | 614 | mutex_unlock(&scx200_acb_list_mutex); |
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index 20895e7a99c9..793300c554b4 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c | |||
| @@ -361,12 +361,6 @@ static struct pm860x_irq_data pm860x_irqs[] = { | |||
| 361 | }, | 361 | }, |
| 362 | }; | 362 | }; |
| 363 | 363 | ||
| 364 | static inline struct pm860x_irq_data *irq_to_pm860x(struct pm860x_chip *chip, | ||
| 365 | int irq) | ||
| 366 | { | ||
| 367 | return &pm860x_irqs[irq - chip->irq_base]; | ||
| 368 | } | ||
| 369 | |||
| 370 | static irqreturn_t pm860x_irq(int irq, void *data) | 364 | static irqreturn_t pm860x_irq(int irq, void *data) |
| 371 | { | 365 | { |
| 372 | struct pm860x_chip *chip = data; | 366 | struct pm860x_chip *chip = data; |
| @@ -388,16 +382,16 @@ static irqreturn_t pm860x_irq(int irq, void *data) | |||
| 388 | return IRQ_HANDLED; | 382 | return IRQ_HANDLED; |
| 389 | } | 383 | } |
| 390 | 384 | ||
| 391 | static void pm860x_irq_lock(unsigned int irq) | 385 | static void pm860x_irq_lock(struct irq_data *data) |
| 392 | { | 386 | { |
| 393 | struct pm860x_chip *chip = get_irq_chip_data(irq); | 387 | struct pm860x_chip *chip = irq_data_get_irq_chip_data(data); |
| 394 | 388 | ||
| 395 | mutex_lock(&chip->irq_lock); | 389 | mutex_lock(&chip->irq_lock); |
| 396 | } | 390 | } |
| 397 | 391 | ||
| 398 | static void pm860x_irq_sync_unlock(unsigned int irq) | 392 | static void pm860x_irq_sync_unlock(struct irq_data *data) |
| 399 | { | 393 | { |
| 400 | struct pm860x_chip *chip = get_irq_chip_data(irq); | 394 | struct pm860x_chip *chip = irq_data_get_irq_chip_data(data); |
| 401 | struct pm860x_irq_data *irq_data; | 395 | struct pm860x_irq_data *irq_data; |
| 402 | struct i2c_client *i2c; | 396 | struct i2c_client *i2c; |
| 403 | static unsigned char cached[3] = {0x0, 0x0, 0x0}; | 397 | static unsigned char cached[3] = {0x0, 0x0, 0x0}; |
| @@ -439,25 +433,25 @@ static void pm860x_irq_sync_unlock(unsigned int irq) | |||
| 439 | mutex_unlock(&chip->irq_lock); | 433 | mutex_unlock(&chip->irq_lock); |
| 440 | } | 434 | } |
| 441 | 435 | ||
| 442 | static void pm860x_irq_enable(unsigned int irq) | 436 | static void pm860x_irq_enable(struct irq_data *data) |
| 443 | { | 437 | { |
| 444 | struct pm860x_chip *chip = get_irq_chip_data(irq); | 438 | struct pm860x_chip *chip = irq_data_get_irq_chip_data(data); |
| 445 | pm860x_irqs[irq - chip->irq_base].enable | 439 | pm860x_irqs[data->irq - chip->irq_base].enable |
| 446 | = pm860x_irqs[irq - chip->irq_base].offs; | 440 | = pm860x_irqs[data->irq - chip->irq_base].offs; |
| 447 | } | 441 | } |
| 448 | 442 | ||
| 449 | static void pm860x_irq_disable(unsigned int irq) | 443 | static void pm860x_irq_disable(struct irq_data *data) |
| 450 | { | 444 | { |
| 451 | struct pm860x_chip *chip = get_irq_chip_data(irq); | 445 | struct pm860x_chip *chip = irq_data_get_irq_chip_data(data); |
| 452 | pm860x_irqs[irq - chip->irq_base].enable = 0; | 446 | pm860x_irqs[data->irq - chip->irq_base].enable = 0; |
| 453 | } | 447 | } |
| 454 | 448 | ||
| 455 | static struct irq_chip pm860x_irq_chip = { | 449 | static struct irq_chip pm860x_irq_chip = { |
| 456 | .name = "88pm860x", | 450 | .name = "88pm860x", |
| 457 | .bus_lock = pm860x_irq_lock, | 451 | .irq_bus_lock = pm860x_irq_lock, |
| 458 | .bus_sync_unlock = pm860x_irq_sync_unlock, | 452 | .irq_bus_sync_unlock = pm860x_irq_sync_unlock, |
| 459 | .enable = pm860x_irq_enable, | 453 | .irq_enable = pm860x_irq_enable, |
| 460 | .disable = pm860x_irq_disable, | 454 | .irq_disable = pm860x_irq_disable, |
| 461 | }; | 455 | }; |
| 462 | 456 | ||
| 463 | static int __devinit device_gpadc_init(struct pm860x_chip *chip, | 457 | static int __devinit device_gpadc_init(struct pm860x_chip *chip, |
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index da9d2971102e..fd018366d670 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
| @@ -496,13 +496,13 @@ config EZX_PCAP | |||
| 496 | 496 | ||
| 497 | config AB8500_CORE | 497 | config AB8500_CORE |
| 498 | bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" | 498 | bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" |
| 499 | depends on GENERIC_HARDIRQS && ABX500_CORE && SPI_MASTER && ARCH_U8500 | 499 | depends on GENERIC_HARDIRQS && ABX500_CORE |
| 500 | select MFD_CORE | 500 | select MFD_CORE |
| 501 | help | 501 | help |
| 502 | Select this option to enable access to AB8500 power management | 502 | Select this option to enable access to AB8500 power management |
| 503 | chip. This connects to U8500 either on the SSP/SPI bus | 503 | chip. This connects to U8500 either on the SSP/SPI bus (deprecated |
| 504 | or the I2C bus via PRCMU. It also adds the irq_chip | 504 | since hardware version v1.0) or the I2C bus via PRCMU. It also adds |
| 505 | parts for handling the Mixed Signal chip events. | 505 | the irq_chip parts for handling the Mixed Signal chip events. |
| 506 | This chip embeds various other multimedia funtionalities as well. | 506 | This chip embeds various other multimedia funtionalities as well. |
| 507 | 507 | ||
| 508 | config AB8500_I2C_CORE | 508 | config AB8500_I2C_CORE |
| @@ -537,6 +537,14 @@ config AB3550_CORE | |||
| 537 | LEDs, vibrator, system power and temperature, power management | 537 | LEDs, vibrator, system power and temperature, power management |
| 538 | and ALSA sound. | 538 | and ALSA sound. |
| 539 | 539 | ||
| 540 | config MFD_CS5535 | ||
| 541 | tristate "Support for CS5535 and CS5536 southbridge core functions" | ||
| 542 | select MFD_CORE | ||
| 543 | depends on PCI | ||
| 544 | ---help--- | ||
| 545 | This is the core driver for CS5535/CS5536 MFD functions. This is | ||
| 546 | necessary for using the board's GPIO and MFGPT functionality. | ||
| 547 | |||
| 540 | config MFD_TIMBERDALE | 548 | config MFD_TIMBERDALE |
| 541 | tristate "Support for the Timberdale FPGA" | 549 | tristate "Support for the Timberdale FPGA" |
| 542 | select MFD_CORE | 550 | select MFD_CORE |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 848e7eac75aa..a54e2c7c6a1c 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
| @@ -70,7 +70,7 @@ obj-$(CONFIG_ABX500_CORE) += abx500-core.o | |||
| 70 | obj-$(CONFIG_AB3100_CORE) += ab3100-core.o | 70 | obj-$(CONFIG_AB3100_CORE) += ab3100-core.o |
| 71 | obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o | 71 | obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o |
| 72 | obj-$(CONFIG_AB3550_CORE) += ab3550-core.o | 72 | obj-$(CONFIG_AB3550_CORE) += ab3550-core.o |
| 73 | obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-spi.o | 73 | obj-$(CONFIG_AB8500_CORE) += ab8500-core.o |
| 74 | obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o | 74 | obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o |
| 75 | obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o | 75 | obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o |
| 76 | obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o | 76 | obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o |
| @@ -82,3 +82,4 @@ obj-$(CONFIG_MFD_JZ4740_ADC) += jz4740-adc.o | |||
| 82 | obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o | 82 | obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o |
| 83 | obj-$(CONFIG_MFD_VX855) += vx855.o | 83 | obj-$(CONFIG_MFD_VX855) += vx855.o |
| 84 | obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o | 84 | obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o |
| 85 | obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o | ||
diff --git a/drivers/mfd/ab3550-core.c b/drivers/mfd/ab3550-core.c index 8a98739e6d9c..5fbca346b998 100644 --- a/drivers/mfd/ab3550-core.c +++ b/drivers/mfd/ab3550-core.c | |||
| @@ -1159,15 +1159,16 @@ static void ab3550_mask_work(struct work_struct *work) | |||
| 1159 | } | 1159 | } |
| 1160 | } | 1160 | } |
| 1161 | 1161 | ||
| 1162 | static void ab3550_mask(unsigned int irq) | 1162 | static void ab3550_mask(struct irq_data *data) |
| 1163 | { | 1163 | { |
| 1164 | unsigned long flags; | 1164 | unsigned long flags; |
| 1165 | struct ab3550 *ab; | 1165 | struct ab3550 *ab; |
| 1166 | struct ab3550_platform_data *plf_data; | 1166 | struct ab3550_platform_data *plf_data; |
| 1167 | int irq; | ||
| 1167 | 1168 | ||
| 1168 | ab = get_irq_chip_data(irq); | 1169 | ab = irq_data_get_irq_chip_data(data); |
| 1169 | plf_data = ab->i2c_client[0]->dev.platform_data; | 1170 | plf_data = ab->i2c_client[0]->dev.platform_data; |
| 1170 | irq -= plf_data->irq.base; | 1171 | irq = data->irq - plf_data->irq.base; |
| 1171 | 1172 | ||
| 1172 | spin_lock_irqsave(&ab->event_lock, flags); | 1173 | spin_lock_irqsave(&ab->event_lock, flags); |
| 1173 | ab->event_mask[irq / 8] |= BIT(irq % 8); | 1174 | ab->event_mask[irq / 8] |= BIT(irq % 8); |
| @@ -1176,15 +1177,16 @@ static void ab3550_mask(unsigned int irq) | |||
| 1176 | schedule_work(&ab->mask_work); | 1177 | schedule_work(&ab->mask_work); |
| 1177 | } | 1178 | } |
| 1178 | 1179 | ||
| 1179 | static void ab3550_unmask(unsigned int irq) | 1180 | static void ab3550_unmask(struct irq_data *data) |
| 1180 | { | 1181 | { |
| 1181 | unsigned long flags; | 1182 | unsigned long flags; |
| 1182 | struct ab3550 *ab; | 1183 | struct ab3550 *ab; |
| 1183 | struct ab3550_platform_data *plf_data; | 1184 | struct ab3550_platform_data *plf_data; |
| 1185 | int irq; | ||
| 1184 | 1186 | ||
| 1185 | ab = get_irq_chip_data(irq); | 1187 | ab = irq_data_get_irq_chip_data(data); |
| 1186 | plf_data = ab->i2c_client[0]->dev.platform_data; | 1188 | plf_data = ab->i2c_client[0]->dev.platform_data; |
| 1187 | irq -= plf_data->irq.base; | 1189 | irq = data->irq - plf_data->irq.base; |
| 1188 | 1190 | ||
| 1189 | spin_lock_irqsave(&ab->event_lock, flags); | 1191 | spin_lock_irqsave(&ab->event_lock, flags); |
| 1190 | ab->event_mask[irq / 8] &= ~BIT(irq % 8); | 1192 | ab->event_mask[irq / 8] &= ~BIT(irq % 8); |
| @@ -1193,20 +1195,16 @@ static void ab3550_unmask(unsigned int irq) | |||
| 1193 | schedule_work(&ab->mask_work); | 1195 | schedule_work(&ab->mask_work); |
| 1194 | } | 1196 | } |
| 1195 | 1197 | ||
| 1196 | static void noop(unsigned int irq) | 1198 | static void noop(struct irq_data *data) |
| 1197 | { | 1199 | { |
| 1198 | } | 1200 | } |
| 1199 | 1201 | ||
| 1200 | static struct irq_chip ab3550_irq_chip = { | 1202 | static struct irq_chip ab3550_irq_chip = { |
| 1201 | .name = "ab3550-core", /* Keep the same name as the request */ | 1203 | .name = "ab3550-core", /* Keep the same name as the request */ |
| 1202 | .startup = NULL, /* defaults to enable */ | 1204 | .irq_disable = ab3550_mask, /* No default to mask in chip.c */ |
| 1203 | .shutdown = NULL, /* defaults to disable */ | 1205 | .irq_ack = noop, |
| 1204 | .enable = NULL, /* defaults to unmask */ | 1206 | .irq_mask = ab3550_mask, |
| 1205 | .disable = ab3550_mask, /* No default to mask in chip.c */ | 1207 | .irq_unmask = ab3550_unmask, |
| 1206 | .ack = noop, | ||
| 1207 | .mask = ab3550_mask, | ||
| 1208 | .unmask = ab3550_unmask, | ||
| 1209 | .end = NULL, | ||
| 1210 | }; | 1208 | }; |
| 1211 | 1209 | ||
| 1212 | struct ab_family_id { | 1210 | struct ab_family_id { |
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index d9640a623ff4..b6887014d687 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
| @@ -52,6 +52,7 @@ | |||
| 52 | #define AB8500_IT_LATCH8_REG 0x27 | 52 | #define AB8500_IT_LATCH8_REG 0x27 |
| 53 | #define AB8500_IT_LATCH9_REG 0x28 | 53 | #define AB8500_IT_LATCH9_REG 0x28 |
| 54 | #define AB8500_IT_LATCH10_REG 0x29 | 54 | #define AB8500_IT_LATCH10_REG 0x29 |
| 55 | #define AB8500_IT_LATCH12_REG 0x2B | ||
| 55 | #define AB8500_IT_LATCH19_REG 0x32 | 56 | #define AB8500_IT_LATCH19_REG 0x32 |
| 56 | #define AB8500_IT_LATCH20_REG 0x33 | 57 | #define AB8500_IT_LATCH20_REG 0x33 |
| 57 | #define AB8500_IT_LATCH21_REG 0x34 | 58 | #define AB8500_IT_LATCH21_REG 0x34 |
| @@ -98,13 +99,17 @@ | |||
| 98 | * offset 0. | 99 | * offset 0. |
| 99 | */ | 100 | */ |
| 100 | static const int ab8500_irq_regoffset[AB8500_NUM_IRQ_REGS] = { | 101 | static const int ab8500_irq_regoffset[AB8500_NUM_IRQ_REGS] = { |
| 101 | 0, 1, 2, 3, 4, 6, 7, 8, 9, 18, 19, 20, 21, | 102 | 0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 18, 19, 20, 21, |
| 102 | }; | 103 | }; |
| 103 | 104 | ||
| 104 | static int ab8500_get_chip_id(struct device *dev) | 105 | static int ab8500_get_chip_id(struct device *dev) |
| 105 | { | 106 | { |
| 106 | struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); | 107 | struct ab8500 *ab8500; |
| 107 | return (int)ab8500->chip_id; | 108 | |
| 109 | if (!dev) | ||
| 110 | return -EINVAL; | ||
| 111 | ab8500 = dev_get_drvdata(dev->parent); | ||
| 112 | return ab8500 ? (int)ab8500->chip_id : -EINVAL; | ||
| 108 | } | 113 | } |
| 109 | 114 | ||
| 110 | static int set_register_interruptible(struct ab8500 *ab8500, u8 bank, | 115 | static int set_register_interruptible(struct ab8500 *ab8500, u8 bank, |
| @@ -228,16 +233,16 @@ static struct abx500_ops ab8500_ops = { | |||
| 228 | .startup_irq_enabled = NULL, | 233 | .startup_irq_enabled = NULL, |
| 229 | }; | 234 | }; |
| 230 | 235 | ||
| 231 | static void ab8500_irq_lock(unsigned int irq) | 236 | static void ab8500_irq_lock(struct irq_data *data) |
| 232 | { | 237 | { |
| 233 | struct ab8500 *ab8500 = get_irq_chip_data(irq); | 238 | struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); |
| 234 | 239 | ||
| 235 | mutex_lock(&ab8500->irq_lock); | 240 | mutex_lock(&ab8500->irq_lock); |
| 236 | } | 241 | } |
| 237 | 242 | ||
| 238 | static void ab8500_irq_sync_unlock(unsigned int irq) | 243 | static void ab8500_irq_sync_unlock(struct irq_data *data) |
| 239 | { | 244 | { |
| 240 | struct ab8500 *ab8500 = get_irq_chip_data(irq); | 245 | struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); |
| 241 | int i; | 246 | int i; |
| 242 | 247 | ||
| 243 | for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) { | 248 | for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) { |
| @@ -248,6 +253,10 @@ static void ab8500_irq_sync_unlock(unsigned int irq) | |||
| 248 | if (new == old) | 253 | if (new == old) |
| 249 | continue; | 254 | continue; |
| 250 | 255 | ||
| 256 | /* Interrupt register 12 does'nt exist prior to version 0x20 */ | ||
| 257 | if (ab8500_irq_regoffset[i] == 11 && ab8500->chip_id < 0x20) | ||
| 258 | continue; | ||
| 259 | |||
| 251 | ab8500->oldmask[i] = new; | 260 | ab8500->oldmask[i] = new; |
| 252 | 261 | ||
| 253 | reg = AB8500_IT_MASK1_REG + ab8500_irq_regoffset[i]; | 262 | reg = AB8500_IT_MASK1_REG + ab8500_irq_regoffset[i]; |
| @@ -257,20 +266,20 @@ static void ab8500_irq_sync_unlock(unsigned int irq) | |||
| 257 | mutex_unlock(&ab8500->irq_lock); | 266 | mutex_unlock(&ab8500->irq_lock); |
| 258 | } | 267 | } |
| 259 | 268 | ||
| 260 | static void ab8500_irq_mask(unsigned int irq) | 269 | static void ab8500_irq_mask(struct irq_data *data) |
| 261 | { | 270 | { |
| 262 | struct ab8500 *ab8500 = get_irq_chip_data(irq); | 271 | struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); |
| 263 | int offset = irq - ab8500->irq_base; | 272 | int offset = data->irq - ab8500->irq_base; |
| 264 | int index = offset / 8; | 273 | int index = offset / 8; |
| 265 | int mask = 1 << (offset % 8); | 274 | int mask = 1 << (offset % 8); |
| 266 | 275 | ||
| 267 | ab8500->mask[index] |= mask; | 276 | ab8500->mask[index] |= mask; |
| 268 | } | 277 | } |
| 269 | 278 | ||
| 270 | static void ab8500_irq_unmask(unsigned int irq) | 279 | static void ab8500_irq_unmask(struct irq_data *data) |
| 271 | { | 280 | { |
| 272 | struct ab8500 *ab8500 = get_irq_chip_data(irq); | 281 | struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); |
| 273 | int offset = irq - ab8500->irq_base; | 282 | int offset = data->irq - ab8500->irq_base; |
| 274 | int index = offset / 8; | 283 | int index = offset / 8; |
| 275 | int mask = 1 << (offset % 8); | 284 | int mask = 1 << (offset % 8); |
| 276 | 285 | ||
| @@ -279,10 +288,10 @@ static void ab8500_irq_unmask(unsigned int irq) | |||
| 279 | 288 | ||
| 280 | static struct irq_chip ab8500_irq_chip = { | 289 | static struct irq_chip ab8500_irq_chip = { |
| 281 | .name = "ab8500", | 290 | .name = "ab8500", |
| 282 | .bus_lock = ab8500_irq_lock, | 291 | .irq_bus_lock = ab8500_irq_lock, |
| 283 | .bus_sync_unlock = ab8500_irq_sync_unlock, | 292 | .irq_bus_sync_unlock = ab8500_irq_sync_unlock, |
| 284 | .mask = ab8500_irq_mask, | 293 | .irq_mask = ab8500_irq_mask, |
| 285 | .unmask = ab8500_irq_unmask, | 294 | .irq_unmask = ab8500_irq_unmask, |
| 286 | }; | 295 | }; |
| 287 | 296 | ||
| 288 | static irqreturn_t ab8500_irq(int irq, void *dev) | 297 | static irqreturn_t ab8500_irq(int irq, void *dev) |
| @@ -297,6 +306,10 @@ static irqreturn_t ab8500_irq(int irq, void *dev) | |||
| 297 | int status; | 306 | int status; |
| 298 | u8 value; | 307 | u8 value; |
| 299 | 308 | ||
| 309 | /* Interrupt register 12 does'nt exist prior to version 0x20 */ | ||
| 310 | if (regoffset == 11 && ab8500->chip_id < 0x20) | ||
| 311 | continue; | ||
| 312 | |||
| 300 | status = get_register_interruptible(ab8500, AB8500_INTERRUPT, | 313 | status = get_register_interruptible(ab8500, AB8500_INTERRUPT, |
| 301 | AB8500_IT_LATCH1_REG + regoffset, &value); | 314 | AB8500_IT_LATCH1_REG + regoffset, &value); |
| 302 | if (status < 0 || value == 0) | 315 | if (status < 0 || value == 0) |
| @@ -393,13 +406,195 @@ static struct resource ab8500_poweronkey_db_resources[] = { | |||
| 393 | }, | 406 | }, |
| 394 | }; | 407 | }; |
| 395 | 408 | ||
| 409 | static struct resource ab8500_bm_resources[] = { | ||
| 410 | { | ||
| 411 | .name = "MAIN_EXT_CH_NOT_OK", | ||
| 412 | .start = AB8500_INT_MAIN_EXT_CH_NOT_OK, | ||
| 413 | .end = AB8500_INT_MAIN_EXT_CH_NOT_OK, | ||
| 414 | .flags = IORESOURCE_IRQ, | ||
| 415 | }, | ||
| 416 | { | ||
| 417 | .name = "BATT_OVV", | ||
| 418 | .start = AB8500_INT_BATT_OVV, | ||
| 419 | .end = AB8500_INT_BATT_OVV, | ||
| 420 | .flags = IORESOURCE_IRQ, | ||
| 421 | }, | ||
| 422 | { | ||
| 423 | .name = "MAIN_CH_UNPLUG_DET", | ||
| 424 | .start = AB8500_INT_MAIN_CH_UNPLUG_DET, | ||
| 425 | .end = AB8500_INT_MAIN_CH_UNPLUG_DET, | ||
| 426 | .flags = IORESOURCE_IRQ, | ||
| 427 | }, | ||
| 428 | { | ||
| 429 | .name = "MAIN_CHARGE_PLUG_DET", | ||
| 430 | .start = AB8500_INT_MAIN_CH_PLUG_DET, | ||
| 431 | .end = AB8500_INT_MAIN_CH_PLUG_DET, | ||
| 432 | .flags = IORESOURCE_IRQ, | ||
| 433 | }, | ||
| 434 | { | ||
| 435 | .name = "VBUS_DET_F", | ||
| 436 | .start = AB8500_INT_VBUS_DET_F, | ||
| 437 | .end = AB8500_INT_VBUS_DET_F, | ||
| 438 | .flags = IORESOURCE_IRQ, | ||
| 439 | }, | ||
| 440 | { | ||
| 441 | .name = "VBUS_DET_R", | ||
| 442 | .start = AB8500_INT_VBUS_DET_R, | ||
| 443 | .end = AB8500_INT_VBUS_DET_R, | ||
| 444 | .flags = IORESOURCE_IRQ, | ||
| 445 | }, | ||
| 446 | { | ||
| 447 | .name = "BAT_CTRL_INDB", | ||
| 448 | .start = AB8500_INT_BAT_CTRL_INDB, | ||
| 449 | .end = AB8500_INT_BAT_CTRL_INDB, | ||
| 450 | .flags = IORESOURCE_IRQ, | ||
| 451 | }, | ||
| 452 | { | ||
| 453 | .name = "CH_WD_EXP", | ||
| 454 | .start = AB8500_INT_CH_WD_EXP, | ||
| 455 | .end = AB8500_INT_CH_WD_EXP, | ||
| 456 | .flags = IORESOURCE_IRQ, | ||
| 457 | }, | ||
| 458 | { | ||
| 459 | .name = "VBUS_OVV", | ||
| 460 | .start = AB8500_INT_VBUS_OVV, | ||
| 461 | .end = AB8500_INT_VBUS_OVV, | ||
| 462 | .flags = IORESOURCE_IRQ, | ||
| 463 | }, | ||
| 464 | { | ||
| 465 | .name = "NCONV_ACCU", | ||
| 466 | .start = AB8500_INT_CCN_CONV_ACC, | ||
| 467 | .end = AB8500_INT_CCN_CONV_ACC, | ||
| 468 | .flags = IORESOURCE_IRQ, | ||
| 469 | }, | ||
| 470 | { | ||
| 471 | .name = "LOW_BAT_F", | ||
| 472 | .start = AB8500_INT_LOW_BAT_F, | ||
| 473 | .end = AB8500_INT_LOW_BAT_F, | ||
| 474 | .flags = IORESOURCE_IRQ, | ||
| 475 | }, | ||
| 476 | { | ||
| 477 | .name = "LOW_BAT_R", | ||
| 478 | .start = AB8500_INT_LOW_BAT_R, | ||
| 479 | .end = AB8500_INT_LOW_BAT_R, | ||
| 480 | .flags = IORESOURCE_IRQ, | ||
| 481 | }, | ||
| 482 | { | ||
| 483 | .name = "BTEMP_LOW", | ||
| 484 | .start = AB8500_INT_BTEMP_LOW, | ||
| 485 | .end = AB8500_INT_BTEMP_LOW, | ||
| 486 | .flags = IORESOURCE_IRQ, | ||
| 487 | }, | ||
| 488 | { | ||
| 489 | .name = "BTEMP_HIGH", | ||
| 490 | .start = AB8500_INT_BTEMP_HIGH, | ||
| 491 | .end = AB8500_INT_BTEMP_HIGH, | ||
| 492 | .flags = IORESOURCE_IRQ, | ||
| 493 | }, | ||
| 494 | { | ||
| 495 | .name = "USB_CHARGER_NOT_OKR", | ||
| 496 | .start = AB8500_INT_USB_CHARGER_NOT_OK, | ||
| 497 | .end = AB8500_INT_USB_CHARGER_NOT_OK, | ||
| 498 | .flags = IORESOURCE_IRQ, | ||
| 499 | }, | ||
| 500 | { | ||
| 501 | .name = "USB_CHARGE_DET_DONE", | ||
| 502 | .start = AB8500_INT_USB_CHG_DET_DONE, | ||
| 503 | .end = AB8500_INT_USB_CHG_DET_DONE, | ||
| 504 | .flags = IORESOURCE_IRQ, | ||
| 505 | }, | ||
| 506 | { | ||
| 507 | .name = "USB_CH_TH_PROT_R", | ||
| 508 | .start = AB8500_INT_USB_CH_TH_PROT_R, | ||
| 509 | .end = AB8500_INT_USB_CH_TH_PROT_R, | ||
| 510 | .flags = IORESOURCE_IRQ, | ||
| 511 | }, | ||
| 512 | { | ||
| 513 | .name = "MAIN_CH_TH_PROT_R", | ||
| 514 | .start = AB8500_INT_MAIN_CH_TH_PROT_R, | ||
| 515 | .end = AB8500_INT_MAIN_CH_TH_PROT_R, | ||
| 516 | .flags = IORESOURCE_IRQ, | ||
| 517 | }, | ||
| 518 | { | ||
| 519 | .name = "USB_CHARGER_NOT_OKF", | ||
| 520 | .start = AB8500_INT_USB_CHARGER_NOT_OKF, | ||
| 521 | .end = AB8500_INT_USB_CHARGER_NOT_OKF, | ||
| 522 | .flags = IORESOURCE_IRQ, | ||
| 523 | }, | ||
| 524 | }; | ||
| 525 | |||
| 526 | static struct resource ab8500_debug_resources[] = { | ||
| 527 | { | ||
| 528 | .name = "IRQ_FIRST", | ||
| 529 | .start = AB8500_INT_MAIN_EXT_CH_NOT_OK, | ||
| 530 | .end = AB8500_INT_MAIN_EXT_CH_NOT_OK, | ||
| 531 | .flags = IORESOURCE_IRQ, | ||
| 532 | }, | ||
| 533 | { | ||
| 534 | .name = "IRQ_LAST", | ||
| 535 | .start = AB8500_INT_USB_CHARGER_NOT_OKF, | ||
| 536 | .end = AB8500_INT_USB_CHARGER_NOT_OKF, | ||
| 537 | .flags = IORESOURCE_IRQ, | ||
| 538 | }, | ||
| 539 | }; | ||
| 540 | |||
| 541 | static struct resource ab8500_usb_resources[] = { | ||
| 542 | { | ||
| 543 | .name = "ID_WAKEUP_R", | ||
| 544 | .start = AB8500_INT_ID_WAKEUP_R, | ||
| 545 | .end = AB8500_INT_ID_WAKEUP_R, | ||
| 546 | .flags = IORESOURCE_IRQ, | ||
| 547 | }, | ||
| 548 | { | ||
| 549 | .name = "ID_WAKEUP_F", | ||
| 550 | .start = AB8500_INT_ID_WAKEUP_F, | ||
| 551 | .end = AB8500_INT_ID_WAKEUP_F, | ||
| 552 | .flags = IORESOURCE_IRQ, | ||
| 553 | }, | ||
| 554 | { | ||
| 555 | .name = "VBUS_DET_F", | ||
| 556 | .start = AB8500_INT_VBUS_DET_F, | ||
| 557 | .end = AB8500_INT_VBUS_DET_F, | ||
| 558 | .flags = IORESOURCE_IRQ, | ||
| 559 | }, | ||
| 560 | { | ||
| 561 | .name = "VBUS_DET_R", | ||
| 562 | .start = AB8500_INT_VBUS_DET_R, | ||
| 563 | .end = AB8500_INT_VBUS_DET_R, | ||
| 564 | .flags = IORESOURCE_IRQ, | ||
| 565 | }, | ||
| 566 | { | ||
| 567 | .name = "USB_LINK_STATUS", | ||
| 568 | .start = AB8500_INT_USB_LINK_STATUS, | ||
| 569 | .end = AB8500_INT_USB_LINK_STATUS, | ||
| 570 | .flags = IORESOURCE_IRQ, | ||
| 571 | }, | ||
| 572 | }; | ||
| 573 | |||
| 574 | static struct resource ab8500_temp_resources[] = { | ||
| 575 | { | ||
| 576 | .name = "AB8500_TEMP_WARM", | ||
| 577 | .start = AB8500_INT_TEMP_WARM, | ||
| 578 | .end = AB8500_INT_TEMP_WARM, | ||
| 579 | .flags = IORESOURCE_IRQ, | ||
| 580 | }, | ||
| 581 | }; | ||
| 582 | |||
| 396 | static struct mfd_cell ab8500_devs[] = { | 583 | static struct mfd_cell ab8500_devs[] = { |
| 397 | #ifdef CONFIG_DEBUG_FS | 584 | #ifdef CONFIG_DEBUG_FS |
| 398 | { | 585 | { |
| 399 | .name = "ab8500-debug", | 586 | .name = "ab8500-debug", |
| 587 | .num_resources = ARRAY_SIZE(ab8500_debug_resources), | ||
| 588 | .resources = ab8500_debug_resources, | ||
| 400 | }, | 589 | }, |
| 401 | #endif | 590 | #endif |
| 402 | { | 591 | { |
| 592 | .name = "ab8500-sysctrl", | ||
| 593 | }, | ||
| 594 | { | ||
| 595 | .name = "ab8500-regulator", | ||
| 596 | }, | ||
| 597 | { | ||
| 403 | .name = "ab8500-gpadc", | 598 | .name = "ab8500-gpadc", |
| 404 | .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), | 599 | .num_resources = ARRAY_SIZE(ab8500_gpadc_resources), |
| 405 | .resources = ab8500_gpadc_resources, | 600 | .resources = ab8500_gpadc_resources, |
| @@ -410,6 +605,22 @@ static struct mfd_cell ab8500_devs[] = { | |||
| 410 | .resources = ab8500_rtc_resources, | 605 | .resources = ab8500_rtc_resources, |
| 411 | }, | 606 | }, |
| 412 | { | 607 | { |
| 608 | .name = "ab8500-bm", | ||
| 609 | .num_resources = ARRAY_SIZE(ab8500_bm_resources), | ||
| 610 | .resources = ab8500_bm_resources, | ||
| 611 | }, | ||
| 612 | { .name = "ab8500-codec", }, | ||
| 613 | { | ||
| 614 | .name = "ab8500-usb", | ||
| 615 | .num_resources = ARRAY_SIZE(ab8500_usb_resources), | ||
| 616 | .resources = ab8500_usb_resources, | ||
| 617 | }, | ||
| 618 | { | ||
| 619 | .name = "ab8500-poweron-key", | ||
| 620 | .num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources), | ||
| 621 | .resources = ab8500_poweronkey_db_resources, | ||
| 622 | }, | ||
| 623 | { | ||
| 413 | .name = "ab8500-pwm", | 624 | .name = "ab8500-pwm", |
| 414 | .id = 1, | 625 | .id = 1, |
| 415 | }, | 626 | }, |
| @@ -421,17 +632,37 @@ static struct mfd_cell ab8500_devs[] = { | |||
| 421 | .name = "ab8500-pwm", | 632 | .name = "ab8500-pwm", |
| 422 | .id = 3, | 633 | .id = 3, |
| 423 | }, | 634 | }, |
| 424 | { .name = "ab8500-charger", }, | 635 | { .name = "ab8500-leds", }, |
| 425 | { .name = "ab8500-audio", }, | ||
| 426 | { .name = "ab8500-usb", }, | ||
| 427 | { .name = "ab8500-regulator", }, | ||
| 428 | { | 636 | { |
| 429 | .name = "ab8500-poweron-key", | 637 | .name = "ab8500-denc", |
| 430 | .num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources), | 638 | }, |
| 431 | .resources = ab8500_poweronkey_db_resources, | 639 | { |
| 640 | .name = "ab8500-temp", | ||
| 641 | .num_resources = ARRAY_SIZE(ab8500_temp_resources), | ||
| 642 | .resources = ab8500_temp_resources, | ||
| 432 | }, | 643 | }, |
| 433 | }; | 644 | }; |
| 434 | 645 | ||
| 646 | static ssize_t show_chip_id(struct device *dev, | ||
| 647 | struct device_attribute *attr, char *buf) | ||
| 648 | { | ||
| 649 | struct ab8500 *ab8500; | ||
| 650 | |||
| 651 | ab8500 = dev_get_drvdata(dev); | ||
| 652 | return sprintf(buf, "%#x\n", ab8500 ? ab8500->chip_id : -EINVAL); | ||
| 653 | } | ||
| 654 | |||
| 655 | static DEVICE_ATTR(chip_id, S_IRUGO, show_chip_id, NULL); | ||
| 656 | |||
| 657 | static struct attribute *ab8500_sysfs_entries[] = { | ||
| 658 | &dev_attr_chip_id.attr, | ||
| 659 | NULL, | ||
| 660 | }; | ||
| 661 | |||
| 662 | static struct attribute_group ab8500_attr_group = { | ||
| 663 | .attrs = ab8500_sysfs_entries, | ||
| 664 | }; | ||
| 665 | |||
| 435 | int __devinit ab8500_init(struct ab8500 *ab8500) | 666 | int __devinit ab8500_init(struct ab8500 *ab8500) |
| 436 | { | 667 | { |
| 437 | struct ab8500_platform_data *plat = dev_get_platdata(ab8500->dev); | 668 | struct ab8500_platform_data *plat = dev_get_platdata(ab8500->dev); |
| @@ -454,8 +685,9 @@ int __devinit ab8500_init(struct ab8500 *ab8500) | |||
| 454 | * 0x0 - Early Drop | 685 | * 0x0 - Early Drop |
| 455 | * 0x10 - Cut 1.0 | 686 | * 0x10 - Cut 1.0 |
| 456 | * 0x11 - Cut 1.1 | 687 | * 0x11 - Cut 1.1 |
| 688 | * 0x20 - Cut 2.0 | ||
| 457 | */ | 689 | */ |
| 458 | if (value == 0x0 || value == 0x10 || value == 0x11) { | 690 | if (value == 0x0 || value == 0x10 || value == 0x11 || value == 0x20) { |
| 459 | ab8500->revision = value; | 691 | ab8500->revision = value; |
| 460 | dev_info(ab8500->dev, "detected chip, revision: %#x\n", value); | 692 | dev_info(ab8500->dev, "detected chip, revision: %#x\n", value); |
| 461 | } else { | 693 | } else { |
| @@ -468,18 +700,16 @@ int __devinit ab8500_init(struct ab8500 *ab8500) | |||
| 468 | plat->init(ab8500); | 700 | plat->init(ab8500); |
| 469 | 701 | ||
| 470 | /* Clear and mask all interrupts */ | 702 | /* Clear and mask all interrupts */ |
| 471 | for (i = 0; i < 10; i++) { | 703 | for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) { |
| 472 | get_register_interruptible(ab8500, AB8500_INTERRUPT, | 704 | /* Interrupt register 12 does'nt exist prior to version 0x20 */ |
| 473 | AB8500_IT_LATCH1_REG + i, &value); | 705 | if (ab8500_irq_regoffset[i] == 11 && ab8500->chip_id < 0x20) |
| 474 | set_register_interruptible(ab8500, AB8500_INTERRUPT, | 706 | continue; |
| 475 | AB8500_IT_MASK1_REG + i, 0xff); | ||
| 476 | } | ||
| 477 | 707 | ||
| 478 | for (i = 18; i < 24; i++) { | ||
| 479 | get_register_interruptible(ab8500, AB8500_INTERRUPT, | 708 | get_register_interruptible(ab8500, AB8500_INTERRUPT, |
| 480 | AB8500_IT_LATCH1_REG + i, &value); | 709 | AB8500_IT_LATCH1_REG + ab8500_irq_regoffset[i], |
| 710 | &value); | ||
| 481 | set_register_interruptible(ab8500, AB8500_INTERRUPT, | 711 | set_register_interruptible(ab8500, AB8500_INTERRUPT, |
| 482 | AB8500_IT_MASK1_REG + i, 0xff); | 712 | AB8500_IT_MASK1_REG + ab8500_irq_regoffset[i], 0xff); |
| 483 | } | 713 | } |
| 484 | 714 | ||
| 485 | ret = abx500_register_ops(ab8500->dev, &ab8500_ops); | 715 | ret = abx500_register_ops(ab8500->dev, &ab8500_ops); |
| @@ -495,7 +725,8 @@ int __devinit ab8500_init(struct ab8500 *ab8500) | |||
| 495 | return ret; | 725 | return ret; |
| 496 | 726 | ||
| 497 | ret = request_threaded_irq(ab8500->irq, NULL, ab8500_irq, | 727 | ret = request_threaded_irq(ab8500->irq, NULL, ab8500_irq, |
| 498 | IRQF_ONESHOT, "ab8500", ab8500); | 728 | IRQF_ONESHOT | IRQF_NO_SUSPEND, |
| 729 | "ab8500", ab8500); | ||
| 499 | if (ret) | 730 | if (ret) |
| 500 | goto out_removeirq; | 731 | goto out_removeirq; |
| 501 | } | 732 | } |
| @@ -506,6 +737,10 @@ int __devinit ab8500_init(struct ab8500 *ab8500) | |||
| 506 | if (ret) | 737 | if (ret) |
| 507 | goto out_freeirq; | 738 | goto out_freeirq; |
| 508 | 739 | ||
| 740 | ret = sysfs_create_group(&ab8500->dev->kobj, &ab8500_attr_group); | ||
| 741 | if (ret) | ||
| 742 | dev_err(ab8500->dev, "error creating sysfs entries\n"); | ||
| 743 | |||
| 509 | return ret; | 744 | return ret; |
| 510 | 745 | ||
| 511 | out_freeirq: | 746 | out_freeirq: |
| @@ -519,6 +754,7 @@ out_removeirq: | |||
| 519 | 754 | ||
| 520 | int __devexit ab8500_exit(struct ab8500 *ab8500) | 755 | int __devexit ab8500_exit(struct ab8500 *ab8500) |
| 521 | { | 756 | { |
| 757 | sysfs_remove_group(&ab8500->dev->kobj, &ab8500_attr_group); | ||
| 522 | mfd_remove_devices(ab8500->dev); | 758 | mfd_remove_devices(ab8500->dev); |
| 523 | if (ab8500->irq_base) { | 759 | if (ab8500->irq_base) { |
| 524 | free_irq(ab8500->irq, ab8500); | 760 | free_irq(ab8500->irq, ab8500); |
diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index 8d1e05a39815..3c1541ae7223 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c | |||
| @@ -24,9 +24,9 @@ static u32 debug_address; | |||
| 24 | * @perm: access permissions for the range | 24 | * @perm: access permissions for the range |
| 25 | */ | 25 | */ |
| 26 | struct ab8500_reg_range { | 26 | struct ab8500_reg_range { |
| 27 | u8 first; | 27 | u8 first; |
| 28 | u8 last; | 28 | u8 last; |
| 29 | u8 perm; | 29 | u8 perm; |
| 30 | }; | 30 | }; |
| 31 | 31 | ||
| 32 | /** | 32 | /** |
| @@ -36,9 +36,9 @@ struct ab8500_reg_range { | |||
| 36 | * @range: the list of register ranges | 36 | * @range: the list of register ranges |
| 37 | */ | 37 | */ |
| 38 | struct ab8500_i2c_ranges { | 38 | struct ab8500_i2c_ranges { |
| 39 | u8 num_ranges; | 39 | u8 num_ranges; |
| 40 | u8 bankid; | 40 | u8 bankid; |
| 41 | const struct ab8500_reg_range *range; | 41 | const struct ab8500_reg_range *range; |
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| 44 | #define AB8500_NAME_STRING "ab8500" | 44 | #define AB8500_NAME_STRING "ab8500" |
| @@ -47,521 +47,521 @@ struct ab8500_i2c_ranges { | |||
| 47 | #define AB8500_REV_REG 0x80 | 47 | #define AB8500_REV_REG 0x80 |
| 48 | 48 | ||
| 49 | static struct ab8500_i2c_ranges debug_ranges[AB8500_NUM_BANKS] = { | 49 | static struct ab8500_i2c_ranges debug_ranges[AB8500_NUM_BANKS] = { |
| 50 | [0x0] = { | 50 | [0x0] = { |
| 51 | .num_ranges = 0, | 51 | .num_ranges = 0, |
| 52 | .range = 0, | 52 | .range = 0, |
| 53 | }, | 53 | }, |
| 54 | [AB8500_SYS_CTRL1_BLOCK] = { | 54 | [AB8500_SYS_CTRL1_BLOCK] = { |
| 55 | .num_ranges = 3, | 55 | .num_ranges = 3, |
| 56 | .range = (struct ab8500_reg_range[]) { | 56 | .range = (struct ab8500_reg_range[]) { |
| 57 | { | 57 | { |
| 58 | .first = 0x00, | 58 | .first = 0x00, |
| 59 | .last = 0x02, | 59 | .last = 0x02, |
| 60 | }, | 60 | }, |
| 61 | { | 61 | { |
| 62 | .first = 0x42, | 62 | .first = 0x42, |
| 63 | .last = 0x42, | 63 | .last = 0x42, |
| 64 | }, | 64 | }, |
| 65 | { | 65 | { |
| 66 | .first = 0x80, | 66 | .first = 0x80, |
| 67 | .last = 0x81, | 67 | .last = 0x81, |
| 68 | }, | 68 | }, |
| 69 | }, | 69 | }, |
| 70 | }, | 70 | }, |
| 71 | [AB8500_SYS_CTRL2_BLOCK] = { | 71 | [AB8500_SYS_CTRL2_BLOCK] = { |
| 72 | .num_ranges = 4, | 72 | .num_ranges = 4, |
| 73 | .range = (struct ab8500_reg_range[]) { | 73 | .range = (struct ab8500_reg_range[]) { |
| 74 | { | 74 | { |
| 75 | .first = 0x00, | 75 | .first = 0x00, |
| 76 | .last = 0x0D, | 76 | .last = 0x0D, |
| 77 | }, | 77 | }, |
| 78 | { | 78 | { |
| 79 | .first = 0x0F, | 79 | .first = 0x0F, |
| 80 | .last = 0x17, | 80 | .last = 0x17, |
| 81 | }, | 81 | }, |
| 82 | { | 82 | { |
| 83 | .first = 0x30, | 83 | .first = 0x30, |
| 84 | .last = 0x30, | 84 | .last = 0x30, |
| 85 | }, | 85 | }, |
| 86 | { | 86 | { |
| 87 | .first = 0x32, | 87 | .first = 0x32, |
| 88 | .last = 0x33, | 88 | .last = 0x33, |
| 89 | }, | 89 | }, |
| 90 | }, | 90 | }, |
| 91 | }, | 91 | }, |
| 92 | [AB8500_REGU_CTRL1] = { | 92 | [AB8500_REGU_CTRL1] = { |
| 93 | .num_ranges = 3, | 93 | .num_ranges = 3, |
| 94 | .range = (struct ab8500_reg_range[]) { | 94 | .range = (struct ab8500_reg_range[]) { |
| 95 | { | 95 | { |
| 96 | .first = 0x00, | 96 | .first = 0x00, |
| 97 | .last = 0x00, | 97 | .last = 0x00, |
| 98 | }, | 98 | }, |
| 99 | { | 99 | { |
| 100 | .first = 0x03, | 100 | .first = 0x03, |
| 101 | .last = 0x10, | 101 | .last = 0x10, |
| 102 | }, | 102 | }, |
| 103 | { | 103 | { |
| 104 | .first = 0x80, | 104 | .first = 0x80, |
| 105 | .last = 0x84, | 105 | .last = 0x84, |
| 106 | }, | 106 | }, |
| 107 | }, | 107 | }, |
| 108 | }, | 108 | }, |
| 109 | [AB8500_REGU_CTRL2] = { | 109 | [AB8500_REGU_CTRL2] = { |
| 110 | .num_ranges = 5, | 110 | .num_ranges = 5, |
| 111 | .range = (struct ab8500_reg_range[]) { | 111 | .range = (struct ab8500_reg_range[]) { |
| 112 | { | 112 | { |
| 113 | .first = 0x00, | 113 | .first = 0x00, |
| 114 | .last = 0x15, | 114 | .last = 0x15, |
| 115 | }, | 115 | }, |
| 116 | { | 116 | { |
| 117 | .first = 0x17, | 117 | .first = 0x17, |
| 118 | .last = 0x19, | 118 | .last = 0x19, |
| 119 | }, | 119 | }, |
| 120 | { | 120 | { |
| 121 | .first = 0x1B, | 121 | .first = 0x1B, |
| 122 | .last = 0x1D, | 122 | .last = 0x1D, |
| 123 | }, | 123 | }, |
| 124 | { | 124 | { |
| 125 | .first = 0x1F, | 125 | .first = 0x1F, |
| 126 | .last = 0x22, | 126 | .last = 0x22, |
| 127 | }, | 127 | }, |
| 128 | { | 128 | { |
| 129 | .first = 0x40, | 129 | .first = 0x40, |
| 130 | .last = 0x44, | 130 | .last = 0x44, |
| 131 | }, | 131 | }, |
| 132 | /* 0x80-0x8B is SIM registers and should | 132 | /* 0x80-0x8B is SIM registers and should |
| 133 | * not be accessed from here */ | 133 | * not be accessed from here */ |
| 134 | }, | 134 | }, |
| 135 | }, | 135 | }, |
| 136 | [AB8500_USB] = { | 136 | [AB8500_USB] = { |
| 137 | .num_ranges = 2, | 137 | .num_ranges = 2, |
| 138 | .range = (struct ab8500_reg_range[]) { | 138 | .range = (struct ab8500_reg_range[]) { |
| 139 | { | 139 | { |
| 140 | .first = 0x80, | 140 | .first = 0x80, |
| 141 | .last = 0x83, | 141 | .last = 0x83, |
| 142 | }, | 142 | }, |
| 143 | { | 143 | { |
| 144 | .first = 0x87, | 144 | .first = 0x87, |
| 145 | .last = 0x8A, | 145 | .last = 0x8A, |
| 146 | }, | 146 | }, |
| 147 | }, | 147 | }, |
| 148 | }, | 148 | }, |
| 149 | [AB8500_TVOUT] = { | 149 | [AB8500_TVOUT] = { |
| 150 | .num_ranges = 9, | 150 | .num_ranges = 9, |
| 151 | .range = (struct ab8500_reg_range[]) { | 151 | .range = (struct ab8500_reg_range[]) { |
| 152 | { | 152 | { |
| 153 | .first = 0x00, | 153 | .first = 0x00, |
| 154 | .last = 0x12, | 154 | .last = 0x12, |
| 155 | }, | 155 | }, |
| 156 | { | 156 | { |
| 157 | .first = 0x15, | 157 | .first = 0x15, |
| 158 | .last = 0x17, | 158 | .last = 0x17, |
| 159 | }, | 159 | }, |
| 160 | { | 160 | { |
| 161 | .first = 0x19, | 161 | .first = 0x19, |
| 162 | .last = 0x21, | 162 | .last = 0x21, |
| 163 | }, | 163 | }, |
| 164 | { | 164 | { |
| 165 | .first = 0x27, | 165 | .first = 0x27, |
| 166 | .last = 0x2C, | 166 | .last = 0x2C, |
| 167 | }, | 167 | }, |
| 168 | { | 168 | { |
| 169 | .first = 0x41, | 169 | .first = 0x41, |
| 170 | .last = 0x41, | 170 | .last = 0x41, |
| 171 | }, | 171 | }, |
| 172 | { | 172 | { |
| 173 | .first = 0x45, | 173 | .first = 0x45, |
| 174 | .last = 0x5B, | 174 | .last = 0x5B, |
| 175 | }, | 175 | }, |
| 176 | { | 176 | { |
| 177 | .first = 0x5D, | 177 | .first = 0x5D, |
| 178 | .last = 0x5D, | 178 | .last = 0x5D, |
| 179 | }, | 179 | }, |
| 180 | { | 180 | { |
| 181 | .first = 0x69, | 181 | .first = 0x69, |
| 182 | .last = 0x69, | 182 | .last = 0x69, |
| 183 | }, | 183 | }, |
| 184 | { | 184 | { |
| 185 | .first = 0x80, | 185 | .first = 0x80, |
| 186 | .last = 0x81, | 186 | .last = 0x81, |
| 187 | }, | 187 | }, |
| 188 | }, | 188 | }, |
| 189 | }, | 189 | }, |
| 190 | [AB8500_DBI] = { | 190 | [AB8500_DBI] = { |
| 191 | .num_ranges = 0, | 191 | .num_ranges = 0, |
| 192 | .range = 0, | 192 | .range = NULL, |
| 193 | }, | 193 | }, |
| 194 | [AB8500_ECI_AV_ACC] = { | 194 | [AB8500_ECI_AV_ACC] = { |
| 195 | .num_ranges = 1, | 195 | .num_ranges = 1, |
| 196 | .range = (struct ab8500_reg_range[]) { | 196 | .range = (struct ab8500_reg_range[]) { |
| 197 | { | 197 | { |
| 198 | .first = 0x80, | 198 | .first = 0x80, |
| 199 | .last = 0x82, | 199 | .last = 0x82, |
| 200 | }, | 200 | }, |
| 201 | }, | 201 | }, |
| 202 | }, | 202 | }, |
| 203 | [0x9] = { | 203 | [0x9] = { |
| 204 | .num_ranges = 0, | 204 | .num_ranges = 0, |
| 205 | .range = 0, | 205 | .range = NULL, |
| 206 | }, | 206 | }, |
| 207 | [AB8500_GPADC] = { | 207 | [AB8500_GPADC] = { |
| 208 | .num_ranges = 1, | 208 | .num_ranges = 1, |
| 209 | .range = (struct ab8500_reg_range[]) { | 209 | .range = (struct ab8500_reg_range[]) { |
| 210 | { | 210 | { |
| 211 | .first = 0x00, | 211 | .first = 0x00, |
| 212 | .last = 0x08, | 212 | .last = 0x08, |
| 213 | }, | 213 | }, |
| 214 | }, | 214 | }, |
| 215 | }, | 215 | }, |
| 216 | [AB8500_CHARGER] = { | 216 | [AB8500_CHARGER] = { |
| 217 | .num_ranges = 8, | 217 | .num_ranges = 8, |
| 218 | .range = (struct ab8500_reg_range[]) { | 218 | .range = (struct ab8500_reg_range[]) { |
| 219 | { | 219 | { |
| 220 | .first = 0x00, | 220 | .first = 0x00, |
| 221 | .last = 0x03, | 221 | .last = 0x03, |
| 222 | }, | 222 | }, |
| 223 | { | 223 | { |
| 224 | .first = 0x05, | 224 | .first = 0x05, |
| 225 | .last = 0x05, | 225 | .last = 0x05, |
| 226 | }, | 226 | }, |
| 227 | { | 227 | { |
| 228 | .first = 0x40, | 228 | .first = 0x40, |
| 229 | .last = 0x40, | 229 | .last = 0x40, |
| 230 | }, | 230 | }, |
| 231 | { | 231 | { |
| 232 | .first = 0x42, | 232 | .first = 0x42, |
| 233 | .last = 0x42, | 233 | .last = 0x42, |
| 234 | }, | 234 | }, |
| 235 | { | 235 | { |
| 236 | .first = 0x44, | 236 | .first = 0x44, |
| 237 | .last = 0x44, | 237 | .last = 0x44, |
| 238 | }, | 238 | }, |
| 239 | { | 239 | { |
| 240 | .first = 0x50, | 240 | .first = 0x50, |
| 241 | .last = 0x55, | 241 | .last = 0x55, |
| 242 | }, | 242 | }, |
| 243 | { | 243 | { |
| 244 | .first = 0x80, | 244 | .first = 0x80, |
| 245 | .last = 0x82, | 245 | .last = 0x82, |
| 246 | }, | 246 | }, |
| 247 | { | 247 | { |
| 248 | .first = 0xC0, | 248 | .first = 0xC0, |
| 249 | .last = 0xC2, | 249 | .last = 0xC2, |
| 250 | }, | 250 | }, |
| 251 | }, | 251 | }, |
| 252 | }, | 252 | }, |
| 253 | [AB8500_GAS_GAUGE] = { | 253 | [AB8500_GAS_GAUGE] = { |
| 254 | .num_ranges = 3, | 254 | .num_ranges = 3, |
| 255 | .range = (struct ab8500_reg_range[]) { | 255 | .range = (struct ab8500_reg_range[]) { |
| 256 | { | 256 | { |
| 257 | .first = 0x00, | 257 | .first = 0x00, |
| 258 | .last = 0x00, | 258 | .last = 0x00, |
| 259 | }, | 259 | }, |
| 260 | { | 260 | { |
| 261 | .first = 0x07, | 261 | .first = 0x07, |
| 262 | .last = 0x0A, | 262 | .last = 0x0A, |
| 263 | }, | 263 | }, |
| 264 | { | 264 | { |
| 265 | .first = 0x10, | 265 | .first = 0x10, |
| 266 | .last = 0x14, | 266 | .last = 0x14, |
| 267 | }, | 267 | }, |
| 268 | }, | 268 | }, |
| 269 | }, | 269 | }, |
| 270 | [AB8500_AUDIO] = { | 270 | [AB8500_AUDIO] = { |
| 271 | .num_ranges = 1, | 271 | .num_ranges = 1, |
| 272 | .range = (struct ab8500_reg_range[]) { | 272 | .range = (struct ab8500_reg_range[]) { |
| 273 | { | 273 | { |
| 274 | .first = 0x00, | 274 | .first = 0x00, |
| 275 | .last = 0x6F, | 275 | .last = 0x6F, |
| 276 | }, | 276 | }, |
| 277 | }, | 277 | }, |
| 278 | }, | 278 | }, |
| 279 | [AB8500_INTERRUPT] = { | 279 | [AB8500_INTERRUPT] = { |
| 280 | .num_ranges = 0, | 280 | .num_ranges = 0, |
| 281 | .range = 0, | 281 | .range = NULL, |
| 282 | }, | 282 | }, |
| 283 | [AB8500_RTC] = { | 283 | [AB8500_RTC] = { |
| 284 | .num_ranges = 1, | 284 | .num_ranges = 1, |
| 285 | .range = (struct ab8500_reg_range[]) { | 285 | .range = (struct ab8500_reg_range[]) { |
| 286 | { | 286 | { |
| 287 | .first = 0x00, | 287 | .first = 0x00, |
| 288 | .last = 0x0F, | 288 | .last = 0x0F, |
| 289 | }, | 289 | }, |
| 290 | }, | 290 | }, |
| 291 | }, | 291 | }, |
| 292 | [AB8500_MISC] = { | 292 | [AB8500_MISC] = { |
| 293 | .num_ranges = 8, | 293 | .num_ranges = 8, |
| 294 | .range = (struct ab8500_reg_range[]) { | 294 | .range = (struct ab8500_reg_range[]) { |
| 295 | { | 295 | { |
| 296 | .first = 0x00, | 296 | .first = 0x00, |
| 297 | .last = 0x05, | 297 | .last = 0x05, |
| 298 | }, | 298 | }, |
| 299 | { | 299 | { |
| 300 | .first = 0x10, | 300 | .first = 0x10, |
| 301 | .last = 0x15, | 301 | .last = 0x15, |
| 302 | }, | 302 | }, |
| 303 | { | 303 | { |
| 304 | .first = 0x20, | 304 | .first = 0x20, |
| 305 | .last = 0x25, | 305 | .last = 0x25, |
| 306 | }, | 306 | }, |
| 307 | { | 307 | { |
| 308 | .first = 0x30, | 308 | .first = 0x30, |
| 309 | .last = 0x35, | 309 | .last = 0x35, |
| 310 | }, | 310 | }, |
| 311 | { | 311 | { |
| 312 | .first = 0x40, | 312 | .first = 0x40, |
| 313 | .last = 0x45, | 313 | .last = 0x45, |
| 314 | }, | 314 | }, |
| 315 | { | 315 | { |
| 316 | .first = 0x50, | 316 | .first = 0x50, |
| 317 | .last = 0x50, | 317 | .last = 0x50, |
| 318 | }, | 318 | }, |
| 319 | { | 319 | { |
| 320 | .first = 0x60, | 320 | .first = 0x60, |
| 321 | .last = 0x67, | 321 | .last = 0x67, |
| 322 | }, | 322 | }, |
| 323 | { | 323 | { |
| 324 | .first = 0x80, | 324 | .first = 0x80, |
| 325 | .last = 0x80, | 325 | .last = 0x80, |
| 326 | }, | 326 | }, |
| 327 | }, | 327 | }, |
| 328 | }, | 328 | }, |
| 329 | [0x11] = { | 329 | [0x11] = { |
| 330 | .num_ranges = 0, | 330 | .num_ranges = 0, |
| 331 | .range = 0, | 331 | .range = NULL, |
| 332 | }, | 332 | }, |
| 333 | [0x12] = { | 333 | [0x12] = { |
| 334 | .num_ranges = 0, | 334 | .num_ranges = 0, |
| 335 | .range = 0, | 335 | .range = NULL, |
| 336 | }, | 336 | }, |
| 337 | [0x13] = { | 337 | [0x13] = { |
| 338 | .num_ranges = 0, | 338 | .num_ranges = 0, |
| 339 | .range = 0, | 339 | .range = NULL, |
| 340 | }, | 340 | }, |
| 341 | [0x14] = { | 341 | [0x14] = { |
| 342 | .num_ranges = 0, | 342 | .num_ranges = 0, |
| 343 | .range = 0, | 343 | .range = NULL, |
| 344 | }, | 344 | }, |
| 345 | [AB8500_OTP_EMUL] = { | 345 | [AB8500_OTP_EMUL] = { |
| 346 | .num_ranges = 1, | 346 | .num_ranges = 1, |
| 347 | .range = (struct ab8500_reg_range[]) { | 347 | .range = (struct ab8500_reg_range[]) { |
| 348 | { | 348 | { |
| 349 | .first = 0x01, | 349 | .first = 0x01, |
| 350 | .last = 0x0F, | 350 | .last = 0x0F, |
| 351 | }, | 351 | }, |
| 352 | }, | 352 | }, |
| 353 | }, | 353 | }, |
| 354 | }; | 354 | }; |
| 355 | 355 | ||
| 356 | static int ab8500_registers_print(struct seq_file *s, void *p) | 356 | static int ab8500_registers_print(struct seq_file *s, void *p) |
| 357 | { | 357 | { |
| 358 | struct device *dev = s->private; | 358 | struct device *dev = s->private; |
| 359 | unsigned int i; | 359 | unsigned int i; |
| 360 | u32 bank = debug_bank; | 360 | u32 bank = debug_bank; |
| 361 | 361 | ||
| 362 | seq_printf(s, AB8500_NAME_STRING " register values:\n"); | 362 | seq_printf(s, AB8500_NAME_STRING " register values:\n"); |
| 363 | 363 | ||
| 364 | seq_printf(s, " bank %u:\n", bank); | 364 | seq_printf(s, " bank %u:\n", bank); |
| 365 | for (i = 0; i < debug_ranges[bank].num_ranges; i++) { | 365 | for (i = 0; i < debug_ranges[bank].num_ranges; i++) { |
| 366 | u32 reg; | 366 | u32 reg; |
| 367 | 367 | ||
| 368 | for (reg = debug_ranges[bank].range[i].first; | 368 | for (reg = debug_ranges[bank].range[i].first; |
| 369 | reg <= debug_ranges[bank].range[i].last; | 369 | reg <= debug_ranges[bank].range[i].last; |
| 370 | reg++) { | 370 | reg++) { |
| 371 | u8 value; | 371 | u8 value; |
| 372 | int err; | 372 | int err; |
| 373 | 373 | ||
| 374 | err = abx500_get_register_interruptible(dev, | 374 | err = abx500_get_register_interruptible(dev, |
| 375 | (u8)bank, (u8)reg, &value); | 375 | (u8)bank, (u8)reg, &value); |
| 376 | if (err < 0) { | 376 | if (err < 0) { |
| 377 | dev_err(dev, "ab->read fail %d\n", err); | 377 | dev_err(dev, "ab->read fail %d\n", err); |
| 378 | return err; | 378 | return err; |
| 379 | } | 379 | } |
| 380 | 380 | ||
| 381 | err = seq_printf(s, " [%u/0x%02X]: 0x%02X\n", bank, | 381 | err = seq_printf(s, " [%u/0x%02X]: 0x%02X\n", bank, |
| 382 | reg, value); | 382 | reg, value); |
| 383 | if (err < 0) { | 383 | if (err < 0) { |
| 384 | dev_err(dev, "seq_printf overflow\n"); | 384 | dev_err(dev, "seq_printf overflow\n"); |
| 385 | /* Error is not returned here since | 385 | /* Error is not returned here since |
| 386 | * the output is wanted in any case */ | 386 | * the output is wanted in any case */ |
| 387 | return 0; | 387 | return 0; |
| 388 | } | 388 | } |
| 389 | } | 389 | } |
| 390 | } | 390 | } |
| 391 | return 0; | 391 | return 0; |
| 392 | } | 392 | } |
| 393 | 393 | ||
| 394 | static int ab8500_registers_open(struct inode *inode, struct file *file) | 394 | static int ab8500_registers_open(struct inode *inode, struct file *file) |
| 395 | { | 395 | { |
| 396 | return single_open(file, ab8500_registers_print, inode->i_private); | 396 | return single_open(file, ab8500_registers_print, inode->i_private); |
| 397 | } | 397 | } |
| 398 | 398 | ||
| 399 | static const struct file_operations ab8500_registers_fops = { | 399 | static const struct file_operations ab8500_registers_fops = { |
| 400 | .open = ab8500_registers_open, | 400 | .open = ab8500_registers_open, |
| 401 | .read = seq_read, | 401 | .read = seq_read, |
| 402 | .llseek = seq_lseek, | 402 | .llseek = seq_lseek, |
| 403 | .release = single_release, | 403 | .release = single_release, |
| 404 | .owner = THIS_MODULE, | 404 | .owner = THIS_MODULE, |
| 405 | }; | 405 | }; |
| 406 | 406 | ||
| 407 | static int ab8500_bank_print(struct seq_file *s, void *p) | 407 | static int ab8500_bank_print(struct seq_file *s, void *p) |
| 408 | { | 408 | { |
| 409 | return seq_printf(s, "%d\n", debug_bank); | 409 | return seq_printf(s, "%d\n", debug_bank); |
| 410 | } | 410 | } |
| 411 | 411 | ||
| 412 | static int ab8500_bank_open(struct inode *inode, struct file *file) | 412 | static int ab8500_bank_open(struct inode *inode, struct file *file) |
| 413 | { | 413 | { |
| 414 | return single_open(file, ab8500_bank_print, inode->i_private); | 414 | return single_open(file, ab8500_bank_print, inode->i_private); |
| 415 | } | 415 | } |
| 416 | 416 | ||
| 417 | static ssize_t ab8500_bank_write(struct file *file, | 417 | static ssize_t ab8500_bank_write(struct file *file, |
| 418 | const char __user *user_buf, | 418 | const char __user *user_buf, |
| 419 | size_t count, loff_t *ppos) | 419 | size_t count, loff_t *ppos) |
| 420 | { | 420 | { |
| 421 | struct device *dev = ((struct seq_file *)(file->private_data))->private; | 421 | struct device *dev = ((struct seq_file *)(file->private_data))->private; |
| 422 | char buf[32]; | 422 | char buf[32]; |
| 423 | int buf_size; | 423 | int buf_size; |
| 424 | unsigned long user_bank; | 424 | unsigned long user_bank; |
| 425 | int err; | 425 | int err; |
| 426 | 426 | ||
| 427 | /* Get userspace string and assure termination */ | 427 | /* Get userspace string and assure termination */ |
| 428 | buf_size = min(count, (sizeof(buf) - 1)); | 428 | buf_size = min(count, (sizeof(buf) - 1)); |
| 429 | if (copy_from_user(buf, user_buf, buf_size)) | 429 | if (copy_from_user(buf, user_buf, buf_size)) |
| 430 | return -EFAULT; | 430 | return -EFAULT; |
| 431 | buf[buf_size] = 0; | 431 | buf[buf_size] = 0; |
| 432 | 432 | ||
| 433 | err = strict_strtoul(buf, 0, &user_bank); | 433 | err = strict_strtoul(buf, 0, &user_bank); |
| 434 | if (err) | 434 | if (err) |
| 435 | return -EINVAL; | 435 | return -EINVAL; |
| 436 | 436 | ||
| 437 | if (user_bank >= AB8500_NUM_BANKS) { | 437 | if (user_bank >= AB8500_NUM_BANKS) { |
| 438 | dev_err(dev, "debugfs error input > number of banks\n"); | 438 | dev_err(dev, "debugfs error input > number of banks\n"); |
| 439 | return -EINVAL; | 439 | return -EINVAL; |
| 440 | } | 440 | } |
| 441 | 441 | ||
| 442 | debug_bank = user_bank; | 442 | debug_bank = user_bank; |
| 443 | 443 | ||
| 444 | return buf_size; | 444 | return buf_size; |
| 445 | } | 445 | } |
| 446 | 446 | ||
| 447 | static int ab8500_address_print(struct seq_file *s, void *p) | 447 | static int ab8500_address_print(struct seq_file *s, void *p) |
| 448 | { | 448 | { |
| 449 | return seq_printf(s, "0x%02X\n", debug_address); | 449 | return seq_printf(s, "0x%02X\n", debug_address); |
| 450 | } | 450 | } |
| 451 | 451 | ||
| 452 | static int ab8500_address_open(struct inode *inode, struct file *file) | 452 | static int ab8500_address_open(struct inode *inode, struct file *file) |
| 453 | { | 453 | { |
| 454 | return single_open(file, ab8500_address_print, inode->i_private); | 454 | return single_open(file, ab8500_address_print, inode->i_private); |
| 455 | } | 455 | } |
| 456 | 456 | ||
| 457 | static ssize_t ab8500_address_write(struct file *file, | 457 | static ssize_t ab8500_address_write(struct file *file, |
| 458 | const char __user *user_buf, | 458 | const char __user *user_buf, |
| 459 | size_t count, loff_t *ppos) | 459 | size_t count, loff_t *ppos) |
| 460 | { | 460 | { |
| 461 | struct device *dev = ((struct seq_file *)(file->private_data))->private; | 461 | struct device *dev = ((struct seq_file *)(file->private_data))->private; |
| 462 | char buf[32]; | 462 | char buf[32]; |
| 463 | int buf_size; | 463 | int buf_size; |
| 464 | unsigned long user_address; | 464 | unsigned long user_address; |
| 465 | int err; | 465 | int err; |
| 466 | 466 | ||
| 467 | /* Get userspace string and assure termination */ | 467 | /* Get userspace string and assure termination */ |
| 468 | buf_size = min(count, (sizeof(buf) - 1)); | 468 | buf_size = min(count, (sizeof(buf) - 1)); |
| 469 | if (copy_from_user(buf, user_buf, buf_size)) | 469 | if (copy_from_user(buf, user_buf, buf_size)) |
| 470 | return -EFAULT; | 470 | return -EFAULT; |
| 471 | buf[buf_size] = 0; | 471 | buf[buf_size] = 0; |
| 472 | 472 | ||
| 473 | err = strict_strtoul(buf, 0, &user_address); | 473 | err = strict_strtoul(buf, 0, &user_address); |
| 474 | if (err) | 474 | if (err) |
| 475 | return -EINVAL; | 475 | return -EINVAL; |
| 476 | if (user_address > 0xff) { | 476 | if (user_address > 0xff) { |
| 477 | dev_err(dev, "debugfs error input > 0xff\n"); | 477 | dev_err(dev, "debugfs error input > 0xff\n"); |
| 478 | return -EINVAL; | 478 | return -EINVAL; |
| 479 | } | 479 | } |
| 480 | debug_address = user_address; | 480 | debug_address = user_address; |
| 481 | return buf_size; | 481 | return buf_size; |
| 482 | } | 482 | } |
| 483 | 483 | ||
| 484 | static int ab8500_val_print(struct seq_file *s, void *p) | 484 | static int ab8500_val_print(struct seq_file *s, void *p) |
| 485 | { | 485 | { |
| 486 | struct device *dev = s->private; | 486 | struct device *dev = s->private; |
| 487 | int ret; | 487 | int ret; |
| 488 | u8 regvalue; | 488 | u8 regvalue; |
| 489 | 489 | ||
| 490 | ret = abx500_get_register_interruptible(dev, | 490 | ret = abx500_get_register_interruptible(dev, |
| 491 | (u8)debug_bank, (u8)debug_address, ®value); | 491 | (u8)debug_bank, (u8)debug_address, ®value); |
| 492 | if (ret < 0) { | 492 | if (ret < 0) { |
| 493 | dev_err(dev, "abx500_get_reg fail %d, %d\n", | 493 | dev_err(dev, "abx500_get_reg fail %d, %d\n", |
| 494 | ret, __LINE__); | 494 | ret, __LINE__); |
| 495 | return -EINVAL; | 495 | return -EINVAL; |
| 496 | } | 496 | } |
| 497 | seq_printf(s, "0x%02X\n", regvalue); | 497 | seq_printf(s, "0x%02X\n", regvalue); |
| 498 | 498 | ||
| 499 | return 0; | 499 | return 0; |
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | static int ab8500_val_open(struct inode *inode, struct file *file) | 502 | static int ab8500_val_open(struct inode *inode, struct file *file) |
| 503 | { | 503 | { |
| 504 | return single_open(file, ab8500_val_print, inode->i_private); | 504 | return single_open(file, ab8500_val_print, inode->i_private); |
| 505 | } | 505 | } |
| 506 | 506 | ||
| 507 | static ssize_t ab8500_val_write(struct file *file, | 507 | static ssize_t ab8500_val_write(struct file *file, |
| 508 | const char __user *user_buf, | 508 | const char __user *user_buf, |
| 509 | size_t count, loff_t *ppos) | 509 | size_t count, loff_t *ppos) |
| 510 | { | 510 | { |
| 511 | struct device *dev = ((struct seq_file *)(file->private_data))->private; | 511 | struct device *dev = ((struct seq_file *)(file->private_data))->private; |
| 512 | char buf[32]; | 512 | char buf[32]; |
| 513 | int buf_size; | 513 | int buf_size; |
| 514 | unsigned long user_val; | 514 | unsigned long user_val; |
| 515 | int err; | 515 | int err; |
| 516 | 516 | ||
| 517 | /* Get userspace string and assure termination */ | 517 | /* Get userspace string and assure termination */ |
| 518 | buf_size = min(count, (sizeof(buf)-1)); | 518 | buf_size = min(count, (sizeof(buf)-1)); |
| 519 | if (copy_from_user(buf, user_buf, buf_size)) | 519 | if (copy_from_user(buf, user_buf, buf_size)) |
| 520 | return -EFAULT; | 520 | return -EFAULT; |
| 521 | buf[buf_size] = 0; | 521 | buf[buf_size] = 0; |
| 522 | 522 | ||
| 523 | err = strict_strtoul(buf, 0, &user_val); | 523 | err = strict_strtoul(buf, 0, &user_val); |
| 524 | if (err) | 524 | if (err) |
| 525 | return -EINVAL; | 525 | return -EINVAL; |
| 526 | if (user_val > 0xff) { | 526 | if (user_val > 0xff) { |
| 527 | dev_err(dev, "debugfs error input > 0xff\n"); | 527 | dev_err(dev, "debugfs error input > 0xff\n"); |
| 528 | return -EINVAL; | 528 | return -EINVAL; |
| 529 | } | 529 | } |
| 530 | err = abx500_set_register_interruptible(dev, | 530 | err = abx500_set_register_interruptible(dev, |
| 531 | (u8)debug_bank, debug_address, (u8)user_val); | 531 | (u8)debug_bank, debug_address, (u8)user_val); |
| 532 | if (err < 0) { | 532 | if (err < 0) { |
| 533 | printk(KERN_ERR "abx500_set_reg failed %d, %d", err, __LINE__); | 533 | printk(KERN_ERR "abx500_set_reg failed %d, %d", err, __LINE__); |
| 534 | return -EINVAL; | 534 | return -EINVAL; |
| 535 | } | 535 | } |
| 536 | 536 | ||
| 537 | return buf_size; | 537 | return buf_size; |
| 538 | } | 538 | } |
| 539 | 539 | ||
| 540 | static const struct file_operations ab8500_bank_fops = { | 540 | static const struct file_operations ab8500_bank_fops = { |
| 541 | .open = ab8500_bank_open, | 541 | .open = ab8500_bank_open, |
| 542 | .write = ab8500_bank_write, | 542 | .write = ab8500_bank_write, |
| 543 | .read = seq_read, | 543 | .read = seq_read, |
| 544 | .llseek = seq_lseek, | 544 | .llseek = seq_lseek, |
| 545 | .release = single_release, | 545 | .release = single_release, |
| 546 | .owner = THIS_MODULE, | 546 | .owner = THIS_MODULE, |
| 547 | }; | 547 | }; |
| 548 | 548 | ||
| 549 | static const struct file_operations ab8500_address_fops = { | 549 | static const struct file_operations ab8500_address_fops = { |
| 550 | .open = ab8500_address_open, | 550 | .open = ab8500_address_open, |
| 551 | .write = ab8500_address_write, | 551 | .write = ab8500_address_write, |
| 552 | .read = seq_read, | 552 | .read = seq_read, |
| 553 | .llseek = seq_lseek, | 553 | .llseek = seq_lseek, |
| 554 | .release = single_release, | 554 | .release = single_release, |
| 555 | .owner = THIS_MODULE, | 555 | .owner = THIS_MODULE, |
| 556 | }; | 556 | }; |
| 557 | 557 | ||
| 558 | static const struct file_operations ab8500_val_fops = { | 558 | static const struct file_operations ab8500_val_fops = { |
| 559 | .open = ab8500_val_open, | 559 | .open = ab8500_val_open, |
| 560 | .write = ab8500_val_write, | 560 | .write = ab8500_val_write, |
| 561 | .read = seq_read, | 561 | .read = seq_read, |
| 562 | .llseek = seq_lseek, | 562 | .llseek = seq_lseek, |
| 563 | .release = single_release, | 563 | .release = single_release, |
| 564 | .owner = THIS_MODULE, | 564 | .owner = THIS_MODULE, |
| 565 | }; | 565 | }; |
| 566 | 566 | ||
| 567 | static struct dentry *ab8500_dir; | 567 | static struct dentry *ab8500_dir; |
| @@ -572,77 +572,77 @@ static struct dentry *ab8500_val_file; | |||
| 572 | 572 | ||
| 573 | static int __devinit ab8500_debug_probe(struct platform_device *plf) | 573 | static int __devinit ab8500_debug_probe(struct platform_device *plf) |
| 574 | { | 574 | { |
| 575 | debug_bank = AB8500_MISC; | 575 | debug_bank = AB8500_MISC; |
| 576 | debug_address = AB8500_REV_REG & 0x00FF; | 576 | debug_address = AB8500_REV_REG & 0x00FF; |
| 577 | 577 | ||
| 578 | ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL); | 578 | ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL); |
| 579 | if (!ab8500_dir) | 579 | if (!ab8500_dir) |
| 580 | goto exit_no_debugfs; | 580 | goto exit_no_debugfs; |
| 581 | 581 | ||
| 582 | ab8500_reg_file = debugfs_create_file("all-bank-registers", | 582 | ab8500_reg_file = debugfs_create_file("all-bank-registers", |
| 583 | S_IRUGO, ab8500_dir, &plf->dev, &ab8500_registers_fops); | 583 | S_IRUGO, ab8500_dir, &plf->dev, &ab8500_registers_fops); |
| 584 | if (!ab8500_reg_file) | 584 | if (!ab8500_reg_file) |
| 585 | goto exit_destroy_dir; | 585 | goto exit_destroy_dir; |
| 586 | 586 | ||
| 587 | ab8500_bank_file = debugfs_create_file("register-bank", | 587 | ab8500_bank_file = debugfs_create_file("register-bank", |
| 588 | (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_bank_fops); | 588 | (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_bank_fops); |
| 589 | if (!ab8500_bank_file) | 589 | if (!ab8500_bank_file) |
| 590 | goto exit_destroy_reg; | 590 | goto exit_destroy_reg; |
| 591 | 591 | ||
| 592 | ab8500_address_file = debugfs_create_file("register-address", | 592 | ab8500_address_file = debugfs_create_file("register-address", |
| 593 | (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, | 593 | (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, |
| 594 | &ab8500_address_fops); | 594 | &ab8500_address_fops); |
| 595 | if (!ab8500_address_file) | 595 | if (!ab8500_address_file) |
| 596 | goto exit_destroy_bank; | 596 | goto exit_destroy_bank; |
| 597 | 597 | ||
| 598 | ab8500_val_file = debugfs_create_file("register-value", | 598 | ab8500_val_file = debugfs_create_file("register-value", |
| 599 | (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_val_fops); | 599 | (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_val_fops); |
| 600 | if (!ab8500_val_file) | 600 | if (!ab8500_val_file) |
| 601 | goto exit_destroy_address; | 601 | goto exit_destroy_address; |
| 602 | 602 | ||
| 603 | return 0; | 603 | return 0; |
| 604 | 604 | ||
| 605 | exit_destroy_address: | 605 | exit_destroy_address: |
| 606 | debugfs_remove(ab8500_address_file); | 606 | debugfs_remove(ab8500_address_file); |
| 607 | exit_destroy_bank: | 607 | exit_destroy_bank: |
| 608 | debugfs_remove(ab8500_bank_file); | 608 | debugfs_remove(ab8500_bank_file); |
| 609 | exit_destroy_reg: | 609 | exit_destroy_reg: |
| 610 | debugfs_remove(ab8500_reg_file); | 610 | debugfs_remove(ab8500_reg_file); |
| 611 | exit_destroy_dir: | 611 | exit_destroy_dir: |
| 612 | debugfs_remove(ab8500_dir); | 612 | debugfs_remove(ab8500_dir); |
| 613 | exit_no_debugfs: | 613 | exit_no_debugfs: |
| 614 | dev_err(&plf->dev, "failed to create debugfs entries.\n"); | 614 | dev_err(&plf->dev, "failed to create debugfs entries.\n"); |
| 615 | return -ENOMEM; | 615 | return -ENOMEM; |
| 616 | } | 616 | } |
| 617 | 617 | ||
| 618 | static int __devexit ab8500_debug_remove(struct platform_device *plf) | 618 | static int __devexit ab8500_debug_remove(struct platform_device *plf) |
| 619 | { | 619 | { |
| 620 | debugfs_remove(ab8500_val_file); | 620 | debugfs_remove(ab8500_val_file); |
| 621 | debugfs_remove(ab8500_address_file); | 621 | debugfs_remove(ab8500_address_file); |
| 622 | debugfs_remove(ab8500_bank_file); | 622 | debugfs_remove(ab8500_bank_file); |
| 623 | debugfs_remove(ab8500_reg_file); | 623 | debugfs_remove(ab8500_reg_file); |
| 624 | debugfs_remove(ab8500_dir); | 624 | debugfs_remove(ab8500_dir); |
| 625 | 625 | ||
| 626 | return 0; | 626 | return 0; |
| 627 | } | 627 | } |
| 628 | 628 | ||
| 629 | static struct platform_driver ab8500_debug_driver = { | 629 | static struct platform_driver ab8500_debug_driver = { |
| 630 | .driver = { | 630 | .driver = { |
| 631 | .name = "ab8500-debug", | 631 | .name = "ab8500-debug", |
| 632 | .owner = THIS_MODULE, | 632 | .owner = THIS_MODULE, |
| 633 | }, | 633 | }, |
| 634 | .probe = ab8500_debug_probe, | 634 | .probe = ab8500_debug_probe, |
| 635 | .remove = __devexit_p(ab8500_debug_remove) | 635 | .remove = __devexit_p(ab8500_debug_remove) |
| 636 | }; | 636 | }; |
| 637 | 637 | ||
| 638 | static int __init ab8500_debug_init(void) | 638 | static int __init ab8500_debug_init(void) |
| 639 | { | 639 | { |
| 640 | return platform_driver_register(&ab8500_debug_driver); | 640 | return platform_driver_register(&ab8500_debug_driver); |
| 641 | } | 641 | } |
| 642 | 642 | ||
| 643 | static void __exit ab8500_debug_exit(void) | 643 | static void __exit ab8500_debug_exit(void) |
| 644 | { | 644 | { |
| 645 | platform_driver_unregister(&ab8500_debug_driver); | 645 | platform_driver_unregister(&ab8500_debug_driver); |
| 646 | } | 646 | } |
| 647 | subsys_initcall(ab8500_debug_init); | 647 | subsys_initcall(ab8500_debug_init); |
| 648 | module_exit(ab8500_debug_exit); | 648 | module_exit(ab8500_debug_exit); |
diff --git a/drivers/mfd/ab8500-spi.c b/drivers/mfd/ab8500-spi.c deleted file mode 100644 index b1653421edb5..000000000000 --- a/drivers/mfd/ab8500-spi.c +++ /dev/null | |||
| @@ -1,143 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) ST-Ericsson SA 2010 | ||
| 3 | * | ||
| 4 | * License Terms: GNU General Public License v2 | ||
| 5 | * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <linux/kernel.h> | ||
| 9 | #include <linux/slab.h> | ||
| 10 | #include <linux/init.h> | ||
| 11 | #include <linux/module.h> | ||
| 12 | #include <linux/platform_device.h> | ||
| 13 | #include <linux/spi/spi.h> | ||
| 14 | #include <linux/mfd/ab8500.h> | ||
| 15 | |||
| 16 | /* | ||
| 17 | * This funtion writes to any AB8500 registers using | ||
| 18 | * SPI protocol & before it writes it packs the data | ||
| 19 | * in the below 24 bit frame format | ||
| 20 | * | ||
| 21 | * *|------------------------------------| | ||
| 22 | * *| 23|22...18|17.......10|9|8|7......0| | ||
| 23 | * *| r/w bank adr data | | ||
| 24 | * * ------------------------------------ | ||
| 25 | * | ||
| 26 | * This function shouldn't be called from interrupt | ||
| 27 | * context | ||
| 28 | */ | ||
| 29 | static int ab8500_spi_write(struct ab8500 *ab8500, u16 addr, u8 data) | ||
| 30 | { | ||
| 31 | struct spi_device *spi = container_of(ab8500->dev, struct spi_device, | ||
| 32 | dev); | ||
| 33 | unsigned long spi_data = addr << 10 | data; | ||
| 34 | struct spi_transfer xfer; | ||
| 35 | struct spi_message msg; | ||
| 36 | |||
| 37 | ab8500->tx_buf[0] = spi_data; | ||
| 38 | ab8500->rx_buf[0] = 0; | ||
| 39 | |||
| 40 | xfer.tx_buf = ab8500->tx_buf; | ||
| 41 | xfer.rx_buf = NULL; | ||
| 42 | xfer.len = sizeof(unsigned long); | ||
| 43 | |||
| 44 | spi_message_init(&msg); | ||
| 45 | spi_message_add_tail(&xfer, &msg); | ||
| 46 | |||
| 47 | return spi_sync(spi, &msg); | ||
| 48 | } | ||
| 49 | |||
| 50 | static int ab8500_spi_read(struct ab8500 *ab8500, u16 addr) | ||
| 51 | { | ||
| 52 | struct spi_device *spi = container_of(ab8500->dev, struct spi_device, | ||
| 53 | dev); | ||
| 54 | unsigned long spi_data = 1 << 23 | addr << 10; | ||
| 55 | struct spi_transfer xfer; | ||
| 56 | struct spi_message msg; | ||
| 57 | int ret; | ||
| 58 | |||
| 59 | ab8500->tx_buf[0] = spi_data; | ||
| 60 | ab8500->rx_buf[0] = 0; | ||
| 61 | |||
| 62 | xfer.tx_buf = ab8500->tx_buf; | ||
| 63 | xfer.rx_buf = ab8500->rx_buf; | ||
| 64 | xfer.len = sizeof(unsigned long); | ||
| 65 | |||
| 66 | spi_message_init(&msg); | ||
| 67 | spi_message_add_tail(&xfer, &msg); | ||
| 68 | |||
| 69 | ret = spi_sync(spi, &msg); | ||
| 70 | if (!ret) | ||
| 71 | /* | ||
| 72 | * Only the 8 lowermost bytes are | ||
| 73 | * defined with value, the rest may | ||
| 74 | * vary depending on chip/board noise. | ||
| 75 | */ | ||
| 76 | ret = ab8500->rx_buf[0] & 0xFFU; | ||
| 77 | |||
| 78 | return ret; | ||
| 79 | } | ||
| 80 | |||
| 81 | static int __devinit ab8500_spi_probe(struct spi_device *spi) | ||
| 82 | { | ||
| 83 | struct ab8500 *ab8500; | ||
| 84 | int ret; | ||
| 85 | |||
| 86 | spi->bits_per_word = 24; | ||
| 87 | ret = spi_setup(spi); | ||
| 88 | if (ret < 0) | ||
| 89 | return ret; | ||
| 90 | |||
| 91 | ab8500 = kzalloc(sizeof *ab8500, GFP_KERNEL); | ||
| 92 | if (!ab8500) | ||
| 93 | return -ENOMEM; | ||
| 94 | |||
| 95 | ab8500->dev = &spi->dev; | ||
| 96 | ab8500->irq = spi->irq; | ||
| 97 | |||
| 98 | ab8500->read = ab8500_spi_read; | ||
| 99 | ab8500->write = ab8500_spi_write; | ||
| 100 | |||
| 101 | spi_set_drvdata(spi, ab8500); | ||
| 102 | |||
| 103 | ret = ab8500_init(ab8500); | ||
| 104 | if (ret) | ||
| 105 | kfree(ab8500); | ||
| 106 | |||
| 107 | return ret; | ||
| 108 | } | ||
| 109 | |||
| 110 | static int __devexit ab8500_spi_remove(struct spi_device *spi) | ||
| 111 | { | ||
| 112 | struct ab8500 *ab8500 = spi_get_drvdata(spi); | ||
| 113 | |||
| 114 | ab8500_exit(ab8500); | ||
| 115 | kfree(ab8500); | ||
| 116 | |||
| 117 | return 0; | ||
| 118 | } | ||
| 119 | |||
| 120 | static struct spi_driver ab8500_spi_driver = { | ||
| 121 | .driver = { | ||
| 122 | .name = "ab8500-spi", | ||
| 123 | .owner = THIS_MODULE, | ||
| 124 | }, | ||
| 125 | .probe = ab8500_spi_probe, | ||
| 126 | .remove = __devexit_p(ab8500_spi_remove) | ||
| 127 | }; | ||
| 128 | |||
| 129 | static int __init ab8500_spi_init(void) | ||
| 130 | { | ||
| 131 | return spi_register_driver(&ab8500_spi_driver); | ||
| 132 | } | ||
| 133 | subsys_initcall(ab8500_spi_init); | ||
| 134 | |||
| 135 | static void __exit ab8500_spi_exit(void) | ||
| 136 | { | ||
| 137 | spi_unregister_driver(&ab8500_spi_driver); | ||
| 138 | } | ||
| 139 | module_exit(ab8500_spi_exit); | ||
| 140 | |||
| 141 | MODULE_AUTHOR("Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com"); | ||
| 142 | MODULE_DESCRIPTION("AB8500 SPI"); | ||
| 143 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 7de708d15d72..6a1f94042612 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c | |||
| @@ -57,7 +57,7 @@ struct asic3_clk { | |||
| 57 | .rate = _rate, \ | 57 | .rate = _rate, \ |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | struct asic3_clk asic3_clk_init[] __initdata = { | 60 | static struct asic3_clk asic3_clk_init[] __initdata = { |
| 61 | INIT_CDEX(SPI, 0), | 61 | INIT_CDEX(SPI, 0), |
| 62 | INIT_CDEX(OWM, 5000000), | 62 | INIT_CDEX(OWM, 5000000), |
| 63 | INIT_CDEX(PWM0, 0), | 63 | INIT_CDEX(PWM0, 0), |
| @@ -102,7 +102,7 @@ static inline u32 asic3_read_register(struct asic3 *asic, | |||
| 102 | (reg >> asic->bus_shift)); | 102 | (reg >> asic->bus_shift)); |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | void asic3_set_register(struct asic3 *asic, u32 reg, u32 bits, bool set) | 105 | static void asic3_set_register(struct asic3 *asic, u32 reg, u32 bits, bool set) |
| 106 | { | 106 | { |
| 107 | unsigned long flags; | 107 | unsigned long flags; |
| 108 | u32 val; | 108 | u32 val; |
| @@ -226,14 +226,14 @@ static inline int asic3_irq_to_index(struct asic3 *asic, int irq) | |||
| 226 | return (irq - asic->irq_base) & 0xf; | 226 | return (irq - asic->irq_base) & 0xf; |
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | static void asic3_mask_gpio_irq(unsigned int irq) | 229 | static void asic3_mask_gpio_irq(struct irq_data *data) |
| 230 | { | 230 | { |
| 231 | struct asic3 *asic = get_irq_chip_data(irq); | 231 | struct asic3 *asic = irq_data_get_irq_chip_data(data); |
| 232 | u32 val, bank, index; | 232 | u32 val, bank, index; |
| 233 | unsigned long flags; | 233 | unsigned long flags; |
| 234 | 234 | ||
| 235 | bank = asic3_irq_to_bank(asic, irq); | 235 | bank = asic3_irq_to_bank(asic, data->irq); |
| 236 | index = asic3_irq_to_index(asic, irq); | 236 | index = asic3_irq_to_index(asic, data->irq); |
| 237 | 237 | ||
| 238 | spin_lock_irqsave(&asic->lock, flags); | 238 | spin_lock_irqsave(&asic->lock, flags); |
| 239 | val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK); | 239 | val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK); |
| @@ -242,9 +242,9 @@ static void asic3_mask_gpio_irq(unsigned int irq) | |||
| 242 | spin_unlock_irqrestore(&asic->lock, flags); | 242 | spin_unlock_irqrestore(&asic->lock, flags); |
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | static void asic3_mask_irq(unsigned int irq) | 245 | static void asic3_mask_irq(struct irq_data *data) |
| 246 | { | 246 | { |
| 247 | struct asic3 *asic = get_irq_chip_data(irq); | 247 | struct asic3 *asic = irq_data_get_irq_chip_data(data); |
| 248 | int regval; | 248 | int regval; |
| 249 | unsigned long flags; | 249 | unsigned long flags; |
| 250 | 250 | ||
| @@ -254,7 +254,7 @@ static void asic3_mask_irq(unsigned int irq) | |||
| 254 | ASIC3_INTR_INT_MASK); | 254 | ASIC3_INTR_INT_MASK); |
| 255 | 255 | ||
| 256 | regval &= ~(ASIC3_INTMASK_MASK0 << | 256 | regval &= ~(ASIC3_INTMASK_MASK0 << |
| 257 | (irq - (asic->irq_base + ASIC3_NUM_GPIOS))); | 257 | (data->irq - (asic->irq_base + ASIC3_NUM_GPIOS))); |
| 258 | 258 | ||
| 259 | asic3_write_register(asic, | 259 | asic3_write_register(asic, |
| 260 | ASIC3_INTR_BASE + | 260 | ASIC3_INTR_BASE + |
| @@ -263,14 +263,14 @@ static void asic3_mask_irq(unsigned int irq) | |||
| 263 | spin_unlock_irqrestore(&asic->lock, flags); | 263 | spin_unlock_irqrestore(&asic->lock, flags); |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | static void asic3_unmask_gpio_irq(unsigned int irq) | 266 | static void asic3_unmask_gpio_irq(struct irq_data *data) |
| 267 | { | 267 | { |
| 268 | struct asic3 *asic = get_irq_chip_data(irq); | 268 | struct asic3 *asic = irq_data_get_irq_chip_data(data); |
| 269 | u32 val, bank, index; | 269 | u32 val, bank, index; |
| 270 | unsigned long flags; | 270 | unsigned long flags; |
| 271 | 271 | ||
| 272 | bank = asic3_irq_to_bank(asic, irq); | 272 | bank = asic3_irq_to_bank(asic, data->irq); |
| 273 | index = asic3_irq_to_index(asic, irq); | 273 | index = asic3_irq_to_index(asic, data->irq); |
| 274 | 274 | ||
| 275 | spin_lock_irqsave(&asic->lock, flags); | 275 | spin_lock_irqsave(&asic->lock, flags); |
| 276 | val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK); | 276 | val = asic3_read_register(asic, bank + ASIC3_GPIO_MASK); |
| @@ -279,9 +279,9 @@ static void asic3_unmask_gpio_irq(unsigned int irq) | |||
| 279 | spin_unlock_irqrestore(&asic->lock, flags); | 279 | spin_unlock_irqrestore(&asic->lock, flags); |
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | static void asic3_unmask_irq(unsigned int irq) | 282 | static void asic3_unmask_irq(struct irq_data *data) |
| 283 | { | 283 | { |
| 284 | struct asic3 *asic = get_irq_chip_data(irq); | 284 | struct asic3 *asic = irq_data_get_irq_chip_data(data); |
| 285 | int regval; | 285 | int regval; |
| 286 | unsigned long flags; | 286 | unsigned long flags; |
| 287 | 287 | ||
| @@ -291,7 +291,7 @@ static void asic3_unmask_irq(unsigned int irq) | |||
| 291 | ASIC3_INTR_INT_MASK); | 291 | ASIC3_INTR_INT_MASK); |
| 292 | 292 | ||
| 293 | regval |= (ASIC3_INTMASK_MASK0 << | 293 | regval |= (ASIC3_INTMASK_MASK0 << |
| 294 | (irq - (asic->irq_base + ASIC3_NUM_GPIOS))); | 294 | (data->irq - (asic->irq_base + ASIC3_NUM_GPIOS))); |
| 295 | 295 | ||
| 296 | asic3_write_register(asic, | 296 | asic3_write_register(asic, |
| 297 | ASIC3_INTR_BASE + | 297 | ASIC3_INTR_BASE + |
| @@ -300,15 +300,15 @@ static void asic3_unmask_irq(unsigned int irq) | |||
| 300 | spin_unlock_irqrestore(&asic->lock, flags); | 300 | spin_unlock_irqrestore(&asic->lock, flags); |
| 301 | } | 301 | } |
| 302 | 302 | ||
| 303 | static int asic3_gpio_irq_type(unsigned int irq, unsigned int type) | 303 | static int asic3_gpio_irq_type(struct irq_data *data, unsigned int type) |
| 304 | { | 304 | { |
| 305 | struct asic3 *asic = get_irq_chip_data(irq); | 305 | struct asic3 *asic = irq_data_get_irq_chip_data(data); |
| 306 | u32 bank, index; | 306 | u32 bank, index; |
| 307 | u16 trigger, level, edge, bit; | 307 | u16 trigger, level, edge, bit; |
| 308 | unsigned long flags; | 308 | unsigned long flags; |
| 309 | 309 | ||
| 310 | bank = asic3_irq_to_bank(asic, irq); | 310 | bank = asic3_irq_to_bank(asic, data->irq); |
| 311 | index = asic3_irq_to_index(asic, irq); | 311 | index = asic3_irq_to_index(asic, data->irq); |
| 312 | bit = 1<<index; | 312 | bit = 1<<index; |
| 313 | 313 | ||
| 314 | spin_lock_irqsave(&asic->lock, flags); | 314 | spin_lock_irqsave(&asic->lock, flags); |
| @@ -318,7 +318,7 @@ static int asic3_gpio_irq_type(unsigned int irq, unsigned int type) | |||
| 318 | bank + ASIC3_GPIO_EDGE_TRIGGER); | 318 | bank + ASIC3_GPIO_EDGE_TRIGGER); |
| 319 | trigger = asic3_read_register(asic, | 319 | trigger = asic3_read_register(asic, |
| 320 | bank + ASIC3_GPIO_TRIGGER_TYPE); | 320 | bank + ASIC3_GPIO_TRIGGER_TYPE); |
| 321 | asic->irq_bothedge[(irq - asic->irq_base) >> 4] &= ~bit; | 321 | asic->irq_bothedge[(data->irq - asic->irq_base) >> 4] &= ~bit; |
| 322 | 322 | ||
| 323 | if (type == IRQ_TYPE_EDGE_RISING) { | 323 | if (type == IRQ_TYPE_EDGE_RISING) { |
| 324 | trigger |= bit; | 324 | trigger |= bit; |
| @@ -328,11 +328,11 @@ static int asic3_gpio_irq_type(unsigned int irq, unsigned int type) | |||
| 328 | edge &= ~bit; | 328 | edge &= ~bit; |
| 329 | } else if (type == IRQ_TYPE_EDGE_BOTH) { | 329 | } else if (type == IRQ_TYPE_EDGE_BOTH) { |
| 330 | trigger |= bit; | 330 | trigger |= bit; |
| 331 | if (asic3_gpio_get(&asic->gpio, irq - asic->irq_base)) | 331 | if (asic3_gpio_get(&asic->gpio, data->irq - asic->irq_base)) |
| 332 | edge &= ~bit; | 332 | edge &= ~bit; |
| 333 | else | 333 | else |
| 334 | edge |= bit; | 334 | edge |= bit; |
| 335 | asic->irq_bothedge[(irq - asic->irq_base) >> 4] |= bit; | 335 | asic->irq_bothedge[(data->irq - asic->irq_base) >> 4] |= bit; |
| 336 | } else if (type == IRQ_TYPE_LEVEL_LOW) { | 336 | } else if (type == IRQ_TYPE_LEVEL_LOW) { |
| 337 | trigger &= ~bit; | 337 | trigger &= ~bit; |
| 338 | level &= ~bit; | 338 | level &= ~bit; |
| @@ -359,17 +359,17 @@ static int asic3_gpio_irq_type(unsigned int irq, unsigned int type) | |||
| 359 | 359 | ||
| 360 | static struct irq_chip asic3_gpio_irq_chip = { | 360 | static struct irq_chip asic3_gpio_irq_chip = { |
| 361 | .name = "ASIC3-GPIO", | 361 | .name = "ASIC3-GPIO", |
| 362 | .ack = asic3_mask_gpio_irq, | 362 | .irq_ack = asic3_mask_gpio_irq, |
| 363 | .mask = asic3_mask_gpio_irq, | 363 | .irq_mask = asic3_mask_gpio_irq, |
| 364 | .unmask = asic3_unmask_gpio_irq, | 364 | .irq_unmask = asic3_unmask_gpio_irq, |
| 365 | .set_type = asic3_gpio_irq_type, | 365 | .irq_set_type = asic3_gpio_irq_type, |
| 366 | }; | 366 | }; |
| 367 | 367 | ||
| 368 | static struct irq_chip asic3_irq_chip = { | 368 | static struct irq_chip asic3_irq_chip = { |
| 369 | .name = "ASIC3", | 369 | .name = "ASIC3", |
| 370 | .ack = asic3_mask_irq, | 370 | .irq_ack = asic3_mask_irq, |
| 371 | .mask = asic3_mask_irq, | 371 | .irq_mask = asic3_mask_irq, |
| 372 | .unmask = asic3_unmask_irq, | 372 | .irq_unmask = asic3_unmask_irq, |
| 373 | }; | 373 | }; |
| 374 | 374 | ||
| 375 | static int __init asic3_irq_probe(struct platform_device *pdev) | 375 | static int __init asic3_irq_probe(struct platform_device *pdev) |
| @@ -635,7 +635,7 @@ static struct resource ds1wm_resources[] = { | |||
| 635 | }, | 635 | }, |
| 636 | { | 636 | { |
| 637 | .start = ASIC3_IRQ_OWM, | 637 | .start = ASIC3_IRQ_OWM, |
| 638 | .start = ASIC3_IRQ_OWM, | 638 | .end = ASIC3_IRQ_OWM, |
| 639 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, | 639 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, |
| 640 | }, | 640 | }, |
| 641 | }; | 641 | }; |
diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c new file mode 100644 index 000000000000..59ca6f151e78 --- /dev/null +++ b/drivers/mfd/cs5535-mfd.c | |||
| @@ -0,0 +1,151 @@ | |||
| 1 | /* | ||
| 2 | * cs5535-mfd.c - core MFD driver for CS5535/CS5536 southbridges | ||
| 3 | * | ||
| 4 | * The CS5535 and CS5536 has an ISA bridge on the PCI bus that is | ||
| 5 | * used for accessing GPIOs, MFGPTs, ACPI, etc. Each subdevice has | ||
| 6 | * an IO range that's specified in a single BAR. The BAR order is | ||
| 7 | * hardcoded in the CS553x specifications. | ||
| 8 | * | ||
| 9 | * Copyright (c) 2010 Andres Salomon <dilinger@queued.net> | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License version 2 as | ||
| 13 | * published by the Free Software Foundation. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <linux/kernel.h> | ||
| 26 | #include <linux/init.h> | ||
| 27 | #include <linux/mfd/core.h> | ||
| 28 | #include <linux/module.h> | ||
| 29 | #include <linux/pci.h> | ||
| 30 | |||
| 31 | #define DRV_NAME "cs5535-mfd" | ||
| 32 | |||
| 33 | enum cs5535_mfd_bars { | ||
| 34 | SMB_BAR = 0, | ||
| 35 | GPIO_BAR = 1, | ||
| 36 | MFGPT_BAR = 2, | ||
| 37 | PMS_BAR = 4, | ||
| 38 | ACPI_BAR = 5, | ||
| 39 | NR_BARS, | ||
| 40 | }; | ||
| 41 | |||
| 42 | static __devinitdata struct resource cs5535_mfd_resources[NR_BARS]; | ||
| 43 | |||
| 44 | static __devinitdata struct mfd_cell cs5535_mfd_cells[] = { | ||
| 45 | { | ||
| 46 | .id = SMB_BAR, | ||
| 47 | .name = "cs5535-smb", | ||
| 48 | .num_resources = 1, | ||
| 49 | .resources = &cs5535_mfd_resources[SMB_BAR], | ||
| 50 | }, | ||
| 51 | { | ||
| 52 | .id = GPIO_BAR, | ||
| 53 | .name = "cs5535-gpio", | ||
| 54 | .num_resources = 1, | ||
| 55 | .resources = &cs5535_mfd_resources[GPIO_BAR], | ||
| 56 | }, | ||
| 57 | { | ||
| 58 | .id = MFGPT_BAR, | ||
| 59 | .name = "cs5535-mfgpt", | ||
| 60 | .num_resources = 1, | ||
| 61 | .resources = &cs5535_mfd_resources[MFGPT_BAR], | ||
| 62 | }, | ||
| 63 | { | ||
| 64 | .id = PMS_BAR, | ||
| 65 | .name = "cs5535-pms", | ||
| 66 | .num_resources = 1, | ||
| 67 | .resources = &cs5535_mfd_resources[PMS_BAR], | ||
| 68 | }, | ||
| 69 | { | ||
| 70 | .id = ACPI_BAR, | ||
| 71 | .name = "cs5535-acpi", | ||
| 72 | .num_resources = 1, | ||
| 73 | .resources = &cs5535_mfd_resources[ACPI_BAR], | ||
| 74 | }, | ||
| 75 | }; | ||
| 76 | |||
| 77 | static int __devinit cs5535_mfd_probe(struct pci_dev *pdev, | ||
| 78 | const struct pci_device_id *id) | ||
| 79 | { | ||
| 80 | int err, i; | ||
| 81 | |||
| 82 | err = pci_enable_device(pdev); | ||
| 83 | if (err) | ||
| 84 | return err; | ||
| 85 | |||
| 86 | /* fill in IO range for each cell; subdrivers handle the region */ | ||
| 87 | for (i = 0; i < ARRAY_SIZE(cs5535_mfd_cells); i++) { | ||
| 88 | int bar = cs5535_mfd_cells[i].id; | ||
| 89 | struct resource *r = &cs5535_mfd_resources[bar]; | ||
| 90 | |||
| 91 | r->flags = IORESOURCE_IO; | ||
| 92 | r->start = pci_resource_start(pdev, bar); | ||
| 93 | r->end = pci_resource_end(pdev, bar); | ||
| 94 | |||
| 95 | /* id is used for temporarily storing BAR; unset it now */ | ||
| 96 | cs5535_mfd_cells[i].id = 0; | ||
| 97 | } | ||
| 98 | |||
| 99 | err = mfd_add_devices(&pdev->dev, -1, cs5535_mfd_cells, | ||
| 100 | ARRAY_SIZE(cs5535_mfd_cells), NULL, 0); | ||
| 101 | if (err) { | ||
| 102 | dev_err(&pdev->dev, "MFD add devices failed: %d\n", err); | ||
| 103 | goto err_disable; | ||
| 104 | } | ||
| 105 | |||
| 106 | dev_info(&pdev->dev, "%zu devices registered.\n", | ||
| 107 | ARRAY_SIZE(cs5535_mfd_cells)); | ||
| 108 | |||
| 109 | return 0; | ||
| 110 | |||
| 111 | err_disable: | ||
| 112 | pci_disable_device(pdev); | ||
| 113 | return err; | ||
| 114 | } | ||
| 115 | |||
| 116 | static void __devexit cs5535_mfd_remove(struct pci_dev *pdev) | ||
| 117 | { | ||
| 118 | mfd_remove_devices(&pdev->dev); | ||
| 119 | pci_disable_device(pdev); | ||
| 120 | } | ||
| 121 | |||
| 122 | static struct pci_device_id cs5535_mfd_pci_tbl[] = { | ||
| 123 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, | ||
| 124 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, | ||
| 125 | { 0, } | ||
| 126 | }; | ||
| 127 | MODULE_DEVICE_TABLE(pci, cs5535_mfd_pci_tbl); | ||
| 128 | |||
| 129 | static struct pci_driver cs5535_mfd_drv = { | ||
| 130 | .name = DRV_NAME, | ||
| 131 | .id_table = cs5535_mfd_pci_tbl, | ||
| 132 | .probe = cs5535_mfd_probe, | ||
| 133 | .remove = __devexit_p(cs5535_mfd_remove), | ||
| 134 | }; | ||
| 135 | |||
| 136 | static int __init cs5535_mfd_init(void) | ||
| 137 | { | ||
| 138 | return pci_register_driver(&cs5535_mfd_drv); | ||
| 139 | } | ||
| 140 | |||
| 141 | static void __exit cs5535_mfd_exit(void) | ||
| 142 | { | ||
| 143 | pci_unregister_driver(&cs5535_mfd_drv); | ||
| 144 | } | ||
| 145 | |||
| 146 | module_init(cs5535_mfd_init); | ||
| 147 | module_exit(cs5535_mfd_exit); | ||
| 148 | |||
| 149 | MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>"); | ||
| 150 | MODULE_DESCRIPTION("MFD driver for CS5535/CS5536 southbridge's ISA PCI device"); | ||
| 151 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c index c2b698d69a93..9e2d8dd5f9e5 100644 --- a/drivers/mfd/ezx-pcap.c +++ b/drivers/mfd/ezx-pcap.c | |||
| @@ -144,26 +144,26 @@ int pcap_to_irq(struct pcap_chip *pcap, int irq) | |||
| 144 | } | 144 | } |
| 145 | EXPORT_SYMBOL_GPL(pcap_to_irq); | 145 | EXPORT_SYMBOL_GPL(pcap_to_irq); |
| 146 | 146 | ||
| 147 | static void pcap_mask_irq(unsigned int irq) | 147 | static void pcap_mask_irq(struct irq_data *d) |
| 148 | { | 148 | { |
| 149 | struct pcap_chip *pcap = get_irq_chip_data(irq); | 149 | struct pcap_chip *pcap = irq_data_get_irq_chip_data(d); |
| 150 | 150 | ||
| 151 | pcap->msr |= 1 << irq_to_pcap(pcap, irq); | 151 | pcap->msr |= 1 << irq_to_pcap(pcap, d->irq); |
| 152 | queue_work(pcap->workqueue, &pcap->msr_work); | 152 | queue_work(pcap->workqueue, &pcap->msr_work); |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | static void pcap_unmask_irq(unsigned int irq) | 155 | static void pcap_unmask_irq(struct irq_data *d) |
| 156 | { | 156 | { |
| 157 | struct pcap_chip *pcap = get_irq_chip_data(irq); | 157 | struct pcap_chip *pcap = irq_data_get_irq_chip_data(d); |
| 158 | 158 | ||
| 159 | pcap->msr &= ~(1 << irq_to_pcap(pcap, irq)); | 159 | pcap->msr &= ~(1 << irq_to_pcap(pcap, d->irq)); |
| 160 | queue_work(pcap->workqueue, &pcap->msr_work); | 160 | queue_work(pcap->workqueue, &pcap->msr_work); |
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | static struct irq_chip pcap_irq_chip = { | 163 | static struct irq_chip pcap_irq_chip = { |
| 164 | .name = "pcap", | 164 | .name = "pcap", |
| 165 | .mask = pcap_mask_irq, | 165 | .irq_mask = pcap_mask_irq, |
| 166 | .unmask = pcap_unmask_irq, | 166 | .irq_unmask = pcap_unmask_irq, |
| 167 | }; | 167 | }; |
| 168 | 168 | ||
| 169 | static void pcap_msr_work(struct work_struct *work) | 169 | static void pcap_msr_work(struct work_struct *work) |
| @@ -199,8 +199,7 @@ static void pcap_isr_work(struct work_struct *work) | |||
| 199 | if (service & 1) { | 199 | if (service & 1) { |
| 200 | struct irq_desc *desc = irq_to_desc(irq); | 200 | struct irq_desc *desc = irq_to_desc(irq); |
| 201 | 201 | ||
| 202 | if (WARN(!desc, KERN_WARNING | 202 | if (WARN(!desc, "Invalid PCAP IRQ %d\n", irq)) |
| 203 | "Invalid PCAP IRQ %d\n", irq)) | ||
| 204 | break; | 203 | break; |
| 205 | 204 | ||
| 206 | if (desc->status & IRQ_DISABLED) | 205 | if (desc->status & IRQ_DISABLED) |
| @@ -218,7 +217,7 @@ static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
| 218 | { | 217 | { |
| 219 | struct pcap_chip *pcap = get_irq_data(irq); | 218 | struct pcap_chip *pcap = get_irq_data(irq); |
| 220 | 219 | ||
| 221 | desc->chip->ack(irq); | 220 | desc->irq_data.chip->irq_ack(&desc->irq_data); |
| 222 | queue_work(pcap->workqueue, &pcap->isr_work); | 221 | queue_work(pcap->workqueue, &pcap->isr_work); |
| 223 | return; | 222 | return; |
| 224 | } | 223 | } |
| @@ -282,7 +281,7 @@ static irqreturn_t pcap_adc_irq(int irq, void *_pcap) | |||
| 282 | mutex_lock(&pcap->adc_mutex); | 281 | mutex_lock(&pcap->adc_mutex); |
| 283 | req = pcap->adc_queue[pcap->adc_head]; | 282 | req = pcap->adc_queue[pcap->adc_head]; |
| 284 | 283 | ||
| 285 | if (WARN(!req, KERN_WARNING "adc irq without pending request\n")) { | 284 | if (WARN(!req, "adc irq without pending request\n")) { |
| 286 | mutex_unlock(&pcap->adc_mutex); | 285 | mutex_unlock(&pcap->adc_mutex); |
| 287 | return IRQ_HANDLED; | 286 | return IRQ_HANDLED; |
| 288 | } | 287 | } |
diff --git a/drivers/mfd/htc-egpio.c b/drivers/mfd/htc-egpio.c index d3e74f8585e0..d00b6d1a69e5 100644 --- a/drivers/mfd/htc-egpio.c +++ b/drivers/mfd/htc-egpio.c | |||
| @@ -70,31 +70,32 @@ static inline void ack_irqs(struct egpio_info *ei) | |||
| 70 | ei->ack_write, ei->ack_register << ei->bus_shift); | 70 | ei->ack_write, ei->ack_register << ei->bus_shift); |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | static void egpio_ack(unsigned int irq) | 73 | static void egpio_ack(struct irq_data *data) |
| 74 | { | 74 | { |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | /* There does not appear to be a way to proactively mask interrupts | 77 | /* There does not appear to be a way to proactively mask interrupts |
| 78 | * on the egpio chip itself. So, we simply ignore interrupts that | 78 | * on the egpio chip itself. So, we simply ignore interrupts that |
| 79 | * aren't desired. */ | 79 | * aren't desired. */ |
| 80 | static void egpio_mask(unsigned int irq) | 80 | static void egpio_mask(struct irq_data *data) |
| 81 | { | 81 | { |
| 82 | struct egpio_info *ei = get_irq_chip_data(irq); | 82 | struct egpio_info *ei = irq_data_get_irq_chip_data(data); |
| 83 | ei->irqs_enabled &= ~(1 << (irq - ei->irq_start)); | 83 | ei->irqs_enabled &= ~(1 << (data->irq - ei->irq_start)); |
| 84 | pr_debug("EGPIO mask %d %04x\n", irq, ei->irqs_enabled); | 84 | pr_debug("EGPIO mask %d %04x\n", data->irq, ei->irqs_enabled); |
| 85 | } | 85 | } |
| 86 | static void egpio_unmask(unsigned int irq) | 86 | |
| 87 | static void egpio_unmask(struct irq_data *data) | ||
| 87 | { | 88 | { |
| 88 | struct egpio_info *ei = get_irq_chip_data(irq); | 89 | struct egpio_info *ei = irq_data_get_irq_chip_data(data); |
| 89 | ei->irqs_enabled |= 1 << (irq - ei->irq_start); | 90 | ei->irqs_enabled |= 1 << (data->irq - ei->irq_start); |
| 90 | pr_debug("EGPIO unmask %d %04x\n", irq, ei->irqs_enabled); | 91 | pr_debug("EGPIO unmask %d %04x\n", data->irq, ei->irqs_enabled); |
| 91 | } | 92 | } |
| 92 | 93 | ||
| 93 | static struct irq_chip egpio_muxed_chip = { | 94 | static struct irq_chip egpio_muxed_chip = { |
| 94 | .name = "htc-egpio", | 95 | .name = "htc-egpio", |
| 95 | .ack = egpio_ack, | 96 | .irq_ack = egpio_ack, |
| 96 | .mask = egpio_mask, | 97 | .irq_mask = egpio_mask, |
| 97 | .unmask = egpio_unmask, | 98 | .irq_unmask = egpio_unmask, |
| 98 | }; | 99 | }; |
| 99 | 100 | ||
| 100 | static void egpio_handler(unsigned int irq, struct irq_desc *desc) | 101 | static void egpio_handler(unsigned int irq, struct irq_desc *desc) |
diff --git a/drivers/mfd/htc-i2cpld.c b/drivers/mfd/htc-i2cpld.c index 594c9a8e25e1..296ad1562f69 100644 --- a/drivers/mfd/htc-i2cpld.c +++ b/drivers/mfd/htc-i2cpld.c | |||
| @@ -82,25 +82,25 @@ struct htcpld_data { | |||
| 82 | /* There does not appear to be a way to proactively mask interrupts | 82 | /* There does not appear to be a way to proactively mask interrupts |
| 83 | * on the htcpld chip itself. So, we simply ignore interrupts that | 83 | * on the htcpld chip itself. So, we simply ignore interrupts that |
| 84 | * aren't desired. */ | 84 | * aren't desired. */ |
| 85 | static void htcpld_mask(unsigned int irq) | 85 | static void htcpld_mask(struct irq_data *data) |
| 86 | { | 86 | { |
| 87 | struct htcpld_chip *chip = get_irq_chip_data(irq); | 87 | struct htcpld_chip *chip = irq_data_get_irq_chip_data(data); |
| 88 | chip->irqs_enabled &= ~(1 << (irq - chip->irq_start)); | 88 | chip->irqs_enabled &= ~(1 << (data->irq - chip->irq_start)); |
| 89 | pr_debug("HTCPLD mask %d %04x\n", irq, chip->irqs_enabled); | 89 | pr_debug("HTCPLD mask %d %04x\n", data->irq, chip->irqs_enabled); |
| 90 | } | 90 | } |
| 91 | static void htcpld_unmask(unsigned int irq) | 91 | static void htcpld_unmask(struct irq_data *data) |
| 92 | { | 92 | { |
| 93 | struct htcpld_chip *chip = get_irq_chip_data(irq); | 93 | struct htcpld_chip *chip = irq_data_get_irq_chip_data(data); |
| 94 | chip->irqs_enabled |= 1 << (irq - chip->irq_start); | 94 | chip->irqs_enabled |= 1 << (data->irq - chip->irq_start); |
| 95 | pr_debug("HTCPLD unmask %d %04x\n", irq, chip->irqs_enabled); | 95 | pr_debug("HTCPLD unmask %d %04x\n", data->irq, chip->irqs_enabled); |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | static int htcpld_set_type(unsigned int irq, unsigned int flags) | 98 | static int htcpld_set_type(struct irq_data *data, unsigned int flags) |
| 99 | { | 99 | { |
| 100 | struct irq_desc *d = irq_to_desc(irq); | 100 | struct irq_desc *d = irq_to_desc(data->irq); |
| 101 | 101 | ||
| 102 | if (!d) { | 102 | if (!d) { |
| 103 | pr_err("HTCPLD invalid IRQ: %d\n", irq); | 103 | pr_err("HTCPLD invalid IRQ: %d\n", data->irq); |
| 104 | return -EINVAL; | 104 | return -EINVAL; |
| 105 | } | 105 | } |
| 106 | 106 | ||
| @@ -118,10 +118,10 @@ static int htcpld_set_type(unsigned int irq, unsigned int flags) | |||
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | static struct irq_chip htcpld_muxed_chip = { | 120 | static struct irq_chip htcpld_muxed_chip = { |
| 121 | .name = "htcpld", | 121 | .name = "htcpld", |
| 122 | .mask = htcpld_mask, | 122 | .irq_mask = htcpld_mask, |
| 123 | .unmask = htcpld_unmask, | 123 | .irq_unmask = htcpld_unmask, |
| 124 | .set_type = htcpld_set_type, | 124 | .irq_set_type = htcpld_set_type, |
| 125 | }; | 125 | }; |
| 126 | 126 | ||
| 127 | /* To properly dispatch IRQ events, we need to read from the | 127 | /* To properly dispatch IRQ events, we need to read from the |
| @@ -235,7 +235,7 @@ static irqreturn_t htcpld_handler(int irq, void *dev) | |||
| 235 | * and that work is scheduled in the set routine. The kernel can then run | 235 | * and that work is scheduled in the set routine. The kernel can then run |
| 236 | * the I2C functions, which will sleep, in process context. | 236 | * the I2C functions, which will sleep, in process context. |
| 237 | */ | 237 | */ |
| 238 | void htcpld_chip_set(struct gpio_chip *chip, unsigned offset, int val) | 238 | static void htcpld_chip_set(struct gpio_chip *chip, unsigned offset, int val) |
| 239 | { | 239 | { |
| 240 | struct i2c_client *client; | 240 | struct i2c_client *client; |
| 241 | struct htcpld_chip *chip_data; | 241 | struct htcpld_chip *chip_data; |
| @@ -259,7 +259,7 @@ void htcpld_chip_set(struct gpio_chip *chip, unsigned offset, int val) | |||
| 259 | schedule_work(&(chip_data->set_val_work)); | 259 | schedule_work(&(chip_data->set_val_work)); |
| 260 | } | 260 | } |
| 261 | 261 | ||
| 262 | void htcpld_chip_set_ni(struct work_struct *work) | 262 | static void htcpld_chip_set_ni(struct work_struct *work) |
| 263 | { | 263 | { |
| 264 | struct htcpld_chip *chip_data; | 264 | struct htcpld_chip *chip_data; |
| 265 | struct i2c_client *client; | 265 | struct i2c_client *client; |
| @@ -269,7 +269,7 @@ void htcpld_chip_set_ni(struct work_struct *work) | |||
| 269 | i2c_smbus_read_byte_data(client, chip_data->cache_out); | 269 | i2c_smbus_read_byte_data(client, chip_data->cache_out); |
| 270 | } | 270 | } |
| 271 | 271 | ||
| 272 | int htcpld_chip_get(struct gpio_chip *chip, unsigned offset) | 272 | static int htcpld_chip_get(struct gpio_chip *chip, unsigned offset) |
| 273 | { | 273 | { |
| 274 | struct htcpld_chip *chip_data; | 274 | struct htcpld_chip *chip_data; |
| 275 | int val = 0; | 275 | int val = 0; |
| @@ -316,7 +316,7 @@ static int htcpld_direction_input(struct gpio_chip *chip, | |||
| 316 | return (offset < chip->ngpio) ? 0 : -EINVAL; | 316 | return (offset < chip->ngpio) ? 0 : -EINVAL; |
| 317 | } | 317 | } |
| 318 | 318 | ||
| 319 | int htcpld_chip_to_irq(struct gpio_chip *chip, unsigned offset) | 319 | static int htcpld_chip_to_irq(struct gpio_chip *chip, unsigned offset) |
| 320 | { | 320 | { |
| 321 | struct htcpld_chip *chip_data; | 321 | struct htcpld_chip *chip_data; |
| 322 | 322 | ||
| @@ -328,7 +328,7 @@ int htcpld_chip_to_irq(struct gpio_chip *chip, unsigned offset) | |||
| 328 | return -EINVAL; | 328 | return -EINVAL; |
| 329 | } | 329 | } |
| 330 | 330 | ||
| 331 | void htcpld_chip_reset(struct i2c_client *client) | 331 | static void htcpld_chip_reset(struct i2c_client *client) |
| 332 | { | 332 | { |
| 333 | struct htcpld_chip *chip_data = i2c_get_clientdata(client); | 333 | struct htcpld_chip *chip_data = i2c_get_clientdata(client); |
| 334 | if (!chip_data) | 334 | if (!chip_data) |
diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c index 9dd1b33f2275..0cc59795f600 100644 --- a/drivers/mfd/jz4740-adc.c +++ b/drivers/mfd/jz4740-adc.c | |||
| @@ -84,31 +84,30 @@ static inline void jz4740_adc_irq_set_masked(struct jz4740_adc *adc, int irq, | |||
| 84 | spin_unlock_irqrestore(&adc->lock, flags); | 84 | spin_unlock_irqrestore(&adc->lock, flags); |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | static void jz4740_adc_irq_mask(unsigned int irq) | 87 | static void jz4740_adc_irq_mask(struct irq_data *data) |
| 88 | { | 88 | { |
| 89 | struct jz4740_adc *adc = get_irq_chip_data(irq); | 89 | struct jz4740_adc *adc = irq_data_get_irq_chip_data(data); |
| 90 | jz4740_adc_irq_set_masked(adc, irq, true); | 90 | jz4740_adc_irq_set_masked(adc, data->irq, true); |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | static void jz4740_adc_irq_unmask(unsigned int irq) | 93 | static void jz4740_adc_irq_unmask(struct irq_data *data) |
| 94 | { | 94 | { |
| 95 | struct jz4740_adc *adc = get_irq_chip_data(irq); | 95 | struct jz4740_adc *adc = irq_data_get_irq_chip_data(data); |
| 96 | jz4740_adc_irq_set_masked(adc, irq, false); | 96 | jz4740_adc_irq_set_masked(adc, data->irq, false); |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | static void jz4740_adc_irq_ack(unsigned int irq) | 99 | static void jz4740_adc_irq_ack(struct irq_data *data) |
| 100 | { | 100 | { |
| 101 | struct jz4740_adc *adc = get_irq_chip_data(irq); | 101 | struct jz4740_adc *adc = irq_data_get_irq_chip_data(data); |
| 102 | 102 | unsigned int irq = data->irq - adc->irq_base; | |
| 103 | irq -= adc->irq_base; | ||
| 104 | writeb(BIT(irq), adc->base + JZ_REG_ADC_STATUS); | 103 | writeb(BIT(irq), adc->base + JZ_REG_ADC_STATUS); |
| 105 | } | 104 | } |
| 106 | 105 | ||
| 107 | static struct irq_chip jz4740_adc_irq_chip = { | 106 | static struct irq_chip jz4740_adc_irq_chip = { |
| 108 | .name = "jz4740-adc", | 107 | .name = "jz4740-adc", |
| 109 | .mask = jz4740_adc_irq_mask, | 108 | .irq_mask = jz4740_adc_irq_mask, |
| 110 | .unmask = jz4740_adc_irq_unmask, | 109 | .irq_unmask = jz4740_adc_irq_unmask, |
| 111 | .ack = jz4740_adc_irq_ack, | 110 | .irq_ack = jz4740_adc_irq_ack, |
| 112 | }; | 111 | }; |
| 113 | 112 | ||
| 114 | static void jz4740_adc_irq_demux(unsigned int irq, struct irq_desc *desc) | 113 | static void jz4740_adc_irq_demux(unsigned int irq, struct irq_desc *desc) |
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c index 44695f5a1800..0e998dc4e7d8 100644 --- a/drivers/mfd/max8925-core.c +++ b/drivers/mfd/max8925-core.c | |||
| @@ -407,16 +407,16 @@ static irqreturn_t max8925_tsc_irq(int irq, void *data) | |||
| 407 | return IRQ_HANDLED; | 407 | return IRQ_HANDLED; |
| 408 | } | 408 | } |
| 409 | 409 | ||
| 410 | static void max8925_irq_lock(unsigned int irq) | 410 | static void max8925_irq_lock(struct irq_data *data) |
| 411 | { | 411 | { |
| 412 | struct max8925_chip *chip = get_irq_chip_data(irq); | 412 | struct max8925_chip *chip = irq_data_get_irq_chip_data(data); |
| 413 | 413 | ||
| 414 | mutex_lock(&chip->irq_lock); | 414 | mutex_lock(&chip->irq_lock); |
| 415 | } | 415 | } |
| 416 | 416 | ||
| 417 | static void max8925_irq_sync_unlock(unsigned int irq) | 417 | static void max8925_irq_sync_unlock(struct irq_data *data) |
| 418 | { | 418 | { |
| 419 | struct max8925_chip *chip = get_irq_chip_data(irq); | 419 | struct max8925_chip *chip = irq_data_get_irq_chip_data(data); |
| 420 | struct max8925_irq_data *irq_data; | 420 | struct max8925_irq_data *irq_data; |
| 421 | static unsigned char cache_chg[2] = {0xff, 0xff}; | 421 | static unsigned char cache_chg[2] = {0xff, 0xff}; |
| 422 | static unsigned char cache_on[2] = {0xff, 0xff}; | 422 | static unsigned char cache_on[2] = {0xff, 0xff}; |
| @@ -492,25 +492,25 @@ static void max8925_irq_sync_unlock(unsigned int irq) | |||
| 492 | mutex_unlock(&chip->irq_lock); | 492 | mutex_unlock(&chip->irq_lock); |
| 493 | } | 493 | } |
| 494 | 494 | ||
| 495 | static void max8925_irq_enable(unsigned int irq) | 495 | static void max8925_irq_enable(struct irq_data *data) |
| 496 | { | 496 | { |
| 497 | struct max8925_chip *chip = get_irq_chip_data(irq); | 497 | struct max8925_chip *chip = irq_data_get_irq_chip_data(data); |
| 498 | max8925_irqs[irq - chip->irq_base].enable | 498 | max8925_irqs[data->irq - chip->irq_base].enable |
| 499 | = max8925_irqs[irq - chip->irq_base].offs; | 499 | = max8925_irqs[data->irq - chip->irq_base].offs; |
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | static void max8925_irq_disable(unsigned int irq) | 502 | static void max8925_irq_disable(struct irq_data *data) |
| 503 | { | 503 | { |
| 504 | struct max8925_chip *chip = get_irq_chip_data(irq); | 504 | struct max8925_chip *chip = irq_data_get_irq_chip_data(data); |
| 505 | max8925_irqs[irq - chip->irq_base].enable = 0; | 505 | max8925_irqs[data->irq - chip->irq_base].enable = 0; |
| 506 | } | 506 | } |
| 507 | 507 | ||
| 508 | static struct irq_chip max8925_irq_chip = { | 508 | static struct irq_chip max8925_irq_chip = { |
| 509 | .name = "max8925", | 509 | .name = "max8925", |
| 510 | .bus_lock = max8925_irq_lock, | 510 | .irq_bus_lock = max8925_irq_lock, |
| 511 | .bus_sync_unlock = max8925_irq_sync_unlock, | 511 | .irq_bus_sync_unlock = max8925_irq_sync_unlock, |
| 512 | .enable = max8925_irq_enable, | 512 | .irq_enable = max8925_irq_enable, |
| 513 | .disable = max8925_irq_disable, | 513 | .irq_disable = max8925_irq_disable, |
| 514 | }; | 514 | }; |
| 515 | 515 | ||
| 516 | static int max8925_irq_init(struct max8925_chip *chip, int irq, | 516 | static int max8925_irq_init(struct max8925_chip *chip, int irq, |
diff --git a/drivers/mfd/max8998-irq.c b/drivers/mfd/max8998-irq.c index 45bfe77b639b..3903e1fbb334 100644 --- a/drivers/mfd/max8998-irq.c +++ b/drivers/mfd/max8998-irq.c | |||
| @@ -102,16 +102,16 @@ irq_to_max8998_irq(struct max8998_dev *max8998, int irq) | |||
| 102 | return &max8998_irqs[irq - max8998->irq_base]; | 102 | return &max8998_irqs[irq - max8998->irq_base]; |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | static void max8998_irq_lock(unsigned int irq) | 105 | static void max8998_irq_lock(struct irq_data *data) |
| 106 | { | 106 | { |
| 107 | struct max8998_dev *max8998 = get_irq_chip_data(irq); | 107 | struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data); |
| 108 | 108 | ||
| 109 | mutex_lock(&max8998->irqlock); | 109 | mutex_lock(&max8998->irqlock); |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | static void max8998_irq_sync_unlock(unsigned int irq) | 112 | static void max8998_irq_sync_unlock(struct irq_data *data) |
| 113 | { | 113 | { |
| 114 | struct max8998_dev *max8998 = get_irq_chip_data(irq); | 114 | struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data); |
| 115 | int i; | 115 | int i; |
| 116 | 116 | ||
| 117 | for (i = 0; i < ARRAY_SIZE(max8998->irq_masks_cur); i++) { | 117 | for (i = 0; i < ARRAY_SIZE(max8998->irq_masks_cur); i++) { |
| @@ -129,28 +129,30 @@ static void max8998_irq_sync_unlock(unsigned int irq) | |||
| 129 | mutex_unlock(&max8998->irqlock); | 129 | mutex_unlock(&max8998->irqlock); |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | static void max8998_irq_unmask(unsigned int irq) | 132 | static void max8998_irq_unmask(struct irq_data *data) |
| 133 | { | 133 | { |
| 134 | struct max8998_dev *max8998 = get_irq_chip_data(irq); | 134 | struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data); |
| 135 | struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998, irq); | 135 | struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998, |
| 136 | data->irq); | ||
| 136 | 137 | ||
| 137 | max8998->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; | 138 | max8998->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; |
| 138 | } | 139 | } |
| 139 | 140 | ||
| 140 | static void max8998_irq_mask(unsigned int irq) | 141 | static void max8998_irq_mask(struct irq_data *data) |
| 141 | { | 142 | { |
| 142 | struct max8998_dev *max8998 = get_irq_chip_data(irq); | 143 | struct max8998_dev *max8998 = irq_data_get_irq_chip_data(data); |
| 143 | struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998, irq); | 144 | struct max8998_irq_data *irq_data = irq_to_max8998_irq(max8998, |
| 145 | data->irq); | ||
| 144 | 146 | ||
| 145 | max8998->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; | 147 | max8998->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; |
| 146 | } | 148 | } |
| 147 | 149 | ||
| 148 | static struct irq_chip max8998_irq_chip = { | 150 | static struct irq_chip max8998_irq_chip = { |
| 149 | .name = "max8998", | 151 | .name = "max8998", |
| 150 | .bus_lock = max8998_irq_lock, | 152 | .irq_bus_lock = max8998_irq_lock, |
| 151 | .bus_sync_unlock = max8998_irq_sync_unlock, | 153 | .irq_bus_sync_unlock = max8998_irq_sync_unlock, |
| 152 | .mask = max8998_irq_mask, | 154 | .irq_mask = max8998_irq_mask, |
| 153 | .unmask = max8998_irq_unmask, | 155 | .irq_unmask = max8998_irq_unmask, |
| 154 | }; | 156 | }; |
| 155 | 157 | ||
| 156 | static irqreturn_t max8998_irq_thread(int irq, void *data) | 158 | static irqreturn_t max8998_irq_thread(int irq, void *data) |
| @@ -181,6 +183,13 @@ static irqreturn_t max8998_irq_thread(int irq, void *data) | |||
| 181 | return IRQ_HANDLED; | 183 | return IRQ_HANDLED; |
| 182 | } | 184 | } |
| 183 | 185 | ||
| 186 | int max8998_irq_resume(struct max8998_dev *max8998) | ||
| 187 | { | ||
| 188 | if (max8998->irq && max8998->irq_base) | ||
| 189 | max8998_irq_thread(max8998->irq_base, max8998); | ||
| 190 | return 0; | ||
| 191 | } | ||
| 192 | |||
| 184 | int max8998_irq_init(struct max8998_dev *max8998) | 193 | int max8998_irq_init(struct max8998_dev *max8998) |
| 185 | { | 194 | { |
| 186 | int i; | 195 | int i; |
diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index bb9977bebe78..bbfe86732602 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c | |||
| @@ -25,6 +25,8 @@ | |||
| 25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
| 26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 27 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
| 28 | #include <linux/interrupt.h> | ||
| 29 | #include <linux/pm_runtime.h> | ||
| 28 | #include <linux/mutex.h> | 30 | #include <linux/mutex.h> |
| 29 | #include <linux/mfd/core.h> | 31 | #include <linux/mfd/core.h> |
| 30 | #include <linux/mfd/max8998.h> | 32 | #include <linux/mfd/max8998.h> |
| @@ -40,6 +42,14 @@ static struct mfd_cell max8998_devs[] = { | |||
| 40 | }, | 42 | }, |
| 41 | }; | 43 | }; |
| 42 | 44 | ||
| 45 | static struct mfd_cell lp3974_devs[] = { | ||
| 46 | { | ||
| 47 | .name = "lp3974-pmic", | ||
| 48 | }, { | ||
| 49 | .name = "lp3974-rtc", | ||
| 50 | }, | ||
| 51 | }; | ||
| 52 | |||
| 43 | int max8998_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest) | 53 | int max8998_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest) |
| 44 | { | 54 | { |
| 45 | struct max8998_dev *max8998 = i2c_get_clientdata(i2c); | 55 | struct max8998_dev *max8998 = i2c_get_clientdata(i2c); |
| @@ -135,6 +145,7 @@ static int max8998_i2c_probe(struct i2c_client *i2c, | |||
| 135 | if (pdata) { | 145 | if (pdata) { |
| 136 | max8998->ono = pdata->ono; | 146 | max8998->ono = pdata->ono; |
| 137 | max8998->irq_base = pdata->irq_base; | 147 | max8998->irq_base = pdata->irq_base; |
| 148 | max8998->wakeup = pdata->wakeup; | ||
| 138 | } | 149 | } |
| 139 | mutex_init(&max8998->iolock); | 150 | mutex_init(&max8998->iolock); |
| 140 | 151 | ||
| @@ -143,9 +154,23 @@ static int max8998_i2c_probe(struct i2c_client *i2c, | |||
| 143 | 154 | ||
| 144 | max8998_irq_init(max8998); | 155 | max8998_irq_init(max8998); |
| 145 | 156 | ||
| 146 | ret = mfd_add_devices(max8998->dev, -1, | 157 | pm_runtime_set_active(max8998->dev); |
| 147 | max8998_devs, ARRAY_SIZE(max8998_devs), | 158 | |
| 148 | NULL, 0); | 159 | switch (id->driver_data) { |
| 160 | case TYPE_LP3974: | ||
| 161 | ret = mfd_add_devices(max8998->dev, -1, | ||
| 162 | lp3974_devs, ARRAY_SIZE(lp3974_devs), | ||
| 163 | NULL, 0); | ||
| 164 | break; | ||
| 165 | case TYPE_MAX8998: | ||
| 166 | ret = mfd_add_devices(max8998->dev, -1, | ||
| 167 | max8998_devs, ARRAY_SIZE(max8998_devs), | ||
| 168 | NULL, 0); | ||
| 169 | break; | ||
| 170 | default: | ||
| 171 | ret = -EINVAL; | ||
| 172 | } | ||
| 173 | |||
| 149 | if (ret < 0) | 174 | if (ret < 0) |
| 150 | goto err; | 175 | goto err; |
| 151 | 176 | ||
| @@ -178,10 +203,113 @@ static const struct i2c_device_id max8998_i2c_id[] = { | |||
| 178 | }; | 203 | }; |
| 179 | MODULE_DEVICE_TABLE(i2c, max8998_i2c_id); | 204 | MODULE_DEVICE_TABLE(i2c, max8998_i2c_id); |
| 180 | 205 | ||
| 206 | static int max8998_suspend(struct device *dev) | ||
| 207 | { | ||
| 208 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | ||
| 209 | struct max8998_dev *max8998 = i2c_get_clientdata(i2c); | ||
| 210 | |||
| 211 | if (max8998->wakeup) | ||
| 212 | set_irq_wake(max8998->irq, 1); | ||
| 213 | return 0; | ||
| 214 | } | ||
| 215 | |||
| 216 | static int max8998_resume(struct device *dev) | ||
| 217 | { | ||
| 218 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | ||
| 219 | struct max8998_dev *max8998 = i2c_get_clientdata(i2c); | ||
| 220 | |||
| 221 | if (max8998->wakeup) | ||
| 222 | set_irq_wake(max8998->irq, 0); | ||
| 223 | /* | ||
| 224 | * In LP3974, if IRQ registers are not "read & clear" | ||
| 225 | * when it's set during sleep, the interrupt becomes | ||
| 226 | * disabled. | ||
| 227 | */ | ||
| 228 | return max8998_irq_resume(i2c_get_clientdata(i2c)); | ||
| 229 | } | ||
| 230 | |||
| 231 | struct max8998_reg_dump { | ||
| 232 | u8 addr; | ||
| 233 | u8 val; | ||
| 234 | }; | ||
| 235 | #define SAVE_ITEM(x) { .addr = (x), .val = 0x0, } | ||
| 236 | struct max8998_reg_dump max8998_dump[] = { | ||
| 237 | SAVE_ITEM(MAX8998_REG_IRQM1), | ||
| 238 | SAVE_ITEM(MAX8998_REG_IRQM2), | ||
| 239 | SAVE_ITEM(MAX8998_REG_IRQM3), | ||
| 240 | SAVE_ITEM(MAX8998_REG_IRQM4), | ||
| 241 | SAVE_ITEM(MAX8998_REG_STATUSM1), | ||
| 242 | SAVE_ITEM(MAX8998_REG_STATUSM2), | ||
| 243 | SAVE_ITEM(MAX8998_REG_CHGR1), | ||
| 244 | SAVE_ITEM(MAX8998_REG_CHGR2), | ||
| 245 | SAVE_ITEM(MAX8998_REG_LDO_ACTIVE_DISCHARGE1), | ||
| 246 | SAVE_ITEM(MAX8998_REG_LDO_ACTIVE_DISCHARGE1), | ||
| 247 | SAVE_ITEM(MAX8998_REG_BUCK_ACTIVE_DISCHARGE3), | ||
| 248 | SAVE_ITEM(MAX8998_REG_ONOFF1), | ||
| 249 | SAVE_ITEM(MAX8998_REG_ONOFF2), | ||
| 250 | SAVE_ITEM(MAX8998_REG_ONOFF3), | ||
| 251 | SAVE_ITEM(MAX8998_REG_ONOFF4), | ||
| 252 | SAVE_ITEM(MAX8998_REG_BUCK1_VOLTAGE1), | ||
| 253 | SAVE_ITEM(MAX8998_REG_BUCK1_VOLTAGE2), | ||
| 254 | SAVE_ITEM(MAX8998_REG_BUCK1_VOLTAGE3), | ||
| 255 | SAVE_ITEM(MAX8998_REG_BUCK1_VOLTAGE4), | ||
| 256 | SAVE_ITEM(MAX8998_REG_BUCK2_VOLTAGE1), | ||
| 257 | SAVE_ITEM(MAX8998_REG_BUCK2_VOLTAGE2), | ||
| 258 | SAVE_ITEM(MAX8998_REG_LDO2_LDO3), | ||
| 259 | SAVE_ITEM(MAX8998_REG_LDO4), | ||
| 260 | SAVE_ITEM(MAX8998_REG_LDO5), | ||
| 261 | SAVE_ITEM(MAX8998_REG_LDO6), | ||
| 262 | SAVE_ITEM(MAX8998_REG_LDO7), | ||
| 263 | SAVE_ITEM(MAX8998_REG_LDO8_LDO9), | ||
| 264 | SAVE_ITEM(MAX8998_REG_LDO10_LDO11), | ||
| 265 | SAVE_ITEM(MAX8998_REG_LDO12), | ||
| 266 | SAVE_ITEM(MAX8998_REG_LDO13), | ||
| 267 | SAVE_ITEM(MAX8998_REG_LDO14), | ||
| 268 | SAVE_ITEM(MAX8998_REG_LDO15), | ||
| 269 | SAVE_ITEM(MAX8998_REG_LDO16), | ||
| 270 | SAVE_ITEM(MAX8998_REG_LDO17), | ||
| 271 | SAVE_ITEM(MAX8998_REG_BKCHR), | ||
| 272 | SAVE_ITEM(MAX8998_REG_LBCNFG1), | ||
| 273 | SAVE_ITEM(MAX8998_REG_LBCNFG2), | ||
| 274 | }; | ||
| 275 | /* Save registers before hibernation */ | ||
| 276 | static int max8998_freeze(struct device *dev) | ||
| 277 | { | ||
| 278 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | ||
| 279 | int i; | ||
| 280 | |||
| 281 | for (i = 0; i < ARRAY_SIZE(max8998_dump); i++) | ||
| 282 | max8998_read_reg(i2c, max8998_dump[i].addr, | ||
| 283 | &max8998_dump[i].val); | ||
| 284 | |||
| 285 | return 0; | ||
| 286 | } | ||
| 287 | |||
| 288 | /* Restore registers after hibernation */ | ||
| 289 | static int max8998_restore(struct device *dev) | ||
| 290 | { | ||
| 291 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | ||
| 292 | int i; | ||
| 293 | |||
| 294 | for (i = 0; i < ARRAY_SIZE(max8998_dump); i++) | ||
| 295 | max8998_write_reg(i2c, max8998_dump[i].addr, | ||
| 296 | max8998_dump[i].val); | ||
| 297 | |||
| 298 | return 0; | ||
| 299 | } | ||
| 300 | |||
| 301 | const struct dev_pm_ops max8998_pm = { | ||
| 302 | .suspend = max8998_suspend, | ||
| 303 | .resume = max8998_resume, | ||
| 304 | .freeze = max8998_freeze, | ||
| 305 | .restore = max8998_restore, | ||
| 306 | }; | ||
| 307 | |||
| 181 | static struct i2c_driver max8998_i2c_driver = { | 308 | static struct i2c_driver max8998_i2c_driver = { |
| 182 | .driver = { | 309 | .driver = { |
| 183 | .name = "max8998", | 310 | .name = "max8998", |
| 184 | .owner = THIS_MODULE, | 311 | .owner = THIS_MODULE, |
| 312 | .pm = &max8998_pm, | ||
| 185 | }, | 313 | }, |
| 186 | .probe = max8998_i2c_probe, | 314 | .probe = max8998_i2c_probe, |
| 187 | .remove = max8998_i2c_remove, | 315 | .remove = max8998_i2c_remove, |
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c index a2ac2ed6d64c..b9fcaf0004da 100644 --- a/drivers/mfd/mc13xxx-core.c +++ b/drivers/mfd/mc13xxx-core.c | |||
| @@ -749,7 +749,7 @@ static int mc13xxx_probe(struct spi_device *spi) | |||
| 749 | if (ret) { | 749 | if (ret) { |
| 750 | err_mask: | 750 | err_mask: |
| 751 | err_revision: | 751 | err_revision: |
| 752 | mutex_unlock(&mc13xxx->lock); | 752 | mc13xxx_unlock(mc13xxx); |
| 753 | dev_set_drvdata(&spi->dev, NULL); | 753 | dev_set_drvdata(&spi->dev, NULL); |
| 754 | kfree(mc13xxx); | 754 | kfree(mc13xxx); |
| 755 | return ret; | 755 | return ret; |
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index ec99f681e773..d83ad0f141af 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
| 16 | #include <linux/acpi.h> | 16 | #include <linux/acpi.h> |
| 17 | #include <linux/mfd/core.h> | 17 | #include <linux/mfd/core.h> |
| 18 | #include <linux/pm_runtime.h> | ||
| 18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
| 19 | 20 | ||
| 20 | static int mfd_add_device(struct device *parent, int id, | 21 | static int mfd_add_device(struct device *parent, int id, |
| @@ -82,6 +83,9 @@ static int mfd_add_device(struct device *parent, int id, | |||
| 82 | if (ret) | 83 | if (ret) |
| 83 | goto fail_res; | 84 | goto fail_res; |
| 84 | 85 | ||
| 86 | if (cell->pm_runtime_no_callbacks) | ||
| 87 | pm_runtime_no_callbacks(&pdev->dev); | ||
| 88 | |||
| 85 | kfree(res); | 89 | kfree(res); |
| 86 | 90 | ||
| 87 | return 0; | 91 | return 0; |
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index bc9275c12133..5de3a760ea1e 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | #include <linux/sm501-regs.h> | 26 | #include <linux/sm501-regs.h> |
| 27 | #include <linux/serial_8250.h> | 27 | #include <linux/serial_8250.h> |
| 28 | 28 | ||
| 29 | #include <asm/io.h> | 29 | #include <linux/io.h> |
| 30 | 30 | ||
| 31 | struct sm501_device { | 31 | struct sm501_device { |
| 32 | struct list_head list; | 32 | struct list_head list; |
| @@ -745,11 +745,8 @@ static int sm501_register_device(struct sm501_devdata *sm, | |||
| 745 | int ret; | 745 | int ret; |
| 746 | 746 | ||
| 747 | for (ptr = 0; ptr < pdev->num_resources; ptr++) { | 747 | for (ptr = 0; ptr < pdev->num_resources; ptr++) { |
| 748 | printk(KERN_DEBUG "%s[%d] flags %08lx: %08llx..%08llx\n", | 748 | printk(KERN_DEBUG "%s[%d] %pR\n", |
| 749 | pdev->name, ptr, | 749 | pdev->name, ptr, &pdev->resource[ptr]); |
| 750 | pdev->resource[ptr].flags, | ||
| 751 | (unsigned long long)pdev->resource[ptr].start, | ||
| 752 | (unsigned long long)pdev->resource[ptr].end); | ||
| 753 | } | 750 | } |
| 754 | 751 | ||
| 755 | ret = platform_device_register(pdev); | 752 | ret = platform_device_register(pdev); |
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index b11487f1e1cb..3e5732b58c49 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c | |||
| @@ -699,16 +699,16 @@ static irqreturn_t stmpe_irq(int irq, void *data) | |||
| 699 | return IRQ_HANDLED; | 699 | return IRQ_HANDLED; |
| 700 | } | 700 | } |
| 701 | 701 | ||
| 702 | static void stmpe_irq_lock(unsigned int irq) | 702 | static void stmpe_irq_lock(struct irq_data *data) |
| 703 | { | 703 | { |
| 704 | struct stmpe *stmpe = get_irq_chip_data(irq); | 704 | struct stmpe *stmpe = irq_data_get_irq_chip_data(data); |
| 705 | 705 | ||
| 706 | mutex_lock(&stmpe->irq_lock); | 706 | mutex_lock(&stmpe->irq_lock); |
| 707 | } | 707 | } |
| 708 | 708 | ||
| 709 | static void stmpe_irq_sync_unlock(unsigned int irq) | 709 | static void stmpe_irq_sync_unlock(struct irq_data *data) |
| 710 | { | 710 | { |
| 711 | struct stmpe *stmpe = get_irq_chip_data(irq); | 711 | struct stmpe *stmpe = irq_data_get_irq_chip_data(data); |
| 712 | struct stmpe_variant_info *variant = stmpe->variant; | 712 | struct stmpe_variant_info *variant = stmpe->variant; |
| 713 | int num = DIV_ROUND_UP(variant->num_irqs, 8); | 713 | int num = DIV_ROUND_UP(variant->num_irqs, 8); |
| 714 | int i; | 714 | int i; |
| @@ -727,20 +727,20 @@ static void stmpe_irq_sync_unlock(unsigned int irq) | |||
| 727 | mutex_unlock(&stmpe->irq_lock); | 727 | mutex_unlock(&stmpe->irq_lock); |
| 728 | } | 728 | } |
| 729 | 729 | ||
| 730 | static void stmpe_irq_mask(unsigned int irq) | 730 | static void stmpe_irq_mask(struct irq_data *data) |
| 731 | { | 731 | { |
| 732 | struct stmpe *stmpe = get_irq_chip_data(irq); | 732 | struct stmpe *stmpe = irq_data_get_irq_chip_data(data); |
| 733 | int offset = irq - stmpe->irq_base; | 733 | int offset = data->irq - stmpe->irq_base; |
| 734 | int regoffset = offset / 8; | 734 | int regoffset = offset / 8; |
| 735 | int mask = 1 << (offset % 8); | 735 | int mask = 1 << (offset % 8); |
| 736 | 736 | ||
| 737 | stmpe->ier[regoffset] &= ~mask; | 737 | stmpe->ier[regoffset] &= ~mask; |
| 738 | } | 738 | } |
| 739 | 739 | ||
| 740 | static void stmpe_irq_unmask(unsigned int irq) | 740 | static void stmpe_irq_unmask(struct irq_data *data) |
| 741 | { | 741 | { |
| 742 | struct stmpe *stmpe = get_irq_chip_data(irq); | 742 | struct stmpe *stmpe = irq_data_get_irq_chip_data(data); |
| 743 | int offset = irq - stmpe->irq_base; | 743 | int offset = data->irq - stmpe->irq_base; |
| 744 | int regoffset = offset / 8; | 744 | int regoffset = offset / 8; |
| 745 | int mask = 1 << (offset % 8); | 745 | int mask = 1 << (offset % 8); |
| 746 | 746 | ||
| @@ -749,10 +749,10 @@ static void stmpe_irq_unmask(unsigned int irq) | |||
| 749 | 749 | ||
| 750 | static struct irq_chip stmpe_irq_chip = { | 750 | static struct irq_chip stmpe_irq_chip = { |
| 751 | .name = "stmpe", | 751 | .name = "stmpe", |
| 752 | .bus_lock = stmpe_irq_lock, | 752 | .irq_bus_lock = stmpe_irq_lock, |
| 753 | .bus_sync_unlock = stmpe_irq_sync_unlock, | 753 | .irq_bus_sync_unlock = stmpe_irq_sync_unlock, |
| 754 | .mask = stmpe_irq_mask, | 754 | .irq_mask = stmpe_irq_mask, |
| 755 | .unmask = stmpe_irq_unmask, | 755 | .irq_unmask = stmpe_irq_unmask, |
| 756 | }; | 756 | }; |
| 757 | 757 | ||
| 758 | static int __devinit stmpe_irq_init(struct stmpe *stmpe) | 758 | static int __devinit stmpe_irq_init(struct stmpe *stmpe) |
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c index 006c121f3f0d..9caeb4ac6ea6 100644 --- a/drivers/mfd/t7l66xb.c +++ b/drivers/mfd/t7l66xb.c | |||
| @@ -199,37 +199,37 @@ static void t7l66xb_irq(unsigned int irq, struct irq_desc *desc) | |||
| 199 | generic_handle_irq(irq_base + i); | 199 | generic_handle_irq(irq_base + i); |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | static void t7l66xb_irq_mask(unsigned int irq) | 202 | static void t7l66xb_irq_mask(struct irq_data *data) |
| 203 | { | 203 | { |
| 204 | struct t7l66xb *t7l66xb = get_irq_chip_data(irq); | 204 | struct t7l66xb *t7l66xb = irq_data_get_irq_chip_data(data); |
| 205 | unsigned long flags; | 205 | unsigned long flags; |
| 206 | u8 imr; | 206 | u8 imr; |
| 207 | 207 | ||
| 208 | spin_lock_irqsave(&t7l66xb->lock, flags); | 208 | spin_lock_irqsave(&t7l66xb->lock, flags); |
| 209 | imr = tmio_ioread8(t7l66xb->scr + SCR_IMR); | 209 | imr = tmio_ioread8(t7l66xb->scr + SCR_IMR); |
| 210 | imr |= 1 << (irq - t7l66xb->irq_base); | 210 | imr |= 1 << (data->irq - t7l66xb->irq_base); |
| 211 | tmio_iowrite8(imr, t7l66xb->scr + SCR_IMR); | 211 | tmio_iowrite8(imr, t7l66xb->scr + SCR_IMR); |
| 212 | spin_unlock_irqrestore(&t7l66xb->lock, flags); | 212 | spin_unlock_irqrestore(&t7l66xb->lock, flags); |
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | static void t7l66xb_irq_unmask(unsigned int irq) | 215 | static void t7l66xb_irq_unmask(struct irq_data *data) |
| 216 | { | 216 | { |
| 217 | struct t7l66xb *t7l66xb = get_irq_chip_data(irq); | 217 | struct t7l66xb *t7l66xb = irq_data_get_irq_chip_data(data); |
| 218 | unsigned long flags; | 218 | unsigned long flags; |
| 219 | u8 imr; | 219 | u8 imr; |
| 220 | 220 | ||
| 221 | spin_lock_irqsave(&t7l66xb->lock, flags); | 221 | spin_lock_irqsave(&t7l66xb->lock, flags); |
| 222 | imr = tmio_ioread8(t7l66xb->scr + SCR_IMR); | 222 | imr = tmio_ioread8(t7l66xb->scr + SCR_IMR); |
| 223 | imr &= ~(1 << (irq - t7l66xb->irq_base)); | 223 | imr &= ~(1 << (data->irq - t7l66xb->irq_base)); |
| 224 | tmio_iowrite8(imr, t7l66xb->scr + SCR_IMR); | 224 | tmio_iowrite8(imr, t7l66xb->scr + SCR_IMR); |
| 225 | spin_unlock_irqrestore(&t7l66xb->lock, flags); | 225 | spin_unlock_irqrestore(&t7l66xb->lock, flags); |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | static struct irq_chip t7l66xb_chip = { | 228 | static struct irq_chip t7l66xb_chip = { |
| 229 | .name = "t7l66xb", | 229 | .name = "t7l66xb", |
| 230 | .ack = t7l66xb_irq_mask, | 230 | .irq_ack = t7l66xb_irq_mask, |
| 231 | .mask = t7l66xb_irq_mask, | 231 | .irq_mask = t7l66xb_irq_mask, |
| 232 | .unmask = t7l66xb_irq_unmask, | 232 | .irq_unmask = t7l66xb_irq_unmask, |
| 233 | }; | 233 | }; |
| 234 | 234 | ||
| 235 | /*--------------------------------------------------------------------------*/ | 235 | /*--------------------------------------------------------------------------*/ |
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index 1ea80d8ad915..9a238633a54d 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c | |||
| @@ -527,41 +527,41 @@ tc6393xb_irq(unsigned int irq, struct irq_desc *desc) | |||
| 527 | } | 527 | } |
| 528 | } | 528 | } |
| 529 | 529 | ||
| 530 | static void tc6393xb_irq_ack(unsigned int irq) | 530 | static void tc6393xb_irq_ack(struct irq_data *data) |
| 531 | { | 531 | { |
| 532 | } | 532 | } |
| 533 | 533 | ||
| 534 | static void tc6393xb_irq_mask(unsigned int irq) | 534 | static void tc6393xb_irq_mask(struct irq_data *data) |
| 535 | { | 535 | { |
| 536 | struct tc6393xb *tc6393xb = get_irq_chip_data(irq); | 536 | struct tc6393xb *tc6393xb = irq_data_get_irq_chip_data(data); |
| 537 | unsigned long flags; | 537 | unsigned long flags; |
| 538 | u8 imr; | 538 | u8 imr; |
| 539 | 539 | ||
| 540 | spin_lock_irqsave(&tc6393xb->lock, flags); | 540 | spin_lock_irqsave(&tc6393xb->lock, flags); |
| 541 | imr = tmio_ioread8(tc6393xb->scr + SCR_IMR); | 541 | imr = tmio_ioread8(tc6393xb->scr + SCR_IMR); |
| 542 | imr |= 1 << (irq - tc6393xb->irq_base); | 542 | imr |= 1 << (data->irq - tc6393xb->irq_base); |
| 543 | tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR); | 543 | tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR); |
| 544 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | 544 | spin_unlock_irqrestore(&tc6393xb->lock, flags); |
| 545 | } | 545 | } |
| 546 | 546 | ||
| 547 | static void tc6393xb_irq_unmask(unsigned int irq) | 547 | static void tc6393xb_irq_unmask(struct irq_data *data) |
| 548 | { | 548 | { |
| 549 | struct tc6393xb *tc6393xb = get_irq_chip_data(irq); | 549 | struct tc6393xb *tc6393xb = irq_data_get_irq_chip_data(data); |
| 550 | unsigned long flags; | 550 | unsigned long flags; |
| 551 | u8 imr; | 551 | u8 imr; |
| 552 | 552 | ||
| 553 | spin_lock_irqsave(&tc6393xb->lock, flags); | 553 | spin_lock_irqsave(&tc6393xb->lock, flags); |
| 554 | imr = tmio_ioread8(tc6393xb->scr + SCR_IMR); | 554 | imr = tmio_ioread8(tc6393xb->scr + SCR_IMR); |
| 555 | imr &= ~(1 << (irq - tc6393xb->irq_base)); | 555 | imr &= ~(1 << (data->irq - tc6393xb->irq_base)); |
| 556 | tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR); | 556 | tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR); |
| 557 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | 557 | spin_unlock_irqrestore(&tc6393xb->lock, flags); |
| 558 | } | 558 | } |
| 559 | 559 | ||
| 560 | static struct irq_chip tc6393xb_chip = { | 560 | static struct irq_chip tc6393xb_chip = { |
| 561 | .name = "tc6393xb", | 561 | .name = "tc6393xb", |
| 562 | .ack = tc6393xb_irq_ack, | 562 | .irq_ack = tc6393xb_irq_ack, |
| 563 | .mask = tc6393xb_irq_mask, | 563 | .irq_mask = tc6393xb_irq_mask, |
| 564 | .unmask = tc6393xb_irq_unmask, | 564 | .irq_unmask = tc6393xb_irq_unmask, |
| 565 | }; | 565 | }; |
| 566 | 566 | ||
| 567 | static void tc6393xb_attach_irq(struct platform_device *dev) | 567 | static void tc6393xb_attach_irq(struct platform_device *dev) |
diff --git a/drivers/mfd/tps65010.c b/drivers/mfd/tps65010.c index 90187fe33e04..93d5fdf020c7 100644 --- a/drivers/mfd/tps65010.c +++ b/drivers/mfd/tps65010.c | |||
| @@ -34,7 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | #include <linux/i2c/tps65010.h> | 35 | #include <linux/i2c/tps65010.h> |
| 36 | 36 | ||
| 37 | #include <asm/gpio.h> | 37 | #include <linux/gpio.h> |
| 38 | 38 | ||
| 39 | 39 | ||
| 40 | /*-------------------------------------------------------------------------*/ | 40 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index b4931ab34929..627cf577b16d 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c | |||
| @@ -46,8 +46,6 @@ | |||
| 46 | 46 | ||
| 47 | /* device id */ | 47 | /* device id */ |
| 48 | #define TPS6586X_VERSIONCRC 0xcd | 48 | #define TPS6586X_VERSIONCRC 0xcd |
| 49 | #define TPS658621A_VERSIONCRC 0x15 | ||
| 50 | #define TPS658621C_VERSIONCRC 0x2c | ||
| 51 | 49 | ||
| 52 | struct tps6586x_irq_data { | 50 | struct tps6586x_irq_data { |
| 53 | u8 mask_reg; | 51 | u8 mask_reg; |
| @@ -325,37 +323,37 @@ static int tps6586x_remove_subdevs(struct tps6586x *tps6586x) | |||
| 325 | return device_for_each_child(tps6586x->dev, NULL, __remove_subdev); | 323 | return device_for_each_child(tps6586x->dev, NULL, __remove_subdev); |
| 326 | } | 324 | } |
| 327 | 325 | ||
| 328 | static void tps6586x_irq_lock(unsigned int irq) | 326 | static void tps6586x_irq_lock(struct irq_data *data) |
| 329 | { | 327 | { |
| 330 | struct tps6586x *tps6586x = get_irq_chip_data(irq); | 328 | struct tps6586x *tps6586x = irq_data_get_irq_chip_data(data); |
| 331 | 329 | ||
| 332 | mutex_lock(&tps6586x->irq_lock); | 330 | mutex_lock(&tps6586x->irq_lock); |
| 333 | } | 331 | } |
| 334 | 332 | ||
| 335 | static void tps6586x_irq_enable(unsigned int irq) | 333 | static void tps6586x_irq_enable(struct irq_data *irq_data) |
| 336 | { | 334 | { |
| 337 | struct tps6586x *tps6586x = get_irq_chip_data(irq); | 335 | struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data); |
| 338 | unsigned int __irq = irq - tps6586x->irq_base; | 336 | unsigned int __irq = irq_data->irq - tps6586x->irq_base; |
| 339 | const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq]; | 337 | const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq]; |
| 340 | 338 | ||
| 341 | tps6586x->mask_reg[data->mask_reg] &= ~data->mask_mask; | 339 | tps6586x->mask_reg[data->mask_reg] &= ~data->mask_mask; |
| 342 | tps6586x->irq_en |= (1 << __irq); | 340 | tps6586x->irq_en |= (1 << __irq); |
| 343 | } | 341 | } |
| 344 | 342 | ||
| 345 | static void tps6586x_irq_disable(unsigned int irq) | 343 | static void tps6586x_irq_disable(struct irq_data *irq_data) |
| 346 | { | 344 | { |
| 347 | struct tps6586x *tps6586x = get_irq_chip_data(irq); | 345 | struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data); |
| 348 | 346 | ||
| 349 | unsigned int __irq = irq - tps6586x->irq_base; | 347 | unsigned int __irq = irq_data->irq - tps6586x->irq_base; |
| 350 | const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq]; | 348 | const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq]; |
| 351 | 349 | ||
| 352 | tps6586x->mask_reg[data->mask_reg] |= data->mask_mask; | 350 | tps6586x->mask_reg[data->mask_reg] |= data->mask_mask; |
| 353 | tps6586x->irq_en &= ~(1 << __irq); | 351 | tps6586x->irq_en &= ~(1 << __irq); |
| 354 | } | 352 | } |
| 355 | 353 | ||
| 356 | static void tps6586x_irq_sync_unlock(unsigned int irq) | 354 | static void tps6586x_irq_sync_unlock(struct irq_data *data) |
| 357 | { | 355 | { |
| 358 | struct tps6586x *tps6586x = get_irq_chip_data(irq); | 356 | struct tps6586x *tps6586x = irq_data_get_irq_chip_data(data); |
| 359 | int i; | 357 | int i; |
| 360 | 358 | ||
| 361 | for (i = 0; i < ARRAY_SIZE(tps6586x->mask_reg); i++) { | 359 | for (i = 0; i < ARRAY_SIZE(tps6586x->mask_reg); i++) { |
| @@ -421,10 +419,10 @@ static int __devinit tps6586x_irq_init(struct tps6586x *tps6586x, int irq, | |||
| 421 | tps6586x->irq_base = irq_base; | 419 | tps6586x->irq_base = irq_base; |
| 422 | 420 | ||
| 423 | tps6586x->irq_chip.name = "tps6586x"; | 421 | tps6586x->irq_chip.name = "tps6586x"; |
| 424 | tps6586x->irq_chip.enable = tps6586x_irq_enable; | 422 | tps6586x->irq_chip.irq_enable = tps6586x_irq_enable; |
| 425 | tps6586x->irq_chip.disable = tps6586x_irq_disable; | 423 | tps6586x->irq_chip.irq_disable = tps6586x_irq_disable; |
| 426 | tps6586x->irq_chip.bus_lock = tps6586x_irq_lock; | 424 | tps6586x->irq_chip.irq_bus_lock = tps6586x_irq_lock; |
| 427 | tps6586x->irq_chip.bus_sync_unlock = tps6586x_irq_sync_unlock; | 425 | tps6586x->irq_chip.irq_bus_sync_unlock = tps6586x_irq_sync_unlock; |
| 428 | 426 | ||
| 429 | for (i = 0; i < ARRAY_SIZE(tps6586x_irqs); i++) { | 427 | for (i = 0; i < ARRAY_SIZE(tps6586x_irqs); i++) { |
| 430 | int __irq = i + tps6586x->irq_base; | 428 | int __irq = i + tps6586x->irq_base; |
| @@ -498,11 +496,7 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client, | |||
| 498 | return -EIO; | 496 | return -EIO; |
| 499 | } | 497 | } |
| 500 | 498 | ||
| 501 | if ((ret != TPS658621A_VERSIONCRC) && | 499 | dev_info(&client->dev, "VERSIONCRC is %02x\n", ret); |
| 502 | (ret != TPS658621C_VERSIONCRC)) { | ||
| 503 | dev_err(&client->dev, "Unsupported chip ID: %x\n", ret); | ||
| 504 | return -ENODEV; | ||
| 505 | } | ||
| 506 | 500 | ||
| 507 | tps6586x = kzalloc(sizeof(struct tps6586x), GFP_KERNEL); | 501 | tps6586x = kzalloc(sizeof(struct tps6586x), GFP_KERNEL); |
| 508 | if (tps6586x == NULL) | 502 | if (tps6586x == NULL) |
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 12abd5b924b3..a35fa7dcbf53 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c | |||
| @@ -1003,7 +1003,7 @@ static int twl_remove(struct i2c_client *client) | |||
| 1003 | } | 1003 | } |
| 1004 | 1004 | ||
| 1005 | /* NOTE: this driver only handles a single twl4030/tps659x0 chip */ | 1005 | /* NOTE: this driver only handles a single twl4030/tps659x0 chip */ |
| 1006 | static int __init | 1006 | static int __devinit |
| 1007 | twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | 1007 | twl_probe(struct i2c_client *client, const struct i2c_device_id *id) |
| 1008 | { | 1008 | { |
| 1009 | int status; | 1009 | int status; |
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index 5d3a1478004b..63a30e88908f 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c | |||
| @@ -599,38 +599,38 @@ static void twl4030_sih_do_edge(struct work_struct *work) | |||
| 599 | * completion, potentially including some re-ordering, of these requests. | 599 | * completion, potentially including some re-ordering, of these requests. |
| 600 | */ | 600 | */ |
| 601 | 601 | ||
| 602 | static void twl4030_sih_mask(unsigned irq) | 602 | static void twl4030_sih_mask(struct irq_data *data) |
| 603 | { | 603 | { |
| 604 | struct sih_agent *sih = get_irq_chip_data(irq); | 604 | struct sih_agent *sih = irq_data_get_irq_chip_data(data); |
| 605 | unsigned long flags; | 605 | unsigned long flags; |
| 606 | 606 | ||
| 607 | spin_lock_irqsave(&sih_agent_lock, flags); | 607 | spin_lock_irqsave(&sih_agent_lock, flags); |
| 608 | sih->imr |= BIT(irq - sih->irq_base); | 608 | sih->imr |= BIT(data->irq - sih->irq_base); |
| 609 | sih->imr_change_pending = true; | 609 | sih->imr_change_pending = true; |
| 610 | queue_work(wq, &sih->mask_work); | 610 | queue_work(wq, &sih->mask_work); |
| 611 | spin_unlock_irqrestore(&sih_agent_lock, flags); | 611 | spin_unlock_irqrestore(&sih_agent_lock, flags); |
| 612 | } | 612 | } |
| 613 | 613 | ||
| 614 | static void twl4030_sih_unmask(unsigned irq) | 614 | static void twl4030_sih_unmask(struct irq_data *data) |
| 615 | { | 615 | { |
| 616 | struct sih_agent *sih = get_irq_chip_data(irq); | 616 | struct sih_agent *sih = irq_data_get_irq_chip_data(data); |
| 617 | unsigned long flags; | 617 | unsigned long flags; |
| 618 | 618 | ||
| 619 | spin_lock_irqsave(&sih_agent_lock, flags); | 619 | spin_lock_irqsave(&sih_agent_lock, flags); |
| 620 | sih->imr &= ~BIT(irq - sih->irq_base); | 620 | sih->imr &= ~BIT(data->irq - sih->irq_base); |
| 621 | sih->imr_change_pending = true; | 621 | sih->imr_change_pending = true; |
| 622 | queue_work(wq, &sih->mask_work); | 622 | queue_work(wq, &sih->mask_work); |
| 623 | spin_unlock_irqrestore(&sih_agent_lock, flags); | 623 | spin_unlock_irqrestore(&sih_agent_lock, flags); |
| 624 | } | 624 | } |
| 625 | 625 | ||
| 626 | static int twl4030_sih_set_type(unsigned irq, unsigned trigger) | 626 | static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger) |
| 627 | { | 627 | { |
| 628 | struct sih_agent *sih = get_irq_chip_data(irq); | 628 | struct sih_agent *sih = irq_data_get_irq_chip_data(data); |
| 629 | struct irq_desc *desc = irq_to_desc(irq); | 629 | struct irq_desc *desc = irq_to_desc(data->irq); |
| 630 | unsigned long flags; | 630 | unsigned long flags; |
| 631 | 631 | ||
| 632 | if (!desc) { | 632 | if (!desc) { |
| 633 | pr_err("twl4030: Invalid IRQ: %d\n", irq); | 633 | pr_err("twl4030: Invalid IRQ: %d\n", data->irq); |
| 634 | return -EINVAL; | 634 | return -EINVAL; |
| 635 | } | 635 | } |
| 636 | 636 | ||
| @@ -641,7 +641,7 @@ static int twl4030_sih_set_type(unsigned irq, unsigned trigger) | |||
| 641 | if ((desc->status & IRQ_TYPE_SENSE_MASK) != trigger) { | 641 | if ((desc->status & IRQ_TYPE_SENSE_MASK) != trigger) { |
| 642 | desc->status &= ~IRQ_TYPE_SENSE_MASK; | 642 | desc->status &= ~IRQ_TYPE_SENSE_MASK; |
| 643 | desc->status |= trigger; | 643 | desc->status |= trigger; |
| 644 | sih->edge_change |= BIT(irq - sih->irq_base); | 644 | sih->edge_change |= BIT(data->irq - sih->irq_base); |
| 645 | queue_work(wq, &sih->edge_work); | 645 | queue_work(wq, &sih->edge_work); |
| 646 | } | 646 | } |
| 647 | spin_unlock_irqrestore(&sih_agent_lock, flags); | 647 | spin_unlock_irqrestore(&sih_agent_lock, flags); |
| @@ -650,9 +650,9 @@ static int twl4030_sih_set_type(unsigned irq, unsigned trigger) | |||
| 650 | 650 | ||
| 651 | static struct irq_chip twl4030_sih_irq_chip = { | 651 | static struct irq_chip twl4030_sih_irq_chip = { |
| 652 | .name = "twl4030", | 652 | .name = "twl4030", |
| 653 | .mask = twl4030_sih_mask, | 653 | .irq_mask = twl4030_sih_mask, |
| 654 | .unmask = twl4030_sih_unmask, | 654 | .irq_unmask = twl4030_sih_unmask, |
| 655 | .set_type = twl4030_sih_set_type, | 655 | .irq_set_type = twl4030_sih_set_type, |
| 656 | }; | 656 | }; |
| 657 | 657 | ||
| 658 | /*----------------------------------------------------------------------*/ | 658 | /*----------------------------------------------------------------------*/ |
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c index 06c8955907e9..4082ed73613f 100644 --- a/drivers/mfd/twl6030-irq.c +++ b/drivers/mfd/twl6030-irq.c | |||
| @@ -332,7 +332,7 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) | |||
| 332 | */ | 332 | */ |
| 333 | twl6030_irq_chip = dummy_irq_chip; | 333 | twl6030_irq_chip = dummy_irq_chip; |
| 334 | twl6030_irq_chip.name = "twl6030"; | 334 | twl6030_irq_chip.name = "twl6030"; |
| 335 | twl6030_irq_chip.set_type = NULL; | 335 | twl6030_irq_chip.irq_set_type = NULL; |
| 336 | 336 | ||
| 337 | for (i = irq_base; i < irq_end; i++) { | 337 | for (i = irq_base; i < irq_end; i++) { |
| 338 | set_irq_chip_and_handler(i, &twl6030_irq_chip, | 338 | set_irq_chip_and_handler(i, &twl6030_irq_chip, |
diff --git a/drivers/mfd/vx855.c b/drivers/mfd/vx855.c index ebb059765edd..348052aa5dbf 100644 --- a/drivers/mfd/vx855.c +++ b/drivers/mfd/vx855.c | |||
| @@ -112,7 +112,7 @@ out: | |||
| 112 | return ret; | 112 | return ret; |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | static void vx855_remove(struct pci_dev *pdev) | 115 | static void __devexit vx855_remove(struct pci_dev *pdev) |
| 116 | { | 116 | { |
| 117 | mfd_remove_devices(&pdev->dev); | 117 | mfd_remove_devices(&pdev->dev); |
| 118 | pci_disable_device(pdev); | 118 | pci_disable_device(pdev); |
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index 76cadcf3b1fe..3fe9a58fe6c7 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c | |||
| @@ -1541,6 +1541,12 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
| 1541 | dev_info(wm831x->dev, "WM8325 revision %c\n", 'A' + rev); | 1541 | dev_info(wm831x->dev, "WM8325 revision %c\n", 'A' + rev); |
| 1542 | break; | 1542 | break; |
| 1543 | 1543 | ||
| 1544 | case WM8326: | ||
| 1545 | parent = WM8326; | ||
| 1546 | wm831x->num_gpio = 12; | ||
| 1547 | dev_info(wm831x->dev, "WM8326 revision %c\n", 'A' + rev); | ||
| 1548 | break; | ||
| 1549 | |||
| 1544 | default: | 1550 | default: |
| 1545 | dev_err(wm831x->dev, "Unknown WM831x device %04x\n", ret); | 1551 | dev_err(wm831x->dev, "Unknown WM831x device %04x\n", ret); |
| 1546 | ret = -EINVAL; | 1552 | ret = -EINVAL; |
| @@ -1610,18 +1616,9 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
| 1610 | break; | 1616 | break; |
| 1611 | 1617 | ||
| 1612 | case WM8320: | 1618 | case WM8320: |
| 1613 | ret = mfd_add_devices(wm831x->dev, -1, | ||
| 1614 | wm8320_devs, ARRAY_SIZE(wm8320_devs), | ||
| 1615 | NULL, 0); | ||
| 1616 | break; | ||
| 1617 | |||
| 1618 | case WM8321: | 1619 | case WM8321: |
| 1619 | ret = mfd_add_devices(wm831x->dev, -1, | ||
| 1620 | wm8320_devs, ARRAY_SIZE(wm8320_devs), | ||
| 1621 | NULL, 0); | ||
| 1622 | break; | ||
| 1623 | |||
| 1624 | case WM8325: | 1620 | case WM8325: |
| 1621 | case WM8326: | ||
| 1625 | ret = mfd_add_devices(wm831x->dev, -1, | 1622 | ret = mfd_add_devices(wm831x->dev, -1, |
| 1626 | wm8320_devs, ARRAY_SIZE(wm8320_devs), | 1623 | wm8320_devs, ARRAY_SIZE(wm8320_devs), |
| 1627 | NULL, wm831x->irq_base); | 1624 | NULL, wm831x->irq_base); |
diff --git a/drivers/mfd/wm831x-i2c.c b/drivers/mfd/wm831x-i2c.c index 156b19859e81..3853fa8e7cc2 100644 --- a/drivers/mfd/wm831x-i2c.c +++ b/drivers/mfd/wm831x-i2c.c | |||
| @@ -94,9 +94,9 @@ static int wm831x_i2c_remove(struct i2c_client *i2c) | |||
| 94 | return 0; | 94 | return 0; |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | static int wm831x_i2c_suspend(struct i2c_client *i2c, pm_message_t mesg) | 97 | static int wm831x_i2c_suspend(struct device *dev) |
| 98 | { | 98 | { |
| 99 | struct wm831x *wm831x = i2c_get_clientdata(i2c); | 99 | struct wm831x *wm831x = dev_get_drvdata(dev); |
| 100 | 100 | ||
| 101 | return wm831x_device_suspend(wm831x); | 101 | return wm831x_device_suspend(wm831x); |
| 102 | } | 102 | } |
| @@ -108,19 +108,23 @@ static const struct i2c_device_id wm831x_i2c_id[] = { | |||
| 108 | { "wm8320", WM8320 }, | 108 | { "wm8320", WM8320 }, |
| 109 | { "wm8321", WM8321 }, | 109 | { "wm8321", WM8321 }, |
| 110 | { "wm8325", WM8325 }, | 110 | { "wm8325", WM8325 }, |
| 111 | { "wm8326", WM8326 }, | ||
| 111 | { } | 112 | { } |
| 112 | }; | 113 | }; |
| 113 | MODULE_DEVICE_TABLE(i2c, wm831x_i2c_id); | 114 | MODULE_DEVICE_TABLE(i2c, wm831x_i2c_id); |
| 114 | 115 | ||
| 116 | static const struct dev_pm_ops wm831x_pm_ops = { | ||
| 117 | .suspend = wm831x_i2c_suspend, | ||
| 118 | }; | ||
| 115 | 119 | ||
| 116 | static struct i2c_driver wm831x_i2c_driver = { | 120 | static struct i2c_driver wm831x_i2c_driver = { |
| 117 | .driver = { | 121 | .driver = { |
| 118 | .name = "wm831x", | 122 | .name = "wm831x", |
| 119 | .owner = THIS_MODULE, | 123 | .owner = THIS_MODULE, |
| 124 | .pm = &wm831x_pm_ops, | ||
| 120 | }, | 125 | }, |
| 121 | .probe = wm831x_i2c_probe, | 126 | .probe = wm831x_i2c_probe, |
| 122 | .remove = wm831x_i2c_remove, | 127 | .remove = wm831x_i2c_remove, |
| 123 | .suspend = wm831x_i2c_suspend, | ||
| 124 | .id_table = wm831x_i2c_id, | 128 | .id_table = wm831x_i2c_id, |
| 125 | }; | 129 | }; |
| 126 | 130 | ||
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c index 294183b6260b..f7192d438aab 100644 --- a/drivers/mfd/wm831x-irq.c +++ b/drivers/mfd/wm831x-irq.c | |||
| @@ -345,16 +345,16 @@ static inline struct wm831x_irq_data *irq_to_wm831x_irq(struct wm831x *wm831x, | |||
| 345 | return &wm831x_irqs[irq - wm831x->irq_base]; | 345 | return &wm831x_irqs[irq - wm831x->irq_base]; |
| 346 | } | 346 | } |
| 347 | 347 | ||
| 348 | static void wm831x_irq_lock(unsigned int irq) | 348 | static void wm831x_irq_lock(struct irq_data *data) |
| 349 | { | 349 | { |
| 350 | struct wm831x *wm831x = get_irq_chip_data(irq); | 350 | struct wm831x *wm831x = irq_data_get_irq_chip_data(data); |
| 351 | 351 | ||
| 352 | mutex_lock(&wm831x->irq_lock); | 352 | mutex_lock(&wm831x->irq_lock); |
| 353 | } | 353 | } |
| 354 | 354 | ||
| 355 | static void wm831x_irq_sync_unlock(unsigned int irq) | 355 | static void wm831x_irq_sync_unlock(struct irq_data *data) |
| 356 | { | 356 | { |
| 357 | struct wm831x *wm831x = get_irq_chip_data(irq); | 357 | struct wm831x *wm831x = irq_data_get_irq_chip_data(data); |
| 358 | int i; | 358 | int i; |
| 359 | 359 | ||
| 360 | for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) { | 360 | for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) { |
| @@ -371,28 +371,30 @@ static void wm831x_irq_sync_unlock(unsigned int irq) | |||
| 371 | mutex_unlock(&wm831x->irq_lock); | 371 | mutex_unlock(&wm831x->irq_lock); |
| 372 | } | 372 | } |
| 373 | 373 | ||
| 374 | static void wm831x_irq_unmask(unsigned int irq) | 374 | static void wm831x_irq_unmask(struct irq_data *data) |
| 375 | { | 375 | { |
| 376 | struct wm831x *wm831x = get_irq_chip_data(irq); | 376 | struct wm831x *wm831x = irq_data_get_irq_chip_data(data); |
| 377 | struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, irq); | 377 | struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, |
| 378 | data->irq); | ||
| 378 | 379 | ||
| 379 | wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; | 380 | wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; |
| 380 | } | 381 | } |
| 381 | 382 | ||
| 382 | static void wm831x_irq_mask(unsigned int irq) | 383 | static void wm831x_irq_mask(struct irq_data *data) |
| 383 | { | 384 | { |
| 384 | struct wm831x *wm831x = get_irq_chip_data(irq); | 385 | struct wm831x *wm831x = irq_data_get_irq_chip_data(data); |
| 385 | struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, irq); | 386 | struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, |
| 387 | data->irq); | ||
| 386 | 388 | ||
| 387 | wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; | 389 | wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; |
| 388 | } | 390 | } |
| 389 | 391 | ||
| 390 | static int wm831x_irq_set_type(unsigned int irq, unsigned int type) | 392 | static int wm831x_irq_set_type(struct irq_data *data, unsigned int type) |
| 391 | { | 393 | { |
| 392 | struct wm831x *wm831x = get_irq_chip_data(irq); | 394 | struct wm831x *wm831x = irq_data_get_irq_chip_data(data); |
| 393 | int val; | 395 | int val, irq; |
| 394 | 396 | ||
| 395 | irq = irq - wm831x->irq_base; | 397 | irq = data->irq - wm831x->irq_base; |
| 396 | 398 | ||
| 397 | if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) { | 399 | if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) { |
| 398 | /* Ignore internal-only IRQs */ | 400 | /* Ignore internal-only IRQs */ |
| @@ -421,12 +423,12 @@ static int wm831x_irq_set_type(unsigned int irq, unsigned int type) | |||
| 421 | } | 423 | } |
| 422 | 424 | ||
| 423 | static struct irq_chip wm831x_irq_chip = { | 425 | static struct irq_chip wm831x_irq_chip = { |
| 424 | .name = "wm831x", | 426 | .name = "wm831x", |
| 425 | .bus_lock = wm831x_irq_lock, | 427 | .irq_bus_lock = wm831x_irq_lock, |
| 426 | .bus_sync_unlock = wm831x_irq_sync_unlock, | 428 | .irq_bus_sync_unlock = wm831x_irq_sync_unlock, |
| 427 | .mask = wm831x_irq_mask, | 429 | .irq_mask = wm831x_irq_mask, |
| 428 | .unmask = wm831x_irq_unmask, | 430 | .irq_unmask = wm831x_irq_unmask, |
| 429 | .set_type = wm831x_irq_set_type, | 431 | .irq_set_type = wm831x_irq_set_type, |
| 430 | }; | 432 | }; |
| 431 | 433 | ||
| 432 | /* The processing of the primary interrupt occurs in a thread so that | 434 | /* The processing of the primary interrupt occurs in a thread so that |
| @@ -515,6 +517,17 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq) | |||
| 515 | return 0; | 517 | return 0; |
| 516 | } | 518 | } |
| 517 | 519 | ||
| 520 | /* Try to flag /IRQ as a wake source; there are a number of | ||
| 521 | * unconditional wake sources in the PMIC so this isn't | ||
| 522 | * conditional but we don't actually care *too* much if it | ||
| 523 | * fails. | ||
| 524 | */ | ||
| 525 | ret = enable_irq_wake(irq); | ||
| 526 | if (ret != 0) { | ||
| 527 | dev_warn(wm831x->dev, "Can't enable IRQ as wake source: %d\n", | ||
| 528 | ret); | ||
| 529 | } | ||
| 530 | |||
| 518 | wm831x->irq = irq; | 531 | wm831x->irq = irq; |
| 519 | wm831x->irq_base = pdata->irq_base; | 532 | wm831x->irq_base = pdata->irq_base; |
| 520 | 533 | ||
diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c index 2789b151b0f9..0a8f772be88c 100644 --- a/drivers/mfd/wm831x-spi.c +++ b/drivers/mfd/wm831x-spi.c | |||
| @@ -81,6 +81,8 @@ static int __devinit wm831x_spi_probe(struct spi_device *spi) | |||
| 81 | type = WM8321; | 81 | type = WM8321; |
| 82 | else if (strcmp(spi->modalias, "wm8325") == 0) | 82 | else if (strcmp(spi->modalias, "wm8325") == 0) |
| 83 | type = WM8325; | 83 | type = WM8325; |
| 84 | else if (strcmp(spi->modalias, "wm8326") == 0) | ||
| 85 | type = WM8326; | ||
| 84 | else { | 86 | else { |
| 85 | dev_err(&spi->dev, "Unknown device type\n"); | 87 | dev_err(&spi->dev, "Unknown device type\n"); |
| 86 | return -EINVAL; | 88 | return -EINVAL; |
| @@ -184,6 +186,17 @@ static struct spi_driver wm8325_spi_driver = { | |||
| 184 | .suspend = wm831x_spi_suspend, | 186 | .suspend = wm831x_spi_suspend, |
| 185 | }; | 187 | }; |
| 186 | 188 | ||
| 189 | static struct spi_driver wm8326_spi_driver = { | ||
| 190 | .driver = { | ||
| 191 | .name = "wm8326", | ||
| 192 | .bus = &spi_bus_type, | ||
| 193 | .owner = THIS_MODULE, | ||
| 194 | }, | ||
| 195 | .probe = wm831x_spi_probe, | ||
| 196 | .remove = __devexit_p(wm831x_spi_remove), | ||
| 197 | .suspend = wm831x_spi_suspend, | ||
| 198 | }; | ||
| 199 | |||
| 187 | static int __init wm831x_spi_init(void) | 200 | static int __init wm831x_spi_init(void) |
| 188 | { | 201 | { |
| 189 | int ret; | 202 | int ret; |
| @@ -212,12 +225,17 @@ static int __init wm831x_spi_init(void) | |||
| 212 | if (ret != 0) | 225 | if (ret != 0) |
| 213 | pr_err("Failed to register WM8325 SPI driver: %d\n", ret); | 226 | pr_err("Failed to register WM8325 SPI driver: %d\n", ret); |
| 214 | 227 | ||
| 228 | ret = spi_register_driver(&wm8326_spi_driver); | ||
| 229 | if (ret != 0) | ||
| 230 | pr_err("Failed to register WM8326 SPI driver: %d\n", ret); | ||
| 231 | |||
| 215 | return 0; | 232 | return 0; |
| 216 | } | 233 | } |
| 217 | subsys_initcall(wm831x_spi_init); | 234 | subsys_initcall(wm831x_spi_init); |
| 218 | 235 | ||
| 219 | static void __exit wm831x_spi_exit(void) | 236 | static void __exit wm831x_spi_exit(void) |
| 220 | { | 237 | { |
| 238 | spi_unregister_driver(&wm8326_spi_driver); | ||
| 221 | spi_unregister_driver(&wm8325_spi_driver); | 239 | spi_unregister_driver(&wm8325_spi_driver); |
| 222 | spi_unregister_driver(&wm8321_spi_driver); | 240 | spi_unregister_driver(&wm8321_spi_driver); |
| 223 | spi_unregister_driver(&wm8320_spi_driver); | 241 | spi_unregister_driver(&wm8320_spi_driver); |
diff --git a/drivers/mfd/wm8350-irq.c b/drivers/mfd/wm8350-irq.c index f56c9adf9493..5839966ebd85 100644 --- a/drivers/mfd/wm8350-irq.c +++ b/drivers/mfd/wm8350-irq.c | |||
| @@ -417,16 +417,16 @@ static irqreturn_t wm8350_irq(int irq, void *irq_data) | |||
| 417 | return IRQ_HANDLED; | 417 | return IRQ_HANDLED; |
| 418 | } | 418 | } |
| 419 | 419 | ||
| 420 | static void wm8350_irq_lock(unsigned int irq) | 420 | static void wm8350_irq_lock(struct irq_data *data) |
| 421 | { | 421 | { |
| 422 | struct wm8350 *wm8350 = get_irq_chip_data(irq); | 422 | struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data); |
| 423 | 423 | ||
| 424 | mutex_lock(&wm8350->irq_lock); | 424 | mutex_lock(&wm8350->irq_lock); |
| 425 | } | 425 | } |
| 426 | 426 | ||
| 427 | static void wm8350_irq_sync_unlock(unsigned int irq) | 427 | static void wm8350_irq_sync_unlock(struct irq_data *data) |
| 428 | { | 428 | { |
| 429 | struct wm8350 *wm8350 = get_irq_chip_data(irq); | 429 | struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data); |
| 430 | int i; | 430 | int i; |
| 431 | 431 | ||
| 432 | for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) { | 432 | for (i = 0; i < ARRAY_SIZE(wm8350->irq_masks); i++) { |
| @@ -442,28 +442,30 @@ static void wm8350_irq_sync_unlock(unsigned int irq) | |||
| 442 | mutex_unlock(&wm8350->irq_lock); | 442 | mutex_unlock(&wm8350->irq_lock); |
| 443 | } | 443 | } |
| 444 | 444 | ||
| 445 | static void wm8350_irq_enable(unsigned int irq) | 445 | static void wm8350_irq_enable(struct irq_data *data) |
| 446 | { | 446 | { |
| 447 | struct wm8350 *wm8350 = get_irq_chip_data(irq); | 447 | struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data); |
| 448 | struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, irq); | 448 | struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, |
| 449 | data->irq); | ||
| 449 | 450 | ||
| 450 | wm8350->irq_masks[irq_data->reg] &= ~irq_data->mask; | 451 | wm8350->irq_masks[irq_data->reg] &= ~irq_data->mask; |
| 451 | } | 452 | } |
| 452 | 453 | ||
| 453 | static void wm8350_irq_disable(unsigned int irq) | 454 | static void wm8350_irq_disable(struct irq_data *data) |
| 454 | { | 455 | { |
| 455 | struct wm8350 *wm8350 = get_irq_chip_data(irq); | 456 | struct wm8350 *wm8350 = irq_data_get_irq_chip_data(data); |
| 456 | struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, irq); | 457 | struct wm8350_irq_data *irq_data = irq_to_wm8350_irq(wm8350, |
| 458 | data->irq); | ||
| 457 | 459 | ||
| 458 | wm8350->irq_masks[irq_data->reg] |= irq_data->mask; | 460 | wm8350->irq_masks[irq_data->reg] |= irq_data->mask; |
| 459 | } | 461 | } |
| 460 | 462 | ||
| 461 | static struct irq_chip wm8350_irq_chip = { | 463 | static struct irq_chip wm8350_irq_chip = { |
| 462 | .name = "wm8350", | 464 | .name = "wm8350", |
| 463 | .bus_lock = wm8350_irq_lock, | 465 | .irq_bus_lock = wm8350_irq_lock, |
| 464 | .bus_sync_unlock = wm8350_irq_sync_unlock, | 466 | .irq_bus_sync_unlock = wm8350_irq_sync_unlock, |
| 465 | .disable = wm8350_irq_disable, | 467 | .irq_disable = wm8350_irq_disable, |
| 466 | .enable = wm8350_irq_enable, | 468 | .irq_enable = wm8350_irq_enable, |
| 467 | }; | 469 | }; |
| 468 | 470 | ||
| 469 | int wm8350_irq_init(struct wm8350 *wm8350, int irq, | 471 | int wm8350_irq_init(struct wm8350 *wm8350, int irq, |
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index 8d221ba5e38d..41233c7fa581 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
| 19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
| 20 | #include <linux/mfd/core.h> | 20 | #include <linux/mfd/core.h> |
| 21 | #include <linux/pm_runtime.h> | ||
| 21 | #include <linux/regulator/consumer.h> | 22 | #include <linux/regulator/consumer.h> |
| 22 | #include <linux/regulator/machine.h> | 23 | #include <linux/regulator/machine.h> |
| 23 | 24 | ||
| @@ -169,8 +170,16 @@ out: | |||
| 169 | EXPORT_SYMBOL_GPL(wm8994_set_bits); | 170 | EXPORT_SYMBOL_GPL(wm8994_set_bits); |
| 170 | 171 | ||
| 171 | static struct mfd_cell wm8994_regulator_devs[] = { | 172 | static struct mfd_cell wm8994_regulator_devs[] = { |
| 172 | { .name = "wm8994-ldo", .id = 1 }, | 173 | { |
| 173 | { .name = "wm8994-ldo", .id = 2 }, | 174 | .name = "wm8994-ldo", |
| 175 | .id = 1, | ||
| 176 | .pm_runtime_no_callbacks = true, | ||
| 177 | }, | ||
| 178 | { | ||
| 179 | .name = "wm8994-ldo", | ||
| 180 | .id = 2, | ||
| 181 | .pm_runtime_no_callbacks = true, | ||
| 182 | }, | ||
| 174 | }; | 183 | }; |
| 175 | 184 | ||
| 176 | static struct resource wm8994_codec_resources[] = { | 185 | static struct resource wm8994_codec_resources[] = { |
| @@ -200,6 +209,7 @@ static struct mfd_cell wm8994_devs[] = { | |||
| 200 | .name = "wm8994-gpio", | 209 | .name = "wm8994-gpio", |
| 201 | .num_resources = ARRAY_SIZE(wm8994_gpio_resources), | 210 | .num_resources = ARRAY_SIZE(wm8994_gpio_resources), |
| 202 | .resources = wm8994_gpio_resources, | 211 | .resources = wm8994_gpio_resources, |
| 212 | .pm_runtime_no_callbacks = true, | ||
| 203 | }, | 213 | }, |
| 204 | }; | 214 | }; |
| 205 | 215 | ||
| @@ -231,7 +241,7 @@ static const char *wm8958_main_supplies[] = { | |||
| 231 | }; | 241 | }; |
| 232 | 242 | ||
| 233 | #ifdef CONFIG_PM | 243 | #ifdef CONFIG_PM |
| 234 | static int wm8994_device_suspend(struct device *dev) | 244 | static int wm8994_suspend(struct device *dev) |
| 235 | { | 245 | { |
| 236 | struct wm8994 *wm8994 = dev_get_drvdata(dev); | 246 | struct wm8994 *wm8994 = dev_get_drvdata(dev); |
| 237 | int ret; | 247 | int ret; |
| @@ -261,7 +271,7 @@ static int wm8994_device_suspend(struct device *dev) | |||
| 261 | return 0; | 271 | return 0; |
| 262 | } | 272 | } |
| 263 | 273 | ||
| 264 | static int wm8994_device_resume(struct device *dev) | 274 | static int wm8994_resume(struct device *dev) |
| 265 | { | 275 | { |
| 266 | struct wm8994 *wm8994 = dev_get_drvdata(dev); | 276 | struct wm8994 *wm8994 = dev_get_drvdata(dev); |
| 267 | int ret; | 277 | int ret; |
| @@ -471,6 +481,9 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) | |||
| 471 | goto err_irq; | 481 | goto err_irq; |
| 472 | } | 482 | } |
| 473 | 483 | ||
| 484 | pm_runtime_enable(wm8994->dev); | ||
| 485 | pm_runtime_resume(wm8994->dev); | ||
| 486 | |||
| 474 | return 0; | 487 | return 0; |
| 475 | 488 | ||
| 476 | err_irq: | 489 | err_irq: |
| @@ -490,6 +503,7 @@ err: | |||
| 490 | 503 | ||
| 491 | static void wm8994_device_exit(struct wm8994 *wm8994) | 504 | static void wm8994_device_exit(struct wm8994 *wm8994) |
| 492 | { | 505 | { |
| 506 | pm_runtime_disable(wm8994->dev); | ||
| 493 | mfd_remove_devices(wm8994->dev); | 507 | mfd_remove_devices(wm8994->dev); |
| 494 | wm8994_irq_exit(wm8994); | 508 | wm8994_irq_exit(wm8994); |
| 495 | regulator_bulk_disable(wm8994->num_supplies, | 509 | regulator_bulk_disable(wm8994->num_supplies, |
| @@ -573,21 +587,6 @@ static int wm8994_i2c_remove(struct i2c_client *i2c) | |||
| 573 | return 0; | 587 | return 0; |
| 574 | } | 588 | } |
| 575 | 589 | ||
| 576 | #ifdef CONFIG_PM | ||
| 577 | static int wm8994_i2c_suspend(struct i2c_client *i2c, pm_message_t state) | ||
| 578 | { | ||
| 579 | return wm8994_device_suspend(&i2c->dev); | ||
| 580 | } | ||
| 581 | |||
| 582 | static int wm8994_i2c_resume(struct i2c_client *i2c) | ||
| 583 | { | ||
| 584 | return wm8994_device_resume(&i2c->dev); | ||
| 585 | } | ||
| 586 | #else | ||
| 587 | #define wm8994_i2c_suspend NULL | ||
| 588 | #define wm8994_i2c_resume NULL | ||
| 589 | #endif | ||
| 590 | |||
| 591 | static const struct i2c_device_id wm8994_i2c_id[] = { | 590 | static const struct i2c_device_id wm8994_i2c_id[] = { |
| 592 | { "wm8994", WM8994 }, | 591 | { "wm8994", WM8994 }, |
| 593 | { "wm8958", WM8958 }, | 592 | { "wm8958", WM8958 }, |
| @@ -595,15 +594,16 @@ static const struct i2c_device_id wm8994_i2c_id[] = { | |||
| 595 | }; | 594 | }; |
| 596 | MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id); | 595 | MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id); |
| 597 | 596 | ||
| 597 | UNIVERSAL_DEV_PM_OPS(wm8994_pm_ops, wm8994_suspend, wm8994_resume, NULL); | ||
| 598 | |||
| 598 | static struct i2c_driver wm8994_i2c_driver = { | 599 | static struct i2c_driver wm8994_i2c_driver = { |
| 599 | .driver = { | 600 | .driver = { |
| 600 | .name = "wm8994", | 601 | .name = "wm8994", |
| 601 | .owner = THIS_MODULE, | 602 | .owner = THIS_MODULE, |
| 603 | .pm = &wm8994_pm_ops, | ||
| 602 | }, | 604 | }, |
| 603 | .probe = wm8994_i2c_probe, | 605 | .probe = wm8994_i2c_probe, |
| 604 | .remove = wm8994_i2c_remove, | 606 | .remove = wm8994_i2c_remove, |
| 605 | .suspend = wm8994_i2c_suspend, | ||
| 606 | .resume = wm8994_i2c_resume, | ||
| 607 | .id_table = wm8994_i2c_id, | 607 | .id_table = wm8994_i2c_id, |
| 608 | }; | 608 | }; |
| 609 | 609 | ||
diff --git a/drivers/mfd/wm8994-irq.c b/drivers/mfd/wm8994-irq.c index 8400eb1ee5db..29e8faf9c01c 100644 --- a/drivers/mfd/wm8994-irq.c +++ b/drivers/mfd/wm8994-irq.c | |||
| @@ -156,16 +156,16 @@ static inline struct wm8994_irq_data *irq_to_wm8994_irq(struct wm8994 *wm8994, | |||
| 156 | return &wm8994_irqs[irq - wm8994->irq_base]; | 156 | return &wm8994_irqs[irq - wm8994->irq_base]; |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | static void wm8994_irq_lock(unsigned int irq) | 159 | static void wm8994_irq_lock(struct irq_data *data) |
| 160 | { | 160 | { |
| 161 | struct wm8994 *wm8994 = get_irq_chip_data(irq); | 161 | struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data); |
| 162 | 162 | ||
| 163 | mutex_lock(&wm8994->irq_lock); | 163 | mutex_lock(&wm8994->irq_lock); |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | static void wm8994_irq_sync_unlock(unsigned int irq) | 166 | static void wm8994_irq_sync_unlock(struct irq_data *data) |
| 167 | { | 167 | { |
| 168 | struct wm8994 *wm8994 = get_irq_chip_data(irq); | 168 | struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data); |
| 169 | int i; | 169 | int i; |
| 170 | 170 | ||
| 171 | for (i = 0; i < ARRAY_SIZE(wm8994->irq_masks_cur); i++) { | 171 | for (i = 0; i < ARRAY_SIZE(wm8994->irq_masks_cur); i++) { |
| @@ -182,28 +182,30 @@ static void wm8994_irq_sync_unlock(unsigned int irq) | |||
| 182 | mutex_unlock(&wm8994->irq_lock); | 182 | mutex_unlock(&wm8994->irq_lock); |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | static void wm8994_irq_unmask(unsigned int irq) | 185 | static void wm8994_irq_unmask(struct irq_data *data) |
| 186 | { | 186 | { |
| 187 | struct wm8994 *wm8994 = get_irq_chip_data(irq); | 187 | struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data); |
| 188 | struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994, irq); | 188 | struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994, |
| 189 | data->irq); | ||
| 189 | 190 | ||
| 190 | wm8994->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; | 191 | wm8994->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; |
| 191 | } | 192 | } |
| 192 | 193 | ||
| 193 | static void wm8994_irq_mask(unsigned int irq) | 194 | static void wm8994_irq_mask(struct irq_data *data) |
| 194 | { | 195 | { |
| 195 | struct wm8994 *wm8994 = get_irq_chip_data(irq); | 196 | struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data); |
| 196 | struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994, irq); | 197 | struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994, |
| 198 | data->irq); | ||
| 197 | 199 | ||
| 198 | wm8994->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; | 200 | wm8994->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; |
| 199 | } | 201 | } |
| 200 | 202 | ||
| 201 | static struct irq_chip wm8994_irq_chip = { | 203 | static struct irq_chip wm8994_irq_chip = { |
| 202 | .name = "wm8994", | 204 | .name = "wm8994", |
| 203 | .bus_lock = wm8994_irq_lock, | 205 | .irq_bus_lock = wm8994_irq_lock, |
| 204 | .bus_sync_unlock = wm8994_irq_sync_unlock, | 206 | .irq_bus_sync_unlock = wm8994_irq_sync_unlock, |
| 205 | .mask = wm8994_irq_mask, | 207 | .irq_mask = wm8994_irq_mask, |
| 206 | .unmask = wm8994_irq_unmask, | 208 | .irq_unmask = wm8994_irq_unmask, |
| 207 | }; | 209 | }; |
| 208 | 210 | ||
| 209 | /* The processing of the primary interrupt occurs in a thread so that | 211 | /* The processing of the primary interrupt occurs in a thread so that |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 1e1a4be8eb6c..cc8e49db45fe 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
| @@ -64,7 +64,7 @@ config ATMEL_PWM | |||
| 64 | 64 | ||
| 65 | config AB8500_PWM | 65 | config AB8500_PWM |
| 66 | bool "AB8500 PWM support" | 66 | bool "AB8500 PWM support" |
| 67 | depends on AB8500_CORE | 67 | depends on AB8500_CORE && ARCH_U8500 |
| 68 | select HAVE_PWM | 68 | select HAVE_PWM |
| 69 | help | 69 | help |
| 70 | This driver exports functions to enable/disble/config/free Pulse | 70 | This driver exports functions to enable/disble/config/free Pulse |
diff --git a/drivers/misc/cs5535-mfgpt.c b/drivers/misc/cs5535-mfgpt.c index 6f6218061b0d..d02d302ee6d5 100644 --- a/drivers/misc/cs5535-mfgpt.c +++ b/drivers/misc/cs5535-mfgpt.c | |||
| @@ -16,12 +16,11 @@ | |||
| 16 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
| 17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
| 18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 19 | #include <linux/pci.h> | 19 | #include <linux/platform_device.h> |
| 20 | #include <linux/cs5535.h> | 20 | #include <linux/cs5535.h> |
| 21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
| 22 | 22 | ||
| 23 | #define DRV_NAME "cs5535-mfgpt" | 23 | #define DRV_NAME "cs5535-mfgpt" |
| 24 | #define MFGPT_BAR 2 | ||
| 25 | 24 | ||
| 26 | static int mfgpt_reset_timers; | 25 | static int mfgpt_reset_timers; |
| 27 | module_param_named(mfgptfix, mfgpt_reset_timers, int, 0644); | 26 | module_param_named(mfgptfix, mfgpt_reset_timers, int, 0644); |
| @@ -37,7 +36,7 @@ static struct cs5535_mfgpt_chip { | |||
| 37 | DECLARE_BITMAP(avail, MFGPT_MAX_TIMERS); | 36 | DECLARE_BITMAP(avail, MFGPT_MAX_TIMERS); |
| 38 | resource_size_t base; | 37 | resource_size_t base; |
| 39 | 38 | ||
| 40 | struct pci_dev *pdev; | 39 | struct platform_device *pdev; |
| 41 | spinlock_t lock; | 40 | spinlock_t lock; |
| 42 | int initialized; | 41 | int initialized; |
| 43 | } cs5535_mfgpt_chip; | 42 | } cs5535_mfgpt_chip; |
| @@ -290,10 +289,10 @@ static int __init scan_timers(struct cs5535_mfgpt_chip *mfgpt) | |||
| 290 | return timers; | 289 | return timers; |
| 291 | } | 290 | } |
| 292 | 291 | ||
| 293 | static int __init cs5535_mfgpt_probe(struct pci_dev *pdev, | 292 | static int __devinit cs5535_mfgpt_probe(struct platform_device *pdev) |
| 294 | const struct pci_device_id *pci_id) | ||
| 295 | { | 293 | { |
| 296 | int err, t; | 294 | struct resource *res; |
| 295 | int err = -EIO, t; | ||
| 297 | 296 | ||
| 298 | /* There are two ways to get the MFGPT base address; one is by | 297 | /* There are two ways to get the MFGPT base address; one is by |
| 299 | * fetching it from MSR_LBAR_MFGPT, the other is by reading the | 298 | * fetching it from MSR_LBAR_MFGPT, the other is by reading the |
| @@ -302,29 +301,27 @@ static int __init cs5535_mfgpt_probe(struct pci_dev *pdev, | |||
| 302 | * it turns out to be unreliable in the face of crappy BIOSes, we | 301 | * it turns out to be unreliable in the face of crappy BIOSes, we |
| 303 | * can always go back to using MSRs.. */ | 302 | * can always go back to using MSRs.. */ |
| 304 | 303 | ||
| 305 | err = pci_enable_device_io(pdev); | 304 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 306 | if (err) { | 305 | if (!res) { |
| 307 | dev_err(&pdev->dev, "can't enable device IO\n"); | 306 | dev_err(&pdev->dev, "can't fetch device resource info\n"); |
| 308 | goto done; | 307 | goto done; |
| 309 | } | 308 | } |
| 310 | 309 | ||
| 311 | err = pci_request_region(pdev, MFGPT_BAR, DRV_NAME); | 310 | if (!request_region(res->start, resource_size(res), pdev->name)) { |
| 312 | if (err) { | 311 | dev_err(&pdev->dev, "can't request region\n"); |
| 313 | dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", MFGPT_BAR); | ||
| 314 | goto done; | 312 | goto done; |
| 315 | } | 313 | } |
| 316 | 314 | ||
| 317 | /* set up the driver-specific struct */ | 315 | /* set up the driver-specific struct */ |
| 318 | cs5535_mfgpt_chip.base = pci_resource_start(pdev, MFGPT_BAR); | 316 | cs5535_mfgpt_chip.base = res->start; |
| 319 | cs5535_mfgpt_chip.pdev = pdev; | 317 | cs5535_mfgpt_chip.pdev = pdev; |
| 320 | spin_lock_init(&cs5535_mfgpt_chip.lock); | 318 | spin_lock_init(&cs5535_mfgpt_chip.lock); |
| 321 | 319 | ||
| 322 | dev_info(&pdev->dev, "allocated PCI BAR #%d: base 0x%llx\n", MFGPT_BAR, | 320 | dev_info(&pdev->dev, "reserved resource region %pR\n", res); |
| 323 | (unsigned long long) cs5535_mfgpt_chip.base); | ||
| 324 | 321 | ||
| 325 | /* detect the available timers */ | 322 | /* detect the available timers */ |
| 326 | t = scan_timers(&cs5535_mfgpt_chip); | 323 | t = scan_timers(&cs5535_mfgpt_chip); |
| 327 | dev_info(&pdev->dev, DRV_NAME ": %d MFGPT timers available\n", t); | 324 | dev_info(&pdev->dev, "%d MFGPT timers available\n", t); |
| 328 | cs5535_mfgpt_chip.initialized = 1; | 325 | cs5535_mfgpt_chip.initialized = 1; |
| 329 | return 0; | 326 | return 0; |
| 330 | 327 | ||
| @@ -332,47 +329,18 @@ done: | |||
| 332 | return err; | 329 | return err; |
| 333 | } | 330 | } |
| 334 | 331 | ||
| 335 | static struct pci_device_id cs5535_mfgpt_pci_tbl[] = { | 332 | static struct platform_driver cs5535_mfgpt_drv = { |
| 336 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, | 333 | .driver = { |
| 337 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, | 334 | .name = DRV_NAME, |
| 338 | { 0, }, | 335 | .owner = THIS_MODULE, |
| 336 | }, | ||
| 337 | .probe = cs5535_mfgpt_probe, | ||
| 339 | }; | 338 | }; |
| 340 | MODULE_DEVICE_TABLE(pci, cs5535_mfgpt_pci_tbl); | ||
| 341 | 339 | ||
| 342 | /* | ||
| 343 | * Just like with the cs5535-gpio driver, we can't use the standard PCI driver | ||
| 344 | * registration stuff. It only allows only one driver to bind to each PCI | ||
| 345 | * device, and we want the GPIO and MFGPT drivers to be able to share a PCI | ||
| 346 | * device. Instead, we manually scan for the PCI device, request a single | ||
| 347 | * region, and keep track of the devices that we're using. | ||
| 348 | */ | ||
| 349 | |||
| 350 | static int __init cs5535_mfgpt_scan_pci(void) | ||
| 351 | { | ||
| 352 | struct pci_dev *pdev; | ||
| 353 | int err = -ENODEV; | ||
| 354 | int i; | ||
| 355 | |||
| 356 | for (i = 0; i < ARRAY_SIZE(cs5535_mfgpt_pci_tbl); i++) { | ||
| 357 | pdev = pci_get_device(cs5535_mfgpt_pci_tbl[i].vendor, | ||
| 358 | cs5535_mfgpt_pci_tbl[i].device, NULL); | ||
| 359 | if (pdev) { | ||
| 360 | err = cs5535_mfgpt_probe(pdev, | ||
| 361 | &cs5535_mfgpt_pci_tbl[i]); | ||
| 362 | if (err) | ||
| 363 | pci_dev_put(pdev); | ||
| 364 | |||
| 365 | /* we only support a single CS5535/6 southbridge */ | ||
| 366 | break; | ||
| 367 | } | ||
| 368 | } | ||
| 369 | |||
| 370 | return err; | ||
| 371 | } | ||
| 372 | 340 | ||
| 373 | static int __init cs5535_mfgpt_init(void) | 341 | static int __init cs5535_mfgpt_init(void) |
| 374 | { | 342 | { |
| 375 | return cs5535_mfgpt_scan_pci(); | 343 | return platform_driver_register(&cs5535_mfgpt_drv); |
| 376 | } | 344 | } |
| 377 | 345 | ||
| 378 | module_init(cs5535_mfgpt_init); | 346 | module_init(cs5535_mfgpt_init); |
| @@ -380,3 +348,4 @@ module_init(cs5535_mfgpt_init); | |||
| 380 | MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>"); | 348 | MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>"); |
| 381 | MODULE_DESCRIPTION("CS5535/CS5536 MFGPT timer driver"); | 349 | MODULE_DESCRIPTION("CS5535/CS5536 MFGPT timer driver"); |
| 382 | MODULE_LICENSE("GPL"); | 350 | MODULE_LICENSE("GPL"); |
| 351 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c index 7568df6122ab..0ec49ca527a8 100644 --- a/drivers/regulator/max8998.c +++ b/drivers/regulator/max8998.c | |||
| @@ -424,6 +424,9 @@ static int max8998_set_voltage_buck(struct regulator_dev *rdev, | |||
| 424 | } | 424 | } |
| 425 | } | 425 | } |
| 426 | 426 | ||
| 427 | if (pdata->buck_voltage_lock) | ||
| 428 | return -EINVAL; | ||
| 429 | |||
| 427 | /* no predefine regulator found */ | 430 | /* no predefine regulator found */ |
| 428 | max8998->buck1_idx = (buck1_last_val % 2) + 2; | 431 | max8998->buck1_idx = (buck1_last_val % 2) + 2; |
| 429 | dev_dbg(max8998->dev, "max8998->buck1_idx:%d\n", | 432 | dev_dbg(max8998->dev, "max8998->buck1_idx:%d\n", |
| @@ -451,18 +454,26 @@ buck1_exit: | |||
| 451 | "BUCK2, i:%d buck2_vol1:%d, buck2_vol2:%d\n" | 454 | "BUCK2, i:%d buck2_vol1:%d, buck2_vol2:%d\n" |
| 452 | , i, max8998->buck2_vol[0], max8998->buck2_vol[1]); | 455 | , i, max8998->buck2_vol[0], max8998->buck2_vol[1]); |
| 453 | if (gpio_is_valid(pdata->buck2_set3)) { | 456 | if (gpio_is_valid(pdata->buck2_set3)) { |
| 454 | if (max8998->buck2_vol[0] == i) { | 457 | |
| 455 | max8998->buck1_idx = 0; | 458 | /* check if requested voltage */ |
| 456 | buck2_gpio_set(pdata->buck2_set3, 0); | 459 | /* value is already defined */ |
| 457 | } else { | 460 | for (j = 0; j < ARRAY_SIZE(max8998->buck2_vol); j++) { |
| 458 | max8998->buck1_idx = 1; | 461 | if (max8998->buck2_vol[j] == i) { |
| 459 | ret = max8998_get_voltage_register(rdev, ®, | 462 | max8998->buck2_idx = j; |
| 460 | &shift, | 463 | buck2_gpio_set(pdata->buck2_set3, j); |
| 461 | &mask); | 464 | goto buck2_exit; |
| 462 | ret = max8998_write_reg(i2c, reg, i); | 465 | } |
| 463 | max8998->buck2_vol[1] = i; | ||
| 464 | buck2_gpio_set(pdata->buck2_set3, 1); | ||
| 465 | } | 466 | } |
| 467 | |||
| 468 | if (pdata->buck_voltage_lock) | ||
| 469 | return -EINVAL; | ||
| 470 | |||
| 471 | max8998_get_voltage_register(rdev, | ||
| 472 | ®, &shift, &mask); | ||
| 473 | ret = max8998_write_reg(i2c, reg, i); | ||
| 474 | max8998->buck2_vol[max8998->buck2_idx] = i; | ||
| 475 | buck2_gpio_set(pdata->buck2_set3, max8998->buck2_idx); | ||
| 476 | buck2_exit: | ||
| 466 | dev_dbg(max8998->dev, "%s: SET3:%d\n", i2c->name, | 477 | dev_dbg(max8998->dev, "%s: SET3:%d\n", i2c->name, |
| 467 | gpio_get_value(pdata->buck2_set3)); | 478 | gpio_get_value(pdata->buck2_set3)); |
| 468 | } else { | 479 | } else { |
| @@ -707,6 +718,9 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) | |||
| 707 | platform_set_drvdata(pdev, max8998); | 718 | platform_set_drvdata(pdev, max8998); |
| 708 | i2c = max8998->iodev->i2c; | 719 | i2c = max8998->iodev->i2c; |
| 709 | 720 | ||
| 721 | max8998->buck1_idx = pdata->buck1_default_idx; | ||
| 722 | max8998->buck2_idx = pdata->buck2_default_idx; | ||
| 723 | |||
| 710 | /* NOTE: */ | 724 | /* NOTE: */ |
| 711 | /* For unused GPIO NOT marked as -1 (thereof equal to 0) WARN_ON */ | 725 | /* For unused GPIO NOT marked as -1 (thereof equal to 0) WARN_ON */ |
| 712 | /* will be displayed */ | 726 | /* will be displayed */ |
| @@ -739,23 +753,46 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) | |||
| 739 | i = 0; | 753 | i = 0; |
| 740 | while (buck12_voltage_map_desc.min + | 754 | while (buck12_voltage_map_desc.min + |
| 741 | buck12_voltage_map_desc.step*i | 755 | buck12_voltage_map_desc.step*i |
| 742 | != (pdata->buck1_max_voltage1 / 1000)) | 756 | < (pdata->buck1_voltage1 / 1000)) |
| 743 | i++; | 757 | i++; |
| 744 | printk(KERN_ERR "i:%d, buck1_idx:%d\n", i, max8998->buck1_idx); | ||
| 745 | max8998->buck1_vol[0] = i; | 758 | max8998->buck1_vol[0] = i; |
| 746 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1, i); | 759 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1, i); |
| 760 | if (ret) | ||
| 761 | return ret; | ||
| 747 | 762 | ||
| 748 | /* Set predefined value for BUCK1 register 2 */ | 763 | /* Set predefined value for BUCK1 register 2 */ |
| 749 | i = 0; | 764 | i = 0; |
| 750 | while (buck12_voltage_map_desc.min + | 765 | while (buck12_voltage_map_desc.min + |
| 751 | buck12_voltage_map_desc.step*i | 766 | buck12_voltage_map_desc.step*i |
| 752 | != (pdata->buck1_max_voltage2 / 1000)) | 767 | < (pdata->buck1_voltage2 / 1000)) |
| 753 | i++; | 768 | i++; |
| 754 | 769 | ||
| 755 | max8998->buck1_vol[1] = i; | 770 | max8998->buck1_vol[1] = i; |
| 756 | printk(KERN_ERR "i:%d, buck1_idx:%d\n", i, max8998->buck1_idx); | 771 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE2, i); |
| 757 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE2, i) | 772 | if (ret) |
| 758 | + ret; | 773 | return ret; |
| 774 | |||
| 775 | /* Set predefined value for BUCK1 register 3 */ | ||
| 776 | i = 0; | ||
| 777 | while (buck12_voltage_map_desc.min + | ||
| 778 | buck12_voltage_map_desc.step*i | ||
| 779 | < (pdata->buck1_voltage3 / 1000)) | ||
| 780 | i++; | ||
| 781 | |||
| 782 | max8998->buck1_vol[2] = i; | ||
| 783 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE3, i); | ||
| 784 | if (ret) | ||
| 785 | return ret; | ||
| 786 | |||
| 787 | /* Set predefined value for BUCK1 register 4 */ | ||
| 788 | i = 0; | ||
| 789 | while (buck12_voltage_map_desc.min + | ||
| 790 | buck12_voltage_map_desc.step*i | ||
| 791 | < (pdata->buck1_voltage4 / 1000)) | ||
| 792 | i++; | ||
| 793 | |||
| 794 | max8998->buck1_vol[3] = i; | ||
| 795 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE4, i); | ||
| 759 | if (ret) | 796 | if (ret) |
| 760 | return ret; | 797 | return ret; |
| 761 | 798 | ||
| @@ -772,18 +809,28 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) | |||
| 772 | gpio_direction_output(pdata->buck2_set3, | 809 | gpio_direction_output(pdata->buck2_set3, |
| 773 | max8998->buck2_idx & 0x1); | 810 | max8998->buck2_idx & 0x1); |
| 774 | 811 | ||
| 775 | /* BUCK2 - set preset default voltage value to buck2_vol[0] */ | 812 | /* BUCK2 register 1 */ |
| 776 | i = 0; | 813 | i = 0; |
| 777 | while (buck12_voltage_map_desc.min + | 814 | while (buck12_voltage_map_desc.min + |
| 778 | buck12_voltage_map_desc.step*i | 815 | buck12_voltage_map_desc.step*i |
| 779 | != (pdata->buck2_max_voltage / 1000)) | 816 | < (pdata->buck2_voltage1 / 1000)) |
| 780 | i++; | 817 | i++; |
| 781 | printk(KERN_ERR "i:%d, buck2_idx:%d\n", i, max8998->buck2_idx); | ||
| 782 | max8998->buck2_vol[0] = i; | 818 | max8998->buck2_vol[0] = i; |
| 783 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, i); | 819 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, i); |
| 784 | if (ret) | 820 | if (ret) |
| 785 | return ret; | 821 | return ret; |
| 786 | 822 | ||
| 823 | /* BUCK2 register 2 */ | ||
| 824 | i = 0; | ||
| 825 | while (buck12_voltage_map_desc.min + | ||
| 826 | buck12_voltage_map_desc.step*i | ||
| 827 | < (pdata->buck2_voltage2 / 1000)) | ||
| 828 | i++; | ||
| 829 | printk(KERN_ERR "i2:%d, buck2_idx:%d\n", i, max8998->buck2_idx); | ||
| 830 | max8998->buck2_vol[1] = i; | ||
| 831 | ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE2, i); | ||
| 832 | if (ret) | ||
| 833 | return ret; | ||
| 787 | } | 834 | } |
| 788 | 835 | ||
| 789 | for (i = 0; i < pdata->num_regulators; i++) { | 836 | for (i = 0; i < pdata->num_regulators; i++) { |
| @@ -835,6 +882,12 @@ static int __devexit max8998_pmic_remove(struct platform_device *pdev) | |||
| 835 | return 0; | 882 | return 0; |
| 836 | } | 883 | } |
| 837 | 884 | ||
| 885 | static const struct platform_device_id max8998_pmic_id[] = { | ||
| 886 | { "max8998-pmic", TYPE_MAX8998 }, | ||
| 887 | { "lp3974-pmic", TYPE_LP3974 }, | ||
| 888 | { } | ||
| 889 | }; | ||
| 890 | |||
| 838 | static struct platform_driver max8998_pmic_driver = { | 891 | static struct platform_driver max8998_pmic_driver = { |
| 839 | .driver = { | 892 | .driver = { |
| 840 | .name = "max8998-pmic", | 893 | .name = "max8998-pmic", |
| @@ -842,6 +895,7 @@ static struct platform_driver max8998_pmic_driver = { | |||
| 842 | }, | 895 | }, |
| 843 | .probe = max8998_pmic_probe, | 896 | .probe = max8998_pmic_probe, |
| 844 | .remove = __devexit_p(max8998_pmic_remove), | 897 | .remove = __devexit_p(max8998_pmic_remove), |
| 898 | .id_table = max8998_pmic_id, | ||
| 845 | }; | 899 | }; |
| 846 | 900 | ||
| 847 | static int __init max8998_pmic_init(void) | 901 | static int __init max8998_pmic_init(void) |
diff --git a/drivers/rtc/rtc-max8998.c b/drivers/rtc/rtc-max8998.c index f22dee35f330..3f7bc6b9fefa 100644 --- a/drivers/rtc/rtc-max8998.c +++ b/drivers/rtc/rtc-max8998.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
| 21 | #include <linux/mfd/max8998.h> | 21 | #include <linux/mfd/max8998.h> |
| 22 | #include <linux/mfd/max8998-private.h> | 22 | #include <linux/mfd/max8998-private.h> |
| 23 | #include <linux/delay.h> | ||
| 23 | 24 | ||
| 24 | #define MAX8998_RTC_SEC 0x00 | 25 | #define MAX8998_RTC_SEC 0x00 |
| 25 | #define MAX8998_RTC_MIN 0x01 | 26 | #define MAX8998_RTC_MIN 0x01 |
| @@ -73,6 +74,7 @@ struct max8998_rtc_info { | |||
| 73 | struct i2c_client *rtc; | 74 | struct i2c_client *rtc; |
| 74 | struct rtc_device *rtc_dev; | 75 | struct rtc_device *rtc_dev; |
| 75 | int irq; | 76 | int irq; |
| 77 | bool lp3974_bug_workaround; | ||
| 76 | }; | 78 | }; |
| 77 | 79 | ||
| 78 | static void max8998_data_to_tm(u8 *data, struct rtc_time *tm) | 80 | static void max8998_data_to_tm(u8 *data, struct rtc_time *tm) |
| @@ -124,10 +126,16 @@ static int max8998_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
| 124 | { | 126 | { |
| 125 | struct max8998_rtc_info *info = dev_get_drvdata(dev); | 127 | struct max8998_rtc_info *info = dev_get_drvdata(dev); |
| 126 | u8 data[8]; | 128 | u8 data[8]; |
| 129 | int ret; | ||
| 127 | 130 | ||
| 128 | max8998_tm_to_data(tm, data); | 131 | max8998_tm_to_data(tm, data); |
| 129 | 132 | ||
| 130 | return max8998_bulk_write(info->rtc, MAX8998_RTC_SEC, 8, data); | 133 | ret = max8998_bulk_write(info->rtc, MAX8998_RTC_SEC, 8, data); |
| 134 | |||
| 135 | if (info->lp3974_bug_workaround) | ||
| 136 | msleep(2000); | ||
| 137 | |||
| 138 | return ret; | ||
| 131 | } | 139 | } |
| 132 | 140 | ||
| 133 | static int max8998_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 141 | static int max8998_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
| @@ -163,12 +171,29 @@ static int max8998_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 163 | 171 | ||
| 164 | static int max8998_rtc_stop_alarm(struct max8998_rtc_info *info) | 172 | static int max8998_rtc_stop_alarm(struct max8998_rtc_info *info) |
| 165 | { | 173 | { |
| 166 | return max8998_write_reg(info->rtc, MAX8998_ALARM0_CONF, 0); | 174 | int ret = max8998_write_reg(info->rtc, MAX8998_ALARM0_CONF, 0); |
| 175 | |||
| 176 | if (info->lp3974_bug_workaround) | ||
| 177 | msleep(2000); | ||
| 178 | |||
| 179 | return ret; | ||
| 167 | } | 180 | } |
| 168 | 181 | ||
| 169 | static int max8998_rtc_start_alarm(struct max8998_rtc_info *info) | 182 | static int max8998_rtc_start_alarm(struct max8998_rtc_info *info) |
| 170 | { | 183 | { |
| 171 | return max8998_write_reg(info->rtc, MAX8998_ALARM0_CONF, 0x77); | 184 | int ret; |
| 185 | u8 alarm0_conf = 0x77; | ||
| 186 | |||
| 187 | /* LP3974 with delay bug chips has rtc alarm bugs with "MONTH" field */ | ||
| 188 | if (info->lp3974_bug_workaround) | ||
| 189 | alarm0_conf = 0x57; | ||
| 190 | |||
| 191 | ret = max8998_write_reg(info->rtc, MAX8998_ALARM0_CONF, alarm0_conf); | ||
| 192 | |||
| 193 | if (info->lp3974_bug_workaround) | ||
| 194 | msleep(2000); | ||
| 195 | |||
| 196 | return ret; | ||
| 172 | } | 197 | } |
| 173 | 198 | ||
| 174 | static int max8998_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 199 | static int max8998_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
| @@ -187,10 +212,13 @@ static int max8998_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
| 187 | if (ret < 0) | 212 | if (ret < 0) |
| 188 | return ret; | 213 | return ret; |
| 189 | 214 | ||
| 215 | if (info->lp3974_bug_workaround) | ||
| 216 | msleep(2000); | ||
| 217 | |||
| 190 | if (alrm->enabled) | 218 | if (alrm->enabled) |
| 191 | return max8998_rtc_start_alarm(info); | 219 | ret = max8998_rtc_start_alarm(info); |
| 192 | 220 | ||
| 193 | return 0; | 221 | return ret; |
| 194 | } | 222 | } |
| 195 | 223 | ||
| 196 | static int max8998_rtc_alarm_irq_enable(struct device *dev, | 224 | static int max8998_rtc_alarm_irq_enable(struct device *dev, |
| @@ -224,6 +252,7 @@ static const struct rtc_class_ops max8998_rtc_ops = { | |||
| 224 | static int __devinit max8998_rtc_probe(struct platform_device *pdev) | 252 | static int __devinit max8998_rtc_probe(struct platform_device *pdev) |
| 225 | { | 253 | { |
| 226 | struct max8998_dev *max8998 = dev_get_drvdata(pdev->dev.parent); | 254 | struct max8998_dev *max8998 = dev_get_drvdata(pdev->dev.parent); |
| 255 | struct max8998_platform_data *pdata = dev_get_platdata(max8998->dev); | ||
| 227 | struct max8998_rtc_info *info; | 256 | struct max8998_rtc_info *info; |
| 228 | int ret; | 257 | int ret; |
| 229 | 258 | ||
| @@ -249,10 +278,18 @@ static int __devinit max8998_rtc_probe(struct platform_device *pdev) | |||
| 249 | 278 | ||
| 250 | ret = request_threaded_irq(info->irq, NULL, max8998_rtc_alarm_irq, 0, | 279 | ret = request_threaded_irq(info->irq, NULL, max8998_rtc_alarm_irq, 0, |
| 251 | "rtc-alarm0", info); | 280 | "rtc-alarm0", info); |
| 281 | |||
| 252 | if (ret < 0) | 282 | if (ret < 0) |
| 253 | dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", | 283 | dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", |
| 254 | info->irq, ret); | 284 | info->irq, ret); |
| 255 | 285 | ||
| 286 | dev_info(&pdev->dev, "RTC CHIP NAME: %s\n", pdev->id_entry->name); | ||
| 287 | if (pdata->rtc_delay) { | ||
| 288 | info->lp3974_bug_workaround = true; | ||
| 289 | dev_warn(&pdev->dev, "LP3974 with RTC REGERR option." | ||
| 290 | " RTC updates will be extremely slow.\n"); | ||
| 291 | } | ||
| 292 | |||
| 256 | return 0; | 293 | return 0; |
| 257 | 294 | ||
| 258 | out_rtc: | 295 | out_rtc: |
| @@ -273,6 +310,12 @@ static int __devexit max8998_rtc_remove(struct platform_device *pdev) | |||
| 273 | return 0; | 310 | return 0; |
| 274 | } | 311 | } |
| 275 | 312 | ||
| 313 | static const struct platform_device_id max8998_rtc_id[] = { | ||
| 314 | { "max8998-rtc", TYPE_MAX8998 }, | ||
| 315 | { "lp3974-rtc", TYPE_LP3974 }, | ||
| 316 | { } | ||
| 317 | }; | ||
| 318 | |||
| 276 | static struct platform_driver max8998_rtc_driver = { | 319 | static struct platform_driver max8998_rtc_driver = { |
| 277 | .driver = { | 320 | .driver = { |
| 278 | .name = "max8998-rtc", | 321 | .name = "max8998-rtc", |
| @@ -280,6 +323,7 @@ static struct platform_driver max8998_rtc_driver = { | |||
| 280 | }, | 323 | }, |
| 281 | .probe = max8998_rtc_probe, | 324 | .probe = max8998_rtc_probe, |
| 282 | .remove = __devexit_p(max8998_rtc_remove), | 325 | .remove = __devexit_p(max8998_rtc_remove), |
| 326 | .id_table = max8998_rtc_id, | ||
| 283 | }; | 327 | }; |
| 284 | 328 | ||
| 285 | static int __init max8998_rtc_init(void) | 329 | static int __init max8998_rtc_init(void) |
diff --git a/include/linux/mfd/ab8500.h b/include/linux/mfd/ab8500.h index 85cf2c28fac6..37f56b7c4c15 100644 --- a/include/linux/mfd/ab8500.h +++ b/include/linux/mfd/ab8500.h | |||
| @@ -74,30 +74,37 @@ | |||
| 74 | #define AB8500_INT_ACC_DETECT_21DB_F 37 | 74 | #define AB8500_INT_ACC_DETECT_21DB_F 37 |
| 75 | #define AB8500_INT_ACC_DETECT_21DB_R 38 | 75 | #define AB8500_INT_ACC_DETECT_21DB_R 38 |
| 76 | #define AB8500_INT_GP_SW_ADC_CONV_END 39 | 76 | #define AB8500_INT_GP_SW_ADC_CONV_END 39 |
| 77 | #define AB8500_INT_BTEMP_LOW 72 | 77 | #define AB8500_INT_ADP_SOURCE_ERROR 72 |
| 78 | #define AB8500_INT_BTEMP_LOW_MEDIUM 73 | 78 | #define AB8500_INT_ADP_SINK_ERROR 73 |
| 79 | #define AB8500_INT_BTEMP_MEDIUM_HIGH 74 | 79 | #define AB8500_INT_ADP_PROBE_PLUG 74 |
| 80 | #define AB8500_INT_BTEMP_HIGH 75 | 80 | #define AB8500_INT_ADP_PROBE_UNPLUG 75 |
| 81 | #define AB8500_INT_USB_CHARGER_NOT_OK 81 | 81 | #define AB8500_INT_ADP_SENSE_OFF 76 |
| 82 | #define AB8500_INT_ID_WAKEUP_R 82 | 82 | #define AB8500_INT_USB_PHY_POWER_ERR 78 |
| 83 | #define AB8500_INT_ID_DET_R1R 84 | 83 | #define AB8500_INT_USB_LINK_STATUS 79 |
| 84 | #define AB8500_INT_ID_DET_R2R 85 | 84 | #define AB8500_INT_BTEMP_LOW 80 |
| 85 | #define AB8500_INT_ID_DET_R3R 86 | 85 | #define AB8500_INT_BTEMP_LOW_MEDIUM 81 |
| 86 | #define AB8500_INT_ID_DET_R4R 87 | 86 | #define AB8500_INT_BTEMP_MEDIUM_HIGH 82 |
| 87 | #define AB8500_INT_ID_WAKEUP_F 88 | 87 | #define AB8500_INT_BTEMP_HIGH 83 |
| 88 | #define AB8500_INT_ID_DET_R1F 90 | 88 | #define AB8500_INT_USB_CHARGER_NOT_OK 89 |
| 89 | #define AB8500_INT_ID_DET_R2F 91 | 89 | #define AB8500_INT_ID_WAKEUP_R 90 |
| 90 | #define AB8500_INT_ID_DET_R3F 92 | 90 | #define AB8500_INT_ID_DET_R1R 92 |
| 91 | #define AB8500_INT_ID_DET_R4F 93 | 91 | #define AB8500_INT_ID_DET_R2R 93 |
| 92 | #define AB8500_INT_USB_CHG_DET_DONE 94 | 92 | #define AB8500_INT_ID_DET_R3R 94 |
| 93 | #define AB8500_INT_USB_CH_TH_PROT_F 96 | 93 | #define AB8500_INT_ID_DET_R4R 95 |
| 94 | #define AB8500_INT_USB_CH_TH_PROP_R 97 | 94 | #define AB8500_INT_ID_WAKEUP_F 96 |
| 95 | #define AB8500_INT_MAIN_CH_TH_PROP_F 98 | 95 | #define AB8500_INT_ID_DET_R1F 98 |
| 96 | #define AB8500_INT_MAIN_CH_TH_PROT_R 99 | 96 | #define AB8500_INT_ID_DET_R2F 99 |
| 97 | #define AB8500_INT_USB_CHARGER_NOT_OKF 103 | 97 | #define AB8500_INT_ID_DET_R3F 100 |
| 98 | #define AB8500_INT_ID_DET_R4F 101 | ||
| 99 | #define AB8500_INT_USB_CHG_DET_DONE 102 | ||
| 100 | #define AB8500_INT_USB_CH_TH_PROT_F 104 | ||
| 101 | #define AB8500_INT_USB_CH_TH_PROT_R 105 | ||
| 102 | #define AB8500_INT_MAIN_CH_TH_PROT_F 106 | ||
| 103 | #define AB8500_INT_MAIN_CH_TH_PROT_R 107 | ||
| 104 | #define AB8500_INT_USB_CHARGER_NOT_OKF 111 | ||
| 98 | 105 | ||
| 99 | #define AB8500_NR_IRQS 104 | 106 | #define AB8500_NR_IRQS 112 |
| 100 | #define AB8500_NUM_IRQ_REGS 13 | 107 | #define AB8500_NUM_IRQ_REGS 14 |
| 101 | 108 | ||
| 102 | /** | 109 | /** |
| 103 | * struct ab8500 - ab8500 internal structure | 110 | * struct ab8500 - ab8500 internal structure |
diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h index 5582ab3d3e48..835996e167e1 100644 --- a/include/linux/mfd/core.h +++ b/include/linux/mfd/core.h | |||
| @@ -47,6 +47,12 @@ struct mfd_cell { | |||
| 47 | 47 | ||
| 48 | /* don't check for resource conflicts */ | 48 | /* don't check for resource conflicts */ |
| 49 | bool ignore_resource_conflicts; | 49 | bool ignore_resource_conflicts; |
| 50 | |||
| 51 | /* | ||
| 52 | * Disable runtime PM callbacks for this subdevice - see | ||
| 53 | * pm_runtime_no_callbacks(). | ||
| 54 | */ | ||
| 55 | bool pm_runtime_no_callbacks; | ||
| 50 | }; | 56 | }; |
| 51 | 57 | ||
| 52 | extern int mfd_add_devices(struct device *parent, int id, | 58 | extern int mfd_add_devices(struct device *parent, int id, |
diff --git a/include/linux/mfd/max8998-private.h b/include/linux/mfd/max8998-private.h index 7363dea6bbcd..effa5d3b96ae 100644 --- a/include/linux/mfd/max8998-private.h +++ b/include/linux/mfd/max8998-private.h | |||
| @@ -159,10 +159,12 @@ struct max8998_dev { | |||
| 159 | u8 irq_masks_cur[MAX8998_NUM_IRQ_REGS]; | 159 | u8 irq_masks_cur[MAX8998_NUM_IRQ_REGS]; |
| 160 | u8 irq_masks_cache[MAX8998_NUM_IRQ_REGS]; | 160 | u8 irq_masks_cache[MAX8998_NUM_IRQ_REGS]; |
| 161 | int type; | 161 | int type; |
| 162 | bool wakeup; | ||
| 162 | }; | 163 | }; |
| 163 | 164 | ||
| 164 | int max8998_irq_init(struct max8998_dev *max8998); | 165 | int max8998_irq_init(struct max8998_dev *max8998); |
| 165 | void max8998_irq_exit(struct max8998_dev *max8998); | 166 | void max8998_irq_exit(struct max8998_dev *max8998); |
| 167 | int max8998_irq_resume(struct max8998_dev *max8998); | ||
| 166 | 168 | ||
| 167 | extern int max8998_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest); | 169 | extern int max8998_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest); |
| 168 | extern int max8998_bulk_read(struct i2c_client *i2c, u8 reg, int count, | 170 | extern int max8998_bulk_read(struct i2c_client *i2c, u8 reg, int count, |
diff --git a/include/linux/mfd/max8998.h b/include/linux/mfd/max8998.h index f8c9f884aff2..61daa167b576 100644 --- a/include/linux/mfd/max8998.h +++ b/include/linux/mfd/max8998.h | |||
| @@ -70,24 +70,43 @@ struct max8998_regulator_data { | |||
| 70 | * @num_regulators: number of regultors used | 70 | * @num_regulators: number of regultors used |
| 71 | * @irq_base: base IRQ number for max8998, required for IRQs | 71 | * @irq_base: base IRQ number for max8998, required for IRQs |
| 72 | * @ono: power onoff IRQ number for max8998 | 72 | * @ono: power onoff IRQ number for max8998 |
| 73 | * @buck1_max_voltage1: BUCK1 maximum alowed voltage register 1 | 73 | * @buck_voltage_lock: Do NOT change the values of the following six |
| 74 | * @buck1_max_voltage2: BUCK1 maximum alowed voltage register 2 | 74 | * registers set by buck?_voltage?. The voltage of BUCK1/2 cannot |
| 75 | * @buck2_max_voltage: BUCK2 maximum alowed voltage | 75 | * be other than the preset values. |
| 76 | * @buck1_voltage1: BUCK1 DVS mode 1 voltage register | ||
| 77 | * @buck1_voltage2: BUCK1 DVS mode 2 voltage register | ||
| 78 | * @buck1_voltage3: BUCK1 DVS mode 3 voltage register | ||
| 79 | * @buck1_voltage4: BUCK1 DVS mode 4 voltage register | ||
| 80 | * @buck2_voltage1: BUCK2 DVS mode 1 voltage register | ||
| 81 | * @buck2_voltage2: BUCK2 DVS mode 2 voltage register | ||
| 76 | * @buck1_set1: BUCK1 gpio pin 1 to set output voltage | 82 | * @buck1_set1: BUCK1 gpio pin 1 to set output voltage |
| 77 | * @buck1_set2: BUCK1 gpio pin 2 to set output voltage | 83 | * @buck1_set2: BUCK1 gpio pin 2 to set output voltage |
| 84 | * @buck1_default_idx: Default for BUCK1 gpio pin 1, 2 | ||
| 78 | * @buck2_set3: BUCK2 gpio pin to set output voltage | 85 | * @buck2_set3: BUCK2 gpio pin to set output voltage |
| 86 | * @buck2_default_idx: Default for BUCK2 gpio pin. | ||
| 87 | * @wakeup: Allow to wake up from suspend | ||
| 88 | * @rtc_delay: LP3974 RTC chip bug that requires delay after a register | ||
| 89 | * write before reading it. | ||
| 79 | */ | 90 | */ |
| 80 | struct max8998_platform_data { | 91 | struct max8998_platform_data { |
| 81 | struct max8998_regulator_data *regulators; | 92 | struct max8998_regulator_data *regulators; |
| 82 | int num_regulators; | 93 | int num_regulators; |
| 83 | int irq_base; | 94 | int irq_base; |
| 84 | int ono; | 95 | int ono; |
| 85 | int buck1_max_voltage1; | 96 | bool buck_voltage_lock; |
| 86 | int buck1_max_voltage2; | 97 | int buck1_voltage1; |
| 87 | int buck2_max_voltage; | 98 | int buck1_voltage2; |
| 99 | int buck1_voltage3; | ||
| 100 | int buck1_voltage4; | ||
| 101 | int buck2_voltage1; | ||
| 102 | int buck2_voltage2; | ||
| 88 | int buck1_set1; | 103 | int buck1_set1; |
| 89 | int buck1_set2; | 104 | int buck1_set2; |
| 105 | int buck1_default_idx; | ||
| 90 | int buck2_set3; | 106 | int buck2_set3; |
| 107 | int buck2_default_idx; | ||
| 108 | bool wakeup; | ||
| 109 | bool rtc_delay; | ||
| 91 | }; | 110 | }; |
| 92 | 111 | ||
| 93 | #endif /* __LINUX_MFD_MAX8998_H */ | 112 | #endif /* __LINUX_MFD_MAX8998_H */ |
diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h index a1239c48b41a..903280d21866 100644 --- a/include/linux/mfd/wm831x/core.h +++ b/include/linux/mfd/wm831x/core.h | |||
| @@ -245,6 +245,7 @@ enum wm831x_parent { | |||
| 245 | WM8320 = 0x8320, | 245 | WM8320 = 0x8320, |
| 246 | WM8321 = 0x8321, | 246 | WM8321 = 0x8321, |
| 247 | WM8325 = 0x8325, | 247 | WM8325 = 0x8325, |
| 248 | WM8326 = 0x8326, | ||
| 248 | }; | 249 | }; |
| 249 | 250 | ||
| 250 | struct wm831x { | 251 | struct wm831x { |
