void __init board_a9m9750dev_init_irq(void) { u32 reg; int i; /* * configure gpio for IRQ_EXT2 * use GPIO 11, because GPIO 32 is used for the LCD */ /* XXX: proper GPIO handling */ BBU_GC(2) &= ~0x2000; for (i = FPGA_IRQ(0); i <= FPGA_IRQ(7); ++i) { set_irq_chip(i, &a9m9750dev_fpga_chip); set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID); } /* IRQ_EXT2: level sensitive + active low */ reg = SYS_EIC(2); REGSET(reg, SYS_EIC, PLTY, AL); REGSET(reg, SYS_EIC, LVEDG, LEVEL); SYS_EIC(2) = reg; set_irq_chained_handler(IRQ_EXT2, a9m9750dev_fpga_demux_handler); }
void __init board_a9m9750dev_init_machine(void) { u32 reg; /* setup static CS0: memory base ... */ REGSETIM(SYS_SMCSSMB(0), SYS_SMCSSMB, CSxB, NS9XXX_CSxSTAT_PHYS(0) >> 12); /* ... and mask */ reg = SYS_SMCSSMM(0); REGSETIM(reg, SYS_SMCSSMM, CSxM, 0xfffff); REGSET(reg, SYS_SMCSSMM, CSEx, EN); SYS_SMCSSMM(0) = reg; /* setup static CS0: memory configuration */ reg = MEM_SMC(0); REGSET(reg, MEM_SMC, WSMC, OFF); REGSET(reg, MEM_SMC, BSMC, OFF); REGSET(reg, MEM_SMC, EW, OFF); REGSET(reg, MEM_SMC, PB, 1); REGSET(reg, MEM_SMC, PC, AL); REGSET(reg, MEM_SMC, PM, DIS); REGSET(reg, MEM_SMC, MW, 8); MEM_SMC(0) = reg; /* setup static CS0: timing */ MEM_SMWED(0) = 0x2; MEM_SMOED(0) = 0x2; MEM_SMRD(0) = 0x6; MEM_SMWD(0) = 0x6; platform_add_devices(board_a9m9750dev_devices, ARRAY_SIZE(board_a9m9750dev_devices)); }
static int ns9360_clockevent_setnextevent(unsigned long evt, struct clock_event_device *clk) { u32 tc = __raw_readl(SYS_TC(TIMER_CLOCKEVENT)); if (REGGET(tc, SYS_TCx, TEN)) { REGSET(tc, SYS_TCx, TEN, DIS); __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT)); } REGSET(tc, SYS_TCx, TEN, EN); __raw_writel(evt, SYS_TRC(TIMER_CLOCKEVENT)); __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT)); return 0; }
static void ns9360_clockevent_setmode(enum clock_event_mode mode, struct clock_event_device *clk) { u32 tc = __raw_readl(SYS_TC(TIMER_CLOCKEVENT)); switch (mode) { case CLOCK_EVT_MODE_PERIODIC: __raw_writel(latch, SYS_TRC(TIMER_CLOCKEVENT)); REGSET(tc, SYS_TCx, REN, EN); REGSET(tc, SYS_TCx, INTS, EN); REGSET(tc, SYS_TCx, TEN, EN); break; case CLOCK_EVT_MODE_ONESHOT: REGSET(tc, SYS_TCx, REN, DIS); REGSET(tc, SYS_TCx, INTS, EN); /* fall through */ case CLOCK_EVT_MODE_UNUSED: case CLOCK_EVT_MODE_SHUTDOWN: case CLOCK_EVT_MODE_RESUME: default: REGSET(tc, SYS_TCx, TEN, DIS); break; } __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT)); }
static irqreturn_t ns9360_clockevent_handler(int irq, void *dev_id) { int timerno = irq - IRQ_NS9360_TIMER0; u32 tc; struct clock_event_device *evt = &ns9360_clockevent_device; /* clear irq */ tc = __raw_readl(SYS_TC(timerno)); if (REGGET(tc, SYS_TCx, REN) == SYS_TCx_REN_DIS) { REGSET(tc, SYS_TCx, TEN, DIS); __raw_writel(tc, SYS_TC(timerno)); } REGSET(tc, SYS_TCx, INTC, SET); __raw_writel(tc, SYS_TC(timerno)); REGSET(tc, SYS_TCx, INTC, UNSET); __raw_writel(tc, SYS_TC(timerno)); evt->event_handler(evt); return IRQ_HANDLED; }
static void __init ns9360_timer_init(void) { int tc; tc = __raw_readl(SYS_TC(TIMER_CLOCKSOURCE)); if (REGGET(tc, SYS_TCx, TEN)) { REGSET(tc, SYS_TCx, TEN, DIS); __raw_writel(tc, SYS_TC(TIMER_CLOCKSOURCE)); } __raw_writel(0, SYS_TRC(TIMER_CLOCKSOURCE)); REGSET(tc, SYS_TCx, TEN, EN); REGSET(tc, SYS_TCx, TDBG, STOP); REGSET(tc, SYS_TCx, TLCS, CPU); REGSET(tc, SYS_TCx, TM, IEE); REGSET(tc, SYS_TCx, INTS, DIS); REGSET(tc, SYS_TCx, UDS, UP); REGSET(tc, SYS_TCx, TSZ, 32); REGSET(tc, SYS_TCx, REN, EN); __raw_writel(tc, SYS_TC(TIMER_CLOCKSOURCE)); ns9360_clocksource.mult = clocksource_hz2mult(ns9360_cpuclock(), ns9360_clocksource.shift); clocksource_register(&ns9360_clocksource); latch = SH_DIV(ns9360_cpuclock(), HZ, 0); tc = __raw_readl(SYS_TC(TIMER_CLOCKEVENT)); REGSET(tc, SYS_TCx, TEN, DIS); REGSET(tc, SYS_TCx, TDBG, STOP); REGSET(tc, SYS_TCx, TLCS, CPU); REGSET(tc, SYS_TCx, TM, IEE); REGSET(tc, SYS_TCx, INTS, DIS); REGSET(tc, SYS_TCx, UDS, DOWN); REGSET(tc, SYS_TCx, TSZ, 32); REGSET(tc, SYS_TCx, REN, EN); __raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT)); ns9360_clockevent_device.mult = div_sc(ns9360_cpuclock(), NSEC_PER_SEC, ns9360_clockevent_device.shift); ns9360_clockevent_device.max_delta_ns = clockevent_delta2ns(-1, &ns9360_clockevent_device); ns9360_clockevent_device.min_delta_ns = clockevent_delta2ns(1, &ns9360_clockevent_device); ns9360_clockevent_device.cpumask = cpumask_of(0); clockevents_register_device(&ns9360_clockevent_device); setup_irq(IRQ_NS9360_TIMER0 + TIMER_CLOCKEVENT, &ns9360_clockevent_action); }
static int table_resize_helper(table_t* table, int col_pos, int col_delta, int row_pos, int row_delta) { size_t size; table_cell_t* cols; table_cell_t* rows; table_cell_t* cells; table_region_t copy_src[4]; table_region_t copy_dst[4]; table_region_t init_dst[3]; table_region_t free_src[3]; int copy_count, init_count, free_count; int col_count, row_count; int i; table_refresh_detail_t refresh_detail; TABLE_TRACE("table_resize_helper(%p, %d, %d, %d, %d)", table, col_pos, col_delta, row_pos, row_delta); if(col_delta == 0 && row_delta == 0) { /* noop */ return 0; } col_count = table->col_count + col_delta; row_count = table->row_count + row_delta; if(col_delta == 0) col_pos = col_count; if(row_delta == 0) row_pos = row_count; /* Allocate buffer for resized table */ size = col_count * sizeof(table_cell_t) + row_count * sizeof(table_cell_t) + (col_count*row_count) * sizeof(table_cell_t); if(size > 0) { cells = (table_cell_t*) malloc(size); if(MC_ERR(cells == NULL)) { MC_TRACE("table_resize: malloc() failed"); return -1; } cols = cells + (col_count * row_count); rows = cols + col_count; } else { cells = NULL; cols = NULL; rows = NULL; } /* Analyze which region of the original cells shall be freed, which shall * be reused in the reallocated buffer, and which in the new buffer need * initialization. */ #define REGSET(reg, c0, r0, c1, r1) \ do { reg.col0 = c0; reg.row0 = r0; \ reg.col1 = c1; reg.row1 = r1; } while (0) if(col_delta >= 0 && row_delta >= 0) { /* * +---+-+---+ * +---+---+ | 0 | | 1 | * | 0 | 1 | +---+-+---+ * +---+---+ ---> | | * | 2 | 3 | +---+-+---+ * +---+---+ | 2 | | 3 | * +---+-+---+ */ REGSET(copy_src[0], 0, 0, col_pos, row_pos); REGSET(copy_dst[0], 0, 0, col_pos, row_pos); REGSET(copy_src[1], col_pos, 0, table->col_count, row_pos); REGSET(copy_dst[1], col_pos + col_delta, 0, col_count, row_pos); REGSET(copy_src[2], 0, row_pos, col_pos, table->row_count); REGSET(copy_dst[2], 0, row_pos + row_delta, col_pos, row_count); REGSET(copy_src[3], col_pos, row_pos, table->col_count, table->row_count); REGSET(copy_dst[3], col_pos + col_delta, row_pos + row_delta, col_count, row_count); copy_count = 4; REGSET(init_dst[0], col_pos, 0, col_pos + col_delta, row_pos); REGSET(init_dst[1], 0, row_pos, col_count, row_pos + row_delta); REGSET(init_dst[2], col_pos, row_pos + row_delta, col_pos + col_delta, row_count); init_count = 3; free_count = 0; } else if(col_delta >= 0 && row_delta < 0) { /* * +---+---+ * | 0 | 1 | +---+-+---+ * +---+---+ | 0 | | 1 | * | | ---> +---+ +---+ * +---+---+ | 2 | | 3 | * | 2 | 3 | +---+-+---+ * +---+---+ */ REGSET(copy_src[0], 0, 0, col_pos, row_pos); REGSET(copy_dst[0], 0, 0, col_pos, row_pos); REGSET(copy_src[1], col_pos, 0, table->col_count, row_pos); REGSET(copy_dst[1], col_pos + col_delta, 0, col_count, row_pos); REGSET(copy_src[2], 0, row_pos - row_delta, col_pos, table->row_count); REGSET(copy_dst[2], 0, row_pos, col_pos, row_count); REGSET(copy_src[3], col_pos, row_pos - row_delta, table->col_count, table->row_count); REGSET(copy_dst[3], col_pos + col_delta, row_pos, col_count, row_count); copy_count = 4; REGSET(init_dst[0], col_pos, 0, col_pos + col_delta, row_count); init_count = 1; REGSET(free_src[0], 0, row_pos, table->col_count, row_pos - row_delta); free_count = 1; } else if(col_delta < 0 && row_delta >= 0) { /* * +---+---+ * +---+-+---+ | 0 | 1 | * | 0 | | 1 | +---+---+ * +---+ +---+ ---> | | * | 2 | | 3 | +---+---+ * +---+-+---+ | 2 | 3 | * +---+---+ */ REGSET(copy_src[0], 0, 0, col_pos, row_pos); REGSET(copy_dst[0], 0, 0, col_pos, row_pos); REGSET(copy_src[1], col_pos - col_delta, 0, table->col_count, row_pos); REGSET(copy_dst[1], col_pos, 0, col_count, row_pos); REGSET(copy_src[2], 0, row_pos, col_pos, table->row_count); REGSET(copy_dst[2], 0, row_pos + row_delta, col_pos, row_count); REGSET(copy_src[3], col_pos - col_delta, row_pos, table->col_count, table->row_count); REGSET(copy_dst[3], col_pos, row_pos + row_delta, col_count, row_count); copy_count = 4; REGSET(init_dst[0], 0, row_pos, col_count, row_pos + row_delta); init_count = 1; REGSET(free_src[0], col_pos, 0, col_pos - col_delta, table->row_count); free_count = 1; } else { MC_ASSERT(col_delta < 0 && row_delta < 0); /* * +---+-+---+ * | 0 | | 1 | +---+---+ * +---+-+---+ | 0 | 1 | * | | ---> +---+---+ * +---+-+---+ | 2 | 3 | * | 2 | | 3 | +---+---+ * +---+-+---+ */ REGSET(copy_src[0], 0, 0, col_pos, row_pos); REGSET(copy_dst[0], 0, 0, col_pos, row_pos); REGSET(copy_src[1], col_pos - col_delta, 0, table->col_count, row_pos); REGSET(copy_dst[1], col_pos, 0, col_count, row_pos); REGSET(copy_src[2], 0, row_pos - row_delta, col_pos, table->row_count); REGSET(copy_dst[2], 0, row_pos, col_pos, row_count); REGSET(copy_src[3], col_pos - col_delta, row_pos - row_delta, table->col_count, table->row_count); REGSET(copy_dst[3], col_pos, row_pos, col_count, row_count); copy_count = 4; init_count = 0; REGSET(free_src[0], col_pos, 0, col_pos - col_delta, row_pos); REGSET(free_src[1], 0, row_pos, table->col_count, row_pos - row_delta); REGSET(free_src[2], col_pos, row_pos - row_delta, col_pos - col_delta, table->row_count); free_count = 3; } #undef REGSET /* Copy cells to be reused */ if(table->cells != NULL && cells != NULL) { for(i = 0; i < copy_count; i++) { MC_ASSERT(copy_src[i].col1-copy_src[i].col0 == copy_dst[i].col1-copy_dst[i].col0); MC_ASSERT(copy_src[i].row1-copy_src[i].row0 == copy_dst[i].row1-copy_dst[i].row0); if(col_delta == 0) { memcpy(&cells[copy_dst[i].row0 * col_count], &table->cells[copy_src[i].row0 * col_count], (copy_src[i].row1-copy_src[i].row0) * (copy_src[i].col1-copy_src[i].col0) * sizeof(table_cell_t)); } else { WORD row_src, row_dst; for(row_src = copy_src[i].row0, row_dst = copy_dst[i].row0; row_src < copy_src[i].row1; row_src++, row_dst++) { memcpy(&cells[row_dst * col_count + copy_dst[i].col0], &table->cells[row_src * table->col_count + copy_src[i].col0], (copy_src[i].col1-copy_src[i].col0) * sizeof(table_cell_t)); } } } } /* Init new cells in the new buffer */ if(cells != NULL) { for(i = 0; i < init_count; i++) { if(col_delta == 0) { memset(&cells[col_count * init_dst[i].row0], 0, col_count * (init_dst[i].row1-init_dst[i].row0) * sizeof(table_cell_t)); } else { WORD row; for(row = init_dst[i].row0; row < init_dst[i].row1; row++) { memset(&cells[row * col_count + init_dst[i].col0], 0, (init_dst[i].col1-init_dst[i].col0) * sizeof(table_cell_t)); } } } } /* Free bogus cells in the old buffer */ if(table->cells != NULL) { for(i = 0; i < free_count; i++) { WORD col, row; for(row = free_src[i].row0; row < free_src[i].row1; row++) { for(col = free_src[i].col0; col < free_src[i].col1; col++) { table_cell_clear(&table->cells[row * table->col_count + col]); } } } } /* Handle column headers */ if(cols != NULL && table->cols != NULL) { memcpy(&cols[0], &table->cols[0], col_pos * sizeof(table_cell_t)); if(col_delta > 0) memcpy(&cols[col_pos + col_delta], &table->cols[col_pos], (table->col_count - col_pos) * sizeof(table_cell_t)); else if(col_delta < 0) memcpy(&cols[col_pos], &table->cols[col_pos - col_delta], (col_count - col_pos) * sizeof(table_cell_t)); } if(cols != NULL && col_delta > 0) memset(&cols[col_pos], 0, col_delta * sizeof(table_cell_t)); if(table->cols != NULL && col_delta < 0) { WORD col; for(col = col_pos; col < col_pos - col_delta; col++) table_cell_clear(&table->cols[col]); } /* Handle row headers */ if(rows != NULL && table->rows != NULL) { memcpy(&rows[0], &table->rows[0], row_pos * sizeof(table_cell_t)); if(row_delta > 0) memcpy(&rows[row_pos + row_delta], &table->rows[row_pos], (table->row_count - row_pos) * sizeof(table_cell_t)); else if(row_delta < 0) memcpy(&rows[row_pos], &table->rows[row_pos - row_delta], (row_count - row_pos) * sizeof(table_cell_t)); } if(rows != NULL && row_delta > 0) memset(&rows[row_pos], 0, row_delta * sizeof(table_cell_t)); if(table->rows != NULL && row_delta < 0) { WORD row; for(row = row_pos; row < row_pos - row_delta; row++) table_cell_clear(&table->rows[row]); } /* Install the new buffer */ if(table->cells != NULL) free(table->cells); table->cols = cols; table->rows = rows; table->cells = cells; table->col_count = col_count; table->row_count = row_count; /* Refresh */ if(col_delta != 0) { refresh_detail.event = TABLE_COLCOUNT_CHANGED; refresh_detail.param[0] = table->col_count - col_delta; refresh_detail.param[1] = table->col_count; refresh_detail.param[2] = col_pos; table_refresh(table, &refresh_detail); } if(row_delta != 0) { refresh_detail.event = TABLE_ROWCOUNT_CHANGED; refresh_detail.param[0] = table->row_count - row_delta; refresh_detail.param[1] = table->row_count; refresh_detail.param[2] = row_pos; table_refresh(table, &refresh_detail); } return 0; }