* @gpio_use_sel: Save GPIO_USE_SEL1~4 register for PM
* @ch: Indicate GPIO channel
* @irq_base: Save base of IRQ number for interrupt
- * @spinlock: Used for register access protection
+ * @spinlock: Shared register access lock
*/
struct ioh_gpio {
void __iomem *base;
u32 gpio_use_sel;
int ch;
int irq_base;
+ raw_spinlock_t *spinlock;
+};
+
+struct ioh_gpio_device {
raw_spinlock_t spinlock;
+ struct ioh_gpio chip[8];
};
static const int num_ports[] = {6, 12, 16, 16, 15, 16, 16, 12};
struct ioh_gpio *chip = gpiochip_get_data(gpio);
unsigned long flags;
- raw_spin_lock_irqsave(&chip->spinlock, flags);
+ raw_spin_lock_irqsave(chip->spinlock, flags);
reg_val = ioread32(&chip->reg->regs[chip->ch].po);
if (val)
reg_val |= BIT(nr);
reg_val &= ~BIT(nr);
iowrite32(reg_val, &chip->reg->regs[chip->ch].po);
- raw_spin_unlock_irqrestore(&chip->spinlock, flags);
+ raw_spin_unlock_irqrestore(chip->spinlock, flags);
return 0;
}
u32 reg_val;
unsigned long flags;
- raw_spin_lock_irqsave(&chip->spinlock, flags);
+ raw_spin_lock_irqsave(chip->spinlock, flags);
pm = ioread32(&chip->reg->regs[chip->ch].pm);
pm &= BIT(num_ports[chip->ch]) - 1;
pm |= BIT(nr);
reg_val &= ~BIT(nr);
iowrite32(reg_val, &chip->reg->regs[chip->ch].po);
- raw_spin_unlock_irqrestore(&chip->spinlock, flags);
+ raw_spin_unlock_irqrestore(chip->spinlock, flags);
return 0;
}
u32 pm;
unsigned long flags;
- raw_spin_lock_irqsave(&chip->spinlock, flags);
+ raw_spin_lock_irqsave(chip->spinlock, flags);
pm = ioread32(&chip->reg->regs[chip->ch].pm);
pm &= BIT(num_ports[chip->ch]) - 1;
pm &= ~BIT(nr);
iowrite32(pm, &chip->reg->regs[chip->ch].pm);
- raw_spin_unlock_irqrestore(&chip->spinlock, flags);
+ raw_spin_unlock_irqrestore(chip->spinlock, flags);
return 0;
}
dev_dbg(chip->dev, "%s:irq=%d type=%d ch=%d pos=%d type=%d\n",
__func__, irq, type, ch, im_pos, type);
- raw_spin_lock_irqsave(&chip->spinlock, flags);
+ raw_spin_lock_irqsave(chip->spinlock, flags);
switch (type) {
case IRQ_TYPE_EDGE_RISING:
ien = ioread32(&chip->reg->regs[chip->ch].ien);
iowrite32(ien | BIT(ch), &chip->reg->regs[chip->ch].ien);
end:
- raw_spin_unlock_irqrestore(&chip->spinlock, flags);
+ raw_spin_unlock_irqrestore(chip->spinlock, flags);
return 0;
}
unsigned long flags;
u32 ien;
- raw_spin_lock_irqsave(&chip->spinlock, flags);
+ raw_spin_lock_irqsave(chip->spinlock, flags);
ien = ioread32(&chip->reg->regs[chip->ch].ien);
ien &= ~BIT(d->irq - chip->irq_base);
iowrite32(ien, &chip->reg->regs[chip->ch].ien);
- raw_spin_unlock_irqrestore(&chip->spinlock, flags);
+ raw_spin_unlock_irqrestore(chip->spinlock, flags);
}
static void ioh_irq_enable(struct irq_data *d)
unsigned long flags;
u32 ien;
- raw_spin_lock_irqsave(&chip->spinlock, flags);
+ raw_spin_lock_irqsave(chip->spinlock, flags);
ien = ioread32(&chip->reg->regs[chip->ch].ien);
ien |= BIT(d->irq - chip->irq_base);
iowrite32(ien, &chip->reg->regs[chip->ch].ien);
- raw_spin_unlock_irqrestore(&chip->spinlock, flags);
+ raw_spin_unlock_irqrestore(chip->spinlock, flags);
}
static irqreturn_t ioh_gpio_handler(int irq, void *dev_id)
int ret;
int i, j;
struct ioh_gpio *chip;
+ struct ioh_gpio_device *priv;
void __iomem *base;
- void *chip_save;
int irq_base;
ret = pcim_enable_device(pdev);
return -ENOMEM;
}
- chip_save = devm_kcalloc(dev, 8, sizeof(*chip), GFP_KERNEL);
- if (chip_save == NULL) {
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
return -ENOMEM;
- }
- chip = chip_save;
+ raw_spin_lock_init(&priv->spinlock);
+ chip = priv->chip;
for (i = 0; i < 8; i++, chip++) {
chip->dev = dev;
chip->base = base;
chip->reg = chip->base;
chip->ch = i;
- raw_spin_lock_init(&chip->spinlock);
+ chip->spinlock = &priv->spinlock;
ioh_gpio_setup(chip, num_ports[i]);
ret = devm_gpiochip_add_data(dev, &chip->gpio, chip);
if (ret) {
}
}
- chip = chip_save;
+ chip = priv->chip;
for (j = 0; j < 8; j++, chip++) {
irq_base = devm_irq_alloc_descs(dev, -1, IOH_IRQ_BASE,
num_ports[j], NUMA_NO_NODE);
return ret;
}
- chip = chip_save;
+ chip = priv->chip;
ret = devm_request_irq(dev, pdev->irq, ioh_gpio_handler,
IRQF_SHARED, KBUILD_MODNAME, chip);
if (ret != 0) {
return ret;
}
- pci_set_drvdata(pdev, chip);
+ pci_set_drvdata(pdev, priv);
return 0;
}
static int ioh_gpio_suspend(struct device *dev)
{
- struct ioh_gpio *chip = dev_get_drvdata(dev);
+ struct ioh_gpio_device *priv = dev_get_drvdata(dev);
unsigned long flags;
- raw_spin_lock_irqsave(&chip->spinlock, flags);
- ioh_gpio_save_reg_conf(chip);
- raw_spin_unlock_irqrestore(&chip->spinlock, flags);
+ raw_spin_lock_irqsave(&priv->spinlock, flags);
+ ioh_gpio_save_reg_conf(priv->chip);
+ raw_spin_unlock_irqrestore(&priv->spinlock, flags);
return 0;
}
static int ioh_gpio_resume(struct device *dev)
{
- struct ioh_gpio *chip = dev_get_drvdata(dev);
+ struct ioh_gpio_device *priv = dev_get_drvdata(dev);
unsigned long flags;
- raw_spin_lock_irqsave(&chip->spinlock, flags);
- iowrite32(0x01, &chip->reg->srst);
- iowrite32(0x00, &chip->reg->srst);
- ioh_gpio_restore_reg_conf(chip);
- raw_spin_unlock_irqrestore(&chip->spinlock, flags);
+ raw_spin_lock_irqsave(&priv->spinlock, flags);
+ iowrite32(0x01, &priv->chip->reg->srst);
+ iowrite32(0x00, &priv->chip->reg->srst);
+ ioh_gpio_restore_reg_conf(priv->chip);
+ raw_spin_unlock_irqrestore(&priv->spinlock, flags);
return 0;
}