149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA/* 249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. 349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * 449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * This program is free software; you can redistribute it and/or modify 549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * it under the terms of the GNU General Public License as published by 649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * the Free Software Foundation; version 2 of the License. 749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * 849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * This program is distributed in the hope that it will be useful, 949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * but WITHOUT ANY WARRANTY; without even the implied warranty of 1049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * GNU General Public License for more details. 1249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * 1349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * You should have received a copy of the GNU General Public License 1449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * along with this program; if not, write to the Free Software 1549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 1649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA */ 17bb207ef1e84ffc4afe89f3a5b84788bac0f968e7Paul Gortmaker#include <linux/module.h> 1849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA#include <linux/kernel.h> 19545554e7c5bb93bfbf134f9f12889701c0aadf97Andrew Morton#include <linux/slab.h> 2049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA#include <linux/pci.h> 2149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA#include <linux/gpio.h> 2254be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA#include <linux/interrupt.h> 2354be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA#include <linux/irq.h> 2454be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 2554be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA#define IOH_EDGE_FALLING 0 2654be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA#define IOH_EDGE_RISING BIT(0) 2754be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA#define IOH_LEVEL_L BIT(1) 2854be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA#define IOH_LEVEL_H (BIT(0) | BIT(1)) 2954be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA#define IOH_EDGE_BOTH BIT(2) 3054be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA#define IOH_IM_MASK (BIT(0) | BIT(1) | BIT(2)) 3154be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 3254be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA#define IOH_IRQ_BASE 0 3349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 3449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA#define PCI_VENDOR_ID_ROHM 0x10DB 3549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 3649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAstruct ioh_reg_comn { 3749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 ien; 3849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 istatus; 3949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 idisp; 4049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 iclr; 4149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 imask; 4249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 imaskclr; 4349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 po; 4449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 pi; 4549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 pm; 4649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 im_0; 4749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 im_1; 4849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 reserved; 4949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA}; 5049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 5149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAstruct ioh_regs { 5249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA struct ioh_reg_comn regs[8]; 5349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 reserve1[16]; 5449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 ioh_sel_reg[4]; 5549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 reserve2[11]; 5649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 srst; 5749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA}; 5849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 5949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA/** 6049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * struct ioh_gpio_reg_data - The register store data. 6154be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA * @ien_reg To store contents of interrupt enable register. 6254be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA * @imask_reg: To store contents of interrupt mask regist 6349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * @po_reg: To store contents of PO register. 6449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * @pm_reg: To store contents of PM register. 6554be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA * @im0_reg: To store contents of interrupt mode regist0 6654be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA * @im1_reg: To store contents of interrupt mode regist1 67b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA * @use_sel_reg: To store contents of GPIO_USE_SEL0~3 6849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA */ 6949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAstruct ioh_gpio_reg_data { 7054be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA u32 ien_reg; 7154be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA u32 imask_reg; 7249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 po_reg; 7349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 pm_reg; 7454be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA u32 im0_reg; 7554be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA u32 im1_reg; 76b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA u32 use_sel_reg; 7749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA}; 7849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 7949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA/** 8049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * struct ioh_gpio - GPIO private data structure. 8149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * @base: PCI base address of Memory mapped I/O register. 8249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * @reg: Memory mapped IOH GPIO register list. 8349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * @dev: Pointer to device structure. 8449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * @gpio: Data for GPIO infrastructure. 8549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * @ioh_gpio_reg: Memory mapped Register data is saved here 8649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * when suspend. 87b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA * @gpio_use_sel: Save GPIO_USE_SEL1~4 register for PM 8849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * @ch: Indicate GPIO channel 8954be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA * @irq_base: Save base of IRQ number for interrupt 9002a6794d57ce54b96b13db80831f35d66e0caf31Axel Lin * @spinlock: Used for register access protection 9149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA */ 9249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAstruct ioh_gpio { 9349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA void __iomem *base; 9449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA struct ioh_regs __iomem *reg; 9549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA struct device *dev; 9649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA struct gpio_chip gpio; 9749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA struct ioh_gpio_reg_data ioh_gpio_reg; 98b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA u32 gpio_use_sel; 9949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA int ch; 10054be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA int irq_base; 10154be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA spinlock_t spinlock; 10249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA}; 10349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 10449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAstatic const int num_ports[] = {6, 12, 16, 16, 15, 16, 16, 12}; 10549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 10649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAstatic void ioh_gpio_set(struct gpio_chip *gpio, unsigned nr, int val) 10749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA{ 10849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 reg_val; 10949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio); 11002a6794d57ce54b96b13db80831f35d66e0caf31Axel Lin unsigned long flags; 11149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 11202a6794d57ce54b96b13db80831f35d66e0caf31Axel Lin spin_lock_irqsave(&chip->spinlock, flags); 11349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA reg_val = ioread32(&chip->reg->regs[chip->ch].po); 11449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA if (val) 11549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA reg_val |= (1 << nr); 11649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA else 11749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA reg_val &= ~(1 << nr); 11849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 11949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA iowrite32(reg_val, &chip->reg->regs[chip->ch].po); 12002a6794d57ce54b96b13db80831f35d66e0caf31Axel Lin spin_unlock_irqrestore(&chip->spinlock, flags); 12149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA} 12249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 12349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAstatic int ioh_gpio_get(struct gpio_chip *gpio, unsigned nr) 12449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA{ 12549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio); 12649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 12749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA return ioread32(&chip->reg->regs[chip->ch].pi) & (1 << nr); 12849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA} 12949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 13049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAstatic int ioh_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, 13149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA int val) 13249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA{ 13349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio); 13449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 pm; 13549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 reg_val; 13602a6794d57ce54b96b13db80831f35d66e0caf31Axel Lin unsigned long flags; 13749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 13802a6794d57ce54b96b13db80831f35d66e0caf31Axel Lin spin_lock_irqsave(&chip->spinlock, flags); 13949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA pm = ioread32(&chip->reg->regs[chip->ch].pm) & 14049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA ((1 << num_ports[chip->ch]) - 1); 14149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA pm |= (1 << nr); 14249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA iowrite32(pm, &chip->reg->regs[chip->ch].pm); 14349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 14449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA reg_val = ioread32(&chip->reg->regs[chip->ch].po); 14549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA if (val) 14649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA reg_val |= (1 << nr); 14749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA else 14849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA reg_val &= ~(1 << nr); 149ba43861277f1858472de4adfc0b28a047484da83Peter Tyser iowrite32(reg_val, &chip->reg->regs[chip->ch].po); 15049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 15102a6794d57ce54b96b13db80831f35d66e0caf31Axel Lin spin_unlock_irqrestore(&chip->spinlock, flags); 15249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 15349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA return 0; 15449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA} 15549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 15649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAstatic int ioh_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) 15749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA{ 15849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio); 15949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA u32 pm; 16002a6794d57ce54b96b13db80831f35d66e0caf31Axel Lin unsigned long flags; 16149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 16202a6794d57ce54b96b13db80831f35d66e0caf31Axel Lin spin_lock_irqsave(&chip->spinlock, flags); 16349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA pm = ioread32(&chip->reg->regs[chip->ch].pm) & 16449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA ((1 << num_ports[chip->ch]) - 1); 16549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA pm &= ~(1 << nr); 16649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA iowrite32(pm, &chip->reg->regs[chip->ch].pm); 16702a6794d57ce54b96b13db80831f35d66e0caf31Axel Lin spin_unlock_irqrestore(&chip->spinlock, flags); 16849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 16949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA return 0; 17049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA} 17149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 172545554e7c5bb93bfbf134f9f12889701c0aadf97Andrew Morton#ifdef CONFIG_PM 17349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA/* 17449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * Save register configuration and disable interrupts. 17549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA */ 17649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAstatic void ioh_gpio_save_reg_conf(struct ioh_gpio *chip) 17749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA{ 178b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA int i; 179b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA 180b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA for (i = 0; i < 8; i ++, chip++) { 181b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA chip->ioh_gpio_reg.po_reg = 182b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA ioread32(&chip->reg->regs[chip->ch].po); 183b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA chip->ioh_gpio_reg.pm_reg = 184b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA ioread32(&chip->reg->regs[chip->ch].pm); 185b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA chip->ioh_gpio_reg.ien_reg = 186b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA ioread32(&chip->reg->regs[chip->ch].ien); 187b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA chip->ioh_gpio_reg.imask_reg = 188b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA ioread32(&chip->reg->regs[chip->ch].imask); 189b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA chip->ioh_gpio_reg.im0_reg = 190b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA ioread32(&chip->reg->regs[chip->ch].im_0); 191b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA chip->ioh_gpio_reg.im1_reg = 192b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA ioread32(&chip->reg->regs[chip->ch].im_1); 193b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA if (i < 4) 194b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA chip->ioh_gpio_reg.use_sel_reg = 195b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA ioread32(&chip->reg->ioh_sel_reg[i]); 196b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA } 19749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA} 19849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 19949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA/* 20049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA * This function restores the register configuration of the GPIO device. 20149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA */ 20249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAstatic void ioh_gpio_restore_reg_conf(struct ioh_gpio *chip) 20349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA{ 204b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA int i; 205b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA 206b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA for (i = 0; i < 8; i ++, chip++) { 207b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA iowrite32(chip->ioh_gpio_reg.po_reg, 208b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA &chip->reg->regs[chip->ch].po); 209b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA iowrite32(chip->ioh_gpio_reg.pm_reg, 210b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA &chip->reg->regs[chip->ch].pm); 211b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA iowrite32(chip->ioh_gpio_reg.ien_reg, 212b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA &chip->reg->regs[chip->ch].ien); 213b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA iowrite32(chip->ioh_gpio_reg.imask_reg, 214b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA &chip->reg->regs[chip->ch].imask); 215b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA iowrite32(chip->ioh_gpio_reg.im0_reg, 216b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA &chip->reg->regs[chip->ch].im_0); 217b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA iowrite32(chip->ioh_gpio_reg.im1_reg, 218b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA &chip->reg->regs[chip->ch].im_1); 219b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA if (i < 4) 220b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA iowrite32(chip->ioh_gpio_reg.use_sel_reg, 221b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA &chip->reg->ioh_sel_reg[i]); 222b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA } 22349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA} 224545554e7c5bb93bfbf134f9f12889701c0aadf97Andrew Morton#endif 22549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 22654be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGAstatic int ioh_gpio_to_irq(struct gpio_chip *gpio, unsigned offset) 22754be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA{ 22854be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio); 22954be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA return chip->irq_base + offset; 23054be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA} 23154be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 23249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAstatic void ioh_gpio_setup(struct ioh_gpio *chip, int num_port) 23349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA{ 23449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA struct gpio_chip *gpio = &chip->gpio; 23549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 23649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA gpio->label = dev_name(chip->dev); 23749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA gpio->owner = THIS_MODULE; 23849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA gpio->direction_input = ioh_gpio_direction_input; 23949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA gpio->get = ioh_gpio_get; 24049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA gpio->direction_output = ioh_gpio_direction_output; 24149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA gpio->set = ioh_gpio_set; 24249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA gpio->dbg_show = NULL; 24349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA gpio->base = -1; 24449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA gpio->ngpio = num_port; 2459fb1f39eb2d6707d265087ee186376e24995f55aLinus Walleij gpio->can_sleep = false; 24654be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA gpio->to_irq = ioh_gpio_to_irq; 24754be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA} 24854be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 24954be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGAstatic int ioh_irq_type(struct irq_data *d, unsigned int type) 25054be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA{ 25154be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA u32 im; 252dd9328a6b026060699d4136d8f926e39281c8a18Márton Németh void __iomem *im_reg; 25354be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA u32 ien; 25454be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA u32 im_pos; 25554be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA int ch; 25654be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA unsigned long flags; 25754be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA u32 val; 25854be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA int irq = d->irq; 25954be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 26054be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA struct ioh_gpio *chip = gc->private; 26154be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 26254be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA ch = irq - chip->irq_base; 26354be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA if (irq <= chip->irq_base + 7) { 26454be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA im_reg = &chip->reg->regs[chip->ch].im_0; 26554be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA im_pos = ch; 26654be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA } else { 26754be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA im_reg = &chip->reg->regs[chip->ch].im_1; 26854be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA im_pos = ch - 8; 26954be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA } 27054be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA dev_dbg(chip->dev, "%s:irq=%d type=%d ch=%d pos=%d type=%d\n", 27154be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA __func__, irq, type, ch, im_pos, type); 27254be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 27354be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA spin_lock_irqsave(&chip->spinlock, flags); 27454be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 27554be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA switch (type) { 27654be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA case IRQ_TYPE_EDGE_RISING: 27754be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA val = IOH_EDGE_RISING; 27854be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA break; 27954be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA case IRQ_TYPE_EDGE_FALLING: 28054be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA val = IOH_EDGE_FALLING; 28154be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA break; 28254be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA case IRQ_TYPE_EDGE_BOTH: 28354be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA val = IOH_EDGE_BOTH; 28454be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA break; 28554be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA case IRQ_TYPE_LEVEL_HIGH: 28654be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA val = IOH_LEVEL_H; 28754be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA break; 28854be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA case IRQ_TYPE_LEVEL_LOW: 28954be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA val = IOH_LEVEL_L; 29054be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA break; 29154be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA case IRQ_TYPE_PROBE: 29254be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA goto end; 29354be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA default: 29454be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA dev_warn(chip->dev, "%s: unknown type(%dd)", 29554be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA __func__, type); 29654be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA goto end; 29754be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA } 29854be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 29954be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA /* Set interrupt mode */ 30054be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA im = ioread32(im_reg) & ~(IOH_IM_MASK << (im_pos * 4)); 30154be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA iowrite32(im | (val << (im_pos * 4)), im_reg); 30254be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 30354be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA /* iclr */ 30454be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA iowrite32(BIT(ch), &chip->reg->regs[chip->ch].iclr); 30554be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 30654be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA /* IMASKCLR */ 30754be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA iowrite32(BIT(ch), &chip->reg->regs[chip->ch].imaskclr); 30854be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 30954be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA /* Enable interrupt */ 31054be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA ien = ioread32(&chip->reg->regs[chip->ch].ien); 31154be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA iowrite32(ien | BIT(ch), &chip->reg->regs[chip->ch].ien); 31254be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGAend: 31354be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA spin_unlock_irqrestore(&chip->spinlock, flags); 31454be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 31554be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA return 0; 31654be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA} 31754be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 31854be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGAstatic void ioh_irq_unmask(struct irq_data *d) 31954be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA{ 32054be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 32154be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA struct ioh_gpio *chip = gc->private; 32254be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 32354be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA iowrite32(1 << (d->irq - chip->irq_base), 32454be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA &chip->reg->regs[chip->ch].imaskclr); 32554be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA} 32654be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 32754be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGAstatic void ioh_irq_mask(struct irq_data *d) 32854be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA{ 32954be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 33054be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA struct ioh_gpio *chip = gc->private; 33154be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 33254be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA iowrite32(1 << (d->irq - chip->irq_base), 33354be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA &chip->reg->regs[chip->ch].imask); 33454be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA} 33554be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 3364d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tangstatic void ioh_irq_disable(struct irq_data *d) 3374d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang{ 3384d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 3394d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang struct ioh_gpio *chip = gc->private; 3404d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang unsigned long flags; 3414d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang u32 ien; 3424d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang 3434d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang spin_lock_irqsave(&chip->spinlock, flags); 3444d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang ien = ioread32(&chip->reg->regs[chip->ch].ien); 3454d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang ien &= ~(1 << (d->irq - chip->irq_base)); 3464d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang iowrite32(ien, &chip->reg->regs[chip->ch].ien); 3474d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang spin_unlock_irqrestore(&chip->spinlock, flags); 3484d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang} 3494d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang 3504d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tangstatic void ioh_irq_enable(struct irq_data *d) 3514d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang{ 3524d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 3534d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang struct ioh_gpio *chip = gc->private; 3544d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang unsigned long flags; 3554d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang u32 ien; 3564d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang 3574d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang spin_lock_irqsave(&chip->spinlock, flags); 3584d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang ien = ioread32(&chip->reg->regs[chip->ch].ien); 3594d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang ien |= 1 << (d->irq - chip->irq_base); 3604d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang iowrite32(ien, &chip->reg->regs[chip->ch].ien); 3614d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang spin_unlock_irqrestore(&chip->spinlock, flags); 3624d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang} 3634d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang 36454be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGAstatic irqreturn_t ioh_gpio_handler(int irq, void *dev_id) 36554be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA{ 36654be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA struct ioh_gpio *chip = dev_id; 36754be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA u32 reg_val; 36854be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA int i, j; 36954be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA int ret = IRQ_NONE; 37054be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 371f9ea14efa5277c47efec341dee2c408b6b80f854Feng Tang for (i = 0; i < 8; i++, chip++) { 37254be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA reg_val = ioread32(&chip->reg->regs[i].istatus); 37354be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA for (j = 0; j < num_ports[i]; j++) { 37454be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA if (reg_val & BIT(j)) { 37554be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA dev_dbg(chip->dev, 37654be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA "%s:[%d]:irq=%d status=0x%x\n", 37754be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA __func__, j, irq, reg_val); 37854be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA iowrite32(BIT(j), 37954be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA &chip->reg->regs[chip->ch].iclr); 38054be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA generic_handle_irq(chip->irq_base + j); 38154be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA ret = IRQ_HANDLED; 38254be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA } 38354be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA } 38454be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA } 38554be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA return ret; 38654be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA} 38754be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 3883836309d93462bbf34851c078be6e5e77d888e3dBill Pembertonstatic void ioh_gpio_alloc_generic_chip(struct ioh_gpio *chip, 38954be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA unsigned int irq_start, unsigned int num) 39054be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA{ 39154be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA struct irq_chip_generic *gc; 39254be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA struct irq_chip_type *ct; 39354be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 39454be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA gc = irq_alloc_generic_chip("ioh_gpio", 1, irq_start, chip->base, 39554be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA handle_simple_irq); 39654be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA gc->private = chip; 39754be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA ct = gc->chip_types; 39854be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 39954be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA ct->chip.irq_mask = ioh_irq_mask; 40054be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA ct->chip.irq_unmask = ioh_irq_unmask; 40154be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA ct->chip.irq_set_type = ioh_irq_type; 4024d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang ct->chip.irq_disable = ioh_irq_disable; 4034d052213ff8f71a4a70fc4eed71b773cfde51fcfFeng Tang ct->chip.irq_enable = ioh_irq_enable; 40454be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 40554be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, 40654be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA IRQ_NOREQUEST | IRQ_NOPROBE, 0); 40749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA} 40849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 4093836309d93462bbf34851c078be6e5e77d888e3dBill Pembertonstatic int ioh_gpio_probe(struct pci_dev *pdev, 41049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA const struct pci_device_id *id) 41149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA{ 41249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA int ret; 41354be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA int i, j; 41449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA struct ioh_gpio *chip; 41549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA void __iomem *base; 416dd9328a6b026060699d4136d8f926e39281c8a18Márton Németh void *chip_save; 41754be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA int irq_base; 41849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 41949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA ret = pci_enable_device(pdev); 42049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA if (ret) { 42149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA dev_err(&pdev->dev, "%s : pci_enable_device failed", __func__); 42249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA goto err_pci_enable; 42349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA } 42449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 42549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA ret = pci_request_regions(pdev, KBUILD_MODNAME); 42649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA if (ret) { 42749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA dev_err(&pdev->dev, "pci_request_regions failed-%d", ret); 42849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA goto err_request_regions; 42949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA } 43049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 43149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA base = pci_iomap(pdev, 1, 0); 4322bd1c85e855c94da564e151cb54553e6cfc2f04bMárton Németh if (!base) { 43349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA dev_err(&pdev->dev, "%s : pci_iomap failed", __func__); 43449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA ret = -ENOMEM; 43549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA goto err_iomap; 43649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA } 43749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 43849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA chip_save = kzalloc(sizeof(*chip) * 8, GFP_KERNEL); 43949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA if (chip_save == NULL) { 44049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA dev_err(&pdev->dev, "%s : kzalloc failed", __func__); 44149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA ret = -ENOMEM; 44249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA goto err_kzalloc; 44349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA } 44449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 44549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA chip = chip_save; 44649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA for (i = 0; i < 8; i++, chip++) { 44749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA chip->dev = &pdev->dev; 44849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA chip->base = base; 44949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA chip->reg = chip->base; 45049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA chip->ch = i; 4517e3a70fb7bccada029c188c89bfbf3c0a63c1500Axel Lin spin_lock_init(&chip->spinlock); 45249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA ioh_gpio_setup(chip, num_ports[i]); 45349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA ret = gpiochip_add(&chip->gpio); 45449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA if (ret) { 45549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA dev_err(&pdev->dev, "IOH gpio: Failed to register GPIO\n"); 45649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA goto err_gpiochip_add; 45749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA } 45849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA } 45949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 46049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA chip = chip_save; 46154be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA for (j = 0; j < 8; j++, chip++) { 46254be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA irq_base = irq_alloc_descs(-1, IOH_IRQ_BASE, num_ports[j], 463a7aaa4f888968b1261c2701cc66f18a3d4b9777bTomoya MORINAGA NUMA_NO_NODE); 46454be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA if (irq_base < 0) { 46554be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA dev_warn(&pdev->dev, 46654be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA "ml_ioh_gpio: Failed to get IRQ base num\n"); 46754be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA chip->irq_base = -1; 468df46dce09113ea0a52ce7403d35087e167f3a460Wei Yongjun ret = irq_base; 46954be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA goto err_irq_alloc_descs; 47054be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA } 47154be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA chip->irq_base = irq_base; 47254be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA ioh_gpio_alloc_generic_chip(chip, irq_base, num_ports[j]); 47354be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA } 47454be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 47554be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA chip = chip_save; 47654be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA ret = request_irq(pdev->irq, ioh_gpio_handler, 47754be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA IRQF_SHARED, KBUILD_MODNAME, chip); 47854be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA if (ret != 0) { 47954be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA dev_err(&pdev->dev, 48054be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA "%s request_irq failed\n", __func__); 48154be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA goto err_request_irq; 48254be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA } 48354be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 48449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA pci_set_drvdata(pdev, chip); 48549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 48649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA return 0; 48749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 48854be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGAerr_request_irq: 48954be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA chip = chip_save; 49054be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGAerr_irq_alloc_descs: 49154be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA while (--j >= 0) { 49254be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA chip--; 49354be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA irq_free_descs(chip->irq_base, num_ports[j]); 49454be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA } 49554be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 49654be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA chip = chip_save; 49749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAerr_gpiochip_add: 49833300571b1111264fd0c5701733f7576323f3e35Axel Lin while (--i >= 0) { 49949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA chip--; 5009f5132ae82fdbb047cc187bf689a81c8cc0de7faabdoulaye berthe gpiochip_remove(&chip->gpio); 50149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA } 50249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA kfree(chip_save); 50349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 50449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAerr_kzalloc: 50549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA pci_iounmap(pdev, base); 50649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 50749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAerr_iomap: 50849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA pci_release_regions(pdev); 50949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 51049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAerr_request_regions: 51149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA pci_disable_device(pdev); 51249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 51349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAerr_pci_enable: 51449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 51549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA dev_err(&pdev->dev, "%s Failed returns %d\n", __func__, ret); 51649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA return ret; 51749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA} 51849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 519206210ce68c1feb1d9d05839ceacc97ad1b0b324Bill Pembertonstatic void ioh_gpio_remove(struct pci_dev *pdev) 52049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA{ 52149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA int i; 52249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA struct ioh_gpio *chip = pci_get_drvdata(pdev); 523dd9328a6b026060699d4136d8f926e39281c8a18Márton Németh void *chip_save; 52449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 52549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA chip_save = chip; 52654be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 52754be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA free_irq(pdev->irq, chip); 52854be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA 52949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA for (i = 0; i < 8; i++, chip++) { 53054be566317b6aece2389a95bb19ea209af9359beTomoya MORINAGA irq_free_descs(chip->irq_base, num_ports[i]); 5319f5132ae82fdbb047cc187bf689a81c8cc0de7faabdoulaye berthe gpiochip_remove(&chip->gpio); 53249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA } 53349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 53449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA chip = chip_save; 53549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA pci_iounmap(pdev, chip->base); 53649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA pci_release_regions(pdev); 53749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA pci_disable_device(pdev); 53849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA kfree(chip); 53949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA} 54049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 54149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA#ifdef CONFIG_PM 54249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAstatic int ioh_gpio_suspend(struct pci_dev *pdev, pm_message_t state) 54349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA{ 54449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA s32 ret; 54549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA struct ioh_gpio *chip = pci_get_drvdata(pdev); 546b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA unsigned long flags; 54749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 548b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA spin_lock_irqsave(&chip->spinlock, flags); 54949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA ioh_gpio_save_reg_conf(chip); 550b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA spin_unlock_irqrestore(&chip->spinlock, flags); 55149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 55249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA ret = pci_save_state(pdev); 55349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA if (ret) { 55449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA dev_err(&pdev->dev, "pci_save_state Failed-%d\n", ret); 55549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA return ret; 55649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA } 55749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA pci_disable_device(pdev); 55849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA pci_set_power_state(pdev, PCI_D0); 55949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA ret = pci_enable_wake(pdev, PCI_D0, 1); 56049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA if (ret) 56149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA dev_err(&pdev->dev, "pci_enable_wake Failed -%d\n", ret); 56249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 56349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA return 0; 56449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA} 56549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 56649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAstatic int ioh_gpio_resume(struct pci_dev *pdev) 56749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA{ 56849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA s32 ret; 56949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA struct ioh_gpio *chip = pci_get_drvdata(pdev); 570b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA unsigned long flags; 57149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 57249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA ret = pci_enable_wake(pdev, PCI_D0, 0); 57349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 57449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA pci_set_power_state(pdev, PCI_D0); 57549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA ret = pci_enable_device(pdev); 57649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA if (ret) { 57749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA dev_err(&pdev->dev, "pci_enable_device Failed-%d ", ret); 57849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA return ret; 57949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA } 58049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA pci_restore_state(pdev); 58149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 582b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA spin_lock_irqsave(&chip->spinlock, flags); 58349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA iowrite32(0x01, &chip->reg->srst); 58449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA iowrite32(0x00, &chip->reg->srst); 58549a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA ioh_gpio_restore_reg_conf(chip); 586b490fa0bf86edbc06562024cbace5e84f0e2cf0eTomoya MORINAGA spin_unlock_irqrestore(&chip->spinlock, flags); 58749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 58849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA return 0; 58949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA} 59049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA#else 59149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA#define ioh_gpio_suspend NULL 59249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA#define ioh_gpio_resume NULL 59349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA#endif 59449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 59514f4a8838acac0fe6bf710ec08fc4cce57c0011bJingoo Hanstatic const struct pci_device_id ioh_gpio_pcidev_id[] = { 59649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x802E) }, 59749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA { 0, } 59849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA}; 59919234cdda517396e5e0b10e77493afa9e30095c3Axel LinMODULE_DEVICE_TABLE(pci, ioh_gpio_pcidev_id); 60049a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 60149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAstatic struct pci_driver ioh_gpio_driver = { 60249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA .name = "ml_ioh_gpio", 60349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA .id_table = ioh_gpio_pcidev_id, 60449a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA .probe = ioh_gpio_probe, 6058283c4ff57bdf3c1d8985c86e4ef44e1bb70f1f6Bill Pemberton .remove = ioh_gpio_remove, 60649a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA .suspend = ioh_gpio_suspend, 60749a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA .resume = ioh_gpio_resume 60849a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA}; 60949a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 61093baa65fe50a83056c97973de2300337b000472eAxel Linmodule_pci_driver(ioh_gpio_driver); 61149a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGA 61249a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAMODULE_DESCRIPTION("OKI SEMICONDUCTOR ML-IOH series GPIO Driver"); 61349a367937fe4250144e24440e5a11ae4344202b1Tomoya MORINAGAMODULE_LICENSE("GPL"); 614