1c103de24SGrant Likely /* 2c103de24SGrant Likely * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. 3c103de24SGrant Likely * 4c103de24SGrant Likely * This program is free software; you can redistribute it and/or modify 5c103de24SGrant Likely * it under the terms of the GNU General Public License as published by 6c103de24SGrant Likely * the Free Software Foundation; version 2 of the License. 7c103de24SGrant Likely * 8c103de24SGrant Likely * This program is distributed in the hope that it will be useful, 9c103de24SGrant Likely * but WITHOUT ANY WARRANTY; without even the implied warranty of 10c103de24SGrant Likely * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11c103de24SGrant Likely * GNU General Public License for more details. 12c103de24SGrant Likely * 13c103de24SGrant Likely * You should have received a copy of the GNU General Public License 14c103de24SGrant Likely * along with this program; if not, write to the Free Software 15c103de24SGrant Likely * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 16c103de24SGrant Likely */ 17bb207ef1SPaul Gortmaker #include <linux/module.h> 18c103de24SGrant Likely #include <linux/kernel.h> 19c103de24SGrant Likely #include <linux/slab.h> 20c103de24SGrant Likely #include <linux/pci.h> 21c103de24SGrant Likely #include <linux/gpio.h> 2254be5663STomoya MORINAGA #include <linux/interrupt.h> 2354be5663STomoya MORINAGA #include <linux/irq.h> 2454be5663STomoya MORINAGA 2554be5663STomoya MORINAGA #define IOH_EDGE_FALLING 0 2654be5663STomoya MORINAGA #define IOH_EDGE_RISING BIT(0) 2754be5663STomoya MORINAGA #define IOH_LEVEL_L BIT(1) 2854be5663STomoya MORINAGA #define IOH_LEVEL_H (BIT(0) | BIT(1)) 2954be5663STomoya MORINAGA #define IOH_EDGE_BOTH BIT(2) 3054be5663STomoya MORINAGA #define IOH_IM_MASK (BIT(0) | BIT(1) | BIT(2)) 3154be5663STomoya MORINAGA 3254be5663STomoya MORINAGA #define IOH_IRQ_BASE 0 33c103de24SGrant Likely 34c103de24SGrant Likely #define PCI_VENDOR_ID_ROHM 0x10DB 35c103de24SGrant Likely 36c103de24SGrant Likely struct ioh_reg_comn { 37c103de24SGrant Likely u32 ien; 38c103de24SGrant Likely u32 istatus; 39c103de24SGrant Likely u32 idisp; 40c103de24SGrant Likely u32 iclr; 41c103de24SGrant Likely u32 imask; 42c103de24SGrant Likely u32 imaskclr; 43c103de24SGrant Likely u32 po; 44c103de24SGrant Likely u32 pi; 45c103de24SGrant Likely u32 pm; 46c103de24SGrant Likely u32 im_0; 47c103de24SGrant Likely u32 im_1; 48c103de24SGrant Likely u32 reserved; 49c103de24SGrant Likely }; 50c103de24SGrant Likely 51c103de24SGrant Likely struct ioh_regs { 52c103de24SGrant Likely struct ioh_reg_comn regs[8]; 53c103de24SGrant Likely u32 reserve1[16]; 54c103de24SGrant Likely u32 ioh_sel_reg[4]; 55c103de24SGrant Likely u32 reserve2[11]; 56c103de24SGrant Likely u32 srst; 57c103de24SGrant Likely }; 58c103de24SGrant Likely 59c103de24SGrant Likely /** 60c103de24SGrant Likely * struct ioh_gpio_reg_data - The register store data. 6154be5663STomoya MORINAGA * @ien_reg To store contents of interrupt enable register. 6254be5663STomoya MORINAGA * @imask_reg: To store contents of interrupt mask regist 63c103de24SGrant Likely * @po_reg: To store contents of PO register. 64c103de24SGrant Likely * @pm_reg: To store contents of PM register. 6554be5663STomoya MORINAGA * @im0_reg: To store contents of interrupt mode regist0 6654be5663STomoya MORINAGA * @im1_reg: To store contents of interrupt mode regist1 67b490fa0bSTomoya MORINAGA * @use_sel_reg: To store contents of GPIO_USE_SEL0~3 68c103de24SGrant Likely */ 69c103de24SGrant Likely struct ioh_gpio_reg_data { 7054be5663STomoya MORINAGA u32 ien_reg; 7154be5663STomoya MORINAGA u32 imask_reg; 72c103de24SGrant Likely u32 po_reg; 73c103de24SGrant Likely u32 pm_reg; 7454be5663STomoya MORINAGA u32 im0_reg; 7554be5663STomoya MORINAGA u32 im1_reg; 76b490fa0bSTomoya MORINAGA u32 use_sel_reg; 77c103de24SGrant Likely }; 78c103de24SGrant Likely 79c103de24SGrant Likely /** 80c103de24SGrant Likely * struct ioh_gpio - GPIO private data structure. 81c103de24SGrant Likely * @base: PCI base address of Memory mapped I/O register. 82c103de24SGrant Likely * @reg: Memory mapped IOH GPIO register list. 83c103de24SGrant Likely * @dev: Pointer to device structure. 84c103de24SGrant Likely * @gpio: Data for GPIO infrastructure. 85c103de24SGrant Likely * @ioh_gpio_reg: Memory mapped Register data is saved here 86c103de24SGrant Likely * when suspend. 87b490fa0bSTomoya MORINAGA * @gpio_use_sel: Save GPIO_USE_SEL1~4 register for PM 88c103de24SGrant Likely * @ch: Indicate GPIO channel 8954be5663STomoya MORINAGA * @irq_base: Save base of IRQ number for interrupt 9054be5663STomoya MORINAGA * @spinlock: Used for register access protection in 9154be5663STomoya MORINAGA * interrupt context ioh_irq_type and PM; 92c103de24SGrant Likely */ 93c103de24SGrant Likely struct ioh_gpio { 94c103de24SGrant Likely void __iomem *base; 95c103de24SGrant Likely struct ioh_regs __iomem *reg; 96c103de24SGrant Likely struct device *dev; 97c103de24SGrant Likely struct gpio_chip gpio; 98c103de24SGrant Likely struct ioh_gpio_reg_data ioh_gpio_reg; 99b490fa0bSTomoya MORINAGA u32 gpio_use_sel; 100c103de24SGrant Likely struct mutex lock; 101c103de24SGrant Likely int ch; 10254be5663STomoya MORINAGA int irq_base; 10354be5663STomoya MORINAGA spinlock_t spinlock; 104c103de24SGrant Likely }; 105c103de24SGrant Likely 106c103de24SGrant Likely static const int num_ports[] = {6, 12, 16, 16, 15, 16, 16, 12}; 107c103de24SGrant Likely 108c103de24SGrant Likely static void ioh_gpio_set(struct gpio_chip *gpio, unsigned nr, int val) 109c103de24SGrant Likely { 110c103de24SGrant Likely u32 reg_val; 111c103de24SGrant Likely struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio); 112c103de24SGrant Likely 113c103de24SGrant Likely mutex_lock(&chip->lock); 114c103de24SGrant Likely reg_val = ioread32(&chip->reg->regs[chip->ch].po); 115c103de24SGrant Likely if (val) 116c103de24SGrant Likely reg_val |= (1 << nr); 117c103de24SGrant Likely else 118c103de24SGrant Likely reg_val &= ~(1 << nr); 119c103de24SGrant Likely 120c103de24SGrant Likely iowrite32(reg_val, &chip->reg->regs[chip->ch].po); 121c103de24SGrant Likely mutex_unlock(&chip->lock); 122c103de24SGrant Likely } 123c103de24SGrant Likely 124c103de24SGrant Likely static int ioh_gpio_get(struct gpio_chip *gpio, unsigned nr) 125c103de24SGrant Likely { 126c103de24SGrant Likely struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio); 127c103de24SGrant Likely 128c103de24SGrant Likely return ioread32(&chip->reg->regs[chip->ch].pi) & (1 << nr); 129c103de24SGrant Likely } 130c103de24SGrant Likely 131c103de24SGrant Likely static int ioh_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, 132c103de24SGrant Likely int val) 133c103de24SGrant Likely { 134c103de24SGrant Likely struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio); 135c103de24SGrant Likely u32 pm; 136c103de24SGrant Likely u32 reg_val; 137c103de24SGrant Likely 138c103de24SGrant Likely mutex_lock(&chip->lock); 139c103de24SGrant Likely pm = ioread32(&chip->reg->regs[chip->ch].pm) & 140c103de24SGrant Likely ((1 << num_ports[chip->ch]) - 1); 141c103de24SGrant Likely pm |= (1 << nr); 142c103de24SGrant Likely iowrite32(pm, &chip->reg->regs[chip->ch].pm); 143c103de24SGrant Likely 144c103de24SGrant Likely reg_val = ioread32(&chip->reg->regs[chip->ch].po); 145c103de24SGrant Likely if (val) 146c103de24SGrant Likely reg_val |= (1 << nr); 147c103de24SGrant Likely else 148c103de24SGrant Likely reg_val &= ~(1 << nr); 149c103de24SGrant Likely iowrite32(reg_val, &chip->reg->regs[chip->ch].po); 150c103de24SGrant Likely 151c103de24SGrant Likely mutex_unlock(&chip->lock); 152c103de24SGrant Likely 153c103de24SGrant Likely return 0; 154c103de24SGrant Likely } 155c103de24SGrant Likely 156c103de24SGrant Likely static int ioh_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) 157c103de24SGrant Likely { 158c103de24SGrant Likely struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio); 159c103de24SGrant Likely u32 pm; 160c103de24SGrant Likely 161c103de24SGrant Likely mutex_lock(&chip->lock); 162c103de24SGrant Likely pm = ioread32(&chip->reg->regs[chip->ch].pm) & 163c103de24SGrant Likely ((1 << num_ports[chip->ch]) - 1); 164c103de24SGrant Likely pm &= ~(1 << nr); 165c103de24SGrant Likely iowrite32(pm, &chip->reg->regs[chip->ch].pm); 166c103de24SGrant Likely mutex_unlock(&chip->lock); 167c103de24SGrant Likely 168c103de24SGrant Likely return 0; 169c103de24SGrant Likely } 170c103de24SGrant Likely 171c103de24SGrant Likely #ifdef CONFIG_PM 172c103de24SGrant Likely /* 173c103de24SGrant Likely * Save register configuration and disable interrupts. 174c103de24SGrant Likely */ 175c103de24SGrant Likely static void ioh_gpio_save_reg_conf(struct ioh_gpio *chip) 176c103de24SGrant Likely { 177b490fa0bSTomoya MORINAGA int i; 178b490fa0bSTomoya MORINAGA 179b490fa0bSTomoya MORINAGA for (i = 0; i < 8; i ++, chip++) { 180b490fa0bSTomoya MORINAGA chip->ioh_gpio_reg.po_reg = 181b490fa0bSTomoya MORINAGA ioread32(&chip->reg->regs[chip->ch].po); 182b490fa0bSTomoya MORINAGA chip->ioh_gpio_reg.pm_reg = 183b490fa0bSTomoya MORINAGA ioread32(&chip->reg->regs[chip->ch].pm); 184b490fa0bSTomoya MORINAGA chip->ioh_gpio_reg.ien_reg = 185b490fa0bSTomoya MORINAGA ioread32(&chip->reg->regs[chip->ch].ien); 186b490fa0bSTomoya MORINAGA chip->ioh_gpio_reg.imask_reg = 187b490fa0bSTomoya MORINAGA ioread32(&chip->reg->regs[chip->ch].imask); 188b490fa0bSTomoya MORINAGA chip->ioh_gpio_reg.im0_reg = 189b490fa0bSTomoya MORINAGA ioread32(&chip->reg->regs[chip->ch].im_0); 190b490fa0bSTomoya MORINAGA chip->ioh_gpio_reg.im1_reg = 191b490fa0bSTomoya MORINAGA ioread32(&chip->reg->regs[chip->ch].im_1); 192b490fa0bSTomoya MORINAGA if (i < 4) 193b490fa0bSTomoya MORINAGA chip->ioh_gpio_reg.use_sel_reg = 194b490fa0bSTomoya MORINAGA ioread32(&chip->reg->ioh_sel_reg[i]); 195b490fa0bSTomoya MORINAGA } 196c103de24SGrant Likely } 197c103de24SGrant Likely 198c103de24SGrant Likely /* 199c103de24SGrant Likely * This function restores the register configuration of the GPIO device. 200c103de24SGrant Likely */ 201c103de24SGrant Likely static void ioh_gpio_restore_reg_conf(struct ioh_gpio *chip) 202c103de24SGrant Likely { 203b490fa0bSTomoya MORINAGA int i; 204b490fa0bSTomoya MORINAGA 205b490fa0bSTomoya MORINAGA for (i = 0; i < 8; i ++, chip++) { 206b490fa0bSTomoya MORINAGA iowrite32(chip->ioh_gpio_reg.po_reg, 207b490fa0bSTomoya MORINAGA &chip->reg->regs[chip->ch].po); 208b490fa0bSTomoya MORINAGA iowrite32(chip->ioh_gpio_reg.pm_reg, 209b490fa0bSTomoya MORINAGA &chip->reg->regs[chip->ch].pm); 210b490fa0bSTomoya MORINAGA iowrite32(chip->ioh_gpio_reg.ien_reg, 211b490fa0bSTomoya MORINAGA &chip->reg->regs[chip->ch].ien); 212b490fa0bSTomoya MORINAGA iowrite32(chip->ioh_gpio_reg.imask_reg, 213b490fa0bSTomoya MORINAGA &chip->reg->regs[chip->ch].imask); 214b490fa0bSTomoya MORINAGA iowrite32(chip->ioh_gpio_reg.im0_reg, 215b490fa0bSTomoya MORINAGA &chip->reg->regs[chip->ch].im_0); 216b490fa0bSTomoya MORINAGA iowrite32(chip->ioh_gpio_reg.im1_reg, 217b490fa0bSTomoya MORINAGA &chip->reg->regs[chip->ch].im_1); 218b490fa0bSTomoya MORINAGA if (i < 4) 219b490fa0bSTomoya MORINAGA iowrite32(chip->ioh_gpio_reg.use_sel_reg, 220b490fa0bSTomoya MORINAGA &chip->reg->ioh_sel_reg[i]); 221b490fa0bSTomoya MORINAGA } 222c103de24SGrant Likely } 223c103de24SGrant Likely #endif 224c103de24SGrant Likely 22554be5663STomoya MORINAGA static int ioh_gpio_to_irq(struct gpio_chip *gpio, unsigned offset) 22654be5663STomoya MORINAGA { 22754be5663STomoya MORINAGA struct ioh_gpio *chip = container_of(gpio, struct ioh_gpio, gpio); 22854be5663STomoya MORINAGA return chip->irq_base + offset; 22954be5663STomoya MORINAGA } 23054be5663STomoya MORINAGA 231c103de24SGrant Likely static void ioh_gpio_setup(struct ioh_gpio *chip, int num_port) 232c103de24SGrant Likely { 233c103de24SGrant Likely struct gpio_chip *gpio = &chip->gpio; 234c103de24SGrant Likely 235c103de24SGrant Likely gpio->label = dev_name(chip->dev); 236c103de24SGrant Likely gpio->owner = THIS_MODULE; 237c103de24SGrant Likely gpio->direction_input = ioh_gpio_direction_input; 238c103de24SGrant Likely gpio->get = ioh_gpio_get; 239c103de24SGrant Likely gpio->direction_output = ioh_gpio_direction_output; 240c103de24SGrant Likely gpio->set = ioh_gpio_set; 241c103de24SGrant Likely gpio->dbg_show = NULL; 242c103de24SGrant Likely gpio->base = -1; 243c103de24SGrant Likely gpio->ngpio = num_port; 244c103de24SGrant Likely gpio->can_sleep = 0; 24554be5663STomoya MORINAGA gpio->to_irq = ioh_gpio_to_irq; 24654be5663STomoya MORINAGA } 24754be5663STomoya MORINAGA 24854be5663STomoya MORINAGA static int ioh_irq_type(struct irq_data *d, unsigned int type) 24954be5663STomoya MORINAGA { 25054be5663STomoya MORINAGA u32 im; 25154be5663STomoya MORINAGA u32 *im_reg; 25254be5663STomoya MORINAGA u32 ien; 25354be5663STomoya MORINAGA u32 im_pos; 25454be5663STomoya MORINAGA int ch; 25554be5663STomoya MORINAGA unsigned long flags; 25654be5663STomoya MORINAGA u32 val; 25754be5663STomoya MORINAGA int irq = d->irq; 25854be5663STomoya MORINAGA struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 25954be5663STomoya MORINAGA struct ioh_gpio *chip = gc->private; 26054be5663STomoya MORINAGA 26154be5663STomoya MORINAGA ch = irq - chip->irq_base; 26254be5663STomoya MORINAGA if (irq <= chip->irq_base + 7) { 26354be5663STomoya MORINAGA im_reg = &chip->reg->regs[chip->ch].im_0; 26454be5663STomoya MORINAGA im_pos = ch; 26554be5663STomoya MORINAGA } else { 26654be5663STomoya MORINAGA im_reg = &chip->reg->regs[chip->ch].im_1; 26754be5663STomoya MORINAGA im_pos = ch - 8; 26854be5663STomoya MORINAGA } 26954be5663STomoya MORINAGA dev_dbg(chip->dev, "%s:irq=%d type=%d ch=%d pos=%d type=%d\n", 27054be5663STomoya MORINAGA __func__, irq, type, ch, im_pos, type); 27154be5663STomoya MORINAGA 27254be5663STomoya MORINAGA spin_lock_irqsave(&chip->spinlock, flags); 27354be5663STomoya MORINAGA 27454be5663STomoya MORINAGA switch (type) { 27554be5663STomoya MORINAGA case IRQ_TYPE_EDGE_RISING: 27654be5663STomoya MORINAGA val = IOH_EDGE_RISING; 27754be5663STomoya MORINAGA break; 27854be5663STomoya MORINAGA case IRQ_TYPE_EDGE_FALLING: 27954be5663STomoya MORINAGA val = IOH_EDGE_FALLING; 28054be5663STomoya MORINAGA break; 28154be5663STomoya MORINAGA case IRQ_TYPE_EDGE_BOTH: 28254be5663STomoya MORINAGA val = IOH_EDGE_BOTH; 28354be5663STomoya MORINAGA break; 28454be5663STomoya MORINAGA case IRQ_TYPE_LEVEL_HIGH: 28554be5663STomoya MORINAGA val = IOH_LEVEL_H; 28654be5663STomoya MORINAGA break; 28754be5663STomoya MORINAGA case IRQ_TYPE_LEVEL_LOW: 28854be5663STomoya MORINAGA val = IOH_LEVEL_L; 28954be5663STomoya MORINAGA break; 29054be5663STomoya MORINAGA case IRQ_TYPE_PROBE: 29154be5663STomoya MORINAGA goto end; 29254be5663STomoya MORINAGA default: 29354be5663STomoya MORINAGA dev_warn(chip->dev, "%s: unknown type(%dd)", 29454be5663STomoya MORINAGA __func__, type); 29554be5663STomoya MORINAGA goto end; 29654be5663STomoya MORINAGA } 29754be5663STomoya MORINAGA 29854be5663STomoya MORINAGA /* Set interrupt mode */ 29954be5663STomoya MORINAGA im = ioread32(im_reg) & ~(IOH_IM_MASK << (im_pos * 4)); 30054be5663STomoya MORINAGA iowrite32(im | (val << (im_pos * 4)), im_reg); 30154be5663STomoya MORINAGA 30254be5663STomoya MORINAGA /* iclr */ 30354be5663STomoya MORINAGA iowrite32(BIT(ch), &chip->reg->regs[chip->ch].iclr); 30454be5663STomoya MORINAGA 30554be5663STomoya MORINAGA /* IMASKCLR */ 30654be5663STomoya MORINAGA iowrite32(BIT(ch), &chip->reg->regs[chip->ch].imaskclr); 30754be5663STomoya MORINAGA 30854be5663STomoya MORINAGA /* Enable interrupt */ 30954be5663STomoya MORINAGA ien = ioread32(&chip->reg->regs[chip->ch].ien); 31054be5663STomoya MORINAGA iowrite32(ien | BIT(ch), &chip->reg->regs[chip->ch].ien); 31154be5663STomoya MORINAGA end: 31254be5663STomoya MORINAGA spin_unlock_irqrestore(&chip->spinlock, flags); 31354be5663STomoya MORINAGA 31454be5663STomoya MORINAGA return 0; 31554be5663STomoya MORINAGA } 31654be5663STomoya MORINAGA 31754be5663STomoya MORINAGA static void ioh_irq_unmask(struct irq_data *d) 31854be5663STomoya MORINAGA { 31954be5663STomoya MORINAGA struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 32054be5663STomoya MORINAGA struct ioh_gpio *chip = gc->private; 32154be5663STomoya MORINAGA 32254be5663STomoya MORINAGA iowrite32(1 << (d->irq - chip->irq_base), 32354be5663STomoya MORINAGA &chip->reg->regs[chip->ch].imaskclr); 32454be5663STomoya MORINAGA } 32554be5663STomoya MORINAGA 32654be5663STomoya MORINAGA static void ioh_irq_mask(struct irq_data *d) 32754be5663STomoya MORINAGA { 32854be5663STomoya MORINAGA struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 32954be5663STomoya MORINAGA struct ioh_gpio *chip = gc->private; 33054be5663STomoya MORINAGA 33154be5663STomoya MORINAGA iowrite32(1 << (d->irq - chip->irq_base), 33254be5663STomoya MORINAGA &chip->reg->regs[chip->ch].imask); 33354be5663STomoya MORINAGA } 33454be5663STomoya MORINAGA 3354d052213SFeng Tang static void ioh_irq_disable(struct irq_data *d) 3364d052213SFeng Tang { 3374d052213SFeng Tang struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 3384d052213SFeng Tang struct ioh_gpio *chip = gc->private; 3394d052213SFeng Tang unsigned long flags; 3404d052213SFeng Tang u32 ien; 3414d052213SFeng Tang 3424d052213SFeng Tang spin_lock_irqsave(&chip->spinlock, flags); 3434d052213SFeng Tang ien = ioread32(&chip->reg->regs[chip->ch].ien); 3444d052213SFeng Tang ien &= ~(1 << (d->irq - chip->irq_base)); 3454d052213SFeng Tang iowrite32(ien, &chip->reg->regs[chip->ch].ien); 3464d052213SFeng Tang spin_unlock_irqrestore(&chip->spinlock, flags); 3474d052213SFeng Tang } 3484d052213SFeng Tang 3494d052213SFeng Tang static void ioh_irq_enable(struct irq_data *d) 3504d052213SFeng Tang { 3514d052213SFeng Tang struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 3524d052213SFeng Tang struct ioh_gpio *chip = gc->private; 3534d052213SFeng Tang unsigned long flags; 3544d052213SFeng Tang u32 ien; 3554d052213SFeng Tang 3564d052213SFeng Tang spin_lock_irqsave(&chip->spinlock, flags); 3574d052213SFeng Tang ien = ioread32(&chip->reg->regs[chip->ch].ien); 3584d052213SFeng Tang ien |= 1 << (d->irq - chip->irq_base); 3594d052213SFeng Tang iowrite32(ien, &chip->reg->regs[chip->ch].ien); 3604d052213SFeng Tang spin_unlock_irqrestore(&chip->spinlock, flags); 3614d052213SFeng Tang } 3624d052213SFeng Tang 36354be5663STomoya MORINAGA static irqreturn_t ioh_gpio_handler(int irq, void *dev_id) 36454be5663STomoya MORINAGA { 36554be5663STomoya MORINAGA struct ioh_gpio *chip = dev_id; 36654be5663STomoya MORINAGA u32 reg_val; 36754be5663STomoya MORINAGA int i, j; 36854be5663STomoya MORINAGA int ret = IRQ_NONE; 36954be5663STomoya MORINAGA 370f9ea14efSFeng Tang for (i = 0; i < 8; i++, chip++) { 37154be5663STomoya MORINAGA reg_val = ioread32(&chip->reg->regs[i].istatus); 37254be5663STomoya MORINAGA for (j = 0; j < num_ports[i]; j++) { 37354be5663STomoya MORINAGA if (reg_val & BIT(j)) { 37454be5663STomoya MORINAGA dev_dbg(chip->dev, 37554be5663STomoya MORINAGA "%s:[%d]:irq=%d status=0x%x\n", 37654be5663STomoya MORINAGA __func__, j, irq, reg_val); 37754be5663STomoya MORINAGA iowrite32(BIT(j), 37854be5663STomoya MORINAGA &chip->reg->regs[chip->ch].iclr); 37954be5663STomoya MORINAGA generic_handle_irq(chip->irq_base + j); 38054be5663STomoya MORINAGA ret = IRQ_HANDLED; 38154be5663STomoya MORINAGA } 38254be5663STomoya MORINAGA } 38354be5663STomoya MORINAGA } 38454be5663STomoya MORINAGA return ret; 38554be5663STomoya MORINAGA } 38654be5663STomoya MORINAGA 38754be5663STomoya MORINAGA static __devinit void ioh_gpio_alloc_generic_chip(struct ioh_gpio *chip, 38854be5663STomoya MORINAGA unsigned int irq_start, unsigned int num) 38954be5663STomoya MORINAGA { 39054be5663STomoya MORINAGA struct irq_chip_generic *gc; 39154be5663STomoya MORINAGA struct irq_chip_type *ct; 39254be5663STomoya MORINAGA 39354be5663STomoya MORINAGA gc = irq_alloc_generic_chip("ioh_gpio", 1, irq_start, chip->base, 39454be5663STomoya MORINAGA handle_simple_irq); 39554be5663STomoya MORINAGA gc->private = chip; 39654be5663STomoya MORINAGA ct = gc->chip_types; 39754be5663STomoya MORINAGA 39854be5663STomoya MORINAGA ct->chip.irq_mask = ioh_irq_mask; 39954be5663STomoya MORINAGA ct->chip.irq_unmask = ioh_irq_unmask; 40054be5663STomoya MORINAGA ct->chip.irq_set_type = ioh_irq_type; 4014d052213SFeng Tang ct->chip.irq_disable = ioh_irq_disable; 4024d052213SFeng Tang ct->chip.irq_enable = ioh_irq_enable; 40354be5663STomoya MORINAGA 40454be5663STomoya MORINAGA irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, 40554be5663STomoya MORINAGA IRQ_NOREQUEST | IRQ_NOPROBE, 0); 406c103de24SGrant Likely } 407c103de24SGrant Likely 408c103de24SGrant Likely static int __devinit ioh_gpio_probe(struct pci_dev *pdev, 409c103de24SGrant Likely const struct pci_device_id *id) 410c103de24SGrant Likely { 411c103de24SGrant Likely int ret; 41254be5663STomoya MORINAGA int i, j; 413c103de24SGrant Likely struct ioh_gpio *chip; 414c103de24SGrant Likely void __iomem *base; 415c103de24SGrant Likely void __iomem *chip_save; 41654be5663STomoya MORINAGA int irq_base; 417c103de24SGrant Likely 418c103de24SGrant Likely ret = pci_enable_device(pdev); 419c103de24SGrant Likely if (ret) { 420c103de24SGrant Likely dev_err(&pdev->dev, "%s : pci_enable_device failed", __func__); 421c103de24SGrant Likely goto err_pci_enable; 422c103de24SGrant Likely } 423c103de24SGrant Likely 424c103de24SGrant Likely ret = pci_request_regions(pdev, KBUILD_MODNAME); 425c103de24SGrant Likely if (ret) { 426c103de24SGrant Likely dev_err(&pdev->dev, "pci_request_regions failed-%d", ret); 427c103de24SGrant Likely goto err_request_regions; 428c103de24SGrant Likely } 429c103de24SGrant Likely 430c103de24SGrant Likely base = pci_iomap(pdev, 1, 0); 431*2bd1c85eSMárton Németh if (!base) { 432c103de24SGrant Likely dev_err(&pdev->dev, "%s : pci_iomap failed", __func__); 433c103de24SGrant Likely ret = -ENOMEM; 434c103de24SGrant Likely goto err_iomap; 435c103de24SGrant Likely } 436c103de24SGrant Likely 437c103de24SGrant Likely chip_save = kzalloc(sizeof(*chip) * 8, GFP_KERNEL); 438c103de24SGrant Likely if (chip_save == NULL) { 439c103de24SGrant Likely dev_err(&pdev->dev, "%s : kzalloc failed", __func__); 440c103de24SGrant Likely ret = -ENOMEM; 441c103de24SGrant Likely goto err_kzalloc; 442c103de24SGrant Likely } 443c103de24SGrant Likely 444c103de24SGrant Likely chip = chip_save; 445c103de24SGrant Likely for (i = 0; i < 8; i++, chip++) { 446c103de24SGrant Likely chip->dev = &pdev->dev; 447c103de24SGrant Likely chip->base = base; 448c103de24SGrant Likely chip->reg = chip->base; 449c103de24SGrant Likely chip->ch = i; 450c103de24SGrant Likely mutex_init(&chip->lock); 451c103de24SGrant Likely ioh_gpio_setup(chip, num_ports[i]); 452c103de24SGrant Likely ret = gpiochip_add(&chip->gpio); 453c103de24SGrant Likely if (ret) { 454c103de24SGrant Likely dev_err(&pdev->dev, "IOH gpio: Failed to register GPIO\n"); 455c103de24SGrant Likely goto err_gpiochip_add; 456c103de24SGrant Likely } 457c103de24SGrant Likely } 458c103de24SGrant Likely 459c103de24SGrant Likely chip = chip_save; 46054be5663STomoya MORINAGA for (j = 0; j < 8; j++, chip++) { 46154be5663STomoya MORINAGA irq_base = irq_alloc_descs(-1, IOH_IRQ_BASE, num_ports[j], 462a7aaa4f8STomoya MORINAGA NUMA_NO_NODE); 46354be5663STomoya MORINAGA if (irq_base < 0) { 46454be5663STomoya MORINAGA dev_warn(&pdev->dev, 46554be5663STomoya MORINAGA "ml_ioh_gpio: Failed to get IRQ base num\n"); 46654be5663STomoya MORINAGA chip->irq_base = -1; 46754be5663STomoya MORINAGA goto err_irq_alloc_descs; 46854be5663STomoya MORINAGA } 46954be5663STomoya MORINAGA chip->irq_base = irq_base; 47054be5663STomoya MORINAGA ioh_gpio_alloc_generic_chip(chip, irq_base, num_ports[j]); 47154be5663STomoya MORINAGA } 47254be5663STomoya MORINAGA 47354be5663STomoya MORINAGA chip = chip_save; 47454be5663STomoya MORINAGA ret = request_irq(pdev->irq, ioh_gpio_handler, 47554be5663STomoya MORINAGA IRQF_SHARED, KBUILD_MODNAME, chip); 47654be5663STomoya MORINAGA if (ret != 0) { 47754be5663STomoya MORINAGA dev_err(&pdev->dev, 47854be5663STomoya MORINAGA "%s request_irq failed\n", __func__); 47954be5663STomoya MORINAGA goto err_request_irq; 48054be5663STomoya MORINAGA } 48154be5663STomoya MORINAGA 482c103de24SGrant Likely pci_set_drvdata(pdev, chip); 483c103de24SGrant Likely 484c103de24SGrant Likely return 0; 485c103de24SGrant Likely 48654be5663STomoya MORINAGA err_request_irq: 48754be5663STomoya MORINAGA chip = chip_save; 48854be5663STomoya MORINAGA err_irq_alloc_descs: 48954be5663STomoya MORINAGA while (--j >= 0) { 49054be5663STomoya MORINAGA chip--; 49154be5663STomoya MORINAGA irq_free_descs(chip->irq_base, num_ports[j]); 49254be5663STomoya MORINAGA } 49354be5663STomoya MORINAGA 49454be5663STomoya MORINAGA chip = chip_save; 495c103de24SGrant Likely err_gpiochip_add: 49633300571SAxel Lin while (--i >= 0) { 497c103de24SGrant Likely chip--; 498c103de24SGrant Likely ret = gpiochip_remove(&chip->gpio); 499c103de24SGrant Likely if (ret) 500c103de24SGrant Likely dev_err(&pdev->dev, "Failed gpiochip_remove(%d)\n", i); 501c103de24SGrant Likely } 502c103de24SGrant Likely kfree(chip_save); 503c103de24SGrant Likely 504c103de24SGrant Likely err_kzalloc: 505c103de24SGrant Likely pci_iounmap(pdev, base); 506c103de24SGrant Likely 507c103de24SGrant Likely err_iomap: 508c103de24SGrant Likely pci_release_regions(pdev); 509c103de24SGrant Likely 510c103de24SGrant Likely err_request_regions: 511c103de24SGrant Likely pci_disable_device(pdev); 512c103de24SGrant Likely 513c103de24SGrant Likely err_pci_enable: 514c103de24SGrant Likely 515c103de24SGrant Likely dev_err(&pdev->dev, "%s Failed returns %d\n", __func__, ret); 516c103de24SGrant Likely return ret; 517c103de24SGrant Likely } 518c103de24SGrant Likely 519c103de24SGrant Likely static void __devexit ioh_gpio_remove(struct pci_dev *pdev) 520c103de24SGrant Likely { 521c103de24SGrant Likely int err; 522c103de24SGrant Likely int i; 523c103de24SGrant Likely struct ioh_gpio *chip = pci_get_drvdata(pdev); 524c103de24SGrant Likely void __iomem *chip_save; 525c103de24SGrant Likely 526c103de24SGrant Likely chip_save = chip; 52754be5663STomoya MORINAGA 52854be5663STomoya MORINAGA free_irq(pdev->irq, chip); 52954be5663STomoya MORINAGA 530c103de24SGrant Likely for (i = 0; i < 8; i++, chip++) { 53154be5663STomoya MORINAGA irq_free_descs(chip->irq_base, num_ports[i]); 532c103de24SGrant Likely err = gpiochip_remove(&chip->gpio); 533c103de24SGrant Likely if (err) 534c103de24SGrant Likely dev_err(&pdev->dev, "Failed gpiochip_remove\n"); 535c103de24SGrant Likely } 536c103de24SGrant Likely 537c103de24SGrant Likely chip = chip_save; 538c103de24SGrant Likely pci_iounmap(pdev, chip->base); 539c103de24SGrant Likely pci_release_regions(pdev); 540c103de24SGrant Likely pci_disable_device(pdev); 541c103de24SGrant Likely kfree(chip); 542c103de24SGrant Likely } 543c103de24SGrant Likely 544c103de24SGrant Likely #ifdef CONFIG_PM 545c103de24SGrant Likely static int ioh_gpio_suspend(struct pci_dev *pdev, pm_message_t state) 546c103de24SGrant Likely { 547c103de24SGrant Likely s32 ret; 548c103de24SGrant Likely struct ioh_gpio *chip = pci_get_drvdata(pdev); 549b490fa0bSTomoya MORINAGA unsigned long flags; 550c103de24SGrant Likely 551b490fa0bSTomoya MORINAGA spin_lock_irqsave(&chip->spinlock, flags); 552c103de24SGrant Likely ioh_gpio_save_reg_conf(chip); 553b490fa0bSTomoya MORINAGA spin_unlock_irqrestore(&chip->spinlock, flags); 554c103de24SGrant Likely 555c103de24SGrant Likely ret = pci_save_state(pdev); 556c103de24SGrant Likely if (ret) { 557c103de24SGrant Likely dev_err(&pdev->dev, "pci_save_state Failed-%d\n", ret); 558c103de24SGrant Likely return ret; 559c103de24SGrant Likely } 560c103de24SGrant Likely pci_disable_device(pdev); 561c103de24SGrant Likely pci_set_power_state(pdev, PCI_D0); 562c103de24SGrant Likely ret = pci_enable_wake(pdev, PCI_D0, 1); 563c103de24SGrant Likely if (ret) 564c103de24SGrant Likely dev_err(&pdev->dev, "pci_enable_wake Failed -%d\n", ret); 565c103de24SGrant Likely 566c103de24SGrant Likely return 0; 567c103de24SGrant Likely } 568c103de24SGrant Likely 569c103de24SGrant Likely static int ioh_gpio_resume(struct pci_dev *pdev) 570c103de24SGrant Likely { 571c103de24SGrant Likely s32 ret; 572c103de24SGrant Likely struct ioh_gpio *chip = pci_get_drvdata(pdev); 573b490fa0bSTomoya MORINAGA unsigned long flags; 574c103de24SGrant Likely 575c103de24SGrant Likely ret = pci_enable_wake(pdev, PCI_D0, 0); 576c103de24SGrant Likely 577c103de24SGrant Likely pci_set_power_state(pdev, PCI_D0); 578c103de24SGrant Likely ret = pci_enable_device(pdev); 579c103de24SGrant Likely if (ret) { 580c103de24SGrant Likely dev_err(&pdev->dev, "pci_enable_device Failed-%d ", ret); 581c103de24SGrant Likely return ret; 582c103de24SGrant Likely } 583c103de24SGrant Likely pci_restore_state(pdev); 584c103de24SGrant Likely 585b490fa0bSTomoya MORINAGA spin_lock_irqsave(&chip->spinlock, flags); 586c103de24SGrant Likely iowrite32(0x01, &chip->reg->srst); 587c103de24SGrant Likely iowrite32(0x00, &chip->reg->srst); 588c103de24SGrant Likely ioh_gpio_restore_reg_conf(chip); 589b490fa0bSTomoya MORINAGA spin_unlock_irqrestore(&chip->spinlock, flags); 590c103de24SGrant Likely 591c103de24SGrant Likely return 0; 592c103de24SGrant Likely } 593c103de24SGrant Likely #else 594c103de24SGrant Likely #define ioh_gpio_suspend NULL 595c103de24SGrant Likely #define ioh_gpio_resume NULL 596c103de24SGrant Likely #endif 597c103de24SGrant Likely 598c103de24SGrant Likely static DEFINE_PCI_DEVICE_TABLE(ioh_gpio_pcidev_id) = { 599c103de24SGrant Likely { PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x802E) }, 600c103de24SGrant Likely { 0, } 601c103de24SGrant Likely }; 602c103de24SGrant Likely MODULE_DEVICE_TABLE(pci, ioh_gpio_pcidev_id); 603c103de24SGrant Likely 604c103de24SGrant Likely static struct pci_driver ioh_gpio_driver = { 605c103de24SGrant Likely .name = "ml_ioh_gpio", 606c103de24SGrant Likely .id_table = ioh_gpio_pcidev_id, 607c103de24SGrant Likely .probe = ioh_gpio_probe, 608c103de24SGrant Likely .remove = __devexit_p(ioh_gpio_remove), 609c103de24SGrant Likely .suspend = ioh_gpio_suspend, 610c103de24SGrant Likely .resume = ioh_gpio_resume 611c103de24SGrant Likely }; 612c103de24SGrant Likely 613c103de24SGrant Likely static int __init ioh_gpio_pci_init(void) 614c103de24SGrant Likely { 615c103de24SGrant Likely return pci_register_driver(&ioh_gpio_driver); 616c103de24SGrant Likely } 617c103de24SGrant Likely module_init(ioh_gpio_pci_init); 618c103de24SGrant Likely 619c103de24SGrant Likely static void __exit ioh_gpio_pci_exit(void) 620c103de24SGrant Likely { 621c103de24SGrant Likely pci_unregister_driver(&ioh_gpio_driver); 622c103de24SGrant Likely } 623c103de24SGrant Likely module_exit(ioh_gpio_pci_exit); 624c103de24SGrant Likely 625c103de24SGrant Likely MODULE_DESCRIPTION("OKI SEMICONDUCTOR ML-IOH series GPIO Driver"); 626c103de24SGrant Likely MODULE_LICENSE("GPL"); 627