mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-26 19:41:00 +07:00
Merge branch 'samsung-irq' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/misc-2.6 into devel-stable
This commit is contained in:
commit
1cf02bbd51
@ -58,12 +58,7 @@ void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid)
|
||||
vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, 0);
|
||||
|
||||
/* add the timer sub-irqs */
|
||||
|
||||
s3c_init_vic_timer_irq(IRQ_TIMER0_VIC, IRQ_TIMER0);
|
||||
s3c_init_vic_timer_irq(IRQ_TIMER1_VIC, IRQ_TIMER1);
|
||||
s3c_init_vic_timer_irq(IRQ_TIMER2_VIC, IRQ_TIMER2);
|
||||
s3c_init_vic_timer_irq(IRQ_TIMER3_VIC, IRQ_TIMER3);
|
||||
s3c_init_vic_timer_irq(IRQ_TIMER4_VIC, IRQ_TIMER4);
|
||||
s3c_init_vic_timer_irq(5, IRQ_TIMER0);
|
||||
|
||||
s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs));
|
||||
}
|
||||
|
@ -41,72 +41,11 @@ struct s5p_gpioint_bank {
|
||||
|
||||
LIST_HEAD(banks);
|
||||
|
||||
static int s5p_gpioint_get_offset(struct irq_data *data)
|
||||
static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type)
|
||||
{
|
||||
struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data);
|
||||
return data->irq - chip->irq_base;
|
||||
}
|
||||
|
||||
static void s5p_gpioint_ack(struct irq_data *data)
|
||||
{
|
||||
struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data);
|
||||
int group, offset, pend_offset;
|
||||
unsigned int value;
|
||||
|
||||
group = chip->group;
|
||||
offset = s5p_gpioint_get_offset(data);
|
||||
pend_offset = REG_OFFSET(group);
|
||||
|
||||
value = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
|
||||
value |= BIT(offset);
|
||||
__raw_writel(value, GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
|
||||
}
|
||||
|
||||
static void s5p_gpioint_mask(struct irq_data *data)
|
||||
{
|
||||
struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data);
|
||||
int group, offset, mask_offset;
|
||||
unsigned int value;
|
||||
|
||||
group = chip->group;
|
||||
offset = s5p_gpioint_get_offset(data);
|
||||
mask_offset = REG_OFFSET(group);
|
||||
|
||||
value = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
|
||||
value |= BIT(offset);
|
||||
__raw_writel(value, GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
|
||||
}
|
||||
|
||||
static void s5p_gpioint_unmask(struct irq_data *data)
|
||||
{
|
||||
struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data);
|
||||
int group, offset, mask_offset;
|
||||
unsigned int value;
|
||||
|
||||
group = chip->group;
|
||||
offset = s5p_gpioint_get_offset(data);
|
||||
mask_offset = REG_OFFSET(group);
|
||||
|
||||
value = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
|
||||
value &= ~BIT(offset);
|
||||
__raw_writel(value, GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
|
||||
}
|
||||
|
||||
static void s5p_gpioint_mask_ack(struct irq_data *data)
|
||||
{
|
||||
s5p_gpioint_mask(data);
|
||||
s5p_gpioint_ack(data);
|
||||
}
|
||||
|
||||
static int s5p_gpioint_set_type(struct irq_data *data, unsigned int type)
|
||||
{
|
||||
struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data);
|
||||
int group, offset, con_offset;
|
||||
unsigned int value;
|
||||
|
||||
group = chip->group;
|
||||
offset = s5p_gpioint_get_offset(data);
|
||||
con_offset = REG_OFFSET(group);
|
||||
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
|
||||
struct irq_chip_type *ct = gc->chip_types;
|
||||
unsigned int shift = (d->irq - gc->irq_base) << 2;
|
||||
|
||||
switch (type) {
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
@ -130,23 +69,12 @@ static int s5p_gpioint_set_type(struct irq_data *data, unsigned int type)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
value = __raw_readl(GPIO_BASE(chip) + CON_OFFSET + con_offset);
|
||||
value &= ~(0x7 << (offset * 0x4));
|
||||
value |= (type << (offset * 0x4));
|
||||
__raw_writel(value, GPIO_BASE(chip) + CON_OFFSET + con_offset);
|
||||
|
||||
gc->type_cache &= ~(0x7 << shift);
|
||||
gc->type_cache |= type << shift;
|
||||
writel(gc->type_cache, gc->reg_base + ct->regs.type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_chip s5p_gpioint = {
|
||||
.name = "s5p_gpioint",
|
||||
.irq_ack = s5p_gpioint_ack,
|
||||
.irq_mask = s5p_gpioint_mask,
|
||||
.irq_mask_ack = s5p_gpioint_mask_ack,
|
||||
.irq_unmask = s5p_gpioint_unmask,
|
||||
.irq_set_type = s5p_gpioint_set_type,
|
||||
};
|
||||
|
||||
static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
struct s5p_gpioint_bank *bank = irq_get_handler_data(irq);
|
||||
@ -179,9 +107,10 @@ static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
|
||||
static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
|
||||
{
|
||||
static int used_gpioint_groups = 0;
|
||||
int irq, group = chip->group;
|
||||
int i;
|
||||
int group = chip->group;
|
||||
struct s5p_gpioint_bank *bank = NULL;
|
||||
struct irq_chip_generic *gc;
|
||||
struct irq_chip_type *ct;
|
||||
|
||||
if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT)
|
||||
return -ENOMEM;
|
||||
@ -211,19 +140,28 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
|
||||
* chained GPIO irq has been successfully registered, allocate new gpio
|
||||
* int group and assign irq nubmers
|
||||
*/
|
||||
|
||||
chip->irq_base = S5P_GPIOINT_BASE +
|
||||
used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE;
|
||||
used_gpioint_groups++;
|
||||
|
||||
bank->chips[group - bank->start] = chip;
|
||||
for (i = 0; i < chip->chip.ngpio; i++) {
|
||||
irq = chip->irq_base + i;
|
||||
irq_set_chip(irq, &s5p_gpioint);
|
||||
irq_set_handler_data(irq, chip);
|
||||
irq_set_handler(irq, handle_level_irq);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
}
|
||||
|
||||
gc = irq_alloc_generic_chip("s5p_gpioint", 1, chip->irq_base,
|
||||
(void __iomem *)GPIO_BASE(chip),
|
||||
handle_level_irq);
|
||||
if (!gc)
|
||||
return -ENOMEM;
|
||||
ct = gc->chip_types;
|
||||
ct->chip.irq_ack = irq_gc_ack;
|
||||
ct->chip.irq_mask = irq_gc_mask_set_bit;
|
||||
ct->chip.irq_unmask = irq_gc_mask_clr_bit;
|
||||
ct->chip.irq_set_type = s5p_gpioint_set_type,
|
||||
ct->regs.ack = PEND_OFFSET + REG_OFFSET(chip->group);
|
||||
ct->regs.mask = MASK_OFFSET + REG_OFFSET(chip->group);
|
||||
ct->regs.type = CON_OFFSET + REG_OFFSET(chip->group);
|
||||
irq_setup_generic_chip(gc, IRQ_MSK(chip->chip.ngpio),
|
||||
IRQ_GC_INIT_MASK_CACHE,
|
||||
IRQ_NOREQUEST | IRQ_NOPROBE, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -64,11 +64,7 @@ void __init s5p_init_irq(u32 *vic, u32 num_vic)
|
||||
vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0);
|
||||
#endif
|
||||
|
||||
s3c_init_vic_timer_irq(IRQ_TIMER0_VIC, IRQ_TIMER0);
|
||||
s3c_init_vic_timer_irq(IRQ_TIMER1_VIC, IRQ_TIMER1);
|
||||
s3c_init_vic_timer_irq(IRQ_TIMER2_VIC, IRQ_TIMER2);
|
||||
s3c_init_vic_timer_irq(IRQ_TIMER3_VIC, IRQ_TIMER3);
|
||||
s3c_init_vic_timer_irq(IRQ_TIMER4_VIC, IRQ_TIMER4);
|
||||
s3c_init_vic_timer_irq(5, IRQ_TIMER0);
|
||||
|
||||
s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs));
|
||||
}
|
||||
|
@ -10,4 +10,4 @@
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
extern void s3c_init_vic_timer_irq(unsigned int vic, unsigned int timer);
|
||||
extern void s3c_init_vic_timer_irq(unsigned int num, unsigned int timer_irq);
|
||||
|
@ -27,60 +27,6 @@
|
||||
/* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
|
||||
* are consecutive when looking up the interrupt in the demux routines.
|
||||
*/
|
||||
|
||||
static inline void __iomem *s3c_irq_uart_base(struct irq_data *data)
|
||||
{
|
||||
struct s3c_uart_irq *uirq = irq_data_get_irq_chip_data(data);
|
||||
return uirq->regs;
|
||||
}
|
||||
|
||||
static inline unsigned int s3c_irq_uart_bit(unsigned int irq)
|
||||
{
|
||||
return irq & 3;
|
||||
}
|
||||
|
||||
static void s3c_irq_uart_mask(struct irq_data *data)
|
||||
{
|
||||
void __iomem *regs = s3c_irq_uart_base(data);
|
||||
unsigned int bit = s3c_irq_uart_bit(data->irq);
|
||||
u32 reg;
|
||||
|
||||
reg = __raw_readl(regs + S3C64XX_UINTM);
|
||||
reg |= (1 << bit);
|
||||
__raw_writel(reg, regs + S3C64XX_UINTM);
|
||||
}
|
||||
|
||||
static void s3c_irq_uart_maskack(struct irq_data *data)
|
||||
{
|
||||
void __iomem *regs = s3c_irq_uart_base(data);
|
||||
unsigned int bit = s3c_irq_uart_bit(data->irq);
|
||||
u32 reg;
|
||||
|
||||
reg = __raw_readl(regs + S3C64XX_UINTM);
|
||||
reg |= (1 << bit);
|
||||
__raw_writel(reg, regs + S3C64XX_UINTM);
|
||||
__raw_writel(1 << bit, regs + S3C64XX_UINTP);
|
||||
}
|
||||
|
||||
static void s3c_irq_uart_unmask(struct irq_data *data)
|
||||
{
|
||||
void __iomem *regs = s3c_irq_uart_base(data);
|
||||
unsigned int bit = s3c_irq_uart_bit(data->irq);
|
||||
u32 reg;
|
||||
|
||||
reg = __raw_readl(regs + S3C64XX_UINTM);
|
||||
reg &= ~(1 << bit);
|
||||
__raw_writel(reg, regs + S3C64XX_UINTM);
|
||||
}
|
||||
|
||||
static void s3c_irq_uart_ack(struct irq_data *data)
|
||||
{
|
||||
void __iomem *regs = s3c_irq_uart_base(data);
|
||||
unsigned int bit = s3c_irq_uart_bit(data->irq);
|
||||
|
||||
__raw_writel(1 << bit, regs + S3C64XX_UINTP);
|
||||
}
|
||||
|
||||
static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
struct s3c_uart_irq *uirq = desc->irq_data.handler_data;
|
||||
@ -97,30 +43,25 @@ static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
|
||||
generic_handle_irq(base + 3);
|
||||
}
|
||||
|
||||
static struct irq_chip s3c_irq_uart = {
|
||||
.name = "s3c-uart",
|
||||
.irq_mask = s3c_irq_uart_mask,
|
||||
.irq_unmask = s3c_irq_uart_unmask,
|
||||
.irq_mask_ack = s3c_irq_uart_maskack,
|
||||
.irq_ack = s3c_irq_uart_ack,
|
||||
};
|
||||
|
||||
static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq)
|
||||
{
|
||||
void __iomem *reg_base = uirq->regs;
|
||||
unsigned int irq;
|
||||
int offs;
|
||||
struct irq_chip_generic *gc;
|
||||
struct irq_chip_type *ct;
|
||||
|
||||
/* mask all interrupts at the start. */
|
||||
__raw_writel(0xf, reg_base + S3C64XX_UINTM);
|
||||
|
||||
for (offs = 0; offs < 3; offs++) {
|
||||
irq = uirq->base_irq + offs;
|
||||
|
||||
irq_set_chip_and_handler(irq, &s3c_irq_uart, handle_level_irq);
|
||||
irq_set_chip_data(irq, uirq);
|
||||
set_irq_flags(irq, IRQF_VALID);
|
||||
}
|
||||
gc = irq_alloc_generic_chip("s3c-uart", 1, uirq->base_irq, reg_base,
|
||||
handle_level_irq);
|
||||
ct = gc->chip_types;
|
||||
ct->chip.irq_ack = irq_gc_ack;
|
||||
ct->chip.irq_mask = irq_gc_mask_set_bit;
|
||||
ct->chip.irq_unmask = irq_gc_mask_clr_bit;
|
||||
ct->regs.ack = S3C64XX_UINTP;
|
||||
ct->regs.mask = S3C64XX_UINTM;
|
||||
irq_setup_generic_chip(gc, IRQ_MSK(4), IRQ_GC_INIT_MASK_CACHE,
|
||||
IRQ_NOREQUEST | IRQ_NOPROBE, 0);
|
||||
|
||||
irq_set_handler_data(uirq->parent_irq, uirq);
|
||||
irq_set_chained_handler(uirq->parent_irq, s3c_irq_demux_uart);
|
||||
|
@ -28,60 +28,43 @@ static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc)
|
||||
}
|
||||
|
||||
/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
|
||||
|
||||
static void s3c_irq_timer_mask(struct irq_data *data)
|
||||
static void s3c_irq_timer_ack(struct irq_data *d)
|
||||
{
|
||||
u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
|
||||
u32 mask = (u32)data->chip_data;
|
||||
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
|
||||
u32 mask = (1 << 5) << (d->irq - gc->irq_base);
|
||||
|
||||
reg &= 0x1f; /* mask out pending interrupts */
|
||||
reg &= ~mask;
|
||||
__raw_writel(reg, S3C64XX_TINT_CSTAT);
|
||||
irq_reg_writel(mask | gc->mask_cache, gc->reg_base);
|
||||
}
|
||||
|
||||
static void s3c_irq_timer_unmask(struct irq_data *data)
|
||||
{
|
||||
u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
|
||||
u32 mask = (u32)data->chip_data;
|
||||
|
||||
reg &= 0x1f; /* mask out pending interrupts */
|
||||
reg |= mask;
|
||||
__raw_writel(reg, S3C64XX_TINT_CSTAT);
|
||||
}
|
||||
|
||||
static void s3c_irq_timer_ack(struct irq_data *data)
|
||||
{
|
||||
u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
|
||||
u32 mask = (u32)data->chip_data;
|
||||
|
||||
reg &= 0x1f;
|
||||
reg |= mask << 5;
|
||||
__raw_writel(reg, S3C64XX_TINT_CSTAT);
|
||||
}
|
||||
|
||||
static struct irq_chip s3c_irq_timer = {
|
||||
.name = "s3c-timer",
|
||||
.irq_mask = s3c_irq_timer_mask,
|
||||
.irq_unmask = s3c_irq_timer_unmask,
|
||||
.irq_ack = s3c_irq_timer_ack,
|
||||
};
|
||||
|
||||
/**
|
||||
* s3c_init_vic_timer_irq() - initialise timer irq chanined off VIC.\
|
||||
* @parent_irq: The parent IRQ on the VIC for the timer.
|
||||
* @timer_irq: The IRQ to be used for the timer.
|
||||
* @num: Number of timers to initialize
|
||||
* @timer_irq: Base IRQ number to be used for the timers.
|
||||
*
|
||||
* Register the necessary IRQ chaining and support for the timer IRQs
|
||||
* chained of the VIC.
|
||||
*/
|
||||
void __init s3c_init_vic_timer_irq(unsigned int parent_irq,
|
||||
unsigned int timer_irq)
|
||||
void __init s3c_init_vic_timer_irq(unsigned int num, unsigned int timer_irq)
|
||||
{
|
||||
unsigned int pirq[5] = { IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
|
||||
IRQ_TIMER3_VIC, IRQ_TIMER4_VIC };
|
||||
struct irq_chip_generic *s3c_tgc;
|
||||
struct irq_chip_type *ct;
|
||||
unsigned int i;
|
||||
|
||||
irq_set_chained_handler(parent_irq, s3c_irq_demux_vic_timer);
|
||||
irq_set_handler_data(parent_irq, (void *)timer_irq);
|
||||
s3c_tgc = irq_alloc_generic_chip("s3c-timer", 1, timer_irq,
|
||||
S3C64XX_TINT_CSTAT, handle_level_irq);
|
||||
ct = s3c_tgc->chip_types;
|
||||
ct->chip.irq_mask = irq_gc_mask_clr_bit;
|
||||
ct->chip.irq_unmask = irq_gc_mask_set_bit;
|
||||
ct->chip.irq_ack = s3c_irq_timer_ack;
|
||||
irq_setup_generic_chip(s3c_tgc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
|
||||
IRQ_NOREQUEST | IRQ_NOPROBE, 0);
|
||||
/* Clear the upper bits of the mask_cache*/
|
||||
s3c_tgc->mask_cache &= 0x1f;
|
||||
|
||||
irq_set_chip_and_handler(timer_irq, &s3c_irq_timer, handle_level_irq);
|
||||
irq_set_chip_data(timer_irq, (void *)(1 << (timer_irq - IRQ_TIMER0)));
|
||||
set_irq_flags(timer_irq, IRQF_VALID);
|
||||
for (i = 0; i < num; i++, timer_irq++) {
|
||||
irq_set_chained_handler(pirq[i], s3c_irq_demux_vic_timer);
|
||||
irq_set_handler_data(pirq[i], (void *)timer_irq);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user