]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 28 Mar 2011 03:07:01 +0000 (20:07 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 28 Mar 2011 03:07:01 +0000 (20:07 -0700)
* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6:
  mfd: Clean up max8997 IRQ namespace
  mfd: Fold irq_set_chip/irq_set_handler
  mfd: Cleanup irq namespace
  mfd: twl6030: Cleanup interrupt handling
  mfd: twl4030: Cleanup interrupt handling
  mfd: mx8925: Remove irq_desc leftovers
  mfd: htc-i2cpld: Cleanup interrupt handling
  mfd: htc-egpio: Cleanup interrupt handling
  mfd: ezx-pcap: Remvove open coded irq handling
  mfd: 88pm860x: Remove unused irq_desc leftovers
  mfd: asic3: Cleanup irq handling
  mfd: Select MFD_CORE if TPS6105X driver is configured
  mfd: Add MODULE_DEVICE_TABLE to rdc321x-southbridge
  mfd: Add MAX8997/8966 IRQ control
  mfd: Constify i2c_device_id tables
  mfd: OLPC: Clean up names to match what OLPC actually uses
  mfd: Add mfd_clone_cell(), convert cs5535-mfd/olpc-xo1 to it

33 files changed:
arch/x86/platform/olpc/olpc-xo1.c
drivers/mfd/88pm860x-core.c
drivers/mfd/Kconfig
drivers/mfd/Makefile
drivers/mfd/ab3550-core.c
drivers/mfd/ab8500-core.c
drivers/mfd/asic3.c
drivers/mfd/cs5535-mfd.c
drivers/mfd/ezx-pcap.c
drivers/mfd/htc-egpio.c
drivers/mfd/htc-i2cpld.c
drivers/mfd/jz4740-adc.c
drivers/mfd/max8925-core.c
drivers/mfd/max8997-irq.c [new file with mode: 0644]
drivers/mfd/max8998-irq.c
drivers/mfd/max8998.c
drivers/mfd/mfd-core.c
drivers/mfd/pcf50633-core.c
drivers/mfd/rdc321x-southbridge.c
drivers/mfd/stmpe.c
drivers/mfd/t7l66xb.c
drivers/mfd/tc3589x.c
drivers/mfd/tc6393xb.c
drivers/mfd/tps6586x.c
drivers/mfd/twl4030-irq.c
drivers/mfd/twl6030-irq.c
drivers/mfd/wl1273-core.c
drivers/mfd/wm831x-irq.c
drivers/mfd/wm8350-irq.c
drivers/mfd/wm8994-irq.c
include/linux/mfd/core.h
include/linux/mfd/max8997-private.h
include/linux/mfd/max8997.h

index 99513642a0e6b324bc7b148fd7160222d043c87e..ab81fb271760ff8f666512944b3a54dec155963d 100644 (file)
@@ -72,9 +72,9 @@ static int __devinit olpc_xo1_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "can't fetch device resource info\n");
                return -EIO;
        }
-       if (strcmp(pdev->name, "olpc-xo1-pms") == 0)
+       if (strcmp(pdev->name, "cs5535-pms") == 0)
                pms_base = res->start;
-       else if (strcmp(pdev->name, "olpc-xo1-ac-acpi") == 0)
+       else if (strcmp(pdev->name, "olpc-xo1-pm-acpi") == 0)
                acpi_base = res->start;
 
        /* If we have both addresses, we can override the poweroff hook */
@@ -90,9 +90,9 @@ static int __devexit olpc_xo1_remove(struct platform_device *pdev)
 {
        mfd_cell_disable(pdev);
 
-       if (strcmp(pdev->name, "olpc-xo1-pms") == 0)
+       if (strcmp(pdev->name, "cs5535-pms") == 0)
                pms_base = 0;
-       else if (strcmp(pdev->name, "olpc-xo1-acpi") == 0)
+       else if (strcmp(pdev->name, "olpc-xo1-pm-acpi") == 0)
                acpi_base = 0;
 
        pm_power_off = NULL;
@@ -101,7 +101,7 @@ static int __devexit olpc_xo1_remove(struct platform_device *pdev)
 
 static struct platform_driver cs5535_pms_drv = {
        .driver = {
-               .name = "olpc-xo1-pms",
+               .name = "cs5535-pms",
                .owner = THIS_MODULE,
        },
        .probe = olpc_xo1_probe,
@@ -110,7 +110,7 @@ static struct platform_driver cs5535_pms_drv = {
 
 static struct platform_driver cs5535_acpi_drv = {
        .driver = {
-               .name = "olpc-xo1-acpi",
+               .name = "olpc-xo1-pm-acpi",
                .owner = THIS_MODULE,
        },
        .probe = olpc_xo1_probe,
@@ -121,22 +121,21 @@ static int __init olpc_xo1_init(void)
 {
        int r;
 
-       r = mfd_shared_platform_driver_register(&cs5535_pms_drv, "cs5535-pms");
+       r = platform_driver_register(&cs5535_pms_drv);
        if (r)
                return r;
 
-       r = mfd_shared_platform_driver_register(&cs5535_acpi_drv,
-                       "cs5535-acpi");
+       r = platform_driver_register(&cs5535_acpi_drv);
        if (r)
-               mfd_shared_platform_driver_unregister(&cs5535_pms_drv);
+               platform_driver_unregister(&cs5535_pms_drv);
 
        return r;
 }
 
 static void __exit olpc_xo1_exit(void)
 {
-       mfd_shared_platform_driver_unregister(&cs5535_acpi_drv);
-       mfd_shared_platform_driver_unregister(&cs5535_pms_drv);
+       platform_driver_unregister(&cs5535_acpi_drv);
+       platform_driver_unregister(&cs5535_pms_drv);
 }
 
 MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>");
index 9c511c1604a5f09c4051172eca8c2b95bbf691df..011cb6ce861bcd8f4d820f6b1e77bff51ec9cd99 100644 (file)
@@ -416,7 +416,6 @@ static int __devinit device_irq_init(struct pm860x_chip *chip,
                                : chip->companion;
        unsigned char status_buf[INT_STATUS_NUM];
        unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
-       struct irq_desc *desc;
        int i, data, mask, ret = -EINVAL;
        int __irq;
 
@@ -468,19 +467,17 @@ static int __devinit device_irq_init(struct pm860x_chip *chip,
        if (!chip->core_irq)
                goto out;
 
-       desc = irq_to_desc(chip->core_irq);
-
        /* register IRQ by genirq */
        for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) {
                __irq = i + chip->irq_base;
-               set_irq_chip_data(__irq, chip);
-               set_irq_chip_and_handler(__irq, &pm860x_irq_chip,
+               irq_set_chip_data(__irq, chip);
+               irq_set_chip_and_handler(__irq, &pm860x_irq_chip,
                                         handle_edge_irq);
-               set_irq_nested_thread(__irq, 1);
+               irq_set_nested_thread(__irq, 1);
 #ifdef CONFIG_ARM
                set_irq_flags(__irq, IRQF_VALID);
 #else
-               set_irq_noprobe(__irq);
+               irq_set_noprobe(__irq);
 #endif
        }
 
index a9a1af49281eea983265c3084c6a1f8bed1585a9..e986f91fff9c43b323a2cac525f1a982ccbf0728 100644 (file)
@@ -133,6 +133,7 @@ config TPS6105X
        tristate "TPS61050/61052 Boost Converters"
        depends on I2C
        select REGULATOR
+       select MFD_CORE
        select REGULATOR_FIXED_VOLTAGE
        help
          This option enables a driver for the TP61050/TPS61052
index 47f5709f3828c48d1b85e894e241341291dccf6f..ef489f253402c8b5e3feff76258486d047d162c5 100644 (file)
@@ -63,7 +63,7 @@ obj-$(CONFIG_UCB1400_CORE)    += ucb1400_core.o
 obj-$(CONFIG_PMIC_DA903X)      += da903x.o
 max8925-objs                   := max8925-core.o max8925-i2c.o
 obj-$(CONFIG_MFD_MAX8925)      += max8925.o
-obj-$(CONFIG_MFD_MAX8997)      += max8997.o
+obj-$(CONFIG_MFD_MAX8997)      += max8997.o max8997-irq.o
 obj-$(CONFIG_MFD_MAX8998)      += max8998.o max8998-irq.o
 
 pcf50633-objs                  := pcf50633-core.o pcf50633-irq.o
index c12d042852269a6ebaeff0e132d316ef2b0a6d0e..ff86acf3e6bde2b16f6e95f2f8c6af90e92bcd64 100644 (file)
@@ -668,7 +668,7 @@ static int ab3550_startup_irq_enabled(struct device *dev, unsigned int irq)
        struct ab3550_platform_data *plf_data;
        bool val;
 
-       ab = get_irq_chip_data(irq);
+       ab = irq_get_chip_data(irq);
        plf_data = ab->i2c_client[0]->dev.platform_data;
        irq -= plf_data->irq.base;
        val = ((ab->startup_events[irq / 8] & BIT(irq % 8)) != 0);
@@ -1296,14 +1296,14 @@ static int __init ab3550_probe(struct i2c_client *client,
                unsigned int irq;
 
                irq = ab3550_plf_data->irq.base + i;
-               set_irq_chip_data(irq, ab);
-               set_irq_chip_and_handler(irq, &ab3550_irq_chip,
-                       handle_simple_irq);
-               set_irq_nested_thread(irq, 1);
+               irq_set_chip_data(irq, ab);
+               irq_set_chip_and_handler(irq, &ab3550_irq_chip,
+                                        handle_simple_irq);
+               irq_set_nested_thread(irq, 1);
 #ifdef CONFIG_ARM
                set_irq_flags(irq, IRQF_VALID);
 #else
-               set_irq_noprobe(irq);
+               irq_set_noprobe(irq);
 #endif
        }
 
index 6e185b272d00890a20a2fff6b6e2f846b00cc753..62e33e2258d492998aec419bb747fd283fd398c3 100644 (file)
@@ -334,14 +334,14 @@ static int ab8500_irq_init(struct ab8500 *ab8500)
        int irq;
 
        for (irq = base; irq < base + AB8500_NR_IRQS; irq++) {
-               set_irq_chip_data(irq, ab8500);
-               set_irq_chip_and_handler(irq, &ab8500_irq_chip,
+               irq_set_chip_data(irq, ab8500);
+               irq_set_chip_and_handler(irq, &ab8500_irq_chip,
                                         handle_simple_irq);
-               set_irq_nested_thread(irq, 1);
+               irq_set_nested_thread(irq, 1);
 #ifdef CONFIG_ARM
                set_irq_flags(irq, IRQF_VALID);
 #else
-               set_irq_noprobe(irq);
+               irq_set_noprobe(irq);
 #endif
        }
 
@@ -357,8 +357,8 @@ static void ab8500_irq_remove(struct ab8500 *ab8500)
 #ifdef CONFIG_ARM
                set_irq_flags(irq, 0);
 #endif
-               set_irq_chip_and_handler(irq, NULL, NULL);
-               set_irq_chip_data(irq, NULL);
+               irq_set_chip_and_handler(irq, NULL, NULL);
+               irq_set_chip_data(irq, NULL);
        }
 }
 
index 0241f08fc00d63cfde562a96c7d7a43818bbf9e0..d4a851c6b5bf17f4da0b8326275a82c458c97983 100644 (file)
@@ -139,13 +139,12 @@ static void asic3_irq_flip_edge(struct asic3 *asic,
 
 static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc)
 {
+       struct asic3 *asic = irq_desc_get_handler_data(desc);
+       struct irq_data *data = irq_desc_get_irq_data(desc);
        int iter, i;
        unsigned long flags;
-       struct asic3 *asic;
-
-       desc->irq_data.chip->irq_ack(&desc->irq_data);
 
-       asic = get_irq_data(irq);
+       data->chip->irq_ack(irq_data);
 
        for (iter = 0 ; iter < MAX_ASIC_ISR_LOOPS; iter++) {
                u32 status;
@@ -188,8 +187,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc)
                                        irqnr = asic->irq_base +
                                                (ASIC3_GPIOS_PER_BANK * bank)
                                                + i;
-                                       desc = irq_to_desc(irqnr);
-                                       desc->handle_irq(irqnr, desc);
+                                       generic_handle_irq(irqnr);
                                        if (asic->irq_bothedge[bank] & bit)
                                                asic3_irq_flip_edge(asic, base,
                                                                    bit);
@@ -200,11 +198,8 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc)
                /* Handle remaining IRQs in the status register */
                for (i = ASIC3_NUM_GPIOS; i < ASIC3_NR_IRQS; i++) {
                        /* They start at bit 4 and go up */
-                       if (status & (1 << (i - ASIC3_NUM_GPIOS + 4))) {
-                               desc = irq_to_desc(asic->irq_base + i);
-                               desc->handle_irq(asic->irq_base + i,
-                                                desc);
-                       }
+                       if (status & (1 << (i - ASIC3_NUM_GPIOS + 4)))
+                               generic_handle_irq(asic->irq_base + i);
                }
        }
 
@@ -393,21 +388,21 @@ static int __init asic3_irq_probe(struct platform_device *pdev)
 
        for (irq = irq_base; irq < irq_base + ASIC3_NR_IRQS; irq++) {
                if (irq < asic->irq_base + ASIC3_NUM_GPIOS)
-                       set_irq_chip(irq, &asic3_gpio_irq_chip);
+                       irq_set_chip(irq, &asic3_gpio_irq_chip);
                else
-                       set_irq_chip(irq, &asic3_irq_chip);
+                       irq_set_chip(irq, &asic3_irq_chip);
 
-               set_irq_chip_data(irq, asic);
-               set_irq_handler(irq, handle_level_irq);
+               irq_set_chip_data(irq, asic);
+               irq_set_handler(irq, handle_level_irq);
                set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
        }
 
        asic3_write_register(asic, ASIC3_OFFSET(INTR, INT_MASK),
                             ASIC3_INTMASK_GINTMASK);
 
-       set_irq_chained_handler(asic->irq_nr, asic3_irq_demux);
-       set_irq_type(asic->irq_nr, IRQ_TYPE_EDGE_RISING);
-       set_irq_data(asic->irq_nr, asic);
+       irq_set_chained_handler(asic->irq_nr, asic3_irq_demux);
+       irq_set_irq_type(asic->irq_nr, IRQ_TYPE_EDGE_RISING);
+       irq_set_handler_data(asic->irq_nr, asic);
 
        return 0;
 }
@@ -421,11 +416,10 @@ static void asic3_irq_remove(struct platform_device *pdev)
 
        for (irq = irq_base; irq < irq_base + ASIC3_NR_IRQS; irq++) {
                set_irq_flags(irq, 0);
-               set_irq_handler(irq, NULL);
-               set_irq_chip(irq, NULL);
-               set_irq_chip_data(irq, NULL);
+               irq_set_chip_and_handler(irq, NULL, NULL);
+               irq_set_chip_data(irq, NULL);
        }
-       set_irq_chained_handler(asic->irq_nr, NULL);
+       irq_set_chained_handler(asic->irq_nr, NULL);
 }
 
 /* GPIOs */
index 886a068710652613e195b54ed433c86f6c664bef..155fa04078821d6fc8d5a5475225bba3a436ba06 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/mfd/core.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <asm/olpc.h>
 
 #define DRV_NAME "cs5535-mfd"
 
@@ -111,6 +112,20 @@ static __devinitdata struct mfd_cell cs5535_mfd_cells[] = {
        },
 };
 
+#ifdef CONFIG_OLPC
+static void __devinit cs5535_clone_olpc_cells(void)
+{
+       const char *acpi_clones[] = { "olpc-xo1-pm-acpi", "olpc-xo1-sci-acpi" };
+
+       if (!machine_is_olpc())
+               return;
+
+       mfd_clone_cell("cs5535-acpi", acpi_clones, ARRAY_SIZE(acpi_clones));
+}
+#else
+static void cs5535_clone_olpc_cells(void) { }
+#endif
+
 static int __devinit cs5535_mfd_probe(struct pci_dev *pdev,
                const struct pci_device_id *id)
 {
@@ -139,6 +154,7 @@ static int __devinit cs5535_mfd_probe(struct pci_dev *pdev,
                dev_err(&pdev->dev, "MFD add devices failed: %d\n", err);
                goto err_disable;
        }
+       cs5535_clone_olpc_cells();
 
        dev_info(&pdev->dev, "%zu devices registered.\n",
                        ARRAY_SIZE(cs5535_mfd_cells));
index 9e2d8dd5f9e53d1d57d0ebbbee5bfedb992068e1..f2f4029e21a081b5c511d768df594f7d6c89bc67 100644 (file)
@@ -162,6 +162,7 @@ static void pcap_unmask_irq(struct irq_data *d)
 
 static struct irq_chip pcap_irq_chip = {
        .name           = "pcap",
+       .irq_disable    = pcap_mask_irq,
        .irq_mask       = pcap_mask_irq,
        .irq_unmask     = pcap_unmask_irq,
 };
@@ -196,17 +197,8 @@ static void pcap_isr_work(struct work_struct *work)
                local_irq_disable();
                service = isr & ~msr;
                for (irq = pcap->irq_base; service; service >>= 1, irq++) {
-                       if (service & 1) {
-                               struct irq_desc *desc = irq_to_desc(irq);
-
-                               if (WARN(!desc, "Invalid PCAP IRQ %d\n", irq))
-                                       break;
-
-                               if (desc->status & IRQ_DISABLED)
-                                       note_interrupt(irq, desc, IRQ_NONE);
-                               else
-                                       desc->handle_irq(irq, desc);
-                       }
+                       if (service & 1)
+                               generic_handle_irq(irq);
                }
                local_irq_enable();
                ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr);
@@ -215,7 +207,7 @@ static void pcap_isr_work(struct work_struct *work)
 
 static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc)
 {
-       struct pcap_chip *pcap = get_irq_data(irq);
+       struct pcap_chip *pcap = irq_get_handler_data(irq);
 
        desc->irq_data.chip->irq_ack(&desc->irq_data);
        queue_work(pcap->workqueue, &pcap->isr_work);
@@ -419,7 +411,7 @@ static int __devexit ezx_pcap_remove(struct spi_device *spi)
 
        /* cleanup irqchip */
        for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++)
-               set_irq_chip_and_handler(i, NULL, NULL);
+               irq_set_chip_and_handler(i, NULL, NULL);
 
        destroy_workqueue(pcap->workqueue);
 
@@ -476,12 +468,12 @@ static int __devinit ezx_pcap_probe(struct spi_device *spi)
 
        /* setup irq chip */
        for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++) {
-               set_irq_chip_and_handler(i, &pcap_irq_chip, handle_simple_irq);
-               set_irq_chip_data(i, pcap);
+               irq_set_chip_and_handler(i, &pcap_irq_chip, handle_simple_irq);
+               irq_set_chip_data(i, pcap);
 #ifdef CONFIG_ARM
                set_irq_flags(i, IRQF_VALID);
 #else
-               set_irq_noprobe(i);
+               irq_set_noprobe(i);
 #endif
        }
 
@@ -490,10 +482,10 @@ static int __devinit ezx_pcap_probe(struct spi_device *spi)
        ezx_pcap_write(pcap, PCAP_REG_ISR, PCAP_CLEAR_INTERRUPT_REGISTER);
        pcap->msr = PCAP_MASK_ALL_INTERRUPT;
 
-       set_irq_type(spi->irq, IRQ_TYPE_EDGE_RISING);
-       set_irq_data(spi->irq, pcap);
-       set_irq_chained_handler(spi->irq, pcap_irq_handler);
-       set_irq_wake(spi->irq, 1);
+       irq_set_irq_type(spi->irq, IRQ_TYPE_EDGE_RISING);
+       irq_set_handler_data(spi->irq, pcap);
+       irq_set_chained_handler(spi->irq, pcap_irq_handler);
+       irq_set_irq_wake(spi->irq, 1);
 
        /* ADC */
        adc_irq = pcap_to_irq(pcap, (pdata->config & PCAP_SECOND_PORT) ?
@@ -522,7 +514,7 @@ remove_subdevs:
        free_irq(adc_irq, pcap);
 free_irqchip:
        for (i = pcap->irq_base; i < (pcap->irq_base + PCAP_NIRQS); i++)
-               set_irq_chip_and_handler(i, NULL, NULL);
+               irq_set_chip_and_handler(i, NULL, NULL);
 /* destroy_workqueue: */
        destroy_workqueue(pcap->workqueue);
 free_pcap:
index d00b6d1a69e531daedb85a479fad72849a1e30c9..bbaec0ccba8f1185dcb4dce0fd899c5b83ecef8a 100644 (file)
@@ -100,7 +100,7 @@ static struct irq_chip egpio_muxed_chip = {
 
 static void egpio_handler(unsigned int irq, struct irq_desc *desc)
 {
-       struct egpio_info *ei = get_irq_data(irq);
+       struct egpio_info *ei = irq_desc_get_handler_data(desc);
        int irqpin;
 
        /* Read current pins. */
@@ -113,9 +113,7 @@ static void egpio_handler(unsigned int irq, struct irq_desc *desc)
        for_each_set_bit(irqpin, &readval, ei->nirqs) {
                /* Run irq handler */
                pr_debug("got IRQ %d\n", irqpin);
-               irq = ei->irq_start + irqpin;
-               desc = irq_to_desc(irq);
-               desc->handle_irq(irq, desc);
+               generic_handle_irq(ei->irq_start + irqpin);
        }
 }
 
@@ -346,14 +344,14 @@ static int __init egpio_probe(struct platform_device *pdev)
                        ei->ack_write = 0;
                irq_end = ei->irq_start + ei->nirqs;
                for (irq = ei->irq_start; irq < irq_end; irq++) {
-                       set_irq_chip(irq, &egpio_muxed_chip);
-                       set_irq_chip_data(irq, ei);
-                       set_irq_handler(irq, handle_simple_irq);
+                       irq_set_chip_and_handler(irq, &egpio_muxed_chip,
+                                                handle_simple_irq);
+                       irq_set_chip_data(irq, ei);
                        set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
                }
-               set_irq_type(ei->chained_irq, IRQ_TYPE_EDGE_RISING);
-               set_irq_data(ei->chained_irq, ei);
-               set_irq_chained_handler(ei->chained_irq, egpio_handler);
+               irq_set_irq_type(ei->chained_irq, IRQ_TYPE_EDGE_RISING);
+               irq_set_handler_data(ei->chained_irq, ei);
+               irq_set_chained_handler(ei->chained_irq, egpio_handler);
                ack_irqs(ei);
 
                device_init_wakeup(&pdev->dev, 1);
@@ -375,11 +373,10 @@ static int __exit egpio_remove(struct platform_device *pdev)
        if (ei->chained_irq) {
                irq_end = ei->irq_start + ei->nirqs;
                for (irq = ei->irq_start; irq < irq_end; irq++) {
-                       set_irq_chip(irq, NULL);
-                       set_irq_handler(irq, NULL);
+                       irq_set_chip_and_handler(irq, NULL, NULL);
                        set_irq_flags(irq, 0);
                }
-               set_irq_chained_handler(ei->chained_irq, NULL);
+               irq_set_chained_handler(ei->chained_irq, NULL);
                device_init_wakeup(&pdev->dev, 0);
        }
        iounmap(ei->base_addr);
index 296ad1562f69a76d0c9b13101eb2821cdf8fcc31..d55065cc324c7cfa9ae91911eff72a51beac2d0a 100644 (file)
@@ -58,6 +58,7 @@ struct htcpld_chip {
        uint                    irq_start;
        int                     nirqs;
 
+       unsigned int            flow_type;
        /*
         * Work structure to allow for setting values outside of any
         * possible interrupt context
@@ -97,12 +98,7 @@ static void htcpld_unmask(struct irq_data *data)
 
 static int htcpld_set_type(struct irq_data *data, unsigned int flags)
 {
-       struct irq_desc *d = irq_to_desc(data->irq);
-
-       if (!d) {
-               pr_err("HTCPLD invalid IRQ: %d\n", data->irq);
-               return -EINVAL;
-       }
+       struct htcpld_chip *chip = irq_data_get_irq_chip_data(data);
 
        if (flags & ~IRQ_TYPE_SENSE_MASK)
                return -EINVAL;
@@ -111,9 +107,7 @@ static int htcpld_set_type(struct irq_data *data, unsigned int flags)
        if (flags & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH))
                return -EINVAL;
 
-       d->status &= ~IRQ_TYPE_SENSE_MASK;
-       d->status |= flags;
-
+       chip->flow_type = flags;
        return 0;
 }
 
@@ -135,7 +129,6 @@ static irqreturn_t htcpld_handler(int irq, void *dev)
        unsigned int i;
        unsigned long flags;
        int irqpin;
-       struct irq_desc *desc;
 
        if (!htcpld) {
                pr_debug("htcpld is null in ISR\n");
@@ -195,23 +188,19 @@ static irqreturn_t htcpld_handler(int irq, void *dev)
                 * associated interrupts.
                 */
                for (irqpin = 0; irqpin < chip->nirqs; irqpin++) {
-                       unsigned oldb, newb;
-                       int flags;
+                       unsigned oldb, newb, type = chip->flow_type;
 
                        irq = chip->irq_start + irqpin;
-                       desc = irq_to_desc(irq);
-                       flags = desc->status;
 
                        /* Run the IRQ handler, but only if the bit value
                         * changed, and the proper flags are set */
                        oldb = (old_val >> irqpin) & 1;
                        newb = (uval >> irqpin) & 1;
 
-                       if ((!oldb && newb && (flags & IRQ_TYPE_EDGE_RISING)) ||
-                           (oldb && !newb &&
-                            (flags & IRQ_TYPE_EDGE_FALLING))) {
+                       if ((!oldb && newb && (type & IRQ_TYPE_EDGE_RISING)) ||
+                           (oldb && !newb && (type & IRQ_TYPE_EDGE_FALLING))) {
                                pr_debug("fire IRQ %d\n", irqpin);
-                               desc->handle_irq(irq, desc);
+                               generic_handle_irq(irq);
                        }
                }
        }
@@ -359,13 +348,13 @@ static int __devinit htcpld_setup_chip_irq(
        /* Setup irq handlers */
        irq_end = chip->irq_start + chip->nirqs;
        for (irq = chip->irq_start; irq < irq_end; irq++) {
-               set_irq_chip(irq, &htcpld_muxed_chip);
-               set_irq_chip_data(irq, chip);
-               set_irq_handler(irq, handle_simple_irq);
+               irq_set_chip_and_handler(irq, &htcpld_muxed_chip,
+                                        handle_simple_irq);
+               irq_set_chip_data(irq, chip);
 #ifdef CONFIG_ARM
                set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
 #else
-               set_irq_probe(irq);
+               irq_set_probe(irq);
 #endif
        }
 
index aa518b9beaf5c4e7ebb9059ddbd8f62d55916c84..a0bd0cf05af3912b1c0c7d490419a3e6eab9d102 100644 (file)
@@ -112,7 +112,7 @@ static struct irq_chip jz4740_adc_irq_chip = {
 
 static void jz4740_adc_irq_demux(unsigned int irq, struct irq_desc *desc)
 {
-       struct jz4740_adc *adc = get_irq_desc_data(desc);
+       struct jz4740_adc *adc = irq_desc_get_handler_data(desc);
        uint8_t status;
        unsigned int i;
 
@@ -310,13 +310,13 @@ static int __devinit jz4740_adc_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, adc);
 
        for (irq = adc->irq_base; irq < adc->irq_base + 5; ++irq) {
-               set_irq_chip_data(irq, adc);
-               set_irq_chip_and_handler(irq, &jz4740_adc_irq_chip,
-                   handle_level_irq);
+               irq_set_chip_data(irq, adc);
+               irq_set_chip_and_handler(irq, &jz4740_adc_irq_chip,
+                                        handle_level_irq);
        }
 
-       set_irq_data(adc->irq, adc);
-       set_irq_chained_handler(adc->irq, jz4740_adc_irq_demux);
+       irq_set_handler_data(adc->irq, adc);
+       irq_set_chained_handler(adc->irq, jz4740_adc_irq_demux);
 
        writeb(0x00, adc->base + JZ_REG_ADC_ENABLE);
        writeb(0xff, adc->base + JZ_REG_ADC_CTRL);
@@ -347,8 +347,8 @@ static int __devexit jz4740_adc_remove(struct platform_device *pdev)
 
        mfd_remove_devices(&pdev->dev);
 
-       set_irq_data(adc->irq, NULL);
-       set_irq_chained_handler(adc->irq, NULL);
+       irq_set_handler_data(adc->irq, NULL);
+       irq_set_chained_handler(adc->irq, NULL);
 
        iounmap(adc->base);
        release_mem_region(adc->mem->start, resource_size(adc->mem));
index 0e998dc4e7d8cb0c9407a90cb615e9559d6d1b21..58cc5fdde01647be4260f4736a55596d5c684242 100644 (file)
@@ -517,7 +517,6 @@ static int max8925_irq_init(struct max8925_chip *chip, int irq,
                            struct max8925_platform_data *pdata)
 {
        unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
-       struct irq_desc *desc;
        int i, ret;
        int __irq;
 
@@ -544,19 +543,18 @@ static int max8925_irq_init(struct max8925_chip *chip, int irq,
        mutex_init(&chip->irq_lock);
        chip->core_irq = irq;
        chip->irq_base = pdata->irq_base;
-       desc = irq_to_desc(chip->core_irq);
 
        /* register with genirq */
        for (i = 0; i < ARRAY_SIZE(max8925_irqs); i++) {
                __irq = i + chip->irq_base;
-               set_irq_chip_data(__irq, chip);
-               set_irq_chip_and_handler(__irq, &max8925_irq_chip,
+               irq_set_chip_data(__irq, chip);
+               irq_set_chip_and_handler(__irq, &max8925_irq_chip,
                                         handle_edge_irq);
-               set_irq_nested_thread(__irq, 1);
+               irq_set_nested_thread(__irq, 1);
 #ifdef CONFIG_ARM
                set_irq_flags(__irq, IRQF_VALID);
 #else
-               set_irq_noprobe(__irq);
+               irq_set_noprobe(__irq);
 #endif
        }
        if (!irq) {
diff --git a/drivers/mfd/max8997-irq.c b/drivers/mfd/max8997-irq.c
new file mode 100644 (file)
index 0000000..638bf7e
--- /dev/null
@@ -0,0 +1,377 @@
+/*
+ * max8997-irq.c - Interrupt controller support for MAX8997
+ *
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
+ * MyungJoo Ham <myungjoo.ham@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * This driver is based on max8998-irq.c
+ */
+
+#include <linux/err.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/max8997.h>
+#include <linux/mfd/max8997-private.h>
+
+static const u8 max8997_mask_reg[] = {
+       [PMIC_INT1] = MAX8997_REG_INT1MSK,
+       [PMIC_INT2] = MAX8997_REG_INT2MSK,
+       [PMIC_INT3] = MAX8997_REG_INT3MSK,
+       [PMIC_INT4] = MAX8997_REG_INT4MSK,
+       [FUEL_GAUGE] = MAX8997_REG_INVALID,
+       [MUIC_INT1] = MAX8997_MUIC_REG_INTMASK1,
+       [MUIC_INT2] = MAX8997_MUIC_REG_INTMASK2,
+       [MUIC_INT3] = MAX8997_MUIC_REG_INTMASK3,
+       [GPIO_LOW] = MAX8997_REG_INVALID,
+       [GPIO_HI] = MAX8997_REG_INVALID,
+       [FLASH_STATUS] = MAX8997_REG_INVALID,
+};
+
+static struct i2c_client *get_i2c(struct max8997_dev *max8997,
+                               enum max8997_irq_source src)
+{
+       switch (src) {
+       case PMIC_INT1 ... PMIC_INT4:
+               return max8997->i2c;
+       case FUEL_GAUGE:
+               return NULL;
+       case MUIC_INT1 ... MUIC_INT3:
+               return max8997->muic;
+       case GPIO_LOW ... GPIO_HI:
+               return max8997->i2c;
+       case FLASH_STATUS:
+               return max8997->i2c;
+       default:
+               return ERR_PTR(-EINVAL);
+       }
+
+       return ERR_PTR(-EINVAL);
+}
+
+struct max8997_irq_data {
+       int mask;
+       enum max8997_irq_source group;
+};
+
+#define DECLARE_IRQ(idx, _group, _mask)                \
+       [(idx)] = { .group = (_group), .mask = (_mask) }
+static const struct max8997_irq_data max8997_irqs[] = {
+       DECLARE_IRQ(MAX8997_PMICIRQ_PWRONR,     PMIC_INT1, 1 << 0),
+       DECLARE_IRQ(MAX8997_PMICIRQ_PWRONF,     PMIC_INT1, 1 << 1),
+       DECLARE_IRQ(MAX8997_PMICIRQ_PWRON1SEC,  PMIC_INT1, 1 << 3),
+       DECLARE_IRQ(MAX8997_PMICIRQ_JIGONR,     PMIC_INT1, 1 << 4),
+       DECLARE_IRQ(MAX8997_PMICIRQ_JIGONF,     PMIC_INT1, 1 << 5),
+       DECLARE_IRQ(MAX8997_PMICIRQ_LOWBAT2,    PMIC_INT1, 1 << 6),
+       DECLARE_IRQ(MAX8997_PMICIRQ_LOWBAT1,    PMIC_INT1, 1 << 7),
+
+       DECLARE_IRQ(MAX8997_PMICIRQ_JIGR,       PMIC_INT2, 1 << 0),
+       DECLARE_IRQ(MAX8997_PMICIRQ_JIGF,       PMIC_INT2, 1 << 1),
+       DECLARE_IRQ(MAX8997_PMICIRQ_MR,         PMIC_INT2, 1 << 2),
+       DECLARE_IRQ(MAX8997_PMICIRQ_DVS1OK,     PMIC_INT2, 1 << 3),
+       DECLARE_IRQ(MAX8997_PMICIRQ_DVS2OK,     PMIC_INT2, 1 << 4),
+       DECLARE_IRQ(MAX8997_PMICIRQ_DVS3OK,     PMIC_INT2, 1 << 5),
+       DECLARE_IRQ(MAX8997_PMICIRQ_DVS4OK,     PMIC_INT2, 1 << 6),
+
+       DECLARE_IRQ(MAX8997_PMICIRQ_CHGINS,     PMIC_INT3, 1 << 0),
+       DECLARE_IRQ(MAX8997_PMICIRQ_CHGRM,      PMIC_INT3, 1 << 1),
+       DECLARE_IRQ(MAX8997_PMICIRQ_DCINOVP,    PMIC_INT3, 1 << 2),
+       DECLARE_IRQ(MAX8997_PMICIRQ_TOPOFFR,    PMIC_INT3, 1 << 3),
+       DECLARE_IRQ(MAX8997_PMICIRQ_CHGRSTF,    PMIC_INT3, 1 << 5),
+       DECLARE_IRQ(MAX8997_PMICIRQ_MBCHGTMEXPD,        PMIC_INT3, 1 << 7),
+
+       DECLARE_IRQ(MAX8997_PMICIRQ_RTC60S,     PMIC_INT4, 1 << 0),
+       DECLARE_IRQ(MAX8997_PMICIRQ_RTCA1,      PMIC_INT4, 1 << 1),
+       DECLARE_IRQ(MAX8997_PMICIRQ_RTCA2,      PMIC_INT4, 1 << 2),
+       DECLARE_IRQ(MAX8997_PMICIRQ_SMPL_INT,   PMIC_INT4, 1 << 3),
+       DECLARE_IRQ(MAX8997_PMICIRQ_RTC1S,      PMIC_INT4, 1 << 4),
+       DECLARE_IRQ(MAX8997_PMICIRQ_WTSR,       PMIC_INT4, 1 << 5),
+
+       DECLARE_IRQ(MAX8997_MUICIRQ_ADCError,   MUIC_INT1, 1 << 2),
+       DECLARE_IRQ(MAX8997_MUICIRQ_ADCLow,     MUIC_INT1, 1 << 1),
+       DECLARE_IRQ(MAX8997_MUICIRQ_ADC,        MUIC_INT1, 1 << 0),
+
+       DECLARE_IRQ(MAX8997_MUICIRQ_VBVolt,     MUIC_INT2, 1 << 4),
+       DECLARE_IRQ(MAX8997_MUICIRQ_DBChg,      MUIC_INT2, 1 << 3),
+       DECLARE_IRQ(MAX8997_MUICIRQ_DCDTmr,     MUIC_INT2, 1 << 2),
+       DECLARE_IRQ(MAX8997_MUICIRQ_ChgDetRun,  MUIC_INT2, 1 << 1),
+       DECLARE_IRQ(MAX8997_MUICIRQ_ChgTyp,     MUIC_INT2, 1 << 0),
+
+       DECLARE_IRQ(MAX8997_MUICIRQ_OVP,        MUIC_INT3, 1 << 2),
+};
+
+static void max8997_irq_lock(struct irq_data *data)
+{
+       struct max8997_dev *max8997 = irq_get_chip_data(data->irq);
+
+       mutex_lock(&max8997->irqlock);
+}
+
+static void max8997_irq_sync_unlock(struct irq_data *data)
+{
+       struct max8997_dev *max8997 = irq_get_chip_data(data->irq);
+       int i;
+
+       for (i = 0; i < MAX8997_IRQ_GROUP_NR; i++) {
+               u8 mask_reg = max8997_mask_reg[i];
+               struct i2c_client *i2c = get_i2c(max8997, i);
+
+               if (mask_reg == MAX8997_REG_INVALID ||
+                               IS_ERR_OR_NULL(i2c))
+                       continue;
+               max8997->irq_masks_cache[i] = max8997->irq_masks_cur[i];
+
+               max8997_write_reg(i2c, max8997_mask_reg[i],
+                               max8997->irq_masks_cur[i]);
+       }
+
+       mutex_unlock(&max8997->irqlock);
+}
+
+static const inline struct max8997_irq_data *
+irq_to_max8997_irq(struct max8997_dev *max8997, int irq)
+{
+       return &max8997_irqs[irq - max8997->irq_base];
+}
+
+static void max8997_irq_mask(struct irq_data *data)
+{
+       struct max8997_dev *max8997 = irq_get_chip_data(data->irq);
+       const struct max8997_irq_data *irq_data = irq_to_max8997_irq(max8997,
+                                                               data->irq);
+
+       max8997->irq_masks_cur[irq_data->group] |= irq_data->mask;
+}
+
+static void max8997_irq_unmask(struct irq_data *data)
+{
+       struct max8997_dev *max8997 = irq_get_chip_data(data->irq);
+       const struct max8997_irq_data *irq_data = irq_to_max8997_irq(max8997,
+                                                               data->irq);
+
+       max8997->irq_masks_cur[irq_data->group] &= ~irq_data->mask;
+}
+
+static struct irq_chip max8997_irq_chip = {
+       .name                   = "max8997",
+       .irq_bus_lock           = max8997_irq_lock,
+       .irq_bus_sync_unlock    = max8997_irq_sync_unlock,
+       .irq_mask               = max8997_irq_mask,
+       .irq_unmask             = max8997_irq_unmask,
+};
+
+#define MAX8997_IRQSRC_PMIC            (1 << 1)
+#define MAX8997_IRQSRC_FUELGAUGE       (1 << 2)
+#define MAX8997_IRQSRC_MUIC            (1 << 3)
+#define MAX8997_IRQSRC_GPIO            (1 << 4)
+#define MAX8997_IRQSRC_FLASH           (1 << 5)
+static irqreturn_t max8997_irq_thread(int irq, void *data)
+{
+       struct max8997_dev *max8997 = data;
+       u8 irq_reg[MAX8997_IRQ_GROUP_NR] = {};
+       u8 irq_src;
+       int ret;
+       int i;
+
+       ret = max8997_read_reg(max8997->i2c, MAX8997_REG_INTSRC, &irq_src);
+       if (ret < 0) {
+               dev_err(max8997->dev, "Failed to read interrupt source: %d\n",
+                               ret);
+               return IRQ_NONE;
+       }
+
+       if (irq_src & MAX8997_IRQSRC_PMIC) {
+               /* PMIC INT1 ~ INT4 */
+               max8997_bulk_read(max8997->i2c, MAX8997_REG_INT1, 4,
+                               &irq_reg[PMIC_INT1]);
+       }
+       if (irq_src & MAX8997_IRQSRC_FUELGAUGE) {
+               /*
+                * TODO: FUEL GAUGE
+                *
+                * This is to be supported by Max17042 driver. When
+                * an interrupt incurs here, it should be relayed to a
+                * Max17042 device that is connected (probably by
+                * platform-data). However, we do not have interrupt
+                * handling in Max17042 driver currently. The Max17042 IRQ
+                * driver should be ready to be used as a stand-alone device and
+                * a Max8997-dependent device. Because it is not ready in
+                * Max17042-side and it is not too critical in operating
+                * Max8997, we do not implement this in initial releases.
+                */
+               irq_reg[FUEL_GAUGE] = 0;
+       }
+       if (irq_src & MAX8997_IRQSRC_MUIC) {
+               /* MUIC INT1 ~ INT3 */
+               max8997_bulk_read(max8997->muic, MAX8997_MUIC_REG_INT1, 3,
+                               &irq_reg[MUIC_INT1]);
+       }
+       if (irq_src & MAX8997_IRQSRC_GPIO) {
+               /* GPIO Interrupt */
+               u8 gpio_info[MAX8997_NUM_GPIO];
+
+               irq_reg[GPIO_LOW] = 0;
+               irq_reg[GPIO_HI] = 0;
+
+               max8997_bulk_read(max8997->i2c, MAX8997_REG_GPIOCNTL1,
+                               MAX8997_NUM_GPIO, gpio_info);
+               for (i = 0; i < MAX8997_NUM_GPIO; i++) {
+                       bool interrupt = false;
+
+                       switch (gpio_info[i] & MAX8997_GPIO_INT_MASK) {
+                       case MAX8997_GPIO_INT_BOTH:
+                               if (max8997->gpio_status[i] != gpio_info[i])
+                                       interrupt = true;
+                               break;
+                       case MAX8997_GPIO_INT_RISE:
+                               if ((max8997->gpio_status[i] != gpio_info[i]) &&
+                                   (gpio_info[i] & MAX8997_GPIO_DATA_MASK))
+                                       interrupt = true;
+                               break;
+                       case MAX8997_GPIO_INT_FALL:
+                               if ((max8997->gpio_status[i] != gpio_info[i]) &&
+                                   !(gpio_info[i] & MAX8997_GPIO_DATA_MASK))
+                                       interrupt = true;
+                               break;
+                       default:
+                               break;
+                       }
+
+                       if (interrupt) {
+                               if (i < 8)
+                                       irq_reg[GPIO_LOW] |= (1 << i);
+                               else
+                                       irq_reg[GPIO_HI] |= (1 << (i - 8));
+                       }
+
+               }
+       }
+       if (irq_src & MAX8997_IRQSRC_FLASH) {
+               /* Flash Status Interrupt */
+               ret = max8997_read_reg(max8997->i2c, MAX8997_REG_FLASHSTATUS,
+                               &irq_reg[FLASH_STATUS]);
+       }
+
+       /* Apply masking */
+       for (i = 0; i < MAX8997_IRQ_GROUP_NR; i++)
+               irq_reg[i] &= ~max8997->irq_masks_cur[i];
+
+       /* Report */
+       for (i = 0; i < MAX8997_IRQ_NR; i++) {
+               if (irq_reg[max8997_irqs[i].group] & max8997_irqs[i].mask)
+                       handle_nested_irq(max8997->irq_base + i);
+       }
+
+       return IRQ_HANDLED;
+}
+
+int max8997_irq_resume(struct max8997_dev *max8997)
+{
+       if (max8997->irq && max8997->irq_base)
+               max8997_irq_thread(max8997->irq_base, max8997);
+       return 0;
+}
+
+int max8997_irq_init(struct max8997_dev *max8997)
+{
+       int i;
+       int cur_irq;
+       int ret;
+       u8 val;
+
+       if (!max8997->irq) {
+               dev_warn(max8997->dev, "No interrupt specified.\n");
+               max8997->irq_base = 0;
+               return 0;
+       }
+
+       if (!max8997->irq_base) {
+               dev_err(max8997->dev, "No interrupt base specified.\n");
+               return 0;
+       }
+
+       mutex_init(&max8997->irqlock);
+
+       /* Mask individual interrupt sources */
+       for (i = 0; i < MAX8997_IRQ_GROUP_NR; i++) {
+               struct i2c_client *i2c;
+
+               max8997->irq_masks_cur[i] = 0xff;
+               max8997->irq_masks_cache[i] = 0xff;
+               i2c = get_i2c(max8997, i);
+
+               if (IS_ERR_OR_NULL(i2c))
+                       continue;
+               if (max8997_mask_reg[i] == MAX8997_REG_INVALID)
+                       continue;
+
+               max8997_write_reg(i2c, max8997_mask_reg[i], 0xff);
+       }
+
+       for (i = 0; i < MAX8997_NUM_GPIO; i++) {
+               max8997->gpio_status[i] = (max8997_read_reg(max8997->i2c,
+                                               MAX8997_REG_GPIOCNTL1 + i,
+                                               &val)
+                                       & MAX8997_GPIO_DATA_MASK) ?
+                                       true : false;
+       }
+
+       /* Register with genirq */
+       for (i = 0; i < MAX8997_IRQ_NR; i++) {
+               cur_irq = i + max8997->irq_base;
+               irq_set_chip_data(cur_irq, max8997);
+               irq_set_chip_and_handler(cur_irq, &max8997_irq_chip,
+                               handle_edge_irq);
+               irq_set_nested_thread(cur_irq, 1);
+#ifdef CONFIG_ARM
+               set_irq_flags(cur_irq, IRQF_VALID);
+#else
+               irq_set_noprobe(cur_irq);
+#endif
+       }
+
+       ret = request_threaded_irq(max8997->irq, NULL, max8997_irq_thread,
+                       IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+                       "max8997-irq", max8997);
+
+       if (ret) {
+               dev_err(max8997->dev, "Failed to request IRQ %d: %d\n",
+                               max8997->irq, ret);
+               return ret;
+       }
+
+       if (!max8997->ono)
+               return 0;
+
+       ret = request_threaded_irq(max8997->ono, NULL, max8997_irq_thread,
+                       IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING |
+                       IRQF_ONESHOT, "max8997-ono", max8997);
+
+       if (ret)
+               dev_err(max8997->dev, "Failed to request ono-IRQ %d: %d\n",
+                               max8997->ono, ret);
+
+       return 0;
+}
+
+void max8997_irq_exit(struct max8997_dev *max8997)
+{
+       if (max8997->ono)
+               free_irq(max8997->ono, max8997);
+
+       if (max8997->irq)
+               free_irq(max8997->irq, max8997);
+}
index 3903e1fbb3347b0792dc83a651b125163ad52c3c..5919710dc9ed47aae020619d6f0b1e5c7a808c23 100644 (file)
@@ -224,14 +224,14 @@ int max8998_irq_init(struct max8998_dev *max8998)
        /* register with genirq */
        for (i = 0; i < MAX8998_IRQ_NR; i++) {
                cur_irq = i + max8998->irq_base;
-               set_irq_chip_data(cur_irq, max8998);
-               set_irq_chip_and_handler(cur_irq, &max8998_irq_chip,
+               irq_set_chip_data(cur_irq, max8998);
+               irq_set_chip_and_handler(cur_irq, &max8998_irq_chip,
                                         handle_edge_irq);
-               set_irq_nested_thread(cur_irq, 1);
+               irq_set_nested_thread(cur_irq, 1);
 #ifdef CONFIG_ARM
                set_irq_flags(cur_irq, IRQF_VALID);
 #else
-               set_irq_noprobe(cur_irq);
+               irq_set_noprobe(cur_irq);
 #endif
        }
 
index c00214257da28c97e80e27c30cedf3ac86ac7cfe..9ec7570f5b8140b53bc620edbba36df37b9757b4 100644 (file)
@@ -209,7 +209,7 @@ static int max8998_suspend(struct device *dev)
        struct max8998_dev *max8998 = i2c_get_clientdata(i2c);
 
        if (max8998->wakeup)
-               set_irq_wake(max8998->irq, 1);
+               irq_set_irq_wake(max8998->irq, 1);
        return 0;
 }
 
@@ -219,7 +219,7 @@ static int max8998_resume(struct device *dev)
        struct max8998_dev *max8998 = i2c_get_clientdata(i2c);
 
        if (max8998->wakeup)
-               set_irq_wake(max8998->irq, 0);
+               irq_set_irq_wake(max8998->irq, 0);
        /*
         * In LP3974, if IRQ registers are not "read & clear"
         * when it's set during sleep, the interrupt becomes
index 79eda0264fb277176a2141338d9d4aa8682ea3b7..d01574d98870a0473b56be995cd0341786b9b767 100644 (file)
@@ -184,16 +184,12 @@ void mfd_remove_devices(struct device *parent)
 }
 EXPORT_SYMBOL(mfd_remove_devices);
 
-static int add_shared_platform_device(const char *cell, const char *name)
+int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones)
 {
        struct mfd_cell cell_entry;
        struct device *dev;
        struct platform_device *pdev;
-       int err;
-
-       /* check if we've already registered a device (don't fail if we have) */
-       if (bus_find_device_by_name(&platform_bus_type, NULL, name))
-               return 0;
+       int i;
 
        /* fetch the parent cell's device (should already be registered!) */
        dev = bus_find_device_by_name(&platform_bus_type, NULL, cell);
@@ -206,44 +202,17 @@ static int add_shared_platform_device(const char *cell, const char *name)
 
        WARN_ON(!cell_entry.enable);
 
-       cell_entry.name = name;
-       err = mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0);
-       if (err)
-               dev_err(dev, "MFD add devices failed: %d\n", err);
-       return err;
-}
-
-int mfd_shared_platform_driver_register(struct platform_driver *drv,
-               const char *cellname)
-{
-       int err;
-
-       err = add_shared_platform_device(cellname, drv->driver.name);
-       if (err)
-               printk(KERN_ERR "failed to add platform device %s\n",
-                               drv->driver.name);
-
-       err = platform_driver_register(drv);
-       if (err)
-               printk(KERN_ERR "failed to add platform driver %s\n",
-                               drv->driver.name);
-
-       return err;
-}
-EXPORT_SYMBOL(mfd_shared_platform_driver_register);
-
-void mfd_shared_platform_driver_unregister(struct platform_driver *drv)
-{
-       struct device *dev;
-
-       dev = bus_find_device_by_name(&platform_bus_type, NULL,
-                       drv->driver.name);
-       if (dev)
-               platform_device_unregister(to_platform_device(dev));
+       for (i = 0; i < n_clones; i++) {
+               cell_entry.name = clones[i];
+               /* don't give up if a single call fails; just report error */
+               if (mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0))
+                       dev_err(dev, "failed to create platform device '%s'\n",
+                                       clones[i]);
+       }
 
-       platform_driver_unregister(drv);
+       return 0;
 }
-EXPORT_SYMBOL(mfd_shared_platform_driver_unregister);
+EXPORT_SYMBOL(mfd_clone_cell);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov");
index c1306ed43e3c10cf0c7f69a95dabcf0ecdbc6bd0..c7687f6a78a0ef9d1799801f667689ca2b214124 100644 (file)
@@ -356,7 +356,7 @@ static int __devexit pcf50633_remove(struct i2c_client *client)
        return 0;
 }
 
-static struct i2c_device_id pcf50633_id_table[] = {
+static const struct i2c_device_id pcf50633_id_table[] = {
        {"pcf50633", 0x73},
        {/* end of list */}
 };
index 193c940225b5bc45bec2fe3a9ce7204e79ef464d..10dbe6374a89328b00da7014e4eccfa886906f2f 100644 (file)
@@ -97,6 +97,7 @@ static DEFINE_PCI_DEVICE_TABLE(rdc321x_sb_table) = {
        { PCI_DEVICE(PCI_VENDOR_ID_RDC, PCI_DEVICE_ID_RDC_R6030) },
        {}
 };
+MODULE_DEVICE_TABLE(pci, rdc321x_sb_table);
 
 static struct pci_driver rdc321x_sb_driver = {
        .name           = "RDC321x Southbridge",
index 3e5732b58c49900efd5da19ad14a72f659df92f5..7ab7746631d4e58a9e2fd0611c13da211ce54463 100644 (file)
@@ -762,14 +762,14 @@ static int __devinit stmpe_irq_init(struct stmpe *stmpe)
        int irq;
 
        for (irq = base; irq < base + num_irqs; irq++) {
-               set_irq_chip_data(irq, stmpe);
-               set_irq_chip_and_handler(irq, &stmpe_irq_chip,
+               irq_set_chip_data(irq, stmpe);
+               irq_set_chip_and_handler(irq, &stmpe_irq_chip,
                                         handle_edge_irq);
-               set_irq_nested_thread(irq, 1);
+               irq_set_nested_thread(irq, 1);
 #ifdef CONFIG_ARM
                set_irq_flags(irq, IRQF_VALID);
 #else
-               set_irq_noprobe(irq);
+               irq_set_noprobe(irq);
 #endif
        }
 
@@ -786,8 +786,8 @@ static void stmpe_irq_remove(struct stmpe *stmpe)
 #ifdef CONFIG_ARM
                set_irq_flags(irq, 0);
 #endif
-               set_irq_chip_and_handler(irq, NULL, NULL);
-               set_irq_chip_data(irq, NULL);
+               irq_set_chip_and_handler(irq, NULL, NULL);
+               irq_set_chip_data(irq, NULL);
        }
 }
 
index af57fc706a4cedf49043309c93d6f5cc47ca7e10..42830e6929649ae99e729479eb76dd1dd4bd917c 100644 (file)
@@ -186,7 +186,7 @@ static struct mfd_cell t7l66xb_cells[] = {
 /* Handle the T7L66XB interrupt mux */
 static void t7l66xb_irq(unsigned int irq, struct irq_desc *desc)
 {
-       struct t7l66xb *t7l66xb = get_irq_data(irq);
+       struct t7l66xb *t7l66xb = irq_get_handler_data(irq);
        unsigned int isr;
        unsigned int i, irq_base;
 
@@ -243,17 +243,16 @@ static void t7l66xb_attach_irq(struct platform_device *dev)
        irq_base = t7l66xb->irq_base;
 
        for (irq = irq_base; irq < irq_base + T7L66XB_NR_IRQS; irq++) {
-               set_irq_chip(irq, &t7l66xb_chip);
-               set_irq_chip_data(irq, t7l66xb);
-               set_irq_handler(irq, handle_level_irq);
+               irq_set_chip_and_handler(irq, &t7l66xb_chip, handle_level_irq);
+               irq_set_chip_data(irq, t7l66xb);
 #ifdef CONFIG_ARM
                set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
 #endif
        }
 
-       set_irq_type(t7l66xb->irq, IRQ_TYPE_EDGE_FALLING);
-       set_irq_data(t7l66xb->irq, t7l66xb);
-       set_irq_chained_handler(t7l66xb->irq, t7l66xb_irq);
+       irq_set_irq_type(t7l66xb->irq, IRQ_TYPE_EDGE_FALLING);
+       irq_set_handler_data(t7l66xb->irq, t7l66xb);
+       irq_set_chained_handler(t7l66xb->irq, t7l66xb_irq);
 }
 
 static void t7l66xb_detach_irq(struct platform_device *dev)
@@ -263,15 +262,15 @@ static void t7l66xb_detach_irq(struct platform_device *dev)
 
        irq_base = t7l66xb->irq_base;
 
-       set_irq_chained_handler(t7l66xb->irq, NULL);
-       set_irq_data(t7l66xb->irq, NULL);
+       irq_set_chained_handler(t7l66xb->irq, NULL);
+       irq_set_handler_data(t7l66xb->irq, NULL);
 
        for (irq = irq_base; irq < irq_base + T7L66XB_NR_IRQS; irq++) {
 #ifdef CONFIG_ARM
                set_irq_flags(irq, 0);
 #endif
-               set_irq_chip(irq, NULL);
-               set_irq_chip_data(irq, NULL);
+               irq_set_chip(irq, NULL);
+               irq_set_chip_data(irq, NULL);
        }
 }
 
index 729dbeed2ce09f0c83f09483e345ffe1c1e63ebb..c27e515b0722b2dfa72263e5bd3725ddd27885fd 100644 (file)
@@ -192,14 +192,14 @@ static int tc3589x_irq_init(struct tc3589x *tc3589x)
        int irq;
 
        for (irq = base; irq < base + TC3589x_NR_INTERNAL_IRQS; irq++) {
-               set_irq_chip_data(irq, tc3589x);
-               set_irq_chip_and_handler(irq, &dummy_irq_chip,
+               irq_set_chip_data(irq, tc3589x);
+               irq_set_chip_and_handler(irq, &dummy_irq_chip,
                                         handle_edge_irq);
-               set_irq_nested_thread(irq, 1);
+               irq_set_nested_thread(irq, 1);
 #ifdef CONFIG_ARM
                set_irq_flags(irq, IRQF_VALID);
 #else
-               set_irq_noprobe(irq);
+               irq_set_noprobe(irq);
 #endif
        }
 
@@ -215,8 +215,8 @@ static void tc3589x_irq_remove(struct tc3589x *tc3589x)
 #ifdef CONFIG_ARM
                set_irq_flags(irq, 0);
 #endif
-               set_irq_chip_and_handler(irq, NULL, NULL);
-               set_irq_chip_data(irq, NULL);
+               irq_set_chip_and_handler(irq, NULL, NULL);
+               irq_set_chip_data(irq, NULL);
        }
 }
 
index 3d62ded86a8fe478a386ae96c41d88e3d81a368d..fc53ce287601b84062940d80428fdf3dcb358c16 100644 (file)
@@ -513,7 +513,7 @@ static int tc6393xb_register_gpio(struct tc6393xb *tc6393xb, int gpio_base)
 static void
 tc6393xb_irq(unsigned int irq, struct irq_desc *desc)
 {
-       struct tc6393xb *tc6393xb = get_irq_data(irq);
+       struct tc6393xb *tc6393xb = irq_get_handler_data(irq);
        unsigned int isr;
        unsigned int i, irq_base;
 
@@ -572,15 +572,14 @@ static void tc6393xb_attach_irq(struct platform_device *dev)
        irq_base = tc6393xb->irq_base;
 
        for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) {
-               set_irq_chip(irq, &tc6393xb_chip);
-               set_irq_chip_data(irq, tc6393xb);
-               set_irq_handler(irq, handle_edge_irq);
+               irq_set_chip_and_handler(irq, &tc6393xb_chip, handle_edge_irq);
+               irq_set_chip_data(irq, tc6393xb);
                set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
        }
 
-       set_irq_type(tc6393xb->irq, IRQ_TYPE_EDGE_FALLING);
-       set_irq_data(tc6393xb->irq, tc6393xb);
-       set_irq_chained_handler(tc6393xb->irq, tc6393xb_irq);
+       irq_set_irq_type(tc6393xb->irq, IRQ_TYPE_EDGE_FALLING);
+       irq_set_handler_data(tc6393xb->irq, tc6393xb);
+       irq_set_chained_handler(tc6393xb->irq, tc6393xb_irq);
 }
 
 static void tc6393xb_detach_irq(struct platform_device *dev)
@@ -588,15 +587,15 @@ static void tc6393xb_detach_irq(struct platform_device *dev)
        struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
        unsigned int irq, irq_base;
 
-       set_irq_chained_handler(tc6393xb->irq, NULL);
-       set_irq_data(tc6393xb->irq, NULL);
+       irq_set_chained_handler(tc6393xb->irq, NULL);
+       irq_set_handler_data(tc6393xb->irq, NULL);
 
        irq_base = tc6393xb->irq_base;
 
        for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) {
                set_irq_flags(irq, 0);
-               set_irq_chip(irq, NULL);
-               set_irq_chip_data(irq, NULL);
+               irq_set_chip(irq, NULL);
+               irq_set_chip_data(irq, NULL);
        }
 }
 
index 0aa9186aec1961cb19d8a6b35ae027c07ffb3a04..b600808690c1092e1d9946f848e537647dbd1def 100644 (file)
@@ -422,10 +422,10 @@ static int __devinit tps6586x_irq_init(struct tps6586x *tps6586x, int irq,
 
        for (i = 0; i < ARRAY_SIZE(tps6586x_irqs); i++) {
                int __irq = i + tps6586x->irq_base;
-               set_irq_chip_data(__irq, tps6586x);
-               set_irq_chip_and_handler(__irq, &tps6586x->irq_chip,
+               irq_set_chip_data(__irq, tps6586x);
+               irq_set_chip_and_handler(__irq, &tps6586x->irq_chip,
                                         handle_simple_irq);
-               set_irq_nested_thread(__irq, 1);
+               irq_set_nested_thread(__irq, 1);
 #ifdef CONFIG_ARM
                set_irq_flags(__irq, IRQF_VALID);
 #endif
index 63a30e88908f8e903df95883c3f571e91fccff9e..8a7ee3139b86fda3bded6748e572893d37b577fb 100644 (file)
@@ -320,24 +320,8 @@ static int twl4030_irq_thread(void *data)
                for (module_irq = twl4030_irq_base;
                                pih_isr;
                                pih_isr >>= 1, module_irq++) {
-                       if (pih_isr & 0x1) {
-                               struct irq_desc *d = irq_to_desc(module_irq);
-
-                               if (!d) {
-                                       pr_err("twl4030: Invalid SIH IRQ: %d\n",
-                                              module_irq);
-                                       return -EINVAL;
-                               }
-
-                               /* These can't be masked ... always warn
-                                * if we get any surprises.
-                                */
-                               if (d->status & IRQ_DISABLED)
-                                       note_interrupt(module_irq, d,
-                                                       IRQ_NONE);
-                               else
-                                       d->handle_irq(module_irq, d);
-                       }
+                       if (pih_isr & 0x1)
+                               generic_handle_irq(module_irq);
                }
                local_irq_enable();
 
@@ -470,7 +454,7 @@ static inline void activate_irq(int irq)
        set_irq_flags(irq, IRQF_VALID);
 #else
        /* same effect on other architectures */
-       set_irq_noprobe(irq);
+       irq_set_noprobe(irq);
 #endif
 }
 
@@ -560,24 +544,18 @@ static void twl4030_sih_do_edge(struct work_struct *work)
        /* Modify only the bits we know must change */
        while (edge_change) {
                int             i = fls(edge_change) - 1;
-               struct irq_desc *d = irq_to_desc(i + agent->irq_base);
+               struct irq_data *idata = irq_get_irq_data(i + agent->irq_base);
                int             byte = 1 + (i >> 2);
                int             off = (i & 0x3) * 2;
-
-               if (!d) {
-                       pr_err("twl4030: Invalid IRQ: %d\n",
-                              i + agent->irq_base);
-                       return;
-               }
+               unsigned int    type;
 
                bytes[byte] &= ~(0x03 << off);
 
-               raw_spin_lock_irq(&d->lock);
-               if (d->status & IRQ_TYPE_EDGE_RISING)
+               type = irqd_get_trigger_type(idata);
+               if (type & IRQ_TYPE_EDGE_RISING)
                        bytes[byte] |= BIT(off + 1);
-               if (d->status & IRQ_TYPE_EDGE_FALLING)
+               if (type & IRQ_TYPE_EDGE_FALLING)
                        bytes[byte] |= BIT(off + 0);
-               raw_spin_unlock_irq(&d->lock);
 
                edge_change &= ~BIT(i);
        }
@@ -626,21 +604,13 @@ static void twl4030_sih_unmask(struct irq_data *data)
 static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger)
 {
        struct sih_agent *sih = irq_data_get_irq_chip_data(data);
-       struct irq_desc *desc = irq_to_desc(data->irq);
        unsigned long flags;
 
-       if (!desc) {
-               pr_err("twl4030: Invalid IRQ: %d\n", data->irq);
-               return -EINVAL;
-       }
-
        if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
                return -EINVAL;
 
        spin_lock_irqsave(&sih_agent_lock, flags);
-       if ((desc->status & IRQ_TYPE_SENSE_MASK) != trigger) {
-               desc->status &= ~IRQ_TYPE_SENSE_MASK;
-               desc->status |= trigger;
+       if (irqd_get_trigger_type(data) != trigger) {
                sih->edge_change |= BIT(data->irq - sih->irq_base);
                queue_work(wq, &sih->edge_work);
        }
@@ -680,7 +650,7 @@ static inline int sih_read_isr(const struct sih *sih)
  */
 static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc)
 {
-       struct sih_agent *agent = get_irq_data(irq);
+       struct sih_agent *agent = irq_get_handler_data(irq);
        const struct sih *sih = agent->sih;
        int isr;
 
@@ -754,9 +724,9 @@ int twl4030_sih_setup(int module)
        for (i = 0; i < sih->bits; i++) {
                irq = irq_base + i;
 
-               set_irq_chip_and_handler(irq, &twl4030_sih_irq_chip,
-                               handle_edge_irq);
-               set_irq_chip_data(irq, agent);
+               irq_set_chip_and_handler(irq, &twl4030_sih_irq_chip,
+                                        handle_edge_irq);
+               irq_set_chip_data(irq, agent);
                activate_irq(irq);
        }
 
@@ -765,8 +735,8 @@ int twl4030_sih_setup(int module)
 
        /* replace generic PIH handler (handle_simple_irq) */
        irq = sih_mod + twl4030_irq_base;
-       set_irq_data(irq, agent);
-       set_irq_chained_handler(irq, handle_twl4030_sih);
+       irq_set_handler_data(irq, agent);
+       irq_set_chained_handler(irq, handle_twl4030_sih);
 
        pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", sih->name,
                        irq, irq_base, twl4030_irq_next - 1);
@@ -815,8 +785,8 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
        twl4030_sih_irq_chip.irq_ack = dummy_irq_chip.irq_ack;
 
        for (i = irq_base; i < irq_end; i++) {
-               set_irq_chip_and_handler(i, &twl4030_irq_chip,
-                               handle_simple_irq);
+               irq_set_chip_and_handler(i, &twl4030_irq_chip,
+                                        handle_simple_irq);
                activate_irq(i);
        }
        twl4030_irq_next = i;
@@ -856,7 +826,7 @@ fail_rqirq:
        /* clean up twl4030_sih_setup */
 fail:
        for (i = irq_base; i < irq_end; i++)
-               set_irq_chip_and_handler(i, NULL, NULL);
+               irq_set_chip_and_handler(i, NULL, NULL);
        destroy_workqueue(wq);
        wq = NULL;
        return status;
index 4082ed73613f98a6abd0fb0a1b8463f0d45a788e..fa937052fbab996b564e46ed17f3fefdae422010 100644 (file)
@@ -140,22 +140,7 @@ static int twl6030_irq_thread(void *data)
                        if (sts.int_sts & 0x1) {
                                int module_irq = twl6030_irq_base +
                                        twl6030_interrupt_mapping[i];
-                               struct irq_desc *d = irq_to_desc(module_irq);
-
-                               if (!d) {
-                                       pr_err("twl6030: Invalid SIH IRQ: %d\n",
-                                              module_irq);
-                                       return -EINVAL;
-                               }
-
-                               /* These can't be masked ... always warn
-                                * if we get any surprises.
-                                */
-                               if (d->status & IRQ_DISABLED)
-                                       note_interrupt(module_irq, d,
-                                                       IRQ_NONE);
-                               else
-                                       d->handle_irq(module_irq, d);
+                               generic_handle_irq(module_irq);
 
                        }
                local_irq_enable();
@@ -198,7 +183,7 @@ static inline void activate_irq(int irq)
        set_irq_flags(irq, IRQF_VALID);
 #else
        /* same effect on other architectures */
-       set_irq_noprobe(irq);
+       irq_set_noprobe(irq);
 #endif
 }
 
@@ -335,8 +320,8 @@ int twl6030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
        twl6030_irq_chip.irq_set_type = NULL;
 
        for (i = irq_base; i < irq_end; i++) {
-               set_irq_chip_and_handler(i, &twl6030_irq_chip,
-                               handle_simple_irq);
+               irq_set_chip_and_handler(i, &twl6030_irq_chip,
+                                        handle_simple_irq);
                activate_irq(i);
        }
 
@@ -365,7 +350,7 @@ fail_irq:
 
 fail_kthread:
        for (i = irq_base; i < irq_end; i++)
-               set_irq_chip_and_handler(i, NULL, NULL);
+               irq_set_chip_and_handler(i, NULL, NULL);
        return status;
 }
 
index f76f6c798046434baeb0dddea523de6b05158d0a..04914f2836c0ad3d22a97d2787d789a1f34e1ae9 100644 (file)
@@ -25,7 +25,7 @@
 
 #define DRIVER_DESC "WL1273 FM Radio Core"
 
-static struct i2c_device_id wl1273_driver_id_table[] = {
+static const struct i2c_device_id wl1273_driver_id_table[] = {
        { WL1273_FM_DRIVER_NAME, 0 },
        { }
 };
index a5cd17e18d09d93ec582d36f19478c66259e71d2..23e66af89dea12d0871aa44fe2b824e692aee8b3 100644 (file)
@@ -553,17 +553,17 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
        for (cur_irq = wm831x->irq_base;
             cur_irq < ARRAY_SIZE(wm831x_irqs) + wm831x->irq_base;
             cur_irq++) {
-               set_irq_chip_data(cur_irq, wm831x);
-               set_irq_chip_and_handler(cur_irq, &wm831x_irq_chip,
+               irq_set_chip_data(cur_irq, wm831x);
+               irq_set_chip_and_handler(cur_irq, &wm831x_irq_chip,
                                         handle_edge_irq);
-               set_irq_nested_thread(cur_irq, 1);
+               irq_set_nested_thread(cur_irq, 1);
 
                /* ARM needs us to explicitly flag the IRQ as valid
                 * and will set them noprobe when we do so. */
 #ifdef CONFIG_ARM
                set_irq_flags(cur_irq, IRQF_VALID);
 #else
-               set_irq_noprobe(cur_irq);
+               irq_set_noprobe(cur_irq);
 #endif
        }
 
index 5839966ebd85bfbd73b8ee229e0ee666c4b98cd2..ed4b22a167b30104d3628bed7d3ee34753dd867b 100644 (file)
@@ -518,17 +518,17 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq,
        for (cur_irq = wm8350->irq_base;
             cur_irq < ARRAY_SIZE(wm8350_irqs) + wm8350->irq_base;
             cur_irq++) {
-               set_irq_chip_data(cur_irq, wm8350);
-               set_irq_chip_and_handler(cur_irq, &wm8350_irq_chip,
+               irq_set_chip_data(cur_irq, wm8350);
+               irq_set_chip_and_handler(cur_irq, &wm8350_irq_chip,
                                         handle_edge_irq);
-               set_irq_nested_thread(cur_irq, 1);
+               irq_set_nested_thread(cur_irq, 1);
 
                /* ARM needs us to explicitly flag the IRQ as valid
                 * and will set them noprobe when we do so. */
 #ifdef CONFIG_ARM
                set_irq_flags(cur_irq, IRQF_VALID);
 #else
-               set_irq_noprobe(cur_irq);
+               irq_set_noprobe(cur_irq);
 #endif
        }
 
index 1e3bf4a2ff8ef7dbfdd0caab962559c6fe5ed3c3..71c6e8f9aedb47af0fb1ab5d72a48bca872ad6ef 100644 (file)
@@ -278,17 +278,17 @@ int wm8994_irq_init(struct wm8994 *wm8994)
        for (cur_irq = wm8994->irq_base;
             cur_irq < ARRAY_SIZE(wm8994_irqs) + wm8994->irq_base;
             cur_irq++) {
-               set_irq_chip_data(cur_irq, wm8994);
-               set_irq_chip_and_handler(cur_irq, &wm8994_irq_chip,
+               irq_set_chip_data(cur_irq, wm8994);
+               irq_set_chip_and_handler(cur_irq, &wm8994_irq_chip,
                                         handle_edge_irq);
-               set_irq_nested_thread(cur_irq, 1);
+               irq_set_nested_thread(cur_irq, 1);
 
                /* ARM needs us to explicitly flag the IRQ as valid
                 * and will set them noprobe when we do so. */
 #ifdef CONFIG_ARM
                set_irq_flags(cur_irq, IRQF_VALID);
 #else
-               set_irq_noprobe(cur_irq);
+               irq_set_noprobe(cur_irq);
 #endif
        }
 
index 1408bf8eed5f2b811bd22aad529c951f1bcc5c1f..ad1b19aa6508eb58af14a64535dcdcd05d454eb9 100644 (file)
@@ -62,6 +62,24 @@ struct mfd_cell {
 extern int mfd_cell_enable(struct platform_device *pdev);
 extern int mfd_cell_disable(struct platform_device *pdev);
 
+/*
+ * "Clone" multiple platform devices for a single cell. This is to be used
+ * for devices that have multiple users of a cell.  For example, if an mfd
+ * driver wants the cell "foo" to be used by a GPIO driver, an MTD driver,
+ * and a platform driver, the following bit of code would be use after first
+ * calling mfd_add_devices():
+ *
+ * const char *fclones[] = { "foo-gpio", "foo-mtd" };
+ * err = mfd_clone_cells("foo", fclones, ARRAY_SIZE(fclones));
+ *
+ * Each driver (MTD, GPIO, and platform driver) would then register
+ * platform_drivers for "foo-mtd", "foo-gpio", and "foo", respectively.
+ * The cell's .enable/.disable hooks should be used to deal with hardware
+ * resource contention.
+ */
+extern int mfd_clone_cell(const char *cell, const char **clones,
+               size_t n_clones);
+
 /*
  * Given a platform device that's been created by mfd_add_devices(), fetch
  * the mfd_cell that created it.
@@ -87,13 +105,4 @@ extern int mfd_add_devices(struct device *parent, int id,
 
 extern void mfd_remove_devices(struct device *parent);
 
-/*
- * For MFD drivers with clients sharing access to resources, these create
- * multiple platform devices per cell.  Contention handling must still be
- * handled via drivers (ie, with enable/disable hooks).
- */
-extern int mfd_shared_platform_driver_register(struct platform_driver *drv,
-               const char *cellname);
-extern void mfd_shared_platform_driver_unregister(struct platform_driver *drv);
-
 #endif
index 93a9477e075fb723a5901ac9a37884ecad1a25ea..69d1010e2e5146d7cd8d0a1c71cf8c05608024e0 100644 (file)
@@ -24,6 +24,8 @@
 
 #include <linux/i2c.h>
 
+#define MAX8997_REG_INVALID    (0xff)
+
 enum max8997_pmic_reg {
        MAX8997_REG_PMIC_ID0    = 0x00,
        MAX8997_REG_PMIC_ID1    = 0x01,
@@ -313,6 +315,7 @@ enum max8997_irq {
 #define MAX8997_REG_BUCK2DVS(x)        (MAX8997_REG_BUCK2DVS1 + (x) - 1)
 #define MAX8997_REG_BUCK5DVS(x)        (MAX8997_REG_BUCK5DVS1 + (x) - 1)
 
+#define MAX8997_NUM_GPIO       12
 struct max8997_dev {
        struct device *dev;
        struct i2c_client *i2c; /* 0xcc / PMIC, Battery Control, and FLASH */
@@ -324,11 +327,19 @@ struct max8997_dev {
        int type;
        struct platform_device *battery; /* battery control (not fuel gauge) */
 
+       int irq;
+       int ono;
+       int irq_base;
        bool wakeup;
+       struct mutex irqlock;
+       int irq_masks_cur[MAX8997_IRQ_GROUP_NR];
+       int irq_masks_cache[MAX8997_IRQ_GROUP_NR];
 
        /* For hibernation */
        u8 reg_dump[MAX8997_REG_PMIC_END + MAX8997_MUIC_REG_END +
                MAX8997_HAPTIC_REG_END];
+
+       bool gpio_status[MAX8997_NUM_GPIO];
 };
 
 enum max8997_types {
@@ -336,6 +347,10 @@ enum max8997_types {
        TYPE_MAX8966,
 };
 
+extern int max8997_irq_init(struct max8997_dev *max8997);
+extern void max8997_irq_exit(struct max8997_dev *max8997);
+extern int max8997_irq_resume(struct max8997_dev *max8997);
+
 extern int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest);
 extern int max8997_bulk_read(struct i2c_client *i2c, u8 reg, int count,
                                u8 *buf);
@@ -344,4 +359,10 @@ extern int max8997_bulk_write(struct i2c_client *i2c, u8 reg, int count,
                                u8 *buf);
 extern int max8997_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask);
 
+#define MAX8997_GPIO_INT_BOTH  (0x3 << 4)
+#define MAX8997_GPIO_INT_RISE  (0x2 << 4)
+#define MAX8997_GPIO_INT_FALL  (0x1 << 4)
+
+#define MAX8997_GPIO_INT_MASK  (0x3 << 4)
+#define MAX8997_GPIO_DATA_MASK (0x1 << 2)
 #endif /*  __LINUX_MFD_MAX8997_PRIV_H */
index cb671b3451bf8666e046e817d04af6d04e482efa..60931d089422c1add45e93a8a813ebeb69d9835c 100644 (file)
@@ -78,8 +78,11 @@ struct max8997_regulator_data {
 };
 
 struct max8997_platform_data {
-       bool wakeup;
-       /* IRQ: Not implemented */
+       /* IRQ */
+       int irq_base;
+       int ono;
+       int wakeup;
+
        /* ---- PMIC ---- */
        struct max8997_regulator_data *regulators;
        int num_regulators;