ipmi_si: Move irq setup handling into the io struct
authorCorey Minyard <cminyard@mvista.com>
Tue, 12 Sep 2017 20:10:22 +0000 (15:10 -0500)
committerCorey Minyard <cminyard@mvista.com>
Wed, 27 Sep 2017 21:03:45 +0000 (16:03 -0500)
So the platform code can do it without having to access the
smi info, getting ready for pulling the platform handling
section to their own files.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
drivers/char/ipmi/ipmi_si.h
drivers/char/ipmi/ipmi_si_intf.c
drivers/char/ipmi/ipmi_si_sm.h

index a4d993b..e84651a 100644 (file)
@@ -5,6 +5,7 @@
  * etc) to the base ipmi system interface code.
  */
 
+#include <linux/interrupt.h>
 #include "ipmi_si_sm.h"
 
 #define IPMI_IO_ADDR_SPACE  0
@@ -16,3 +17,7 @@
 struct smi_info;
 
 int ipmi_si_add_smi(struct smi_info *info);
+irqreturn_t ipmi_si_irq_handler(int irq, void *data);
+void ipmi_irq_start_cleanup(struct si_sm_io *io);
+int ipmi_std_irq_setup(struct si_sm_io *io);
+void ipmi_irq_finish_setup(struct si_sm_io *io);
index 8cc101e..4b832b9 100644 (file)
@@ -175,8 +175,6 @@ struct smi_info {
        struct si_sm_io io;
        int (*io_setup)(struct smi_info *info);
        void (*io_cleanup)(struct smi_info *info);
-       int (*irq_setup)(struct smi_info *info);
-       void (*irq_cleanup)(struct smi_info *info);
        unsigned int io_size;
 
        /*
@@ -1177,11 +1175,17 @@ do_mod_timer:
        spin_unlock_irqrestore(&(smi_info->si_lock), flags);
 }
 
-static irqreturn_t si_irq_handler(int irq, void *data)
+irqreturn_t ipmi_si_irq_handler(int irq, void *data)
 {
        struct smi_info *smi_info = data;
        unsigned long   flags;
 
+       if (smi_info->io.si_type == SI_BT)
+               /* We need to clear the IRQ flag for the BT interface. */
+               smi_info->io.outputb(&smi_info->io, IPMI_BT_INTMASK_REG,
+                                    IPMI_BT_INTMASK_CLEAR_IRQ_BIT
+                                    | IPMI_BT_INTMASK_ENABLE_IRQ_BIT);
+
        spin_lock_irqsave(&(smi_info->si_lock), flags);
 
        smi_inc_stat(smi_info, interrupts);
@@ -1193,16 +1197,6 @@ static irqreturn_t si_irq_handler(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-static irqreturn_t si_bt_irq_handler(int irq, void *data)
-{
-       struct smi_info *smi_info = data;
-       /* We need to clear the IRQ flag for the BT interface. */
-       smi_info->io.outputb(&smi_info->io, IPMI_BT_INTMASK_REG,
-                            IPMI_BT_INTMASK_CLEAR_IRQ_BIT
-                            | IPMI_BT_INTMASK_ENABLE_IRQ_BIT);
-       return si_irq_handler(irq, data);
-}
-
 static int smi_start_processing(void       *send_info,
                                ipmi_smi_t intf)
 {
@@ -1216,8 +1210,10 @@ static int smi_start_processing(void       *send_info,
        smi_mod_timer(new_smi, jiffies + SI_TIMEOUT_JIFFIES);
 
        /* Try to claim any interrupts. */
-       if (new_smi->irq_setup)
-               new_smi->irq_setup(new_smi);
+       if (new_smi->io.irq_setup) {
+               new_smi->io.irq_handler_data = new_smi;
+               new_smi->io.irq_setup(&new_smi->io);
+       }
 
        /*
         * Check if the user forcefully enabled the daemon.
@@ -1400,46 +1396,48 @@ MODULE_PARM_DESC(kipmid_max_busy_us,
                 " sleeping. 0 (default) means to wait forever. Set to 100-500"
                 " if kipmid is using up a lot of CPU time.");
 
+void ipmi_irq_finish_setup(struct si_sm_io *io)
+{
+       if (io->si_type == SI_BT)
+               /* Enable the interrupt in the BT interface. */
+               io->outputb(io, IPMI_BT_INTMASK_REG,
+                           IPMI_BT_INTMASK_ENABLE_IRQ_BIT);
+}
 
-static void std_irq_cleanup(struct smi_info *info)
+void ipmi_irq_start_cleanup(struct si_sm_io *io)
 {
-       if (info->io.si_type == SI_BT)
+       if (io->si_type == SI_BT)
                /* Disable the interrupt in the BT interface. */
-               info->io.outputb(&info->io, IPMI_BT_INTMASK_REG, 0);
-       free_irq(info->io.irq, info);
+               io->outputb(io, IPMI_BT_INTMASK_REG, 0);
+}
+
+static void std_irq_cleanup(struct si_sm_io *io)
+{
+       ipmi_irq_start_cleanup(io);
+       free_irq(io->irq, io->irq_handler_data);
 }
 
-static int std_irq_setup(struct smi_info *info)
+int ipmi_std_irq_setup(struct si_sm_io *io)
 {
        int rv;
 
-       if (!info->io.irq)
+       if (!io->irq)
                return 0;
 
-       if (info->io.si_type == SI_BT) {
-               rv = request_irq(info->io.irq,
-                                si_bt_irq_handler,
-                                IRQF_SHARED,
-                                DEVICE_NAME,
-                                info);
-               if (!rv)
-                       /* Enable the interrupt in the BT interface. */
-                       info->io.outputb(&info->io, IPMI_BT_INTMASK_REG,
-                                        IPMI_BT_INTMASK_ENABLE_IRQ_BIT);
-       } else
-               rv = request_irq(info->io.irq,
-                                si_irq_handler,
-                                IRQF_SHARED,
-                                DEVICE_NAME,
-                                info);
+       rv = request_irq(io->irq,
+                        ipmi_si_irq_handler,
+                        IRQF_SHARED,
+                        DEVICE_NAME,
+                        io->irq_handler_data);
        if (rv) {
-               dev_warn(info->io.dev, "%s unable to claim interrupt %d,"
+               dev_warn(io->dev, "%s unable to claim interrupt %d,"
                         " running polled\n",
-                        DEVICE_NAME, info->io.irq);
-               info->io.irq = 0;
+                        DEVICE_NAME, io->irq);
+               io->irq = 0;
        } else {
-               info->irq_cleanup = std_irq_cleanup;
-               dev_info(info->io.dev, "Using irq %d\n", info->io.irq);
+               io->irq_cleanup = std_irq_cleanup;
+               ipmi_irq_finish_setup(io);
+               dev_info(io->dev, "Using irq %d\n", io->irq);
        }
 
        return rv;
@@ -1920,7 +1918,7 @@ static int hotmod_handler(const char *val, struct kernel_param *kp)
                        info->io.regshift = regshift;
                        info->io.irq = irq;
                        if (info->io.irq)
-                               info->irq_setup = std_irq_setup;
+                               info->io.irq_setup = ipmi_std_irq_setup;
                        info->io.slave_addr = ipmb;
 
                        rv = ipmi_si_add_smi(info);
@@ -2014,7 +2012,7 @@ static int hardcode_find_bmc(void)
                info->io.regshift = regshifts[i];
                info->io.irq = irqs[i];
                if (info->io.irq)
-                       info->irq_setup = std_irq_setup;
+                       info->io.irq_setup = ipmi_std_irq_setup;
                info->io.slave_addr = slave_addrs[i];
 
                if (!ipmi_si_add_smi(info)) {
@@ -2043,49 +2041,43 @@ static int acpi_failure;
 static u32 ipmi_acpi_gpe(acpi_handle gpe_device,
        u32 gpe_number, void *context)
 {
-       struct smi_info *smi_info = context;
-       unsigned long   flags;
-
-       spin_lock_irqsave(&(smi_info->si_lock), flags);
-
-       smi_inc_stat(smi_info, interrupts);
-
-       debug_timestamp("ACPI_GPE");
-
-       smi_event_handler(smi_info, 0);
-       spin_unlock_irqrestore(&(smi_info->si_lock), flags);
+       struct si_sm_io *io = context;
 
+       ipmi_si_irq_handler(io->irq, io->irq_handler_data);
        return ACPI_INTERRUPT_HANDLED;
 }
 
-static void acpi_gpe_irq_cleanup(struct smi_info *info)
+static void acpi_gpe_irq_cleanup(struct si_sm_io *io)
 {
-       if (!info->io.irq)
+       if (!io->irq)
                return;
 
-       acpi_remove_gpe_handler(NULL, info->io.irq, &ipmi_acpi_gpe);
+       ipmi_irq_start_cleanup(io);
+       acpi_remove_gpe_handler(NULL, io->irq, &ipmi_acpi_gpe);
 }
 
-static int acpi_gpe_irq_setup(struct smi_info *info)
+static int acpi_gpe_irq_setup(struct si_sm_io *io)
 {
        acpi_status status;
 
-       if (!info->io.irq)
+       if (!io->irq)
                return 0;
 
        status = acpi_install_gpe_handler(NULL,
-                                         info->io.irq,
+                                         io->irq,
                                          ACPI_GPE_LEVEL_TRIGGERED,
                                          &ipmi_acpi_gpe,
-                                         info);
+                                         io);
        if (status != AE_OK) {
-               dev_warn(info->io.dev, "%s unable to claim ACPI GPE %d,"
-                        " running polled\n", DEVICE_NAME, info->io.irq);
-               info->io.irq = 0;
+               dev_warn(io->dev,
+                        "Unable to claim ACPI GPE %d, running polled\n",
+                        io->irq);
+               io->irq = 0;
                return -EINVAL;
        } else {
-               info->irq_cleanup = acpi_gpe_irq_cleanup;
-               dev_info(info->io.dev, "Using ACPI GPE %d\n", info->io.irq);
+               io->irq_cleanup = acpi_gpe_irq_cleanup;
+               ipmi_irq_finish_setup(io);
+               dev_info(io->dev, "Using ACPI GPE %d\n", io->irq);
                return 0;
        }
 }
@@ -2179,15 +2171,15 @@ static int try_init_spmi(struct SPMITable *spmi)
        if (spmi->InterruptType & 1) {
                /* We've got a GPE interrupt. */
                info->io.irq = spmi->GPE;
-               info->irq_setup = acpi_gpe_irq_setup;
+               info->io.irq_setup = acpi_gpe_irq_setup;
        } else if (spmi->InterruptType & 2) {
                /* We've got an APIC/SAPIC interrupt. */
                info->io.irq = spmi->GlobalSystemInterrupt;
-               info->irq_setup = std_irq_setup;
+               info->io.irq_setup = ipmi_std_irq_setup;
        } else {
                /* Use the default interrupt setting. */
                info->io.irq = 0;
-               info->irq_setup = NULL;
+               info->io.irq_setup = NULL;
        }
 
        if (spmi->addr.bit_width) {
@@ -2342,7 +2334,7 @@ static int dmi_ipmi_probe(struct platform_device *pdev)
 
        info->io.irq = platform_get_irq(pdev, 0);
        if (info->io.irq > 0)
-               info->irq_setup = std_irq_setup;
+               info->io.irq_setup = ipmi_std_irq_setup;
        else
                info->io.irq = 0;
 
@@ -2479,7 +2471,7 @@ static int ipmi_pci_probe(struct pci_dev *pdev,
 
        info->io.irq = pdev->irq;
        if (info->io.irq)
-               info->irq_setup = std_irq_setup;
+               info->io.irq_setup = ipmi_std_irq_setup;
 
        info->io.dev = &pdev->dev;
        pci_set_drvdata(pdev, info);
@@ -2583,7 +2575,7 @@ static int of_ipmi_probe(struct platform_device *pdev)
 
        info->io.si_type        = (enum si_type) match->data;
        info->io.addr_source    = SI_DEVICETREE;
-       info->io.irq_setup      = std_irq_setup;
+       info->io.irq_setup      = ipmi_std_irq_setup;
 
        if (resource.flags & IORESOURCE_IO) {
                info->io_setup          = port_setup;
@@ -2715,13 +2707,13 @@ static int acpi_ipmi_probe(struct platform_device *pdev)
        status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp);
        if (ACPI_SUCCESS(status)) {
                info->io.irq = tmp;
-               info->irq_setup = acpi_gpe_irq_setup;
+               info->io.irq_setup = acpi_gpe_irq_setup;
        } else {
                int irq = platform_get_irq(pdev, 0);
 
                if (irq > 0) {
                        info->io.irq = irq;
-                       info->irq_setup = std_irq_setup;
+                       info->io.irq_setup = ipmi_std_irq_setup;
                }
        }
 
@@ -2809,7 +2801,7 @@ static int __init ipmi_parisc_probe(struct parisc_device *dev)
        info->io.regspacing     = 1;
        info->io.regshift       = 0;
        info->io.irq            = 0; /* no interrupt */
-       info->irq_setup         = NULL;
+       info->io.irq_setup      = NULL;
        info->io.dev            = &dev->dev;
 
        dev_dbg(&dev->dev, "addr 0x%lx\n", info->io.addr_data);
@@ -3665,9 +3657,9 @@ out_err:
                ipmi_unregister_smi(intf);
        }
 
-       if (new_smi->irq_cleanup) {
-               new_smi->irq_cleanup(new_smi);
-               new_smi->irq_cleanup = NULL;
+       if (new_smi->io.irq_cleanup) {
+               new_smi->io.irq_cleanup(&new_smi->io);
+               new_smi->io.irq_cleanup = NULL;
        }
 
        /*
@@ -3842,8 +3834,8 @@ static void cleanup_one_si(struct smi_info *to_clean)
         * Make sure that interrupts, the timer and the thread are
         * stopped and will not run again.
         */
-       if (to_clean->irq_cleanup)
-               to_clean->irq_cleanup(to_clean);
+       if (to_clean->io.irq_cleanup)
+               to_clean->io.irq_cleanup(&to_clean->io);
        wait_for_timer_and_thread(to_clean);
 
        /*
index ffbf67f..bf3f50c 100644 (file)
@@ -72,6 +72,10 @@ struct si_sm_io {
        void *addr_source_data;
 
        int irq;
+       int (*irq_setup)(struct si_sm_io *io);
+       void *irq_handler_data;
+       void (*irq_cleanup)(struct si_sm_io *io);
+
        u8 slave_addr;
        enum si_type si_type;
        struct device *dev;