Merge master.kernel.org:/home/rmk/linux-2.6-arm
* master.kernel.org:/home/rmk/linux-2.6-arm: [ARM] 5326/1: AFEB9260: Fix for i2c_board_info structure [ARM] mx31ads: Add missing include [ARM] MXC: Fix mxc_gpio_get(), which must read PSR register instead DR. [ARM] MX3: Use ioremap wrapper to map SoC devices nonshared [ARM] gpio_free might sleep, arm architecture [ARM] ep93xx: fix OHCI DMA mask leds: da903x: (da9030 only) led brightness reversed. [ARM] sharpsl_pm: fix compilation w/o CONFIG_PM [ARM] pcm037: map AIPS1 and AIPS2 as nonshared area [ARM] build fixes for netX serial driver [ARM] 5323/1: Remove outdated empeg documentation. [ARM] 5299/1: Add maintainer for Mobilepro 900/c [ARM] corgi_lcd: fix simultaneous compilation with corgi_bl [ARM] pxa/spitz: fix spi cs on spitz [ARM] 5322/1: Fix fastpath issue in mmci.c [ARM] xsc3: revert writethrough memory-type encoding change
This commit is contained in:
Коммит
7105212bd3
|
@ -1,13 +0,0 @@
|
|||
Empeg, Ltd's Empeg MP3 Car Audio Player
|
||||
|
||||
The initial design is to go in your car, but you can use it at home, on a
|
||||
boat... almost anywhere. The principle is to store CD-quality music using
|
||||
MPEG technology onto a hard disk in the unit, and use the power of the
|
||||
embedded computer to serve up the music you want.
|
||||
|
||||
For more details, see:
|
||||
|
||||
http://www.empeg.com
|
||||
|
||||
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
Infra-red driver documentation.
|
||||
|
||||
Mike Crowe <mac@empeg.com>
|
||||
(C) Empeg Ltd 1999
|
||||
|
||||
Not a lot here yet :-)
|
||||
|
||||
The Kenwood KCA-R6A remote control generates a sequence like the following:
|
||||
|
||||
Go low for approx 16T (Around 9000us)
|
||||
Go high for approx 8T (Around 4000us)
|
||||
Go low for less than 2T (Around 750us)
|
||||
|
||||
For each of the 32 bits
|
||||
Go high for more than 2T (Around 1500us) == 1
|
||||
Go high for less than T (Around 400us) == 0
|
||||
Go low for less than 2T (Around 750us)
|
||||
|
||||
Rather than repeat a signal when the button is held down certain buttons
|
||||
generate the following code to indicate repetition.
|
||||
|
||||
Go low for approx 16T
|
||||
Go high for approx 4T
|
||||
Go low for less than 2T
|
||||
|
||||
(By removing the <2T from the start of the sequence and placing at the end
|
||||
it can be considered a stop bit but I found it easier to deal with it at
|
||||
the start).
|
||||
|
||||
The 32 bits are encoded as XxYy where x and y are the actual data values
|
||||
while X and Y are the logical inverses of the associated data values. Using
|
||||
LSB first yields sensible codes for the numbers.
|
||||
|
||||
All codes are of the form b9xx
|
||||
|
||||
The numeric keys generate the code 0x where x is the number pressed.
|
||||
|
||||
Tuner 1c
|
||||
Tape 1d
|
||||
CD 1e
|
||||
CD-MD-CH 1f
|
||||
Track- 0a
|
||||
Track+ 0b
|
||||
Rewind 0c
|
||||
FF 0d
|
||||
DNPP 5e
|
||||
Play/Pause 0e
|
||||
Vol+ 14
|
||||
Vol- 15
|
|
@ -1,11 +0,0 @@
|
|||
#!/bin/sh
|
||||
mknod /dev/display c 244 0
|
||||
mknod /dev/ir c 242 0
|
||||
mknod /dev/usb0 c 243 0
|
||||
mknod /dev/audio c 245 4
|
||||
mknod /dev/dsp c 245 3
|
||||
mknod /dev/mixer c 245 0
|
||||
mknod /dev/empeg_state c 246 0
|
||||
mknod /dev/radio0 c 81 64
|
||||
ln -sf radio0 radio
|
||||
ln -sf usb0 usb
|
|
@ -610,6 +610,11 @@ P: Philipp Zabel
|
|||
M: philipp.zabel@gmail.com
|
||||
S: Maintained
|
||||
|
||||
ARM/NEC MOBILEPRO 900/c MACHINE SUPPORT
|
||||
P: Michael Petchkovsky
|
||||
M: mkpetch@internode.on.net
|
||||
S: Maintained
|
||||
|
||||
ARM/TOSA MACHINE SUPPORT
|
||||
P: Dmitry Baryshkov
|
||||
M: dbaryshkov@gmail.com
|
||||
|
|
|
@ -54,11 +54,13 @@
|
|||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
#ifdef CONFIG_PM
|
||||
static int sharpsl_off_charge_battery(void);
|
||||
static int sharpsl_check_battery_temp(void);
|
||||
static int sharpsl_check_battery_voltage(void);
|
||||
static int sharpsl_ac_check(void);
|
||||
static int sharpsl_fatal_check(void);
|
||||
#endif
|
||||
static int sharpsl_check_battery_temp(void);
|
||||
static int sharpsl_ac_check(void);
|
||||
static int sharpsl_average_value(int ad);
|
||||
static void sharpsl_average_clear(void);
|
||||
static void sharpsl_charge_toggle(struct work_struct *private_);
|
||||
|
@ -424,6 +426,7 @@ static int sharpsl_check_battery_temp(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int sharpsl_check_battery_voltage(void)
|
||||
{
|
||||
int val, i, buff[5];
|
||||
|
@ -455,6 +458,7 @@ static int sharpsl_check_battery_voltage(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int sharpsl_ac_check(void)
|
||||
{
|
||||
|
@ -586,8 +590,6 @@ static int corgi_pxa_pm_enter(suspend_state_t state)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Check for fatal battery errors
|
||||
|
@ -738,7 +740,10 @@ static int sharpsl_off_charge_battery(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#define sharpsl_pm_suspend NULL
|
||||
#define sharpsl_pm_resume NULL
|
||||
#endif
|
||||
|
||||
static ssize_t battery_percentage_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
|
@ -768,10 +773,12 @@ static void sharpsl_apm_get_power_status(struct apm_power_info *info)
|
|||
info->battery_life = sharpsl_pm.battstat.mainbat_percent;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static struct platform_suspend_ops sharpsl_pm_ops = {
|
||||
.enter = corgi_pxa_pm_enter,
|
||||
.valid = suspend_valid_only_mem,
|
||||
};
|
||||
#endif
|
||||
|
||||
static int __init sharpsl_pm_probe(struct platform_device *pdev)
|
||||
{
|
||||
|
@ -802,7 +809,9 @@ static int __init sharpsl_pm_probe(struct platform_device *pdev)
|
|||
|
||||
apm_get_power_status = sharpsl_apm_get_power_status;
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
suspend_set_ops(&sharpsl_pm_ops);
|
||||
#endif
|
||||
|
||||
mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
|
||||
|
||||
|
|
|
@ -165,6 +165,7 @@ static struct at91_mmc_data __initdata afeb9260_mmc_data = {
|
|||
static struct i2c_board_info __initdata afeb9260_i2c_devices[] = {
|
||||
{
|
||||
I2C_BOARD_INFO("fm3130", 0x68),
|
||||
}, {
|
||||
I2C_BOARD_INFO("24c64", 0x50),
|
||||
},
|
||||
};
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#ifndef __ASM_ARCH_AT91RM9200_GPIO_H
|
||||
#define __ASM_ARCH_AT91RM9200_GPIO_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#define PIN_BASE NR_AIC_IRQS
|
||||
|
@ -220,6 +221,7 @@ static inline int gpio_request(unsigned gpio, const char *label)
|
|||
|
||||
static inline void gpio_free(unsigned gpio)
|
||||
{
|
||||
might_sleep();
|
||||
}
|
||||
|
||||
extern int gpio_direction_input(unsigned gpio);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <linux/serial_core.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/timex.h>
|
||||
#include <linux/delay.h>
|
||||
|
@ -449,12 +450,13 @@ static struct resource ep93xx_ohci_resources[] = {
|
|||
},
|
||||
};
|
||||
|
||||
|
||||
static struct platform_device ep93xx_ohci_device = {
|
||||
.name = "ep93xx-ohci",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.dma_mask = (void *)0xffffffff,
|
||||
.coherent_dma_mask = 0xffffffff,
|
||||
.dma_mask = &ep93xx_ohci_device.dev.coherent_dma_mask,
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
},
|
||||
.num_resources = ARRAY_SIZE(ep93xx_ohci_resources),
|
||||
.resource = ep93xx_ohci_resources,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#ifndef _IMX_GPIO_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <mach/imx-regs.h>
|
||||
|
||||
#define IMX_GPIO_ALLOC_MODE_NORMAL 0
|
||||
|
@ -63,6 +64,8 @@ static inline int gpio_request(unsigned gpio, const char *label)
|
|||
|
||||
static inline void gpio_free(unsigned gpio)
|
||||
{
|
||||
might_sleep();
|
||||
|
||||
imx_gpio_free(gpio);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#ifndef __ASM_ARCH_IXP4XX_GPIO_H
|
||||
#define __ASM_ARCH_IXP4XX_GPIO_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
static inline int gpio_request(unsigned gpio, const char *label)
|
||||
|
@ -34,6 +35,8 @@ static inline int gpio_request(unsigned gpio, const char *label)
|
|||
|
||||
static inline void gpio_free(unsigned gpio)
|
||||
{
|
||||
might_sleep();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#ifndef __ASM_ARCH_GPIO_H_
|
||||
#define __ASM_ARCH_GPIO_H_
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#define KS8695_GPIO_0 0
|
||||
#define KS8695_GPIO_1 1
|
||||
#define KS8695_GPIO_2 2
|
||||
|
@ -74,6 +76,7 @@ static inline int gpio_request(unsigned int pin, const char *label)
|
|||
|
||||
static inline void gpio_free(unsigned int pin)
|
||||
{
|
||||
might_sleep();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#include <mach/imx-uart.h>
|
||||
#include <mach/iomux-mx3.h>
|
||||
|
||||
#include "devices.h"
|
||||
|
||||
/*!
|
||||
* @file mx31ads.c
|
||||
*
|
||||
|
|
|
@ -91,12 +91,12 @@ static struct map_desc pcm037_io_desc[] __initdata = {
|
|||
.virtual = AIPS1_BASE_ADDR_VIRT,
|
||||
.pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
|
||||
.length = AIPS1_SIZE,
|
||||
.type = MT_DEVICE
|
||||
.type = MT_DEVICE_NONSHARED
|
||||
}, {
|
||||
.virtual = AIPS2_BASE_ADDR_VIRT,
|
||||
.pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
|
||||
.length = AIPS2_SIZE,
|
||||
.type = MT_DEVICE
|
||||
.type = MT_DEVICE_NONSHARED
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
@ -63,6 +64,7 @@ EXPORT_SYMBOL(gpio_request);
|
|||
|
||||
void gpio_free(unsigned gpio)
|
||||
{
|
||||
might_sleep();
|
||||
clear_bit(gpio, gpiores);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -165,6 +165,8 @@ EXPORT_SYMBOL(gpio_request);
|
|||
|
||||
void gpio_free(unsigned pin)
|
||||
{
|
||||
might_sleep();
|
||||
|
||||
if (pin >= GPIO_MAX || !test_bit(pin, gpio_valid)) {
|
||||
pr_debug("%s: invalid GPIO %d\n", __func__, pin);
|
||||
return;
|
||||
|
|
|
@ -204,7 +204,9 @@ static struct sharpsl_charger_machinfo corgi_pm_machinfo = {
|
|||
.read_devdata = corgipm_read_devdata,
|
||||
.charger_wakeup = corgi_charger_wakeup,
|
||||
.should_wakeup = corgi_should_wakeup,
|
||||
#ifdef CONFIG_BACKLIGHT_CORGI
|
||||
#if defined(CONFIG_LCD_CORGI)
|
||||
.backlight_limit = corgi_lcd_limit_intensity,
|
||||
#elif defined(CONFIG_BACKLIGHT_CORGI)
|
||||
.backlight_limit = corgibl_limit_intensity,
|
||||
#endif
|
||||
.charge_on_volt = SHARPSL_CHARGE_ON_VOLT,
|
||||
|
|
|
@ -26,6 +26,7 @@ struct corgits_machinfo {
|
|||
* SharpSL Backlight
|
||||
*/
|
||||
extern void corgibl_limit_intensity(int limit);
|
||||
extern void corgi_lcd_limit_intensity(int limit);
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -385,6 +385,16 @@ static void __init spitz_init_spi(void)
|
|||
if (err)
|
||||
goto err_free_2;
|
||||
|
||||
err = gpio_direction_output(SPITZ_GPIO_ADS7846_CS, 1);
|
||||
if (err)
|
||||
goto err_free_3;
|
||||
err = gpio_direction_output(SPITZ_GPIO_LCDCON_CS, 1);
|
||||
if (err)
|
||||
goto err_free_3;
|
||||
err = gpio_direction_output(SPITZ_GPIO_MAX1111_CS, 1);
|
||||
if (err)
|
||||
goto err_free_3;
|
||||
|
||||
if (machine_is_akita()) {
|
||||
spitz_lcdcon_info.gpio_backlight_cont = AKITA_GPIO_BACKLIGHT_CONT;
|
||||
spitz_lcdcon_info.gpio_backlight_on = AKITA_GPIO_BACKLIGHT_ON;
|
||||
|
@ -394,6 +404,8 @@ static void __init spitz_init_spi(void)
|
|||
spi_register_board_info(ARRAY_AND_SIZE(spitz_spi_devices));
|
||||
return;
|
||||
|
||||
err_free_3:
|
||||
gpio_free(SPITZ_GPIO_MAX1111_CS);
|
||||
err_free_2:
|
||||
gpio_free(SPITZ_GPIO_LCDCON_CS);
|
||||
err_free_1:
|
||||
|
|
|
@ -198,7 +198,9 @@ struct sharpsl_charger_machinfo spitz_pm_machinfo = {
|
|||
.read_devdata = spitzpm_read_devdata,
|
||||
.charger_wakeup = spitz_charger_wakeup,
|
||||
.should_wakeup = spitz_should_wakeup,
|
||||
#ifdef CONFIG_BACKLIGHT_CORGI
|
||||
#if defined(CONFIG_LCD_CORGI)
|
||||
.backlight_limit = corgi_lcd_limit_intensity,
|
||||
#elif defined(CONFIG_BACKLIGHT_CORGI)
|
||||
.backlight_limit = corgibl_limit_intensity,
|
||||
#endif
|
||||
.charge_on_volt = SHARPSL_CHARGE_ON_VOLT,
|
||||
|
|
|
@ -349,7 +349,7 @@ ENTRY(cpu_xsc3_switch_mm)
|
|||
cpu_xsc3_mt_table:
|
||||
.long 0x00 @ L_PTE_MT_UNCACHED
|
||||
.long PTE_EXT_TEX(1) @ L_PTE_MT_BUFFERABLE
|
||||
.long PTE_CACHEABLE @ L_PTE_MT_WRITETHROUGH
|
||||
.long PTE_EXT_TEX(5) | PTE_CACHEABLE @ L_PTE_MT_WRITETHROUGH
|
||||
.long PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEBACK
|
||||
.long PTE_EXT_TEX(1) | PTE_BUFFERABLE @ L_PTE_MT_DEV_SHARED
|
||||
.long 0x00 @ unused
|
||||
|
|
|
@ -188,7 +188,7 @@ static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset)
|
|||
struct mxc_gpio_port *port =
|
||||
container_of(chip, struct mxc_gpio_port, chip);
|
||||
|
||||
return (__raw_readl(port->base + GPIO_DR) >> offset) & 1;
|
||||
return (__raw_readl(port->base + GPIO_PSR) >> offset) & 1;
|
||||
}
|
||||
|
||||
static int mxc_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
|
|
|
@ -14,6 +14,26 @@
|
|||
/* Allow IO space to be anywhere in the memory */
|
||||
#define IO_SPACE_LIMIT 0xffffffff
|
||||
|
||||
#ifdef CONFIG_ARCH_MX3
|
||||
#define __arch_ioremap __mx3_ioremap
|
||||
#define __arch_iounmap __iounmap
|
||||
|
||||
static inline void __iomem *
|
||||
__mx3_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
|
||||
{
|
||||
if (mtype == MT_DEVICE) {
|
||||
/* Access all peripherals below 0x80000000 as nonshared device
|
||||
* but leave l2cc alone.
|
||||
*/
|
||||
if ((phys_addr < 0x80000000) && ((phys_addr < L2CC_BASE_ADDR) ||
|
||||
(phys_addr >= L2CC_BASE_ADDR + L2CC_SIZE)))
|
||||
mtype = MT_DEVICE_NONSHARED;
|
||||
}
|
||||
|
||||
return __arm_ioremap(phys_addr, size, mtype);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* io address mapping macro */
|
||||
#define __io(a) ((void __iomem *)(a))
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ static void da903x_led_work(struct work_struct *work)
|
|||
offset = DA9030_LED_OFFSET(led->id);
|
||||
val = led->flags & ~0x87;
|
||||
val |= (led->new_brightness) ? 0x80 : 0; /* EN bit */
|
||||
val |= (led->new_brightness >> 5) & 0x7; /* PWM<2:0> */
|
||||
val |= (0x7 - (led->new_brightness >> 5)) & 0x7; /* PWM<2:0> */
|
||||
da903x_write(led->master, DA9030_LED1_CONTROL + offset, val);
|
||||
break;
|
||||
case DA9030_ID_VIBRA:
|
||||
|
|
|
@ -391,6 +391,7 @@ static irqreturn_t mmci_irq(int irq, void *dev_id)
|
|||
static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
||||
{
|
||||
struct mmci_host *host = mmc_priv(mmc);
|
||||
unsigned long flags;
|
||||
|
||||
WARN_ON(host->mrq != NULL);
|
||||
|
||||
|
@ -402,7 +403,7 @@ static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
|||
return;
|
||||
}
|
||||
|
||||
spin_lock_irq(&host->lock);
|
||||
spin_lock_irqsave(&host->lock, flags);
|
||||
|
||||
host->mrq = mrq;
|
||||
|
||||
|
@ -411,7 +412,7 @@ static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
|||
|
||||
mmci_start_command(host, mrq->cmd, 0);
|
||||
|
||||
spin_unlock_irq(&host->lock);
|
||||
spin_unlock_irqrestore(&host->lock, flags);
|
||||
}
|
||||
|
||||
static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
|
||||
|
|
|
@ -1276,7 +1276,7 @@ config SERIAL_SGI_IOC3
|
|||
say Y or M. Otherwise, say N.
|
||||
|
||||
config SERIAL_NETX
|
||||
bool "NetX serial port support"
|
||||
tristate "NetX serial port support"
|
||||
depends on ARM && ARCH_NETX
|
||||
select SERIAL_CORE
|
||||
help
|
||||
|
@ -1288,7 +1288,7 @@ config SERIAL_NETX
|
|||
|
||||
config SERIAL_NETX_CONSOLE
|
||||
bool "Console on NetX serial port"
|
||||
depends on SERIAL_NETX
|
||||
depends on SERIAL_NETX=y
|
||||
select SERIAL_CORE_CONSOLE
|
||||
help
|
||||
If you have enabled the serial port on the Hilscher NetX SoC
|
||||
|
|
|
@ -42,8 +42,6 @@
|
|||
#define SERIAL_NX_MAJOR 204
|
||||
#define MINOR_START 170
|
||||
|
||||
#ifdef CONFIG_SERIAL_NETX_CONSOLE
|
||||
|
||||
enum uart_regs {
|
||||
UART_DR = 0x00,
|
||||
UART_SR = 0x04,
|
||||
|
@ -528,6 +526,8 @@ static struct netx_port netx_ports[] = {
|
|||
}
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SERIAL_NETX_CONSOLE
|
||||
|
||||
static void netx_console_putchar(struct uart_port *port, int ch)
|
||||
{
|
||||
while (readl(port->membase + UART_FR) & FR_BUSY);
|
||||
|
|
|
@ -439,7 +439,7 @@ static int corgi_bl_update_status(struct backlight_device *bd)
|
|||
return corgi_bl_set_intensity(lcd, intensity);
|
||||
}
|
||||
|
||||
void corgibl_limit_intensity(int limit)
|
||||
void corgi_lcd_limit_intensity(int limit)
|
||||
{
|
||||
if (limit)
|
||||
corgibl_flags |= CORGIBL_BATTLOW;
|
||||
|
@ -448,7 +448,7 @@ void corgibl_limit_intensity(int limit)
|
|||
|
||||
backlight_update_status(the_corgi_lcd->bl_dev);
|
||||
}
|
||||
EXPORT_SYMBOL(corgibl_limit_intensity);
|
||||
EXPORT_SYMBOL(corgi_lcd_limit_intensity);
|
||||
|
||||
static struct backlight_ops corgi_bl_ops = {
|
||||
.get_brightness = corgi_bl_get_intensity,
|
||||
|
|
Загрузка…
Ссылка в новой задаче