linux/arch/sh/boards/mach-highlander/psw.c
<<
>>
Prefs
   1/*
   2 * arch/sh/boards/renesas/r7780rp/psw.c
   3 *
   4 * push switch support for RDBRP-1/RDBREVRP-1 debug boards.
   5 *
   6 * Copyright (C) 2006  Paul Mundt
   7 *
   8 * This file is subject to the terms and conditions of the GNU General Public
   9 * License.  See the file "COPYING" in the main directory of this archive
  10 * for more details.
  11 */
  12#include <linux/io.h>
  13#include <linux/module.h>
  14#include <linux/interrupt.h>
  15#include <linux/platform_device.h>
  16#include <mach/highlander.h>
  17#include <asm/push-switch.h>
  18
  19static irqreturn_t psw_irq_handler(int irq, void *arg)
  20{
  21        struct platform_device *pdev = arg;
  22        struct push_switch *psw = platform_get_drvdata(pdev);
  23        struct push_switch_platform_info *psw_info = pdev->dev.platform_data;
  24        unsigned int l, mask;
  25        int ret = 0;
  26
  27        l = __raw_readw(PA_DBSW);
  28
  29        /* Nothing to do if there's no state change */
  30        if (psw->state) {
  31                ret = 1;
  32                goto out;
  33        }
  34
  35        mask = l & 0x70;
  36        /* Figure out who raised it */
  37        if (mask & (1 << psw_info->bit)) {
  38                psw->state = !!(mask & (1 << psw_info->bit));
  39                if (psw->state) /* debounce */
  40                        mod_timer(&psw->debounce, jiffies + 50);
  41
  42                ret = 1;
  43        }
  44
  45out:
  46        /* Clear the switch IRQs */
  47        l |= (0x7 << 12);
  48        __raw_writew(l, PA_DBSW);
  49
  50        return IRQ_RETVAL(ret);
  51}
  52
  53static struct resource psw_resources[] = {
  54        [0] = {
  55                .start  = IRQ_PSW,
  56                .flags  = IORESOURCE_IRQ,
  57        },
  58};
  59
  60static struct push_switch_platform_info s2_platform_data = {
  61        .name           = "s2",
  62        .bit            = 6,
  63        .irq_flags      = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
  64                          IRQF_SHARED,
  65        .irq_handler    = psw_irq_handler,
  66};
  67
  68static struct platform_device s2_switch_device = {
  69        .name           = "push-switch",
  70        .id             = 0,
  71        .num_resources  = ARRAY_SIZE(psw_resources),
  72        .resource       = psw_resources,
  73        .dev            = {
  74                .platform_data = &s2_platform_data,
  75        },
  76};
  77
  78static struct push_switch_platform_info s3_platform_data = {
  79        .name           = "s3",
  80        .bit            = 5,
  81        .irq_flags      = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
  82                          IRQF_SHARED,
  83        .irq_handler    = psw_irq_handler,
  84};
  85
  86static struct platform_device s3_switch_device = {
  87        .name           = "push-switch",
  88        .id             = 1,
  89        .num_resources  = ARRAY_SIZE(psw_resources),
  90        .resource       = psw_resources,
  91        .dev            = {
  92                .platform_data = &s3_platform_data,
  93        },
  94};
  95
  96static struct push_switch_platform_info s4_platform_data = {
  97        .name           = "s4",
  98        .bit            = 4,
  99        .irq_flags      = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
 100                          IRQF_SHARED,
 101        .irq_handler    = psw_irq_handler,
 102};
 103
 104static struct platform_device s4_switch_device = {
 105        .name           = "push-switch",
 106        .id             = 2,
 107        .num_resources  = ARRAY_SIZE(psw_resources),
 108        .resource       = psw_resources,
 109        .dev            = {
 110                .platform_data = &s4_platform_data,
 111        },
 112};
 113
 114static struct platform_device *psw_devices[] = {
 115        &s2_switch_device, &s3_switch_device, &s4_switch_device,
 116};
 117
 118static int __init psw_init(void)
 119{
 120        return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices));
 121}
 122module_init(psw_init);
 123