static int check_reserved(const struct gpio_desc *desc, const char *func)
{
	struct gpio_dev_priv *uc_priv;

	if (!dm_gpio_is_valid(desc))
		return -ENOENT;

	uc_priv = dev_get_uclass_priv(desc->dev);
	if (!uc_priv->name[desc->offset]) {
		printf("%s: %s: error: gpio %s%d not reserved\n",
		       desc->dev->name, func,
		       uc_priv->bank_name ? uc_priv->bank_name : "",
		       desc->offset);
		return -EBUSY;
	}

	return 0;
}
static int ich6_gpio_probe(struct udevice *dev)
{
	struct ich6_bank_platdata *plat = dev_get_platdata(dev);
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	struct ich6_bank_priv *bank = dev_get_priv(dev);
	struct udevice *pinctrl;

	/* Set up pin control if available */
	syscon_get_by_driver_data(X86_SYSCON_PINCONF, &pinctrl);

	uc_priv->gpio_count = GPIO_PER_BANK;
	uc_priv->bank_name = plat->bank_name;
	bank->use_sel = plat->base_addr;
	bank->io_sel = plat->base_addr + 4;
	bank->lvl = plat->base_addr + 8;

	return 0;
}
Exemplo n.º 3
0
static int sdhci_cdns_probe(struct udevice *dev)
{
	DECLARE_GLOBAL_DATA_PTR;
	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
	struct sdhci_cdns_plat *plat = dev_get_platdata(dev);
	struct sdhci_host *host = dev_get_priv(dev);
	fdt_addr_t base;
	int ret;

	base = devfdt_get_addr(dev);
	if (base == FDT_ADDR_T_NONE)
		return -EINVAL;

	plat->hrs_addr = devm_ioremap(dev, base, SZ_1K);
	if (!plat->hrs_addr)
		return -ENOMEM;

	host->name = dev->name;
	host->ioaddr = plat->hrs_addr + SDHCI_CDNS_SRS_BASE;
	host->ops = &sdhci_cdns_ops;
	host->quirks |= SDHCI_QUIRK_WAIT_SEND_CMD;
	sdhci_cdns_mmc_ops = sdhci_ops;
#ifdef MMC_SUPPORTS_TUNING
	sdhci_cdns_mmc_ops.execute_tuning = sdhci_cdns_execute_tuning;
#endif

	ret = mmc_of_parse(dev, &plat->cfg);
	if (ret)
		return ret;

	ret = sdhci_cdns_phy_init(plat, gd->fdt_blob, dev_of_offset(dev));
	if (ret)
		return ret;

	ret = sdhci_setup_cfg(&plat->cfg, host, 0, 0);
	if (ret)
		return ret;

	upriv->mmc = &plat->mmc;
	host->mmc = &plat->mmc;
	host->mmc->priv = host;

	return sdhci_probe(dev);
}
static int ich6_gpio_probe(struct udevice *dev)
{
	struct ich6_bank_platdata *plat = dev_get_platdata(dev);
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	struct ich6_bank_priv *bank = dev_get_priv(dev);

	if (gd->arch.gpio_map) {
		setup_pch_gpios(plat->base_addr, gd->arch.gpio_map);
		gd->arch.gpio_map = NULL;
	}

	uc_priv->gpio_count = GPIO_PER_BANK;
	uc_priv->bank_name = plat->bank_name;
	bank->use_sel = plat->base_addr;
	bank->io_sel = plat->base_addr + 4;
	bank->lvl = plat->base_addr + 8;

	return 0;
}
Exemplo n.º 5
0
static int uniphier_gpio_probe(struct udevice *dev)
{
	struct uniphier_gpio_priv *priv = dev_get_priv(dev);
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	fdt_addr_t addr;

	addr = devfdt_get_addr(dev);
	if (addr == FDT_ADDR_T_NONE)
		return -EINVAL;

	priv->regs = devm_ioremap(dev, addr, SZ_512);
	if (!priv->regs)
		return -ENOMEM;

	uc_priv->gpio_count = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
					      "ngpios", 0);

	return 0;
}
Exemplo n.º 6
0
static int i2c_mux_bus_xfer(struct udevice *dev, struct i2c_msg *msg,
			    int nmsgs)
{
	struct udevice *mux = dev->parent;
	struct i2c_mux *priv = dev_get_uclass_priv(mux);
	struct dm_i2c_ops *ops = i2c_get_ops(priv->i2c_bus);
	int ret, ret2;

	debug("%s: %s, bus %s\n", __func__, dev->name, priv->i2c_bus->name);
	if (!ops->xfer)
		return -ENOSYS;
	ret = i2c_mux_select(dev);
	if (ret)
		return ret;
	ret = ops->xfer(priv->i2c_bus, msg, nmsgs);
	ret2 = i2c_mux_deselect(dev);

	return ret ? ret : ret2;
}
Exemplo n.º 7
0
int video_bridge_set_active(struct udevice *dev, bool active)
{
	struct video_bridge_priv *uc_priv = dev_get_uclass_priv(dev);
	int ret;

	debug("%s: %d\n", __func__, active);
	ret = dm_gpio_set_value(&uc_priv->sleep, !active);
	if (ret)
		return ret;
	if (active) {
		ret = dm_gpio_set_value(&uc_priv->reset, true);
		if (ret)
			return ret;
		udelay(10);
		ret = dm_gpio_set_value(&uc_priv->reset, false);
	}

	return ret;
}
Exemplo n.º 8
0
static int i2c_mux_bus_probe(struct udevice *dev, uint chip_addr,
			     uint chip_flags)
{
	struct udevice *mux = dev->parent;
	struct i2c_mux *priv = dev_get_uclass_priv(mux);
	struct dm_i2c_ops *ops = i2c_get_ops(priv->i2c_bus);
	int ret, ret2;

	debug("%s: %s, bus %s\n", __func__, dev->name, priv->i2c_bus->name);
	if (!ops->probe_chip)
		return -ENOSYS;
	ret = i2c_mux_select(dev);
	if (ret)
		return ret;
	ret = ops->probe_chip(priv->i2c_bus, chip_addr, chip_flags);
	ret2 = i2c_mux_deselect(dev);

	return ret ? ret : ret2;
}
Exemplo n.º 9
0
static int omap_hsmmc_probe(struct udevice *dev)
{
	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
	struct omap_hsmmc_data *priv = dev_get_priv(dev);
	struct mmc_config *cfg;
	struct mmc *mmc;

	cfg = &priv->cfg;
	cfg->name = "OMAP SD/MMC";
	cfg->ops = &omap_hsmmc_ops;

	mmc = mmc_create(cfg, priv);
	if (mmc == NULL)
		return -1;

	upriv->mmc = mmc;

	return 0;
}
Exemplo n.º 10
0
int _dm_gpio_free(struct udevice *dev, uint offset)
{
	struct gpio_dev_priv *uc_priv;
	int ret;

	uc_priv = dev_get_uclass_priv(dev);
	if (!uc_priv->name[offset])
		return -ENXIO;
	if (gpio_get_ops(dev)->free) {
		ret = gpio_get_ops(dev)->free(dev, offset);
		if (ret)
			return ret;
	}

	free(uc_priv->name[offset]);
	uc_priv->name[offset] = NULL;

	return 0;
}
Exemplo n.º 11
0
static int console_normal_set_row(struct udevice *dev, uint row, int clr)
{
	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
	void *line;
	int pixels = VIDEO_FONT_HEIGHT * vid_priv->line_length;
	int i;

	line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * vid_priv->line_length;
	switch (vid_priv->bpix) {
#ifdef CONFIG_VIDEO_BPP8
	case VIDEO_BPP8: {
		uint8_t *dst = line;

		for (i = 0; i < pixels; i++)
			*dst++ = clr;
		break;
	}
#endif
#ifdef CONFIG_VIDEO_BPP16
	case VIDEO_BPP16: {
		uint16_t *dst = line;

		for (i = 0; i < pixels; i++)
			*dst++ = clr;
		break;
	}
#endif
#ifdef CONFIG_VIDEO_BPP32
	case VIDEO_BPP32: {
		uint32_t *dst = line;

		for (i = 0; i < pixels; i++)
			*dst++ = clr;
		break;
	}
#endif
	default:
		return -ENOSYS;
	}

	return 0;
}
Exemplo n.º 12
0
static int sandbox_sdl_probe(struct udevice *dev)
{
	struct sandbox_sdl_plat *plat = dev_get_platdata(dev);
	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
	int ret;

	ret = sandbox_sdl_init_display(plat->xres, plat->yres, plat->bpix);
	if (ret) {
		puts("LCD init failed\n");
		return ret;
	}
	uc_priv->xsize = plat->xres;
	uc_priv->ysize = plat->yres;
	uc_priv->bpix = plat->bpix;
	uc_priv->rot = plat->rot;
	uc_priv->vidconsole_drv_name = plat->vidconsole_drv_name;
	uc_priv->font_size = plat->font_size;

	return 0;
}
Exemplo n.º 13
0
/**
 * compress_frame_buffer() - Compress the frame buffer and return its size
 *
 * We want to write tests which perform operations on the video console and
 * check that the frame buffer ends up with the correct contents. But it is
 * painful to store 'known good' images for comparison with the frame
 * buffer. As an alternative, we can compress the frame buffer and check the
 * size of the compressed data. This provides a pretty good level of
 * certainty and the resulting tests need only check a single value.
 *
 * @dev:	Video device
 * @return compressed size of the frame buffer, or -ve on error
 */
static int compress_frame_buffer(struct udevice *dev)
{
	struct video_priv *priv = dev_get_uclass_priv(dev);
	uint destlen;
	void *dest;
	int ret;

	destlen = priv->fb_size;
	dest = malloc(priv->fb_size);
	if (!dest)
		return -ENOMEM;
	ret = BZ2_bzBuffToBuffCompress(dest, &destlen,
				       priv->fb, priv->fb_size,
				       3, 0, 0);
	free(dest);
	if (ret)
		return ret;

	return destlen;
}
Exemplo n.º 14
0
int dm_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
{
	struct dm_i2c_ops *ops = i2c_get_ops(bus);
	struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus);
	int ret;

	/*
	 * If we have a method, call it. If not then the driver probably wants
	 * to deal with speed changes on the next transfer. It can easily read
	 * the current speed from this uclass
	 */
	if (ops->set_bus_speed) {
		ret = ops->set_bus_speed(bus, speed);
		if (ret)
			return ret;
	}
	i2c->speed_hz = speed;

	return 0;
}
Exemplo n.º 15
0
static int rockchip_gpio_probe(struct udevice *dev)
{
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	struct rockchip_gpio_priv *priv = dev_get_priv(dev);
	char *end;
	int ret;

	priv->regs = dev_read_addr_ptr(dev);
	ret = uclass_first_device_err(UCLASS_PINCTRL, &priv->pinctrl);
	if (ret)
		return ret;

	uc_priv->gpio_count = ROCKCHIP_GPIOS_PER_BANK;
	end = strrchr(dev->name, '@');
	priv->bank = trailing_strtoln(dev->name, end);
	priv->name[0] = 'A' + priv->bank;
	uc_priv->bank_name = priv->name;

	return 0;
}
Exemplo n.º 16
0
int musb_usb_probe(struct udevice *dev)
{
	struct musb_host_data *host = dev_get_priv(dev);
	struct usb_bus_priv *priv = dev_get_uclass_priv(dev);
	int ret;

	priv->desc_before_addr = true;

	if (!host->host) {
		host->host = musb_init_controller(&musb_plat, NULL,
						  (void *)SUNXI_USB0_BASE);
		if (!host->host)
			return -EIO;
	}

	ret = musb_lowlevel_init(host);
	if (ret == 0)
		printf("MUSB OTG\n");

	return ret;
}
Exemplo n.º 17
0
static int arasan_sdhci_probe(struct udevice *dev)
{
	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
	struct sdhci_host *host = dev_get_priv(dev);

	host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD |
		       SDHCI_QUIRK_BROKEN_R1B;

#ifdef CONFIG_ZYNQ_HISPD_BROKEN
	host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
#endif

	host->version = sdhci_readw(host, SDHCI_HOST_VERSION);

	add_sdhci(host, CONFIG_ZYNQ_SDHCI_MAX_FREQ,
		  CONFIG_ZYNQ_SDHCI_MIN_FREQ);

	upriv->mmc = host->mmc;

	return 0;
}
Exemplo n.º 18
0
static int timer_pre_probe(struct udevice *dev)
{
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
	struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	struct clk timer_clk;
	int err;
	ulong ret;

	err = clk_get_by_index(dev, 0, &timer_clk);
	if (!err) {
		ret = clk_get_rate(&timer_clk);
		if (IS_ERR_VALUE(ret))
			return ret;
		uc_priv->clock_rate = ret;
	} else
		uc_priv->clock_rate = fdtdec_get_int(gd->fdt_blob,
				dev_of_offset(dev),	"clock-frequency", 0);
#endif

	return 0;
}
Exemplo n.º 19
0
static int atmel_hlcdc_probe(struct udevice *dev)
{
	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
	struct atmel_hlcdc_priv *priv = dev_get_priv(dev);
	int ret;

	ret = at91_hlcdc_enable_clk(dev);
	if (ret)
		return ret;

	atmel_hlcdc_init(dev);

	uc_priv->xsize = priv->timing.hactive.typ;
	uc_priv->ysize = priv->timing.vactive.typ;
	uc_priv->bpix = priv->vl_bpix;

	/* Enable flushing if we enabled dcache */
	video_set_flush_dcache(dev, true);

	return 0;
}
Exemplo n.º 20
0
/**
 * gpio_to_device() - Convert global GPIO number to device, number
 *
 * Convert the GPIO number to an entry in the list of GPIOs
 * or GPIO blocks registered with the GPIO controller. Returns
 * entry on success, NULL on error.
 *
 * @gpio:	The numeric representation of the GPIO
 * @desc:	Returns description (desc->flags will always be 0)
 * @return 0 if found, -ENOENT if not found
 */
static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
{
	struct gpio_dev_priv *uc_priv;
	struct udevice *dev;
	int ret;

	for (ret = uclass_first_device(UCLASS_GPIO, &dev);
	     dev;
	     ret = uclass_next_device(&dev)) {
		uc_priv = dev_get_uclass_priv(dev);
		if (gpio >= uc_priv->gpio_base &&
		    gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
			desc->dev = dev;
			desc->offset = gpio - uc_priv->gpio_base;
			desc->flags = 0;
			return 0;
		}
	}

	/* No such GPIO */
	return ret ? ret : -ENOENT;
}
Exemplo n.º 21
0
static int ti_musb_host_probe(struct udevice *dev)
{
	struct musb_host_data *host = dev_get_priv(dev);
	struct ti_musb_platdata *platdata = dev_get_platdata(dev);
	struct usb_bus_priv *priv = dev_get_uclass_priv(dev);
	struct omap_musb_board_data *otg_board_data;
	int ret;

	priv->desc_before_addr = true;

	otg_board_data = &platdata->otg_board_data;

	host->host = musb_init_controller(&platdata->plat,
					  (struct device *)otg_board_data,
					  platdata->base);
	if (!host->host)
		return -EIO;

	ret = musb_lowlevel_init(host);

	return ret;
}
Exemplo n.º 22
0
int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
{
	struct dm_gpio_ops *ops = gpio_get_ops(dev);
	struct gpio_dev_priv *priv;
	char *str = buf;
	int func;
	int ret;
	int len;

	BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));

	*buf = 0;
	priv = dev_get_uclass_priv(dev);
	ret = gpio_get_raw_function(dev, offset, NULL);
	if (ret < 0)
		return ret;
	func = ret;
	len = snprintf(str, buffsize, "%s%d: %s",
		       priv->bank_name ? priv->bank_name : "",
		       offset, gpio_function[func]);
	if (func == GPIOF_INPUT || func == GPIOF_OUTPUT ||
	    func == GPIOF_UNUSED) {
		const char *label;
		bool used;

		ret = ops->get_value(dev, offset);
		if (ret < 0)
			return ret;
		used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED;
		snprintf(str + len, buffsize - len, ": %d [%c]%s%s",
			 ret,
			 used ? 'x' : ' ',
			 used ? " " : "",
			 label ? label : "");
	}

	return 0;
}
Exemplo n.º 23
0
int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc)
{
	struct gpio_dev_priv *uc_priv = NULL;
	struct udevice *dev;
	ulong offset;
	int numeric;
	int ret;

	numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1;
	for (ret = uclass_first_device(UCLASS_GPIO, &dev);
	     dev;
	     ret = uclass_next_device(&dev)) {
		int len;

		uc_priv = dev_get_uclass_priv(dev);
		if (numeric != -1) {
			offset = numeric - uc_priv->gpio_base;
			/* Allow GPIOs to be numbered from 0 */
			if (offset < uc_priv->gpio_count)
				break;
		}

		len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;

		if (!strncasecmp(name, uc_priv->bank_name, len)) {
			if (!strict_strtoul(name + len, 10, &offset))
				break;
		}
	}

	if (!dev)
		return ret ? ret : -EINVAL;

	desc->dev = dev;
	desc->offset = offset;

	return 0;
}
static int broadwell_gpio_probe(struct udevice *dev)
{
	struct broadwell_bank_platdata *plat = dev_get_platdata(dev);
	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
	struct broadwell_bank_priv *priv = dev_get_priv(dev);
	struct udevice *pinctrl;
	int ret;

	/* Set up pin control if available */
	ret = syscon_get_by_driver_data(X86_SYSCON_PINCONF, &pinctrl);
	debug("%s, pinctrl=%p, ret=%d\n", __func__, pinctrl, ret);

	uc_priv->gpio_count = GPIO_PER_BANK;
	uc_priv->bank_name = plat->bank_name;

	priv->regs = (struct pch_lp_gpio_regs *)(uintptr_t)plat->base_addr;
	priv->bank = plat->bank;
	priv->offset = priv->bank * 32;
	debug("%s: probe done, regs %p, bank %d\n", __func__, priv->regs,
	      priv->bank);

	return 0;
}
Exemplo n.º 25
0
static int syscon_pre_probe(struct udevice *dev)
{
	struct syscon_uc_info *priv = dev_get_uclass_priv(dev);

	/* Special case for PCI devices, which don't have a regmap */
	if (device_get_uclass_id(dev->parent) == UCLASS_PCI)
		return 0;

	/*
	 * With OF_PLATDATA we really have no way of knowing the format of
	 * the device-specific platform data. So we assume that it starts with
	 * a 'reg' member, and this holds a single address and size. Drivers
	 * using OF_PLATDATA will need to ensure that this is true.
	 */
#if CONFIG_IS_ENABLED(OF_PLATDATA)
	struct syscon_base_platdata *plat = dev_get_platdata(dev);

	return regmap_init_mem_platdata(dev, plat->reg, ARRAY_SIZE(plat->reg),
					&priv->regmap);
#else
	return regmap_init_mem(dev_ofnode(dev), &priv->regmap);
#endif
}
Exemplo n.º 26
0
int gpio_lookup_name(const char *name, struct udevice **devp,
		     unsigned int *offsetp, unsigned int *gpiop)
{
	struct gpio_desc desc;
	int ret;

	if (devp)
		*devp = NULL;
	ret = dm_gpio_lookup_name(name, &desc);
	if (ret)
		return ret;

	if (devp)
		*devp = desc.dev;
	if (offsetp)
		*offsetp = desc.offset;
	if (gpiop) {
		struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc.dev);

		*gpiop = uc_priv->gpio_base + desc.offset;
	}

	return 0;
}
Exemplo n.º 27
0
/* We need to renumber the GPIOs when any driver is probed/removed */
static int gpio_renumber(struct udevice *removed_dev)
{
	struct gpio_dev_priv *uc_priv;
	struct udevice *dev;
	struct uclass *uc;
	unsigned base;
	int ret;

	ret = uclass_get(UCLASS_GPIO, &uc);
	if (ret)
		return ret;

	/* Ensure that we have a base for each bank */
	base = 0;
	uclass_foreach_dev(dev, uc) {
		if (device_active(dev) && dev != removed_dev) {
			uc_priv = dev_get_uclass_priv(dev);
			uc_priv->gpio_base = base;
			base += uc_priv->gpio_count;
		}
	}

	return 0;
}
Exemplo n.º 28
0
static int tegra124_lcd_init(struct udevice *dev, void *lcdbase,
			     enum video_log2_bpp l2bpp)
{
	struct video_priv *uc_priv = dev_get_uclass_priv(dev);
	struct display_timing timing;
	int ret;

	clock_set_up_plldp();
	clock_start_periph_pll(PERIPH_ID_HOST1X, CLOCK_ID_PERIPH, 408000000);

	clock_enable(PERIPH_ID_HOST1X);
	clock_enable(PERIPH_ID_DISP1);
	clock_enable(PERIPH_ID_PWM);
	clock_enable(PERIPH_ID_DPAUX);
	clock_enable(PERIPH_ID_SOR0);
	udelay(2);

	reset_set_enable(PERIPH_ID_HOST1X, 0);
	reset_set_enable(PERIPH_ID_DISP1, 0);
	reset_set_enable(PERIPH_ID_PWM, 0);
	reset_set_enable(PERIPH_ID_DPAUX, 0);
	reset_set_enable(PERIPH_ID_SOR0, 0);

	ret = display_init(dev, lcdbase, 1 << l2bpp, &timing);
	if (ret)
		return ret;

	uc_priv->xsize = roundup(timing.hactive.typ, 16);
	uc_priv->ysize = timing.vactive.typ;
	uc_priv->bpix = l2bpp;

	video_set_flush_dcache(dev, 1);
	debug("%s: done\n", __func__);

	return 0;
}
Exemplo n.º 29
0
int dm_gpio_request(struct gpio_desc *desc, const char *label)
{
	struct udevice *dev = desc->dev;
	struct gpio_dev_priv *uc_priv;
	char *str;
	int ret;

	uc_priv = dev_get_uclass_priv(dev);
	if (uc_priv->name[desc->offset])
		return -EBUSY;
	str = strdup(label);
	if (!str)
		return -ENOMEM;
	if (gpio_get_ops(dev)->request) {
		ret = gpio_get_ops(dev)->request(dev, desc->offset, label);
		if (ret) {
			free(str);
			return ret;
		}
	}
	uc_priv->name[desc->offset] = str;

	return 0;
}
Exemplo n.º 30
0
int dma_get_device(u32 transfer_type, struct udevice **devp)
{
	struct udevice *dev;
	int ret;

	for (ret = uclass_first_device(UCLASS_DMA, &dev); dev && !ret;
	     ret = uclass_next_device(&dev)) {
		struct dma_dev_priv *uc_priv;

		uc_priv = dev_get_uclass_priv(dev);
		if (uc_priv->supported & transfer_type)
			break;
	}

	if (!dev) {
		pr_err("No DMA device found that supports %x type\n",
		      transfer_type);
		return -EPROTONOSUPPORT;
	}

	*devp = dev;

	return ret;
}