void kempld_enable_uart_for_console(void) { if (!CONFIG(CONSOLE_SERIAL)) return; if (kempld_get_mutex(100) < 0) return; switch (CONFIG_UART_FOR_CONSOLE) { case 0: kempld_write8(KEMPLD_UART_0, KEMPLD_UART_ENABLE | KEMPLD_UART_3F8 << KEMPLD_UART_IO_SHIFT); break; case 1: kempld_write8(KEMPLD_UART_1, KEMPLD_UART_ENABLE | KEMPLD_UART_2F8 << KEMPLD_UART_IO_SHIFT); break; default: break; } kempld_release_mutex(); }
static int kempld_wdt_probe_stages(struct watchdog_device *wdd) { struct kempld_wdt_data *wdt_data = watchdog_get_drvdata(wdd); struct kempld_device_data *pld = wdt_data->pld; struct kempld_wdt_stage *pretimeout_stage; struct kempld_wdt_stage *timeout_stage; u8 index, data, data_orig; u32 mask; int i, j; pretimeout_stage = &wdt_data->stage[STAGE_PRETIMEOUT]; timeout_stage = &wdt_data->stage[STAGE_TIMEOUT]; pretimeout_stage->mask = 0; timeout_stage->mask = 0; for (i = 0; i < 3; i++) { index = KEMPLD_WDT_STAGE_TIMEOUT(i); mask = 0; kempld_get_mutex(pld); /* Probe each byte individually. */ for (j = 0; j < 4; j++) { data_orig = kempld_read8(pld, index + j); kempld_write8(pld, index + j, 0x00); data = kempld_read8(pld, index + j); /* A failed write means this byte is reserved */ if (data != 0x00) break; kempld_write8(pld, index + j, data_orig); mask |= 0xff << (j * 8); } kempld_release_mutex(pld); /* Assign available stages to timeout and pretimeout */ if (!timeout_stage->mask) { timeout_stage->mask = mask; timeout_stage->id = i; } else { if (pld->feature_mask & KEMPLD_FEATURE_BIT_NMI) { pretimeout_stage->mask = timeout_stage->mask; timeout_stage->mask = mask; pretimeout_stage->id = timeout_stage->id; timeout_stage->id = i; } break; } } if (!timeout_stage->mask) return -ENODEV; return 0; }
static int kempld_wdt_set_stage_timeout(struct kempld_wdt_data *wdt_data, struct kempld_wdt_stage *stage, unsigned int timeout) { struct kempld_device_data *pld = wdt_data->pld; u32 prescaler = kempld_prescaler[PRESCALER_21]; u64 stage_timeout64; u32 stage_timeout; u32 remainder; u8 stage_cfg; if (!stage) return -EINVAL; stage_timeout64 = (u64)timeout * pld->pld_clock; remainder = do_div(stage_timeout64, prescaler); if (remainder) stage_timeout64++; if (stage_timeout64 > stage->mask) return -EINVAL; stage_timeout = stage_timeout64 & stage->mask; kempld_get_mutex(pld); stage_cfg = kempld_read8(pld, KEMPLD_WDT_STAGE_CFG(stage->id)); stage_cfg &= ~STAGE_CFG_PRESCALER_MASK; stage_cfg |= STAGE_CFG_SET_PRESCALER(PRESCALER_21); kempld_write8(pld, KEMPLD_WDT_STAGE_CFG(stage->id), stage_cfg); kempld_write32(pld, KEMPLD_WDT_STAGE_TIMEOUT(stage->id), stage_timeout); kempld_release_mutex(pld); return 0; }
static int kempld_wdt_set_stage_action(struct kempld_wdt_data *wdt_data, struct kempld_wdt_stage *stage, u8 action) { struct kempld_device_data *pld = wdt_data->pld; u8 stage_cfg; if (!stage || !stage->mask) return -EINVAL; kempld_get_mutex(pld); stage_cfg = kempld_read8(pld, KEMPLD_WDT_STAGE_CFG(stage->id)); stage_cfg &= ~STAGE_CFG_ACTION_MASK; stage_cfg |= (action & STAGE_CFG_ACTION_MASK); if (action == ACTION_RESET) stage_cfg |= STAGE_CFG_ASSERT; else stage_cfg &= ~STAGE_CFG_ASSERT; kempld_write8(pld, KEMPLD_WDT_STAGE_CFG(stage->id), stage_cfg); kempld_release_mutex(pld); return 0; }
static int kempld_wdt_keepalive(struct watchdog_device *wdd) { struct kempld_wdt_data *wdt_data = watchdog_get_drvdata(wdd); struct kempld_device_data *pld = wdt_data->pld; kempld_get_mutex(pld); kempld_write8(pld, KEMPLD_WDT_KICK, 'K'); kempld_release_mutex(pld); return 0; }
/* * Set or clear GPIO bit * kempld_get_mutex must be called prior to calling this function. */ static void kempld_gpio_bitop(struct kempld_device_data *pld, u8 reg, u8 bit, u8 val) { u8 status; status = kempld_read8(pld, reg); if (val) status |= KEMPLD_GPIO_MASK(bit); else status &= ~KEMPLD_GPIO_MASK(bit); kempld_write8(pld, reg, status); }
static int kempld_wdt_stop(struct watchdog_device *wdd) { struct kempld_wdt_data *wdt_data = watchdog_get_drvdata(wdd); struct kempld_device_data *pld = wdt_data->pld; u8 status; kempld_get_mutex(pld); status = kempld_read8(pld, KEMPLD_WDT_CFG); status &= ~KEMPLD_WDT_CFG_ENABLE; kempld_write8(pld, KEMPLD_WDT_CFG, status); status = kempld_read8(pld, KEMPLD_WDT_CFG); kempld_release_mutex(pld); /* Check if the watchdog was disabled */ if (status & KEMPLD_WDT_CFG_ENABLE) return -EACCES; return 0; }
static int kempld_wdt_start(struct watchdog_device *wdd) { struct kempld_wdt_data *wdt_data = watchdog_get_drvdata(wdd); struct kempld_device_data *pld = wdt_data->pld; u8 status; int ret; ret = kempld_wdt_set_timeout(wdd, wdd->timeout); if (ret) return ret; kempld_get_mutex(pld); status = kempld_read8(pld, KEMPLD_WDT_CFG); status |= KEMPLD_WDT_CFG_ENABLE; kempld_write8(pld, KEMPLD_WDT_CFG, status); status = kempld_read8(pld, KEMPLD_WDT_CFG); kempld_release_mutex(pld); /* Check if the watchdog was enabled */ if (!(status & KEMPLD_WDT_CFG_ENABLE)) return -EACCES; return 0; }
/** * kempld_write16 - write 16 bit register * @pld: kempld_device_data structure describing the PLD * @index: register index on the chip * @data: new register value * * kempld_get_mutex must be called prior to calling this function. */ void kempld_write16(struct kempld_device_data *pld, u8 index, u16 data) { kempld_write8(pld, index, (u8)data); kempld_write8(pld, index + 1, (u8)(data >> 8)); }