Merge branches 'hwmod_am335x_support_3.6', 'clkdm_pwrdm_devel_a_3.6' and 'misc_devel_3.6' into omap_devel_f_3.6
This commit is contained in:
Коммит
8cb8de5d87
|
@ -70,7 +70,7 @@ static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)
|
|||
|
||||
static int omap4_clkdm_sleep(struct clockdomain *clkdm)
|
||||
{
|
||||
omap4_cminst_clkdm_force_sleep(clkdm->prcm_partition,
|
||||
omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition,
|
||||
clkdm->cm_inst, clkdm->clkdm_offs);
|
||||
return 0;
|
||||
}
|
||||
|
@ -90,8 +90,12 @@ static void omap4_clkdm_allow_idle(struct clockdomain *clkdm)
|
|||
|
||||
static void omap4_clkdm_deny_idle(struct clockdomain *clkdm)
|
||||
{
|
||||
omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
|
||||
clkdm->cm_inst, clkdm->clkdm_offs);
|
||||
if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
|
||||
omap4_clkdm_wakeup(clkdm);
|
||||
else
|
||||
omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition,
|
||||
clkdm->cm_inst,
|
||||
clkdm->clkdm_offs);
|
||||
}
|
||||
|
||||
static int omap4_clkdm_clk_enable(struct clockdomain *clkdm)
|
||||
|
|
|
@ -234,20 +234,6 @@ void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs)
|
|||
_clktrctrl_write(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, part, inst, cdoffs);
|
||||
}
|
||||
|
||||
/**
|
||||
* omap4_cminst_clkdm_force_sleep - try to put a clockdomain into idle
|
||||
* @part: PRCM partition ID that the clockdomain registers exist in
|
||||
* @inst: CM instance register offset (*_INST macro)
|
||||
* @cdoffs: Clockdomain register offset (*_CDOFFS macro)
|
||||
*
|
||||
* Put a clockdomain referred to by (@part, @inst, @cdoffs) into idle
|
||||
* No return value.
|
||||
*/
|
||||
void omap4_cminst_clkdm_force_sleep(u8 part, s16 inst, u16 cdoffs)
|
||||
{
|
||||
_clktrctrl_write(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, part, inst, cdoffs);
|
||||
}
|
||||
|
||||
/**
|
||||
* omap4_cminst_clkdm_force_sleep - try to take a clockdomain out of idle
|
||||
* @part: PRCM partition ID that the clockdomain registers exist in
|
||||
|
|
|
@ -16,38 +16,13 @@ extern void omap4_cminst_clkdm_enable_hwsup(u8 part, s16 inst, u16 cdoffs);
|
|||
extern void omap4_cminst_clkdm_disable_hwsup(u8 part, s16 inst, u16 cdoffs);
|
||||
extern void omap4_cminst_clkdm_force_sleep(u8 part, s16 inst, u16 cdoffs);
|
||||
extern void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs);
|
||||
|
||||
extern int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs);
|
||||
|
||||
# ifdef CONFIG_ARCH_OMAP4
|
||||
extern int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs,
|
||||
u16 clkctrl_offs);
|
||||
|
||||
extern void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs,
|
||||
u16 clkctrl_offs);
|
||||
extern void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs,
|
||||
u16 clkctrl_offs);
|
||||
|
||||
# else
|
||||
|
||||
static inline int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs,
|
||||
u16 clkctrl_offs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst,
|
||||
s16 cdoffs, u16 clkctrl_offs)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs,
|
||||
u16 clkctrl_offs)
|
||||
{
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
/*
|
||||
* In an ideal world, we would not export these low-level functions,
|
||||
* but this will probably take some time to fix properly
|
||||
|
|
|
@ -182,6 +182,7 @@
|
|||
#define OMAP3630_CONTROL_FUSE_OPP120_VDD1 (OMAP2_CONTROL_GENERAL + 0x0120)
|
||||
#define OMAP3630_CONTROL_FUSE_OPP50_VDD2 (OMAP2_CONTROL_GENERAL + 0x0128)
|
||||
#define OMAP3630_CONTROL_FUSE_OPP100_VDD2 (OMAP2_CONTROL_GENERAL + 0x012C)
|
||||
#define OMAP3630_CONTROL_CAMERA_PHY_CTRL (OMAP2_CONTROL_GENERAL + 0x02f0)
|
||||
|
||||
/* OMAP44xx control efuse offsets */
|
||||
#define OMAP44XX_CONTROL_FUSE_IVA_OPP50 0x22C
|
||||
|
|
|
@ -135,11 +135,20 @@ static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n)
|
|||
*/
|
||||
static int _omap3_noncore_dpll_lock(struct clk *clk)
|
||||
{
|
||||
const struct dpll_data *dd;
|
||||
u8 ai;
|
||||
int r;
|
||||
u8 state = 1;
|
||||
int r = 0;
|
||||
|
||||
pr_debug("clock: locking DPLL %s\n", clk->name);
|
||||
|
||||
dd = clk->dpll_data;
|
||||
state <<= __ffs(dd->idlest_mask);
|
||||
|
||||
/* Check if already locked */
|
||||
if ((__raw_readl(dd->idlest_reg) & dd->idlest_mask) == state)
|
||||
goto done;
|
||||
|
||||
ai = omap3_dpll_autoidle_read(clk);
|
||||
|
||||
if (ai)
|
||||
|
@ -152,6 +161,7 @@ static int _omap3_noncore_dpll_lock(struct clk *clk)
|
|||
if (ai)
|
||||
omap3_dpll_allow_idle(clk);
|
||||
|
||||
done:
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -387,6 +387,49 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v
|
||||
* @oh: struct omap_hwmod *
|
||||
*
|
||||
* The DMADISABLE bit is a semi-automatic bit present in sysconfig register
|
||||
* of some modules. When the DMA must perform read/write accesses, the
|
||||
* DMADISABLE bit is cleared by the hardware. But when the DMA must stop
|
||||
* for power management, software must set the DMADISABLE bit back to 1.
|
||||
*
|
||||
* Set the DMADISABLE bit in @v for hwmod @oh. Returns -EINVAL upon
|
||||
* error or 0 upon success.
|
||||
*/
|
||||
static int _set_dmadisable(struct omap_hwmod *oh)
|
||||
{
|
||||
u32 v;
|
||||
u32 dmadisable_mask;
|
||||
|
||||
if (!oh->class->sysc ||
|
||||
!(oh->class->sysc->sysc_flags & SYSC_HAS_DMADISABLE))
|
||||
return -EINVAL;
|
||||
|
||||
if (!oh->class->sysc->sysc_fields) {
|
||||
WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* clocks must be on for this operation */
|
||||
if (oh->_state != _HWMOD_STATE_ENABLED) {
|
||||
pr_warn("omap_hwmod: %s: dma can be disabled only from enabled state\n", oh->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pr_debug("omap_hwmod: %s: setting DMADISABLE\n", oh->name);
|
||||
|
||||
v = oh->_sysc_cache;
|
||||
dmadisable_mask =
|
||||
(0x1 << oh->class->sysc->sysc_fields->dmadisable_shift);
|
||||
v |= dmadisable_mask;
|
||||
_write_sysconfig(v, oh);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* _set_module_autoidle: set the OCP_SYSCONFIG AUTOIDLE field in @v
|
||||
* @oh: struct omap_hwmod *
|
||||
|
@ -1698,11 +1741,17 @@ dis_opt_clks:
|
|||
* therefore have no OCP header registers to access. Others (like the
|
||||
* IVA) have idiosyncratic reset sequences. So for these relatively
|
||||
* rare cases, custom reset code can be supplied in the struct
|
||||
* omap_hwmod_class .reset function pointer. Passes along the return
|
||||
* value from either _ocp_softreset() or the custom reset function -
|
||||
* these must return -EINVAL if the hwmod cannot be reset this way or
|
||||
* if the hwmod is in the wrong state, -ETIMEDOUT if the module did
|
||||
* not reset in time, or 0 upon success.
|
||||
* omap_hwmod_class .reset function pointer.
|
||||
*
|
||||
* _set_dmadisable() is called to set the DMADISABLE bit so that it
|
||||
* does not prevent idling of the system. This is necessary for cases
|
||||
* where ROMCODE/BOOTLOADER uses dma and transfers control to the
|
||||
* kernel without disabling dma.
|
||||
*
|
||||
* Passes along the return value from either _ocp_softreset() or the
|
||||
* custom reset function - these must return -EINVAL if the hwmod
|
||||
* cannot be reset this way or if the hwmod is in the wrong state,
|
||||
* -ETIMEDOUT if the module did not reset in time, or 0 upon success.
|
||||
*/
|
||||
static int _reset(struct omap_hwmod *oh)
|
||||
{
|
||||
|
@ -1724,6 +1773,8 @@ static int _reset(struct omap_hwmod *oh)
|
|||
}
|
||||
}
|
||||
|
||||
_set_dmadisable(oh);
|
||||
|
||||
/*
|
||||
* OCP_SYSCONFIG bits need to be reprogrammed after a
|
||||
* softreset. The _enable() function should be split to avoid
|
||||
|
@ -3401,3 +3452,18 @@ int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap_hwmod_get_main_clk - get pointer to main clock name
|
||||
* @oh: struct omap_hwmod *
|
||||
*
|
||||
* Returns the main clock name assocated with @oh upon success,
|
||||
* or NULL if @oh is NULL.
|
||||
*/
|
||||
const char *omap_hwmod_get_main_clk(struct omap_hwmod *oh)
|
||||
{
|
||||
if (!oh)
|
||||
return NULL;
|
||||
|
||||
return oh->main_clk;
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ struct omap_hwmod_sysc_fields omap_hwmod_sysc_type2 = {
|
|||
.midle_shift = SYSC_TYPE2_MIDLEMODE_SHIFT,
|
||||
.sidle_shift = SYSC_TYPE2_SIDLEMODE_SHIFT,
|
||||
.srst_shift = SYSC_TYPE2_SOFTRESET_SHIFT,
|
||||
.dmadisable_shift = SYSC_TYPE2_DMADISABLE_SHIFT,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -526,7 +526,8 @@ int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
|
|||
*
|
||||
* Return the powerdomain @pwrdm's current power state. Returns -EINVAL
|
||||
* if the powerdomain pointer is null or returns the current power state
|
||||
* upon success.
|
||||
* upon success. Note that if the power domain only supports the ON state
|
||||
* then just return ON as the current state.
|
||||
*/
|
||||
int pwrdm_read_pwrst(struct powerdomain *pwrdm)
|
||||
{
|
||||
|
@ -535,6 +536,9 @@ int pwrdm_read_pwrst(struct powerdomain *pwrdm)
|
|||
if (!pwrdm)
|
||||
return -EINVAL;
|
||||
|
||||
if (pwrdm->pwrsts == PWRSTS_ON)
|
||||
return PWRDM_POWER_ON;
|
||||
|
||||
if (arch_pwrdm && arch_pwrdm->pwrdm_read_pwrst)
|
||||
ret = arch_pwrdm->pwrdm_read_pwrst(pwrdm);
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "prm2xxx_3xxx.h"
|
||||
#include "prm44xx.h"
|
||||
#include "prminst44xx.h"
|
||||
#include "cminst44xx.h"
|
||||
#include "prm-regbits-24xx.h"
|
||||
#include "prm-regbits-44xx.h"
|
||||
#include "control.h"
|
||||
|
@ -164,3 +165,25 @@ void __init omap2_set_globals_prcm(struct omap_globals *omap2_globals)
|
|||
omap_cm_base_init();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Stubbed functions so that common files continue to build when
|
||||
* custom builds are used
|
||||
* XXX These are temporary and should be removed at the earliest possible
|
||||
* opportunity
|
||||
*/
|
||||
int __weak omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs,
|
||||
u16 clkctrl_offs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __weak omap4_cminst_module_enable(u8 mode, u8 part, u16 inst,
|
||||
s16 cdoffs, u16 clkctrl_offs)
|
||||
{
|
||||
}
|
||||
|
||||
void __weak omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs,
|
||||
u16 clkctrl_offs)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -228,68 +228,6 @@
|
|||
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
/*
|
||||
* Stub omap2xxx/omap3xxx functions so that common files
|
||||
* continue to build when custom builds are used
|
||||
*/
|
||||
#if defined(CONFIG_ARCH_OMAP4) && !(defined(CONFIG_ARCH_OMAP2) || \
|
||||
defined(CONFIG_ARCH_OMAP3))
|
||||
static inline u32 omap2_prm_read_mod_reg(s16 module, u16 idx)
|
||||
{
|
||||
WARN(1, "prm: omap2xxx/omap3xxx specific function and "
|
||||
"not suppose to be used on omap4\n");
|
||||
return 0;
|
||||
}
|
||||
static inline void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx)
|
||||
{
|
||||
WARN(1, "prm: omap2xxx/omap3xxx specific function and "
|
||||
"not suppose to be used on omap4\n");
|
||||
}
|
||||
static inline u32 omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits,
|
||||
s16 module, s16 idx)
|
||||
{
|
||||
WARN(1, "prm: omap2xxx/omap3xxx specific function and "
|
||||
"not suppose to be used on omap4\n");
|
||||
return 0;
|
||||
}
|
||||
static inline u32 omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
|
||||
{
|
||||
WARN(1, "prm: omap2xxx/omap3xxx specific function and "
|
||||
"not suppose to be used on omap4\n");
|
||||
return 0;
|
||||
}
|
||||
static inline u32 omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
|
||||
{
|
||||
WARN(1, "prm: omap2xxx/omap3xxx specific function and "
|
||||
"not suppose to be used on omap4\n");
|
||||
return 0;
|
||||
}
|
||||
static inline u32 omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
|
||||
{
|
||||
WARN(1, "prm: omap2xxx/omap3xxx specific function and "
|
||||
"not suppose to be used on omap4\n");
|
||||
return 0;
|
||||
}
|
||||
static inline int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift)
|
||||
{
|
||||
WARN(1, "prm: omap2xxx/omap3xxx specific function and "
|
||||
"not suppose to be used on omap4\n");
|
||||
return 0;
|
||||
}
|
||||
static inline int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
|
||||
{
|
||||
WARN(1, "prm: omap2xxx/omap3xxx specific function and "
|
||||
"not suppose to be used on omap4\n");
|
||||
return 0;
|
||||
}
|
||||
static inline int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift,
|
||||
u8 st_shift)
|
||||
{
|
||||
WARN(1, "prm: omap2xxx/omap3xxx specific function and "
|
||||
"not suppose to be used on omap4\n");
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
/* Power/reset management domain register get/set */
|
||||
extern u32 omap2_prm_read_mod_reg(s16 module, u16 idx);
|
||||
extern void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx);
|
||||
|
@ -320,9 +258,6 @@ extern void omap3xxx_prm_read_pending_irqs(unsigned long *events);
|
|||
extern void omap3xxx_prm_ocp_barrier(void);
|
||||
extern void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask);
|
||||
extern void omap3xxx_prm_restore_irqen(u32 *saved_mask);
|
||||
|
||||
#endif /* CONFIG_ARCH_OMAP4 */
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
@ -319,3 +319,65 @@ err:
|
|||
omap_prcm_irq_cleanup();
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
* Stubbed functions so that common files continue to build when
|
||||
* custom builds are used
|
||||
* XXX These are temporary and should be removed at the earliest possible
|
||||
* opportunity
|
||||
*/
|
||||
u32 __weak omap2_prm_read_mod_reg(s16 module, u16 idx)
|
||||
{
|
||||
WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __weak omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx)
|
||||
{
|
||||
WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
|
||||
}
|
||||
|
||||
u32 __weak omap2_prm_rmw_mod_reg_bits(u32 mask, u32 bits,
|
||||
s16 module, s16 idx)
|
||||
{
|
||||
WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 __weak omap2_prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)
|
||||
{
|
||||
WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 __weak omap2_prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
|
||||
{
|
||||
WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 __weak omap2_prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
|
||||
{
|
||||
WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __weak omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift)
|
||||
{
|
||||
WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __weak omap2_prm_assert_hardreset(s16 prm_mod, u8 shift)
|
||||
{
|
||||
WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __weak omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift,
|
||||
u8 st_shift)
|
||||
{
|
||||
WARN(1, "prm: omap2xxx/omap3xxx specific function called on non-omap2xxx/3xxx\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,8 @@ extern struct omap_hwmod_sysc_fields omap_hwmod_sysc_type3;
|
|||
#define SYSC_TYPE2_SIDLEMODE_MASK (0x3 << SYSC_TYPE2_SIDLEMODE_SHIFT)
|
||||
#define SYSC_TYPE2_MIDLEMODE_SHIFT 4
|
||||
#define SYSC_TYPE2_MIDLEMODE_MASK (0x3 << SYSC_TYPE2_MIDLEMODE_SHIFT)
|
||||
#define SYSC_TYPE2_DMADISABLE_SHIFT 16
|
||||
#define SYSC_TYPE2_DMADISABLE_MASK (0x1 << SYSC_TYPE2_DMADISABLE_SHIFT)
|
||||
|
||||
/*
|
||||
* OCP SYSCONFIG bit shifts/masks TYPE3.
|
||||
|
@ -293,6 +295,7 @@ struct omap_hwmod_ocp_if {
|
|||
#define SYSS_HAS_RESET_STATUS (1 << 7)
|
||||
#define SYSC_NO_CACHE (1 << 8) /* XXX SW flag, belongs elsewhere */
|
||||
#define SYSC_HAS_RESET_STATUS (1 << 9)
|
||||
#define SYSC_HAS_DMADISABLE (1 << 10)
|
||||
|
||||
/* omap_hwmod_sysconfig.clockact flags */
|
||||
#define CLOCKACT_TEST_BOTH 0x0
|
||||
|
@ -308,6 +311,7 @@ struct omap_hwmod_ocp_if {
|
|||
* @enwkup_shift: Offset of the enawakeup bit
|
||||
* @srst_shift: Offset of the softreset bit
|
||||
* @autoidle_shift: Offset of the autoidle bit
|
||||
* @dmadisable_shift: Offset of the dmadisable bit
|
||||
*/
|
||||
struct omap_hwmod_sysc_fields {
|
||||
u8 midle_shift;
|
||||
|
@ -316,6 +320,7 @@ struct omap_hwmod_sysc_fields {
|
|||
u8 enwkup_shift;
|
||||
u8 srst_shift;
|
||||
u8 autoidle_shift;
|
||||
u8 dmadisable_shift;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -641,6 +646,8 @@ int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
|
|||
|
||||
int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx);
|
||||
|
||||
const char *omap_hwmod_get_main_clk(struct omap_hwmod *oh);
|
||||
|
||||
/*
|
||||
* Chip variant-specific hwmod init routines - XXX should be converted
|
||||
* to use initcalls once the initial boot ordering is straightened out
|
||||
|
|
Загрузка…
Ссылка в новой задаче