~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/sh/boards/mach-x3proto/gpio.c

Version: ~ [ linux-5.11-rc3 ] ~ [ linux-5.10.7 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.89 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.167 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.215 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.251 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.251 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * arch/sh/boards/mach-x3proto/gpio.c
  3  *
  4  * Renesas SH-X3 Prototype Baseboard GPIO Support.
  5  *
  6  * Copyright (C) 2010 - 2012  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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 13 
 14 #include <linux/init.h>
 15 #include <linux/interrupt.h>
 16 #include <linux/gpio/driver.h>
 17 #include <linux/irq.h>
 18 #include <linux/kernel.h>
 19 #include <linux/spinlock.h>
 20 #include <linux/irqdomain.h>
 21 #include <linux/io.h>
 22 #include <mach/ilsel.h>
 23 #include <mach/hardware.h>
 24 
 25 #define KEYCTLR 0xb81c0000
 26 #define KEYOUTR 0xb81c0002
 27 #define KEYDETR 0xb81c0004
 28 
 29 static DEFINE_SPINLOCK(x3proto_gpio_lock);
 30 static struct irq_domain *x3proto_irq_domain;
 31 
 32 static int x3proto_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
 33 {
 34         unsigned long flags;
 35         unsigned int data;
 36 
 37         spin_lock_irqsave(&x3proto_gpio_lock, flags);
 38         data = __raw_readw(KEYCTLR);
 39         data |= (1 << gpio);
 40         __raw_writew(data, KEYCTLR);
 41         spin_unlock_irqrestore(&x3proto_gpio_lock, flags);
 42 
 43         return 0;
 44 }
 45 
 46 static int x3proto_gpio_get(struct gpio_chip *chip, unsigned gpio)
 47 {
 48         return !!(__raw_readw(KEYDETR) & (1 << gpio));
 49 }
 50 
 51 static int x3proto_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
 52 {
 53         int virq;
 54 
 55         if (gpio < chip->ngpio)
 56                 virq = irq_create_mapping(x3proto_irq_domain, gpio);
 57         else
 58                 virq = -ENXIO;
 59 
 60         return virq;
 61 }
 62 
 63 static void x3proto_gpio_irq_handler(struct irq_desc *desc)
 64 {
 65         struct irq_data *data = irq_desc_get_irq_data(desc);
 66         struct irq_chip *chip = irq_data_get_irq_chip(data);
 67         unsigned long mask;
 68         int pin;
 69 
 70         chip->irq_mask_ack(data);
 71 
 72         mask = __raw_readw(KEYDETR);
 73         for_each_set_bit(pin, &mask, NR_BASEBOARD_GPIOS)
 74                 generic_handle_irq(irq_linear_revmap(x3proto_irq_domain, pin));
 75 
 76         chip->irq_unmask(data);
 77 }
 78 
 79 struct gpio_chip x3proto_gpio_chip = {
 80         .label                  = "x3proto-gpio",
 81         .direction_input        = x3proto_gpio_direction_input,
 82         .get                    = x3proto_gpio_get,
 83         .to_irq                 = x3proto_gpio_to_irq,
 84         .base                   = -1,
 85         .ngpio                  = NR_BASEBOARD_GPIOS,
 86 };
 87 
 88 static int x3proto_gpio_irq_map(struct irq_domain *domain, unsigned int virq,
 89                                 irq_hw_number_t hwirq)
 90 {
 91         irq_set_chip_and_handler_name(virq, &dummy_irq_chip, handle_simple_irq,
 92                                       "gpio");
 93 
 94         return 0;
 95 }
 96 
 97 static struct irq_domain_ops x3proto_gpio_irq_ops = {
 98         .map    = x3proto_gpio_irq_map,
 99         .xlate  = irq_domain_xlate_twocell,
100 };
101 
102 int __init x3proto_gpio_setup(void)
103 {
104         int ilsel, ret;
105 
106         ilsel = ilsel_enable(ILSEL_KEY);
107         if (unlikely(ilsel < 0))
108                 return ilsel;
109 
110         ret = gpiochip_add_data(&x3proto_gpio_chip, NULL);
111         if (unlikely(ret))
112                 goto err_gpio;
113 
114         x3proto_irq_domain = irq_domain_add_linear(NULL, NR_BASEBOARD_GPIOS,
115                                                    &x3proto_gpio_irq_ops, NULL);
116         if (unlikely(!x3proto_irq_domain))
117                 goto err_irq;
118 
119         pr_info("registering '%s' support, handling GPIOs %u -> %u, "
120                 "bound to IRQ %u\n",
121                 x3proto_gpio_chip.label, x3proto_gpio_chip.base,
122                 x3proto_gpio_chip.base + x3proto_gpio_chip.ngpio,
123                 ilsel);
124 
125         irq_set_chained_handler(ilsel, x3proto_gpio_irq_handler);
126         irq_set_irq_wake(ilsel, 1);
127 
128         return 0;
129 
130 err_irq:
131         gpiochip_remove(&x3proto_gpio_chip);
132         ret = 0;
133 err_gpio:
134         synchronize_irq(ilsel);
135 
136         ilsel_disable(ILSEL_KEY);
137 
138         return ret;
139 }
140 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp