From e08e19c331fb249e6dc86365ee80d16045c4aeb1 Mon Sep 17 00:00:00 2001 From: "H. Nikolaus Schaller" Date: Fri, 16 Oct 2015 14:53:38 +0200 Subject: iio:adc: add iio driver for Palmas (twl6035/7) gpadc This driver code was found as: https://android.googlesource.com/kernel/tegra/+/aaabb2e045f31e5a970109ffdaae900dd403d17e/drivers/staging/iio/adc Fixed various compilation issues and test this driver on omap5 evm. Signed-off-by: Pradeep Goudagunta Signed-off-by: H. Nikolaus Schaller Signed-off-by: Marek Belisko Acked-by: Laxman Dewangan Reviewed-by: Jonathan Cameron Acked-by: Lee Jones Signed-off-by: Jonathan Cameron --- include/linux/mfd/palmas.h | 75 +++++++++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 24 deletions(-) (limited to 'include') diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h index 13e1d96935ed..c800dbc42079 100644 --- a/include/linux/mfd/palmas.h +++ b/include/linux/mfd/palmas.h @@ -134,21 +134,32 @@ struct palmas_pmic_driver_data { struct regulator_config config); }; +struct palmas_adc_wakeup_property { + int adc_channel_number; + int adc_high_threshold; + int adc_low_threshold; +}; + struct palmas_gpadc_platform_data { /* Channel 3 current source is only enabled during conversion */ - int ch3_current; + int ch3_current; /* 0: off; 1: 10uA; 2: 400uA; 3: 800 uA */ /* Channel 0 current source can be used for battery detection. * If used for battery detection this will cause a permanent current * consumption depending on current level set here. */ - int ch0_current; + int ch0_current; /* 0: off; 1: 5uA; 2: 15uA; 3: 20 uA */ + bool extended_delay; /* use extended delay for conversion */ /* default BAT_REMOVAL_DAT setting on device probe */ int bat_removal; /* Sets the START_POLARITY bit in the RT_CTRL register */ int start_polarity; + + int auto_conversion_period_ms; + struct palmas_adc_wakeup_property *adc_wakeup1_data; + struct palmas_adc_wakeup_property *adc_wakeup2_data; }; struct palmas_reg_init { @@ -405,28 +416,7 @@ struct palmas_gpadc_calibration { s32 offset_error; }; -struct palmas_gpadc { - struct device *dev; - struct palmas *palmas; - - int ch3_current; - int ch0_current; - - int gpadc_force; - - int bat_removal; - - struct mutex reading_lock; - struct completion irq_complete; - - int eoc_sw_irq; - - struct palmas_gpadc_calibration *palmas_cal_tbl; - - int conv0_channel; - int conv1_channel; - int rt_channel; -}; +#define PALMAS_DATASHEET_NAME(_name) "palmas-gpadc-chan-"#_name struct palmas_gpadc_result { s32 raw_code; @@ -520,6 +510,43 @@ enum palmas_irqs { PALMAS_NUM_IRQ, }; +/* Palmas GPADC Channels */ +enum { + PALMAS_ADC_CH_IN0, + PALMAS_ADC_CH_IN1, + PALMAS_ADC_CH_IN2, + PALMAS_ADC_CH_IN3, + PALMAS_ADC_CH_IN4, + PALMAS_ADC_CH_IN5, + PALMAS_ADC_CH_IN6, + PALMAS_ADC_CH_IN7, + PALMAS_ADC_CH_IN8, + PALMAS_ADC_CH_IN9, + PALMAS_ADC_CH_IN10, + PALMAS_ADC_CH_IN11, + PALMAS_ADC_CH_IN12, + PALMAS_ADC_CH_IN13, + PALMAS_ADC_CH_IN14, + PALMAS_ADC_CH_IN15, + PALMAS_ADC_CH_MAX, +}; + +/* Palmas GPADC Channel0 Current Source */ +enum { + PALMAS_ADC_CH0_CURRENT_SRC_0, + PALMAS_ADC_CH0_CURRENT_SRC_5, + PALMAS_ADC_CH0_CURRENT_SRC_15, + PALMAS_ADC_CH0_CURRENT_SRC_20, +}; + +/* Palmas GPADC Channel3 Current Source */ +enum { + PALMAS_ADC_CH3_CURRENT_SRC_0, + PALMAS_ADC_CH3_CURRENT_SRC_10, + PALMAS_ADC_CH3_CURRENT_SRC_400, + PALMAS_ADC_CH3_CURRENT_SRC_800, +}; + struct palmas_pmic { struct palmas *palmas; struct device *dev; -- cgit v1.2.3 From b440655b896b2d5a2fb5f918801fb0e281a537cd Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Oct 2015 18:10:26 +0200 Subject: iio: Add support for indicating fixed watermarks For buffers which have a fixed wake-up watermark the watermark attribute should be read-only. Add a new FIXED_WATERMARK flag to the struct iio_buffer_access_funcs, which can be set by a buffer implementation. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- include/linux/iio/buffer.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h index 1600c55828e0..4d99a53d1fe7 100644 --- a/include/linux/iio/buffer.h +++ b/include/linux/iio/buffer.h @@ -17,6 +17,12 @@ struct iio_buffer; +/** + * INDIO_BUFFER_FLAG_FIXED_WATERMARK - Watermark level of the buffer can not be + * configured. It has a fixed value which will be buffer specific. + */ +#define INDIO_BUFFER_FLAG_FIXED_WATERMARK BIT(0) + /** * struct iio_buffer_access_funcs - access functions for buffers. * @store_to: actually store stuff to the buffer @@ -30,6 +36,7 @@ struct iio_buffer; * @release: called when the last reference to the buffer is dropped, * should free all resources allocated by the buffer. * @modes: Supported operating modes by this buffer type + * @flags: A bitmask combination of INDIO_BUFFER_FLAG_* * * The purpose of this structure is to make the buffer element * modular as event for a given driver, different usecases may require @@ -54,6 +61,7 @@ struct iio_buffer_access_funcs { void (*release)(struct iio_buffer *buffer); unsigned int modes; + unsigned int flags; }; /** -- cgit v1.2.3 From e18a2ad45caeb11226e49c25068d0f2efe2adf6c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Oct 2015 18:10:27 +0200 Subject: iio: Add buffer enable/disable callbacks This patch adds a enable and disable callback that is called when the buffer is enabled/disabled. This can be used by buffer implementations that need to do some setup or teardown work. E.g. a DMA based buffer can use this to start/stop the DMA transfer. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- include/linux/iio/buffer.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h index 4d99a53d1fe7..2ec3ad58e8a0 100644 --- a/include/linux/iio/buffer.h +++ b/include/linux/iio/buffer.h @@ -33,6 +33,11 @@ struct iio_buffer; * storage. * @set_bytes_per_datum:set number of bytes per datum * @set_length: set number of datums in buffer + * @enable: called if the buffer is attached to a device and the + * device starts sampling. Calls are balanced with + * @disable. + * @disable: called if the buffer is attached to a device and the + * device stops sampling. Calles are balanced with @enable. * @release: called when the last reference to the buffer is dropped, * should free all resources allocated by the buffer. * @modes: Supported operating modes by this buffer type @@ -58,6 +63,9 @@ struct iio_buffer_access_funcs { int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd); int (*set_length)(struct iio_buffer *buffer, int length); + int (*enable)(struct iio_buffer *buffer, struct iio_dev *indio_dev); + int (*disable)(struct iio_buffer *buffer, struct iio_dev *indio_dev); + void (*release)(struct iio_buffer *buffer); unsigned int modes; -- cgit v1.2.3 From 670b19ae9bfdbcb4ce2c2ffb2ec1659a7f4a2074 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Oct 2015 18:10:28 +0200 Subject: iio: Add generic DMA buffer infrastructure The traditional approach used in IIO to implement buffered capture requires the generation of at least one interrupt per sample. In the interrupt handler the driver reads the sample from the device and copies it to a software buffer. This approach has a rather large per sample overhead associated with it. And while it works fine for samplerates in the range of up to 1000 samples per second it starts to consume a rather large share of the available CPU processing time once we go beyond that, this is especially true on an embedded system with limited processing power. The regular interrupt also causes increased power consumption by not allowing the hardware into deeper sleep states, which is something that becomes more and more important on mobile battery powered devices. And while the recently added watermark support mitigates some of the issues by allowing the device to generate interrupts at a rate lower than the data output rate, this still requires a storage buffer inside the device and even if it exists it is only a few 100 samples deep at most. DMA support on the other hand allows to capture multiple millions or even more samples without any CPU interaction. This allows the CPU to either go to sleep for longer periods or focus on other tasks which increases overall system performance and power consumption. In addition to that some devices might not even offer a way to read the data other than using DMA, which makes DMA mandatory to use for them. The tasks involved in implementing a DMA buffer can be divided into two categories. The first category is memory buffer management (allocation, mapping, etc.) and hooking this up the IIO buffer callbacks like read(), enable(), disable(), etc. The second category of tasks is to setup the DMA hardware and manage the DMA transfers. Tasks from the first category will be very similar for all IIO drivers supporting DMA buffers, while the tasks from the second category will be hardware specific. This patch implements a generic infrastructure that take care of the former tasks. It provides a set of functions that implement the standard IIO buffer iio_buffer_access_funcs callbacks. These can either be used as is or be overloaded and augmented with driver specific code where necessary. For the DMA buffer support infrastructure that is introduced in this series sample data is grouped by so called blocks. A block is the basic unit at which data is exchanged between the application and the hardware. The application is responsible for allocating the memory associated with the block and then passes the block to the hardware. When the hardware has captured the amount of samples equal to size of a block it will notify the application, which can then read the data from the block and process it. The block size can freely chosen (within the constraints of the hardware). This allows to make a trade-off between latency and management overhead. The larger the block size the lower the per sample overhead but the latency between when the data was captured and when the application will be able to access it increases, in a similar way smaller block sizes have a larger per sample management overhead but a lower latency. The ideal block size thus depends on system and application requirements. For the time being the infrastructure only implements a simple double buffered scheme which allocates two blocks each with half the size of the configured buffer size. This provides basic support for capturing continuous uninterrupted data over the existing file-IO ABI. Future extensions to the DMA buffer infrastructure will give applications a more fine grained control over how many blocks are allocated and the size of each block. But this requires userspace ABI additions which are intentionally not part of this patch and will be added separately. Tasks of the second category need to be implemented by a device specific driver. They can be hooked up into the generic infrastructure using two simple callbacks, submit() and abort(). The submit() callback is used to schedule DMA transfers for blocks. Once a DMA transfer has been completed it is expected that the buffer driver calls iio_dma_buffer_block_done() to notify. The abort() callback is used for stopping all pending and active DMA transfers when the buffer is disabled. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- include/linux/iio/buffer-dma.h | 152 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 include/linux/iio/buffer-dma.h (limited to 'include') diff --git a/include/linux/iio/buffer-dma.h b/include/linux/iio/buffer-dma.h new file mode 100644 index 000000000000..767467d886de --- /dev/null +++ b/include/linux/iio/buffer-dma.h @@ -0,0 +1,152 @@ +/* + * Copyright 2013-2015 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2. + */ + +#ifndef __INDUSTRIALIO_DMA_BUFFER_H__ +#define __INDUSTRIALIO_DMA_BUFFER_H__ + +#include +#include +#include +#include +#include + +struct iio_dma_buffer_queue; +struct iio_dma_buffer_ops; +struct device; + +struct iio_buffer_block { + u32 size; + u32 bytes_used; +}; + +/** + * enum iio_block_state - State of a struct iio_dma_buffer_block + * @IIO_BLOCK_STATE_DEQUEUED: Block is not queued + * @IIO_BLOCK_STATE_QUEUED: Block is on the incoming queue + * @IIO_BLOCK_STATE_ACTIVE: Block is currently being processed by the DMA + * @IIO_BLOCK_STATE_DONE: Block is on the outgoing queue + * @IIO_BLOCK_STATE_DEAD: Block has been marked as to be freed + */ +enum iio_block_state { + IIO_BLOCK_STATE_DEQUEUED, + IIO_BLOCK_STATE_QUEUED, + IIO_BLOCK_STATE_ACTIVE, + IIO_BLOCK_STATE_DONE, + IIO_BLOCK_STATE_DEAD, +}; + +/** + * struct iio_dma_buffer_block - IIO buffer block + * @head: List head + * @size: Total size of the block in bytes + * @bytes_used: Number of bytes that contain valid data + * @vaddr: Virutal address of the blocks memory + * @phys_addr: Physical address of the blocks memory + * @queue: Parent DMA buffer queue + * @kref: kref used to manage the lifetime of block + * @state: Current state of the block + */ +struct iio_dma_buffer_block { + /* May only be accessed by the owner of the block */ + struct list_head head; + size_t bytes_used; + + /* + * Set during allocation, constant thereafter. May be accessed read-only + * by anybody holding a reference to the block. + */ + void *vaddr; + dma_addr_t phys_addr; + size_t size; + struct iio_dma_buffer_queue *queue; + + /* Must not be accessed outside the core. */ + struct kref kref; + /* + * Must not be accessed outside the core. Access needs to hold + * queue->list_lock if the block is not owned by the core. + */ + enum iio_block_state state; +}; + +/** + * struct iio_dma_buffer_queue_fileio - FileIO state for the DMA buffer + * @blocks: Buffer blocks used for fileio + * @active_block: Block being used in read() + * @pos: Read offset in the active block + * @block_size: Size of each block + */ +struct iio_dma_buffer_queue_fileio { + struct iio_dma_buffer_block *blocks[2]; + struct iio_dma_buffer_block *active_block; + size_t pos; + size_t block_size; +}; + +/** + * struct iio_dma_buffer_queue - DMA buffer base structure + * @buffer: IIO buffer base structure + * @dev: Parent device + * @ops: DMA buffer callbacks + * @lock: Protects the incoming list, active and the fields in the fileio + * substruct + * @list_lock: Protects lists that contain blocks which can be modified in + * atomic context as well as blocks on those lists. This is the outgoing queue + * list and typically also a list of active blocks in the part that handles + * the DMA controller + * @incoming: List of buffers on the incoming queue + * @outgoing: List of buffers on the outgoing queue + * @active: Whether the buffer is currently active + * @fileio: FileIO state + */ +struct iio_dma_buffer_queue { + struct iio_buffer buffer; + struct device *dev; + const struct iio_dma_buffer_ops *ops; + + struct mutex lock; + spinlock_t list_lock; + struct list_head incoming; + struct list_head outgoing; + + bool active; + + struct iio_dma_buffer_queue_fileio fileio; +}; + +/** + * struct iio_dma_buffer_ops - DMA buffer callback operations + * @submit: Called when a block is submitted to the DMA controller + * @abort: Should abort all pending transfers + */ +struct iio_dma_buffer_ops { + int (*submit)(struct iio_dma_buffer_queue *queue, + struct iio_dma_buffer_block *block); + void (*abort)(struct iio_dma_buffer_queue *queue); +}; + +void iio_dma_buffer_block_done(struct iio_dma_buffer_block *block); +void iio_dma_buffer_block_list_abort(struct iio_dma_buffer_queue *queue, + struct list_head *list); + +int iio_dma_buffer_enable(struct iio_buffer *buffer, + struct iio_dev *indio_dev); +int iio_dma_buffer_disable(struct iio_buffer *buffer, + struct iio_dev *indio_dev); +int iio_dma_buffer_read(struct iio_buffer *buffer, size_t n, + char __user *user_buffer); +size_t iio_dma_buffer_data_available(struct iio_buffer *buffer); +int iio_dma_buffer_set_bytes_per_datum(struct iio_buffer *buffer, size_t bpd); +int iio_dma_buffer_set_length(struct iio_buffer *buffer, int length); +int iio_dma_buffer_request_update(struct iio_buffer *buffer); + +int iio_dma_buffer_init(struct iio_dma_buffer_queue *queue, + struct device *dma_dev, const struct iio_dma_buffer_ops *ops); +void iio_dma_buffer_exit(struct iio_dma_buffer_queue *queue); +void iio_dma_buffer_release(struct iio_dma_buffer_queue *queue); + +#endif -- cgit v1.2.3 From 2d6ca60f328450ff5c7802d0857d12e3711348ce Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Oct 2015 18:10:29 +0200 Subject: iio: Add a DMAengine framework based buffer Add a generic fully device independent DMA buffer implementation that uses the DMAegnine framework to perform the DMA transfers. This can be used by converter drivers that whish to provide a DMA buffer for converters that are connected to a DMA core that implements the DMAengine API. Apart from allocating the buffer using iio_dmaengine_buffer_alloc() and freeing it using iio_dmaengine_buffer_free() no additional converter driver specific code is required when using this DMA buffer implementation. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- include/linux/iio/buffer-dmaengine.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 include/linux/iio/buffer-dmaengine.h (limited to 'include') diff --git a/include/linux/iio/buffer-dmaengine.h b/include/linux/iio/buffer-dmaengine.h new file mode 100644 index 000000000000..5dcddf427bb0 --- /dev/null +++ b/include/linux/iio/buffer-dmaengine.h @@ -0,0 +1,18 @@ +/* + * Copyright 2014-2015 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __IIO_DMAENGINE_H__ +#define __IIO_DMAENGINE_H__ + +struct iio_buffer; +struct device; + +struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev, + const char *channel); +void iio_dmaengine_buffer_free(struct iio_buffer *buffer); + +#endif -- cgit v1.2.3 From 28b8b26b308e656edfa9467867d5f79212da2ec3 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 30 Oct 2015 20:33:20 -0700 Subject: mtd: add get/set of_node/flash_node helpers We are going to begin using the mtd->dev.of_node field for MTD device nodes, so let's add helpers for it. Also, we'll be making some conversions on spi_nor (and nand_chip eventually) too, so get that ready with their own helpers. Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- include/linux/mtd/mtd.h | 11 +++++++++++ include/linux/mtd/nand.h | 11 +++++++++++ include/linux/mtd/spi-nor.h | 11 +++++++++++ 3 files changed, 33 insertions(+) (limited to 'include') diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index f17fa75809aa..cc84923011c0 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -254,6 +254,17 @@ struct mtd_info { int usecount; }; +static inline void mtd_set_of_node(struct mtd_info *mtd, + struct device_node *np) +{ + mtd->dev.of_node = np; +} + +static inline struct device_node *mtd_get_of_node(struct mtd_info *mtd) +{ + return mtd->dev.of_node; +} + int mtd_erase(struct mtd_info *mtd, struct erase_info *instr); int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, void **virt, resource_size_t *phys); diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 5a9d1d4c2487..4f7c9b97982f 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -719,6 +719,17 @@ struct nand_chip { void *priv; }; +static inline void nand_set_flash_node(struct nand_chip *chip, + struct device_node *np) +{ + chip->flash_node = np; +} + +static inline struct device_node *nand_get_flash_node(struct nand_chip *chip) +{ + return chip->flash_node; +} + /* * NAND Flash Manufacturer ID Codes */ diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index c8723b62c4cd..6d991df8f986 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -185,6 +185,17 @@ struct spi_nor { void *priv; }; +static inline void spi_nor_set_flash_node(struct spi_nor *nor, + struct device_node *np) +{ + nor->flash_node = np; +} + +static inline struct device_node *spi_nor_get_flash_node(struct spi_nor *nor) +{ + return nor->flash_node; +} + /** * spi_nor_scan() - scan the SPI NOR * @nor: the spi_nor structure -- cgit v1.2.3 From 3b6521eab0386a4854d47b1a01947d7dc46ec98d Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 30 Oct 2015 20:33:21 -0700 Subject: mtd: ofpart: grab device tree node directly from master device node It seems more logical to use a device node directly associated with the MTD master device (i.e., mtd->dev.of_node field) rather than requiring auxiliary partition parser information to be passed in by the driver in a separate struct. This patch supports the mtd->dev.of_node field and deprecates the parser data 'of_node' field Driver conversions may now follow. Additional side benefit to assigning mtd->dev.of_node rather than using parser data: the driver core will automatically create a device -> node symlink for us. Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- include/linux/mtd/partitions.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index 6a35e6de5da1..e742f34b67eb 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -56,7 +56,9 @@ struct device_node; /** * struct mtd_part_parser_data - used to pass data to MTD partition parsers. * @origin: for RedBoot, start address of MTD device - * @of_node: for OF parsers, device node containing partitioning information + * @of_node: for OF parsers, device node containing partitioning information. + * This field is deprecated, as the device node should simply be + * assigned to the master struct device. */ struct mtd_part_parser_data { unsigned long origin; -- cgit v1.2.3 From 30069af7348b56eb8c5e1dda7788a531c5f24ca2 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 30 Oct 2015 20:33:27 -0700 Subject: mtd: spi-nor: drop flash_node field We can just alias to the MTD of_node. Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- include/linux/mtd/spi-nor.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 6d991df8f986..955f268d159a 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -124,7 +124,6 @@ struct mtd_info; * @mtd: point to a mtd_info structure * @lock: the lock for the read/write/erase/lock/unlock operations * @dev: point to a spi device, or a spi nor controller device. - * @flash_node: point to a device node describing this flash instance. * @page_size: the page size of the SPI NOR * @addr_width: number of address bytes * @erase_opcode: the opcode for erasing a sector @@ -155,7 +154,6 @@ struct spi_nor { struct mtd_info mtd; struct mutex lock; struct device *dev; - struct device_node *flash_node; u32 page_size; u8 addr_width; u8 erase_opcode; @@ -188,12 +186,12 @@ struct spi_nor { static inline void spi_nor_set_flash_node(struct spi_nor *nor, struct device_node *np) { - nor->flash_node = np; + mtd_set_of_node(&nor->mtd, np); } static inline struct device_node *spi_nor_get_flash_node(struct spi_nor *nor) { - return nor->flash_node; + return mtd_get_of_node(&nor->mtd); } /** -- cgit v1.2.3 From e270bca531b40cd0a143176eb093d173b9c6f418 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 30 Oct 2015 20:33:29 -0700 Subject: mtd: ofpart: drop 'of_node' partition parser data This field is no longer used anywhere, as it is superseded by mtd->dev.of_node. Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- include/linux/mtd/partitions.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include') diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index e742f34b67eb..773975a3c9e6 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -56,13 +56,9 @@ struct device_node; /** * struct mtd_part_parser_data - used to pass data to MTD partition parsers. * @origin: for RedBoot, start address of MTD device - * @of_node: for OF parsers, device node containing partitioning information. - * This field is deprecated, as the device node should simply be - * assigned to the master struct device. */ struct mtd_part_parser_data { unsigned long origin; - struct device_node *of_node; }; -- cgit v1.2.3 From 26add94cd535d1e000e7871fe69c7bb89e942d67 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 11 Nov 2015 17:05:56 -0800 Subject: mtd: partitions: kill unused ecclayout struct This field is not used. Reported here: http://lists.infradead.org/pipermail/linux-mtd/2015-October/062417.html Reported-by: Brian Foster Cc: Brian Foster Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- include/linux/mtd/partitions.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index 773975a3c9e6..8421520c10eb 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -41,7 +41,6 @@ struct mtd_partition { uint64_t size; /* partition size */ uint64_t offset; /* offset within the master MTD space */ uint32_t mask_flags; /* master MTD flags to mask out for this partition */ - struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only) */ }; #define MTDPART_OFS_RETAIN (-3) -- cgit v1.2.3 From b36f09c3c441a6e59eab9315032e7d546571de3f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 20 Oct 2015 11:46:28 +0200 Subject: dmaengine: Add transfer termination synchronization support The DMAengine API has a long standing race condition that is inherent to the API itself. Calling dmaengine_terminate_all() is supposed to stop and abort any pending or active transfers that have previously been submitted. Unfortunately it is possible that this operation races against a currently running (or with some drivers also scheduled) completion callback. Since the API allows dmaengine_terminate_all() to be called from atomic context as well as from within a completion callback it is not possible to synchronize to the execution of the completion callback from within dmaengine_terminate_all() itself. This means that a user of the DMAengine API does not know when it is safe to free resources used in the completion callback, which can result in a use-after-free race condition. This patch addresses the issue by introducing an explicit synchronization primitive to the DMAengine API called dmaengine_synchronize(). The existing dmaengine_terminate_all() is deprecated in favor of dmaengine_terminate_sync() and dmaengine_terminate_async(). The former aborts all pending and active transfers and synchronizes to the current context, meaning it will wait until all running completion callbacks have finished. This means it is only possible to call this function from non-atomic context. The later function does not synchronize, but can still be used in atomic context or from within a complete callback. It has to be followed up by dmaengine_synchronize() before a client can free the resources used in a completion callback. In addition to this the semantics of the device_terminate_all() callback are slightly relaxed by this patch. It is now OK for a driver to only schedule the termination of the active transfer, but does not necessarily have to wait until the DMA controller has completely stopped. The driver must ensure though that the controller has stopped and no longer accesses any memory when the device_synchronize() callback returns. This was in part done since most drivers do not pay attention to this anyway at the moment and to emphasize that this needs to be done when the device_synchronize() callback is implemented. But it also helps with implementing support for devices where stopping the controller can require operations that may sleep. Signed-off-by: Lars-Peter Clausen Signed-off-by: Vinod Koul --- include/linux/dmaengine.h | 90 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) (limited to 'include') diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index c47c68e535e8..4662d9aa6d5a 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -654,6 +654,8 @@ enum dmaengine_alignment { * paused. Returns 0 or an error code * @device_terminate_all: Aborts all transfers on a channel. Returns 0 * or an error code + * @device_synchronize: Synchronizes the termination of a transfers to the + * current context. * @device_tx_status: poll for transaction completion, the optional * txstate parameter can be supplied with a pointer to get a * struct with auxiliary transfer status information, otherwise the call @@ -737,6 +739,7 @@ struct dma_device { int (*device_pause)(struct dma_chan *chan); int (*device_resume)(struct dma_chan *chan); int (*device_terminate_all)(struct dma_chan *chan); + void (*device_synchronize)(struct dma_chan *chan); enum dma_status (*device_tx_status)(struct dma_chan *chan, dma_cookie_t cookie, @@ -828,6 +831,13 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_sg( src_sg, src_nents, flags); } +/** + * dmaengine_terminate_all() - Terminate all active DMA transfers + * @chan: The channel for which to terminate the transfers + * + * This function is DEPRECATED use either dmaengine_terminate_sync() or + * dmaengine_terminate_async() instead. + */ static inline int dmaengine_terminate_all(struct dma_chan *chan) { if (chan->device->device_terminate_all) @@ -836,6 +846,86 @@ static inline int dmaengine_terminate_all(struct dma_chan *chan) return -ENOSYS; } +/** + * dmaengine_terminate_async() - Terminate all active DMA transfers + * @chan: The channel for which to terminate the transfers + * + * Calling this function will terminate all active and pending descriptors + * that have previously been submitted to the channel. It is not guaranteed + * though that the transfer for the active descriptor has stopped when the + * function returns. Furthermore it is possible the complete callback of a + * submitted transfer is still running when this function returns. + * + * dmaengine_synchronize() needs to be called before it is safe to free + * any memory that is accessed by previously submitted descriptors or before + * freeing any resources accessed from within the completion callback of any + * perviously submitted descriptors. + * + * This function can be called from atomic context as well as from within a + * complete callback of a descriptor submitted on the same channel. + * + * If none of the two conditions above apply consider using + * dmaengine_terminate_sync() instead. + */ +static inline int dmaengine_terminate_async(struct dma_chan *chan) +{ + if (chan->device->device_terminate_all) + return chan->device->device_terminate_all(chan); + + return -EINVAL; +} + +/** + * dmaengine_synchronize() - Synchronize DMA channel termination + * @chan: The channel to synchronize + * + * Synchronizes to the DMA channel termination to the current context. When this + * function returns it is guaranteed that all transfers for previously issued + * descriptors have stopped and and it is safe to free the memory assoicated + * with them. Furthermore it is guaranteed that all complete callback functions + * for a previously submitted descriptor have finished running and it is safe to + * free resources accessed from within the complete callbacks. + * + * The behavior of this function is undefined if dma_async_issue_pending() has + * been called between dmaengine_terminate_async() and this function. + * + * This function must only be called from non-atomic context and must not be + * called from within a complete callback of a descriptor submitted on the same + * channel. + */ +static inline void dmaengine_synchronize(struct dma_chan *chan) +{ + if (chan->device->device_synchronize) + chan->device->device_synchronize(chan); +} + +/** + * dmaengine_terminate_sync() - Terminate all active DMA transfers + * @chan: The channel for which to terminate the transfers + * + * Calling this function will terminate all active and pending transfers + * that have previously been submitted to the channel. It is similar to + * dmaengine_terminate_async() but guarantees that the DMA transfer has actually + * stopped and that all complete callbacks have finished running when the + * function returns. + * + * This function must only be called from non-atomic context and must not be + * called from within a complete callback of a descriptor submitted on the same + * channel. + */ +static inline int dmaengine_terminate_sync(struct dma_chan *chan) +{ + int ret; + + ret = dmaengine_terminate_async(chan); + if (ret) + return ret; + + dmaengine_synchronize(chan); + + return 0; +} + static inline int dmaengine_pause(struct dma_chan *chan) { if (chan->device->device_pause) -- cgit v1.2.3 From 9eeacd3a2f17438d9d286ff2f78c4709a4148be7 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Tue, 13 Oct 2015 21:54:29 +0200 Subject: dmaengine: enable DMA_CTRL_REUSE In the current state, the capability of transfer reuse can neither be set by a slave dmaengine driver, nor used by a client driver, because the capability is not available to dma_get_slave_caps(). Fix this by adding a way to declare the capability. Fixes: 272420214d26 ("dmaengine: Add DMA_CTRL_REUSE") Signed-off-by: Robert Jarzmik Signed-off-by: Vinod Koul --- include/linux/dmaengine.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index c47c68e535e8..6f94b5cbd97c 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -659,6 +659,7 @@ enum dmaengine_alignment { * struct with auxiliary transfer status information, otherwise the call * will just return a simple status code * @device_issue_pending: push pending transactions to hardware + * @descriptor_reuse: a submitted transfer can be resubmitted after completion */ struct dma_device { @@ -681,6 +682,7 @@ struct dma_device { u32 src_addr_widths; u32 dst_addr_widths; u32 directions; + bool descriptor_reuse; enum dma_residue_granularity residue_granularity; int (*device_alloc_chan_resources)(struct dma_chan *chan); -- cgit v1.2.3 From 2bb129ebb23d2dfec3cd9c22dc7defd681cfcd58 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 13 Nov 2015 12:46:00 +0100 Subject: dmaengine: ioatdma: constify dca_ops structures The dca_ops structure is never modified, so declare it as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Acked-by: Dan Williams Signed-off-by: Vinod Koul --- include/linux/dca.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/dca.h b/include/linux/dca.h index d27a7a05718d..ad956c2e07a8 100644 --- a/include/linux/dca.h +++ b/include/linux/dca.h @@ -34,7 +34,7 @@ void dca_unregister_notify(struct notifier_block *nb); struct dca_provider { struct list_head node; - struct dca_ops *ops; + const struct dca_ops *ops; struct device *cd; int id; }; @@ -53,7 +53,8 @@ struct dca_ops { int (*dev_managed) (struct dca_provider *, struct device *); }; -struct dca_provider *alloc_dca_provider(struct dca_ops *ops, int priv_size); +struct dca_provider *alloc_dca_provider(const struct dca_ops *ops, + int priv_size); void free_dca_provider(struct dca_provider *dca); int register_dca_provider(struct dca_provider *dca, struct device *dev); void unregister_dca_provider(struct dca_provider *dca, struct device *dev); -- cgit v1.2.3 From 3bd4dce1366fefe6575b841816e595f54e8e9752 Mon Sep 17 00:00:00 2001 From: Mitko Haralanov Date: Fri, 30 Oct 2015 18:58:41 -0400 Subject: staging/rdma/hfi1: Clean up macro indentation In preparation for implementing Expected TID caching we do some simple clean up of header file macros. Signed-off-by: Mitko Haralanov Signed-off-by: Ira Weiny Signed-off-by: Greg Kroah-Hartman --- include/uapi/rdma/hfi/hfi1_user.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/include/uapi/rdma/hfi/hfi1_user.h b/include/uapi/rdma/hfi/hfi1_user.h index 599562fe5d57..a2fc6cbfe414 100644 --- a/include/uapi/rdma/hfi/hfi1_user.h +++ b/include/uapi/rdma/hfi/hfi1_user.h @@ -127,13 +127,13 @@ #define HFI1_CMD_TID_UPDATE 4 /* update expected TID entries */ #define HFI1_CMD_TID_FREE 5 /* free expected TID entries */ #define HFI1_CMD_CREDIT_UPD 6 /* force an update of PIO credit */ -#define HFI1_CMD_SDMA_STATUS_UPD 7 /* force update of SDMA status ring */ +#define HFI1_CMD_SDMA_STATUS_UPD 7 /* force update of SDMA status ring */ #define HFI1_CMD_RECV_CTRL 8 /* control receipt of packets */ #define HFI1_CMD_POLL_TYPE 9 /* set the kind of polling we want */ #define HFI1_CMD_ACK_EVENT 10 /* ack & clear user status bits */ -#define HFI1_CMD_SET_PKEY 11 /* set context's pkey */ -#define HFI1_CMD_CTXT_RESET 12 /* reset context's HW send context */ +#define HFI1_CMD_SET_PKEY 11 /* set context's pkey */ +#define HFI1_CMD_CTXT_RESET 12 /* reset context's HW send context */ /* separate EPROM commands from normal PSM commands */ #define HFI1_CMD_EP_INFO 64 /* read EPROM device ID */ #define HFI1_CMD_EP_ERASE_CHIP 65 /* erase whole EPROM */ @@ -144,18 +144,18 @@ #define HFI1_CMD_EP_WRITE_P0 70 /* write EPROM partition 0 */ #define HFI1_CMD_EP_WRITE_P1 71 /* write EPROM partition 1 */ -#define _HFI1_EVENT_FROZEN_BIT 0 -#define _HFI1_EVENT_LINKDOWN_BIT 1 -#define _HFI1_EVENT_LID_CHANGE_BIT 2 -#define _HFI1_EVENT_LMC_CHANGE_BIT 3 -#define _HFI1_EVENT_SL2VL_CHANGE_BIT 4 +#define _HFI1_EVENT_FROZEN_BIT 0 +#define _HFI1_EVENT_LINKDOWN_BIT 1 +#define _HFI1_EVENT_LID_CHANGE_BIT 2 +#define _HFI1_EVENT_LMC_CHANGE_BIT 3 +#define _HFI1_EVENT_SL2VL_CHANGE_BIT 4 #define _HFI1_MAX_EVENT_BIT _HFI1_EVENT_SL2VL_CHANGE_BIT -#define HFI1_EVENT_FROZEN (1UL << _HFI1_EVENT_FROZEN_BIT) -#define HFI1_EVENT_LINKDOWN_BIT (1UL << _HFI1_EVENT_LINKDOWN_BIT) -#define HFI1_EVENT_LID_CHANGE_BIT (1UL << _HFI1_EVENT_LID_CHANGE_BIT) -#define HFI1_EVENT_LMC_CHANGE_BIT (1UL << _HFI1_EVENT_LMC_CHANGE_BIT) -#define HFI1_EVENT_SL2VL_CHANGE_BIT (1UL << _HFI1_EVENT_SL2VL_CHANGE_BIT) +#define HFI1_EVENT_FROZEN (1UL << _HFI1_EVENT_FROZEN_BIT) +#define HFI1_EVENT_LINKDOWN (1UL << _HFI1_EVENT_LINKDOWN_BIT) +#define HFI1_EVENT_LID_CHANGE (1UL << _HFI1_EVENT_LID_CHANGE_BIT) +#define HFI1_EVENT_LMC_CHANGE (1UL << _HFI1_EVENT_LMC_CHANGE_BIT) +#define HFI1_EVENT_SL2VL_CHANGE (1UL << _HFI1_EVENT_SL2VL_CHANGE_BIT) /* * These are the status bits readable (in ASCII form, 64bit value) -- cgit v1.2.3 From 3ff3f518a135fa4592fe2817e9ac2cce1fa23dc2 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Mon, 9 Nov 2015 22:20:37 -0800 Subject: regulator: Make bulk API support optional supplies Make it possible to use the bulk API with optional supplies, by allowing the consumer to marking supplies as optional in the regulator_bulk_data. Signed-off-by: Bjorn Andersson Signed-off-by: Mark Brown --- include/linux/regulator/consumer.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 9e0e76992be0..48603506f8de 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -140,6 +140,8 @@ struct regulator; * * @supply: The name of the supply. Initialised by the user before * using the bulk regulator APIs. + * @optional: The supply should be considered optional. Initialised by the user + * before using the bulk regulator APIs. * @consumer: The regulator consumer for the supply. This will be managed * by the bulk API. * @@ -149,6 +151,7 @@ struct regulator; */ struct regulator_bulk_data { const char *supply; + bool optional; struct regulator *consumer; /* private: Internal use */ -- cgit v1.2.3 From a0067db36a2f9733a2e956a44ef8145e6a809bdb Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 18 Nov 2015 15:21:32 +0100 Subject: spi: s3c64xx: pass DMA arguments in platform data The s3c64xx platform data already contains a pointer to the DMA filter function, but not to the associated data. This simplifies the code and makes it more generic by passing the data along with the filter function like we do for other drivers. Signed-off-by: Arnd Bergmann Signed-off-by: Mark Brown --- include/linux/platform_data/spi-s3c64xx.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/platform_data/spi-s3c64xx.h b/include/linux/platform_data/spi-s3c64xx.h index d3889b98a1a1..fb5625bcca9a 100644 --- a/include/linux/platform_data/spi-s3c64xx.h +++ b/include/linux/platform_data/spi-s3c64xx.h @@ -40,6 +40,8 @@ struct s3c64xx_spi_info { int num_cs; int (*cfg_gpio)(void); dma_filter_fn filter; + void *dma_tx; + void *dma_rx; }; /** -- cgit v1.2.3 From 9eba47ddd8fee8a21f45e6e1d707103f040d90c7 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 16 Nov 2015 14:37:35 +0100 Subject: mtd: nand: add an mtd_to_nand() helper Some drivers are retrieving the nand_chip pointer using the container_of macro on a struct wrapping both the nand_chip and the mtd_info struct while the standard way of retrieving this pointer is through mtd->priv. Provide an helper to do that. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- include/linux/mtd/nand.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 5a9d1d4c2487..a4839b3f27da 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -719,6 +719,11 @@ struct nand_chip { void *priv; }; +static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd) +{ + return mtd->priv; +} + /* * NAND Flash Manufacturer ID Codes */ -- cgit v1.2.3 From c67cbb839da9cc2757eabfa128556db6a2baf160 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 10 Nov 2015 12:15:27 -0800 Subject: mtd: spi-nor: provide default erase_sector implementation Some spi-nor drivers perform sector erase by duplicating their write_reg() command. Let's not require that the driver fill this out, and provide a default instead. Tested on m25p80.c and Medatek's MT8173 SPI NOR flash driver. Signed-off-by: Brian Norris --- include/linux/mtd/spi-nor.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 955f268d159a..7bed97471e53 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -143,7 +143,8 @@ struct mtd_info; * @read: [DRIVER-SPECIFIC] read data from the SPI NOR * @write: [DRIVER-SPECIFIC] write data to the SPI NOR * @erase: [DRIVER-SPECIFIC] erase a sector of the SPI NOR - * at the offset @offs + * at the offset @offs; if not provided by the driver, + * spi-nor will send the erase opcode via write_reg() * @flash_lock: [FLASH-SPECIFIC] lock a region of the SPI NOR * @flash_unlock: [FLASH-SPECIFIC] unlock a region of the SPI NOR * @flash_is_locked: [FLASH-SPECIFIC] check if a region of the SPI NOR is -- cgit v1.2.3 From b9eab01125bf3cb6f5fbab1811402d16c9fcf4ec Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 11 Nov 2015 19:13:29 -0800 Subject: mtd: partitions: add module_mtd_part_parser() helper This can help eliminate some boilerplate by generating the module_init() and module_exit() functions, and by automatically assigning the module owner. Signed-off-by: Brian Norris --- include/linux/mtd/partitions.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index 8421520c10eb..d002d9b5d797 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -73,9 +73,21 @@ struct mtd_part_parser { struct mtd_part_parser_data *); }; -extern void register_mtd_parser(struct mtd_part_parser *parser); +extern int __register_mtd_parser(struct mtd_part_parser *parser, + struct module *owner); +#define register_mtd_parser(parser) __register_mtd_parser(parser, THIS_MODULE) + extern void deregister_mtd_parser(struct mtd_part_parser *parser); +/* + * module_mtd_part_parser() - Helper macro for MTD partition parsers that don't + * do anything special in module init/exit. Each driver may only use this macro + * once, and calling it replaces module_init() and module_exit(). + */ +#define module_mtd_part_parser(__mtd_part_parser) \ + module_driver(__mtd_part_parser, register_mtd_parser, \ + deregister_mtd_parser) + int mtd_is_partition(const struct mtd_info *mtd); int mtd_add_partition(struct mtd_info *master, const char *name, long long offset, long long length); -- cgit v1.2.3 From b466c1dd73d5303a313fb0c962e4eb5879bc1336 Mon Sep 17 00:00:00 2001 From: Simon Wood Date: Thu, 19 Nov 2015 16:42:14 -0700 Subject: HID: Add vendor specific usage pages for Logitech G920 The Logitech G920 uses a couple of vendor specific usage pages, which results in incorrect number of axis/buttons being detected. This patch adds these pages to the 'ignore' list. Reported-by: Elias Vanderstuyft Signed-off-by: Simon Wood Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- include/linux/hid.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/hid.h b/include/linux/hid.h index 251a1d382e23..a6d7a3fc2cb3 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -168,6 +168,8 @@ struct hid_item { #define HID_UP_MSVENDOR 0xff000000 #define HID_UP_CUSTOM 0x00ff0000 #define HID_UP_LOGIVENDOR 0xffbc0000 +#define HID_UP_LOGIVENDOR2 0xff090000 +#define HID_UP_LOGIVENDOR3 0xff430000 #define HID_UP_LNVENDOR 0xffa00000 #define HID_UP_SENSOR 0x00200000 -- cgit v1.2.3 From 403c5c0650816375527a6feecfb255d9b494dda3 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 8 Oct 2015 09:11:48 +0200 Subject: HSI: Remove struct hsi_client private fields from kernel-doc The kernel-doc how to says that structure fields that are inside a "private:" area shouldn't be listed in the generated documentation but the private fields for struct hsi_client private are listed. This also fixes the following make htmldocs warnings: .//include/linux/hsi/hsi.h:150: warning: Excess struct/union/enum/typedef member 'e_handler' description in 'hsi_client' .//include/linux/hsi/hsi.h:150: warning: Excess struct/union/enum/typedef member 'pclaimed' description in 'hsi_client' .//include/linux/hsi/hsi.h:150: warning: Excess struct/union/enum/typedef member 'nb' description in 'hsi_client' Signed-off-by: Javier Martinez Canillas Signed-off-by: Sebastian Reichel --- include/linux/hsi/hsi.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include') diff --git a/include/linux/hsi/hsi.h b/include/linux/hsi/hsi.h index 5dd60c2e120f..2790591c77cf 100644 --- a/include/linux/hsi/hsi.h +++ b/include/linux/hsi/hsi.h @@ -135,9 +135,6 @@ static inline int hsi_register_board_info(struct hsi_board_info const *info, * @device: Driver model representation of the device * @tx_cfg: HSI TX configuration * @rx_cfg: HSI RX configuration - * @e_handler: Callback for handling port events (RX Wake High/Low) - * @pclaimed: Keeps tracks if the clients claimed its associated HSI port - * @nb: Notifier block for port events */ struct hsi_client { struct device device; -- cgit v1.2.3 From 9e4808d2c6a6660d5d2cd572e689570df14a8472 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Fri, 20 Nov 2015 16:07:51 +0530 Subject: mfd: sec: Add support for S2MPS15 PMIC Add support for S2MPS15 PMIC which is similar to S2MPS11 PMIC. The S2MPS15 PMIC supports 27 LDO regulators, 10 buck regulators, RTC, three 32.768KHz clock outputs and battery charger. This patch adds initial support for LDO and buck regulators of S2MPS15 device. Signed-off-by: Thomas Abraham Signed-off-by: Alim Akhtar Reviewed-by: Krzysztof Kozlowski [Alim: Added s2mps15_devs like rtc and clk and related changes] Signed-off-by: Lee Jones --- include/linux/mfd/samsung/core.h | 1 + include/linux/mfd/samsung/s2mps15.h | 158 ++++++++++++++++++++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 include/linux/mfd/samsung/s2mps15.h (limited to 'include') diff --git a/include/linux/mfd/samsung/core.h b/include/linux/mfd/samsung/core.h index a06098639399..6bc4bcd488ac 100644 --- a/include/linux/mfd/samsung/core.h +++ b/include/linux/mfd/samsung/core.h @@ -44,6 +44,7 @@ enum sec_device_type { S2MPS11X, S2MPS13X, S2MPS14X, + S2MPS15X, S2MPU02, }; diff --git a/include/linux/mfd/samsung/s2mps15.h b/include/linux/mfd/samsung/s2mps15.h new file mode 100644 index 000000000000..36d35287c3c0 --- /dev/null +++ b/include/linux/mfd/samsung/s2mps15.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __LINUX_MFD_S2MPS15_H +#define __LINUX_MFD_S2MPS15_H + +/* S2MPS15 registers */ +enum s2mps15_reg { + S2MPS15_REG_ID, + S2MPS15_REG_INT1, + S2MPS15_REG_INT2, + S2MPS15_REG_INT3, + S2MPS15_REG_INT1M, + S2MPS15_REG_INT2M, + S2MPS15_REG_INT3M, + S2MPS15_REG_ST1, + S2MPS15_REG_ST2, + S2MPS15_REG_PWRONSRC, + S2MPS15_REG_OFFSRC, + S2MPS15_REG_BU_CHG, + S2MPS15_REG_RTC_BUF, + S2MPS15_REG_CTRL1, + S2MPS15_REG_CTRL2, + S2MPS15_REG_RSVD1, + S2MPS15_REG_RSVD2, + S2MPS15_REG_RSVD3, + S2MPS15_REG_RSVD4, + S2MPS15_REG_RSVD5, + S2MPS15_REG_RSVD6, + S2MPS15_REG_CTRL3, + S2MPS15_REG_RSVD7, + S2MPS15_REG_RSVD8, + S2MPS15_REG_RSVD9, + S2MPS15_REG_B1CTRL1, + S2MPS15_REG_B1CTRL2, + S2MPS15_REG_B2CTRL1, + S2MPS15_REG_B2CTRL2, + S2MPS15_REG_B3CTRL1, + S2MPS15_REG_B3CTRL2, + S2MPS15_REG_B4CTRL1, + S2MPS15_REG_B4CTRL2, + S2MPS15_REG_B5CTRL1, + S2MPS15_REG_B5CTRL2, + S2MPS15_REG_B6CTRL1, + S2MPS15_REG_B6CTRL2, + S2MPS15_REG_B7CTRL1, + S2MPS15_REG_B7CTRL2, + S2MPS15_REG_B8CTRL1, + S2MPS15_REG_B8CTRL2, + S2MPS15_REG_B9CTRL1, + S2MPS15_REG_B9CTRL2, + S2MPS15_REG_B10CTRL1, + S2MPS15_REG_B10CTRL2, + S2MPS15_REG_BBCTRL1, + S2MPS15_REG_BBCTRL2, + S2MPS15_REG_BRAMP, + S2MPS15_REG_LDODVS1, + S2MPS15_REG_LDODVS2, + S2MPS15_REG_LDODVS3, + S2MPS15_REG_LDODVS4, + S2MPS15_REG_L1CTRL, + S2MPS15_REG_L2CTRL, + S2MPS15_REG_L3CTRL, + S2MPS15_REG_L4CTRL, + S2MPS15_REG_L5CTRL, + S2MPS15_REG_L6CTRL, + S2MPS15_REG_L7CTRL, + S2MPS15_REG_L8CTRL, + S2MPS15_REG_L9CTRL, + S2MPS15_REG_L10CTRL, + S2MPS15_REG_L11CTRL, + S2MPS15_REG_L12CTRL, + S2MPS15_REG_L13CTRL, + S2MPS15_REG_L14CTRL, + S2MPS15_REG_L15CTRL, + S2MPS15_REG_L16CTRL, + S2MPS15_REG_L17CTRL, + S2MPS15_REG_L18CTRL, + S2MPS15_REG_L19CTRL, + S2MPS15_REG_L20CTRL, + S2MPS15_REG_L21CTRL, + S2MPS15_REG_L22CTRL, + S2MPS15_REG_L23CTRL, + S2MPS15_REG_L24CTRL, + S2MPS15_REG_L25CTRL, + S2MPS15_REG_L26CTRL, + S2MPS15_REG_L27CTRL, + S2MPS15_REG_LDODSCH1, + S2MPS15_REG_LDODSCH2, + S2MPS15_REG_LDODSCH3, + S2MPS15_REG_LDODSCH4, +}; + +/* S2MPS15 regulator ids */ +enum s2mps15_regulators { + S2MPS15_LDO1, + S2MPS15_LDO2, + S2MPS15_LDO3, + S2MPS15_LDO4, + S2MPS15_LDO5, + S2MPS15_LDO6, + S2MPS15_LDO7, + S2MPS15_LDO8, + S2MPS15_LDO9, + S2MPS15_LDO10, + S2MPS15_LDO11, + S2MPS15_LDO12, + S2MPS15_LDO13, + S2MPS15_LDO14, + S2MPS15_LDO15, + S2MPS15_LDO16, + S2MPS15_LDO17, + S2MPS15_LDO18, + S2MPS15_LDO19, + S2MPS15_LDO20, + S2MPS15_LDO21, + S2MPS15_LDO22, + S2MPS15_LDO23, + S2MPS15_LDO24, + S2MPS15_LDO25, + S2MPS15_LDO26, + S2MPS15_LDO27, + S2MPS15_BUCK1, + S2MPS15_BUCK2, + S2MPS15_BUCK3, + S2MPS15_BUCK4, + S2MPS15_BUCK5, + S2MPS15_BUCK6, + S2MPS15_BUCK7, + S2MPS15_BUCK8, + S2MPS15_BUCK9, + S2MPS15_BUCK10, + S2MPS15_BUCK11, + S2MPS15_REGULATOR_MAX, +}; + +#define S2MPS15_LDO_VSEL_MASK (0x3F) +#define S2MPS15_BUCK_VSEL_MASK (0xFF) + +#define S2MPS15_ENABLE_SHIFT (0x06) +#define S2MPS15_ENABLE_MASK (0x03 << S2MPS15_ENABLE_SHIFT) + +#define S2MPS15_LDO_N_VOLTAGES (S2MPS15_LDO_VSEL_MASK + 1) +#define S2MPS15_BUCK_N_VOLTAGES (S2MPS15_BUCK_VSEL_MASK + 1) + +#endif /* __LINUX_MFD_S2MPS15_H */ -- cgit v1.2.3 From a65e5efa7c5faa8c320fe56cc351d47fcd006749 Mon Sep 17 00:00:00 2001 From: Alim Akhtar Date: Fri, 20 Nov 2015 16:07:53 +0530 Subject: rtc: s5m.c: Add support for S2MPS15 RTC RTC found in s2mps15 is almost same as one found on s2mps13 with few differences in RTC_UPDATE register fields, like: 1> Bit[4] and Bit[1] are reversed - On s2mps13 WUDR -> bit[4], AUDR -> bit[1] - On s2mps15 WUDR -> bit[1], AUDR -> bit[4] 2> In case of s2mps13, for alarm register, need to set both WDUR and ADUR high, whereas for s2mps15 only set AUDR to high. 3> On s2mps15, WUDR, RUDR and AUDR functions should never be used at the same time. This patch add required changes to enable s2mps15 rtc timer. Signed-off-by: Alim Akhtar Reviewed-by: Krzysztof Kozlowski Acked-by: Alexandre Belloni Signed-off-by: Lee Jones --- include/linux/mfd/samsung/rtc.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/mfd/samsung/rtc.h b/include/linux/mfd/samsung/rtc.h index 29c30ac36020..a65e4655d470 100644 --- a/include/linux/mfd/samsung/rtc.h +++ b/include/linux/mfd/samsung/rtc.h @@ -107,6 +107,8 @@ enum s2mps_rtc_reg { #define S2MPS_RTC_WUDR_MASK (1 << S2MPS_RTC_WUDR_SHIFT) #define S2MPS13_RTC_AUDR_SHIFT 1 #define S2MPS13_RTC_AUDR_MASK (1 << S2MPS13_RTC_AUDR_SHIFT) +#define S2MPS15_RTC_WUDR_SHIFT 1 +#define S2MPS15_RTC_WUDR_MASK (1 << S2MPS15_RTC_WUDR_SHIFT) #define S2MPS_RTC_RUDR_SHIFT 0 #define S2MPS_RTC_RUDR_MASK (1 << S2MPS_RTC_RUDR_SHIFT) #define RTC_TCON_SHIFT 1 -- cgit v1.2.3 From 414ca017a54d26c3a58ed1504884e51448d22ae1 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Fri, 20 Nov 2015 10:48:02 -0500 Subject: nfsd4: fix gss-proxy 4.1 mounts for some AD principals The principal name on a gss cred is used to setup the NFSv4.0 callback, which has to have a client principal name to authenticate to. That code wants the name to be in the form servicetype@hostname. rpc.svcgssd passes down such names (and passes down no principal name at all in the case the principal isn't a service principal). gss-proxy always passes down the principal name, and passes it down in the form servicetype/hostname@REALM. So we've been munging the name gss-proxy passes down into the format the NFSv4.0 callback code expects, or throwing away the name if we can't. Since the introduction of the MACH_CRED enforcement in NFSv4.1, we've also been using the principal name to verify that certain operations are done as the same principal as was used on the original EXCHANGE_ID call. For that application, the original name passed down by gss-proxy is also useful. Lack of that name in some cases was causing some kerberized NFSv4.1 mount failures in an Active Directory environment. This fix only works in the gss-proxy case. The fix for legacy rpc.svcgssd would be more involved, and rpc.svcgssd already has other problems in the AD case. Reported-and-tested-by: James Ralston Acked-by: Simo Sorce Signed-off-by: J. Bruce Fields --- include/linux/sunrpc/svcauth.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/sunrpc/svcauth.h b/include/linux/sunrpc/svcauth.h index 8d71d6577459..c00f53a4ccdd 100644 --- a/include/linux/sunrpc/svcauth.h +++ b/include/linux/sunrpc/svcauth.h @@ -23,13 +23,19 @@ struct svc_cred { kgid_t cr_gid; struct group_info *cr_group_info; u32 cr_flavor; /* pseudoflavor */ - char *cr_principal; /* for gss */ + /* name of form servicetype/hostname@REALM, passed down by + * gss-proxy: */ + char *cr_raw_principal; + /* name of form servicetype@hostname, passed down by + * rpc.svcgssd, or computed from the above: */ + char *cr_principal; struct gss_api_mech *cr_gss_mech; }; static inline void init_svc_cred(struct svc_cred *cred) { cred->cr_group_info = NULL; + cred->cr_raw_principal = NULL; cred->cr_principal = NULL; cred->cr_gss_mech = NULL; } @@ -38,6 +44,7 @@ static inline void free_svc_cred(struct svc_cred *cred) { if (cred->cr_group_info) put_group_info(cred->cr_group_info); + kfree(cred->cr_raw_principal); kfree(cred->cr_principal); gss_mech_put(cred->cr_gss_mech); init_svc_cred(cred); -- cgit v1.2.3 From c0ea88b890d67cff2667188f14189d8346e89a0f Mon Sep 17 00:00:00 2001 From: Nikita Kiryanov Date: Wed, 25 Nov 2015 13:59:04 +0200 Subject: regulator: tps65218: add support for LS3 current regulator Add support for TPS65218 LS3 current regulator, which is capable of 4 current input limit modes: 100, 200, 500, and 1000 uA. Signed-off-by: Nikita Kiryanov Signed-off-by: Mark Brown --- include/linux/mfd/tps65218.h | 7 ++++++- include/linux/regulator/driver.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/mfd/tps65218.h b/include/linux/mfd/tps65218.h index 2f9b593246ee..d58f3b5f585a 100644 --- a/include/linux/mfd/tps65218.h +++ b/include/linux/mfd/tps65218.h @@ -200,6 +200,8 @@ enum tps65218_regulator_id { TPS65218_DCDC_4, TPS65218_DCDC_5, TPS65218_DCDC_6, + /* LS's */ + TPS65218_LS_3, /* LDOs */ TPS65218_LDO_1, }; @@ -210,8 +212,11 @@ enum tps65218_regulator_id { #define TPS65218_NUM_DCDC 6 /* Number of LDO voltage regulators available */ #define TPS65218_NUM_LDO 1 +/* Number of total LS current regulators available */ +#define TPS65218_NUM_LS 1 /* Number of total regulators available */ -#define TPS65218_NUM_REGULATOR (TPS65218_NUM_DCDC + TPS65218_NUM_LDO) +#define TPS65218_NUM_REGULATOR (TPS65218_NUM_DCDC + TPS65218_NUM_LDO \ + + TPS65218_NUM_LS) /* Define the TPS65218 IRQ numbers */ enum tps65218_irqs { diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 9c2903e58adb..16ac9e108806 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -302,6 +302,8 @@ struct regulator_desc { unsigned int vsel_reg; unsigned int vsel_mask; + unsigned int csel_reg; + unsigned int csel_mask; unsigned int apply_reg; unsigned int apply_bit; unsigned int enable_reg; -- cgit v1.2.3 From c15d75bec6d0a937f7a15b81052ed99d310e9767 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 18 Nov 2015 00:50:28 +0800 Subject: scsi: Centralise ssp frame information units The xfer_rdy, command, and task frame's iu structures are not available in , but only aic94xx driver folder. Add them to include/scsi/sas.h Signed-off-by: John Garry Reviewed-by: Arnd Bergmann Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- include/scsi/sas.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) (limited to 'include') diff --git a/include/scsi/sas.h b/include/scsi/sas.h index 0d2607d12387..42a84ef42683 100644 --- a/include/scsi/sas.h +++ b/include/scsi/sas.h @@ -344,6 +344,43 @@ struct ssp_response_iu { u8 sense_data[0]; } __attribute__ ((packed)); +struct ssp_command_iu { + u8 lun[8]; + u8 _r_a; + + union { + struct { + u8 attr:3; + u8 prio:4; + u8 efb:1; + }; + u8 efb_prio_attr; + }; + + u8 _r_b; + + u8 _r_c:2; + u8 add_cdb_len:6; + + u8 cdb[16]; + u8 add_cdb[0]; +} __attribute__ ((packed)); + +struct xfer_rdy_iu { + __be32 requested_offset; + __be32 write_data_len; + __be32 _r_a; +} __attribute__ ((packed)); + +struct ssp_tmf_iu { + u8 lun[8]; + u16 _r_a; + u8 tmf; + u8 _r_b; + __be16 tag; + u8 _r_c[14]; +} __attribute__ ((packed)); + /* ---------- SMP ---------- */ struct report_general_resp { @@ -538,6 +575,43 @@ struct ssp_response_iu { u8 sense_data[0]; } __attribute__ ((packed)); +struct ssp_command_iu { + u8 lun[8]; + u8 _r_a; + + union { + struct { + u8 efb:1; + u8 prio:4; + u8 attr:3; + }; + u8 efb_prio_attr; + }; + + u8 _r_b; + + u8 add_cdb_len:6; + u8 _r_c:2; + + u8 cdb[16]; + u8 add_cdb[0]; +} __attribute__ ((packed)); + +struct xfer_rdy_iu { + __be32 requested_offset; + __be32 write_data_len; + __be32 _r_a; +} __attribute__ ((packed)); + +struct ssp_tmf_iu { + u8 lun[8]; + u16 _r_a; + u8 tmf; + u8 _r_b; + __be16 tag; + u8 _r_c[14]; +} __attribute__ ((packed)); + /* ---------- SMP ---------- */ struct report_general_resp { -- cgit v1.2.3 From 09e2b0b14690fb13ccfc04af49f156df3e25b152 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 9 Nov 2015 13:24:28 +0100 Subject: scsi: rescan VPD attributes The VPD page information might change, so we need to be able to update it. This patch implements a VPD page rescan whenever the 'rescan' sysfs attribute is triggered. Signed-off-by: Hannes Reinecke Reviewed-by: Johannes Thumshirn Reviewed-by: Shane Seymour Signed-off-by: Martin K. Petersen --- include/scsi/scsi_device.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index fe89d7cd67b9..bde4077f2864 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -109,6 +109,7 @@ struct scsi_device { char type; char scsi_level; char inq_periph_qual; /* PQ from INQUIRY data */ + struct mutex inquiry_mutex; unsigned char inquiry_len; /* valid bytes in 'inquiry' */ unsigned char * inquiry; /* INQUIRY response data */ const char * vendor; /* [back_compat] point into 'inquiry' ... */ @@ -117,9 +118,9 @@ struct scsi_device { #define SCSI_VPD_PG_LEN 255 int vpd_pg83_len; - unsigned char *vpd_pg83; + unsigned char __rcu *vpd_pg83; int vpd_pg80_len; - unsigned char *vpd_pg80; + unsigned char __rcu *vpd_pg80; unsigned char current_tag; /* current tag */ struct scsi_target *sdev_target; /* used only for single_lun */ -- cgit v1.2.3 From 749de3dac5e4d65cbed3b58f89c56883e31d1a5a Mon Sep 17 00:00:00 2001 From: Nicola Corna Date: Thu, 29 Oct 2015 12:34:23 +0100 Subject: i2c: add i2c quirk flag for unsupported clock stretching Add I2C_AQ_NO_CLK_STRETCH quirk flag, to be used when clock stretching is not supported. Signed-off-by: Nicola Corna Signed-off-by: Wolfram Sang --- include/linux/i2c.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 768063baafbf..96970024883f 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -493,6 +493,8 @@ struct i2c_adapter_quirks { /* convenience macro for typical write-then read case */ #define I2C_AQ_COMB_WRITE_THEN_READ (I2C_AQ_COMB | I2C_AQ_COMB_WRITE_FIRST | \ I2C_AQ_COMB_READ_SECOND | I2C_AQ_COMB_SAME_ADDR) +/* clock stretching is not supported */ +#define I2C_AQ_NO_CLK_STRETCH BIT(4) /* * i2c_adapter is the structure used to identify a physical i2c bus along -- cgit v1.2.3 From cfa576db834cacc1bb01bc41b2f61a8b578e67c5 Mon Sep 17 00:00:00 2001 From: Nicola Corna Date: Thu, 29 Oct 2015 12:34:26 +0100 Subject: i2c: add i2c_check_quirks helper function This patch adds a i2c_check_quirks helper function to check the quirk flags of an i2c adapter, in a similar way to i2c_check_functionality. Signed-off-by: Nicola Corna Signed-off-by: Wolfram Sang --- include/linux/i2c.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include') diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 96970024883f..51028f351d13 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -617,6 +617,20 @@ static inline int i2c_check_functionality(struct i2c_adapter *adap, u32 func) return (func & i2c_get_functionality(adap)) == func; } +/** + * i2c_check_quirks() - Function for checking the quirk flags in an i2c adapter + * @adap: i2c adapter + * @quirks: quirk flags + * + * Return: true if the adapter has all the specified quirk flags, false if not + */ +static inline bool i2c_check_quirks(struct i2c_adapter *adap, u64 quirks) +{ + if (!adap->quirks) + return false; + return (adap->quirks->flags & quirks) == quirks; +} + /* Return the adapter number for a specific adapter */ static inline int i2c_adapter_id(struct i2c_adapter *adap) { -- cgit v1.2.3 From 2c81de771f38e54324ede3f24118f4852570b384 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 26 Nov 2015 09:05:04 +0100 Subject: mtd: spi-nor: include mtd.h header for struct mtd_info definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So far struct spi_nor was using just a pointer to struct mtd_info so it wasn't needed to have it fully defined there. After recent change we embed whole struct so we need to include a proper header. Fixes: 1976367173a4 ("mtd: spi-nor: embed struct mtd_info within struct spi_nor") Signed-off-by: Rafał Miłecki Signed-off-by: Brian Norris --- include/linux/mtd/spi-nor.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 7bed97471e53..fac3f6f53981 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -12,6 +12,7 @@ #include #include +#include /* * Manufacturer IDs @@ -117,8 +118,6 @@ enum spi_nor_option_flags { SNOR_F_USE_FSR = BIT(0), }; -struct mtd_info; - /** * struct spi_nor - Structure for defining a the SPI NOR layer * @mtd: point to a mtd_info structure -- cgit v1.2.3 From fe7579d6122f2869d00b55842bca9e2a9be51607 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 24 Nov 2015 23:09:02 +0100 Subject: mtd: cfi: don't warn about broken geometry for !CONFIG_MTD The linux/mtd/map.h header file is included by a couple of platform specific files that are built even when CONFIG_MTD is disabled, and we always get warning "No CONFIG_MTD_MAP_BANK_WIDTH_xx selected. No NOR chip support can work" in that case. This adds an #ifdef around the pointless warning, as everything is really fine when we don't build the drivers anyway. Signed-off-by: Arnd Bergmann Signed-off-by: Brian Norris --- include/linux/mtd/map.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h index 366cf77953b5..58f3ba709ade 100644 --- a/include/linux/mtd/map.h +++ b/include/linux/mtd/map.h @@ -142,7 +142,9 @@ #endif #ifndef map_bankwidth +#ifdef CONFIG_MTD #warning "No CONFIG_MTD_MAP_BANK_WIDTH_xx selected. No NOR chip support can work" +#endif static inline int map_bankwidth(void *map) { BUG(); -- cgit v1.2.3 From 3b1884c24c98dada51fc4b05735773f0078711d2 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 30 Nov 2015 15:28:06 +0100 Subject: spi: Uninline spi_unregister_device() Uninline spi_unregister_device() in preparation of adding more code to it. Add kerneldoc documentation while we're at it. Signed-off-by: Geert Uytterhoeven Signed-off-by: Mark Brown --- include/linux/spi/spi.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'include') diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index cce80e6dc7d1..075bede66521 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -1115,12 +1115,7 @@ spi_add_device(struct spi_device *spi); extern struct spi_device * spi_new_device(struct spi_master *, struct spi_board_info *); -static inline void -spi_unregister_device(struct spi_device *spi) -{ - if (spi) - device_unregister(&spi->dev); -} +extern void spi_unregister_device(struct spi_device *spi); extern const struct spi_device_id * spi_get_device_id(const struct spi_device *sdev); -- cgit v1.2.3 From de64aa9ec129ba627634088f662a4d09e356ddb6 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 23 Nov 2015 11:23:07 +0100 Subject: mtd: nand: fix ONFI parameter page layout src_ssync_features field is only 1 byte large, and the 4th reserved area is actually 8 bytes large. Fixes: d1e1f4e42b5 ("mtd: nand: add support for reading ONFI parameters from NAND device") Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- include/linux/mtd/nand.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 056d1650eb89..eaf48b5a95dd 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -276,7 +276,7 @@ struct nand_onfi_params { __le16 t_r; __le16 t_ccs; __le16 src_sync_timing_mode; - __le16 src_ssync_features; + u8 src_ssync_features; __le16 clk_pin_capacitance_typ; __le16 io_pin_capacitance_typ; __le16 input_pin_capacitance_typ; @@ -284,7 +284,7 @@ struct nand_onfi_params { u8 driver_strength_support; __le16 t_int_r; __le16 t_ald; - u8 reserved4[7]; + u8 reserved4[8]; /* vendor */ __le16 vendor_revision; -- cgit v1.2.3 From 74e98be45fe069fcdb00f35eccbb179309ab65cd Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 1 Dec 2015 11:08:32 -0800 Subject: mtd: nand: fix typo (t_ald -> t_adl) It's "ADL" ("ALE to data loading" time) not "ALD". Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- include/linux/mtd/nand.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index eaf48b5a95dd..fad634ea1685 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -283,7 +283,7 @@ struct nand_onfi_params { u8 input_pin_capacitance_max; u8 driver_strength_support; __le16 t_int_r; - __le16 t_ald; + __le16 t_adl; u8 reserved4[8]; /* vendor */ @@ -407,7 +407,7 @@ struct nand_jedec_params { __le16 input_pin_capacitance_typ; __le16 clk_pin_capacitance_typ; u8 driver_strength_support; - __le16 t_ald; + __le16 t_adl; u8 reserved4[36]; /* ECC and endurance block */ -- cgit v1.2.3 From 6fb8ac81cb3125aafc7136f2ef0145da792bab94 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 28 Nov 2015 16:07:10 +0100 Subject: USB: constify usb_mon_operations structure The usb_mon_operations structure is never modified, so declare it as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Greg Kroah-Hartman --- include/linux/usb/hcd.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index f89c24bd53a4..4dcf8446dbcd 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -660,7 +660,7 @@ struct usb_mon_operations { /* void (*urb_unlink)(struct usb_bus *bus, struct urb *urb); */ }; -extern struct usb_mon_operations *mon_ops; +extern const struct usb_mon_operations *mon_ops; static inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb) { @@ -682,7 +682,7 @@ static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb, (*mon_ops->urb_complete)(bus, urb, status); } -int usb_mon_register(struct usb_mon_operations *ops); +int usb_mon_register(const struct usb_mon_operations *ops); void usb_mon_deregister(void); #else -- cgit v1.2.3 From bf5ce5bf3cc7136fd7fe5e8999a580bc93a9c8f6 Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Sat, 14 Nov 2015 16:26:32 +0800 Subject: usb: core: lpm: fix usb3_hardware_lpm sysfs node Commit 655fe4effe0f ("usbcore: add sysfs support to xHCI usb3 hardware LPM") introduced usb3_hardware_lpm sysfs node. This doesn't show the correct status of USB3 U1 and U2 LPM status. This patch fixes this by replacing usb3_hardware_lpm with two nodes, usb3_hardware_lpm_u1 (for U1) and usb3_hardware_lpm_u2 (for U2), and recording the U1/U2 LPM status in right places. This patch should be back-ported to kernels as old as 4.3, that contains Commit 655fe4effe0f ("usbcore: add sysfs support to xHCI usb3 hardware LPM"). Cc: stable@vger.kernel.org Signed-off-by: Lu Baolu Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/usb.h b/include/linux/usb.h index b9a28074210f..b79925dd2b41 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -511,6 +511,8 @@ struct usb3_lpm_parameters { * @usb2_hw_lpm_enabled: USB2 hardware LPM is enabled * @usb2_hw_lpm_allowed: Userspace allows USB 2.0 LPM to be enabled * @usb3_lpm_enabled: USB3 hardware LPM enabled + * @usb3_lpm_u1_enabled: USB3 hardware U1 LPM enabled + * @usb3_lpm_u2_enabled: USB3 hardware U2 LPM enabled * @string_langid: language ID for strings * @product: iProduct string, if present (static) * @manufacturer: iManufacturer string, if present (static) @@ -584,6 +586,8 @@ struct usb_device { unsigned usb2_hw_lpm_enabled:1; unsigned usb2_hw_lpm_allowed:1; unsigned usb3_lpm_enabled:1; + unsigned usb3_lpm_u1_enabled:1; + unsigned usb3_lpm_u2_enabled:1; int string_langid; /* static strings from the device */ -- cgit v1.2.3 From 498378d9d2c12d97318028f1a648d98ee7568430 Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Sat, 14 Nov 2015 16:26:34 +0800 Subject: usb: core: lpm: remove usb3_lpm_enabled in usb_device Commit 8306095fd2c1 ("USB: Disable USB 3.0 LPM in critical sections.") adds usb3_lpm_enabled member to struct usb_device. There is no reference to this member now. Hence, it could be removed. Signed-off-by: Lu Baolu Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include') diff --git a/include/linux/usb.h b/include/linux/usb.h index b79925dd2b41..89533ba38691 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -510,7 +510,6 @@ struct usb3_lpm_parameters { * @usb2_hw_lpm_besl_capable: device can perform USB2 hardware BESL LPM * @usb2_hw_lpm_enabled: USB2 hardware LPM is enabled * @usb2_hw_lpm_allowed: Userspace allows USB 2.0 LPM to be enabled - * @usb3_lpm_enabled: USB3 hardware LPM enabled * @usb3_lpm_u1_enabled: USB3 hardware U1 LPM enabled * @usb3_lpm_u2_enabled: USB3 hardware U2 LPM enabled * @string_langid: language ID for strings @@ -585,7 +584,6 @@ struct usb_device { unsigned usb2_hw_lpm_besl_capable:1; unsigned usb2_hw_lpm_enabled:1; unsigned usb2_hw_lpm_allowed:1; - unsigned usb3_lpm_enabled:1; unsigned usb3_lpm_u1_enabled:1; unsigned usb3_lpm_u2_enabled:1; int string_langid; -- cgit v1.2.3 From 095077ad37043574ce7a3978e92c89f535a6612c Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:50 +0100 Subject: scsi: remove scsi_show_sense_hdr() Last caller is gone, so remove it. Signed-off-by: Hannes Reinecke Reviewed-by: Bart Van Assche Reviewed-by: Christoph Hellwig Reviewed-by: Martin K. Petersen Reviewed-by: Johannes Thumshirn Signed-off-by: Martin K. Petersen --- include/scsi/scsi_dbg.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include') diff --git a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h index f8170e90b49d..56710e03101c 100644 --- a/include/scsi/scsi_dbg.h +++ b/include/scsi/scsi_dbg.h @@ -12,8 +12,6 @@ extern size_t __scsi_format_command(char *, size_t, const unsigned char *, size_t); extern void scsi_show_extd_sense(const struct scsi_device *, const char *, unsigned char, unsigned char); -extern void scsi_show_sense_hdr(const struct scsi_device *, const char *, - const struct scsi_sense_hdr *); extern void scsi_print_sense_hdr(const struct scsi_device *, const char *, const struct scsi_sense_hdr *); extern void scsi_print_sense(const struct scsi_cmnd *); -- cgit v1.2.3 From 9983bed3907c379d1d30b7509bb0a871ed655f9d Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:55 +0100 Subject: scsi: Add scsi_vpd_lun_id() Add a function scsi_vpd_lun_id() to return a unique device identifcation based on the designation descriptors of VPD page 0x83. As devices might implement several descriptors the order of preference is: - NAA IEE Registered Extended - EUI-64 based 16-byte - EUI-64 based 12-byte - NAA IEEE Registered - NAA IEEE Extended A SCSI name string descriptor is preferred to all of them if the identification is longer than 16 bytes. The returned unique device identification will be formatted as a SCSI Name string to avoid clashes between different designator types. [mkp: Fixed up kernel doc comment from Johannes] Signed-off-by: Hannes Reinecke Reviewed-by: Ewan Milne Reviewed-by: Johannes Thumshirn Reviewed-by: Christoph Hellwig Signed-off-by: Martin K. Petersen --- include/scsi/scsi_device.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index bde4077f2864..4c49cfa25cac 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -415,6 +415,7 @@ static inline int scsi_execute_req(struct scsi_device *sdev, } extern void sdev_disable_disk_events(struct scsi_device *sdev); extern void sdev_enable_disk_events(struct scsi_device *sdev); +extern int scsi_vpd_lun_id(struct scsi_device *, char *, size_t); #ifdef CONFIG_PM extern int scsi_autopm_get_device(struct scsi_device *); -- cgit v1.2.3 From a8aa3978588a4fa2d9edabc151adedd97bbed091 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 1 Dec 2015 10:16:57 +0100 Subject: scsi: Add scsi_vpd_tpg_id() Implement scsi_vpd_tpg_id() to extract the target port group id and the relative port id from SCSI VPD page 0x83. Reviewed-by: Johannes Thumshirn Reviewed-by: Christoph Hellwig Signed-off-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- include/scsi/scsi_device.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 4c49cfa25cac..f63a16760ae9 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -416,6 +416,7 @@ static inline int scsi_execute_req(struct scsi_device *sdev, extern void sdev_disable_disk_events(struct scsi_device *sdev); extern void sdev_enable_disk_events(struct scsi_device *sdev); extern int scsi_vpd_lun_id(struct scsi_device *, char *, size_t); +extern int scsi_vpd_tpg_id(struct scsi_device *, int *); #ifdef CONFIG_PM extern int scsi_autopm_get_device(struct scsi_device *); -- cgit v1.2.3 From b662f809d41009749a9ee6f9a4db3d9af579e171 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Mon, 9 Nov 2015 09:14:00 +0200 Subject: iio: core: Introduce IIO software triggers A software trigger associates an IIO device trigger with a software interrupt source (e.g: timer, sysfs). This patch adds the generic infrastructure for handling software triggers. Software interrupts sources are kept in a iio_trigger_types_list and registered separately when the associated kernel module is loaded. Software triggers can be created directly from drivers or from user space via configfs interface. To sum up, this dynamically creates "triggers" group to be found under /config/iio/triggers and offers the possibility of dynamically creating trigger types groups. The first supported trigger type is "hrtimer" found under /config/iio/triggers/hrtimer. Signed-off-by: Daniel Baluta Signed-off-by: Jonathan Cameron --- include/linux/iio/sw_trigger.h | 71 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 include/linux/iio/sw_trigger.h (limited to 'include') diff --git a/include/linux/iio/sw_trigger.h b/include/linux/iio/sw_trigger.h new file mode 100644 index 000000000000..c2f33b2b35a5 --- /dev/null +++ b/include/linux/iio/sw_trigger.h @@ -0,0 +1,71 @@ +/* + * Industrial I/O software trigger interface + * + * Copyright (c) 2015 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#ifndef __IIO_SW_TRIGGER +#define __IIO_SW_TRIGGER + +#include +#include +#include +#include + +#define module_iio_sw_trigger_driver(__iio_sw_trigger_type) \ + module_driver(__iio_sw_trigger_type, iio_register_sw_trigger_type, \ + iio_unregister_sw_trigger_type) + +extern struct configfs_subsystem iio_configfs_subsys; +struct iio_sw_trigger_ops; + +struct iio_sw_trigger_type { + const char *name; + struct module *owner; + const struct iio_sw_trigger_ops *ops; + struct list_head list; + struct config_group *group; +}; + +struct iio_sw_trigger { + struct iio_trigger *trigger; + struct iio_sw_trigger_type *trigger_type; + struct config_group group; +}; + +struct iio_sw_trigger_ops { + struct iio_sw_trigger* (*probe)(const char *); + int (*remove)(struct iio_sw_trigger *); +}; + +static inline +struct iio_sw_trigger *to_iio_sw_trigger(struct config_item *item) +{ + return container_of(to_config_group(item), struct iio_sw_trigger, + group); +} + +int iio_register_sw_trigger_type(struct iio_sw_trigger_type *tt); +void iio_unregister_sw_trigger_type(struct iio_sw_trigger_type *tt); + +struct iio_sw_trigger *iio_sw_trigger_create(const char *, const char *); +void iio_sw_trigger_destroy(struct iio_sw_trigger *); + +int iio_sw_trigger_type_configfs_register(struct iio_sw_trigger_type *tt); +void iio_sw_trigger_type_configfs_unregister(struct iio_sw_trigger_type *tt); + +static inline +void iio_swt_group_init_type_name(struct iio_sw_trigger *t, + const char *name, + struct config_item_type *type) +{ +#ifdef CONFIG_CONFIGFS_FS + config_group_init_type_name(&t->group, name, type); +#endif +} + +#endif /* __IIO_SW_TRIGGER */ -- cgit v1.2.3 From b2b018ef48675a9a524fa9791ea7d67fdac405f7 Mon Sep 17 00:00:00 2001 From: Chris J Arges Date: Tue, 1 Dec 2015 20:40:54 -0600 Subject: livepatch: add old_sympos as disambiguator field to klp_func Currently, patching objects with duplicate symbol names fail because the creation of the sysfs function directory collides with the previous attempt. Appending old_addr to the function name is problematic as it reveals the address of the function being patch to a normal user. Using the symbol's occurrence in kallsyms to postfix the function name in the sysfs directory solves the issue of having consistent unique names and ensuring that the address is not exposed to a normal user. In addition, using the symbol position as the user's method to disambiguate symbols instead of addr allows for disambiguating symbols in modules as well for both function addresses and for relocs. This also simplifies much of the code. Special handling for kASLR is no longer needed and can be removed. The klp_find_verify_func_addr function can be replaced by klp_find_object_symbol, and klp_verify_vmlinux_symbol and its callback can be removed completely. In cases of duplicate symbols, old_sympos will be used to disambiguate instead of old_addr. By default old_sympos will be 0, and patching will only succeed if the symbol is unique. Specifying a positive value will ensure that occurrence of the symbol in kallsyms for the patched object will be used for patching if it is valid. In addition, make old_addr an internal structure field not to be specified by the user. Finally, remove klp_find_verify_func_addr as it can be replaced by klp_find_object_symbol directly. Support for symbol position disambiguation for relocations is added in the next patch in this series. Signed-off-by: Chris J Arges Reviewed-by: Petr Mladek Acked-by: Josh Poimboeuf Signed-off-by: Jiri Kosina --- include/linux/livepatch.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h index 31db7a05dd36..b60e8abab0ab 100644 --- a/include/linux/livepatch.h +++ b/include/linux/livepatch.h @@ -37,8 +37,9 @@ enum klp_state { * struct klp_func - function structure for live patching * @old_name: name of the function to be patched * @new_func: pointer to the patched function code - * @old_addr: a hint conveying at what address the old function - * can be found (optional, vmlinux patches only) + * @old_sympos: a hint indicating which symbol position the old function + * can be found (optional) + * @old_addr: the address of the function being patched * @kobj: kobject for sysfs resources * @state: tracks function-level patch application state * @stack_node: list node for klp_ops func_stack list @@ -48,16 +49,16 @@ struct klp_func { const char *old_name; void *new_func; /* - * The old_addr field is optional and can be used to resolve - * duplicate symbol names in the vmlinux object. If this - * information is not present, the symbol is located by name - * with kallsyms. If the name is not unique and old_addr is - * not provided, the patch application fails as there is no - * way to resolve the ambiguity. + * The old_sympos field is optional and can be used to resolve + * duplicate symbol names in livepatch objects. If this field is zero, + * it is expected the symbol is unique, otherwise patching fails. If + * this value is greater than zero then that occurrence of the symbol + * in kallsyms for the given object is used. */ - unsigned long old_addr; + unsigned long old_sympos; /* internal */ + unsigned long old_addr; struct kobject kobj; enum klp_state state; struct list_head stack_node; -- cgit v1.2.3 From 064c89df6247cd829a7880cc8a87b7ed2cdfccd8 Mon Sep 17 00:00:00 2001 From: Chris J Arges Date: Tue, 1 Dec 2015 20:40:55 -0600 Subject: livepatch: add sympos as disambiguator field to klp_reloc In cases of duplicate symbols, sympos will be used to disambiguate instead of val. By default sympos will be 0, and patching will only succeed if the symbol is unique. Specifying a positive value will ensure that occurrence of the symbol in kallsyms for the patched object will be used for patching if it is valid. For external relocations sympos is not supported. Remove klp_verify_callback, klp_verify_args and klp_verify_vmlinux_symbol as they are no longer used. From the klp_reloc structure remove val, as it can be refactored as a local variable in klp_write_object_relocations. Signed-off-by: Chris J Arges Reviewed-by: Petr Mladek Acked-by: Josh Poimboeuf Signed-off-by: Jiri Kosina --- include/linux/livepatch.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/livepatch.h b/include/linux/livepatch.h index b60e8abab0ab..a8828652f794 100644 --- a/include/linux/livepatch.h +++ b/include/linux/livepatch.h @@ -67,8 +67,7 @@ struct klp_func { /** * struct klp_reloc - relocation structure for live patching * @loc: address where the relocation will be written - * @val: address of the referenced symbol (optional, - * vmlinux patches only) + * @sympos: position in kallsyms to disambiguate symbols (optional) * @type: ELF relocation type * @name: name of the referenced symbol (for lookup/verification) * @addend: offset from the referenced symbol @@ -76,7 +75,7 @@ struct klp_func { */ struct klp_reloc { unsigned long loc; - unsigned long val; + unsigned long sympos; unsigned long type; const char *name; int addend; -- cgit v1.2.3 From ea1f3339909d8973b41f09ef7275d7e49974b910 Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Tue, 3 Nov 2015 15:08:32 +0000 Subject: mfd: arizona: Support Cirrus Logic CS47L24 and WM1831 This patch adds the regmap configuration tables and core MFD handling for the CS47L24 and WM1831 codecs. Note that compared to the other Arizona codecs, these devices do not have an LDO1 or micsupp regulators, extcon driver, or the DCVDD isolation control. Signed-off-by: Richard Fitzgerald Signed-off-by: Lee Jones --- include/linux/mfd/arizona/core.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/mfd/arizona/core.h b/include/linux/mfd/arizona/core.h index 79e607e2f081..d55a42297d49 100644 --- a/include/linux/mfd/arizona/core.h +++ b/include/linux/mfd/arizona/core.h @@ -27,6 +27,8 @@ enum arizona_type { WM8280 = 4, WM8998 = 5, WM1814 = 6, + WM1831 = 7, + CS47L24 = 8, }; #define ARIZONA_IRQ_GP1 0 @@ -166,6 +168,7 @@ static inline int wm5102_patch(struct arizona *arizona) #endif int wm5110_patch(struct arizona *arizona); +int cs47l24_patch(struct arizona *arizona); int wm8997_patch(struct arizona *arizona); int wm8998_patch(struct arizona *arizona); -- cgit v1.2.3 From 7523e4dc5057e157212b4741abd6256e03404cf1 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 26 Nov 2015 09:44:08 +1030 Subject: module: use a structure to encapsulate layout. Makes it easier to handle init vs core cleanly, though the change is fairly invasive across random architectures. It simplifies the rbtree code immediately, however, while keeping the core data together in the same cachline (now iff the rbtree code is enabled). Acked-by: Peter Zijlstra Reviewed-by: Josh Poimboeuf Signed-off-by: Rusty Russell Signed-off-by: Jiri Kosina --- include/linux/module.h | 64 +++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 35 deletions(-) (limited to 'include') diff --git a/include/linux/module.h b/include/linux/module.h index 3a19c79918e0..6e68e8cf4d0d 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -302,6 +302,28 @@ struct mod_tree_node { struct latch_tree_node node; }; +struct module_layout { + /* The actual code + data. */ + void *base; + /* Total size. */ + unsigned int size; + /* The size of the executable code. */ + unsigned int text_size; + /* Size of RO section of the module (text+rodata) */ + unsigned int ro_size; + +#ifdef CONFIG_MODULES_TREE_LOOKUP + struct mod_tree_node mtn; +#endif +}; + +#ifdef CONFIG_MODULES_TREE_LOOKUP +/* Only touch one cacheline for common rbtree-for-core-layout case. */ +#define __module_layout_align ____cacheline_aligned +#else +#define __module_layout_align +#endif + struct module { enum module_state state; @@ -366,37 +388,9 @@ struct module { /* Startup function. */ int (*init)(void); - /* - * If this is non-NULL, vfree() after init() returns. - * - * Cacheline align here, such that: - * module_init, module_core, init_size, core_size, - * init_text_size, core_text_size and mtn_core::{mod,node[0]} - * are on the same cacheline. - */ - void *module_init ____cacheline_aligned; - - /* Here is the actual code + data, vfree'd on unload. */ - void *module_core; - - /* Here are the sizes of the init and core sections */ - unsigned int init_size, core_size; - - /* The size of the executable code in each section. */ - unsigned int init_text_size, core_text_size; - -#ifdef CONFIG_MODULES_TREE_LOOKUP - /* - * We want mtn_core::{mod,node[0]} to be in the same cacheline as the - * above entries such that a regular lookup will only touch one - * cacheline. - */ - struct mod_tree_node mtn_core; - struct mod_tree_node mtn_init; -#endif - - /* Size of RO sections of the module (text+rodata) */ - unsigned int init_ro_size, core_ro_size; + /* Core layout: rbtree is accessed frequently, so keep together. */ + struct module_layout core_layout __module_layout_align; + struct module_layout init_layout; /* Arch-specific module values */ struct mod_arch_specific arch; @@ -505,15 +499,15 @@ bool is_module_text_address(unsigned long addr); static inline bool within_module_core(unsigned long addr, const struct module *mod) { - return (unsigned long)mod->module_core <= addr && - addr < (unsigned long)mod->module_core + mod->core_size; + return (unsigned long)mod->core_layout.base <= addr && + addr < (unsigned long)mod->core_layout.base + mod->core_layout.size; } static inline bool within_module_init(unsigned long addr, const struct module *mod) { - return (unsigned long)mod->module_init <= addr && - addr < (unsigned long)mod->module_init + mod->init_size; + return (unsigned long)mod->init_layout.base <= addr && + addr < (unsigned long)mod->init_layout.base + mod->init_layout.size; } static inline bool within_module(unsigned long addr, const struct module *mod) -- cgit v1.2.3 From 85c898db6327353d38f3dd428457384cf81f83f8 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 26 Nov 2015 09:45:08 +1030 Subject: module: clean up RO/NX handling. Modules have three sections: text, rodata and writable data. The code handled the case where these overlapped, however they never can: debug_align() ensures they are always page-aligned. This is why we got away with manually traversing the pages in set_all_modules_text_rw() without rounding. We create three helper functions: frob_text(), frob_rodata() and frob_writable_data(). We then call these explicitly at every point, so it's clear what we're doing. We also expose module_enable_ro() and module_disable_ro() for livepatch to use. Reviewed-by: Josh Poimboeuf Signed-off-by: Rusty Russell Signed-off-by: Jiri Kosina --- include/linux/module.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/module.h b/include/linux/module.h index 6e68e8cf4d0d..4560d8f1545d 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -762,9 +762,13 @@ extern int module_sysfs_initialized; #ifdef CONFIG_DEBUG_SET_MODULE_RONX extern void set_all_modules_text_rw(void); extern void set_all_modules_text_ro(void); +extern void module_enable_ro(const struct module *mod); +extern void module_disable_ro(const struct module *mod); #else static inline void set_all_modules_text_rw(void) { } static inline void set_all_modules_text_ro(void) { } +static inline void module_enable_ro(const struct module *mod) { } +static inline void module_disable_ro(const struct module *mod) { } #endif #ifdef CONFIG_GENERIC_BUG -- cgit v1.2.3 From 703df6c097956d17a818e63961c82e8e9eef9fef Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Mon, 23 Nov 2015 10:53:51 -0600 Subject: power: bq27xxx_battery: Reorganize I2C into a module Separate out I2C functionality into a module. This fixes several small issues and simplifies the driver initialization. Signed-off-by: Andrew F. Davis Signed-off-by: Sebastian Reichel --- include/linux/power/bq27xxx_battery.h | 57 +++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/include/linux/power/bq27xxx_battery.h b/include/linux/power/bq27xxx_battery.h index 45f6a7b5b3cb..998d8f1c3c91 100644 --- a/include/linux/power/bq27xxx_battery.h +++ b/include/linux/power/bq27xxx_battery.h @@ -1,6 +1,16 @@ #ifndef __LINUX_BQ27X00_BATTERY_H__ #define __LINUX_BQ27X00_BATTERY_H__ +enum bq27xxx_chip { + BQ27000 = 1, /* bq27000, bq27200 */ + BQ27010, /* bq27010, bq27210 */ + BQ27500, /* bq27500, bq27510, bq27520 */ + BQ27530, /* bq27530, bq27531 */ + BQ27541, /* bq27541, bq27542, bq27546, bq27742 */ + BQ27545, /* bq27545 */ + BQ27421, /* bq27421, bq27425, bq27441, bq27621 */ +}; + /** * struct bq27xxx_plaform_data - Platform data for bq27xxx devices * @name: Name of the battery. @@ -12,20 +22,47 @@ * register to be read. The return value should either be the content of * the passed register or an error value. */ -enum bq27xxx_chip { - BQ27000 = 1, /* bq27000, bq27200 */ - BQ27010, /* bq27010, bq27210 */ - BQ27500, /* bq27500, bq27510, bq27520 */ - BQ27530, /* bq27530, bq27531 */ - BQ27541, /* bq27541, bq27542, bq27546, bq27742 */ - BQ27545, /* bq27545 */ - BQ27421, /* bq27421, bq27425, bq27441, bq27621 */ -}; - struct bq27xxx_platform_data { const char *name; enum bq27xxx_chip chip; int (*read)(struct device *dev, unsigned int); }; +struct bq27xxx_device_info; +struct bq27xxx_access_methods { + int (*read)(struct bq27xxx_device_info *di, u8 reg, bool single); +}; + +struct bq27xxx_reg_cache { + int temperature; + int time_to_empty; + int time_to_empty_avg; + int time_to_full; + int charge_full; + int cycle_count; + int capacity; + int energy; + int flags; + int power_avg; + int health; +}; + +struct bq27xxx_device_info { + struct device *dev; + enum bq27xxx_chip chip; + const char *name; + struct bq27xxx_access_methods bus; + struct bq27xxx_reg_cache cache; + int charge_design_full; + unsigned long last_update; + struct delayed_work work; + struct power_supply *bat; + struct mutex lock; + u8 *regs; +}; + +void bq27xxx_battery_update(struct bq27xxx_device_info *di); +int bq27xxx_battery_setup(struct bq27xxx_device_info *di); +void bq27xxx_battery_teardown(struct bq27xxx_device_info *di); + #endif -- cgit v1.2.3 From b1d6ab1aa8cdc23b89bcd578ea8d5e3c501a13d9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 23 Nov 2015 11:06:43 +0100 Subject: dmaengine: Add might_sleep() to dmaengine_synchronize() Implementations of dmaengine_synchronize() are allowed to sleep, hence the function must not be called to from atomic context. Add might_sleep() to dmaengine_synchronize() to make it easier to detect non-compliant callers. Suggested-by: Andy Shevchenko Signed-off-by: Lars-Peter Clausen Signed-off-by: Vinod Koul --- include/linux/dmaengine.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 4662d9aa6d5a..2f69e1d93f92 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -895,6 +895,8 @@ static inline int dmaengine_terminate_async(struct dma_chan *chan) */ static inline void dmaengine_synchronize(struct dma_chan *chan) { + might_sleep(); + if (chan->device->device_synchronize) chan->device->device_synchronize(chan); } -- cgit v1.2.3 From 8d6c16dd7213fa43702416e3dd1059e9e36bc758 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 5 Dec 2015 16:23:26 +0000 Subject: iio:configfs: Introduce iio/configfs.h to provide a location for the configfs_subsystem This exported element needs to be accesible to all drivers using configfs within IIO. Previously it was in the sw_trig.h file which only convered one such usecase. This also fixes a sparse warning as it is now in a header that makes sense to include from industrialio-configfs.c Signed-off-by: Jonathan Cameron < jic23@kernel.org> --- include/linux/iio/configfs.h | 15 +++++++++++++++ include/linux/iio/sw_trigger.h | 1 - 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 include/linux/iio/configfs.h (limited to 'include') diff --git a/include/linux/iio/configfs.h b/include/linux/iio/configfs.h new file mode 100644 index 000000000000..93befd67c15c --- /dev/null +++ b/include/linux/iio/configfs.h @@ -0,0 +1,15 @@ +/* + * Industrial I/O configfs support + * + * Copyright (c) 2015 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ +#ifndef __IIO_CONFIGFS +#define __IIO_CONFIGFS + +extern struct configfs_subsystem iio_configfs_subsys; + +#endif /* __IIO_CONFIGFS */ diff --git a/include/linux/iio/sw_trigger.h b/include/linux/iio/sw_trigger.h index c2f33b2b35a5..5198f8ed08a4 100644 --- a/include/linux/iio/sw_trigger.h +++ b/include/linux/iio/sw_trigger.h @@ -20,7 +20,6 @@ module_driver(__iio_sw_trigger_type, iio_register_sw_trigger_type, \ iio_unregister_sw_trigger_type) -extern struct configfs_subsystem iio_configfs_subsys; struct iio_sw_trigger_ops; struct iio_sw_trigger_type { -- cgit v1.2.3 From 0b4663a1f4a7541d070ddb3da4b606389a02d5c8 Mon Sep 17 00:00:00 2001 From: Ashley Towns Date: Thu, 12 Nov 2015 20:54:17 +1100 Subject: dt-bindings: fixes some incorrect header guards in dt-bindings where the preprocessor #ifndef/#define variables were mismatched. Signed-off-by: Ashley Towns Signed-off-by: Jiri Kosina --- include/dt-bindings/leds/common.h | 2 +- include/dt-bindings/mfd/palmas.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/dt-bindings/leds/common.h b/include/dt-bindings/leds/common.h index 79fcef72ef57..7958bec7de8c 100644 --- a/include/dt-bindings/leds/common.h +++ b/include/dt-bindings/leds/common.h @@ -6,7 +6,7 @@ * Author: Jacek Anaszewski */ -#ifndef __DT_BINDINGS_LEDS_H__ +#ifndef __DT_BINDINGS_LEDS_H #define __DT_BINDINGS_LEDS_H /* External trigger type */ diff --git a/include/dt-bindings/mfd/palmas.h b/include/dt-bindings/mfd/palmas.h index 2c8ac4841385..cdb075aae4e1 100644 --- a/include/dt-bindings/mfd/palmas.h +++ b/include/dt-bindings/mfd/palmas.h @@ -7,7 +7,7 @@ * */ -#ifndef __DT_BINDINGS_PALMAS_H__ +#ifndef __DT_BINDINGS_PALMAS_H #define __DT_BINDINGS_PALMAS_H /* External control pins */ -- cgit v1.2.3 From ed4f85c03cc7460a2f76afb73c22b8894b44ee20 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Tue, 1 Dec 2015 12:03:06 +0100 Subject: mtd: nand: embed an mtd_info structure into nand_chip Currently all NAND controller drivers are providing both the mtd_info and nand_chip struct and then let the NAND subsystem to initialize a few things before registering the mtd instance to the MTD layer. Embed an mtd_info field into nand_chip to add some consistency to all NAND controller drivers. This change will also help factorizing boilerplate code copied in all NAND drivers. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- include/linux/mtd/nand.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index fad634ea1685..d6710575ddb6 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -540,6 +540,7 @@ struct nand_buffers { /** * struct nand_chip - NAND Private Flash Chip Data + * @mtd: MTD device registered to the MTD framework * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the * flash device * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the @@ -640,6 +641,7 @@ struct nand_buffers { */ struct nand_chip { + struct mtd_info mtd; void __iomem *IO_ADDR_R; void __iomem *IO_ADDR_W; -- cgit v1.2.3 From ffd014f43fdcb6edb5a7f302de1e717e8c0673d5 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Tue, 1 Dec 2015 12:03:07 +0100 Subject: mtd: nand: add nand_to_mtd() helper Add a new helper to retrieve the MTD device attached to a NAND chip. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- include/linux/mtd/nand.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index d6710575ddb6..b614ed2105ac 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -737,6 +737,11 @@ static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd) return mtd->priv; } +static inline struct mtd_info *nand_to_mtd(struct nand_chip *chip) +{ + return &chip->mtd; +} + /* * NAND Flash Manufacturer ID Codes */ -- cgit v1.2.3 From b9adf469f8abb8a66f5795bbd8fe50fe201a14a1 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 4 Dec 2015 15:25:14 -0800 Subject: mtd: partitions: make parsers return 'const' partition arrays We only want to modify these arrays inside the parser "drivers", so the drivers should construct them however they like, then return them as immutable arrays. This will make other refactorings easier. Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- include/linux/mtd/partitions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index d002d9b5d797..6185536daacc 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -69,7 +69,7 @@ struct mtd_part_parser { struct list_head list; struct module *owner; const char *name; - int (*parse_fn)(struct mtd_info *, struct mtd_partition **, + int (*parse_fn)(struct mtd_info *, const struct mtd_partition **, struct mtd_part_parser_data *); }; -- cgit v1.2.3 From 07fd2f871c5e3dfb8ff5eb9c4b44fdb4cf1aeff5 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Fri, 4 Dec 2015 15:25:17 -0800 Subject: mtd: partitions: pass around 'mtd_partitions' wrapper struct For some of the core partitioning code, it helps to keep info about the parsed partition (and who parsed them) together in one place. Signed-off-by: Brian Norris --- include/linux/mtd/partitions.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include') diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index 6185536daacc..cceaf7bd1537 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -73,6 +73,13 @@ struct mtd_part_parser { struct mtd_part_parser_data *); }; +/* Container for passing around a set of parsed partitions */ +struct mtd_partitions { + const struct mtd_partition *parts; + int nr_parts; + const struct mtd_part_parser *parser; +}; + extern int __register_mtd_parser(struct mtd_part_parser *parser, struct module *owner); #define register_mtd_parser(parser) __register_mtd_parser(parser, THIS_MODULE) -- cgit v1.2.3 From adc83bf8896353603213754353dd66dae69e3d7f Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 9 Dec 2015 10:24:03 -0800 Subject: mtd: partitions: support a cleanup callback for parsers If partition parsers need to clean up their resources, we shouldn't assume that all memory will fit in a single kmalloc() that the caller can kfree(). We should allow the parser to provide a proper cleanup routine. Note that this means we need to keep a hold on the parser's module for a bit longer, and release it later with mtd_part_parser_put(). Alongside this, define a default callback that we'll automatically use if the parser doesn't provide one, so we can still retain the old behavior. Signed-off-by: Brian Norris Reviewed-by: Boris Brezillon --- include/linux/mtd/partitions.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index cceaf7bd1537..70736e1e6c8f 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -71,6 +71,7 @@ struct mtd_part_parser { const char *name; int (*parse_fn)(struct mtd_info *, const struct mtd_partition **, struct mtd_part_parser_data *); + void (*cleanup)(const struct mtd_partition *pparts, int nr_parts); }; /* Container for passing around a set of parsed partitions */ -- cgit v1.2.3 From 4d42e95fc789393d267bbab8b4684936c1529378 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 4 Dec 2015 16:56:29 +0100 Subject: dmaengine: sh: Remove unused R-Car HPB-DMAC driver As of commit 4baadb9e05c68962 ("ARM: shmobile: r8a7778: remove obsolete setup code"), the Renesas R-Car HPB-DMAC driver is no longer used. In theory it could still be used on R-Car Gen1 SoCs, but that requires adding DT support to the driver, which is not planned. Remove the driver, it can be resurrected from git history when needed. Signed-off-by: Geert Uytterhoeven Acked-by: Simon Horman Signed-off-by: Vinod Koul --- include/linux/platform_data/dma-rcar-hpbdma.h | 103 -------------------------- 1 file changed, 103 deletions(-) delete mode 100644 include/linux/platform_data/dma-rcar-hpbdma.h (limited to 'include') diff --git a/include/linux/platform_data/dma-rcar-hpbdma.h b/include/linux/platform_data/dma-rcar-hpbdma.h deleted file mode 100644 index 648b8ea61a22..000000000000 --- a/include/linux/platform_data/dma-rcar-hpbdma.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2011-2013 Renesas Electronics Corporation - * Copyright (C) 2013 Cogent Embedded, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - */ - -#ifndef __DMA_RCAR_HPBDMA_H -#define __DMA_RCAR_HPBDMA_H - -#include -#include - -/* Transmit sizes and respective register values */ -enum { - XMIT_SZ_8BIT = 0, - XMIT_SZ_16BIT = 1, - XMIT_SZ_32BIT = 2, - XMIT_SZ_MAX -}; - -/* DMA control register (DCR) bits */ -#define HPB_DMAE_DCR_DTAMD (1u << 26) -#define HPB_DMAE_DCR_DTAC (1u << 25) -#define HPB_DMAE_DCR_DTAU (1u << 24) -#define HPB_DMAE_DCR_DTAU1 (1u << 23) -#define HPB_DMAE_DCR_SWMD (1u << 22) -#define HPB_DMAE_DCR_BTMD (1u << 21) -#define HPB_DMAE_DCR_PKMD (1u << 20) -#define HPB_DMAE_DCR_CT (1u << 18) -#define HPB_DMAE_DCR_ACMD (1u << 17) -#define HPB_DMAE_DCR_DIP (1u << 16) -#define HPB_DMAE_DCR_SMDL (1u << 13) -#define HPB_DMAE_DCR_SPDAM (1u << 12) -#define HPB_DMAE_DCR_SDRMD_MASK (3u << 10) -#define HPB_DMAE_DCR_SDRMD_MOD (0u << 10) -#define HPB_DMAE_DCR_SDRMD_AUTO (1u << 10) -#define HPB_DMAE_DCR_SDRMD_TIMER (2u << 10) -#define HPB_DMAE_DCR_SPDS_MASK (3u << 8) -#define HPB_DMAE_DCR_SPDS_8BIT (0u << 8) -#define HPB_DMAE_DCR_SPDS_16BIT (1u << 8) -#define HPB_DMAE_DCR_SPDS_32BIT (2u << 8) -#define HPB_DMAE_DCR_DMDL (1u << 5) -#define HPB_DMAE_DCR_DPDAM (1u << 4) -#define HPB_DMAE_DCR_DDRMD_MASK (3u << 2) -#define HPB_DMAE_DCR_DDRMD_MOD (0u << 2) -#define HPB_DMAE_DCR_DDRMD_AUTO (1u << 2) -#define HPB_DMAE_DCR_DDRMD_TIMER (2u << 2) -#define HPB_DMAE_DCR_DPDS_MASK (3u << 0) -#define HPB_DMAE_DCR_DPDS_8BIT (0u << 0) -#define HPB_DMAE_DCR_DPDS_16BIT (1u << 0) -#define HPB_DMAE_DCR_DPDS_32BIT (2u << 0) - -/* Asynchronous reset register (ASYNCRSTR) bits */ -#define HPB_DMAE_ASYNCRSTR_ASRST41 BIT(10) -#define HPB_DMAE_ASYNCRSTR_ASRST40 BIT(9) -#define HPB_DMAE_ASYNCRSTR_ASRST39 BIT(8) -#define HPB_DMAE_ASYNCRSTR_ASRST27 BIT(7) -#define HPB_DMAE_ASYNCRSTR_ASRST26 BIT(6) -#define HPB_DMAE_ASYNCRSTR_ASRST25 BIT(5) -#define HPB_DMAE_ASYNCRSTR_ASRST24 BIT(4) -#define HPB_DMAE_ASYNCRSTR_ASRST23 BIT(3) -#define HPB_DMAE_ASYNCRSTR_ASRST22 BIT(2) -#define HPB_DMAE_ASYNCRSTR_ASRST21 BIT(1) -#define HPB_DMAE_ASYNCRSTR_ASRST20 BIT(0) - -struct hpb_dmae_slave_config { - unsigned int id; - dma_addr_t addr; - u32 dcr; - u32 port; - u32 rstr; - u32 mdr; - u32 mdm; - u32 flags; -#define HPB_DMAE_SET_ASYNC_RESET BIT(0) -#define HPB_DMAE_SET_ASYNC_MODE BIT(1) - u32 dma_ch; -}; - -#define HPB_DMAE_CHANNEL(_irq, _s_id) \ -{ \ - .ch_irq = _irq, \ - .s_id = _s_id, \ -} - -struct hpb_dmae_channel { - unsigned int ch_irq; - unsigned int s_id; -}; - -struct hpb_dmae_pdata { - const struct hpb_dmae_slave_config *slaves; - int num_slaves; - const struct hpb_dmae_channel *channels; - int num_channels; - const unsigned int ts_shift[XMIT_SZ_MAX]; - int num_hw_channels; -}; - -#endif -- cgit v1.2.3 From 49ddedf3bfcb59a562c7db0e50aecd1422e9cdc9 Mon Sep 17 00:00:00 2001 From: Martin Sperl Date: Fri, 27 Nov 2015 13:56:03 +0000 Subject: spi: add spi_message_init_no_memset to avoid zeroing the spi_message In the spi_loopback_test driver there is the need to initialize a spi_message that is filled with values from a static structure. Applying spi_message_init to such a prefilled structure results in all the settings getting reset to zero, which is not what we want. Copying each field of spi_message separately instead always includes the risk that some new fields have not been implemented in the copying code. So here we introduce a version of spi_message_init called spi_message_init_no_memset that does not fill the structure with zero first, but only initializes the relevant list_heads. Signed-off-by: Martin Sperl Signed-off-by: Mark Brown --- include/linux/spi/spi.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index cce80e6dc7d1..4c54d4744107 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -762,10 +762,15 @@ struct spi_message { void *state; }; +static inline void spi_message_init_no_memset(struct spi_message *m) +{ + INIT_LIST_HEAD(&m->transfers); +} + static inline void spi_message_init(struct spi_message *m) { memset(m, 0, sizeof *m); - INIT_LIST_HEAD(&m->transfers); + spi_message_init_no_memset(m); } static inline void -- cgit v1.2.3 From bd94c4077a0b2ecc35562c294f80f3659ecd8499 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 28 Oct 2015 12:46:05 +0900 Subject: serial: support 16-bit register interface for console Currently, 8-bit (MMIO) and 32-bit (MMIO32) register interfaces are supported for the 8250 console, but the 16-bit (MMIO16) is not. The 8250 UART device on my board is connected to a 16-bit bus and my main motivation is to use earlycon with it. (Refer to arch/arm/boot/dts/uniphier-support-card.dtsi) Signed-off-by: Masahiro Yamada Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- include/linux/serial_core.h | 1 + include/uapi/linux/serial.h | 1 + 2 files changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 297d4fa1cfe5..35aa87b96b71 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -150,6 +150,7 @@ struct uart_port { #define UPIO_AU (SERIAL_IO_AU) /* Au1x00 and RT288x type IO */ #define UPIO_TSI (SERIAL_IO_TSI) /* Tsi108/109 type IO */ #define UPIO_MEM32BE (SERIAL_IO_MEM32BE) /* 32b big endian */ +#define UPIO_MEM16 (SERIAL_IO_MEM16) /* 16b little endian */ unsigned int read_status_mask; /* driver specific */ unsigned int ignore_status_mask; /* driver specific */ diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h index 25331f9faa76..5d59c3ebf459 100644 --- a/include/uapi/linux/serial.h +++ b/include/uapi/linux/serial.h @@ -69,6 +69,7 @@ struct serial_struct { #define SERIAL_IO_AU 4 #define SERIAL_IO_TSI 5 #define SERIAL_IO_MEM32BE 6 +#define SERIAL_IO_MEM16 7 #define UART_CLEAR_FIFO 0x01 #define UART_USE_FIFO 0x02 -- cgit v1.2.3 From 998b4a4571b87eb6795863e07683fa5d4e0398ba Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 13:01:08 -0500 Subject: tty: Improve tty_debug() macro Incorporate suggestions for tty core debug macro improvements - printk(KERN_DEBUG) => pr_debug() - ##args => ##__VA_ARGS__ - remove do {} while() - output tty_name() first cc: Joe Perches Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- include/linux/tty.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/linux/tty.h b/include/linux/tty.h index 5e31f1b99037..3695c884258a 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -667,10 +667,7 @@ static inline void proc_tty_register_driver(struct tty_driver *d) {} static inline void proc_tty_unregister_driver(struct tty_driver *d) {} #endif -#define tty_debug(tty, f, args...) \ - do { \ - printk(KERN_DEBUG "%s: %s: " f, __func__, \ - tty_name(tty), ##args); \ - } while (0) +#define tty_debug(tty, f, ...) \ + pr_debug("%s: %s: " f, tty_name(tty), __func__, ##__VA_ARGS__) #endif -- cgit v1.2.3 From 82b8f888e99c81c609710901d8defbc8eff13f79 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 13:01:09 -0500 Subject: tty: Make tty_paranoia_check() file scope tty_paranoia_check() is only used within drivers/tty/tty_io.c; remove extern declaration in header and limit symbol to file scope. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- include/linux/tty.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include') diff --git a/include/linux/tty.h b/include/linux/tty.h index 3695c884258a..0532465ea142 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -419,8 +419,6 @@ static inline struct tty_struct *tty_kref_get(struct tty_struct *tty) return tty; } -extern int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, - const char *routine); extern const char *tty_name(const struct tty_struct *tty); extern void tty_wait_until_sent(struct tty_struct *tty, long timeout); extern int __tty_check_change(struct tty_struct *tty, int sig); -- cgit v1.2.3 From 0a083eddae33b6e20234d05a9cf54f87b0095511 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 13:01:12 -0500 Subject: tty: core: Add helper fn to deref tty driver name Similar to tty_name(), add tty_driver_name() helper to safely dereference tty->driver->name (otherwise return empty string). Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- include/linux/tty.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/tty.h b/include/linux/tty.h index 0532465ea142..a9c1af990da9 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -420,6 +420,7 @@ static inline struct tty_struct *tty_kref_get(struct tty_struct *tty) } extern const char *tty_name(const struct tty_struct *tty); +extern const char *tty_driver_name(const struct tty_struct *tty); extern void tty_wait_until_sent(struct tty_struct *tty, long timeout); extern int __tty_check_change(struct tty_struct *tty, int sig); extern int tty_check_change(struct tty_struct *tty); -- cgit v1.2.3 From 339f36ba14cf9f8fcf6e6b78385bd6811ec59fbe Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 13:01:13 -0500 Subject: tty: Define tty_*() printk macros Since not all ttys are devices (eg., SysV ptys), dev_*() printk macros cannot be used. Define tty_*() printk macros that output in similar format to dev_*() macros (ie., : .....). Transform the most-trivial printk( LEVEL ...) usage to tty_*() usage. NB: The function name has been eliminated from messages with unique context, or prefixed to the format when given. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- include/linux/tty.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/tty.h b/include/linux/tty.h index a9c1af990da9..f578e8405ff0 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -666,7 +666,17 @@ static inline void proc_tty_register_driver(struct tty_driver *d) {} static inline void proc_tty_unregister_driver(struct tty_driver *d) {} #endif +#define tty_msg(fn, tty, f, ...) \ + fn("%s %s: " f, tty_driver_name(tty), tty_name(tty), ##__VA_ARGS__) + #define tty_debug(tty, f, ...) \ - pr_debug("%s: %s: " f, tty_name(tty), __func__, ##__VA_ARGS__) + tty_msg(pr_debug, tty, "%s:" f, __func__, ##__VA_ARGS__) +#define tty_info(tty, f, ...) tty_msg(pr_info, tty, f, ##__VA_ARGS__) +#define tty_notice(tty, f, ...) tty_msg(pr_notice, tty, f, ##__VA_ARGS__) +#define tty_warn(tty, f, ...) tty_msg(pr_warn, tty, f, ##__VA_ARGS__) +#define tty_err(tty, f, ...) tty_msg(pr_err, tty, f, ##__VA_ARGS__) + +#define tty_info_ratelimited(tty, f, ...) \ + tty_msg(pr_info_ratelimited, tty, f, ##__VA_ARGS__) #endif -- cgit v1.2.3 From d435cefe9cbc9308cac8d4b19069a572e2bd1558 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 13:01:19 -0500 Subject: tty: Remove __func__ from tty_debug() macro Now that tty_debug() macro uses pr_debug(), the function name can be printed when using dynamic debug; printing the function name within the format string is redundant. Remove the __func__ parameter and print specifier from the format string. Add context to messages for when the function name is not printed by dynamic debug, or when dynamic debug is not enabled. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- include/linux/tty.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/tty.h b/include/linux/tty.h index f578e8405ff0..f06dd7a41a03 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -669,8 +669,7 @@ static inline void proc_tty_unregister_driver(struct tty_driver *d) {} #define tty_msg(fn, tty, f, ...) \ fn("%s %s: " f, tty_driver_name(tty), tty_name(tty), ##__VA_ARGS__) -#define tty_debug(tty, f, ...) \ - tty_msg(pr_debug, tty, "%s:" f, __func__, ##__VA_ARGS__) +#define tty_debug(tty, f, ...) tty_msg(pr_debug, tty, f, ##__VA_ARGS__) #define tty_info(tty, f, ...) tty_msg(pr_info, tty, f, ##__VA_ARGS__) #define tty_notice(tty, f, ...) tty_msg(pr_notice, tty, f, ##__VA_ARGS__) #define tty_warn(tty, f, ...) tty_msg(pr_warn, tty, f, ##__VA_ARGS__) -- cgit v1.2.3 From 4de91ebcc788f81d2a974d91208f5560ddf36378 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sun, 8 Nov 2015 09:18:31 -0500 Subject: tty: Remove dead tty_write_flush() declaration and macro tty_write_flush() has no definition and the TTY_WRITE_FLUSH() macro is never invoked; remove. Signed-off-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- include/linux/tty.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include') diff --git a/include/linux/tty.h b/include/linux/tty.h index f06dd7a41a03..2fd8708ea888 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -345,8 +345,6 @@ struct tty_file_private { #define TTY_HUPPED 18 /* Post driver->hangup() */ #define TTY_LDISC_HALTED 22 /* Line discipline is halted */ -#define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) - /* Values for tty->flow_change */ #define TTY_THROTTLE_SAFE 1 #define TTY_UNTHROTTLE_SAFE 2 @@ -395,8 +393,6 @@ static inline int __init tty_init(void) { return 0; } #endif -extern void tty_write_flush(struct tty_struct *); - extern struct ktermios tty_std_termios; extern int vcs_init(void); -- cgit v1.2.3 From d1b5c87fa8058a3f477ae05555916dd1cea934ad Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 16 Nov 2015 16:48:12 +0100 Subject: serial: remove NWP serial support The NWP serial driver is no longer needed, as the two users of this hardware have migrated to a much faster generation hardware, see https://en.wikipedia.org/wiki/QPACE2 for the replacement. Signed-off-by: Arnd Bergmann Cc: Benjamin Krill Cc: linuxppc-dev@lists.ozlabs.org Signed-off-by: Greg Kroah-Hartman --- include/linux/nwpserial.h | 18 ------------------ include/uapi/linux/serial_core.h | 2 +- 2 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 include/linux/nwpserial.h (limited to 'include') diff --git a/include/linux/nwpserial.h b/include/linux/nwpserial.h deleted file mode 100644 index 9acb21572eaf..000000000000 --- a/include/linux/nwpserial.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Serial Port driver for a NWP uart device - * - * Copyright (C) 2008 IBM Corp., Benjamin Krill - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ -#ifndef _NWPSERIAL_H -#define _NWPSERIAL_H - -int nwpserial_register_port(struct uart_port *port); -void nwpserial_unregister_port(int line); - -#endif /* _NWPSERIAL_H */ diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index 93ba148f923e..3e5d757407fb 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -176,7 +176,7 @@ #define PORT_S3C6400 84 -/* NWPSERIAL */ +/* NWPSERIAL, now removed */ #define PORT_NWPSERIAL 85 /* MAX3100 */ -- cgit v1.2.3 From 7ec758718920e5e5876d0d02ece6855128c8eb1e Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 16 Nov 2015 17:40:57 +0000 Subject: tty: amba-pl011: add support for ZTE UART (EXPERIMENTAL) Add (incomplete) support for the ZTE UART to the AMBA PL011 driver. This is similar to the ARM and ST variants, except it has a different register address layout, and requires 32-bit accesses to the registers. Use the newly introduced register tables and access size support to cope with these differences. Signed-off-by: Russell King Reviewed-by: Peter Hurley Signed-off-by: Greg Kroah-Hartman --- include/linux/amba/serial.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include') diff --git a/include/linux/amba/serial.h b/include/linux/amba/serial.h index 0ddb5c02ad8b..d76a19ba2cff 100644 --- a/include/linux/amba/serial.h +++ b/include/linux/amba/serial.h @@ -65,6 +65,24 @@ #define ST_UART011_ABCR 0x100 /* Autobaud control register. */ #define ST_UART011_ABIMSC 0x15C /* Autobaud interrupt mask/clear register. */ +/* + * ZTE UART register offsets. This UART has a radically different address + * allocation from the ARM and ST variants, so we list all registers here. + * We assume unlisted registers do not exist. + */ +#define ZX_UART011_DR 0x04 +#define ZX_UART011_FR 0x14 +#define ZX_UART011_IBRD 0x24 +#define ZX_UART011_FBRD 0x28 +#define ZX_UART011_LCRH 0x30 +#define ZX_UART011_CR 0x34 +#define ZX_UART011_IFLS 0x38 +#define ZX_UART011_IMSC 0x40 +#define ZX_UART011_RIS 0x44 +#define ZX_UART011_MIS 0x48 +#define ZX_UART011_ICR 0x4c +#define ZX_UART011_DMACR 0x50 + #define UART011_DR_OE (1 << 11) #define UART011_DR_BE (1 << 10) #define UART011_DR_PE (1 << 9) -- cgit v1.2.3 From 858965d909db32fb567a06916bbebdb8951cd39e Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 27 Nov 2015 21:29:24 -0500 Subject: serial: Fix UPIO_MEM comment The original semantics of UPIO_MEM did not include the notion of bitness and endianness; different drivers used UPIO_MEM to refer to their original mmio bitness/endianness. For example, for the 8250 driver this is 8-bit LE but for the amba-pl011 driver this is 16-bit LE. Since UPIO_* values are userspace ABI via TIOCGSERIAL/TIOCSSERIAL ioctls, the original meaning of UPIIO_MEM must remain as it was: the original mmio stride/width/endianness of the driver. Signed-off-by: Peter Hurley Acked-by: Timur Tabi Signed-off-by: Greg Kroah-Hartman --- include/linux/serial_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 35aa87b96b71..e03d6ba5e5b4 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -145,7 +145,7 @@ struct uart_port { #define UPIO_PORT (SERIAL_IO_PORT) /* 8b I/O port access */ #define UPIO_HUB6 (SERIAL_IO_HUB6) /* Hub6 ISA card */ -#define UPIO_MEM (SERIAL_IO_MEM) /* 8b MMIO access */ +#define UPIO_MEM (SERIAL_IO_MEM) /* driver-specific */ #define UPIO_MEM32 (SERIAL_IO_MEM32) /* 32b little endian */ #define UPIO_AU (SERIAL_IO_AU) /* Au1x00 and RT288x type IO */ #define UPIO_TSI (SERIAL_IO_TSI) /* Tsi108/109 type IO */ -- cgit v1.2.3 From e1dba01ca620bb0b3864d5237c1c597d9e012ebf Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 8 Dec 2015 10:37:46 +0100 Subject: i2c: add generic routine to parse DT for timing information Inspired from the i2c-rk3x driver (thanks guys!) but refactored and extended. See built-in docs for further information. Signed-off-by: Wolfram Sang Reviewed-by: Mika Westerberg Signed-off-by: Wolfram Sang --- include/linux/i2c.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include') diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 51028f351d13..bc2b19ad9357 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -413,6 +413,22 @@ struct i2c_algorithm { #endif }; +/** + * struct i2c_timings - I2C timing information + * @bus_freq_hz: the bus frequency in Hz + * @scl_rise_ns: time SCL signal takes to rise in ns; t(r) in the I2C specification + * @scl_fall_ns: time SCL signal takes to fall in ns; t(f) in the I2C specification + * @scl_int_delay_ns: time IP core additionally needs to setup SCL in ns + * @sda_fall_ns: time SDA signal takes to fall in ns; t(f) in the I2C specification + */ +struct i2c_timings { + u32 bus_freq_hz; + u32 scl_rise_ns; + u32 scl_fall_ns; + u32 scl_int_delay_ns; + u32 sda_fall_ns; +}; + /** * struct i2c_bus_recovery_info - I2C bus recovery information * @recover_bus: Recover routine. Either pass driver's recover_bus() routine, or @@ -604,6 +620,7 @@ extern void i2c_clients_command(struct i2c_adapter *adap, extern struct i2c_adapter *i2c_get_adapter(int nr); extern void i2c_put_adapter(struct i2c_adapter *adap); +void i2c_parse_fw_timings(struct device *dev, struct i2c_timings *t, bool use_defaults); /* Return the functionality mask */ static inline u32 i2c_get_functionality(struct i2c_adapter *adap) @@ -660,6 +677,7 @@ extern struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node) /* must call i2c_put_adapter() when done with returned i2c_adapter device */ struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node); + #else static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) -- cgit v1.2.3 From 665d2c2848f14c0c2a2e89192bde9073c4d352f7 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 8 Dec 2015 17:04:59 -0800 Subject: mtd: bcm47xxnflash: really unregister NAND on device removal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The field bcma_nflash::mtd is never set to be non-zero anywhere, but we test for it in the removal path. So the MTD is never unregistered. Also, we should use nand_release(), not mtd_device_unregister(). Finally, we don't need to use the 'platdata' for stashing/retrieving our *driver* data -- that's what *_{get,set}_drvdata() are for. So, kill off bcm_nflash::mtd, and stash the struct bcm47xxnflash in drvdata instead. Also move the forward declaration of mtd_info up a bit, since struct bcma_sflash should be using it. Caught while inspecting other changes being made to this driver. Compile tested only. Signed-off-by: Brian Norris Cc: "Rafał Miłecki" Cc: linux-wireless@vger.kernel.org Acked-by: Boris Brezillon --- include/linux/bcma/bcma_driver_chipcommon.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index cf038431a5cc..db51a6ffb7d6 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h @@ -579,6 +579,8 @@ struct bcma_pflash { }; #ifdef CONFIG_BCMA_SFLASH +struct mtd_info; + struct bcma_sflash { bool present; u32 window; @@ -592,13 +594,9 @@ struct bcma_sflash { #endif #ifdef CONFIG_BCMA_NFLASH -struct mtd_info; - struct bcma_nflash { bool present; bool boot; /* This is the flash the SoC boots from */ - - struct mtd_info *mtd; }; #endif -- cgit v1.2.3 From a11fac3776fc4db6a9fa1104b1d0477809c677e0 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 14 Dec 2015 18:58:42 -0800 Subject: f2fs: add symbol to avoid any confusion with tools This patch adds MAX_VOLUME_NAME to sync with f2fs-tools. Signed-off-by: Jaegeuk Kim --- include/linux/f2fs_fs.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index 25c6324a0dd0..e59c3be92106 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -51,6 +51,7 @@ #define MAX_ACTIVE_DATA_LOGS 8 #define VERSION_LEN 256 +#define MAX_VOLUME_NAME 512 /* * For superblock @@ -84,7 +85,7 @@ struct f2fs_super_block { __le32 node_ino; /* node inode number */ __le32 meta_ino; /* meta inode number */ __u8 uuid[16]; /* 128-bit uuid for volume */ - __le16 volume_name[512]; /* volume name */ + __le16 volume_name[MAX_VOLUME_NAME]; /* volume name */ __le32 extension_count; /* # of extensions below */ __u8 extension_list[F2FS_MAX_EXTENSION][8]; /* extension array */ __le32 cp_payload; -- cgit v1.2.3 From b4ed5d1682c6613988c2eb1de55df5ac9988afcc Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Mon, 14 Dec 2015 16:01:34 -0800 Subject: tools: hv: report ENOSPC errors in hv_fcopy_daemon Currently some "Unspecified error 0x80004005" is reported on the Windows side if something fails. Handle the ENOSPC case and return ERROR_DISK_FULL, which allows at least Copy-VMFile to report a meaning full error. Signed-off-by: Olaf Hering Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- include/uapi/linux/hyperv.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/uapi/linux/hyperv.h b/include/uapi/linux/hyperv.h index e4c0a35d6417..e347b24ef9fb 100644 --- a/include/uapi/linux/hyperv.h +++ b/include/uapi/linux/hyperv.h @@ -313,6 +313,7 @@ enum hv_kvp_exchg_pool { #define HV_INVALIDARG 0x80070057 #define HV_GUID_NOTFOUND 0x80041002 #define HV_ERROR_ALREADY_EXISTS 0x80070050 +#define HV_ERROR_DISK_FULL 0x80070070 #define ADDR_FAMILY_NONE 0x00 #define ADDR_FAMILY_IPV4 0x01 -- cgit v1.2.3 From 619848bd074343ff2bdeeafca0be39748f6da372 Mon Sep 17 00:00:00 2001 From: Jake Oshins Date: Mon, 14 Dec 2015 16:01:39 -0800 Subject: drivers:hv: Export a function that maps Linux CPU num onto Hyper-V proc num This patch exposes the mapping between Linux CPU number and Hyper-V virtual processor number. This is necessary because the hypervisor needs to know which virtual processors to target when making a mapping in the Interrupt Redirection Table in the I/O MMU. Signed-off-by: Jake Oshins Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- include/linux/hyperv.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 8fdc17b84739..fddb3e0e8feb 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -983,6 +983,8 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj, resource_size_t size, resource_size_t align, bool fb_overlap_ok); +int vmbus_cpu_number_to_vp_number(int cpu_number); + /** * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device * -- cgit v1.2.3 From a108393dbf764efb2405f21ca759806c65b8bc16 Mon Sep 17 00:00:00 2001 From: Jake Oshins Date: Mon, 14 Dec 2015 16:01:40 -0800 Subject: drivers:hv: Export the API to invoke a hypercall on Hyper-V This patch exposes the function that hv_vmbus.ko uses to make hypercalls. This is necessary for retargeting an interrupt when it is given a new affinity. Since we are exporting this API, rename the API as it will be visible outside the hv.c file. Signed-off-by: Jake Oshins Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- include/linux/hyperv.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index fddb3e0e8feb..24d0b656e6e7 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -984,6 +984,7 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj, bool fb_overlap_ok); int vmbus_cpu_number_to_vp_number(int cpu_number); +u64 hv_do_hypercall(u64 control, void *input, void *output); /** * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device -- cgit v1.2.3 From 3053c762444a83ec6a8777f9476668b23b8ab180 Mon Sep 17 00:00:00 2001 From: Jake Oshins Date: Mon, 14 Dec 2015 16:01:41 -0800 Subject: drivers:hv: Define the channel type for Hyper-V PCI Express pass-through This defines the channel type for PCI front-ends in Hyper-V VMs. Signed-off-by: Jake Oshins Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- include/linux/hyperv.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include') diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 24d0b656e6e7..c9a9eed89af2 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1140,6 +1140,17 @@ u64 hv_do_hypercall(u64 control, void *input, void *output); 0xab, 0x99, 0xbd, 0x1f, 0x1c, 0x86, 0xb5, 0x01 \ } +/* + * PCI Express Pass Through + * {44C4F61D-4444-4400-9D52-802E27EDE19F} + */ + +#define HV_PCIE_GUID \ + .guid = { \ + 0x1D, 0xF6, 0xC4, 0x44, 0x44, 0x44, 0x00, 0x44, \ + 0x9D, 0x52, 0x80, 0x2E, 0x27, 0xED, 0xE1, 0x9F \ + } + /* * Common header for Hyper-V ICs */ -- cgit v1.2.3 From af3ff643ea91ba64dd8d0b1cbed54d44512f96cd Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 14 Dec 2015 16:01:43 -0800 Subject: Drivers: hv: vmbus: Use uuid_le type consistently Consistently use uuid_le type in the Hyper-V driver code. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- include/linux/hyperv.h | 92 ++++++++++++++--------------------------- include/linux/mod_devicetable.h | 2 +- 2 files changed, 33 insertions(+), 61 deletions(-) (limited to 'include') diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index c9a9eed89af2..b9f3bb25d8b4 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -997,6 +997,8 @@ u64 hv_do_hypercall(u64 control, void *input, void *output); .guid = { g0, g1, g2, g3, g4, g5, g6, g7, \ g8, g9, ga, gb, gc, gd, ge, gf }, + + /* * GUID definitions of various offer types - services offered to the guest. */ @@ -1006,118 +1008,94 @@ u64 hv_do_hypercall(u64 control, void *input, void *output); * {f8615163-df3e-46c5-913f-f2d2f965ed0e} */ #define HV_NIC_GUID \ - .guid = { \ - 0x63, 0x51, 0x61, 0xf8, 0x3e, 0xdf, 0xc5, 0x46, \ - 0x91, 0x3f, 0xf2, 0xd2, 0xf9, 0x65, 0xed, 0x0e \ - } + .guid = UUID_LE(0xf8615163, 0xdf3e, 0x46c5, 0x91, 0x3f, \ + 0xf2, 0xd2, 0xf9, 0x65, 0xed, 0x0e) /* * IDE GUID * {32412632-86cb-44a2-9b5c-50d1417354f5} */ #define HV_IDE_GUID \ - .guid = { \ - 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, \ - 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 \ - } + .guid = UUID_LE(0x32412632, 0x86cb, 0x44a2, 0x9b, 0x5c, \ + 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5) /* * SCSI GUID * {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */ #define HV_SCSI_GUID \ - .guid = { \ - 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, \ - 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f \ - } + .guid = UUID_LE(0xba6163d9, 0x04a1, 0x4d29, 0xb6, 0x05, \ + 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f) /* * Shutdown GUID * {0e0b6031-5213-4934-818b-38d90ced39db} */ #define HV_SHUTDOWN_GUID \ - .guid = { \ - 0x31, 0x60, 0x0b, 0x0e, 0x13, 0x52, 0x34, 0x49, \ - 0x81, 0x8b, 0x38, 0xd9, 0x0c, 0xed, 0x39, 0xdb \ - } + .guid = UUID_LE(0x0e0b6031, 0x5213, 0x4934, 0x81, 0x8b, \ + 0x38, 0xd9, 0x0c, 0xed, 0x39, 0xdb) /* * Time Synch GUID * {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */ #define HV_TS_GUID \ - .guid = { \ - 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, \ - 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf \ - } + .guid = UUID_LE(0x9527e630, 0xd0ae, 0x497b, 0xad, 0xce, \ + 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf) /* * Heartbeat GUID * {57164f39-9115-4e78-ab55-382f3bd5422d} */ #define HV_HEART_BEAT_GUID \ - .guid = { \ - 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, \ - 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d \ - } + .guid = UUID_LE(0x57164f39, 0x9115, 0x4e78, 0xab, 0x55, \ + 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d) /* * KVP GUID * {a9a0f4e7-5a45-4d96-b827-8a841e8c03e6} */ #define HV_KVP_GUID \ - .guid = { \ - 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, \ - 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6 \ - } + .guid = UUID_LE(0xa9a0f4e7, 0x5a45, 0x4d96, 0xb8, 0x27, \ + 0x8a, 0x84, 0x1e, 0x8c, 0x03, 0xe6) /* * Dynamic memory GUID * {525074dc-8985-46e2-8057-a307dc18a502} */ #define HV_DM_GUID \ - .guid = { \ - 0xdc, 0x74, 0x50, 0X52, 0x85, 0x89, 0xe2, 0x46, \ - 0x80, 0x57, 0xa3, 0x07, 0xdc, 0x18, 0xa5, 0x02 \ - } + .guid = UUID_LE(0x525074dc, 0x8985, 0x46e2, 0x80, 0x57, \ + 0xa3, 0x07, 0xdc, 0x18, 0xa5, 0x02) /* * Mouse GUID * {cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a} */ #define HV_MOUSE_GUID \ - .guid = { \ - 0x9e, 0xb6, 0xa8, 0xcf, 0x4a, 0x5b, 0xc0, 0x4c, \ - 0xb9, 0x8b, 0x8b, 0xa1, 0xa1, 0xf3, 0xf9, 0x5a \ - } + .guid = UUID_LE(0xcfa8b69e, 0x5b4a, 0x4cc0, 0xb9, 0x8b, \ + 0x8b, 0xa1, 0xa1, 0xf3, 0xf9, 0x5a) /* * VSS (Backup/Restore) GUID */ #define HV_VSS_GUID \ - .guid = { \ - 0x29, 0x2e, 0xfa, 0x35, 0x23, 0xea, 0x36, 0x42, \ - 0x96, 0xae, 0x3a, 0x6e, 0xba, 0xcb, 0xa4, 0x40 \ - } + .guid = UUID_LE(0x35fa2e29, 0xea23, 0x4236, 0x96, 0xae, \ + 0x3a, 0x6e, 0xba, 0xcb, 0xa4, 0x40) /* * Synthetic Video GUID * {DA0A7802-E377-4aac-8E77-0558EB1073F8} */ #define HV_SYNTHVID_GUID \ - .guid = { \ - 0x02, 0x78, 0x0a, 0xda, 0x77, 0xe3, 0xac, 0x4a, \ - 0x8e, 0x77, 0x05, 0x58, 0xeb, 0x10, 0x73, 0xf8 \ - } + .guid = UUID_LE(0xda0a7802, 0xe377, 0x4aac, 0x8e, 0x77, \ + 0x05, 0x58, 0xeb, 0x10, 0x73, 0xf8) /* * Synthetic FC GUID * {2f9bcc4a-0069-4af3-b76b-6fd0be528cda} */ #define HV_SYNTHFC_GUID \ - .guid = { \ - 0x4A, 0xCC, 0x9B, 0x2F, 0x69, 0x00, 0xF3, 0x4A, \ - 0xB7, 0x6B, 0x6F, 0xD0, 0xBE, 0x52, 0x8C, 0xDA \ - } + .guid = UUID_LE(0x2f9bcc4a, 0x0069, 0x4af3, 0xb7, 0x6b, \ + 0x6f, 0xd0, 0xbe, 0x52, 0x8c, 0xda) /* * Guest File Copy Service @@ -1125,20 +1103,16 @@ u64 hv_do_hypercall(u64 control, void *input, void *output); */ #define HV_FCOPY_GUID \ - .guid = { \ - 0xE3, 0x4B, 0xD1, 0x34, 0xE4, 0xDE, 0xC8, 0x41, \ - 0x9A, 0xE7, 0x6B, 0x17, 0x49, 0x77, 0xC1, 0x92 \ - } + .guid = UUID_LE(0x34d14be3, 0xdee4, 0x41c8, 0x9a, 0xe7, \ + 0x6b, 0x17, 0x49, 0x77, 0xc1, 0x92) /* * NetworkDirect. This is the guest RDMA service. * {8c2eaf3d-32a7-4b09-ab99-bd1f1c86b501} */ #define HV_ND_GUID \ - .guid = { \ - 0x3d, 0xaf, 0x2e, 0x8c, 0xa7, 0x32, 0x09, 0x4b, \ - 0xab, 0x99, 0xbd, 0x1f, 0x1c, 0x86, 0xb5, 0x01 \ - } + .guid = UUID_LE(0x8c2eaf3d, 0x32a7, 0x4b09, 0xab, 0x99, \ + 0xbd, 0x1f, 0x1c, 0x86, 0xb5, 0x01) /* * PCI Express Pass Through @@ -1146,10 +1120,8 @@ u64 hv_do_hypercall(u64 control, void *input, void *output); */ #define HV_PCIE_GUID \ - .guid = { \ - 0x1D, 0xF6, 0xC4, 0x44, 0x44, 0x44, 0x00, 0x44, \ - 0x9D, 0x52, 0x80, 0x2E, 0x27, 0xED, 0xE1, 0x9F \ - } + .guid = UUID_LE(0x44c4f61d, 0x4444, 0x4400, 0x9d, 0x52, \ + 0x80, 0x2e, 0x27, 0xed, 0xe1, 0x9f) /* * Common header for Hyper-V ICs diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 64f36e09a790..6e4c645e1c0d 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -404,7 +404,7 @@ struct virtio_device_id { * For Hyper-V devices we use the device guid as the id. */ struct hv_vmbus_device_id { - __u8 guid[16]; + uuid_le guid; kernel_ulong_t driver_data; /* Data private to the driver */ }; -- cgit v1.2.3 From 90e031fa06ad6b660a8e9bebbb80bd30e555a2a5 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 14 Dec 2015 16:01:45 -0800 Subject: Drivers: hv: vmbus: Get rid of the unused macro The macro VMBUS_DEVICE() is unused; get rid of it. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- include/linux/hyperv.h | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'include') diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index b9f3bb25d8b4..f773a6871f4c 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -986,19 +986,6 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj, int vmbus_cpu_number_to_vp_number(int cpu_number); u64 hv_do_hypercall(u64 control, void *input, void *output); -/** - * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device - * - * This macro is used to create a struct hv_vmbus_device_id that matches a - * specific device. - */ -#define VMBUS_DEVICE(g0, g1, g2, g3, g4, g5, g6, g7, \ - g8, g9, ga, gb, gc, gd, ge, gf) \ - .guid = { g0, g1, g2, g3, g4, g5, g6, g7, \ - g8, g9, ga, gb, gc, gd, ge, gf }, - - - /* * GUID definitions of various offer types - services offered to the guest. */ -- cgit v1.2.3 From 8599846d73997cdbccf63f23394d871cfad1e5e6 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Mon, 14 Dec 2015 16:01:54 -0800 Subject: Drivers: hv: vmbus: Fix a Host signaling bug Currently we have two policies for deciding when to signal the host: One based on the ring buffer state and the other based on what the VMBUS client driver wants to do. Consider the case when the client wants to explicitly control when to signal the host. In this case, if the client were to defer signaling, we will not be able to signal the host subsequently when the client does want to signal since the ring buffer state will prevent the signaling. Implement logic to have only one signaling policy in force for a given channel. Signed-off-by: K. Y. Srinivasan Reviewed-by: Haiyang Zhang Tested-by: Haiyang Zhang Cc: # v4.2+ Signed-off-by: Greg Kroah-Hartman --- include/linux/hyperv.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include') diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index f773a6871f4c..acd995b81c6b 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -630,6 +630,11 @@ struct hv_input_signal_event_buffer { struct hv_input_signal_event event; }; +enum hv_signal_policy { + HV_SIGNAL_POLICY_DEFAULT = 0, + HV_SIGNAL_POLICY_EXPLICIT, +}; + struct vmbus_channel { /* Unique channel id */ int id; @@ -757,8 +762,21 @@ struct vmbus_channel { * link up channels based on their CPU affinity. */ struct list_head percpu_list; + /* + * Host signaling policy: The default policy will be + * based on the ring buffer state. We will also support + * a policy where the client driver can have explicit + * signaling control. + */ + enum hv_signal_policy signal_policy; }; +static inline void set_channel_signal_state(struct vmbus_channel *c, + enum hv_signal_policy policy) +{ + c->signal_policy = policy; +} + static inline void set_channel_read_state(struct vmbus_channel *c, bool state) { c->batched_reading = state; -- cgit v1.2.3 From 45870a441361d1c05a5f767c4ece2f6e30e0da9c Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Mon, 14 Dec 2015 19:01:58 -0800 Subject: Drivers: hv: ring_buffer: remove stray smp_read_barrier_depends() smp_read_barrier_depends() does nothing on almost all arcitectures including x86 and having it in the beginning of hv_get_ringbuffer_availbytes() does not provide any guarantees anyway. Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- include/linux/hyperv.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include') diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index acd995b81c6b..179ff330af59 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -141,8 +141,6 @@ hv_get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi, { u32 read_loc, write_loc, dsize; - smp_read_barrier_depends(); - /* Capture the read/write indices before they changed */ read_loc = rbi->ring_buffer->read_index; write_loc = rbi->ring_buffer->write_index; -- cgit v1.2.3 From 51f141a97a1406bb0b59d490e837a39ccb7c3999 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 18 Nov 2015 14:34:09 +0900 Subject: usb: renesas_usbhs: Modify pipe configuration The current code has info->bufnmb_last to calculate the BUFNMB bits of PIPEBUF register. However, since the bufnmb_last is initialized in the usbhs_pipe_init() only, this driver is possible to set unexpected value to the register if usb_ep_{enable,disable}() are called many times. So, this patch modifies the pipe configuration via struct renesas_usbhs_driver_param to simplify the code. Also this patch changes: - a double buffer configuration - isochronous buffer size from 512 to 1024 Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- include/linux/usb/renesas_usbhs.h | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/usb/renesas_usbhs.h b/include/linux/usb/renesas_usbhs.h index bfb74723f151..4db191fe8c2c 100644 --- a/include/linux/usb/renesas_usbhs.h +++ b/include/linux/usb/renesas_usbhs.h @@ -105,12 +105,26 @@ struct renesas_usbhs_platform_callback { * some register needs USB chip specific parameters. * This struct show it to driver */ + +struct renesas_usbhs_driver_pipe_config { + u8 type; /* USB_ENDPOINT_XFER_xxx */ + u16 bufsize; + u8 bufnum; + bool double_buf; +}; +#define RENESAS_USBHS_PIPE(_type, _size, _num, _double_buf) { \ + .type = (_type), \ + .bufsize = (_size), \ + .bufnum = (_num), \ + .double_buf = (_double_buf), \ + } + struct renesas_usbhs_driver_param { /* * pipe settings */ - u32 *pipe_type; /* array of USB_ENDPOINT_XFER_xxx (from ep0) */ - int pipe_size; /* pipe_type array size */ + struct renesas_usbhs_driver_pipe_config *pipe_configs; + int pipe_size; /* pipe_configs array size */ /* * option: -- cgit v1.2.3 From 98bfb39466954c69d2a448e6ddcab6d91cd48e25 Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Tue, 3 Nov 2015 11:51:15 -0600 Subject: usb: of: add an api to get dr_mode by the phy node Some USB phy drivers have different handling for the controller in each dr_mode. But the phy driver does not have visibility to the dr_mode of the controller. This adds an api to return the dr_mode of the controller which associates the given phy node. Signed-off-by: Bin Liu Signed-off-by: Felipe Balbi --- include/linux/usb/of.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/linux/usb/of.h b/include/linux/usb/of.h index c3fe9e48ce27..3805757dcdc2 100644 --- a/include/linux/usb/of.h +++ b/include/linux/usb/of.h @@ -12,10 +12,15 @@ #include #if IS_ENABLED(CONFIG_OF) +enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np); bool of_usb_host_tpl_support(struct device_node *np); int of_usb_update_otg_caps(struct device_node *np, struct usb_otg_caps *otg_caps); #else +enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np) +{ + return USB_DR_MODE_UNKNOWN; +} static inline bool of_usb_host_tpl_support(struct device_node *np) { return false; -- cgit v1.2.3 From 375da6271b685e97d2d936fffa6e405b93674c26 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 4 Dec 2015 17:04:25 +0100 Subject: usb: phy: Remove unused Renesas R-Car (Gen1) USB PHY driver As of commit 3d7608e4c169af03 ("ARM: shmobile: bockw: remove legacy board file and config"), the Renesas R-Car (Gen1) USB PHY driver is no longer used. In theory it could still be used on R-Car Gen1 SoCs, but that would require adding DT support to the driver. Instead, a new driver using the generic PHY framework should be written, as was done for R-Car Gen2. Remove the driver for good. Acked-by: Simon Horman Signed-off-by: Geert Uytterhoeven Signed-off-by: Felipe Balbi --- include/linux/platform_data/usb-rcar-phy.h | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 include/linux/platform_data/usb-rcar-phy.h (limited to 'include') diff --git a/include/linux/platform_data/usb-rcar-phy.h b/include/linux/platform_data/usb-rcar-phy.h deleted file mode 100644 index 8ec6964a32a5..000000000000 --- a/include/linux/platform_data/usb-rcar-phy.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2013 Renesas Solutions Corp. - * Copyright (C) 2013 Cogent Embedded, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __USB_RCAR_PHY_H -#define __USB_RCAR_PHY_H - -#include - -struct rcar_phy_platform_data { - bool ferrite_bead:1; /* (R8A7778 only) */ - - bool port1_func:1; /* true: port 1 used by function, false: host */ - unsigned penc1:1; /* Output of the PENC1 pin in function mode */ - struct { /* Overcurrent pin control for ports 0..2 */ - bool select_3_3v:1; /* true: USB_OVCn pin, false: OVCn pin */ - /* Set to false on port 1 in function mode */ - bool active_high:1; /* true: active high, false: active low */ - /* Set to true on port 1 in function mode */ - } ovc_pin[3]; /* (R8A7778 only has 2 ports) */ -}; - -#endif /* __USB_RCAR_PHY_H */ -- cgit v1.2.3 From 2284b29d3d9dd16490909962574d7f3fef83fd97 Mon Sep 17 00:00:00 2001 From: Ruslan Bilovol Date: Mon, 23 Nov 2015 09:56:35 +0100 Subject: usb: gadget: bind UDC by name passed via usb_gadget_driver structure Introduce new 'udc_name' member to usb_gadget_driver structure. The 'udc_name' is a name of UDC that usb_gadget_driver should be bound to. If udc_name is NULL, it will be bound to any available UDC. Tested-by: Maxime Ripard Signed-off-by: Ruslan Bilovol Signed-off-by: Marek Szyprowski Tested-by: Peter Chen Signed-off-by: Felipe Balbi --- include/linux/usb/gadget.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 3d583a10b926..63963c21866d 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -1012,6 +1012,8 @@ static inline int usb_gadget_activate(struct usb_gadget *gadget) * @reset: Invoked on USB bus reset. It is mandatory for all gadget drivers * and should be called in_interrupt. * @driver: Driver model state for this driver. + * @udc_name: A name of UDC this driver should be bound to. If udc_name is NULL, + * this driver will be bound to any available UDC. * * Devices are disabled till a gadget driver successfully bind()s, which * means the driver will handle setup() requests needed to enumerate (and @@ -1072,6 +1074,8 @@ struct usb_gadget_driver { /* FIXME support safe rmmod */ struct device_driver driver; + + char *udc_name; }; -- cgit v1.2.3 From 88f73ebdfa75602af18e070a4d5d6d9091bcfada Mon Sep 17 00:00:00 2001 From: Ruslan Bilovol Date: Mon, 23 Nov 2015 09:56:37 +0100 Subject: usb: gadget: udc-core: remove unused usb_udc_attach_driver() Now when last user of usb_udc_attach_driver() is switched to passing UDC name via usb_gadget_driver struct, it's safe to remove this function Tested-by: Maxime Ripard Signed-off-by: Ruslan Bilovol Signed-off-by: Marek Szyprowski Tested-by: Peter Chen Signed-off-by: Felipe Balbi --- include/linux/usb/gadget.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include') diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 63963c21866d..ce2188d338e6 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -1121,8 +1121,6 @@ extern int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget, void (*release)(struct device *dev)); extern int usb_add_gadget_udc(struct device *parent, struct usb_gadget *gadget); extern void usb_del_gadget_udc(struct usb_gadget *gadget); -extern int usb_udc_attach_driver(const char *name, - struct usb_gadget_driver *driver); /*-------------------------------------------------------------------------*/ -- cgit v1.2.3 From 855ed04a3758b205e84b269f92d26ab36ed8e2f7 Mon Sep 17 00:00:00 2001 From: Ruslan Bilovol Date: Mon, 23 Nov 2015 09:56:38 +0100 Subject: usb: gadget: udc-core: independent registration of gadgets and gadget drivers Change behavior during registration of gadgets and gadget drivers in udc-core. Instead of previous approach when for successful probe of usb gadget driver at least one usb gadget should be already registered use another one where gadget drivers and gadgets can be registered in udc-core independently. Independent registration of gadgets and gadget drivers is useful for built-in into kernel gadget and gadget driver case - because it's possible that gadget is really probed only on late_init stage (due to deferred probe) whereas gadget driver's probe is silently failed on module_init stage due to no any UDC added. Also it is useful for modules case - now there is no difference what module to insert first: gadget module or gadget driver one. Tested-by: Maxime Ripard Signed-off-by: Ruslan Bilovol [simplified code as requested by Alan Stern and Felipe Balbi, fixed checkpatch issues] Signed-off-by: Marek Szyprowski Tested-by: Peter Chen Signed-off-by: Felipe Balbi --- include/linux/usb/gadget.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index ce2188d338e6..92467eea76de 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -1014,6 +1014,7 @@ static inline int usb_gadget_activate(struct usb_gadget *gadget) * @driver: Driver model state for this driver. * @udc_name: A name of UDC this driver should be bound to. If udc_name is NULL, * this driver will be bound to any available UDC. + * @pending: UDC core private data used for deferred probe of this driver. * * Devices are disabled till a gadget driver successfully bind()s, which * means the driver will handle setup() requests needed to enumerate (and @@ -1076,6 +1077,7 @@ struct usb_gadget_driver { struct device_driver driver; char *udc_name; + struct list_head pending; }; -- cgit v1.2.3 From 8055555fc4590fbda32d4bbf7888bdb2cd4b2b74 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 30 Nov 2015 21:37:12 -0800 Subject: usb: musb: core: Fix handling of the phy notifications We currently can't unload omap2430 MUSB platform glue driver module and this cause issues for fixing the MUSB code further. The reason we can't remove omap2430 is because it uses the PHY functions and also exports the omap_musb_mailbox function that some PHY drivers are using. Let's fix the issue by exporting a more generic musb_mailbox function from the MUSB core and allow platform glue layers to register phy_callback function as needed. And now we can now also get rid of the include/linux/musb-omap.h. Cc: Bin Liu Cc: Felipe Balbi Cc: Kishon Vijay Abraham I Cc: NeilBrown Reviewed-by: Kishon Vijay Abraham I Signed-off-by: Tony Lindgren Signed-off-by: Felipe Balbi --- include/linux/usb/musb-omap.h | 30 ------------------------------ include/linux/usb/musb.h | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 30 deletions(-) delete mode 100644 include/linux/usb/musb-omap.h (limited to 'include') diff --git a/include/linux/usb/musb-omap.h b/include/linux/usb/musb-omap.h deleted file mode 100644 index 7774c5986f07..000000000000 --- a/include/linux/usb/musb-omap.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2011-2012 by Texas Instruments - * - * The Inventra Controller Driver for Linux is free software; you - * can redistribute it and/or modify it under the terms of the GNU - * General Public License version 2 as published by the Free Software - * Foundation. - */ - -#ifndef __MUSB_OMAP_H__ -#define __MUSB_OMAP_H__ - -enum omap_musb_vbus_id_status { - OMAP_MUSB_UNKNOWN = 0, - OMAP_MUSB_ID_GROUND, - OMAP_MUSB_ID_FLOAT, - OMAP_MUSB_VBUS_VALID, - OMAP_MUSB_VBUS_OFF, -}; - -#if (defined(CONFIG_USB_MUSB_OMAP2PLUS) || \ - defined(CONFIG_USB_MUSB_OMAP2PLUS_MODULE)) -void omap_musb_mailbox(enum omap_musb_vbus_id_status status); -#else -static inline void omap_musb_mailbox(enum omap_musb_vbus_id_status status) -{ -} -#endif - -#endif /* __MUSB_OMAP_H__ */ diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h index fa6dc132bd1b..96ddfb7ab018 100644 --- a/include/linux/usb/musb.h +++ b/include/linux/usb/musb.h @@ -133,6 +133,21 @@ struct musb_hdrc_platform_data { const void *platform_ops; }; +enum musb_vbus_id_status { + MUSB_UNKNOWN = 0, + MUSB_ID_GROUND, + MUSB_ID_FLOAT, + MUSB_VBUS_VALID, + MUSB_VBUS_OFF, +}; + +#if IS_ENABLED(CONFIG_USB_MUSB_HDRC) +void musb_mailbox(enum musb_vbus_id_status status); +#else +static inline void musb_mailbox(enum musb_vbus_id_status status) +{ +} +#endif /* TUSB 6010 support */ -- cgit v1.2.3 From 6b0f8f9c52efe24d6dac06ab963b7bd91c723751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=B6sz=C3=B6rm=C3=A9nyi=20Zolt=C3=A1n?= Date: Wed, 16 Dec 2015 11:11:50 -0800 Subject: Input: add eGalaxTouch serial touchscreen driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are two EETI touchscreen drivers in the kernel (eeti_ts and egalax_ts) but both are for I2C-connected panels. This is for a different, serial and not multi-touch touchscreen panel. The protocol documentation is at http://www.eeti.com.tw/pdf/Software%20Programming%20Guide_v2.0.pdf Signed-off-by: Böszörményi Zoltán Signed-off-by: Dmitry Torokhov --- include/uapi/linux/serio.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/uapi/linux/serio.h b/include/uapi/linux/serio.h index becdd78295cc..c2ea1698257f 100644 --- a/include/uapi/linux/serio.h +++ b/include/uapi/linux/serio.h @@ -77,5 +77,6 @@ #define SERIO_PS2MULT 0x3c #define SERIO_TSC40 0x3d #define SERIO_WACOM_IV 0x3e +#define SERIO_EGALAX 0x3f #endif /* _UAPI_SERIO_H */ -- cgit v1.2.3 From b8bbd6b2923279f1c9c74d59638b38a1eace78e8 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 12 Nov 2015 13:36:06 +0100 Subject: serial: sh-sci: Add BRG register definitions Add register definitions for the Baud Rate Generator for External Clock (BRG), as found in some SCIF and in HSCIF, including a new regtype for the "SH-4(A)"-derived SCIF variant with BRG. Signed-off-by: Geert Uytterhoeven Acked-by: Greg Kroah-Hartman --- include/linux/serial_sci.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index 7c536ac5be05..9f2bfd055742 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -32,6 +32,7 @@ enum { SCIx_SH2_SCIF_FIFODATA_REGTYPE, SCIx_SH3_SCIF_REGTYPE, SCIx_SH4_SCIF_REGTYPE, + SCIx_SH4_SCIF_BRG_REGTYPE, SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, SCIx_SH4_SCIF_FIFODATA_REGTYPE, SCIx_SH7705_SCIF_REGTYPE, -- cgit v1.2.3 From be99c84300950e876074916b215b511f69f83d3b Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 17 Dec 2015 09:55:41 -0600 Subject: usb: of: fix build breakage on !OF If OF is disabled, we will try to define a stub for of_usb_get_dr_mode_by_phy(), however that missed a static inline annotation which made us redefine the stub over and over again. Fix that. Fixes: 98bfb3946695 ("usb: of: add an api to get dr_mode by the phy node") Signed-off-by: Felipe Balbi --- include/linux/usb/of.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/usb/of.h b/include/linux/usb/of.h index 3805757dcdc2..974bce93aa28 100644 --- a/include/linux/usb/of.h +++ b/include/linux/usb/of.h @@ -17,7 +17,8 @@ bool of_usb_host_tpl_support(struct device_node *np); int of_usb_update_otg_caps(struct device_node *np, struct usb_otg_caps *otg_caps); #else -enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np) +static inline enum usb_dr_mode +of_usb_get_dr_mode_by_phy(struct device_node *phy_np) { return USB_DR_MODE_UNKNOWN; } -- cgit v1.2.3 From fcd71d9cc6e301bdbd71829b79e80168473ca609 Mon Sep 17 00:00:00 2001 From: Sudip Mukherjee Date: Tue, 8 Dec 2015 14:17:55 +0530 Subject: of: fix declaration of of_io_request_and_map We are having build failure with linux-next for sparc allmodconfig with the error messages: drivers/built-in.o: In function `meson6_timer_init': meson6_timer.c:(.init.text+0x5fe8): undefined reference to `of_io_request_and_map' drivers/built-in.o: In function `mtk_timer_init': mtk_timer.c:(.init.text+0x6af0): undefined reference to `of_io_request_and_map' drivers/built-in.o: In function `asm9260_timer_init': asm9260_timer.c:(.init.text+0x6c48): undefined reference to `of_io_request_and_map' CONFIG_OF is defined for sparc so it is expected that we have a definition of of_io_request_and_map() but of/address.c is only compiled if it is !SPARC. In other words, CONFIG_OF_ADDRESS is not defined for sparc so we get the build failure. Fixes: e572f844ca66 ("clocksource/drivers/meson6: Add the COMPILE_TEST option") Fixes: bec8c4617611 ("clocksource/drivers/mediatek: Add the COMPILE_TEST option") Fixes: 4a373b45f94a ("clocksource/drivers/asm9260: Add the COMPILE_TEST option") Acked-by: Daniel Lezcano Signed-off-by: Sudip Mukherjee [robh: move include of io.h out of ifdef's] Signed-off-by: Rob Herring --- include/linux/of_address.h | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/linux/of_address.h b/include/linux/of_address.h index 507daad0bc8d..01c0a556448b 100644 --- a/include/linux/of_address.h +++ b/include/linux/of_address.h @@ -3,6 +3,7 @@ #include #include #include +#include struct of_pci_range_parser { struct device_node *node; @@ -36,6 +37,8 @@ extern struct device_node *of_find_matching_node_by_address( const struct of_device_id *matches, u64 base_address); extern void __iomem *of_iomap(struct device_node *device, int index); +void __iomem *of_io_request_and_map(struct device_node *device, + int index, const char *name); /* Extract an address from a device, returns the region size and * the address space flags too. The PCI version uses a BAR number @@ -57,6 +60,11 @@ extern int of_dma_get_range(struct device_node *np, u64 *dma_addr, u64 *paddr, u64 *size); extern bool of_dma_is_coherent(struct device_node *np); #else /* CONFIG_OF_ADDRESS */ +static inline void __iomem *of_io_request_and_map(struct device_node *device, + int index, const char *name) +{ + return IOMEM_ERR_PTR(-EINVAL); +} static inline u64 of_translate_address(struct device_node *np, const __be32 *addr) @@ -112,12 +120,7 @@ static inline bool of_dma_is_coherent(struct device_node *np) extern int of_address_to_resource(struct device_node *dev, int index, struct resource *r); void __iomem *of_iomap(struct device_node *node, int index); -void __iomem *of_io_request_and_map(struct device_node *device, - int index, const char *name); #else - -#include - static inline int of_address_to_resource(struct device_node *dev, int index, struct resource *r) { @@ -128,12 +131,6 @@ static inline void __iomem *of_iomap(struct device_node *device, int index) { return NULL; } - -static inline void __iomem *of_io_request_and_map(struct device_node *device, - int index, const char *name) -{ - return IOMEM_ERR_PTR(-EINVAL); -} #endif #if defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI) -- cgit v1.2.3 From 4cf185379b7504d640c9dd72f959f081b25f6ea2 Mon Sep 17 00:00:00 2001 From: Chao Yu Date: Thu, 17 Dec 2015 17:17:16 +0800 Subject: f2fs: add a tracepoint for sync_dirty_inodes This patch adds a tracepoint for sync_dirty_inodes. Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim --- include/trace/events/f2fs.h | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'include') diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h index 00b4a6308249..a1b488809f06 100644 --- a/include/trace/events/f2fs.h +++ b/include/trace/events/f2fs.h @@ -1265,6 +1265,44 @@ TRACE_EVENT(f2fs_destroy_extent_tree, __entry->node_cnt) ); +DECLARE_EVENT_CLASS(f2fs_sync_dirty_inodes, + + TP_PROTO(struct super_block *sb, int type, int count), + + TP_ARGS(sb, type, count), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(int, type) + __field(int, count) + ), + + TP_fast_assign( + __entry->dev = sb->s_dev; + __entry->type = type; + __entry->count = count; + ), + + TP_printk("dev = (%d,%d), %s, dirty count = %d", + show_dev(__entry), + show_file_type(__entry->type), + __entry->count) +); + +DEFINE_EVENT(f2fs_sync_dirty_inodes, f2fs_sync_dirty_inodes_enter, + + TP_PROTO(struct super_block *sb, int type, int count), + + TP_ARGS(sb, type, count) +); + +DEFINE_EVENT(f2fs_sync_dirty_inodes, f2fs_sync_dirty_inodes_exit, + + TP_PROTO(struct super_block *sb, int type, int count), + + TP_ARGS(sb, type, count) +); + #endif /* _TRACE_F2FS_H */ /* This part must be outside protection */ -- cgit v1.2.3 From a8135d0d79e9d0ad3a4ff494fceeaae838becf38 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 14 Dec 2015 22:47:40 +0200 Subject: dmaengine: core: Introduce new, universal API to request a channel The two API function can cover most, if not all current APIs used to request a channel. With minimal effort dmaengine drivers, platforms and dmaengine user drivers can be converted to use the two function. struct dma_chan *dma_request_chan_by_mask(const dma_cap_mask_t *mask); To request any channel matching with the requested capabilities, can be used to request channel for memcpy, memset, xor, etc where no hardware synchronization is needed. struct dma_chan *dma_request_chan(struct device *dev, const char *name); To request a slave channel. The dma_request_chan() will try to find the channel via DT, ACPI or in case if the kernel booted in non DT/ACPI mode it will use a filter lookup table and retrieves the needed information from the dma_slave_map provided by the DMA drivers. This legacy mode needs changes in platform code, in dmaengine drivers and finally the dmaengine user drivers can be converted: For each dmaengine driver an array of DMA device, slave and the parameter for the filter function needs to be added: static const struct dma_slave_map da830_edma_map[] = { { "davinci-mcasp.0", "rx", EDMA_FILTER_PARAM(0, 0) }, { "davinci-mcasp.0", "tx", EDMA_FILTER_PARAM(0, 1) }, { "davinci-mcasp.1", "rx", EDMA_FILTER_PARAM(0, 2) }, { "davinci-mcasp.1", "tx", EDMA_FILTER_PARAM(0, 3) }, { "davinci-mcasp.2", "rx", EDMA_FILTER_PARAM(0, 4) }, { "davinci-mcasp.2", "tx", EDMA_FILTER_PARAM(0, 5) }, { "spi_davinci.0", "rx", EDMA_FILTER_PARAM(0, 14) }, { "spi_davinci.0", "tx", EDMA_FILTER_PARAM(0, 15) }, { "da830-mmc.0", "rx", EDMA_FILTER_PARAM(0, 16) }, { "da830-mmc.0", "tx", EDMA_FILTER_PARAM(0, 17) }, { "spi_davinci.1", "rx", EDMA_FILTER_PARAM(0, 18) }, { "spi_davinci.1", "tx", EDMA_FILTER_PARAM(0, 19) }, }; This information is going to be needed by the dmaengine driver, so modification to the platform_data is needed, and the driver map should be added to the pdata of the DMA driver: da8xx_edma0_pdata.slave_map = da830_edma_map; da8xx_edma0_pdata.slavecnt = ARRAY_SIZE(da830_edma_map); The DMA driver then needs to configure the needed device -> filter_fn mapping before it registers with dma_async_device_register() : ecc->dma_slave.filter_map.map = info->slave_map; ecc->dma_slave.filter_map.mapcnt = info->slavecnt; ecc->dma_slave.filter_map.fn = edma_filter_fn; When neither DT or ACPI lookup is available the dma_request_chan() will try to match the requester's device name with the filter_map's list of device names, when a match found it will use the information from the dma_slave_map to get the channel with the dma_get_channel() internal function. Signed-off-by: Peter Ujfalusi Reviewed-by: Arnd Bergmann Signed-off-by: Vinod Koul --- include/linux/dmaengine.h | 51 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index c47c68e535e8..d50a6b51a73d 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -606,12 +606,39 @@ enum dmaengine_alignment { DMAENGINE_ALIGN_64_BYTES = 6, }; +/** + * struct dma_slave_map - associates slave device and it's slave channel with + * parameter to be used by a filter function + * @devname: name of the device + * @slave: slave channel name + * @param: opaque parameter to pass to struct dma_filter.fn + */ +struct dma_slave_map { + const char *devname; + const char *slave; + void *param; +}; + +/** + * struct dma_filter - information for slave device/channel to filter_fn/param + * mapping + * @fn: filter function callback + * @mapcnt: number of slave device/channel in the map + * @map: array of channel to filter mapping data + */ +struct dma_filter { + dma_filter_fn fn; + int mapcnt; + const struct dma_slave_map *map; +}; + /** * struct dma_device - info on the entity supplying DMA services * @chancnt: how many DMA channels are supported * @privatecnt: how many DMA channels are requested by dma_request_channel * @channels: the list of struct dma_chan * @global_node: list_head for global dma_device_list + * @filter: information for device/slave to filter function/param mapping * @cap_mask: one or more dma_capability flags * @max_xor: maximum number of xor sources, 0 if no capability * @max_pq: maximum number of PQ sources and PQ-continue capability @@ -666,6 +693,7 @@ struct dma_device { unsigned int privatecnt; struct list_head channels; struct list_head global_node; + struct dma_filter filter; dma_cap_mask_t cap_mask; unsigned short max_xor; unsigned short max_pq; @@ -1140,9 +1168,11 @@ enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx); void dma_issue_pending_all(void); struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask, dma_filter_fn fn, void *fn_param); -struct dma_chan *dma_request_slave_channel_reason(struct device *dev, - const char *name); struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name); + +struct dma_chan *dma_request_chan(struct device *dev, const char *name); +struct dma_chan *dma_request_chan_by_mask(const dma_cap_mask_t *mask); + void dma_release_channel(struct dma_chan *chan); int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps); #else @@ -1166,16 +1196,21 @@ static inline struct dma_chan *__dma_request_channel(const dma_cap_mask_t *mask, { return NULL; } -static inline struct dma_chan *dma_request_slave_channel_reason( - struct device *dev, const char *name) -{ - return ERR_PTR(-ENODEV); -} static inline struct dma_chan *dma_request_slave_channel(struct device *dev, const char *name) { return NULL; } +static inline struct dma_chan *dma_request_chan(struct device *dev, + const char *name) +{ + return ERR_PTR(-ENODEV); +} +static inline struct dma_chan *dma_request_chan_by_mask( + const dma_cap_mask_t *mask) +{ + return ERR_PTR(-ENODEV); +} static inline void dma_release_channel(struct dma_chan *chan) { } @@ -1186,6 +1221,8 @@ static inline int dma_get_slave_caps(struct dma_chan *chan, } #endif +#define dma_request_slave_channel_reason(dev, name) dma_request_chan(dev, name) + static inline int dmaengine_desc_set_reuse(struct dma_async_tx_descriptor *tx) { struct dma_slave_caps caps; -- cgit v1.2.3 From 23e6723c060faf5a0fc8d7bfbec440d29943fa99 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 14 Dec 2015 22:47:41 +0200 Subject: dmaengine: edma: Add support for DMA filter mapping to slave devices Add support for providing device to filter_fn mapping so client drivers can switch to use the dma_request_chan() API. Signed-off-by: Peter Ujfalusi Reviewed-by: Arnd Bergmann Signed-off-by: Vinod Koul --- include/linux/platform_data/edma.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include') diff --git a/include/linux/platform_data/edma.h b/include/linux/platform_data/edma.h index e2878baeb90e..105700e62ea1 100644 --- a/include/linux/platform_data/edma.h +++ b/include/linux/platform_data/edma.h @@ -53,12 +53,16 @@ enum dma_event_q { #define EDMA_CTLR(i) ((i) >> 16) #define EDMA_CHAN_SLOT(i) ((i) & 0xffff) +#define EDMA_FILTER_PARAM(ctlr, chan) ((int[]) { EDMA_CTLR_CHAN(ctlr, chan) }) + struct edma_rsv_info { const s16 (*rsv_chans)[2]; const s16 (*rsv_slots)[2]; }; +struct dma_slave_map; + /* platform_data for EDMA driver */ struct edma_soc_info { /* @@ -76,6 +80,9 @@ struct edma_soc_info { s8 (*queue_priority_mapping)[2]; const s16 (*xbar_chans)[2]; + + const struct dma_slave_map *slave_map; + int slavecnt; }; #endif -- cgit v1.2.3 From 020c62ae38946cae01571a0b4e6f445dfdb7ec1c Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 14 Dec 2015 22:47:42 +0200 Subject: dmaengine: omap-dma: Add support for DMA filter mapping to slave devices Add support for providing device to filter_fn mapping so client drivers can switch to use the dma_request_chan() API. Signed-off-by: Peter Ujfalusi Reviewed-by: Arnd Bergmann Signed-off-by: Vinod Koul --- include/linux/omap-dma.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/linux/omap-dma.h b/include/linux/omap-dma.h index 88fa8af2b937..1d99b61adc65 100644 --- a/include/linux/omap-dma.h +++ b/include/linux/omap-dma.h @@ -267,6 +267,9 @@ struct omap_dma_reg { u8 type; }; +#define SDMA_FILTER_PARAM(hw_req) ((int[]) { (hw_req) }) +struct dma_slave_map; + /* System DMA platform data structure */ struct omap_system_dma_plat_info { const struct omap_dma_reg *reg_map; @@ -278,6 +281,9 @@ struct omap_system_dma_plat_info { void (*clear_dma)(int lch); void (*dma_write)(u32 val, int reg, int lch); u32 (*dma_read)(int reg, int lch); + + const struct dma_slave_map *slave_map; + int slavecnt; }; #ifdef CONFIG_ARCH_OMAP2PLUS -- cgit v1.2.3 From 9c9eef89ec74433f00593938f8af5113383d898a Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:23 +0100 Subject: mtd: nand: sh_flctl: use the mtd instance embedded in struct nand_chip struct nand_chip now embeds an mtd device. Make use of this mtd instance. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- include/linux/mtd/sh_flctl.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h index 1c28f8879b1c..76e3e88bedfe 100644 --- a/include/linux/mtd/sh_flctl.h +++ b/include/linux/mtd/sh_flctl.h @@ -143,7 +143,6 @@ enum flctl_ecc_res_t { struct dma_chan; struct sh_flctl { - struct mtd_info mtd; struct nand_chip chip; struct platform_device *pdev; struct dev_pm_qos_request pm_qos; @@ -186,7 +185,7 @@ struct sh_flctl_platform_data { static inline struct sh_flctl *mtd_to_flctl(struct mtd_info *mtdinfo) { - return container_of(mtdinfo, struct sh_flctl, mtd); + return container_of(mtd_to_nand(mtdinfo), struct sh_flctl, chip); } #endif /* __SH_FLCTL_H__ */ -- cgit v1.2.3 From 2d3b77bac34bf99d7fdfd712ec2dc4317b3e850b Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:33 +0100 Subject: mtd: nand: update mtd_to_nand() Now that all drivers are using the mtd instance embedded in the nand_chip struct we can safely update the mtd_to_nand() implementation to use the container_of macro instead of returning the content of mtd->priv. This will allow us to remove mtd->priv = chip assignments done in all NAND controller drivers. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- include/linux/mtd/nand.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index b614ed2105ac..9cb7ace6fb1f 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -734,7 +734,7 @@ static inline struct device_node *nand_get_flash_node(struct nand_chip *chip) static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd) { - return mtd->priv; + return container_of(mtd, struct nand_chip, mtd); } static inline struct mtd_info *nand_to_mtd(struct nand_chip *chip) -- cgit v1.2.3 From 29574ede097438c560e8115caff9b6b8668730be Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:38 +0100 Subject: mtd: nand: kill the chip->flash_node field Now that the nand_chip struct directly embeds an mtd_info struct we can get rid of the ->flash_node field and forward set/get_flash_node requests to the MTD layer. As a side effect, we no longer need the mtd_set_of_node() call done in nand_dt_init(). Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- include/linux/mtd/nand.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 9cb7ace6fb1f..2bee2e42ae2f 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -545,7 +545,6 @@ struct nand_buffers { * flash device * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the * flash device. - * @flash_node: [BOARDSPECIFIC] device node describing this instance * @read_byte: [REPLACEABLE] read one byte from the chip * @read_word: [REPLACEABLE] read one word from the chip * @write_byte: [REPLACEABLE] write a single byte to the chip on the @@ -645,8 +644,6 @@ struct nand_chip { void __iomem *IO_ADDR_R; void __iomem *IO_ADDR_W; - struct device_node *flash_node; - uint8_t (*read_byte)(struct mtd_info *mtd); u16 (*read_word)(struct mtd_info *mtd); void (*write_byte)(struct mtd_info *mtd, uint8_t byte); @@ -724,12 +721,12 @@ struct nand_chip { static inline void nand_set_flash_node(struct nand_chip *chip, struct device_node *np) { - chip->flash_node = np; + mtd_set_of_node(&chip->mtd, np); } static inline struct device_node *nand_get_flash_node(struct nand_chip *chip) { - return chip->flash_node; + return mtd_get_of_node(&chip->mtd); } static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd) -- cgit v1.2.3 From 8142b47ef33c655a34e08efd46b65732fe190675 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Mon, 14 Dec 2015 16:13:31 +0100 Subject: mtd: nand: remove unused and buggy get_platform_nandchip() helper function Nobody uses the get_platform_nandchip() helper function which is supposed to return a pointer to a platform_nand_chip struct from an mtd_info pointer. Moreover, this function is buggy since the introduction of the plat_nand layer (chip->priv is now storing a pointer to an intermediate plat_nand_data structure allocated in plat_nand_probe(), and we have no way to retrieve a pointer to the provided platform_nand_chip struct from this plat_nand_data pointer). While we are at it, remove the useless (and buggy, since it's pointing to something stored on the stack) data->chip.priv assignment. Signed-off-by: Boris Brezillon Fixes: 711fdf627ce1 ("[MTD] [NAND] platform NAND driver: add driver") Cc: Vitaly Wool Signed-off-by: Brian Norris --- include/linux/mtd/nand.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'include') diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 2bee2e42ae2f..3e92be1d2d43 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -927,15 +927,6 @@ struct platform_nand_data { struct platform_nand_ctrl ctrl; }; -/* Some helpers to access the data structures */ -static inline -struct platform_nand_chip *get_platform_nandchip(struct mtd_info *mtd) -{ - struct nand_chip *chip = mtd->priv; - - return chip->priv; -} - /* return the supported features. */ static inline int onfi_feature(struct nand_chip *chip) { -- cgit v1.2.3 From 052876f8e5aec887d22c4d06e54aa5531ffcec75 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Fri, 18 Dec 2015 17:20:09 -0800 Subject: Input: uinput - add new UINPUT_DEV_SETUP and UI_ABS_SETUP ioctl This adds two new ioctls, UINPUT_DEV_SETUP and UI_ABS_SETUP, that replaces the old device setup method (by write()'ing "struct uinput_user_dev" to the node). The old method is not easily extendable and requires huge payloads. Furthermore, overloading write() without properly versioned objects is error-prone. Therefore, we introduce two new ioctls to replace the old method. These ioctls support all features of the old method, plus a "resolution" field for absinfo. Furthermore, it's properly forward-compatible to new ABS codes and a growing "struct input_absinfo" structure. UI_ABS_SETUP also allows user-space to skip unknown axes if not set. There is no need to copy the whole array temporarily into the kernel, but instead the caller issues several ioctl where we copy each value manually. Signed-off-by: David Herrmann Signed-off-by: Benjamin Tissoires Reviewed-by: David Herrmann Signed-off-by: Dmitry Torokhov --- include/linux/uinput.h | 5 +++ include/uapi/linux/uinput.h | 83 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 85 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/uinput.h b/include/linux/uinput.h index 0994c0d01a09..75de43da2301 100644 --- a/include/linux/uinput.h +++ b/include/linux/uinput.h @@ -20,6 +20,11 @@ * Author: Aristeu Sergio Rozanski Filho * * Changes/Revisions: + * 0.5 08/13/2015 (David Herrmann & + * Benjamin Tissoires ) + * - add UI_DEV_SETUP ioctl + * - add UI_ABS_SETUP ioctl + * - add UI_GET_VERSION ioctl * 0.4 01/09/2014 (Benjamin Tissoires ) * - add UI_GET_SYSNAME ioctl * 0.3 24/05/2006 (Anssi Hannula ) diff --git a/include/uapi/linux/uinput.h b/include/uapi/linux/uinput.h index 013c9d8db372..77b8cf73a178 100644 --- a/include/uapi/linux/uinput.h +++ b/include/uapi/linux/uinput.h @@ -20,6 +20,11 @@ * Author: Aristeu Sergio Rozanski Filho * * Changes/Revisions: + * 0.5 08/13/2015 (David Herrmann & + * Benjamin Tissoires ) + * - add UI_DEV_SETUP ioctl + * - add UI_ABS_SETUP ioctl + * - add UI_GET_VERSION ioctl * 0.4 01/09/2014 (Benjamin Tissoires ) * - add UI_GET_SYSNAME ioctl * 0.3 24/05/2006 (Anssi Hannula ) @@ -37,8 +42,8 @@ #include #include -#define UINPUT_VERSION 4 - +#define UINPUT_VERSION 5 +#define UINPUT_MAX_NAME_SIZE 80 struct uinput_ff_upload { __u32 request_id; @@ -58,6 +63,79 @@ struct uinput_ff_erase { #define UI_DEV_CREATE _IO(UINPUT_IOCTL_BASE, 1) #define UI_DEV_DESTROY _IO(UINPUT_IOCTL_BASE, 2) +struct uinput_setup { + struct input_id id; + char name[UINPUT_MAX_NAME_SIZE]; + __u32 ff_effects_max; +}; + +/** + * UI_DEV_SETUP - Set device parameters for setup + * + * This ioctl sets parameters for the input device to be created. It must be + * issued *before* calling UI_DEV_CREATE or it will fail. This ioctl supersedes + * the old "struct uinput_user_dev" method, which wrote this data via write(). + * To actually set the absolute axes, you also need to call the ioctl + * UI_ABS_SETUP *before* calling this ioctl. + * + * This ioctl takes a "struct uinput_setup" object as argument. The fields of + * this object are as follows: + * id: See the description of "struct input_id". This field is + * copied unchanged into the new device. + * name: This is used unchanged as name for the new device. + * ff_effects_max: This limits the maximum numbers of force-feedback effects. + * See below for a description of FF with uinput. + * + * This ioctl can be called multiple times and will overwrite previous values. + * If this ioctl fails with -EINVAL, you're recommended to use the old + * "uinput_user_dev" method via write() as fallback, in case you run on an old + * kernel that does not support this ioctl. + * + * This ioctl may fail with -EINVAL if it is not supported or if you passed + * incorrect values, -ENOMEM if the kernel runs out of memory or -EFAULT if the + * passed uinput_setup object cannot be read/written. + * If this call fails, partial data may have already been applied to the + * internal device. + */ +#define UI_DEV_SETUP _IOW(UINPUT_IOCTL_BASE, 3, struct uinput_setup) + +struct uinput_abs_setup { + __u16 code; /* axis code */ + /* __u16 filler; */ + struct input_absinfo absinfo; +}; + +/** + * UI_ABS_SETUP - Set absolute axis information for the device to setup + * + * This ioctl sets one absolute axis information for the input device to be + * created. It must be issued *before* calling UI_DEV_SETUP and UI_DEV_CREATE + * for every absolute axis the device exports. + * This ioctl supersedes the old "struct uinput_user_dev" method, which wrote + * part of this data and the content of UI_DEV_SETUP via write(). + * + * This ioctl takes a "struct uinput_abs_setup" object as argument. The fields + * of this object are as follows: + * code: The corresponding input code associated with this axis + * (ABS_X, ABS_Y, etc...) + * absinfo: See "struct input_absinfo" for a description of this field. + * This field is copied unchanged into the kernel for the + * specified axis. If the axis is not enabled via + * UI_SET_ABSBIT, this ioctl will enable it. + * + * This ioctl can be called multiple times and will overwrite previous values. + * If this ioctl fails with -EINVAL, you're recommended to use the old + * "uinput_user_dev" method via write() as fallback, in case you run on an old + * kernel that does not support this ioctl. + * + * This ioctl may fail with -EINVAL if it is not supported or if you passed + * incorrect values, -ENOMEM if the kernel runs out of memory or -EFAULT if the + * passed uinput_setup object cannot be read/written. + * If this call fails, partial data may have already been applied to the + * internal device. + */ +#define UI_ABS_SETUP _IOW(UINPUT_IOCTL_BASE, 4, struct uinput_abs_setup) + #define UI_SET_EVBIT _IOW(UINPUT_IOCTL_BASE, 100, int) #define UI_SET_KEYBIT _IOW(UINPUT_IOCTL_BASE, 101, int) #define UI_SET_RELBIT _IOW(UINPUT_IOCTL_BASE, 102, int) @@ -144,7 +222,6 @@ struct uinput_ff_erase { #define UI_FF_UPLOAD 1 #define UI_FF_ERASE 2 -#define UINPUT_MAX_NAME_SIZE 80 struct uinput_user_dev { char name[UINPUT_MAX_NAME_SIZE]; struct input_id id; -- cgit v1.2.3 From fbae10db094046dba1d59e1c2ee5140835045f14 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 25 Oct 2015 10:34:13 +0100 Subject: Input: uinput - rework ABS validation Rework the uinput ABS validation to check passed absinfo data immediately, but do ABS initialization as last step in UI_DEV_CREATE. The behavior observed by user-space is not changed, as ABS initialization was never checked for errors. With this in place, the order of device initialization and abs configuration is no longer fixed. Userspace can initialize the device and afterwards set absinfo just fine. Signed-off-by: David Herrmann Reviewed-by: Benjamin Tissoires Tested-by: Benjamin Tissoires Signed-off-by: Dmitry Torokhov --- include/uapi/linux/uinput.h | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'include') diff --git a/include/uapi/linux/uinput.h b/include/uapi/linux/uinput.h index 77b8cf73a178..dc652e224b67 100644 --- a/include/uapi/linux/uinput.h +++ b/include/uapi/linux/uinput.h @@ -72,13 +72,12 @@ struct uinput_setup { /** * UI_DEV_SETUP - Set device parameters for setup * - * This ioctl sets parameters for the input device to be created. It must be - * issued *before* calling UI_DEV_CREATE or it will fail. This ioctl supersedes - * the old "struct uinput_user_dev" method, which wrote this data via write(). - * To actually set the absolute axes, you also need to call the ioctl - * UI_ABS_SETUP *before* calling this ioctl. + * This ioctl sets parameters for the input device to be created. It + * supersedes the old "struct uinput_user_dev" method, which wrote this data + * via write(). To actually set the absolute axes UI_ABS_SETUP should be + * used. * - * This ioctl takes a "struct uinput_setup" object as argument. The fields of + * The ioctl takes a "struct uinput_setup" object as argument. The fields of * this object are as follows: * id: See the description of "struct input_id". This field is * copied unchanged into the new device. @@ -87,9 +86,9 @@ struct uinput_setup { * See below for a description of FF with uinput. * * This ioctl can be called multiple times and will overwrite previous values. - * If this ioctl fails with -EINVAL, you're recommended to use the old - * "uinput_user_dev" method via write() as fallback, in case you run on an old - * kernel that does not support this ioctl. + * If this ioctl fails with -EINVAL, it is recommended to use the old + * "uinput_user_dev" method via write() as a fallback, in case you run on an + * old kernel that does not support this ioctl. * * This ioctl may fail with -EINVAL if it is not supported or if you passed * incorrect values, -ENOMEM if the kernel runs out of memory or -EFAULT if the @@ -109,12 +108,10 @@ struct uinput_abs_setup { * UI_ABS_SETUP - Set absolute axis information for the device to setup * * This ioctl sets one absolute axis information for the input device to be - * created. It must be issued *before* calling UI_DEV_SETUP and UI_DEV_CREATE - * for every absolute axis the device exports. - * This ioctl supersedes the old "struct uinput_user_dev" method, which wrote + * created. It supersedes the old "struct uinput_user_dev" method, which wrote * part of this data and the content of UI_DEV_SETUP via write(). * - * This ioctl takes a "struct uinput_abs_setup" object as argument. The fields + * The ioctl takes a "struct uinput_abs_setup" object as argument. The fields * of this object are as follows: * code: The corresponding input code associated with this axis * (ABS_X, ABS_Y, etc...) @@ -124,9 +121,9 @@ struct uinput_abs_setup { * UI_SET_ABSBIT, this ioctl will enable it. * * This ioctl can be called multiple times and will overwrite previous values. - * If this ioctl fails with -EINVAL, you're recommended to use the old - * "uinput_user_dev" method via write() as fallback, in case you run on an old - * kernel that does not support this ioctl. + * If this ioctl fails with -EINVAL, it is recommended to use the old + * "uinput_user_dev" method via write() as a fallback, in case you run on an + * old kernel that does not support this ioctl. * * This ioctl may fail with -EINVAL if it is not supported or if you passed * incorrect values, -ENOMEM if the kernel runs out of memory or -EFAULT if the -- cgit v1.2.3 From 1873315fb156cbc8e46f28e8b128f17ff6c31728 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 8 Dec 2015 16:38:12 +0100 Subject: mtd: sh_flctl: pass FIFO as physical address By convention, the FIFO address we pass using dmaengine_slave_config is a physical address in the form that is understood by the DMA engine, as a dma_addr_t, phys_addr_t or resource_size_t. The sh_flctl driver however passes a virtual __iomem address that gets cast to dma_addr_t in the slave driver. This happens to work on shmobile because that platform sets up an identity mapping for its MMIO regions, but such code is not portable to other platforms, and prevents us from ever changing the platform mapping or reusing the driver on other architectures like ARM64 that might not have the mapping. We also get a warning about a type mismatch for the case that dma_addr_t is wider than a pointer, i.e. when CONFIG_LPAE is set: drivers/mtd/nand/sh_flctl.c: In function 'flctl_setup_dma': drivers/mtd/nand/sh_flctl.c:163:17: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] cfg.dst_addr = (dma_addr_t)FLDTFIFO(flctl); This changes the driver to instead pass the physical address of the FIFO that is extracted from the MMIO resource, making the code more portable and avoiding the warning. Signed-off-by: Arnd Bergmann Signed-off-by: Brian Norris --- include/linux/mtd/sh_flctl.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h index 76e3e88bedfe..2251add65fa7 100644 --- a/include/linux/mtd/sh_flctl.h +++ b/include/linux/mtd/sh_flctl.h @@ -147,6 +147,7 @@ struct sh_flctl { struct platform_device *pdev; struct dev_pm_qos_request pm_qos; void __iomem *reg; + resource_size_t fifo; uint8_t done_buff[2048 + 64]; /* max size 2048 + 64 */ int read_bytes; -- cgit v1.2.3 From 3b91d09c1ca69a69c470efe5fbf346e3e90181d5 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Wed, 9 Dec 2015 11:12:03 -0800 Subject: scsi_transport_sas: add is_sas_attached() function Adds a function designed to be callable any time (regardless of whether the transport attributes are configured or not) which returns true if the device is attached over a SAS transport. The design of this function is that transport specific functions can be embedded within a if (is_sas_attached(sdev)) { ... } which would be compiled out (and thus eliminate the symbols) if SAS is not configured. Reviewed-by: Hannes Reinecke Signed-off-by: James Bottomley --- include/scsi/scsi_transport_sas.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include') diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h index 0bd71e2702e3..a8fdd10fc9c5 100644 --- a/include/scsi/scsi_transport_sas.h +++ b/include/scsi/scsi_transport_sas.h @@ -10,6 +10,15 @@ struct scsi_transport_template; struct sas_rphy; struct request; +#if !IS_ENABLED(CONFIG_SCSI_SAS_ATTRS) +static inline int is_sas_attached(struct scsi_device *sdev) +{ + return 0; +} +#else +extern int is_sas_attached(struct scsi_device *sdev); +#endif + static inline int sas_protocol_ata(enum sas_protocol proto) { return ((proto & SAS_PROTOCOL_SATA) || -- cgit v1.2.3 From bcf508c13385e74972f5cc06d8471d5c100395b0 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Wed, 9 Dec 2015 11:13:35 -0800 Subject: scsi_transport_sas: add function to get SAS endpoint address For a device known to be SAS connected, this will return the endpoint address. This is useful for getting the SAS address of SATA devices. Reviewed-by: Hannes Reinecke Signed-off-by: James Bottomley --- include/scsi/scsi_transport_sas.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h index a8fdd10fc9c5..13c0b2ba1b6c 100644 --- a/include/scsi/scsi_transport_sas.h +++ b/include/scsi/scsi_transport_sas.h @@ -189,6 +189,7 @@ extern int sas_phy_add(struct sas_phy *); extern void sas_phy_delete(struct sas_phy *); extern int scsi_is_sas_phy(const struct device *); +u64 sas_get_address(struct scsi_device *); unsigned int sas_tlr_supported(struct scsi_device *); unsigned int sas_is_tlr_enabled(struct scsi_device *); void sas_disable_tlr(struct scsi_device *); -- cgit v1.2.3 From 9955a7835bf376e12482583958b2661f501b868b Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Mon, 21 Dec 2015 14:24:13 +0530 Subject: phy: omap-usb2: use *syscon* framework API to power on/off the PHY Deprecate using phy-omap-control driver to power on/off the PHY, and use *syscon* framework to do the same. This handles powering on/off the PHY for the USB2 PHYs used in various TI SoCs. Signed-off-by: Kishon Vijay Abraham I --- include/linux/phy/omap_usb.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'include') diff --git a/include/linux/phy/omap_usb.h b/include/linux/phy/omap_usb.h index dc2c541a619b..2e5fb870efa9 100644 --- a/include/linux/phy/omap_usb.h +++ b/include/linux/phy/omap_usb.h @@ -30,6 +30,12 @@ struct usb_dpll_params { u32 mf; }; +enum omap_usb_phy_type { + TYPE_USB2, /* USB2_PHY, power down in CONTROL_DEV_CONF */ + TYPE_DRA7USB2, /* USB2 PHY, power and power_aux e.g. DRA7 */ + TYPE_AM437USB2, /* USB2 PHY, power e.g. AM437x */ +}; + struct omap_usb { struct usb_phy phy; struct phy_companion *comparator; @@ -40,11 +46,20 @@ struct omap_usb { struct clk *wkupclk; struct clk *optclk; u8 flags; + enum omap_usb_phy_type type; + struct regmap *syscon_phy_power; /* ctrl. reg. acces */ + unsigned int power_reg; /* power reg. index within syscon */ + u32 mask; + u32 power_on; + u32 power_off; }; struct usb_phy_data { const char *label; u8 flags; + u32 mask; + u32 power_on; + u32 power_off; }; /* Driver Flags */ @@ -52,6 +67,14 @@ struct usb_phy_data { #define OMAP_USB2_HAS_SET_VBUS (1 << 1) #define OMAP_USB2_CALIBRATE_FALSE_DISCONNECT (1 << 2) +#define OMAP_DEV_PHY_PD BIT(0) +#define OMAP_USB2_PHY_PD BIT(28) + +#define AM437X_USB2_PHY_PD BIT(0) +#define AM437X_USB2_OTG_PD BIT(1) +#define AM437X_USB2_OTGVDET_EN BIT(19) +#define AM437X_USB2_OTGSESSEND_EN BIT(20) + #define phy_to_omapusb(x) container_of((x), struct omap_usb, phy) #if defined(CONFIG_OMAP_USB2) || defined(CONFIG_OMAP_USB2_MODULE) -- cgit v1.2.3 From 2048157ad02e65f6327118dd4a7b9c9f1fd12f77 Mon Sep 17 00:00:00 2001 From: Dexuan Cui Date: Mon, 21 Dec 2015 12:21:22 -0800 Subject: Drivers: hv: vmbus: fix the building warning with hyperv-keyboard With the recent change af3ff643ea91ba64dd8d0b1cbed54d44512f96cd (Drivers: hv: vmbus: Use uuid_le type consistently), we always get this warning: CC [M] drivers/input/serio/hyperv-keyboard.o drivers/input/serio/hyperv-keyboard.c:427:2: warning: missing braces around initializer [-Wmissing-braces] { HV_KBD_GUID, }, ^ drivers/input/serio/hyperv-keyboard.c:427:2: warning: (near initialization for .id_table[0].guid.b.) [-Wmissing-braces] The patch fixes the warning. Signed-off-by: Dexuan Cui Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- include/linux/hyperv.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 179ff330af59..753dbad0bf94 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1078,6 +1078,14 @@ u64 hv_do_hypercall(u64 control, void *input, void *output); .guid = UUID_LE(0xcfa8b69e, 0x5b4a, 0x4cc0, 0xb9, 0x8b, \ 0x8b, 0xa1, 0xa1, 0xf3, 0xf9, 0x5a) +/* + * Keyboard GUID + * {f912ad6d-2b17-48ea-bd65-f927a61c7684} + */ +#define HV_KBD_GUID \ + .guid = UUID_LE(0xf912ad6d, 0x2b17, 0x48ea, 0xbd, 0x65, \ + 0xf9, 0x27, 0xa6, 0x1c, 0x76, 0x84) + /* * VSS (Backup/Restore) GUID */ -- cgit v1.2.3 From cd371e0959a3f2d5df69d50000750f7eefc94659 Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Mon, 16 Nov 2015 21:59:35 -0500 Subject: staging/rdma/hfi1: Adjust EPROM partitions, add EPROM commands Add a new EPROM partition, adjusting partition placement. Add EPROM range commands as a supserset of the partition commands. Remove old partition commands. Enhance EPROM erase, creating a range function and using the largest erase (sub) commands when possible. Reviewed-by: Dennis Dalessandro Signed-off-by: Dean Luick Signed-off-by: Jubin John Signed-off-by: Greg Kroah-Hartman --- include/uapi/rdma/hfi/hfi1_user.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/uapi/rdma/hfi/hfi1_user.h b/include/uapi/rdma/hfi/hfi1_user.h index a2fc6cbfe414..288694e422fb 100644 --- a/include/uapi/rdma/hfi/hfi1_user.h +++ b/include/uapi/rdma/hfi/hfi1_user.h @@ -137,12 +137,10 @@ /* separate EPROM commands from normal PSM commands */ #define HFI1_CMD_EP_INFO 64 /* read EPROM device ID */ #define HFI1_CMD_EP_ERASE_CHIP 65 /* erase whole EPROM */ -#define HFI1_CMD_EP_ERASE_P0 66 /* erase EPROM partition 0 */ -#define HFI1_CMD_EP_ERASE_P1 67 /* erase EPROM partition 1 */ -#define HFI1_CMD_EP_READ_P0 68 /* read EPROM partition 0 */ -#define HFI1_CMD_EP_READ_P1 69 /* read EPROM partition 1 */ -#define HFI1_CMD_EP_WRITE_P0 70 /* write EPROM partition 0 */ -#define HFI1_CMD_EP_WRITE_P1 71 /* write EPROM partition 1 */ +/* range 66-74 no longer used */ +#define HFI1_CMD_EP_ERASE_RANGE 75 /* erase EPROM range */ +#define HFI1_CMD_EP_READ_RANGE 76 /* read EPROM range */ +#define HFI1_CMD_EP_WRITE_RANGE 77 /* write EPROM range */ #define _HFI1_EVENT_FROZEN_BIT 0 #define _HFI1_EVENT_LINKDOWN_BIT 1 -- cgit v1.2.3 From 77d6bd47cc2824af016086c2bd4650685b159e22 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Fri, 18 Dec 2015 12:35:47 +1100 Subject: vfio: Add explicit alignments in vfio_iommu_spapr_tce_create The vfio_iommu_spapr_tce_create struct has 4x32bit and 2x64bit fields which should have resulted in sizeof(fio_iommu_spapr_tce_create) equal to 32 bytes. However due to the gcc's default alignment, the actual size of this struct is 40 bytes. This fills gaps with __resv1/2 fields. This should not cause any change in behavior. Signed-off-by: Alexey Kardashevskiy Acked-by: David Gibson Signed-off-by: Alex Williamson --- include/uapi/linux/vfio.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h index 9fd7b5d8df2f..d1172331ca62 100644 --- a/include/uapi/linux/vfio.h +++ b/include/uapi/linux/vfio.h @@ -568,8 +568,10 @@ struct vfio_iommu_spapr_tce_create { __u32 flags; /* in */ __u32 page_shift; + __u32 __resv1; __u64 window_size; __u32 levels; + __u32 __resv2; /* out */ __u64 start_addr; }; -- cgit v1.2.3 From 03a76b60f8ba27974e2d252bc555d2c103420e15 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Mon, 21 Dec 2015 15:13:33 -0700 Subject: vfio: Include No-IOMMU mode There is really no way to safely give a user full access to a DMA capable device without an IOMMU to protect the host system. There is also no way to provide DMA translation, for use cases such as device assignment to virtual machines. However, there are still those users that want userspace drivers even under those conditions. The UIO driver exists for this use case, but does not provide the degree of device access and programming that VFIO has. In an effort to avoid code duplication, this introduces a No-IOMMU mode for VFIO. This mode requires building VFIO with CONFIG_VFIO_NOIOMMU and enabling the "enable_unsafe_noiommu_mode" option on the vfio driver. This should make it very clear that this mode is not safe. Additionally, CAP_SYS_RAWIO privileges are necessary to work with groups and containers using this mode. Groups making use of this support are named /dev/vfio/noiommu-$GROUP and can only make use of the special VFIO_NOIOMMU_IOMMU for the container. Use of this mode, specifically binding a device without a native IOMMU group to a VFIO bus driver will taint the kernel and should therefore not be considered supported. This patch includes no-iommu support for the vfio-pci bus driver only. Signed-off-by: Alex Williamson Acked-by: Michael S. Tsirkin --- include/linux/vfio.h | 3 +++ include/uapi/linux/vfio.h | 7 +++++++ 2 files changed, 10 insertions(+) (limited to 'include') diff --git a/include/linux/vfio.h b/include/linux/vfio.h index ddb440975382..610a86a892b8 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -44,6 +44,9 @@ struct vfio_device_ops { void (*request)(void *device_data, unsigned int count); }; +extern struct iommu_group *vfio_iommu_group_get(struct device *dev); +extern void vfio_iommu_group_put(struct iommu_group *group, struct device *dev); + extern int vfio_add_group_dev(struct device *dev, const struct vfio_device_ops *ops, void *device_data); diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h index d1172331ca62..7d7a4c6f2090 100644 --- a/include/uapi/linux/vfio.h +++ b/include/uapi/linux/vfio.h @@ -38,6 +38,13 @@ #define VFIO_SPAPR_TCE_v2_IOMMU 7 +/* + * The No-IOMMU IOMMU offers no translation or isolation for devices and + * supports no ioctls outside of VFIO_CHECK_EXTENSION. Use of VFIO's No-IOMMU + * code will taint the host kernel and should be used with extreme caution. + */ +#define VFIO_NOIOMMU_IOMMU 8 + /* * The IOCTL interface is designed for extensibility by embedding the * structure length (argsz) and flags into structures passed between -- cgit v1.2.3 From 7d2c2acac577959dbbddefefa91d1ba1b80460b3 Mon Sep 17 00:00:00 2001 From: "Andrew F. Davis" Date: Mon, 14 Dec 2015 16:35:57 -0600 Subject: iio: Make IIO value formating function globally available. Make IIO value formating function globally available to allow IIO drivers to output values as the core does. Signed-off-by: Andrew F. Davis Signed-off-by: Jonathan Cameron --- include/linux/iio/iio.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 19c94c9acc81..b5894118755f 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -636,6 +636,8 @@ static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev) } #endif +ssize_t iio_format_value(char *buf, unsigned int type, int size, int *vals); + int iio_str_to_fixpoint(const char *str, int fract_mult, int *integer, int *fract); -- cgit v1.2.3 From 8a0859b65b06ea07461271ce4f1fe25b48d1ec55 Mon Sep 17 00:00:00 2001 From: "Du, Changbin" Date: Fri, 18 Dec 2015 15:36:40 +0800 Subject: usb: gadget: forbid queuing request to a disabled ep Queue a request to disabled ep doesn't make sense, and induce caller make mistakes. Here is a example for the android mtp gadget function driver. A mem corruption can happen on below senario. 1) On disconnect, mtp driver disable its EPs, 2) During send_file_work and receive_file_work, mtp queues a request to ep. (The mtp driver need improve its synchronization logic!) 3) mtp_function_unbind is invoked and all mtp requests are freed. 4) when udc process the request queued on step 2, will cause kernel NULL pointer dereference exception. Signed-off-by: Du, Changbin Signed-off-by: Felipe Balbi --- include/linux/usb/gadget.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 92467eea76de..d82d0068872b 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -402,6 +402,9 @@ static inline void usb_ep_free_request(struct usb_ep *ep, static inline int usb_ep_queue(struct usb_ep *ep, struct usb_request *req, gfp_t gfp_flags) { + if (WARN_ON_ONCE(!ep->enabled && ep->address)) + return -ESHUTDOWN; + return ep->ops->queue(ep, req, gfp_flags); } -- cgit v1.2.3 From de2dd0eb30af55d3893979d5641c50c7a8969c99 Mon Sep 17 00:00:00 2001 From: Zhao Qiang Date: Mon, 30 Nov 2015 10:48:52 +0800 Subject: genalloc:support memory-allocation with bytes-alignment to genalloc Bytes alignment is required to manage some special RAM, so add gen_pool_first_fit_align to genalloc, meanwhile add gen_pool_alloc_algo to pass algo in case user layer using more than one algo, and pass data to gen_pool_first_fit_align(modify gen_pool_alloc as a wrapper) Signed-off-by: Zhao Qiang Signed-off-by: Scott Wood --- include/linux/genalloc.h | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index 7ff168d06967..3c676ce46ee0 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -30,10 +30,12 @@ #ifndef __GENALLOC_H__ #define __GENALLOC_H__ +#include #include struct device; struct device_node; +struct gen_pool; /** * Allocation callback function type definition @@ -47,7 +49,7 @@ typedef unsigned long (*genpool_algo_t)(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, - void *data); + void *data, struct gen_pool *pool); /* * General purpose special memory pool descriptor. @@ -75,6 +77,13 @@ struct gen_pool_chunk { unsigned long bits[0]; /* bitmap for allocating memory chunk */ }; +/* + * gen_pool data descriptor for gen_pool_first_fit_align. + */ +struct genpool_data_align { + int align; /* alignment by bytes for starting address */ +}; + extern struct gen_pool *gen_pool_create(int, int); extern phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long); extern int gen_pool_add_virt(struct gen_pool *, unsigned long, phys_addr_t, @@ -98,6 +107,8 @@ static inline int gen_pool_add(struct gen_pool *pool, unsigned long addr, } extern void gen_pool_destroy(struct gen_pool *); extern unsigned long gen_pool_alloc(struct gen_pool *, size_t); +extern unsigned long gen_pool_alloc_algo(struct gen_pool *, size_t, + genpool_algo_t algo, void *data); extern void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size, dma_addr_t *dma); extern void gen_pool_free(struct gen_pool *, unsigned long, size_t); @@ -110,14 +121,22 @@ extern void gen_pool_set_algo(struct gen_pool *pool, genpool_algo_t algo, void *data); extern unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size, - unsigned long start, unsigned int nr, void *data); + unsigned long start, unsigned int nr, void *data, + struct gen_pool *pool); + +extern unsigned long gen_pool_first_fit_align(unsigned long *map, + unsigned long size, unsigned long start, unsigned int nr, + void *data, struct gen_pool *pool); + extern unsigned long gen_pool_first_fit_order_align(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, - void *data); + void *data, struct gen_pool *pool); extern unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size, - unsigned long start, unsigned int nr, void *data); + unsigned long start, unsigned int nr, void *data, + struct gen_pool *pool); + extern struct gen_pool *devm_gen_pool_create(struct device *dev, int min_alloc_order, int nid, const char *name); -- cgit v1.2.3 From b26981c8f743d3cb64a6907eb1f5c6c4ba6ca672 Mon Sep 17 00:00:00 2001 From: Zhao Qiang Date: Mon, 30 Nov 2015 10:48:53 +0800 Subject: genalloc:support allocating specific region Add new algo for genalloc, it reserve a specific region of memory Signed-off-by: Zhao Qiang Signed-off-by: Scott Wood --- include/linux/genalloc.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include') diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index 3c676ce46ee0..29d4385903d4 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -84,6 +84,13 @@ struct genpool_data_align { int align; /* alignment by bytes for starting address */ }; +/* + * gen_pool data descriptor for gen_pool_fixed_alloc. + */ +struct genpool_data_fixed { + unsigned long offset; /* The offset of the specific region */ +}; + extern struct gen_pool *gen_pool_create(int, int); extern phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long); extern int gen_pool_add_virt(struct gen_pool *, unsigned long, phys_addr_t, @@ -124,6 +131,10 @@ extern unsigned long gen_pool_first_fit(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, void *data, struct gen_pool *pool); +extern unsigned long gen_pool_fixed_alloc(unsigned long *map, + unsigned long size, unsigned long start, unsigned int nr, + void *data, struct gen_pool *pool); + extern unsigned long gen_pool_first_fit_align(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, void *data, struct gen_pool *pool); -- cgit v1.2.3 From 7aa1aa6ecec2af19d9aa85430ce3e56119e21626 Mon Sep 17 00:00:00 2001 From: Zhao Qiang Date: Mon, 30 Nov 2015 10:48:57 +0800 Subject: QE: Move QE from arch/powerpc to drivers/soc ls1 has qe and ls1 has arm cpu. move qe from arch/powerpc to drivers/soc/fsl to adapt to powerpc and arm Signed-off-by: Zhao Qiang Signed-off-by: Scott Wood --- include/soc/fsl/qe/immap_qe.h | 491 ++++++++++++++++++++++++++ include/soc/fsl/qe/qe.h | 790 ++++++++++++++++++++++++++++++++++++++++++ include/soc/fsl/qe/qe_ic.h | 139 ++++++++ include/soc/fsl/qe/ucc.h | 64 ++++ include/soc/fsl/qe/ucc_fast.h | 244 +++++++++++++ include/soc/fsl/qe/ucc_slow.h | 277 +++++++++++++++ 6 files changed, 2005 insertions(+) create mode 100644 include/soc/fsl/qe/immap_qe.h create mode 100644 include/soc/fsl/qe/qe.h create mode 100644 include/soc/fsl/qe/qe_ic.h create mode 100644 include/soc/fsl/qe/ucc.h create mode 100644 include/soc/fsl/qe/ucc_fast.h create mode 100644 include/soc/fsl/qe/ucc_slow.h (limited to 'include') diff --git a/include/soc/fsl/qe/immap_qe.h b/include/soc/fsl/qe/immap_qe.h new file mode 100644 index 000000000000..bedbff891423 --- /dev/null +++ b/include/soc/fsl/qe/immap_qe.h @@ -0,0 +1,491 @@ +/* + * QUICC Engine (QE) Internal Memory Map. + * The Internal Memory Map for devices with QE on them. This + * is the superset of all QE devices (8360, etc.). + + * Copyright (C) 2006. Freescale Semiconductor, Inc. All rights reserved. + * + * Authors: Shlomi Gridish + * Li Yang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef _ASM_POWERPC_IMMAP_QE_H +#define _ASM_POWERPC_IMMAP_QE_H +#ifdef __KERNEL__ + +#include +#include + +#define QE_IMMAP_SIZE (1024 * 1024) /* 1MB from 1MB+IMMR */ + +/* QE I-RAM */ +struct qe_iram { + __be32 iadd; /* I-RAM Address Register */ + __be32 idata; /* I-RAM Data Register */ + u8 res0[0x04]; + __be32 iready; /* I-RAM Ready Register */ + u8 res1[0x70]; +} __attribute__ ((packed)); + +/* QE Interrupt Controller */ +struct qe_ic_regs { + __be32 qicr; + __be32 qivec; + __be32 qripnr; + __be32 qipnr; + __be32 qipxcc; + __be32 qipycc; + __be32 qipwcc; + __be32 qipzcc; + __be32 qimr; + __be32 qrimr; + __be32 qicnr; + u8 res0[0x4]; + __be32 qiprta; + __be32 qiprtb; + u8 res1[0x4]; + __be32 qricr; + u8 res2[0x20]; + __be32 qhivec; + u8 res3[0x1C]; +} __attribute__ ((packed)); + +/* Communications Processor */ +struct cp_qe { + __be32 cecr; /* QE command register */ + __be32 ceccr; /* QE controller configuration register */ + __be32 cecdr; /* QE command data register */ + u8 res0[0xA]; + __be16 ceter; /* QE timer event register */ + u8 res1[0x2]; + __be16 cetmr; /* QE timers mask register */ + __be32 cetscr; /* QE time-stamp timer control register */ + __be32 cetsr1; /* QE time-stamp register 1 */ + __be32 cetsr2; /* QE time-stamp register 2 */ + u8 res2[0x8]; + __be32 cevter; /* QE virtual tasks event register */ + __be32 cevtmr; /* QE virtual tasks mask register */ + __be16 cercr; /* QE RAM control register */ + u8 res3[0x2]; + u8 res4[0x24]; + __be16 ceexe1; /* QE external request 1 event register */ + u8 res5[0x2]; + __be16 ceexm1; /* QE external request 1 mask register */ + u8 res6[0x2]; + __be16 ceexe2; /* QE external request 2 event register */ + u8 res7[0x2]; + __be16 ceexm2; /* QE external request 2 mask register */ + u8 res8[0x2]; + __be16 ceexe3; /* QE external request 3 event register */ + u8 res9[0x2]; + __be16 ceexm3; /* QE external request 3 mask register */ + u8 res10[0x2]; + __be16 ceexe4; /* QE external request 4 event register */ + u8 res11[0x2]; + __be16 ceexm4; /* QE external request 4 mask register */ + u8 res12[0x3A]; + __be32 ceurnr; /* QE microcode revision number register */ + u8 res13[0x244]; +} __attribute__ ((packed)); + +/* QE Multiplexer */ +struct qe_mux { + __be32 cmxgcr; /* CMX general clock route register */ + __be32 cmxsi1cr_l; /* CMX SI1 clock route low register */ + __be32 cmxsi1cr_h; /* CMX SI1 clock route high register */ + __be32 cmxsi1syr; /* CMX SI1 SYNC route register */ + __be32 cmxucr[4]; /* CMX UCCx clock route registers */ + __be32 cmxupcr; /* CMX UPC clock route register */ + u8 res0[0x1C]; +} __attribute__ ((packed)); + +/* QE Timers */ +struct qe_timers { + u8 gtcfr1; /* Timer 1 and Timer 2 global config register*/ + u8 res0[0x3]; + u8 gtcfr2; /* Timer 3 and timer 4 global config register*/ + u8 res1[0xB]; + __be16 gtmdr1; /* Timer 1 mode register */ + __be16 gtmdr2; /* Timer 2 mode register */ + __be16 gtrfr1; /* Timer 1 reference register */ + __be16 gtrfr2; /* Timer 2 reference register */ + __be16 gtcpr1; /* Timer 1 capture register */ + __be16 gtcpr2; /* Timer 2 capture register */ + __be16 gtcnr1; /* Timer 1 counter */ + __be16 gtcnr2; /* Timer 2 counter */ + __be16 gtmdr3; /* Timer 3 mode register */ + __be16 gtmdr4; /* Timer 4 mode register */ + __be16 gtrfr3; /* Timer 3 reference register */ + __be16 gtrfr4; /* Timer 4 reference register */ + __be16 gtcpr3; /* Timer 3 capture register */ + __be16 gtcpr4; /* Timer 4 capture register */ + __be16 gtcnr3; /* Timer 3 counter */ + __be16 gtcnr4; /* Timer 4 counter */ + __be16 gtevr1; /* Timer 1 event register */ + __be16 gtevr2; /* Timer 2 event register */ + __be16 gtevr3; /* Timer 3 event register */ + __be16 gtevr4; /* Timer 4 event register */ + __be16 gtps; /* Timer 1 prescale register */ + u8 res2[0x46]; +} __attribute__ ((packed)); + +/* BRG */ +struct qe_brg { + __be32 brgc[16]; /* BRG configuration registers */ + u8 res0[0x40]; +} __attribute__ ((packed)); + +/* SPI */ +struct spi { + u8 res0[0x20]; + __be32 spmode; /* SPI mode register */ + u8 res1[0x2]; + u8 spie; /* SPI event register */ + u8 res2[0x1]; + u8 res3[0x2]; + u8 spim; /* SPI mask register */ + u8 res4[0x1]; + u8 res5[0x1]; + u8 spcom; /* SPI command register */ + u8 res6[0x2]; + __be32 spitd; /* SPI transmit data register (cpu mode) */ + __be32 spird; /* SPI receive data register (cpu mode) */ + u8 res7[0x8]; +} __attribute__ ((packed)); + +/* SI */ +struct si1 { + __be16 siamr1; /* SI1 TDMA mode register */ + __be16 sibmr1; /* SI1 TDMB mode register */ + __be16 sicmr1; /* SI1 TDMC mode register */ + __be16 sidmr1; /* SI1 TDMD mode register */ + u8 siglmr1_h; /* SI1 global mode register high */ + u8 res0[0x1]; + u8 sicmdr1_h; /* SI1 command register high */ + u8 res2[0x1]; + u8 sistr1_h; /* SI1 status register high */ + u8 res3[0x1]; + __be16 sirsr1_h; /* SI1 RAM shadow address register high */ + u8 sitarc1; /* SI1 RAM counter Tx TDMA */ + u8 sitbrc1; /* SI1 RAM counter Tx TDMB */ + u8 sitcrc1; /* SI1 RAM counter Tx TDMC */ + u8 sitdrc1; /* SI1 RAM counter Tx TDMD */ + u8 sirarc1; /* SI1 RAM counter Rx TDMA */ + u8 sirbrc1; /* SI1 RAM counter Rx TDMB */ + u8 sircrc1; /* SI1 RAM counter Rx TDMC */ + u8 sirdrc1; /* SI1 RAM counter Rx TDMD */ + u8 res4[0x8]; + __be16 siemr1; /* SI1 TDME mode register 16 bits */ + __be16 sifmr1; /* SI1 TDMF mode register 16 bits */ + __be16 sigmr1; /* SI1 TDMG mode register 16 bits */ + __be16 sihmr1; /* SI1 TDMH mode register 16 bits */ + u8 siglmg1_l; /* SI1 global mode register low 8 bits */ + u8 res5[0x1]; + u8 sicmdr1_l; /* SI1 command register low 8 bits */ + u8 res6[0x1]; + u8 sistr1_l; /* SI1 status register low 8 bits */ + u8 res7[0x1]; + __be16 sirsr1_l; /* SI1 RAM shadow address register low 16 bits*/ + u8 siterc1; /* SI1 RAM counter Tx TDME 8 bits */ + u8 sitfrc1; /* SI1 RAM counter Tx TDMF 8 bits */ + u8 sitgrc1; /* SI1 RAM counter Tx TDMG 8 bits */ + u8 sithrc1; /* SI1 RAM counter Tx TDMH 8 bits */ + u8 sirerc1; /* SI1 RAM counter Rx TDME 8 bits */ + u8 sirfrc1; /* SI1 RAM counter Rx TDMF 8 bits */ + u8 sirgrc1; /* SI1 RAM counter Rx TDMG 8 bits */ + u8 sirhrc1; /* SI1 RAM counter Rx TDMH 8 bits */ + u8 res8[0x8]; + __be32 siml1; /* SI1 multiframe limit register */ + u8 siedm1; /* SI1 extended diagnostic mode register */ + u8 res9[0xBB]; +} __attribute__ ((packed)); + +/* SI Routing Tables */ +struct sir { + u8 tx[0x400]; + u8 rx[0x400]; + u8 res0[0x800]; +} __attribute__ ((packed)); + +/* USB Controller */ +struct qe_usb_ctlr { + u8 usb_usmod; + u8 usb_usadr; + u8 usb_uscom; + u8 res1[1]; + __be16 usb_usep[4]; + u8 res2[4]; + __be16 usb_usber; + u8 res3[2]; + __be16 usb_usbmr; + u8 res4[1]; + u8 usb_usbs; + __be16 usb_ussft; + u8 res5[2]; + __be16 usb_usfrn; + u8 res6[0x22]; +} __attribute__ ((packed)); + +/* MCC */ +struct qe_mcc { + __be32 mcce; /* MCC event register */ + __be32 mccm; /* MCC mask register */ + __be32 mccf; /* MCC configuration register */ + __be32 merl; /* MCC emergency request level register */ + u8 res0[0xF0]; +} __attribute__ ((packed)); + +/* QE UCC Slow */ +struct ucc_slow { + __be32 gumr_l; /* UCCx general mode register (low) */ + __be32 gumr_h; /* UCCx general mode register (high) */ + __be16 upsmr; /* UCCx protocol-specific mode register */ + u8 res0[0x2]; + __be16 utodr; /* UCCx transmit on demand register */ + __be16 udsr; /* UCCx data synchronization register */ + __be16 ucce; /* UCCx event register */ + u8 res1[0x2]; + __be16 uccm; /* UCCx mask register */ + u8 res2[0x1]; + u8 uccs; /* UCCx status register */ + u8 res3[0x24]; + __be16 utpt; + u8 res4[0x52]; + u8 guemr; /* UCC general extended mode register */ +} __attribute__ ((packed)); + +/* QE UCC Fast */ +struct ucc_fast { + __be32 gumr; /* UCCx general mode register */ + __be32 upsmr; /* UCCx protocol-specific mode register */ + __be16 utodr; /* UCCx transmit on demand register */ + u8 res0[0x2]; + __be16 udsr; /* UCCx data synchronization register */ + u8 res1[0x2]; + __be32 ucce; /* UCCx event register */ + __be32 uccm; /* UCCx mask register */ + u8 uccs; /* UCCx status register */ + u8 res2[0x7]; + __be32 urfb; /* UCC receive FIFO base */ + __be16 urfs; /* UCC receive FIFO size */ + u8 res3[0x2]; + __be16 urfet; /* UCC receive FIFO emergency threshold */ + __be16 urfset; /* UCC receive FIFO special emergency + threshold */ + __be32 utfb; /* UCC transmit FIFO base */ + __be16 utfs; /* UCC transmit FIFO size */ + u8 res4[0x2]; + __be16 utfet; /* UCC transmit FIFO emergency threshold */ + u8 res5[0x2]; + __be16 utftt; /* UCC transmit FIFO transmit threshold */ + u8 res6[0x2]; + __be16 utpt; /* UCC transmit polling timer */ + u8 res7[0x2]; + __be32 urtry; /* UCC retry counter register */ + u8 res8[0x4C]; + u8 guemr; /* UCC general extended mode register */ +} __attribute__ ((packed)); + +struct ucc { + union { + struct ucc_slow slow; + struct ucc_fast fast; + u8 res[0x200]; /* UCC blocks are 512 bytes each */ + }; +} __attribute__ ((packed)); + +/* MultiPHY UTOPIA POS Controllers (UPC) */ +struct upc { + __be32 upgcr; /* UTOPIA/POS general configuration register */ + __be32 uplpa; /* UTOPIA/POS last PHY address */ + __be32 uphec; /* ATM HEC register */ + __be32 upuc; /* UTOPIA/POS UCC configuration */ + __be32 updc1; /* UTOPIA/POS device 1 configuration */ + __be32 updc2; /* UTOPIA/POS device 2 configuration */ + __be32 updc3; /* UTOPIA/POS device 3 configuration */ + __be32 updc4; /* UTOPIA/POS device 4 configuration */ + __be32 upstpa; /* UTOPIA/POS STPA threshold */ + u8 res0[0xC]; + __be32 updrs1_h; /* UTOPIA/POS device 1 rate select */ + __be32 updrs1_l; /* UTOPIA/POS device 1 rate select */ + __be32 updrs2_h; /* UTOPIA/POS device 2 rate select */ + __be32 updrs2_l; /* UTOPIA/POS device 2 rate select */ + __be32 updrs3_h; /* UTOPIA/POS device 3 rate select */ + __be32 updrs3_l; /* UTOPIA/POS device 3 rate select */ + __be32 updrs4_h; /* UTOPIA/POS device 4 rate select */ + __be32 updrs4_l; /* UTOPIA/POS device 4 rate select */ + __be32 updrp1; /* UTOPIA/POS device 1 receive priority low */ + __be32 updrp2; /* UTOPIA/POS device 2 receive priority low */ + __be32 updrp3; /* UTOPIA/POS device 3 receive priority low */ + __be32 updrp4; /* UTOPIA/POS device 4 receive priority low */ + __be32 upde1; /* UTOPIA/POS device 1 event */ + __be32 upde2; /* UTOPIA/POS device 2 event */ + __be32 upde3; /* UTOPIA/POS device 3 event */ + __be32 upde4; /* UTOPIA/POS device 4 event */ + __be16 uprp1; + __be16 uprp2; + __be16 uprp3; + __be16 uprp4; + u8 res1[0x8]; + __be16 uptirr1_0; /* Device 1 transmit internal rate 0 */ + __be16 uptirr1_1; /* Device 1 transmit internal rate 1 */ + __be16 uptirr1_2; /* Device 1 transmit internal rate 2 */ + __be16 uptirr1_3; /* Device 1 transmit internal rate 3 */ + __be16 uptirr2_0; /* Device 2 transmit internal rate 0 */ + __be16 uptirr2_1; /* Device 2 transmit internal rate 1 */ + __be16 uptirr2_2; /* Device 2 transmit internal rate 2 */ + __be16 uptirr2_3; /* Device 2 transmit internal rate 3 */ + __be16 uptirr3_0; /* Device 3 transmit internal rate 0 */ + __be16 uptirr3_1; /* Device 3 transmit internal rate 1 */ + __be16 uptirr3_2; /* Device 3 transmit internal rate 2 */ + __be16 uptirr3_3; /* Device 3 transmit internal rate 3 */ + __be16 uptirr4_0; /* Device 4 transmit internal rate 0 */ + __be16 uptirr4_1; /* Device 4 transmit internal rate 1 */ + __be16 uptirr4_2; /* Device 4 transmit internal rate 2 */ + __be16 uptirr4_3; /* Device 4 transmit internal rate 3 */ + __be32 uper1; /* Device 1 port enable register */ + __be32 uper2; /* Device 2 port enable register */ + __be32 uper3; /* Device 3 port enable register */ + __be32 uper4; /* Device 4 port enable register */ + u8 res2[0x150]; +} __attribute__ ((packed)); + +/* SDMA */ +struct sdma { + __be32 sdsr; /* Serial DMA status register */ + __be32 sdmr; /* Serial DMA mode register */ + __be32 sdtr1; /* SDMA system bus threshold register */ + __be32 sdtr2; /* SDMA secondary bus threshold register */ + __be32 sdhy1; /* SDMA system bus hysteresis register */ + __be32 sdhy2; /* SDMA secondary bus hysteresis register */ + __be32 sdta1; /* SDMA system bus address register */ + __be32 sdta2; /* SDMA secondary bus address register */ + __be32 sdtm1; /* SDMA system bus MSNUM register */ + __be32 sdtm2; /* SDMA secondary bus MSNUM register */ + u8 res0[0x10]; + __be32 sdaqr; /* SDMA address bus qualify register */ + __be32 sdaqmr; /* SDMA address bus qualify mask register */ + u8 res1[0x4]; + __be32 sdebcr; /* SDMA CAM entries base register */ + u8 res2[0x38]; +} __attribute__ ((packed)); + +/* Debug Space */ +struct dbg { + __be32 bpdcr; /* Breakpoint debug command register */ + __be32 bpdsr; /* Breakpoint debug status register */ + __be32 bpdmr; /* Breakpoint debug mask register */ + __be32 bprmrr0; /* Breakpoint request mode risc register 0 */ + __be32 bprmrr1; /* Breakpoint request mode risc register 1 */ + u8 res0[0x8]; + __be32 bprmtr0; /* Breakpoint request mode trb register 0 */ + __be32 bprmtr1; /* Breakpoint request mode trb register 1 */ + u8 res1[0x8]; + __be32 bprmir; /* Breakpoint request mode immediate register */ + __be32 bprmsr; /* Breakpoint request mode serial register */ + __be32 bpemr; /* Breakpoint exit mode register */ + u8 res2[0x48]; +} __attribute__ ((packed)); + +/* + * RISC Special Registers (Trap and Breakpoint). These are described in + * the QE Developer's Handbook. + */ +struct rsp { + __be32 tibcr[16]; /* Trap/instruction breakpoint control regs */ + u8 res0[64]; + __be32 ibcr0; + __be32 ibs0; + __be32 ibcnr0; + u8 res1[4]; + __be32 ibcr1; + __be32 ibs1; + __be32 ibcnr1; + __be32 npcr; + __be32 dbcr; + __be32 dbar; + __be32 dbamr; + __be32 dbsr; + __be32 dbcnr; + u8 res2[12]; + __be32 dbdr_h; + __be32 dbdr_l; + __be32 dbdmr_h; + __be32 dbdmr_l; + __be32 bsr; + __be32 bor; + __be32 bior; + u8 res3[4]; + __be32 iatr[4]; + __be32 eccr; /* Exception control configuration register */ + __be32 eicr; + u8 res4[0x100-0xf8]; +} __attribute__ ((packed)); + +struct qe_immap { + struct qe_iram iram; /* I-RAM */ + struct qe_ic_regs ic; /* Interrupt Controller */ + struct cp_qe cp; /* Communications Processor */ + struct qe_mux qmx; /* QE Multiplexer */ + struct qe_timers qet; /* QE Timers */ + struct spi spi[0x2]; /* spi */ + struct qe_mcc mcc; /* mcc */ + struct qe_brg brg; /* brg */ + struct qe_usb_ctlr usb; /* USB */ + struct si1 si1; /* SI */ + u8 res11[0x800]; + struct sir sir; /* SI Routing Tables */ + struct ucc ucc1; /* ucc1 */ + struct ucc ucc3; /* ucc3 */ + struct ucc ucc5; /* ucc5 */ + struct ucc ucc7; /* ucc7 */ + u8 res12[0x600]; + struct upc upc1; /* MultiPHY UTOPIA POS Ctrlr 1*/ + struct ucc ucc2; /* ucc2 */ + struct ucc ucc4; /* ucc4 */ + struct ucc ucc6; /* ucc6 */ + struct ucc ucc8; /* ucc8 */ + u8 res13[0x600]; + struct upc upc2; /* MultiPHY UTOPIA POS Ctrlr 2*/ + struct sdma sdma; /* SDMA */ + struct dbg dbg; /* 0x104080 - 0x1040FF + Debug Space */ + struct rsp rsp[0x2]; /* 0x104100 - 0x1042FF + RISC Special Registers + (Trap and Breakpoint) */ + u8 res14[0x300]; /* 0x104300 - 0x1045FF */ + u8 res15[0x3A00]; /* 0x104600 - 0x107FFF */ + u8 res16[0x8000]; /* 0x108000 - 0x110000 */ + u8 muram[0xC000]; /* 0x110000 - 0x11C000 + Multi-user RAM */ + u8 res17[0x24000]; /* 0x11C000 - 0x140000 */ + u8 res18[0xC0000]; /* 0x140000 - 0x200000 */ +} __attribute__ ((packed)); + +extern struct qe_immap __iomem *qe_immr; +extern phys_addr_t get_qe_base(void); + +/* + * Returns the offset within the QE address space of the given pointer. + * + * Note that the QE does not support 36-bit physical addresses, so if + * get_qe_base() returns a number above 4GB, the caller will probably fail. + */ +static inline phys_addr_t immrbar_virt_to_phys(void *address) +{ + void *q = (void *)qe_immr; + + /* Is it a MURAM address? */ + if ((address >= q) && (address < (q + QE_IMMAP_SIZE))) + return get_qe_base() + (address - q); + + /* It's an address returned by kmalloc */ + return virt_to_phys(address); +} + +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_IMMAP_QE_H */ diff --git a/include/soc/fsl/qe/qe.h b/include/soc/fsl/qe/qe.h new file mode 100644 index 000000000000..c7fa36c335c9 --- /dev/null +++ b/include/soc/fsl/qe/qe.h @@ -0,0 +1,790 @@ +/* + * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved. + * + * Authors: Shlomi Gridish + * Li Yang + * + * Description: + * QUICC Engine (QE) external definitions and structure. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef _ASM_POWERPC_QE_H +#define _ASM_POWERPC_QE_H +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define QE_NUM_OF_SNUM 256 /* There are 256 serial number in QE */ +#define QE_NUM_OF_BRGS 16 +#define QE_NUM_OF_PORTS 1024 + +/* Memory partitions +*/ +#define MEM_PART_SYSTEM 0 +#define MEM_PART_SECONDARY 1 +#define MEM_PART_MURAM 2 + +/* Clocks and BRGs */ +enum qe_clock { + QE_CLK_NONE = 0, + QE_BRG1, /* Baud Rate Generator 1 */ + QE_BRG2, /* Baud Rate Generator 2 */ + QE_BRG3, /* Baud Rate Generator 3 */ + QE_BRG4, /* Baud Rate Generator 4 */ + QE_BRG5, /* Baud Rate Generator 5 */ + QE_BRG6, /* Baud Rate Generator 6 */ + QE_BRG7, /* Baud Rate Generator 7 */ + QE_BRG8, /* Baud Rate Generator 8 */ + QE_BRG9, /* Baud Rate Generator 9 */ + QE_BRG10, /* Baud Rate Generator 10 */ + QE_BRG11, /* Baud Rate Generator 11 */ + QE_BRG12, /* Baud Rate Generator 12 */ + QE_BRG13, /* Baud Rate Generator 13 */ + QE_BRG14, /* Baud Rate Generator 14 */ + QE_BRG15, /* Baud Rate Generator 15 */ + QE_BRG16, /* Baud Rate Generator 16 */ + QE_CLK1, /* Clock 1 */ + QE_CLK2, /* Clock 2 */ + QE_CLK3, /* Clock 3 */ + QE_CLK4, /* Clock 4 */ + QE_CLK5, /* Clock 5 */ + QE_CLK6, /* Clock 6 */ + QE_CLK7, /* Clock 7 */ + QE_CLK8, /* Clock 8 */ + QE_CLK9, /* Clock 9 */ + QE_CLK10, /* Clock 10 */ + QE_CLK11, /* Clock 11 */ + QE_CLK12, /* Clock 12 */ + QE_CLK13, /* Clock 13 */ + QE_CLK14, /* Clock 14 */ + QE_CLK15, /* Clock 15 */ + QE_CLK16, /* Clock 16 */ + QE_CLK17, /* Clock 17 */ + QE_CLK18, /* Clock 18 */ + QE_CLK19, /* Clock 19 */ + QE_CLK20, /* Clock 20 */ + QE_CLK21, /* Clock 21 */ + QE_CLK22, /* Clock 22 */ + QE_CLK23, /* Clock 23 */ + QE_CLK24, /* Clock 24 */ + QE_CLK_DUMMY +}; + +static inline bool qe_clock_is_brg(enum qe_clock clk) +{ + return clk >= QE_BRG1 && clk <= QE_BRG16; +} + +extern spinlock_t cmxgcr_lock; + +/* Export QE common operations */ +#ifdef CONFIG_QUICC_ENGINE +extern void qe_reset(void); +#else +static inline void qe_reset(void) {} +#endif + +int cpm_muram_init(void); + +#if defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE) +unsigned long cpm_muram_alloc(unsigned long size, unsigned long align); +int cpm_muram_free(unsigned long offset); +unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size); +unsigned long cpm_muram_alloc_common(unsigned long size, genpool_algo_t algo, + void *data); +void __iomem *cpm_muram_addr(unsigned long offset); +unsigned long cpm_muram_offset(void __iomem *addr); +dma_addr_t cpm_muram_dma(void __iomem *addr); +#else +static inline unsigned long cpm_muram_alloc(unsigned long size, + unsigned long align) +{ + return -ENOSYS; +} + +static inline int cpm_muram_free(unsigned long offset) +{ + return -ENOSYS; +} + +static inline unsigned long cpm_muram_alloc_fixed(unsigned long offset, + unsigned long size) +{ + return -ENOSYS; +} + +static inline void __iomem *cpm_muram_addr(unsigned long offset) +{ + return NULL; +} + +static inline unsigned long cpm_muram_offset(void __iomem *addr) +{ + return -ENOSYS; +} + +static inline dma_addr_t cpm_muram_dma(void __iomem *addr) +{ + return 0; +} +#endif /* defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE) */ + +/* QE PIO */ +#define QE_PIO_PINS 32 + +struct qe_pio_regs { + __be32 cpodr; /* Open drain register */ + __be32 cpdata; /* Data register */ + __be32 cpdir1; /* Direction register */ + __be32 cpdir2; /* Direction register */ + __be32 cppar1; /* Pin assignment register */ + __be32 cppar2; /* Pin assignment register */ +#ifdef CONFIG_PPC_85xx + u8 pad[8]; +#endif +}; + +#define QE_PIO_DIR_IN 2 +#define QE_PIO_DIR_OUT 1 +extern void __par_io_config_pin(struct qe_pio_regs __iomem *par_io, u8 pin, + int dir, int open_drain, int assignment, + int has_irq); +#ifdef CONFIG_QUICC_ENGINE +extern int par_io_init(struct device_node *np); +extern int par_io_of_config(struct device_node *np); +extern int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain, + int assignment, int has_irq); +extern int par_io_data_set(u8 port, u8 pin, u8 val); +#else +static inline int par_io_init(struct device_node *np) { return -ENOSYS; } +static inline int par_io_of_config(struct device_node *np) { return -ENOSYS; } +static inline int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain, + int assignment, int has_irq) { return -ENOSYS; } +static inline int par_io_data_set(u8 port, u8 pin, u8 val) { return -ENOSYS; } +#endif /* CONFIG_QUICC_ENGINE */ + +/* + * Pin multiplexing functions. + */ +struct qe_pin; +#ifdef CONFIG_QE_GPIO +extern struct qe_pin *qe_pin_request(struct device_node *np, int index); +extern void qe_pin_free(struct qe_pin *qe_pin); +extern void qe_pin_set_gpio(struct qe_pin *qe_pin); +extern void qe_pin_set_dedicated(struct qe_pin *pin); +#else +static inline struct qe_pin *qe_pin_request(struct device_node *np, int index) +{ + return ERR_PTR(-ENOSYS); +} +static inline void qe_pin_free(struct qe_pin *qe_pin) {} +static inline void qe_pin_set_gpio(struct qe_pin *qe_pin) {} +static inline void qe_pin_set_dedicated(struct qe_pin *pin) {} +#endif /* CONFIG_QE_GPIO */ + +#ifdef CONFIG_QUICC_ENGINE +int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input); +#else +static inline int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, + u32 cmd_input) +{ + return -ENOSYS; +} +#endif /* CONFIG_QUICC_ENGINE */ + +/* QE internal API */ +enum qe_clock qe_clock_source(const char *source); +unsigned int qe_get_brg_clk(void); +int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier); +int qe_get_snum(void); +void qe_put_snum(u8 snum); +unsigned int qe_get_num_of_risc(void); +unsigned int qe_get_num_of_snums(void); + +static inline int qe_alive_during_sleep(void) +{ + /* + * MPC8568E reference manual says: + * + * "...power down sequence waits for all I/O interfaces to become idle. + * In some applications this may happen eventually without actively + * shutting down interfaces, but most likely, software will have to + * take steps to shut down the eTSEC, QUICC Engine Block, and PCI + * interfaces before issuing the command (either the write to the core + * MSR[WE] as described above or writing to POWMGTCSR) to put the + * device into sleep state." + * + * MPC8569E reference manual has a similar paragraph. + */ +#ifdef CONFIG_PPC_85xx + return 0; +#else + return 1; +#endif +} + +/* we actually use cpm_muram implementation, define this for convenience */ +#define qe_muram_init cpm_muram_init +#define qe_muram_alloc cpm_muram_alloc +#define qe_muram_alloc_fixed cpm_muram_alloc_fixed +#define qe_muram_free cpm_muram_free +#define qe_muram_addr cpm_muram_addr +#define qe_muram_offset cpm_muram_offset + +/* Structure that defines QE firmware binary files. + * + * See Documentation/powerpc/qe_firmware.txt for a description of these + * fields. + */ +struct qe_firmware { + struct qe_header { + __be32 length; /* Length of the entire structure, in bytes */ + u8 magic[3]; /* Set to { 'Q', 'E', 'F' } */ + u8 version; /* Version of this layout. First ver is '1' */ + } header; + u8 id[62]; /* Null-terminated identifier string */ + u8 split; /* 0 = shared I-RAM, 1 = split I-RAM */ + u8 count; /* Number of microcode[] structures */ + struct { + __be16 model; /* The SOC model */ + u8 major; /* The SOC revision major */ + u8 minor; /* The SOC revision minor */ + } __attribute__ ((packed)) soc; + u8 padding[4]; /* Reserved, for alignment */ + __be64 extended_modes; /* Extended modes */ + __be32 vtraps[8]; /* Virtual trap addresses */ + u8 reserved[4]; /* Reserved, for future expansion */ + struct qe_microcode { + u8 id[32]; /* Null-terminated identifier */ + __be32 traps[16]; /* Trap addresses, 0 == ignore */ + __be32 eccr; /* The value for the ECCR register */ + __be32 iram_offset; /* Offset into I-RAM for the code */ + __be32 count; /* Number of 32-bit words of the code */ + __be32 code_offset; /* Offset of the actual microcode */ + u8 major; /* The microcode version major */ + u8 minor; /* The microcode version minor */ + u8 revision; /* The microcode version revision */ + u8 padding; /* Reserved, for alignment */ + u8 reserved[4]; /* Reserved, for future expansion */ + } __attribute__ ((packed)) microcode[1]; + /* All microcode binaries should be located here */ + /* CRC32 should be located here, after the microcode binaries */ +} __attribute__ ((packed)); + +struct qe_firmware_info { + char id[64]; /* Firmware name */ + u32 vtraps[8]; /* Virtual trap addresses */ + u64 extended_modes; /* Extended modes */ +}; + +#ifdef CONFIG_QUICC_ENGINE +/* Upload a firmware to the QE */ +int qe_upload_firmware(const struct qe_firmware *firmware); +#else +static inline int qe_upload_firmware(const struct qe_firmware *firmware) +{ + return -ENOSYS; +} +#endif /* CONFIG_QUICC_ENGINE */ + +/* Obtain information on the uploaded firmware */ +struct qe_firmware_info *qe_get_firmware_info(void); + +/* QE USB */ +int qe_usb_clock_set(enum qe_clock clk, int rate); + +/* Buffer descriptors */ +struct qe_bd { + __be16 status; + __be16 length; + __be32 buf; +} __attribute__ ((packed)); + +#define BD_STATUS_MASK 0xffff0000 +#define BD_LENGTH_MASK 0x0000ffff + +/* Alignment */ +#define QE_INTR_TABLE_ALIGN 16 /* ??? */ +#define QE_ALIGNMENT_OF_BD 8 +#define QE_ALIGNMENT_OF_PRAM 64 + +/* RISC allocation */ +#define QE_RISC_ALLOCATION_RISC1 0x1 /* RISC 1 */ +#define QE_RISC_ALLOCATION_RISC2 0x2 /* RISC 2 */ +#define QE_RISC_ALLOCATION_RISC3 0x4 /* RISC 3 */ +#define QE_RISC_ALLOCATION_RISC4 0x8 /* RISC 4 */ +#define QE_RISC_ALLOCATION_RISC1_AND_RISC2 (QE_RISC_ALLOCATION_RISC1 | \ + QE_RISC_ALLOCATION_RISC2) +#define QE_RISC_ALLOCATION_FOUR_RISCS (QE_RISC_ALLOCATION_RISC1 | \ + QE_RISC_ALLOCATION_RISC2 | \ + QE_RISC_ALLOCATION_RISC3 | \ + QE_RISC_ALLOCATION_RISC4) + +/* QE extended filtering Table Lookup Key Size */ +enum qe_fltr_tbl_lookup_key_size { + QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES + = 0x3f, /* LookupKey parsed by the Generate LookupKey + CMD is truncated to 8 bytes */ + QE_FLTR_TABLE_LOOKUP_KEY_SIZE_16_BYTES + = 0x5f, /* LookupKey parsed by the Generate LookupKey + CMD is truncated to 16 bytes */ +}; + +/* QE FLTR extended filtering Largest External Table Lookup Key Size */ +enum qe_fltr_largest_external_tbl_lookup_key_size { + QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_NONE + = 0x0,/* not used */ + QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_8_BYTES + = QE_FLTR_TABLE_LOOKUP_KEY_SIZE_8_BYTES, /* 8 bytes */ + QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES + = QE_FLTR_TABLE_LOOKUP_KEY_SIZE_16_BYTES, /* 16 bytes */ +}; + +/* structure representing QE parameter RAM */ +struct qe_timer_tables { + u16 tm_base; /* QE timer table base adr */ + u16 tm_ptr; /* QE timer table pointer */ + u16 r_tmr; /* QE timer mode register */ + u16 r_tmv; /* QE timer valid register */ + u32 tm_cmd; /* QE timer cmd register */ + u32 tm_cnt; /* QE timer internal cnt */ +} __attribute__ ((packed)); + +#define QE_FLTR_TAD_SIZE 8 + +/* QE extended filtering Termination Action Descriptor (TAD) */ +struct qe_fltr_tad { + u8 serialized[QE_FLTR_TAD_SIZE]; +} __attribute__ ((packed)); + +/* Communication Direction */ +enum comm_dir { + COMM_DIR_NONE = 0, + COMM_DIR_RX = 1, + COMM_DIR_TX = 2, + COMM_DIR_RX_AND_TX = 3 +}; + +/* QE CMXUCR Registers. + * There are two UCCs represented in each of the four CMXUCR registers. + * These values are for the UCC in the LSBs + */ +#define QE_CMXUCR_MII_ENET_MNG 0x00007000 +#define QE_CMXUCR_MII_ENET_MNG_SHIFT 12 +#define QE_CMXUCR_GRANT 0x00008000 +#define QE_CMXUCR_TSA 0x00004000 +#define QE_CMXUCR_BKPT 0x00000100 +#define QE_CMXUCR_TX_CLK_SRC_MASK 0x0000000F + +/* QE CMXGCR Registers. +*/ +#define QE_CMXGCR_MII_ENET_MNG 0x00007000 +#define QE_CMXGCR_MII_ENET_MNG_SHIFT 12 +#define QE_CMXGCR_USBCS 0x0000000f +#define QE_CMXGCR_USBCS_CLK3 0x1 +#define QE_CMXGCR_USBCS_CLK5 0x2 +#define QE_CMXGCR_USBCS_CLK7 0x3 +#define QE_CMXGCR_USBCS_CLK9 0x4 +#define QE_CMXGCR_USBCS_CLK13 0x5 +#define QE_CMXGCR_USBCS_CLK17 0x6 +#define QE_CMXGCR_USBCS_CLK19 0x7 +#define QE_CMXGCR_USBCS_CLK21 0x8 +#define QE_CMXGCR_USBCS_BRG9 0x9 +#define QE_CMXGCR_USBCS_BRG10 0xa + +/* QE CECR Commands. +*/ +#define QE_CR_FLG 0x00010000 +#define QE_RESET 0x80000000 +#define QE_INIT_TX_RX 0x00000000 +#define QE_INIT_RX 0x00000001 +#define QE_INIT_TX 0x00000002 +#define QE_ENTER_HUNT_MODE 0x00000003 +#define QE_STOP_TX 0x00000004 +#define QE_GRACEFUL_STOP_TX 0x00000005 +#define QE_RESTART_TX 0x00000006 +#define QE_CLOSE_RX_BD 0x00000007 +#define QE_SWITCH_COMMAND 0x00000007 +#define QE_SET_GROUP_ADDRESS 0x00000008 +#define QE_START_IDMA 0x00000009 +#define QE_MCC_STOP_RX 0x00000009 +#define QE_ATM_TRANSMIT 0x0000000a +#define QE_HPAC_CLEAR_ALL 0x0000000b +#define QE_GRACEFUL_STOP_RX 0x0000001a +#define QE_RESTART_RX 0x0000001b +#define QE_HPAC_SET_PRIORITY 0x0000010b +#define QE_HPAC_STOP_TX 0x0000020b +#define QE_HPAC_STOP_RX 0x0000030b +#define QE_HPAC_GRACEFUL_STOP_TX 0x0000040b +#define QE_HPAC_GRACEFUL_STOP_RX 0x0000050b +#define QE_HPAC_START_TX 0x0000060b +#define QE_HPAC_START_RX 0x0000070b +#define QE_USB_STOP_TX 0x0000000a +#define QE_USB_RESTART_TX 0x0000000c +#define QE_QMC_STOP_TX 0x0000000c +#define QE_QMC_STOP_RX 0x0000000d +#define QE_SS7_SU_FIL_RESET 0x0000000e +/* jonathbr added from here down for 83xx */ +#define QE_RESET_BCS 0x0000000a +#define QE_MCC_INIT_TX_RX_16 0x00000003 +#define QE_MCC_STOP_TX 0x00000004 +#define QE_MCC_INIT_TX_1 0x00000005 +#define QE_MCC_INIT_RX_1 0x00000006 +#define QE_MCC_RESET 0x00000007 +#define QE_SET_TIMER 0x00000008 +#define QE_RANDOM_NUMBER 0x0000000c +#define QE_ATM_MULTI_THREAD_INIT 0x00000011 +#define QE_ASSIGN_PAGE 0x00000012 +#define QE_ADD_REMOVE_HASH_ENTRY 0x00000013 +#define QE_START_FLOW_CONTROL 0x00000014 +#define QE_STOP_FLOW_CONTROL 0x00000015 +#define QE_ASSIGN_PAGE_TO_DEVICE 0x00000016 + +#define QE_ASSIGN_RISC 0x00000010 +#define QE_CR_MCN_NORMAL_SHIFT 6 +#define QE_CR_MCN_USB_SHIFT 4 +#define QE_CR_MCN_RISC_ASSIGN_SHIFT 8 +#define QE_CR_SNUM_SHIFT 17 + +/* QE CECR Sub Block - sub block of QE command. +*/ +#define QE_CR_SUBBLOCK_INVALID 0x00000000 +#define QE_CR_SUBBLOCK_USB 0x03200000 +#define QE_CR_SUBBLOCK_UCCFAST1 0x02000000 +#define QE_CR_SUBBLOCK_UCCFAST2 0x02200000 +#define QE_CR_SUBBLOCK_UCCFAST3 0x02400000 +#define QE_CR_SUBBLOCK_UCCFAST4 0x02600000 +#define QE_CR_SUBBLOCK_UCCFAST5 0x02800000 +#define QE_CR_SUBBLOCK_UCCFAST6 0x02a00000 +#define QE_CR_SUBBLOCK_UCCFAST7 0x02c00000 +#define QE_CR_SUBBLOCK_UCCFAST8 0x02e00000 +#define QE_CR_SUBBLOCK_UCCSLOW1 0x00000000 +#define QE_CR_SUBBLOCK_UCCSLOW2 0x00200000 +#define QE_CR_SUBBLOCK_UCCSLOW3 0x00400000 +#define QE_CR_SUBBLOCK_UCCSLOW4 0x00600000 +#define QE_CR_SUBBLOCK_UCCSLOW5 0x00800000 +#define QE_CR_SUBBLOCK_UCCSLOW6 0x00a00000 +#define QE_CR_SUBBLOCK_UCCSLOW7 0x00c00000 +#define QE_CR_SUBBLOCK_UCCSLOW8 0x00e00000 +#define QE_CR_SUBBLOCK_MCC1 0x03800000 +#define QE_CR_SUBBLOCK_MCC2 0x03a00000 +#define QE_CR_SUBBLOCK_MCC3 0x03000000 +#define QE_CR_SUBBLOCK_IDMA1 0x02800000 +#define QE_CR_SUBBLOCK_IDMA2 0x02a00000 +#define QE_CR_SUBBLOCK_IDMA3 0x02c00000 +#define QE_CR_SUBBLOCK_IDMA4 0x02e00000 +#define QE_CR_SUBBLOCK_HPAC 0x01e00000 +#define QE_CR_SUBBLOCK_SPI1 0x01400000 +#define QE_CR_SUBBLOCK_SPI2 0x01600000 +#define QE_CR_SUBBLOCK_RAND 0x01c00000 +#define QE_CR_SUBBLOCK_TIMER 0x01e00000 +#define QE_CR_SUBBLOCK_GENERAL 0x03c00000 + +/* QE CECR Protocol - For non-MCC, specifies mode for QE CECR command */ +#define QE_CR_PROTOCOL_UNSPECIFIED 0x00 /* For all other protocols */ +#define QE_CR_PROTOCOL_HDLC_TRANSPARENT 0x00 +#define QE_CR_PROTOCOL_QMC 0x02 +#define QE_CR_PROTOCOL_UART 0x04 +#define QE_CR_PROTOCOL_ATM_POS 0x0A +#define QE_CR_PROTOCOL_ETHERNET 0x0C +#define QE_CR_PROTOCOL_L2_SWITCH 0x0D + +/* BRG configuration register */ +#define QE_BRGC_ENABLE 0x00010000 +#define QE_BRGC_DIVISOR_SHIFT 1 +#define QE_BRGC_DIVISOR_MAX 0xFFF +#define QE_BRGC_DIV16 1 + +/* QE Timers registers */ +#define QE_GTCFR1_PCAS 0x80 +#define QE_GTCFR1_STP2 0x20 +#define QE_GTCFR1_RST2 0x10 +#define QE_GTCFR1_GM2 0x08 +#define QE_GTCFR1_GM1 0x04 +#define QE_GTCFR1_STP1 0x02 +#define QE_GTCFR1_RST1 0x01 + +/* SDMA registers */ +#define QE_SDSR_BER1 0x02000000 +#define QE_SDSR_BER2 0x01000000 + +#define QE_SDMR_GLB_1_MSK 0x80000000 +#define QE_SDMR_ADR_SEL 0x20000000 +#define QE_SDMR_BER1_MSK 0x02000000 +#define QE_SDMR_BER2_MSK 0x01000000 +#define QE_SDMR_EB1_MSK 0x00800000 +#define QE_SDMR_ER1_MSK 0x00080000 +#define QE_SDMR_ER2_MSK 0x00040000 +#define QE_SDMR_CEN_MASK 0x0000E000 +#define QE_SDMR_SBER_1 0x00000200 +#define QE_SDMR_SBER_2 0x00000200 +#define QE_SDMR_EB1_PR_MASK 0x000000C0 +#define QE_SDMR_ER1_PR 0x00000008 + +#define QE_SDMR_CEN_SHIFT 13 +#define QE_SDMR_EB1_PR_SHIFT 6 + +#define QE_SDTM_MSNUM_SHIFT 24 + +#define QE_SDEBCR_BA_MASK 0x01FFFFFF + +/* Communication Processor */ +#define QE_CP_CERCR_MEE 0x8000 /* Multi-user RAM ECC enable */ +#define QE_CP_CERCR_IEE 0x4000 /* Instruction RAM ECC enable */ +#define QE_CP_CERCR_CIR 0x0800 /* Common instruction RAM */ + +/* I-RAM */ +#define QE_IRAM_IADD_AIE 0x80000000 /* Auto Increment Enable */ +#define QE_IRAM_IADD_BADDR 0x00080000 /* Base Address */ +#define QE_IRAM_READY 0x80000000 /* Ready */ + +/* UPC */ +#define UPGCR_PROTOCOL 0x80000000 /* protocol ul2 or pl2 */ +#define UPGCR_TMS 0x40000000 /* Transmit master/slave mode */ +#define UPGCR_RMS 0x20000000 /* Receive master/slave mode */ +#define UPGCR_ADDR 0x10000000 /* Master MPHY Addr multiplexing */ +#define UPGCR_DIAG 0x01000000 /* Diagnostic mode */ + +/* UCC GUEMR register */ +#define UCC_GUEMR_MODE_MASK_RX 0x02 +#define UCC_GUEMR_MODE_FAST_RX 0x02 +#define UCC_GUEMR_MODE_SLOW_RX 0x00 +#define UCC_GUEMR_MODE_MASK_TX 0x01 +#define UCC_GUEMR_MODE_FAST_TX 0x01 +#define UCC_GUEMR_MODE_SLOW_TX 0x00 +#define UCC_GUEMR_MODE_MASK (UCC_GUEMR_MODE_MASK_RX | UCC_GUEMR_MODE_MASK_TX) +#define UCC_GUEMR_SET_RESERVED3 0x10 /* Bit 3 in the guemr is reserved but + must be set 1 */ + +/* structure representing UCC SLOW parameter RAM */ +struct ucc_slow_pram { + __be16 rbase; /* RX BD base address */ + __be16 tbase; /* TX BD base address */ + u8 rbmr; /* RX bus mode register (same as CPM's RFCR) */ + u8 tbmr; /* TX bus mode register (same as CPM's TFCR) */ + __be16 mrblr; /* Rx buffer length */ + __be32 rstate; /* Rx internal state */ + __be32 rptr; /* Rx internal data pointer */ + __be16 rbptr; /* rb BD Pointer */ + __be16 rcount; /* Rx internal byte count */ + __be32 rtemp; /* Rx temp */ + __be32 tstate; /* Tx internal state */ + __be32 tptr; /* Tx internal data pointer */ + __be16 tbptr; /* Tx BD pointer */ + __be16 tcount; /* Tx byte count */ + __be32 ttemp; /* Tx temp */ + __be32 rcrc; /* temp receive CRC */ + __be32 tcrc; /* temp transmit CRC */ +} __attribute__ ((packed)); + +/* General UCC SLOW Mode Register (GUMRH & GUMRL) */ +#define UCC_SLOW_GUMR_H_SAM_QMC 0x00000000 +#define UCC_SLOW_GUMR_H_SAM_SATM 0x00008000 +#define UCC_SLOW_GUMR_H_REVD 0x00002000 +#define UCC_SLOW_GUMR_H_TRX 0x00001000 +#define UCC_SLOW_GUMR_H_TTX 0x00000800 +#define UCC_SLOW_GUMR_H_CDP 0x00000400 +#define UCC_SLOW_GUMR_H_CTSP 0x00000200 +#define UCC_SLOW_GUMR_H_CDS 0x00000100 +#define UCC_SLOW_GUMR_H_CTSS 0x00000080 +#define UCC_SLOW_GUMR_H_TFL 0x00000040 +#define UCC_SLOW_GUMR_H_RFW 0x00000020 +#define UCC_SLOW_GUMR_H_TXSY 0x00000010 +#define UCC_SLOW_GUMR_H_4SYNC 0x00000004 +#define UCC_SLOW_GUMR_H_8SYNC 0x00000008 +#define UCC_SLOW_GUMR_H_16SYNC 0x0000000c +#define UCC_SLOW_GUMR_H_RTSM 0x00000002 +#define UCC_SLOW_GUMR_H_RSYN 0x00000001 + +#define UCC_SLOW_GUMR_L_TCI 0x10000000 +#define UCC_SLOW_GUMR_L_RINV 0x02000000 +#define UCC_SLOW_GUMR_L_TINV 0x01000000 +#define UCC_SLOW_GUMR_L_TEND 0x00040000 +#define UCC_SLOW_GUMR_L_TDCR_MASK 0x00030000 +#define UCC_SLOW_GUMR_L_TDCR_32 0x00030000 +#define UCC_SLOW_GUMR_L_TDCR_16 0x00020000 +#define UCC_SLOW_GUMR_L_TDCR_8 0x00010000 +#define UCC_SLOW_GUMR_L_TDCR_1 0x00000000 +#define UCC_SLOW_GUMR_L_RDCR_MASK 0x0000c000 +#define UCC_SLOW_GUMR_L_RDCR_32 0x0000c000 +#define UCC_SLOW_GUMR_L_RDCR_16 0x00008000 +#define UCC_SLOW_GUMR_L_RDCR_8 0x00004000 +#define UCC_SLOW_GUMR_L_RDCR_1 0x00000000 +#define UCC_SLOW_GUMR_L_RENC_NRZI 0x00000800 +#define UCC_SLOW_GUMR_L_RENC_NRZ 0x00000000 +#define UCC_SLOW_GUMR_L_TENC_NRZI 0x00000100 +#define UCC_SLOW_GUMR_L_TENC_NRZ 0x00000000 +#define UCC_SLOW_GUMR_L_DIAG_MASK 0x000000c0 +#define UCC_SLOW_GUMR_L_DIAG_LE 0x000000c0 +#define UCC_SLOW_GUMR_L_DIAG_ECHO 0x00000080 +#define UCC_SLOW_GUMR_L_DIAG_LOOP 0x00000040 +#define UCC_SLOW_GUMR_L_DIAG_NORM 0x00000000 +#define UCC_SLOW_GUMR_L_ENR 0x00000020 +#define UCC_SLOW_GUMR_L_ENT 0x00000010 +#define UCC_SLOW_GUMR_L_MODE_MASK 0x0000000F +#define UCC_SLOW_GUMR_L_MODE_BISYNC 0x00000008 +#define UCC_SLOW_GUMR_L_MODE_AHDLC 0x00000006 +#define UCC_SLOW_GUMR_L_MODE_UART 0x00000004 +#define UCC_SLOW_GUMR_L_MODE_QMC 0x00000002 + +/* General UCC FAST Mode Register */ +#define UCC_FAST_GUMR_TCI 0x20000000 +#define UCC_FAST_GUMR_TRX 0x10000000 +#define UCC_FAST_GUMR_TTX 0x08000000 +#define UCC_FAST_GUMR_CDP 0x04000000 +#define UCC_FAST_GUMR_CTSP 0x02000000 +#define UCC_FAST_GUMR_CDS 0x01000000 +#define UCC_FAST_GUMR_CTSS 0x00800000 +#define UCC_FAST_GUMR_TXSY 0x00020000 +#define UCC_FAST_GUMR_RSYN 0x00010000 +#define UCC_FAST_GUMR_RTSM 0x00002000 +#define UCC_FAST_GUMR_REVD 0x00000400 +#define UCC_FAST_GUMR_ENR 0x00000020 +#define UCC_FAST_GUMR_ENT 0x00000010 + +/* UART Slow UCC Event Register (UCCE) */ +#define UCC_UART_UCCE_AB 0x0200 +#define UCC_UART_UCCE_IDLE 0x0100 +#define UCC_UART_UCCE_GRA 0x0080 +#define UCC_UART_UCCE_BRKE 0x0040 +#define UCC_UART_UCCE_BRKS 0x0020 +#define UCC_UART_UCCE_CCR 0x0008 +#define UCC_UART_UCCE_BSY 0x0004 +#define UCC_UART_UCCE_TX 0x0002 +#define UCC_UART_UCCE_RX 0x0001 + +/* HDLC Slow UCC Event Register (UCCE) */ +#define UCC_HDLC_UCCE_GLR 0x1000 +#define UCC_HDLC_UCCE_GLT 0x0800 +#define UCC_HDLC_UCCE_IDLE 0x0100 +#define UCC_HDLC_UCCE_BRKE 0x0040 +#define UCC_HDLC_UCCE_BRKS 0x0020 +#define UCC_HDLC_UCCE_TXE 0x0010 +#define UCC_HDLC_UCCE_RXF 0x0008 +#define UCC_HDLC_UCCE_BSY 0x0004 +#define UCC_HDLC_UCCE_TXB 0x0002 +#define UCC_HDLC_UCCE_RXB 0x0001 + +/* BISYNC Slow UCC Event Register (UCCE) */ +#define UCC_BISYNC_UCCE_GRA 0x0080 +#define UCC_BISYNC_UCCE_TXE 0x0010 +#define UCC_BISYNC_UCCE_RCH 0x0008 +#define UCC_BISYNC_UCCE_BSY 0x0004 +#define UCC_BISYNC_UCCE_TXB 0x0002 +#define UCC_BISYNC_UCCE_RXB 0x0001 + +/* Gigabit Ethernet Fast UCC Event Register (UCCE) */ +#define UCC_GETH_UCCE_MPD 0x80000000 +#define UCC_GETH_UCCE_SCAR 0x40000000 +#define UCC_GETH_UCCE_GRA 0x20000000 +#define UCC_GETH_UCCE_CBPR 0x10000000 +#define UCC_GETH_UCCE_BSY 0x08000000 +#define UCC_GETH_UCCE_RXC 0x04000000 +#define UCC_GETH_UCCE_TXC 0x02000000 +#define UCC_GETH_UCCE_TXE 0x01000000 +#define UCC_GETH_UCCE_TXB7 0x00800000 +#define UCC_GETH_UCCE_TXB6 0x00400000 +#define UCC_GETH_UCCE_TXB5 0x00200000 +#define UCC_GETH_UCCE_TXB4 0x00100000 +#define UCC_GETH_UCCE_TXB3 0x00080000 +#define UCC_GETH_UCCE_TXB2 0x00040000 +#define UCC_GETH_UCCE_TXB1 0x00020000 +#define UCC_GETH_UCCE_TXB0 0x00010000 +#define UCC_GETH_UCCE_RXB7 0x00008000 +#define UCC_GETH_UCCE_RXB6 0x00004000 +#define UCC_GETH_UCCE_RXB5 0x00002000 +#define UCC_GETH_UCCE_RXB4 0x00001000 +#define UCC_GETH_UCCE_RXB3 0x00000800 +#define UCC_GETH_UCCE_RXB2 0x00000400 +#define UCC_GETH_UCCE_RXB1 0x00000200 +#define UCC_GETH_UCCE_RXB0 0x00000100 +#define UCC_GETH_UCCE_RXF7 0x00000080 +#define UCC_GETH_UCCE_RXF6 0x00000040 +#define UCC_GETH_UCCE_RXF5 0x00000020 +#define UCC_GETH_UCCE_RXF4 0x00000010 +#define UCC_GETH_UCCE_RXF3 0x00000008 +#define UCC_GETH_UCCE_RXF2 0x00000004 +#define UCC_GETH_UCCE_RXF1 0x00000002 +#define UCC_GETH_UCCE_RXF0 0x00000001 + +/* UCC Protocol Specific Mode Register (UPSMR), when used for UART */ +#define UCC_UART_UPSMR_FLC 0x8000 +#define UCC_UART_UPSMR_SL 0x4000 +#define UCC_UART_UPSMR_CL_MASK 0x3000 +#define UCC_UART_UPSMR_CL_8 0x3000 +#define UCC_UART_UPSMR_CL_7 0x2000 +#define UCC_UART_UPSMR_CL_6 0x1000 +#define UCC_UART_UPSMR_CL_5 0x0000 +#define UCC_UART_UPSMR_UM_MASK 0x0c00 +#define UCC_UART_UPSMR_UM_NORMAL 0x0000 +#define UCC_UART_UPSMR_UM_MAN_MULTI 0x0400 +#define UCC_UART_UPSMR_UM_AUTO_MULTI 0x0c00 +#define UCC_UART_UPSMR_FRZ 0x0200 +#define UCC_UART_UPSMR_RZS 0x0100 +#define UCC_UART_UPSMR_SYN 0x0080 +#define UCC_UART_UPSMR_DRT 0x0040 +#define UCC_UART_UPSMR_PEN 0x0010 +#define UCC_UART_UPSMR_RPM_MASK 0x000c +#define UCC_UART_UPSMR_RPM_ODD 0x0000 +#define UCC_UART_UPSMR_RPM_LOW 0x0004 +#define UCC_UART_UPSMR_RPM_EVEN 0x0008 +#define UCC_UART_UPSMR_RPM_HIGH 0x000C +#define UCC_UART_UPSMR_TPM_MASK 0x0003 +#define UCC_UART_UPSMR_TPM_ODD 0x0000 +#define UCC_UART_UPSMR_TPM_LOW 0x0001 +#define UCC_UART_UPSMR_TPM_EVEN 0x0002 +#define UCC_UART_UPSMR_TPM_HIGH 0x0003 + +/* UCC Protocol Specific Mode Register (UPSMR), when used for Ethernet */ +#define UCC_GETH_UPSMR_FTFE 0x80000000 +#define UCC_GETH_UPSMR_PTPE 0x40000000 +#define UCC_GETH_UPSMR_ECM 0x04000000 +#define UCC_GETH_UPSMR_HSE 0x02000000 +#define UCC_GETH_UPSMR_PRO 0x00400000 +#define UCC_GETH_UPSMR_CAP 0x00200000 +#define UCC_GETH_UPSMR_RSH 0x00100000 +#define UCC_GETH_UPSMR_RPM 0x00080000 +#define UCC_GETH_UPSMR_R10M 0x00040000 +#define UCC_GETH_UPSMR_RLPB 0x00020000 +#define UCC_GETH_UPSMR_TBIM 0x00010000 +#define UCC_GETH_UPSMR_RES1 0x00002000 +#define UCC_GETH_UPSMR_RMM 0x00001000 +#define UCC_GETH_UPSMR_CAM 0x00000400 +#define UCC_GETH_UPSMR_BRO 0x00000200 +#define UCC_GETH_UPSMR_SMM 0x00000080 +#define UCC_GETH_UPSMR_SGMM 0x00000020 + +/* UCC Transmit On Demand Register (UTODR) */ +#define UCC_SLOW_TOD 0x8000 +#define UCC_FAST_TOD 0x8000 + +/* UCC Bus Mode Register masks */ +/* Not to be confused with the Bundle Mode Register */ +#define UCC_BMR_GBL 0x20 +#define UCC_BMR_BO_BE 0x10 +#define UCC_BMR_CETM 0x04 +#define UCC_BMR_DTB 0x02 +#define UCC_BMR_BDB 0x01 + +/* Function code masks */ +#define FC_GBL 0x20 +#define FC_DTB_LCL 0x02 +#define UCC_FAST_FUNCTION_CODE_GBL 0x20 +#define UCC_FAST_FUNCTION_CODE_DTB_LCL 0x02 +#define UCC_FAST_FUNCTION_CODE_BDB_LCL 0x01 + +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_QE_H */ diff --git a/include/soc/fsl/qe/qe_ic.h b/include/soc/fsl/qe/qe_ic.h new file mode 100644 index 000000000000..1e155ca6d33c --- /dev/null +++ b/include/soc/fsl/qe/qe_ic.h @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved. + * + * Authors: Shlomi Gridish + * Li Yang + * + * Description: + * QE IC external definitions and structure. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef _ASM_POWERPC_QE_IC_H +#define _ASM_POWERPC_QE_IC_H + +#include + +struct device_node; +struct qe_ic; + +#define NUM_OF_QE_IC_GROUPS 6 + +/* Flags when we init the QE IC */ +#define QE_IC_SPREADMODE_GRP_W 0x00000001 +#define QE_IC_SPREADMODE_GRP_X 0x00000002 +#define QE_IC_SPREADMODE_GRP_Y 0x00000004 +#define QE_IC_SPREADMODE_GRP_Z 0x00000008 +#define QE_IC_SPREADMODE_GRP_RISCA 0x00000010 +#define QE_IC_SPREADMODE_GRP_RISCB 0x00000020 + +#define QE_IC_LOW_SIGNAL 0x00000100 +#define QE_IC_HIGH_SIGNAL 0x00000200 + +#define QE_IC_GRP_W_PRI0_DEST_SIGNAL_HIGH 0x00001000 +#define QE_IC_GRP_W_PRI1_DEST_SIGNAL_HIGH 0x00002000 +#define QE_IC_GRP_X_PRI0_DEST_SIGNAL_HIGH 0x00004000 +#define QE_IC_GRP_X_PRI1_DEST_SIGNAL_HIGH 0x00008000 +#define QE_IC_GRP_Y_PRI0_DEST_SIGNAL_HIGH 0x00010000 +#define QE_IC_GRP_Y_PRI1_DEST_SIGNAL_HIGH 0x00020000 +#define QE_IC_GRP_Z_PRI0_DEST_SIGNAL_HIGH 0x00040000 +#define QE_IC_GRP_Z_PRI1_DEST_SIGNAL_HIGH 0x00080000 +#define QE_IC_GRP_RISCA_PRI0_DEST_SIGNAL_HIGH 0x00100000 +#define QE_IC_GRP_RISCA_PRI1_DEST_SIGNAL_HIGH 0x00200000 +#define QE_IC_GRP_RISCB_PRI0_DEST_SIGNAL_HIGH 0x00400000 +#define QE_IC_GRP_RISCB_PRI1_DEST_SIGNAL_HIGH 0x00800000 +#define QE_IC_GRP_W_DEST_SIGNAL_SHIFT (12) + +/* QE interrupt sources groups */ +enum qe_ic_grp_id { + QE_IC_GRP_W = 0, /* QE interrupt controller group W */ + QE_IC_GRP_X, /* QE interrupt controller group X */ + QE_IC_GRP_Y, /* QE interrupt controller group Y */ + QE_IC_GRP_Z, /* QE interrupt controller group Z */ + QE_IC_GRP_RISCA, /* QE interrupt controller RISC group A */ + QE_IC_GRP_RISCB /* QE interrupt controller RISC group B */ +}; + +#ifdef CONFIG_QUICC_ENGINE +void qe_ic_init(struct device_node *node, unsigned int flags, + void (*low_handler)(struct irq_desc *desc), + void (*high_handler)(struct irq_desc *desc)); +unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic); +unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic); +#else +static inline void qe_ic_init(struct device_node *node, unsigned int flags, + void (*low_handler)(struct irq_desc *desc), + void (*high_handler)(struct irq_desc *desc)) +{} +static inline unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic) +{ return 0; } +static inline unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic) +{ return 0; } +#endif /* CONFIG_QUICC_ENGINE */ + +void qe_ic_set_highest_priority(unsigned int virq, int high); +int qe_ic_set_priority(unsigned int virq, unsigned int priority); +int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high); + +static inline void qe_ic_cascade_low_ipic(struct irq_desc *desc) +{ + struct qe_ic *qe_ic = irq_desc_get_handler_data(desc); + unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic); + + if (cascade_irq != NO_IRQ) + generic_handle_irq(cascade_irq); +} + +static inline void qe_ic_cascade_high_ipic(struct irq_desc *desc) +{ + struct qe_ic *qe_ic = irq_desc_get_handler_data(desc); + unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic); + + if (cascade_irq != NO_IRQ) + generic_handle_irq(cascade_irq); +} + +static inline void qe_ic_cascade_low_mpic(struct irq_desc *desc) +{ + struct qe_ic *qe_ic = irq_desc_get_handler_data(desc); + unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic); + struct irq_chip *chip = irq_desc_get_chip(desc); + + if (cascade_irq != NO_IRQ) + generic_handle_irq(cascade_irq); + + chip->irq_eoi(&desc->irq_data); +} + +static inline void qe_ic_cascade_high_mpic(struct irq_desc *desc) +{ + struct qe_ic *qe_ic = irq_desc_get_handler_data(desc); + unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic); + struct irq_chip *chip = irq_desc_get_chip(desc); + + if (cascade_irq != NO_IRQ) + generic_handle_irq(cascade_irq); + + chip->irq_eoi(&desc->irq_data); +} + +static inline void qe_ic_cascade_muxed_mpic(struct irq_desc *desc) +{ + struct qe_ic *qe_ic = irq_desc_get_handler_data(desc); + unsigned int cascade_irq; + struct irq_chip *chip = irq_desc_get_chip(desc); + + cascade_irq = qe_ic_get_high_irq(qe_ic); + if (cascade_irq == NO_IRQ) + cascade_irq = qe_ic_get_low_irq(qe_ic); + + if (cascade_irq != NO_IRQ) + generic_handle_irq(cascade_irq); + + chip->irq_eoi(&desc->irq_data); +} + +#endif /* _ASM_POWERPC_QE_IC_H */ diff --git a/include/soc/fsl/qe/ucc.h b/include/soc/fsl/qe/ucc.h new file mode 100644 index 000000000000..894f14cbb044 --- /dev/null +++ b/include/soc/fsl/qe/ucc.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved. + * + * Authors: Shlomi Gridish + * Li Yang + * + * Description: + * Internal header file for UCC unit routines. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef __UCC_H__ +#define __UCC_H__ + +#include +#include + +#define STATISTICS + +#define UCC_MAX_NUM 8 + +/* Slow or fast type for UCCs. +*/ +enum ucc_speed_type { + UCC_SPEED_TYPE_FAST = UCC_GUEMR_MODE_FAST_RX | UCC_GUEMR_MODE_FAST_TX, + UCC_SPEED_TYPE_SLOW = UCC_GUEMR_MODE_SLOW_RX | UCC_GUEMR_MODE_SLOW_TX +}; + +/* ucc_set_type + * Sets UCC to slow or fast mode. + * + * ucc_num - (In) number of UCC (0-7). + * speed - (In) slow or fast mode for UCC. + */ +int ucc_set_type(unsigned int ucc_num, enum ucc_speed_type speed); + +int ucc_set_qe_mux_mii_mng(unsigned int ucc_num); + +int ucc_set_qe_mux_rxtx(unsigned int ucc_num, enum qe_clock clock, + enum comm_dir mode); + +int ucc_mux_set_grant_tsa_bkpt(unsigned int ucc_num, int set, u32 mask); + +/* QE MUX clock routing for UCC +*/ +static inline int ucc_set_qe_mux_grant(unsigned int ucc_num, int set) +{ + return ucc_mux_set_grant_tsa_bkpt(ucc_num, set, QE_CMXUCR_GRANT); +} + +static inline int ucc_set_qe_mux_tsa(unsigned int ucc_num, int set) +{ + return ucc_mux_set_grant_tsa_bkpt(ucc_num, set, QE_CMXUCR_TSA); +} + +static inline int ucc_set_qe_mux_bkpt(unsigned int ucc_num, int set) +{ + return ucc_mux_set_grant_tsa_bkpt(ucc_num, set, QE_CMXUCR_BKPT); +} + +#endif /* __UCC_H__ */ diff --git a/include/soc/fsl/qe/ucc_fast.h b/include/soc/fsl/qe/ucc_fast.h new file mode 100644 index 000000000000..df8ea7958c63 --- /dev/null +++ b/include/soc/fsl/qe/ucc_fast.h @@ -0,0 +1,244 @@ +/* + * Internal header file for UCC FAST unit routines. + * + * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved. + * + * Authors: Shlomi Gridish + * Li Yang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef __UCC_FAST_H__ +#define __UCC_FAST_H__ + +#include + +#include +#include + +#include + +/* Receive BD's status */ +#define R_E 0x80000000 /* buffer empty */ +#define R_W 0x20000000 /* wrap bit */ +#define R_I 0x10000000 /* interrupt on reception */ +#define R_L 0x08000000 /* last */ +#define R_F 0x04000000 /* first */ + +/* transmit BD's status */ +#define T_R 0x80000000 /* ready bit */ +#define T_W 0x20000000 /* wrap bit */ +#define T_I 0x10000000 /* interrupt on completion */ +#define T_L 0x08000000 /* last */ + +/* Rx Data buffer must be 4 bytes aligned in most cases */ +#define UCC_FAST_RX_ALIGN 4 +#define UCC_FAST_MRBLR_ALIGNMENT 4 +#define UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT 8 + +/* Sizes */ +#define UCC_FAST_URFS_MIN_VAL 0x88 +#define UCC_FAST_RECEIVE_VIRTUAL_FIFO_SIZE_FUDGE_FACTOR 8 + +/* ucc_fast_channel_protocol_mode - UCC FAST mode */ +enum ucc_fast_channel_protocol_mode { + UCC_FAST_PROTOCOL_MODE_HDLC = 0x00000000, + UCC_FAST_PROTOCOL_MODE_RESERVED01 = 0x00000001, + UCC_FAST_PROTOCOL_MODE_RESERVED_QMC = 0x00000002, + UCC_FAST_PROTOCOL_MODE_RESERVED02 = 0x00000003, + UCC_FAST_PROTOCOL_MODE_RESERVED_UART = 0x00000004, + UCC_FAST_PROTOCOL_MODE_RESERVED03 = 0x00000005, + UCC_FAST_PROTOCOL_MODE_RESERVED_EX_MAC_1 = 0x00000006, + UCC_FAST_PROTOCOL_MODE_RESERVED_EX_MAC_2 = 0x00000007, + UCC_FAST_PROTOCOL_MODE_RESERVED_BISYNC = 0x00000008, + UCC_FAST_PROTOCOL_MODE_RESERVED04 = 0x00000009, + UCC_FAST_PROTOCOL_MODE_ATM = 0x0000000A, + UCC_FAST_PROTOCOL_MODE_RESERVED05 = 0x0000000B, + UCC_FAST_PROTOCOL_MODE_ETHERNET = 0x0000000C, + UCC_FAST_PROTOCOL_MODE_RESERVED06 = 0x0000000D, + UCC_FAST_PROTOCOL_MODE_POS = 0x0000000E, + UCC_FAST_PROTOCOL_MODE_RESERVED07 = 0x0000000F +}; + +/* ucc_fast_transparent_txrx - UCC Fast Transparent TX & RX */ +enum ucc_fast_transparent_txrx { + UCC_FAST_GUMR_TRANSPARENT_TTX_TRX_NORMAL = 0x00000000, + UCC_FAST_GUMR_TRANSPARENT_TTX_TRX_TRANSPARENT = 0x18000000 +}; + +/* UCC fast diagnostic mode */ +enum ucc_fast_diag_mode { + UCC_FAST_DIAGNOSTIC_NORMAL = 0x0, + UCC_FAST_DIAGNOSTIC_LOCAL_LOOP_BACK = 0x40000000, + UCC_FAST_DIAGNOSTIC_AUTO_ECHO = 0x80000000, + UCC_FAST_DIAGNOSTIC_LOOP_BACK_AND_ECHO = 0xC0000000 +}; + +/* UCC fast Sync length (transparent mode only) */ +enum ucc_fast_sync_len { + UCC_FAST_SYNC_LEN_NOT_USED = 0x0, + UCC_FAST_SYNC_LEN_AUTOMATIC = 0x00004000, + UCC_FAST_SYNC_LEN_8_BIT = 0x00008000, + UCC_FAST_SYNC_LEN_16_BIT = 0x0000C000 +}; + +/* UCC fast RTS mode */ +enum ucc_fast_ready_to_send { + UCC_FAST_SEND_IDLES_BETWEEN_FRAMES = 0x00000000, + UCC_FAST_SEND_FLAGS_BETWEEN_FRAMES = 0x00002000 +}; + +/* UCC fast receiver decoding mode */ +enum ucc_fast_rx_decoding_method { + UCC_FAST_RX_ENCODING_NRZ = 0x00000000, + UCC_FAST_RX_ENCODING_NRZI = 0x00000800, + UCC_FAST_RX_ENCODING_RESERVED0 = 0x00001000, + UCC_FAST_RX_ENCODING_RESERVED1 = 0x00001800 +}; + +/* UCC fast transmitter encoding mode */ +enum ucc_fast_tx_encoding_method { + UCC_FAST_TX_ENCODING_NRZ = 0x00000000, + UCC_FAST_TX_ENCODING_NRZI = 0x00000100, + UCC_FAST_TX_ENCODING_RESERVED0 = 0x00000200, + UCC_FAST_TX_ENCODING_RESERVED1 = 0x00000300 +}; + +/* UCC fast CRC length */ +enum ucc_fast_transparent_tcrc { + UCC_FAST_16_BIT_CRC = 0x00000000, + UCC_FAST_CRC_RESERVED0 = 0x00000040, + UCC_FAST_32_BIT_CRC = 0x00000080, + UCC_FAST_CRC_RESERVED1 = 0x000000C0 +}; + +/* Fast UCC initialization structure */ +struct ucc_fast_info { + int ucc_num; + enum qe_clock rx_clock; + enum qe_clock tx_clock; + u32 regs; + int irq; + u32 uccm_mask; + int bd_mem_part; + int brkpt_support; + int grant_support; + int tsa; + int cdp; + int cds; + int ctsp; + int ctss; + int tci; + int txsy; + int rtsm; + int revd; + int rsyn; + u16 max_rx_buf_length; + u16 urfs; + u16 urfet; + u16 urfset; + u16 utfs; + u16 utfet; + u16 utftt; + u16 ufpt; + enum ucc_fast_channel_protocol_mode mode; + enum ucc_fast_transparent_txrx ttx_trx; + enum ucc_fast_tx_encoding_method tenc; + enum ucc_fast_rx_decoding_method renc; + enum ucc_fast_transparent_tcrc tcrc; + enum ucc_fast_sync_len synl; +}; + +struct ucc_fast_private { + struct ucc_fast_info *uf_info; + struct ucc_fast __iomem *uf_regs; /* a pointer to the UCC regs. */ + u32 __iomem *p_ucce; /* a pointer to the event register in memory. */ + u32 __iomem *p_uccm; /* a pointer to the mask register in memory. */ +#ifdef CONFIG_UGETH_TX_ON_DEMAND + u16 __iomem *p_utodr; /* pointer to the transmit on demand register */ +#endif + int enabled_tx; /* Whether channel is enabled for Tx (ENT) */ + int enabled_rx; /* Whether channel is enabled for Rx (ENR) */ + int stopped_tx; /* Whether channel has been stopped for Tx + (STOP_TX, etc.) */ + int stopped_rx; /* Whether channel has been stopped for Rx */ + u32 ucc_fast_tx_virtual_fifo_base_offset;/* pointer to base of Tx + virtual fifo */ + u32 ucc_fast_rx_virtual_fifo_base_offset;/* pointer to base of Rx + virtual fifo */ +#ifdef STATISTICS + u32 tx_frames; /* Transmitted frames counter. */ + u32 rx_frames; /* Received frames counter (only frames + passed to application). */ + u32 tx_discarded; /* Discarded tx frames counter (frames that + were discarded by the driver due to errors). + */ + u32 rx_discarded; /* Discarded rx frames counter (frames that + were discarded by the driver due to errors). + */ +#endif /* STATISTICS */ + u16 mrblr; /* maximum receive buffer length */ +}; + +/* ucc_fast_init + * Initializes Fast UCC according to user provided parameters. + * + * uf_info - (In) pointer to the fast UCC info structure. + * uccf_ret - (Out) pointer to the fast UCC structure. + */ +int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** uccf_ret); + +/* ucc_fast_free + * Frees all resources for fast UCC. + * + * uccf - (In) pointer to the fast UCC structure. + */ +void ucc_fast_free(struct ucc_fast_private * uccf); + +/* ucc_fast_enable + * Enables a fast UCC port. + * This routine enables Tx and/or Rx through the General UCC Mode Register. + * + * uccf - (In) pointer to the fast UCC structure. + * mode - (In) TX, RX, or both. + */ +void ucc_fast_enable(struct ucc_fast_private * uccf, enum comm_dir mode); + +/* ucc_fast_disable + * Disables a fast UCC port. + * This routine disables Tx and/or Rx through the General UCC Mode Register. + * + * uccf - (In) pointer to the fast UCC structure. + * mode - (In) TX, RX, or both. + */ +void ucc_fast_disable(struct ucc_fast_private * uccf, enum comm_dir mode); + +/* ucc_fast_irq + * Handles interrupts on fast UCC. + * Called from the general interrupt routine to handle interrupts on fast UCC. + * + * uccf - (In) pointer to the fast UCC structure. + */ +void ucc_fast_irq(struct ucc_fast_private * uccf); + +/* ucc_fast_transmit_on_demand + * Immediately forces a poll of the transmitter for data to be sent. + * Typically, the hardware performs a periodic poll for data that the + * transmit routine has set up to be transmitted. In cases where + * this polling cycle is not soon enough, this optional routine can + * be invoked to force a poll right away, instead. Proper use for + * each transmission for which this functionality is desired is to + * call the transmit routine and then this routine right after. + * + * uccf - (In) pointer to the fast UCC structure. + */ +void ucc_fast_transmit_on_demand(struct ucc_fast_private * uccf); + +u32 ucc_fast_get_qe_cr_subblock(int uccf_num); + +void ucc_fast_dump_regs(struct ucc_fast_private * uccf); + +#endif /* __UCC_FAST_H__ */ diff --git a/include/soc/fsl/qe/ucc_slow.h b/include/soc/fsl/qe/ucc_slow.h new file mode 100644 index 000000000000..6c0573a0825c --- /dev/null +++ b/include/soc/fsl/qe/ucc_slow.h @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved. + * + * Authors: Shlomi Gridish + * Li Yang + * + * Description: + * Internal header file for UCC SLOW unit routines. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef __UCC_SLOW_H__ +#define __UCC_SLOW_H__ + +#include + +#include +#include + +#include + +/* transmit BD's status */ +#define T_R 0x80000000 /* ready bit */ +#define T_PAD 0x40000000 /* add pads to short frames */ +#define T_W 0x20000000 /* wrap bit */ +#define T_I 0x10000000 /* interrupt on completion */ +#define T_L 0x08000000 /* last */ + +#define T_A 0x04000000 /* Address - the data transmitted as address + chars */ +#define T_TC 0x04000000 /* transmit CRC */ +#define T_CM 0x02000000 /* continuous mode */ +#define T_DEF 0x02000000 /* collision on previous attempt to transmit */ +#define T_P 0x01000000 /* Preamble - send Preamble sequence before + data */ +#define T_HB 0x01000000 /* heartbeat */ +#define T_NS 0x00800000 /* No Stop */ +#define T_LC 0x00800000 /* late collision */ +#define T_RL 0x00400000 /* retransmission limit */ +#define T_UN 0x00020000 /* underrun */ +#define T_CT 0x00010000 /* CTS lost */ +#define T_CSL 0x00010000 /* carrier sense lost */ +#define T_RC 0x003c0000 /* retry count */ + +/* Receive BD's status */ +#define R_E 0x80000000 /* buffer empty */ +#define R_W 0x20000000 /* wrap bit */ +#define R_I 0x10000000 /* interrupt on reception */ +#define R_L 0x08000000 /* last */ +#define R_C 0x08000000 /* the last byte in this buffer is a cntl + char */ +#define R_F 0x04000000 /* first */ +#define R_A 0x04000000 /* the first byte in this buffer is address + byte */ +#define R_CM 0x02000000 /* continuous mode */ +#define R_ID 0x01000000 /* buffer close on reception of idles */ +#define R_M 0x01000000 /* Frame received because of promiscuous + mode */ +#define R_AM 0x00800000 /* Address match */ +#define R_DE 0x00800000 /* Address match */ +#define R_LG 0x00200000 /* Break received */ +#define R_BR 0x00200000 /* Frame length violation */ +#define R_NO 0x00100000 /* Rx Non Octet Aligned Packet */ +#define R_FR 0x00100000 /* Framing Error (no stop bit) character + received */ +#define R_PR 0x00080000 /* Parity Error character received */ +#define R_AB 0x00080000 /* Frame Aborted */ +#define R_SH 0x00080000 /* frame is too short */ +#define R_CR 0x00040000 /* CRC Error */ +#define R_OV 0x00020000 /* Overrun */ +#define R_CD 0x00010000 /* CD lost */ +#define R_CL 0x00010000 /* this frame is closed because of a + collision */ + +/* Rx Data buffer must be 4 bytes aligned in most cases.*/ +#define UCC_SLOW_RX_ALIGN 4 +#define UCC_SLOW_MRBLR_ALIGNMENT 4 +#define UCC_SLOW_PRAM_SIZE 0x100 +#define ALIGNMENT_OF_UCC_SLOW_PRAM 64 + +/* UCC Slow Channel Protocol Mode */ +enum ucc_slow_channel_protocol_mode { + UCC_SLOW_CHANNEL_PROTOCOL_MODE_QMC = 0x00000002, + UCC_SLOW_CHANNEL_PROTOCOL_MODE_UART = 0x00000004, + UCC_SLOW_CHANNEL_PROTOCOL_MODE_BISYNC = 0x00000008, +}; + +/* UCC Slow Transparent Transmit CRC (TCRC) */ +enum ucc_slow_transparent_tcrc { + /* 16-bit CCITT CRC (HDLC). (X16 + X12 + X5 + 1) */ + UCC_SLOW_TRANSPARENT_TCRC_CCITT_CRC16 = 0x00000000, + /* CRC16 (BISYNC). (X16 + X15 + X2 + 1) */ + UCC_SLOW_TRANSPARENT_TCRC_CRC16 = 0x00004000, + /* 32-bit CCITT CRC (Ethernet and HDLC) */ + UCC_SLOW_TRANSPARENT_TCRC_CCITT_CRC32 = 0x00008000, +}; + +/* UCC Slow oversampling rate for transmitter (TDCR) */ +enum ucc_slow_tx_oversampling_rate { + /* 1x clock mode */ + UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_1 = 0x00000000, + /* 8x clock mode */ + UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_8 = 0x00010000, + /* 16x clock mode */ + UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_16 = 0x00020000, + /* 32x clock mode */ + UCC_SLOW_OVERSAMPLING_RATE_TX_TDCR_32 = 0x00030000, +}; + +/* UCC Slow Oversampling rate for receiver (RDCR) +*/ +enum ucc_slow_rx_oversampling_rate { + /* 1x clock mode */ + UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_1 = 0x00000000, + /* 8x clock mode */ + UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_8 = 0x00004000, + /* 16x clock mode */ + UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_16 = 0x00008000, + /* 32x clock mode */ + UCC_SLOW_OVERSAMPLING_RATE_RX_RDCR_32 = 0x0000c000, +}; + +/* UCC Slow Transmitter encoding method (TENC) +*/ +enum ucc_slow_tx_encoding_method { + UCC_SLOW_TRANSMITTER_ENCODING_METHOD_TENC_NRZ = 0x00000000, + UCC_SLOW_TRANSMITTER_ENCODING_METHOD_TENC_NRZI = 0x00000100 +}; + +/* UCC Slow Receiver decoding method (RENC) +*/ +enum ucc_slow_rx_decoding_method { + UCC_SLOW_RECEIVER_DECODING_METHOD_RENC_NRZ = 0x00000000, + UCC_SLOW_RECEIVER_DECODING_METHOD_RENC_NRZI = 0x00000800 +}; + +/* UCC Slow Diagnostic mode (DIAG) +*/ +enum ucc_slow_diag_mode { + UCC_SLOW_DIAG_MODE_NORMAL = 0x00000000, + UCC_SLOW_DIAG_MODE_LOOPBACK = 0x00000040, + UCC_SLOW_DIAG_MODE_ECHO = 0x00000080, + UCC_SLOW_DIAG_MODE_LOOPBACK_ECHO = 0x000000c0 +}; + +struct ucc_slow_info { + int ucc_num; + int protocol; /* QE_CR_PROTOCOL_xxx */ + enum qe_clock rx_clock; + enum qe_clock tx_clock; + phys_addr_t regs; + int irq; + u16 uccm_mask; + int data_mem_part; + int init_tx; + int init_rx; + u32 tx_bd_ring_len; + u32 rx_bd_ring_len; + int rx_interrupts; + int brkpt_support; + int grant_support; + int tsa; + int cdp; + int cds; + int ctsp; + int ctss; + int rinv; + int tinv; + int rtsm; + int rfw; + int tci; + int tend; + int tfl; + int txsy; + u16 max_rx_buf_length; + enum ucc_slow_transparent_tcrc tcrc; + enum ucc_slow_channel_protocol_mode mode; + enum ucc_slow_diag_mode diag; + enum ucc_slow_tx_oversampling_rate tdcr; + enum ucc_slow_rx_oversampling_rate rdcr; + enum ucc_slow_tx_encoding_method tenc; + enum ucc_slow_rx_decoding_method renc; +}; + +struct ucc_slow_private { + struct ucc_slow_info *us_info; + struct ucc_slow __iomem *us_regs; /* Ptr to memory map of UCC regs */ + struct ucc_slow_pram *us_pram; /* a pointer to the parameter RAM */ + u32 us_pram_offset; + int enabled_tx; /* Whether channel is enabled for Tx (ENT) */ + int enabled_rx; /* Whether channel is enabled for Rx (ENR) */ + int stopped_tx; /* Whether channel has been stopped for Tx + (STOP_TX, etc.) */ + int stopped_rx; /* Whether channel has been stopped for Rx */ + struct list_head confQ; /* frames passed to chip waiting for tx */ + u32 first_tx_bd_mask; /* mask is used in Tx routine to save status + and length for first BD in a frame */ + u32 tx_base_offset; /* first BD in Tx BD table offset (In MURAM) */ + u32 rx_base_offset; /* first BD in Rx BD table offset (In MURAM) */ + struct qe_bd *confBd; /* next BD for confirm after Tx */ + struct qe_bd *tx_bd; /* next BD for new Tx request */ + struct qe_bd *rx_bd; /* next BD to collect after Rx */ + void *p_rx_frame; /* accumulating receive frame */ + u16 *p_ucce; /* a pointer to the event register in memory. + */ + u16 *p_uccm; /* a pointer to the mask register in memory */ + u16 saved_uccm; /* a saved mask for the RX Interrupt bits */ +#ifdef STATISTICS + u32 tx_frames; /* Transmitted frames counters */ + u32 rx_frames; /* Received frames counters (only frames + passed to application) */ + u32 rx_discarded; /* Discarded frames counters (frames that + were discarded by the driver due to + errors) */ +#endif /* STATISTICS */ +}; + +/* ucc_slow_init + * Initializes Slow UCC according to provided parameters. + * + * us_info - (In) pointer to the slow UCC info structure. + * uccs_ret - (Out) pointer to the slow UCC structure. + */ +int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** uccs_ret); + +/* ucc_slow_free + * Frees all resources for slow UCC. + * + * uccs - (In) pointer to the slow UCC structure. + */ +void ucc_slow_free(struct ucc_slow_private * uccs); + +/* ucc_slow_enable + * Enables a fast UCC port. + * This routine enables Tx and/or Rx through the General UCC Mode Register. + * + * uccs - (In) pointer to the slow UCC structure. + * mode - (In) TX, RX, or both. + */ +void ucc_slow_enable(struct ucc_slow_private * uccs, enum comm_dir mode); + +/* ucc_slow_disable + * Disables a fast UCC port. + * This routine disables Tx and/or Rx through the General UCC Mode Register. + * + * uccs - (In) pointer to the slow UCC structure. + * mode - (In) TX, RX, or both. + */ +void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode); + +/* ucc_slow_graceful_stop_tx + * Smoothly stops transmission on a specified slow UCC. + * + * uccs - (In) pointer to the slow UCC structure. + */ +void ucc_slow_graceful_stop_tx(struct ucc_slow_private * uccs); + +/* ucc_slow_stop_tx + * Stops transmission on a specified slow UCC. + * + * uccs - (In) pointer to the slow UCC structure. + */ +void ucc_slow_stop_tx(struct ucc_slow_private * uccs); + +/* ucc_slow_restart_tx + * Restarts transmitting on a specified slow UCC. + * + * uccs - (In) pointer to the slow UCC structure. + */ +void ucc_slow_restart_tx(struct ucc_slow_private *uccs); + +u32 ucc_slow_get_qe_cr_subblock(int uccs_num); + +#endif /* __UCC_SLOW_H__ */ -- cgit v1.2.3 From c3d4879e01bec484f50a78c108341f039d470e96 Mon Sep 17 00:00:00 2001 From: Scott Mayhew Date: Fri, 11 Dec 2015 16:45:58 -0500 Subject: sunrpc: Add a function to close temporary transports immediately Add a function svc_age_temp_xprts_now() to close temporary transports whose xpt_local matches the address passed in server_addr immediately instead of waiting for them to be closed by the timer function. The function is intended to be used by notifier_blocks that will be added to nfsd and lockd that will run when an ip address is deleted. This will eliminate the ACK storms and client hangs that occur in HA-NFS configurations where nfsd & lockd is left running on the cluster nodes all the time and the NFS 'service' is migrated back and forth within a short timeframe. Signed-off-by: Scott Mayhew Signed-off-by: J. Bruce Fields --- include/linux/sunrpc/svc_xprt.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h index 78512cfe1fe6..b7dabc4baafd 100644 --- a/include/linux/sunrpc/svc_xprt.h +++ b/include/linux/sunrpc/svc_xprt.h @@ -128,6 +128,7 @@ struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name, const unsigned short port); int svc_xprt_names(struct svc_serv *serv, char *buf, const int buflen); void svc_add_new_perm_xprt(struct svc_serv *serv, struct svc_xprt *xprt); +void svc_age_temp_xprts_now(struct svc_serv *, struct sockaddr *); static inline void svc_xprt_get(struct svc_xprt *xprt) { -- cgit v1.2.3 From d8ce9bf5551bfea431893bdd0a943f24a5170828 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Sun, 27 Dec 2015 17:25:20 +0800 Subject: HID: move to_hid_device() to hid.h to_hid_device() macro is defined in both hid-lg4ff.c and hid-logitech-hidpp.c. So I move it to include/linux/hid.h. Signed-off-by: Geliang Tang Signed-off-by: Jiri Kosina --- include/linux/hid.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/hid.h b/include/linux/hid.h index a6d7a3fc2cb3..1472026367ed 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -565,6 +565,9 @@ struct hid_device { /* device report descriptor */ wait_queue_head_t debug_wait; }; +#define to_hid_device(pdev) \ + container_of(pdev, struct hid_device, dev) + static inline void *hid_get_drvdata(struct hid_device *hdev) { return dev_get_drvdata(&hdev->dev); -- cgit v1.2.3 From ba91a96718d17160890e161f702db6e60747248a Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Sun, 27 Dec 2015 17:25:22 +0800 Subject: HID: add a new helper to_hid_driver() Add a new helper to_hid_driver() and use it in hid-core.c. Signed-off-by: Geliang Tang Signed-off-by: Jiri Kosina --- include/linux/hid.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/hid.h b/include/linux/hid.h index 1472026367ed..75b66eccc692 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -717,6 +717,9 @@ struct hid_driver { struct device_driver driver; }; +#define to_hid_driver(pdrv) \ + container_of(pdrv, struct hid_driver, driver) + /** * hid_ll_driver - low level driver callbacks * @start: called on probe to start the device -- cgit v1.2.3 From 9a4bf31d05a801e2358d96f69b39fb8ce2c69dd8 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Thu, 10 Dec 2015 10:41:58 -0500 Subject: nfs: add new tracepoint for pnfs_update_layout pnfs_update_layout is really the "nexus" of layout handling. If it returns NULL then we end up going through the MDS. This patch adds some tracepoints to that function that allow us to determine the cause when we end up going through the MDS unexpectedly. Signed-off-by: Jeff Layton Signed-off-by: Trond Myklebust --- include/linux/nfs4.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include') diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index e7e78537aea2..0e30f2c5ff49 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -592,4 +592,18 @@ enum data_content4 { NFS4_CONTENT_HOLE = 1, }; +enum pnfs_update_layout_reason { + PNFS_UPDATE_LAYOUT_UNKNOWN = 0, + PNFS_UPDATE_LAYOUT_NO_PNFS, + PNFS_UPDATE_LAYOUT_RD_ZEROLEN, + PNFS_UPDATE_LAYOUT_MDSTHRESH, + PNFS_UPDATE_LAYOUT_NOMEM, + PNFS_UPDATE_LAYOUT_BULK_RECALL, + PNFS_UPDATE_LAYOUT_IO_TEST_FAIL, + PNFS_UPDATE_LAYOUT_FOUND_CACHED, + PNFS_UPDATE_LAYOUT_RETURN, + PNFS_UPDATE_LAYOUT_BLOCKED, + PNFS_UPDATE_LAYOUT_SEND_LAYOUTGET, +}; + #endif -- cgit v1.2.3 From 99ade3c71b1e40e7174d6527709399a87f3d05e0 Mon Sep 17 00:00:00 2001 From: Andrew Elble Date: Wed, 2 Dec 2015 09:39:51 -0500 Subject: nfs: machine credential support for additional operations Allow LAYOUTRETURN and DELEGRETURN to use machine credentials if the server supports it. Add request for OPEN_DOWNGRADE as the close path also uses that. Signed-off-by: Andrew Elble Signed-off-by: Trond Myklebust --- include/linux/nfs_fs_sb.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 2469ab0bb3a1..7fcc13c8cf1f 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -102,6 +102,7 @@ struct nfs_client { #define NFS_SP4_MACH_CRED_STATEID 4 /* TEST_STATEID and FREE_STATEID */ #define NFS_SP4_MACH_CRED_WRITE 5 /* WRITE */ #define NFS_SP4_MACH_CRED_COMMIT 6 /* COMMIT */ +#define NFS_SP4_MACH_CRED_PNFS_CLEANUP 7 /* LAYOUTRETURN */ #endif /* CONFIG_NFS_V4 */ /* Our own IP address, as a null-terminated string. -- cgit v1.2.3 From d6c843b96e1cb5199147e3281a724e3c0b69a9ab Mon Sep 17 00:00:00 2001 From: Peng Tao Date: Sat, 5 Dec 2015 16:20:43 +0800 Subject: nfs: only remove page from mapping if launder_page fails Instead of dropping pages when write fails, only do it when we get fatal failure in launder_page write back. Signed-off-by: Peng Tao Signed-off-by: Trond Myklebust --- include/linux/nfs_fs.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index c0e961474a52..b88fc46cfbb8 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -517,12 +517,24 @@ extern int nfs_updatepage(struct file *, struct page *, unsigned int, unsigned */ extern int nfs_sync_inode(struct inode *inode); extern int nfs_wb_all(struct inode *inode); -extern int nfs_wb_page(struct inode *inode, struct page* page); +extern int nfs_wb_single_page(struct inode *inode, struct page *page, bool launder); extern int nfs_wb_page_cancel(struct inode *inode, struct page* page); extern int nfs_commit_inode(struct inode *, int); extern struct nfs_commit_data *nfs_commitdata_alloc(void); extern void nfs_commit_free(struct nfs_commit_data *data); +static inline int +nfs_wb_launder_page(struct inode *inode, struct page *page) +{ + return nfs_wb_single_page(inode, page, true); +} + +static inline int +nfs_wb_page(struct inode *inode, struct page *page) +{ + return nfs_wb_single_page(inode, page, false); +} + static inline int nfs_have_writebacks(struct inode *inode) { -- cgit v1.2.3 From 37e9ed22b1552fa94ee7db2901a5e7d8bdf60b15 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 22 Dec 2015 12:30:24 -0500 Subject: pNFS: Add flag to track if we've called nfs4_ff_layout_stat_io_start_read/write Signed-off-by: Trond Myklebust --- include/linux/nfs_xdr.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 11bbae44f4cb..7b30ac0c7def 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1375,6 +1375,7 @@ enum { NFS_IOHDR_ERROR = 0, NFS_IOHDR_EOF, NFS_IOHDR_REDO, + NFS_IOHDR_STAT, }; struct nfs_pgio_header { @@ -1454,6 +1455,7 @@ struct nfs_commit_data { const struct rpc_call_ops *mds_ops; const struct nfs_commit_completion_ops *completion_ops; int (*commit_done_cb) (struct rpc_task *task, struct nfs_commit_data *data); + unsigned long flags; }; struct nfs_pgio_completion_ops { -- cgit v1.2.3 From dc602dd706cb64036132a7903ead1c67d9a7bcb9 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 31 Dec 2015 11:44:06 -0500 Subject: NFS/pNFS: Fix up pNFS write reschedule layering violations and bugs The flexfiles layout in particular, seems to want to poke around in the O_DIRECT flags when retransmitting. This patch sets up an interface to allow it to call back into O_DIRECT to handle retransmission correctly. It also fixes a potential bug whereby we could change the behaviour of O_DIRECT if an error is already pending. Signed-off-by: Trond Myklebust --- include/linux/nfs_xdr.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 11bbae44f4cb..e89dbb14138c 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1460,6 +1460,7 @@ struct nfs_pgio_completion_ops { void (*error_cleanup)(struct list_head *head); void (*init_hdr)(struct nfs_pgio_header *hdr); void (*completion)(struct nfs_pgio_header *hdr); + void (*reschedule_io)(struct nfs_pgio_header *hdr); }; struct nfs_unlinkdata { -- cgit v1.2.3 From af7cf057933f01dc7f33ddfb5e436ad598ed17ad Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 29 Sep 2015 20:34:05 -0400 Subject: NFS: Allow multiple commit requests in flight per file Allow synchronous RPC calls to wait for pending RPC calls to finish, but also allow asynchronous ones to just fire off another commit. With this patch, the xfstests generic/074 test completes in 226s instead of 242s Signed-off-by: Trond Myklebust --- include/linux/nfs_fs.h | 1 - include/linux/nfs_xdr.h | 1 - 2 files changed, 2 deletions(-) (limited to 'include') diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index c0e961474a52..ebf0bd72a42b 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -216,7 +216,6 @@ struct nfs_inode { #define NFS_INO_FLUSHING (4) /* inode is flushing out data */ #define NFS_INO_FSCACHE (5) /* inode can be cached by FS-Cache */ #define NFS_INO_FSCACHE_LOCK (6) /* FS-Cache cookie management lock */ -#define NFS_INO_COMMIT (7) /* inode is committing unstable writes */ #define NFS_INO_LAYOUTCOMMIT (9) /* layoutcommit required */ #define NFS_INO_LAYOUTCOMMITTING (10) /* layoutcommit inflight */ #define NFS_INO_LAYOUTSTATS (11) /* layoutstats inflight */ diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index e89dbb14138c..a8905b7d4d7f 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1423,7 +1423,6 @@ struct nfs_mds_commit_info { struct nfs_commit_data; struct nfs_inode; struct nfs_commit_completion_ops { - void (*error_cleanup) (struct nfs_inode *nfsi); void (*completion) (struct nfs_commit_data *data); }; -- cgit v1.2.3 From b20135d0b2431900a3a5395970ffb7e4f3767c8b Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Thu, 31 Dec 2015 09:28:06 -0500 Subject: NFSv4.1/pNFS: Don't queue up a new commit if the layout segment is invalid If the layout segment is invalid, then we should not be adding more write requests to the commit list. Instead, those writes should be replayed after requesting a new layout. Signed-off-by: Trond Myklebust --- include/linux/nfs_xdr.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index a8905b7d4d7f..bee3e60a7006 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -1420,10 +1420,12 @@ struct nfs_mds_commit_info { struct list_head list; }; +struct nfs_commit_info; struct nfs_commit_data; struct nfs_inode; struct nfs_commit_completion_ops { void (*completion) (struct nfs_commit_data *data); + void (*resched_write) (struct nfs_commit_info *, struct nfs_page *); }; struct nfs_commit_info { -- cgit v1.2.3 From d1b98c23f7547cc37c8f230acbedb26f0d47e9e1 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 1 Jan 2016 08:53:37 +0100 Subject: quota: constify qtree_fmt_operations structures The qtree_fmt_operations structures are never modified, so declare them as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: Jan Kara --- include/linux/dqblk_qtree.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/dqblk_qtree.h b/include/linux/dqblk_qtree.h index 82a16527b367..ff8b55359648 100644 --- a/include/linux/dqblk_qtree.h +++ b/include/linux/dqblk_qtree.h @@ -34,7 +34,7 @@ struct qtree_mem_dqinfo { unsigned int dqi_entry_size; /* Size of quota entry in quota file */ unsigned int dqi_usable_bs; /* Space usable in block for quota data */ unsigned int dqi_qtree_depth; /* Precomputed depth of quota tree */ - struct qtree_fmt_operations *dqi_ops; /* Operations for entry manipulation */ + const struct qtree_fmt_operations *dqi_ops; /* Operations for entry manipulation */ }; int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot); -- cgit v1.2.3 From 4acad4aae10d1fa79a075b38b5c73772c44f576c Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: Wed, 2 Dec 2015 10:38:21 +0000 Subject: spi: expose master transfer size limitation. On some SPI controllers it is not feasible to transfer arbitrary amount of data at once. When the limit on transfer size is a few kilobytes at least it makes sense to use the SPI hardware rather than reverting to gpio driver. The protocol drivers need a way to check that they do not sent overly long messages, though. Signed-off-by: Michal Suchanek Signed-off-by: Mark Brown --- include/linux/spi/spi.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'include') diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index cce80e6dc7d1..3eebc6c235fb 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -425,6 +425,12 @@ struct spi_master { #define SPI_MASTER_MUST_RX BIT(3) /* requires rx */ #define SPI_MASTER_MUST_TX BIT(4) /* requires tx */ + /* + * on some hardware transfer size may be constrained + * the limit may depend on device transfer settings + */ + size_t (*max_transfer_size)(struct spi_device *spi); + /* lock and mutex for SPI bus locking */ spinlock_t bus_lock_spinlock; struct mutex bus_lock_mutex; @@ -832,6 +838,15 @@ extern int spi_async(struct spi_device *spi, struct spi_message *message); extern int spi_async_locked(struct spi_device *spi, struct spi_message *message); +static inline size_t +spi_max_transfer_size(struct spi_device *spi) +{ + struct spi_master *master = spi->master; + if (!master->max_transfer_size) + return SIZE_MAX; + return master->max_transfer_size(spi); +} + /*---------------------------------------------------------------------------*/ /* All these synchronous SPI transfer routines are utilities layered -- cgit v1.2.3 From 9ebc6ef188a0656f3620835f9be7fe22c1644c1c Mon Sep 17 00:00:00 2001 From: Deepa Dinamani Date: Mon, 21 Dec 2015 10:51:01 +1100 Subject: drivers: md: use ktime_get_real_seconds() get_seconds() API is not y2038 safe on 32 bit systems and the API is deprecated. Replace it with calls to ktime_get_real_seconds() API instead. Change mddev structure types to time64_t accordingly. 32 bit signed timestamps will overflow in the year 2038. Change the user interface mdu_array_info_s structure timestamps: ctime and utime values used in ioctls GET_ARRAY_INFO and SET_ARRAY_INFO to unsigned int. This will extend the field to last until the year 2106. The long term plan is to get rid of ctime and utime values in this structure as this information can be read from the on-disk meta data directly. Clamp the tim64_t timestamps to positive values with a max of U32_MAX when returning from GET_ARRAY_INFO ioctl to accommodate above changes in the data type of timestamps to unsigned int. v0.90 on disk meta data uses u32 for maintaining time stamps. So this will also last until year 2106. Assumption is that the usage of v0.90 will be deprecated by year 2106. Timestamp fields in the on disk meta data for v1.0 version already use 64 bit data types. Remove the truncation of the bits while writing to or reading from these from the disk. Signed-off-by: Deepa Dinamani Reviewed-by: Arnd Bergmann Signed-off-by: NeilBrown --- include/uapi/linux/raid/md_u.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/uapi/linux/raid/md_u.h b/include/uapi/linux/raid/md_u.h index 1cb8aa6850b5..36cd8210a5d1 100644 --- a/include/uapi/linux/raid/md_u.h +++ b/include/uapi/linux/raid/md_u.h @@ -80,7 +80,7 @@ typedef struct mdu_array_info_s { int major_version; int minor_version; int patch_version; - int ctime; + unsigned int ctime; int level; int size; int nr_disks; @@ -91,7 +91,7 @@ typedef struct mdu_array_info_s { /* * Generic state information */ - int utime; /* 0 Superblock update time */ + unsigned int utime; /* 0 Superblock update time */ int state; /* 1 State bits (clean, ...) */ int active_disks; /* 2 Number of currently active disks */ int working_disks; /* 3 Number of working disks */ -- cgit v1.2.3 From d5e26bb1d812ba74f29b6bcbc88c3dbfb3eed824 Mon Sep 17 00:00:00 2001 From: "Matthew R. Ochs" Date: Mon, 14 Dec 2015 14:55:44 -0600 Subject: cxlflash: Fix to avoid virtual LUN failover failure Applications which use virtual LUN's that are backed by a physical LUN over both adapter ports may experience an I/O failure in the event of a link loss (e.g. cable pull). Virtual LUNs may be accessed through one or both ports of the adapter. This access is encoded in the translation entries that comprise the virtual LUN and used by the AFU for load-balancing I/O and handling failover scenarios. In a link loss scenario, even though the AFU is able to maintain connectivity to the LUN, it is up to the application to retry the failed I/O. When applications are unaware of the virtual LUN's underlying topology, they are unable to make a sound decision of when to retry an I/O and therefore are forced to make their reaction to a failed I/O absolute. The result is either a failure to retry I/O or increased latency for scenarios where a retry is pointless. To remedy this scenario, provide feedback back to the application on virtual LUN creation as to which ports the LUN may be accessed. LUN's spanning both ports are candidates for a retry in a presence of an I/O failure. Signed-off-by: Matthew R. Ochs Acked-by: Manoj Kumar Reviewed-by: Uma Krishnan Signed-off-by: Martin K. Petersen --- include/uapi/scsi/cxlflash_ioctl.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include') diff --git a/include/uapi/scsi/cxlflash_ioctl.h b/include/uapi/scsi/cxlflash_ioctl.h index 831351b2e660..2302f3ce5f86 100644 --- a/include/uapi/scsi/cxlflash_ioctl.h +++ b/include/uapi/scsi/cxlflash_ioctl.h @@ -30,6 +30,16 @@ struct dk_cxlflash_hdr { __u64 return_flags; /* Returned flags */ }; +/* + * Return flag definitions available to all ioctls + * + * Similar to the input flags, these are grown from the bottom-up with the + * intention that ioctl-specific return flag definitions would grow from the + * top-down, allowing the two sets to co-exist. While not required/enforced + * at this time, this provides future flexibility. + */ +#define DK_CXLFLASH_ALL_PORTS_ACTIVE 0x0000000000000001ULL + /* * Notes: * ----- -- cgit v1.2.3 From 6e9411923b8f4c0e568cbae0f35b7ee4eb989914 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Wed, 30 Dec 2015 20:32:03 +0100 Subject: mtd: nand: return consistent error codes in ecc.correct() implementations The error code returned by the ecc.correct() are not consistent over the all implementations. Document the expected behavior in include/linux/mtd/nand.h and fix offending implementations. [Brian: this looks like a bugfix for the ECC reporting in the bf5xx_nand driver, but we haven't seen any testing results for it] Signed-off-by: Boris Brezillon Tested-by: Franklin S Cooper Jr. Signed-off-by: Brian Norris --- include/linux/mtd/nand.h | 8 +++++++- include/linux/mtd/nand_bch.h | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 3e92be1d2d43..518958115182 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -456,7 +456,13 @@ struct nand_hw_control { * @hwctl: function to control hardware ECC generator. Must only * be provided if an hardware ECC is available * @calculate: function for ECC calculation or readback from ECC hardware - * @correct: function for ECC correction, matching to ECC generator (sw/hw) + * @correct: function for ECC correction, matching to ECC generator (sw/hw). + * Should return a positive number representing the number of + * corrected bitflips, -EBADMSG if the number of bitflips exceed + * ECC strength, or any other error code if the error is not + * directly related to correction. + * If -EBADMSG is returned the input buffers should be left + * untouched. * @read_page_raw: function to read a raw page without ECC. This function * should hide the specific layout used by the ECC * controller and always return contiguous in-band and diff --git a/include/linux/mtd/nand_bch.h b/include/linux/mtd/nand_bch.h index 74acf5367556..fb0bc3420a10 100644 --- a/include/linux/mtd/nand_bch.h +++ b/include/linux/mtd/nand_bch.h @@ -55,7 +55,7 @@ static inline int nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf, unsigned char *read_ecc, unsigned char *calc_ecc) { - return -1; + return -ENOTSUPP; } static inline struct nand_bch_control * -- cgit v1.2.3 From 40cbe6eee97b706f27bcc4c6aa1018bbe4f1e577 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Wed, 30 Dec 2015 20:32:04 +0100 Subject: mtd: nand: use nand_check_erased_ecc_chunk in default ECC read functions The default NAND read functions are relying on the underlying controller driver to correct bitflips, but some of those controllers cannot properly fix bitflips in erased pages. Check for bitflips in erased pages in default core functions if the driver delegated the this check by setting the NAND_ECC_GENERIC_ERASED_CHECK flag. Signed-off-by: Boris Brezillon Tested-by: Franklin S Cooper Jr. Signed-off-by: Brian Norris --- include/linux/mtd/nand.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include') diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 518958115182..86487dbe7358 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -129,6 +129,14 @@ typedef enum { /* Enable Hardware ECC before syndrome is read back from flash */ #define NAND_ECC_READSYN 2 +/* + * Enable generic NAND 'page erased' check. This check is only done when + * ecc.correct() returns -EBADMSG. + * Set this flag if your implementation does not fix bitflips in erased + * pages and you want to rely on the default implementation. + */ +#define NAND_ECC_GENERIC_ERASED_CHECK BIT(0) + /* Bit mask for flags passed to do_nand_read_ecc */ #define NAND_GET_DEVICE 0x80 @@ -451,6 +459,7 @@ struct nand_hw_control { * @total: total number of ECC bytes per page * @prepad: padding information for syndrome based ECC generators * @postpad: padding information for syndrome based ECC generators + * @options: ECC specific options (see NAND_ECC_XXX flags defined above) * @layout: ECC layout control struct pointer * @priv: pointer to private ECC control data * @hwctl: function to control hardware ECC generator. Must only @@ -500,6 +509,7 @@ struct nand_ecc_ctrl { int strength; int prepad; int postpad; + unsigned int options; struct nand_ecclayout *layout; void *priv; void (*hwctl)(struct mtd_info *mtd, int mode); -- cgit v1.2.3 From 2a297450dd188a5d4e5e428c189b2de54f9073ba Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 23 Dec 2015 22:25:13 +0100 Subject: lockd: constify nlmsvc_binding structure The nlmsvc_binding structure is never modified, so declare it as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall Signed-off-by: J. Bruce Fields --- include/linux/lockd/bind.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h index 4d24d64578c4..140edab64446 100644 --- a/include/linux/lockd/bind.h +++ b/include/linux/lockd/bind.h @@ -29,7 +29,7 @@ struct nlmsvc_binding { void (*fclose)(struct file *); }; -extern struct nlmsvc_binding * nlmsvc_ops; +extern const struct nlmsvc_binding *nlmsvc_ops; /* * Similar to nfs_client_initdata, but without the NFS-specific -- cgit v1.2.3 From d39ddbd9ef70949bb78283a067e1b3366111dd90 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Dec 2015 09:00:39 +0100 Subject: mtd: nand: add helpers to access ->priv Add two helpers to access the field reserved for private controller data. This makes it clearer what this field is reserved for and ease future refactoring. Signed-off-by: Boris Brezillon Signed-off-by: Brian Norris --- include/linux/mtd/nand.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include') diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 86487dbe7358..bdd68e22b5a5 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -755,6 +755,16 @@ static inline struct mtd_info *nand_to_mtd(struct nand_chip *chip) return &chip->mtd; } +static inline void *nand_get_controller_data(struct nand_chip *chip) +{ + return chip->priv; +} + +static inline void nand_set_controller_data(struct nand_chip *chip, void *priv) +{ + chip->priv = priv; +} + /* * NAND Flash Manufacturer ID Codes */ -- cgit v1.2.3 From 210c7c1750fdf769647d1d526c9ea34c412c9eee Mon Sep 17 00:00:00 2001 From: Benjamin Coddington Date: Wed, 6 Jan 2016 10:40:18 -0500 Subject: NFS: Use wait_on_atomic_t() for unlock after readahead The use of wait_on_atomic_t() for waiting on I/O to complete before unlocking allows us to git rid of the NFS_IO_INPROGRESS flag, and thus the nfs_iocounter's flags member, and finally the nfs_iocounter altogether. The count of I/O is moved to the lock context, and the counter increment/decrement functions become simple enough to open-code. Signed-off-by: Benjamin Coddington [Trond: Fix up conflict with existing function nfs_wait_atomic_killable()] Signed-off-by: Trond Myklebust --- include/linux/nfs_fs.h | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'include') diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 9eee972863a7..196aaceafda7 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -60,18 +60,12 @@ struct nfs_lockowner { pid_t l_pid; }; -#define NFS_IO_INPROGRESS 0 -struct nfs_io_counter { - unsigned long flags; - atomic_t io_count; -}; - struct nfs_lock_context { atomic_t count; struct list_head list; struct nfs_open_context *open_context; struct nfs_lockowner lockowner; - struct nfs_io_counter io_count; + atomic_t io_count; }; struct nfs4_state; -- cgit v1.2.3 From 5a023cdba50c5f5f2bc351783b3131699deb3937 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 30 Nov 2015 10:20:29 -0800 Subject: block: enable dax for raw block devices If an application wants exclusive access to all of the persistent memory provided by an NVDIMM namespace it can use this raw-block-dax facility to forgo establishing a filesystem. This capability is targeted primarily to hypervisors wanting to provision persistent memory for guests. It can be disabled / enabled dynamically via the new BLKDAXSET ioctl. Cc: Jeff Moyer Cc: Christoph Hellwig Cc: Dave Chinner Cc: Andrew Morton Cc: Ross Zwisler Reported-by: kbuild test robot Reviewed-by: Jan Kara Signed-off-by: Dan Williams --- include/linux/fs.h | 11 +++++++++++ include/uapi/linux/fs.h | 2 ++ 2 files changed, 13 insertions(+) (limited to 'include') diff --git a/include/linux/fs.h b/include/linux/fs.h index 3aa514254161..96fabc93b583 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -482,6 +482,9 @@ struct block_device { int bd_fsfreeze_count; /* Mutex for freeze */ struct mutex bd_fsfreeze_mutex; +#ifdef CONFIG_FS_DAX + int bd_map_count; +#endif }; /* @@ -2264,6 +2267,14 @@ extern struct super_block *freeze_bdev(struct block_device *); extern void emergency_thaw_all(void); extern int thaw_bdev(struct block_device *bdev, struct super_block *sb); extern int fsync_bdev(struct block_device *); +#ifdef CONFIG_FS_DAX +extern bool blkdev_dax_capable(struct block_device *bdev); +#else +static inline bool blkdev_dax_capable(struct block_device *bdev) +{ + return false; +} +#endif extern struct super_block *blockdev_superblock; diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h index f15d980249b5..401c409e9239 100644 --- a/include/uapi/linux/fs.h +++ b/include/uapi/linux/fs.h @@ -152,6 +152,8 @@ struct inodes_stat_t { #define BLKSECDISCARD _IO(0x12,125) #define BLKROTATIONAL _IO(0x12,126) #define BLKZEROOUT _IO(0x12,127) +#define BLKDAXSET _IO(0x12,128) +#define BLKDAXGET _IO(0x12,129) #define BMAP_IOCTL 1 /* obsolete - kept for compatibility */ #define FIBMAP _IO(0x00,1) /* bmap access */ -- cgit v1.2.3 From 9e0e252a048b0ba5066f0dc15c3b2468ffe5c422 Mon Sep 17 00:00:00 2001 From: Vishal Verma Date: Thu, 24 Dec 2015 19:20:32 -0700 Subject: badblocks: Add core badblock management code Take the core badblocks implementation from md, and make it generally available. This follows the same style as kernel implementations of linked lists, rb-trees etc, where you can have a structure that can be embedded anywhere, and accessor functions to manipulate the data. The only changes in this copy of the code are ones to generalize function/variable names from md-specific ones. Also add init and free functions. Signed-off-by: Vishal Verma Signed-off-by: Dan Williams --- include/linux/badblocks.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 include/linux/badblocks.h (limited to 'include') diff --git a/include/linux/badblocks.h b/include/linux/badblocks.h new file mode 100644 index 000000000000..929344630b51 --- /dev/null +++ b/include/linux/badblocks.h @@ -0,0 +1,53 @@ +#ifndef _LINUX_BADBLOCKS_H +#define _LINUX_BADBLOCKS_H + +#include +#include +#include +#include + +#define BB_LEN_MASK (0x00000000000001FFULL) +#define BB_OFFSET_MASK (0x7FFFFFFFFFFFFE00ULL) +#define BB_ACK_MASK (0x8000000000000000ULL) +#define BB_MAX_LEN 512 +#define BB_OFFSET(x) (((x) & BB_OFFSET_MASK) >> 9) +#define BB_LEN(x) (((x) & BB_LEN_MASK) + 1) +#define BB_ACK(x) (!!((x) & BB_ACK_MASK)) +#define BB_MAKE(a, l, ack) (((a)<<9) | ((l)-1) | ((u64)(!!(ack)) << 63)) + +/* Bad block numbers are stored sorted in a single page. + * 64bits is used for each block or extent. + * 54 bits are sector number, 9 bits are extent size, + * 1 bit is an 'acknowledged' flag. + */ +#define MAX_BADBLOCKS (PAGE_SIZE/8) + +struct badblocks { + int count; /* count of bad blocks */ + int unacked_exist; /* there probably are unacknowledged + * bad blocks. This is only cleared + * when a read discovers none + */ + int shift; /* shift from sectors to block size + * a -ve shift means badblocks are + * disabled.*/ + u64 *page; /* badblock list */ + int changed; + seqlock_t lock; + sector_t sector; + sector_t size; /* in sectors */ +}; + +int badblocks_check(struct badblocks *bb, sector_t s, int sectors, + sector_t *first_bad, int *bad_sectors); +int badblocks_set(struct badblocks *bb, sector_t s, int sectors, + int acknowledged); +int badblocks_clear(struct badblocks *bb, sector_t s, int sectors); +void ack_all_badblocks(struct badblocks *bb); +ssize_t badblocks_show(struct badblocks *bb, char *page, int unack); +ssize_t badblocks_store(struct badblocks *bb, const char *page, size_t len, + int unack); +int badblocks_init(struct badblocks *bb, int enable); +void badblocks_free(struct badblocks *bb); + +#endif -- cgit v1.2.3 From 99e6608c9e7414ae4f2168df8bf8fae3eb49e41f Mon Sep 17 00:00:00 2001 From: Vishal Verma Date: Sat, 9 Jan 2016 08:36:51 -0800 Subject: block: Add badblock management for gendisks NVDIMM devices, which can behave more like DRAM rather than block devices, may develop bad cache lines, or 'poison'. A block device exposed by the pmem driver can then consume poison via a read (or write), and cause a machine check. On platforms without machine check recovery features, this would mean a crash. The block device maintaining a runtime list of all known sectors that have poison can directly avoid this, and also provide a path forward to enable proper handling/recovery for DAX faults on such a device. Use the new badblock management interfaces to add a badblocks list to gendisks. Signed-off-by: Vishal Verma Signed-off-by: Dan Williams --- include/linux/genhd.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 847cc1d91634..0bbec6880051 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -162,6 +162,7 @@ struct disk_part_tbl { }; struct disk_events; +struct badblocks; #if defined(CONFIG_BLK_DEV_INTEGRITY) @@ -213,6 +214,7 @@ struct gendisk { struct kobject integrity_kobj; #endif /* CONFIG_BLK_DEV_INTEGRITY */ int node_id; + struct badblocks *bb; }; static inline struct gendisk *part_to_disk(struct hd_struct *part) @@ -433,6 +435,11 @@ extern void add_disk(struct gendisk *disk); extern void del_gendisk(struct gendisk *gp); extern struct gendisk *get_gendisk(dev_t dev, int *partno); extern struct block_device *bdget_disk(struct gendisk *disk, int partno); +int disk_alloc_badblocks(struct gendisk *disk); +extern int disk_check_badblocks(struct gendisk *disk, sector_t s, int sectors, + sector_t *first_bad, int *bad_sectors); +extern int disk_set_badblocks(struct gendisk *disk, sector_t s, int sectors); +extern int disk_clear_badblocks(struct gendisk *disk, sector_t s, int sectors); extern void set_device_ro(struct block_device *bdev, int flag); extern void set_disk_ro(struct gendisk *disk, int flag); -- cgit v1.2.3 From 0caeef63e6d2f866d85bb507bf63e0ce8ec91cef Mon Sep 17 00:00:00 2001 From: Vishal Verma Date: Thu, 24 Dec 2015 19:21:43 -0700 Subject: libnvdimm: Add a poison list and export badblocks During region creation, perform Address Range Scrubs (ARS) for the SPA (System Physical Address) ranges to retrieve known poison locations from firmware. Add a new data structure 'nd_poison' which is used as a list in nvdimm_bus to store these poison locations. When creating a pmem namespace, if there is any known poison associated with its physical address space, convert the poison ranges to bad sectors that are exposed using the badblocks interface. Signed-off-by: Vishal Verma Signed-off-by: Dan Williams --- include/linux/libnvdimm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h index 3f021dc5da8c..bed40dff0e86 100644 --- a/include/linux/libnvdimm.h +++ b/include/linux/libnvdimm.h @@ -116,6 +116,7 @@ static inline struct nd_blk_region_desc *to_blk_region_desc( } +int nvdimm_bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length); struct nvdimm_bus *__nvdimm_bus_register(struct device *parent, struct nvdimm_bus_descriptor *nfit_desc, struct module *module); #define nvdimm_bus_register(parent, desc) \ -- cgit v1.2.3 From d3b407fb3f782bd915db64e266010ea30a2d381e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 6 Jan 2016 12:19:22 -0800 Subject: badblocks: rename badblocks_free to badblocks_exit For symmetry with badblocks_init() make it clear that this path only destroys incremental allocations of a badblocks instance, and does not free the badblocks instance itself. Signed-off-by: Dan Williams --- include/linux/badblocks.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/badblocks.h b/include/linux/badblocks.h index 929344630b51..2d98c026c57f 100644 --- a/include/linux/badblocks.h +++ b/include/linux/badblocks.h @@ -48,6 +48,6 @@ ssize_t badblocks_show(struct badblocks *bb, char *page, int unack); ssize_t badblocks_store(struct badblocks *bb, const char *page, size_t len, int unack); int badblocks_init(struct badblocks *bb, int enable); -void badblocks_free(struct badblocks *bb); +void badblocks_exit(struct badblocks *bb); #endif -- cgit v1.2.3 From 16263ff6c72eb4cc00aa287230144dda12ccad12 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 4 Jan 2016 23:50:23 -0800 Subject: block, badblocks: introduce devm_init_badblocks Provide a devres interface for initializing a badblocks instance. The pmem driver has several scenarios where it will be beneficial to have this structure automatically freed when the device is disabled / fails probe. Signed-off-by: Dan Williams --- include/linux/badblocks.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/badblocks.h b/include/linux/badblocks.h index 2d98c026c57f..c3bdf8c59480 100644 --- a/include/linux/badblocks.h +++ b/include/linux/badblocks.h @@ -2,6 +2,7 @@ #define _LINUX_BADBLOCKS_H #include +#include #include #include #include @@ -23,6 +24,7 @@ #define MAX_BADBLOCKS (PAGE_SIZE/8) struct badblocks { + struct device *dev; /* set by devm_init_badblocks */ int count; /* count of bad blocks */ int unacked_exist; /* there probably are unacknowledged * bad blocks. This is only cleared @@ -49,5 +51,15 @@ ssize_t badblocks_store(struct badblocks *bb, const char *page, size_t len, int unack); int badblocks_init(struct badblocks *bb, int enable); void badblocks_exit(struct badblocks *bb); - +struct device; +int devm_init_badblocks(struct device *dev, struct badblocks *bb); +static inline void devm_exit_badblocks(struct device *dev, struct badblocks *bb) +{ + if (bb->dev != dev) { + dev_WARN_ONCE(dev, 1, "%s: badblocks instance not associated\n", + __func__); + return; + } + badblocks_exit(bb); +} #endif -- cgit v1.2.3 From 55f5560d8c18fe33fc169f8d244a9247dcac7612 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 5 Jan 2016 00:28:18 -0800 Subject: block: kill disk_{check|set|clear|alloc}_badblocks These actions are completely managed by a block driver or can use the badblocks api directly. Signed-off-by: Dan Williams --- include/linux/genhd.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 0bbec6880051..5c706765404a 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -435,11 +435,6 @@ extern void add_disk(struct gendisk *disk); extern void del_gendisk(struct gendisk *gp); extern struct gendisk *get_gendisk(dev_t dev, int *partno); extern struct block_device *bdget_disk(struct gendisk *disk, int partno); -int disk_alloc_badblocks(struct gendisk *disk); -extern int disk_check_badblocks(struct gendisk *disk, sector_t s, int sectors, - sector_t *first_bad, int *bad_sectors); -extern int disk_set_badblocks(struct gendisk *disk, sector_t s, int sectors); -extern int disk_clear_badblocks(struct gendisk *disk, sector_t s, int sectors); extern void set_device_ro(struct block_device *bdev, int flag); extern void set_disk_ro(struct gendisk *disk, int flag); -- cgit v1.2.3 From f199d39349beabcb1a374cb02e0845a0ae84f3fd Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 14 Dec 2015 10:19:11 +0000 Subject: mfd: arizona: Add device tree binding to specify mono outputs Add device tree bindings to support specifying outputs from the chip as mono outputs. Whilst we are doing it change the out_mono pdata from a bool to an int, because Sparse gets upset about using ARRAY_SIZE on bools. Signed-off-by: Charles Keepax Signed-off-by: Lee Jones --- include/linux/mfd/arizona/pdata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h index 57b45caaea80..64faeeff698c 100644 --- a/include/linux/mfd/arizona/pdata.h +++ b/include/linux/mfd/arizona/pdata.h @@ -171,7 +171,7 @@ struct arizona_pdata { int inmode[ARIZONA_MAX_INPUT]; /** Mode for outputs */ - bool out_mono[ARIZONA_MAX_OUTPUT]; + int out_mono[ARIZONA_MAX_OUTPUT]; /** PDM speaker mute setting */ unsigned int spk_mute[ARIZONA_MAX_PDM_SPK]; -- cgit v1.2.3 From d062f91193dbd5a0c1d8469c8517ec8dd552c3f2 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Wed, 3 Jun 2015 12:12:53 -0300 Subject: [media] media: new media controller API for device resource support Add new media controller API to allocate media device as a device resource. When a media device is created on the main struct device which is the parent device for the interface device, it will be available to all drivers associated with that interface. For example, if a usb media device driver creates the media device on the main struct device which is common for all the drivers that control the media device, including the non-media ALSA driver, media controller API can be used to share access to the resources on the media device. This new interface provides the above described feature. A second interface that finds and returns the media device is added to allow drivers to find the media device created by any of the drivers associated with the device. Signed-off-by: Shuah Khan Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index 6e6db78f1ee2..22792cd5b1d1 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -95,6 +95,8 @@ void media_device_unregister(struct media_device *mdev); int __must_check media_device_register_entity(struct media_device *mdev, struct media_entity *entity); void media_device_unregister_entity(struct media_entity *entity); +struct media_device *media_device_get_devres(struct device *dev); +struct media_device *media_device_find_devres(struct device *dev); /* Iterate over all entities. */ #define media_device_for_each_entity(entity, mdev) \ -- cgit v1.2.3 From e576d60bb21e7add884f052ff0e5c28ebf7b7461 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Fri, 5 Jun 2015 17:11:54 -0300 Subject: [media] media: define Media Controller API when CONFIG_MEDIA_CONTROLLER enabled Change to define Media Controller API when CONFIG_MEDIA_CONTROLLER is enabled. Define stubs for CONFIG_MEDIA_CONTROLLER disabled case. This will help avoid drivers needing to enclose Media Controller code within ifdef CONFIG_MEDIA_CONTROLLER block. Signed-off-by: Shuah Khan Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index 22792cd5b1d1..a44f18fdf321 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -80,6 +80,8 @@ struct media_device { unsigned int notification); }; +#ifdef CONFIG_MEDIA_CONTROLLER + /* Supported link_notify @notification values. */ #define MEDIA_DEV_NOTIFY_PRE_LINK_CH 0 #define MEDIA_DEV_NOTIFY_POST_LINK_CH 1 @@ -102,4 +104,29 @@ struct media_device *media_device_find_devres(struct device *dev); #define media_device_for_each_entity(entity, mdev) \ list_for_each_entry(entity, &(mdev)->entities, list) +#else +static inline int media_device_register(struct media_device *mdev) +{ + return 0; +} +static inline void media_device_unregister(struct media_device *mdev) +{ +} +static inline int media_device_register_entity(struct media_device *mdev, + struct media_entity *entity) +{ + return 0; +} +static inline void media_device_unregister_entity(struct media_entity *entity) +{ +} +static inline struct media_device *media_device_get_devres(struct device *dev) +{ + return NULL; +} +static inline struct media_device *media_device_find_devres(struct device *dev) +{ + return NULL; +} +#endif /* CONFIG_MEDIA_CONTROLLER */ #endif -- cgit v1.2.3 From 1809510715c4187fa7338204cac53e30326d5d04 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 6 Aug 2015 09:25:57 -0300 Subject: [media] media: get rid of unused "extra_links" param on media_entity_init() Currently, media_entity_init() creates an array with the links, allocated at init time. It provides a parameter (extra_links) that would allocate more links than the current needs, but this is not used by any driver. As we want to be able to do dynamic link allocation/removal, we'll need to change the implementation of the links. So, before doing that, let's first remove that extra unused parameter, in order to cleanup the interface first. Signed-off-by: Mauro Carvalho Chehab Acked-by: Sakari Ailus Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 197f93799753..b92366317aee 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -134,7 +134,7 @@ struct media_entity_graph { }; int media_entity_init(struct media_entity *entity, u16 num_pads, - struct media_pad *pads, u16 extra_links); + struct media_pad *pads); void media_entity_cleanup(struct media_entity *entity); int media_entity_create_link(struct media_entity *source, u16 source_pad, -- cgit v1.2.3 From fa762394fd85c838ade769990478bc4e01fd95e8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Aug 2015 10:42:05 -0300 Subject: [media] media: create a macro to get entity ID Instead of accessing directly entity.id, let's create a macro, as this field will be moved into a common struct later on. Acked-by: Hans Verkuil Reviewed-by: Javier Martinez Canillas Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index b92366317aee..57881758927e 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -113,6 +113,11 @@ static inline u32 media_entity_subtype(struct media_entity *entity) return entity->type & MEDIA_ENT_SUBTYPE_MASK; } +static inline u32 media_entity_id(struct media_entity *entity) +{ + return entity->id; +} + #define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 #define MEDIA_ENTITY_ENUM_MAX_ID 64 -- cgit v1.2.3 From ec6e4c950621a1d0db1e9b015ede4a3938fdfd18 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 25 Aug 2015 10:28:36 -0300 Subject: [media] media: add a common struct to be embed on media graph objects Due to the MC API proposed changes, we'll need to have an unique object ID for all graph objects, and have some shared fields that will be common on all media graph objects. Right now, the only common object is the object ID, but other fields will be added later on. Acked-by: Hans Verkuil Reviewed-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 61 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 57881758927e..96626356b8f3 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -28,6 +28,39 @@ #include #include +/* Enums used internally at the media controller to represent graphs */ + +/** + * enum media_gobj_type - type of a graph object + * + */ +enum media_gobj_type { + /* FIXME: add the types here, as we embed media_gobj */ + MEDIA_GRAPH_NONE +}; + +#define MEDIA_BITS_PER_TYPE 8 +#define MEDIA_BITS_PER_LOCAL_ID (32 - MEDIA_BITS_PER_TYPE) +#define MEDIA_LOCAL_ID_MASK GENMASK(MEDIA_BITS_PER_LOCAL_ID - 1, 0) + +/* Structs to represent the objects that belong to a media graph */ + +/** + * struct media_gobj - Define a graph object. + * + * @id: Non-zero object ID identifier. The ID should be unique + * inside a media_device, as it is composed by + * MEDIA_BITS_PER_TYPE to store the type plus + * MEDIA_BITS_PER_LOCAL_ID to store a per-type ID + * (called as "local ID"). + * + * All objects on the media graph should have this struct embedded + */ +struct media_gobj { + u32 id; +}; + + struct media_pipeline { }; @@ -118,6 +151,26 @@ static inline u32 media_entity_id(struct media_entity *entity) return entity->id; } +static inline enum media_gobj_type media_type(struct media_gobj *gobj) +{ + return gobj->id >> MEDIA_BITS_PER_LOCAL_ID; +} + +static inline u32 media_localid(struct media_gobj *gobj) +{ + return gobj->id & MEDIA_LOCAL_ID_MASK; +} + +static inline u32 media_gobj_gen_id(enum media_gobj_type type, u32 local_id) +{ + u32 id; + + id = type << MEDIA_BITS_PER_LOCAL_ID; + id |= local_id & MEDIA_LOCAL_ID_MASK; + + return id; +} + #define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 #define MEDIA_ENTITY_ENUM_MAX_ID 64 @@ -138,6 +191,14 @@ struct media_entity_graph { int top; }; +#define gobj_to_entity(gobj) \ + container_of(gobj, struct media_entity, graph_obj) + +void media_gobj_init(struct media_device *mdev, + enum media_gobj_type type, + struct media_gobj *gobj); +void media_gobj_remove(struct media_gobj *gobj); + int media_entity_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads); void media_entity_cleanup(struct media_entity *entity); -- cgit v1.2.3 From bfab2aacccfc144e2cceccb71ec89f1eff1b8c51 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Aug 2015 12:47:48 -0300 Subject: [media] media: use media_gobj inside entities As entities are graph objects, let's embed media_gobj on it. That ensures an unique ID for entities that can be global along the entire media controller. For now, we'll keep the already existing entity ID. Such field need to be dropped at some point, but for now, let's not do this, to avoid needing to review all drivers and the userspace apps. Acked-by: Hans Verkuil Tested-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 3 ++- include/media/media-entity.h | 9 ++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index a44f18fdf321..f6deef6e5820 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -41,7 +41,7 @@ struct device; * @bus_info: Unique and stable device location identifier * @hw_revision: Hardware device revision * @driver_version: Device driver version - * @entity_id: ID of the next entity to be registered + * @entity_id: Unique ID used on the last entity registered * @entities: List of registered entities * @lock: Entities list lock * @graph_mutex: Entities graph operation lock @@ -69,6 +69,7 @@ struct media_device { u32 driver_version; u32 entity_id; + struct list_head entities; /* Protects the entities list */ diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 96626356b8f3..4faa4d830da4 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -33,10 +33,10 @@ /** * enum media_gobj_type - type of a graph object * + * @MEDIA_GRAPH_ENTITY: Identify a media entity */ enum media_gobj_type { - /* FIXME: add the types here, as we embed media_gobj */ - MEDIA_GRAPH_NONE + MEDIA_GRAPH_ENTITY, }; #define MEDIA_BITS_PER_TYPE 8 @@ -94,10 +94,9 @@ struct media_entity_operations { }; struct media_entity { + struct media_gobj graph_obj; struct list_head list; struct media_device *parent; /* Media device this entity belongs to*/ - u32 id; /* Entity ID, unique in the parent media - * device context */ const char *name; /* Entity name */ u32 type; /* Entity type (MEDIA_ENT_T_*) */ u32 revision; /* Entity revision, driver specific */ @@ -148,7 +147,7 @@ static inline u32 media_entity_subtype(struct media_entity *entity) static inline u32 media_entity_id(struct media_entity *entity) { - return entity->id; + return entity->graph_obj.id; } static inline enum media_gobj_type media_type(struct media_gobj *gobj) -- cgit v1.2.3 From 18710dc67a433ed2c3ecaaffefd8e34502e53262 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Aug 2015 12:50:08 -0300 Subject: [media] media: use media_gobj inside pads PADs also need unique object IDs that won't conflict with the entity object IDs. The pad objects are currently created via media_entity_init() and, once created, never change. While this will likely change in the future in order to support dynamic changes, for now we'll keep PADs as arrays and initialize the media_gobj embedded structs when registering the entity. Acked-by: Hans Verkuil Tested-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 2 ++ include/media/media-entity.h | 3 +++ 2 files changed, 5 insertions(+) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index f6deef6e5820..9493721f630e 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -42,6 +42,7 @@ struct device; * @hw_revision: Hardware device revision * @driver_version: Device driver version * @entity_id: Unique ID used on the last entity registered + * @pad_id: Unique ID used on the last pad registered * @entities: List of registered entities * @lock: Entities list lock * @graph_mutex: Entities graph operation lock @@ -69,6 +70,7 @@ struct media_device { u32 driver_version; u32 entity_id; + u32 pad_id; struct list_head entities; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 4faa4d830da4..b91c78d34f79 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -34,9 +34,11 @@ * enum media_gobj_type - type of a graph object * * @MEDIA_GRAPH_ENTITY: Identify a media entity + * @MEDIA_GRAPH_PAD: Identify a media pad */ enum media_gobj_type { MEDIA_GRAPH_ENTITY, + MEDIA_GRAPH_PAD, }; #define MEDIA_BITS_PER_TYPE 8 @@ -72,6 +74,7 @@ struct media_link { }; struct media_pad { + struct media_gobj graph_obj; struct media_entity *entity; /* Entity this pad belongs to */ u16 index; /* Pad index in the entity pads array */ unsigned long flags; /* Pad flags (MEDIA_PAD_FL_*) */ -- cgit v1.2.3 From 6b6a42780597028135f82c96e42c6d2bcd83fbae Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 14 Aug 2015 12:54:36 -0300 Subject: [media] media: use media_gobj inside links Just like entities and pads, links also need to have unique Object IDs along a given media controller. So, let's add a media_gobj inside it and initialize the object then a new link is created. Acked-by: Hans Verkuil Tested-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 2 ++ include/media/media-entity.h | 3 +++ 2 files changed, 5 insertions(+) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index 9493721f630e..05414e351f8e 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -43,6 +43,7 @@ struct device; * @driver_version: Device driver version * @entity_id: Unique ID used on the last entity registered * @pad_id: Unique ID used on the last pad registered + * @link_id: Unique ID used on the last link registered * @entities: List of registered entities * @lock: Entities list lock * @graph_mutex: Entities graph operation lock @@ -71,6 +72,7 @@ struct media_device { u32 entity_id; u32 pad_id; + u32 link_id; struct list_head entities; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index b91c78d34f79..bf93c90e9218 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -35,10 +35,12 @@ * * @MEDIA_GRAPH_ENTITY: Identify a media entity * @MEDIA_GRAPH_PAD: Identify a media pad + * @MEDIA_GRAPH_LINK: Identify a media link */ enum media_gobj_type { MEDIA_GRAPH_ENTITY, MEDIA_GRAPH_PAD, + MEDIA_GRAPH_LINK, }; #define MEDIA_BITS_PER_TYPE 8 @@ -67,6 +69,7 @@ struct media_pipeline { }; struct media_link { + struct media_gobj graph_obj; struct media_pad *source; /* Source pad */ struct media_pad *sink; /* Sink pad */ struct media_link *reverse; /* Link in the reverse direction */ -- cgit v1.2.3 From 39a956c4147e4f696f729916f677673e9a9dc7ab Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 13 Aug 2015 14:42:42 -0300 Subject: [media] media: add a debug message to warn about gobj creation/removal It helps to check if the media controller is doing the right thing with the object creation and removal. No extra code/data will be produced if DEBUG or CONFIG_DYNAMIC_DEBUG is not enabled. Acked-by: Hans Verkuil Reviewed-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index bf93c90e9218..96a5d3e6f6f4 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -61,6 +61,7 @@ enum media_gobj_type { * All objects on the media graph should have this struct embedded */ struct media_gobj { + struct media_device *mdev; u32 id; }; @@ -199,6 +200,12 @@ struct media_entity_graph { #define gobj_to_entity(gobj) \ container_of(gobj, struct media_entity, graph_obj) +#define gobj_to_pad(gobj) \ + container_of(gobj, struct media_pad, graph_obj) + +#define gobj_to_link(gobj) \ + container_of(gobj, struct media_link, graph_obj) + void media_gobj_init(struct media_device *mdev, enum media_gobj_type type, struct media_gobj *gobj); -- cgit v1.2.3 From 8df00a15817e3a252510ac914870214859325189 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 7 Aug 2015 08:14:38 -0300 Subject: [media] media: rename the function that create pad links With the new API, a link can be either between two PADs or between an interface and an entity. So, we need to use a better name for the function that create links between two pads. So, rename the such function to media_create_pad_link(). No functional changes. This patch was created via this shell script: for i in $(find drivers/media -name '*.[ch]' -type f) $(find drivers/staging/media -name '*.[ch]' -type f) $(find include/ -name '*.h' -type f) ; do sed s,media_entity_create_link,media_create_pad_link,g <$i >a && mv a $i; done Acked-by: Hans Verkuil Tested-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 96a5d3e6f6f4..ad9e16e5e44d 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -215,7 +215,7 @@ int media_entity_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads); void media_entity_cleanup(struct media_entity *entity); -int media_entity_create_link(struct media_entity *source, u16 source_pad, +int media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flags); void __media_entity_remove_links(struct media_entity *entity); void media_entity_remove_links(struct media_entity *entity); -- cgit v1.2.3 From b42ff142b8d880427e8c30b05de71b841a67aaad Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Wed, 19 Aug 2015 12:35:22 -0300 Subject: [media] media: remove media entity .parent field Now that the struct media_entity .parent field is unused, it can be safely removed. Since all the previous users were converted to use the .mdev field from the embedded struct media_gobj instead. Signed-off-by: Javier Martinez Canillas Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index ad9e16e5e44d..a493dd9910f4 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -103,7 +103,6 @@ struct media_entity_operations { struct media_entity { struct media_gobj graph_obj; struct list_head list; - struct media_device *parent; /* Media device this entity belongs to*/ const char *name; /* Entity name */ u32 type; /* Entity type (MEDIA_ENT_T_*) */ u32 revision; /* Entity revision, driver specific */ -- cgit v1.2.3 From a1d2510ebd7a14f0d1a89c138101beaeac076dd2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Aug 2015 07:43:07 -0300 Subject: [media] uapi/media.h: Declare interface types for V4L2 and DVB Declare the interface types that will be used by the new G_TOPOLOGY ioctl that will be defined later on. For now, we need those types, as they'll be used on the internal structs associated with the new media_interface graph object defined on the next patch. Acked-by: Hans Verkuil Reviewed-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/media.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'include') diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 4e816be3de39..3ad3d6be293f 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -167,6 +167,27 @@ struct media_links_enum { __u32 reserved[4]; }; +/* Interface type ranges */ + +#define MEDIA_INTF_T_DVB_BASE 0x00000100 +#define MEDIA_INTF_T_V4L_BASE 0x00000200 + +/* Interface types */ + +#define MEDIA_INTF_T_DVB_FE (MEDIA_INTF_T_DVB_BASE) +#define MEDIA_INTF_T_DVB_DEMUX (MEDIA_INTF_T_DVB_BASE + 1) +#define MEDIA_INTF_T_DVB_DVR (MEDIA_INTF_T_DVB_BASE + 2) +#define MEDIA_INTF_T_DVB_CA (MEDIA_INTF_T_DVB_BASE + 3) +#define MEDIA_INTF_T_DVB_NET (MEDIA_INTF_T_DVB_BASE + 4) + +#define MEDIA_INTF_T_V4L_VIDEO (MEDIA_INTF_T_V4L_BASE) +#define MEDIA_INTF_T_V4L_VBI (MEDIA_INTF_T_V4L_BASE + 1) +#define MEDIA_INTF_T_V4L_RADIO (MEDIA_INTF_T_V4L_BASE + 2) +#define MEDIA_INTF_T_V4L_SUBDEV (MEDIA_INTF_T_V4L_BASE + 3) +#define MEDIA_INTF_T_V4L_SWRADIO (MEDIA_INTF_T_V4L_BASE + 4) + +/* TBD: declare the structs needed for the new G_TOPOLOGY ioctl */ + #define MEDIA_IOC_DEVICE_INFO _IOWR('|', 0x00, struct media_device_info) #define MEDIA_IOC_ENUM_ENTITIES _IOWR('|', 0x01, struct media_entity_desc) #define MEDIA_IOC_ENUM_LINKS _IOWR('|', 0x02, struct media_links_enum) -- cgit v1.2.3 From 27e543fa87deea308f0cc5224ab19e397b0a5ded Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Aug 2015 09:07:34 -0300 Subject: [media] media: add functions to allow creating interfaces Interfaces are different than entities: they represent a Kernel<->userspace interaction, while entities represent a piece of hardware/firmware/software that executes a function. Let's distinguish them by creating a separate structure to store the interfaces. Later patches should change the existing drivers and logic to split the current interface embedded inside the entity structure (device nodes) into a separate object of the graph. Acked-by: Hans Verkuil Reviewed-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 2 ++ include/media/media-entity.h | 48 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index 05414e351f8e..3b14394d5701 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -44,6 +44,7 @@ struct device; * @entity_id: Unique ID used on the last entity registered * @pad_id: Unique ID used on the last pad registered * @link_id: Unique ID used on the last link registered + * @intf_devnode_id: Unique ID used on the last interface devnode registered * @entities: List of registered entities * @lock: Entities list lock * @graph_mutex: Entities graph operation lock @@ -73,6 +74,7 @@ struct media_device { u32 entity_id; u32 pad_id; u32 link_id; + u32 intf_devnode_id; struct list_head entities; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index a493dd9910f4..4d5fc91c4134 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -36,11 +36,14 @@ * @MEDIA_GRAPH_ENTITY: Identify a media entity * @MEDIA_GRAPH_PAD: Identify a media pad * @MEDIA_GRAPH_LINK: Identify a media link + * @MEDIA_GRAPH_INTF_DEVNODE: Identify a media Kernel API interface via + * a device node */ enum media_gobj_type { MEDIA_GRAPH_ENTITY, MEDIA_GRAPH_PAD, MEDIA_GRAPH_LINK, + MEDIA_GRAPH_INTF_DEVNODE, }; #define MEDIA_BITS_PER_TYPE 8 @@ -141,6 +144,34 @@ struct media_entity { } info; }; +/** + * struct media_intf_devnode - Define a Kernel API interface + * + * @graph_obj: embedded graph object + * @type: Type of the interface as defined at the + * uapi/media/media.h header, e. g. + * MEDIA_INTF_T_* + * @flags: Interface flags as defined at uapi/media/media.h + */ +struct media_interface { + struct media_gobj graph_obj; + u32 type; + u32 flags; +}; + +/** + * struct media_intf_devnode - Define a Kernel API interface via a device node + * + * @intf: embedded interface object + * @major: Major number of a device node + * @minor: Minor number of a device node + */ +struct media_intf_devnode { + struct media_interface intf; + u32 major; + u32 minor; +}; + static inline u32 media_entity_type(struct media_entity *entity) { return entity->type & MEDIA_ENT_TYPE_MASK; @@ -205,6 +236,18 @@ struct media_entity_graph { #define gobj_to_link(gobj) \ container_of(gobj, struct media_link, graph_obj) +#define gobj_to_link(gobj) \ + container_of(gobj, struct media_link, graph_obj) + +#define gobj_to_pad(gobj) \ + container_of(gobj, struct media_pad, graph_obj) + +#define gobj_to_intf(gobj) \ + container_of(gobj, struct media_interface, graph_obj) + +#define intf_to_devnode(intf) \ + container_of(intf, struct media_intf_devnode, intf) + void media_gobj_init(struct media_device *mdev, enum media_gobj_type type, struct media_gobj *gobj); @@ -236,6 +279,11 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, struct media_pipeline *pipe); void media_entity_pipeline_stop(struct media_entity *entity); +struct media_intf_devnode *media_devnode_create(struct media_device *mdev, + u32 type, u32 flags, + u32 major, u32 minor, + gfp_t gfp_flags); +void media_devnode_remove(struct media_intf_devnode *devnode); #define media_entity_call(entity, operation, args...) \ (((entity)->ops && (entity)->ops->operation) ? \ (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD) -- cgit v1.2.3 From 57208e5e25f263d27ea00e530c95f62071573cb7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 7 Aug 2015 06:55:40 -0300 Subject: [media] media: convert links from array to list The entire logic that represent graph links were developed on a time where there were no needs to dynamic remove links. So, although links are created/removed one by one via some functions, they're stored as an array inside the entity struct. As the array may grow, there's a logic inside the code that checks if the amount of space is not enough to store the needed links. If it isn't the core uses krealloc() to change the size of the link, with is bad, as it leaves the memory fragmented. So, convert links into a list. Also, currently, both source and sink entities need the link at the graph traversal logic inside media_entity. So there's a logic duplicating all links. That makes it to spend twice the memory needed. This is not a big deal for today's usage, where the number of links are not big. Yet, if during the MC workshop discussions, it was said that IIO graphs could have up to 4,000 entities. So, we may want to remove the duplication on some future. The problem is that it would require a separate linked list to store the backlinks inside the entity, or to use a more complex algorithm to do graph backlink traversal, with is something that the current graph traversal inside the core can't cope with. So, let's postpone a such change if/when it is actually needed. It should also be noticed that the media_link structure uses 44 bytes on 32-bit architectures and 84 bytes on 64-bit architecture. It will thus be allocated out of the 64-bytes and 96-bytes pools respectively. That's a 12.5% memory waste on 64-bit architectures and 31.25% on 32-bit architecture. A linked list is less efficient than an array in this case, but this could later be optimized if we can get rid of the reverse links (with would reduce memory allocation by 50%). Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 4d5fc91c4134..2e5646cf36e7 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -74,6 +74,7 @@ struct media_pipeline { struct media_link { struct media_gobj graph_obj; + struct list_head list; struct media_pad *source; /* Source pad */ struct media_pad *sink; /* Sink pad */ struct media_link *reverse; /* Link in the reverse direction */ @@ -116,10 +117,9 @@ struct media_entity { u16 num_links; /* Number of existing links, both * enabled and disabled */ u16 num_backlinks; /* Number of backlinks */ - u16 max_links; /* Maximum number of links */ - struct media_pad *pads; /* Pads array (num_pads elements) */ - struct media_link *links; /* Links array (max_links elements)*/ + struct media_pad *pads; /* Pads array (num_pads objects) */ + struct list_head links; /* Links list */ const struct media_entity_operations *ops; /* Entity operations */ @@ -220,7 +220,7 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u32 local_id) struct media_entity_graph { struct { struct media_entity *entity; - int link; + struct list_head *link; } stack[MEDIA_ENTITY_ENUM_MAX_DEPTH]; DECLARE_BITMAP(entities, MEDIA_ENTITY_ENUM_MAX_ID); @@ -254,7 +254,7 @@ void media_gobj_init(struct media_device *mdev, void media_gobj_remove(struct media_gobj *gobj); int media_entity_init(struct media_entity *entity, u16 num_pads, - struct media_pad *pads); + struct media_pad *pads); void media_entity_cleanup(struct media_entity *entity); int media_create_pad_link(struct media_entity *source, u16 source_pad, -- cgit v1.2.3 From 4b8a3c08592ae0d530c87e2e1672ed8d9184dc09 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 20 Aug 2015 09:10:07 -0300 Subject: [media] media: make media_link more generic to handle interace links By adding an union at media_link, we get for free a way to represent interface->entity links. No need to change anything at the code, just at the internal header file. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 2e5646cf36e7..a7b21a7f4c64 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -75,14 +75,20 @@ struct media_pipeline { struct media_link { struct media_gobj graph_obj; struct list_head list; - struct media_pad *source; /* Source pad */ - struct media_pad *sink; /* Sink pad */ + union { + struct media_gobj *gobj0; + struct media_pad *source; + }; + union { + struct media_gobj *gobj1; + struct media_pad *sink; + }; struct media_link *reverse; /* Link in the reverse direction */ unsigned long flags; /* Link flags (MEDIA_LNK_FL_*) */ }; struct media_pad { - struct media_gobj graph_obj; + struct media_gobj graph_obj; /* must be first field in struct */ struct media_entity *entity; /* Entity this pad belongs to */ u16 index; /* Pad index in the entity pads array */ unsigned long flags; /* Pad flags (MEDIA_PAD_FL_*) */ @@ -105,7 +111,7 @@ struct media_entity_operations { }; struct media_entity { - struct media_gobj graph_obj; + struct media_gobj graph_obj; /* must be first field in struct */ struct list_head list; const char *name; /* Entity name */ u32 type; /* Entity type (MEDIA_ENT_T_*) */ @@ -119,7 +125,7 @@ struct media_entity { u16 num_backlinks; /* Number of backlinks */ struct media_pad *pads; /* Pads array (num_pads objects) */ - struct list_head links; /* Links list */ + struct list_head links; /* Pad-to-pad links list */ const struct media_entity_operations *ops; /* Entity operations */ -- cgit v1.2.3 From 86e2662071d6f26704bb290317746149ce07be7a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 7 Aug 2015 10:36:25 -0300 Subject: [media] media: add support to link interfaces and entities Now that we have a new graph object called "interfaces", we need to be able to link them to the entities. Add a linked list to the interfaces to allow them to be linked to the entities. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index a7b21a7f4c64..d64e8cb4de98 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -78,10 +78,12 @@ struct media_link { union { struct media_gobj *gobj0; struct media_pad *source; + struct media_interface *intf; }; union { struct media_gobj *gobj1; struct media_pad *sink; + struct media_entity *entity; }; struct media_link *reverse; /* Link in the reverse direction */ unsigned long flags; /* Link flags (MEDIA_LNK_FL_*) */ @@ -154,6 +156,7 @@ struct media_entity { * struct media_intf_devnode - Define a Kernel API interface * * @graph_obj: embedded graph object + * @links: List of links pointing to graph entities * @type: Type of the interface as defined at the * uapi/media/media.h header, e. g. * MEDIA_INTF_T_* @@ -161,6 +164,7 @@ struct media_entity { */ struct media_interface { struct media_gobj graph_obj; + struct list_head links; u32 type; u32 flags; }; @@ -290,6 +294,11 @@ struct media_intf_devnode *media_devnode_create(struct media_device *mdev, u32 major, u32 minor, gfp_t gfp_flags); void media_devnode_remove(struct media_intf_devnode *devnode); +struct media_link *media_create_intf_link(struct media_entity *entity, + struct media_interface *intf, + u32 flags); +void media_remove_intf_link(struct media_link *link); + #define media_entity_call(entity, operation, args...) \ (((entity)->ops && (entity)->ops->operation) ? \ (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD) -- cgit v1.2.3 From 57cf79b79b18d885c144889989b47149e23c8dc2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 21 Aug 2015 09:23:22 -0300 Subject: [media] media: add a linked list to track interfaces by mdev The media device should list the interface objects, so add a linked list for those interfaces in struct media_device. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 2 ++ include/media/media-entity.h | 3 +++ 2 files changed, 5 insertions(+) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index 3b14394d5701..51807efa505b 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -46,6 +46,7 @@ struct device; * @link_id: Unique ID used on the last link registered * @intf_devnode_id: Unique ID used on the last interface devnode registered * @entities: List of registered entities + * @interfaces: List of registered interfaces * @lock: Entities list lock * @graph_mutex: Entities graph operation lock * @link_notify: Link state change notification callback @@ -77,6 +78,7 @@ struct media_device { u32 intf_devnode_id; struct list_head entities; + struct list_head interfaces; /* Protects the entities list */ spinlock_t lock; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index d64e8cb4de98..ca35e07d9348 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -156,6 +156,8 @@ struct media_entity { * struct media_intf_devnode - Define a Kernel API interface * * @graph_obj: embedded graph object + * @list: Linked list used to find other interfaces that belong + * to the same media controller * @links: List of links pointing to graph entities * @type: Type of the interface as defined at the * uapi/media/media.h header, e. g. @@ -164,6 +166,7 @@ struct media_entity { */ struct media_interface { struct media_gobj graph_obj; + struct list_head list; struct list_head links; u32 type; u32 flags; -- cgit v1.2.3 From 32fdc0e1a87c1ed50f77a9e54413165282e99b8b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 21 Aug 2015 11:40:34 -0300 Subject: [media] uapi/media.h: Fix entity namespace Now that interfaces got created, we need to fix the entity namespace. So, let's create a consistent new namespace and add backward compatibility macros to keep the old namespace preserved. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/media.h | 76 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 57 insertions(+), 19 deletions(-) (limited to 'include') diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 3ad3d6be293f..8e9896820bee 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -42,31 +42,69 @@ struct media_device_info { #define MEDIA_ENT_ID_FLAG_NEXT (1 << 31) +/* + * Base numbers for entity types + * + * Please notice that the huge gap of 16 bits for each base is overkill! + * 8 bits is more than enough to avoid starving entity types for each + * subsystem. + * + * However, It is kept this way just to avoid binary breakages with the + * namespace provided on legacy versions of this header. + */ +#define MEDIA_ENT_T_DVB_BASE 0x00000000 +#define MEDIA_ENT_T_V4L2_BASE 0x00010000 +#define MEDIA_ENT_T_V4L2_SUBDEV_BASE 0x00020000 + +/* + * V4L2 entities - Those are used for DMA (mmap/DMABUF) and + * read()/write() data I/O associated with the V4L2 devnodes. + */ +#define MEDIA_ENT_T_V4L2_VIDEO (MEDIA_ENT_T_V4L2_BASE + 1) + /* + * Please notice that numbers between MEDIA_ENT_T_V4L2_BASE + 2 and + * MEDIA_ENT_T_V4L2_BASE + 4 can't be used, as those values used + * to be declared for FB, ALSA and DVB entities. + * As those values were never actually used in practice, we're just + * adding them as backward compatibility macros and keeping the + * numberspace clean here. This way, we avoid breaking compilation, + * in the case of having some userspace application using the old + * symbols. + */ +#define MEDIA_ENT_T_V4L2_VBI (MEDIA_ENT_T_V4L2_BASE + 5) +#define MEDIA_ENT_T_V4L2_SWRADIO (MEDIA_ENT_T_V4L2_BASE + 6) + +/* V4L2 Sub-device entities */ +#define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 1) +#define MEDIA_ENT_T_V4L2_SUBDEV_FLASH (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 2) +#define MEDIA_ENT_T_V4L2_SUBDEV_LENS (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 3) + /* A converter of analogue video to its digital representation. */ +#define MEDIA_ENT_T_V4L2_SUBDEV_DECODER (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 4) + /* Tuner entity is actually both V4L2 and DVB subdev */ +#define MEDIA_ENT_T_V4L2_SUBDEV_TUNER (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 5) + +/* DVB entities */ +#define MEDIA_ENT_T_DVB_DEMOD (MEDIA_ENT_T_DVB_BASE + 1) +#define MEDIA_ENT_T_DVB_DEMUX (MEDIA_ENT_T_DVB_BASE + 2) +#define MEDIA_ENT_T_DVB_TSOUT (MEDIA_ENT_T_DVB_BASE + 3) +#define MEDIA_ENT_T_DVB_CA (MEDIA_ENT_T_DVB_BASE + 4) +#define MEDIA_ENT_T_DVB_NET_DECAP (MEDIA_ENT_T_DVB_BASE + 5) + +/* Legacy symbols used to avoid userspace compilation breakages */ #define MEDIA_ENT_TYPE_SHIFT 16 #define MEDIA_ENT_TYPE_MASK 0x00ff0000 #define MEDIA_ENT_SUBTYPE_MASK 0x0000ffff -#define MEDIA_ENT_T_DEVNODE (1 << MEDIA_ENT_TYPE_SHIFT) -#define MEDIA_ENT_T_DEVNODE_V4L (MEDIA_ENT_T_DEVNODE + 1) +#define MEDIA_ENT_T_DEVNODE MEDIA_ENT_T_V4L2_BASE +#define MEDIA_ENT_T_V4L2_SUBDEV MEDIA_ENT_T_V4L2_SUBDEV_BASE + +#define MEDIA_ENT_T_DEVNODE_V4L MEDIA_ENT_T_V4L2_VIDEO + #define MEDIA_ENT_T_DEVNODE_FB (MEDIA_ENT_T_DEVNODE + 2) #define MEDIA_ENT_T_DEVNODE_ALSA (MEDIA_ENT_T_DEVNODE + 3) -#define MEDIA_ENT_T_DEVNODE_DVB_FE (MEDIA_ENT_T_DEVNODE + 4) -#define MEDIA_ENT_T_DEVNODE_DVB_DEMUX (MEDIA_ENT_T_DEVNODE + 5) -#define MEDIA_ENT_T_DEVNODE_DVB_DVR (MEDIA_ENT_T_DEVNODE + 6) -#define MEDIA_ENT_T_DEVNODE_DVB_CA (MEDIA_ENT_T_DEVNODE + 7) -#define MEDIA_ENT_T_DEVNODE_DVB_NET (MEDIA_ENT_T_DEVNODE + 8) - -/* Legacy symbol. Use it to avoid userspace compilation breakages */ -#define MEDIA_ENT_T_DEVNODE_DVB MEDIA_ENT_T_DEVNODE_DVB_FE - -#define MEDIA_ENT_T_V4L2_SUBDEV (2 << MEDIA_ENT_TYPE_SHIFT) -#define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV + 1) -#define MEDIA_ENT_T_V4L2_SUBDEV_FLASH (MEDIA_ENT_T_V4L2_SUBDEV + 2) -#define MEDIA_ENT_T_V4L2_SUBDEV_LENS (MEDIA_ENT_T_V4L2_SUBDEV + 3) -/* A converter of analogue video to its digital representation. */ -#define MEDIA_ENT_T_V4L2_SUBDEV_DECODER (MEDIA_ENT_T_V4L2_SUBDEV + 4) - -#define MEDIA_ENT_T_V4L2_SUBDEV_TUNER (MEDIA_ENT_T_V4L2_SUBDEV + 5) +#define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_T_DEVNODE + 4) + +/* Entity types */ #define MEDIA_ENT_FL_DEFAULT (1 << 0) -- cgit v1.2.3 From fa17b46a6a01013f48c33934c09e02f51f099f2b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 21 Aug 2015 12:17:40 -0300 Subject: [media] media: add macros to check if subdev or V4L2 DMA As we'll be removing entity subtypes from the Kernel, we need to provide a way for drivers and core to check if a given entity is represented by a V4L2 subdev or if it is an V4L2 I/O entity (typically with DMA). Drivers that create entities that don't belong to any defined subdev category should use MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 34 ++++++++++++++++++++++++++++++++++ include/uapi/linux/media.h | 3 +++ 2 files changed, 37 insertions(+) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index ca35e07d9348..2596878f4b9f 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -220,6 +220,40 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u32 local_id) return id; } +static inline bool is_media_entity_v4l2_io(struct media_entity *entity) +{ + if (!entity) + return false; + + switch (entity->type) { + case MEDIA_ENT_T_V4L2_VIDEO: + case MEDIA_ENT_T_V4L2_VBI: + case MEDIA_ENT_T_V4L2_SWRADIO: + return true; + default: + return false; + } +} + +static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) +{ + if (!entity) + return false; + + switch (entity->type) { + case MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN: + case MEDIA_ENT_T_V4L2_SUBDEV_SENSOR: + case MEDIA_ENT_T_V4L2_SUBDEV_FLASH: + case MEDIA_ENT_T_V4L2_SUBDEV_LENS: + case MEDIA_ENT_T_V4L2_SUBDEV_DECODER: + case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: + return true; + + default: + return false; + } +} + #define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 #define MEDIA_ENTITY_ENUM_MAX_ID 64 diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 8e9896820bee..c9314645d933 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -75,6 +75,9 @@ struct media_device_info { #define MEDIA_ENT_T_V4L2_SWRADIO (MEDIA_ENT_T_V4L2_BASE + 6) /* V4L2 Sub-device entities */ + +#define MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN MEDIA_ENT_T_V4L2_SUBDEV_BASE + #define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 1) #define MEDIA_ENT_T_V4L2_SUBDEV_FLASH (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 2) #define MEDIA_ENT_T_V4L2_SUBDEV_LENS (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 3) -- cgit v1.2.3 From b50bde4e476dede4a28e9c8fdcd134da2f34ef2e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 May 2015 22:12:38 -0300 Subject: [media] v4l2-subdev: use MEDIA_ENT_T_UNKNOWN for new subdevs Instead of abusing MEDIA_ENT_T_V4L2_SUBDEV, initialize new subdev entities as MEDIA_ENT_T_UNKNOWN. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/media.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include') diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index c9314645d933..43109445d126 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -42,6 +42,14 @@ struct media_device_info { #define MEDIA_ENT_ID_FLAG_NEXT (1 << 31) +/* Used values for media_entity_desc::type */ + +/* + * Initial value to be used when a new entity is created + * Drivers should change it to something useful + */ +#define MEDIA_ENT_T_UNKNOWN 0x00000000 + /* * Base numbers for entity types * @@ -76,6 +84,12 @@ struct media_device_info { /* V4L2 Sub-device entities */ +/* + * Subdevs are initialized with MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN, + * in order to preserve backward compatibility. + * Drivers should change to the proper subdev type before + * registering the entity. + */ #define MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN MEDIA_ENT_T_V4L2_SUBDEV_BASE #define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 1) -- cgit v1.2.3 From 687b4209c83e9b0633f794949c0bc6fb1401ccba Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 7 May 2015 22:12:39 -0300 Subject: [media] media controller: get rid of entity subtype on Kernel Don't use anymore the type/subtype entity data/macros inside the Kernel. Acked-by: Hans Verkuil Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 10 ---------- include/uapi/linux/media.h | 2 -- 2 files changed, 12 deletions(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 2596878f4b9f..5171e3c1c71a 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -185,16 +185,6 @@ struct media_intf_devnode { u32 minor; }; -static inline u32 media_entity_type(struct media_entity *entity) -{ - return entity->type & MEDIA_ENT_TYPE_MASK; -} - -static inline u32 media_entity_subtype(struct media_entity *entity) -{ - return entity->type & MEDIA_ENT_SUBTYPE_MASK; -} - static inline u32 media_entity_id(struct media_entity *entity) { return entity->graph_obj.id; diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 43109445d126..ecb6ac865905 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -42,8 +42,6 @@ struct media_device_info { #define MEDIA_ENT_ID_FLAG_NEXT (1 << 31) -/* Used values for media_entity_desc::type */ - /* * Initial value to be used when a new entity is created * Drivers should change it to something useful -- cgit v1.2.3 From 4376679a3426c88caba883bcaf4e9af04eba6d9d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 29 Aug 2015 14:50:46 -0300 Subject: [media] media.h: don't use legacy entity macros at Kernel Put the legacy MEDIA_ENT_* macros under a #ifndef __KERNEL__, in order to be sure that none of those old symbols are used inside the Kernel. Acked-by: Laurent Pinchart Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/media.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index ecb6ac865905..3c4080106df8 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -105,6 +105,7 @@ struct media_device_info { #define MEDIA_ENT_T_DVB_CA (MEDIA_ENT_T_DVB_BASE + 4) #define MEDIA_ENT_T_DVB_NET_DECAP (MEDIA_ENT_T_DVB_BASE + 5) +#ifndef __KERNEL__ /* Legacy symbols used to avoid userspace compilation breakages */ #define MEDIA_ENT_TYPE_SHIFT 16 #define MEDIA_ENT_TYPE_MASK 0x00ff0000 @@ -118,6 +119,7 @@ struct media_device_info { #define MEDIA_ENT_T_DEVNODE_FB (MEDIA_ENT_T_DEVNODE + 2) #define MEDIA_ENT_T_DEVNODE_ALSA (MEDIA_ENT_T_DEVNODE + 3) #define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_T_DEVNODE + 4) +#endif /* Entity types */ -- cgit v1.2.3 From c398bb6441949bd1f2acf5072116ecba143df03b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 23 Aug 2015 08:28:21 -0300 Subject: [media] uapi/media.h: Add MEDIA_IOC_G_TOPOLOGY ioctl Add a new ioctl that will report the entire topology on one go. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 2 + include/uapi/linux/media.h | 88 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 5171e3c1c71a..dbc4da450fc2 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -181,6 +181,8 @@ struct media_interface { */ struct media_intf_devnode { struct media_interface intf; + + /* Should match the fields at media_v2_intf_devnode */ u32 major; u32 minor; }; diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 3c4080106df8..72ac39de3822 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -206,6 +206,10 @@ struct media_pad_desc { #define MEDIA_LNK_FL_IMMUTABLE (1 << 1) #define MEDIA_LNK_FL_DYNAMIC (1 << 2) +#define MEDIA_LNK_FL_LINK_TYPE (0xf << 28) +# define MEDIA_LNK_FL_DATA_LINK (0 << 28) +# define MEDIA_LNK_FL_INTERFACE_LINK (1 << 28) + struct media_link_desc { struct media_pad_desc source; struct media_pad_desc sink; @@ -241,11 +245,93 @@ struct media_links_enum { #define MEDIA_INTF_T_V4L_SUBDEV (MEDIA_INTF_T_V4L_BASE + 3) #define MEDIA_INTF_T_V4L_SWRADIO (MEDIA_INTF_T_V4L_BASE + 4) -/* TBD: declare the structs needed for the new G_TOPOLOGY ioctl */ +/* + * MC next gen API definitions + * + * NOTE: The declarations below are close to the MC RFC for the Media + * Controller, the next generation. Yet, there are a few adjustments + * to do, as we want to be able to have a functional API before + * the MC properties change. Those will be properly marked below. + * Please also notice that I removed "num_pads", "num_links", + * from the proposal, as a proper userspace application will likely + * use lists for pads/links, just as we intend to do in Kernelspace. + * The API definition should be freed from fields that are bound to + * some specific data structure. + * + * FIXME: Currently, I opted to name the new types as "media_v2", as this + * won't cause any conflict with the Kernelspace namespace, nor with + * the previous kAPI media_*_desc namespace. This can be changed + * later, before the adding this API upstream. + */ + + +struct media_v2_entity { + __u32 id; + char name[64]; /* FIXME: move to a property? (RFC says so) */ + __u16 reserved[14]; +}; + +/* Should match the specific fields at media_intf_devnode */ +struct media_v2_intf_devnode { + __u32 major; + __u32 minor; +}; + +struct media_v2_interface { + __u32 id; + __u32 intf_type; + __u32 flags; + __u32 reserved[9]; + + union { + struct media_v2_intf_devnode devnode; + __u32 raw[16]; + }; +}; + +struct media_v2_pad { + __u32 id; + __u32 entity_id; + __u32 flags; + __u16 reserved[9]; +}; + +struct media_v2_link { + __u32 id; + __u32 source_id; + __u32 sink_id; + __u32 flags; + __u32 reserved[5]; +}; + +struct media_v2_topology { + __u32 topology_version; + + __u32 num_entities; + struct media_v2_entity *entities; + + __u32 num_interfaces; + struct media_v2_interface *interfaces; + + __u32 num_pads; + struct media_v2_pad *pads; + + __u32 num_links; + struct media_v2_link *links; + + struct { + __u32 reserved_num; + void *reserved_ptr; + } reserved_types[16]; + __u32 reserved[8]; +}; + +/* ioctls */ #define MEDIA_IOC_DEVICE_INFO _IOWR('|', 0x00, struct media_device_info) #define MEDIA_IOC_ENUM_ENTITIES _IOWR('|', 0x01, struct media_entity_desc) #define MEDIA_IOC_ENUM_LINKS _IOWR('|', 0x02, struct media_links_enum) #define MEDIA_IOC_SETUP_LINK _IOWR('|', 0x03, struct media_link_desc) +#define MEDIA_IOC_G_TOPOLOGY _IOWR('|', 0x04, struct media_v2_topology) #endif /* __LINUX_MEDIA_H */ -- cgit v1.2.3 From cf975a4b40ec9a947dae614b23128f3984a2d324 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 23 Aug 2015 07:51:22 -0300 Subject: [media] media: Use a macro to interate between all interfaces Just like we do with entities, use a similar macro for the interfaces loop. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index 51807efa505b..f23d686aaac6 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -113,6 +113,11 @@ struct media_device *media_device_find_devres(struct device *dev); #define media_device_for_each_entity(entity, mdev) \ list_for_each_entry(entity, &(mdev)->entities, list) +/* Iterate over all interfaces. */ +#define media_device_for_each_intf(intf, mdev) \ + list_for_each_entry(intf, &(mdev)->interfaces, list) + + #else static inline int media_device_register(struct media_device *mdev) { -- cgit v1.2.3 From 05bfa9fa1cda91953e1b5975b059542b83c5245c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 23 Aug 2015 07:51:33 -0300 Subject: [media] media: move mdev list init to gobj Let's control the topology changes inside the graph_object. So, move the addition and removal of interfaces/entities from the mdev lists to media_gobj_init() and media_gobj_remove(). The main reason is that mdev should have lists for all object types, as the new MC api will require to store objects in separate places. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 4 ++-- include/media/media-entity.h | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index f23d686aaac6..85fa302047bd 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -111,11 +111,11 @@ struct media_device *media_device_find_devres(struct device *dev); /* Iterate over all entities. */ #define media_device_for_each_entity(entity, mdev) \ - list_for_each_entry(entity, &(mdev)->entities, list) + list_for_each_entry(entity, &(mdev)->entities, graph_obj.list) /* Iterate over all interfaces. */ #define media_device_for_each_intf(intf, mdev) \ - list_for_each_entry(intf, &(mdev)->interfaces, list) + list_for_each_entry(intf, &(mdev)->interfaces, graph_obj.list) #else diff --git a/include/media/media-entity.h b/include/media/media-entity.h index dbc4da450fc2..f9058601440a 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -66,6 +66,7 @@ enum media_gobj_type { struct media_gobj { struct media_device *mdev; u32 id; + struct list_head list; }; @@ -114,7 +115,6 @@ struct media_entity_operations { struct media_entity { struct media_gobj graph_obj; /* must be first field in struct */ - struct list_head list; const char *name; /* Entity name */ u32 type; /* Entity type (MEDIA_ENT_T_*) */ u32 revision; /* Entity revision, driver specific */ @@ -166,7 +166,6 @@ struct media_entity { */ struct media_interface { struct media_gobj graph_obj; - struct list_head list; struct list_head links; u32 type; u32 flags; -- cgit v1.2.3 From 9155d859b6bec29cdbbd80a509be35de55115f00 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 23 Aug 2015 08:00:33 -0300 Subject: [media] media-device: add pads and links to media_device The MC next gen API sends objects to userspace grouped by their types. In the case of pads and links, in order to improve performance and have a simpler code, the best is to store them also on separate linked lists at MC. If we don't do that, we would need this kind of interaction to send data to userspace (code is in structured english): for each entity: for each pad: store pads for each entity: for each link: store link for each interface: for each link: store link With would require one nested loop for pads and two nested loops for links. By using separate linked lists for them, just one loop would be enough. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index 85fa302047bd..0d1b9c687454 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -47,6 +47,8 @@ struct device; * @intf_devnode_id: Unique ID used on the last interface devnode registered * @entities: List of registered entities * @interfaces: List of registered interfaces + * @pads: List of registered pads + * @links: List of registered links * @lock: Entities list lock * @graph_mutex: Entities graph operation lock * @link_notify: Link state change notification callback @@ -79,6 +81,8 @@ struct media_device { struct list_head entities; struct list_head interfaces; + struct list_head pads; + struct list_head links; /* Protects the entities list */ spinlock_t lock; @@ -117,6 +121,14 @@ struct media_device *media_device_find_devres(struct device *dev); #define media_device_for_each_intf(intf, mdev) \ list_for_each_entry(intf, &(mdev)->interfaces, graph_obj.list) +/* Iterate over all pads. */ +#define media_device_for_each_pad(pad, mdev) \ + list_for_each_entry(pad, &(mdev)->pads, graph_obj.list) + +/* Iterate over all links. */ +#define media_device_for_each_link(link, mdev) \ + list_for_each_entry(link, &(mdev)->links, graph_obj.list) + #else static inline int media_device_register(struct media_device *mdev) -- cgit v1.2.3 From 2521fdac28d0ceea659be1620fef96b1cbff09b6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 23 Aug 2015 09:40:26 -0300 Subject: [media] media_device: add a topology version field Every time a graph object is added or removed, the version of the topology changes. That's a requirement for the new MEDIA_IOC_G_TOPOLOGY, in order to allow userspace to know that the topology has changed after a previous call to it. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index 0d1b9c687454..1b12774a9ab4 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -41,6 +41,8 @@ struct device; * @bus_info: Unique and stable device location identifier * @hw_revision: Hardware device revision * @driver_version: Device driver version + * @topology_version: Monotonic counter for storing the version of the graph + * topology. Should be incremented each time the topology changes. * @entity_id: Unique ID used on the last entity registered * @pad_id: Unique ID used on the last pad registered * @link_id: Unique ID used on the last link registered @@ -74,6 +76,8 @@ struct media_device { u32 hw_revision; u32 driver_version; + u32 topology_version; + u32 entity_id; u32 pad_id; u32 link_id; -- cgit v1.2.3 From 7c4696a910d404eda3477e76a35c155a6b83ca3e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 24 Aug 2015 08:46:46 -0300 Subject: [media] media-entity: unregister entity links Add functions to explicitly unregister all entity links. This function is called automatically when an entity link is destroyed. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index f9058601440a..0753f3029d06 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -326,6 +326,9 @@ struct media_link *media_create_intf_link(struct media_entity *entity, struct media_interface *intf, u32 flags); void media_remove_intf_link(struct media_link *link); +void __media_remove_intf_links(struct media_interface *intf); +void media_remove_intf_links(struct media_interface *intf); + #define media_entity_call(entity, operation, args...) \ (((entity)->ops && (entity)->ops->operation) ? \ -- cgit v1.2.3 From d47109fa45ee2dc4e0b2710a8225e6c3ac7ea9fd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 29 Aug 2015 21:23:44 -0300 Subject: [media] media-device: remove interfaces and interface links Just like what's done with entities, when the media controller is unregistered, release any interface and interface links that might still be there. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 0753f3029d06..f165d303f03c 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -325,6 +325,7 @@ void media_devnode_remove(struct media_intf_devnode *devnode); struct media_link *media_create_intf_link(struct media_entity *entity, struct media_interface *intf, u32 flags); +void __media_remove_intf_link(struct media_link *link); void media_remove_intf_link(struct media_link *link); void __media_remove_intf_links(struct media_interface *intf); void media_remove_intf_links(struct media_interface *intf); -- cgit v1.2.3 From a08fad1ec80c69c79b3ffb6d84968b0952d32da1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 9 Dec 2015 19:47:35 -0200 Subject: [media] media-entity: protect object creation/removal using spin lock Some parts of the media controller are using mutexes while others are using spin locks in order to protect creation and removal of elements in the graph. That's wrong! Also, the V4L2 core can remove graph elements on non-interactive context: BUG: sleeping function called from invalid context at include/linux/sched.h:2776 Fix it by always using spin locks for graph element addition/removal, just like entity creation/removal is protected at media-device.c Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index 1b12774a9ab4..87ff299e1265 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -88,7 +88,7 @@ struct media_device { struct list_head pads; struct list_head links; - /* Protects the entities list */ + /* Protects the graph objects creation/removal */ spinlock_t lock; /* Serializes graph operations. */ struct mutex graph_mutex; -- cgit v1.2.3 From 188d2d551244f4196b616c90f3411732a6ebb2ab Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 31 Aug 2015 13:23:03 -0300 Subject: [media] tuner-core: add an input pad Tuners actually have at least one connector on its input. Add a PAD to connect it. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/tuner.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/media/tuner.h b/include/media/tuner.h index 486b6a54363b..e5321fda5489 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -21,6 +21,14 @@ #include +/* Tuner PADs */ +/* FIXME: is this the right place for it? */ +enum tuner_pad_index { + TUNER_PAD_RF_INPUT, + TUNER_PAD_IF_OUTPUT, + TUNER_NUM_PADS +}; + #define ADDR_UNSET (255) #define TUNER_TEMIC_PAL 0 /* 4002 FH5 (3X 7756, 9483) */ -- cgit v1.2.3 From d9c21e3e4b459b45e11406b83ebde163181508a1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 24 Aug 2015 08:47:54 -0300 Subject: [media] v4l2-core: create MC interfaces for devnodes V4L2 device (and subdevice) nodes should create an interface, if the Media Controller support is enabled. Please notice that radio devices should not create an entity, as radio input/output is either via wires or via ALSA. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-dev.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index acbcd2f5fe7f..eeabf20e87a6 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -86,6 +86,7 @@ struct video_device { #if defined(CONFIG_MEDIA_CONTROLLER) struct media_entity entity; + struct media_intf_devnode *intf_devnode; #endif /* device ops */ const struct v4l2_file_operations *fops; -- cgit v1.2.3 From c358e80d70d97efc144e7d496c92985ad74218a8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 29 Aug 2015 23:43:03 -0300 Subject: [media] media-entity.h: document all the structs Only a few structs are documented on kernel-doc-nano format (the ones added by the MC next gen patches). Add a documentation for all structs, and ensure that they'll be producing the documentation at the Kernel's device driver DocBook. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 114 +++++++++++++++++++++++++++++++------------ 1 file changed, 84 insertions(+), 30 deletions(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index f165d303f03c..fd19aecdcbb6 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -55,11 +55,13 @@ enum media_gobj_type { /** * struct media_gobj - Define a graph object. * + * @mdev: Pointer to the struct media_device that owns the object * @id: Non-zero object ID identifier. The ID should be unique * inside a media_device, as it is composed by * MEDIA_BITS_PER_TYPE to store the type plus * MEDIA_BITS_PER_LOCAL_ID to store a per-type ID * (called as "local ID"). + * @list: List entry stored in one of the per-type mdev object lists * * All objects on the media graph should have this struct embedded */ @@ -73,6 +75,28 @@ struct media_gobj { struct media_pipeline { }; +/** + * struct media_link - A link object part of a media graph. + * + * @graph_obj: Embedded structure containing the media object common data + * @list: Linked list associated with an entity or an interface that + * owns the link. + * @gobj0: Part of a union. Used to get the pointer for the first + * graph_object of the link. + * @source: Part of a union. Used only if the first object (gobj0) is + * a pad. In that case, it represents the source pad. + * @intf: Part of a union. Used only if the first object (gobj0) is + * an interface. + * @gobj1: Part of a union. Used to get the pointer for the second + * graph_object of the link. + * @source: Part of a union. Used only if the second object (gobj1) is + * a pad. In that case, it represents the sink pad. + * @entity: Part of a union. Used only if the second object (gobj1) is + * an entity. + * @reverse: Pointer to the link for the reverse direction of a pad to pad + * link. + * @flags: Link flags, as defined in uapi/media.h (MEDIA_LNK_FL_*) + */ struct media_link { struct media_gobj graph_obj; struct list_head list; @@ -86,15 +110,23 @@ struct media_link { struct media_pad *sink; struct media_entity *entity; }; - struct media_link *reverse; /* Link in the reverse direction */ - unsigned long flags; /* Link flags (MEDIA_LNK_FL_*) */ + struct media_link *reverse; + unsigned long flags; }; +/** + * struct media_pad - A media pad graph object. + * + * @graph_obj: Embedded structure containing the media object common data + * @entity: Entity this pad belongs to + * @index: Pad index in the entity pads array, numbered from 0 to n + * @flags: Pad flags, as defined in uapi/media.h (MEDIA_PAD_FL_*) + */ struct media_pad { struct media_gobj graph_obj; /* must be first field in struct */ - struct media_entity *entity; /* Entity this pad belongs to */ - u16 index; /* Pad index in the entity pads array */ - unsigned long flags; /* Pad flags (MEDIA_PAD_FL_*) */ + struct media_entity *entity; + u16 index; + unsigned long flags; }; /** @@ -113,56 +145,78 @@ struct media_entity_operations { int (*link_validate)(struct media_link *link); }; +/** + * struct media_entity - A media entity graph object. + * + * @graph_obj: Embedded structure containing the media object common data. + * @name: Entity name. + * @type: Entity type, as defined in uapi/media.h (MEDIA_ENT_T_*) + * @revision: Entity revision - OBSOLETE - should be removed soon. + * @flags: Entity flags, as defined in uapi/media.h (MEDIA_ENT_FL_*) + * @group_id: Entity group ID - OBSOLETE - should be removed soon. + * @num_pads: Number of sink and source pads. + * @num_links: Total number of links, forward and back, enabled and disabled. + * @num_backlinks: Number of backlinks + * @pads: Pads array with the size defined by @num_pads. + * @links: List of data links. + * @ops: Entity operations. + * @stream_count: Stream count for the entity. + * @use_count: Use count for the entity. + * @pipe: Pipeline this entity belongs to. + * @info: Union with devnode information. Kept just for backward + * compatibility. + * @major: Devnode major number (zero if not applicable). Kept just + * for backward compatibility. + * @minor: Devnode minor number (zero if not applicable). Kept just + * for backward compatibility. + * + * NOTE: @stream_count and @use_count reference counts must never be + * negative, but are signed integers on purpose: a simple WARN_ON(<0) check + * can be used to detect reference count bugs that would make them negative. + */ struct media_entity { struct media_gobj graph_obj; /* must be first field in struct */ - const char *name; /* Entity name */ - u32 type; /* Entity type (MEDIA_ENT_T_*) */ - u32 revision; /* Entity revision, driver specific */ - unsigned long flags; /* Entity flags (MEDIA_ENT_FL_*) */ - u32 group_id; /* Entity group ID */ + const char *name; + u32 type; + u32 revision; + unsigned long flags; + u32 group_id; - u16 num_pads; /* Number of sink and source pads */ - u16 num_links; /* Number of existing links, both - * enabled and disabled */ - u16 num_backlinks; /* Number of backlinks */ + u16 num_pads; + u16 num_links; + u16 num_backlinks; - struct media_pad *pads; /* Pads array (num_pads objects) */ - struct list_head links; /* Pad-to-pad links list */ + struct media_pad *pads; + struct list_head links; - const struct media_entity_operations *ops; /* Entity operations */ + const struct media_entity_operations *ops; /* Reference counts must never be negative, but are signed integers on * purpose: a simple WARN_ON(<0) check can be used to detect reference * count bugs that would make them negative. */ - int stream_count; /* Stream count for the entity. */ - int use_count; /* Use count for the entity. */ + int stream_count; + int use_count; - struct media_pipeline *pipe; /* Pipeline this entity belongs to. */ + struct media_pipeline *pipe; union { - /* Node specifications */ struct { u32 major; u32 minor; } dev; - - /* Sub-device specifications */ - /* Nothing needed yet */ } info; }; /** - * struct media_intf_devnode - Define a Kernel API interface + * struct media_interface - A media interface graph object. * * @graph_obj: embedded graph object - * @list: Linked list used to find other interfaces that belong - * to the same media controller * @links: List of links pointing to graph entities - * @type: Type of the interface as defined at the + * @type: Type of the interface as defined in the * uapi/media/media.h header, e. g. * MEDIA_INTF_T_* - * @flags: Interface flags as defined at uapi/media/media.h + * @flags: Interface flags as defined in uapi/media/media.h */ struct media_interface { struct media_gobj graph_obj; @@ -172,7 +226,7 @@ struct media_interface { }; /** - * struct media_intf_devnode - Define a Kernel API interface via a device node + * struct media_intf_devnode - A media interface via a device node. * * @intf: embedded interface object * @major: Major number of a device node -- cgit v1.2.3 From 49a11518f84c6fda6b2740e592ce53e1a22311a3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 31 Aug 2015 11:41:29 -0300 Subject: [media] media.h: create connector entities for hybrid TV devices Add entities to represent the connectors that exists inside a hybrid TV device. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/media.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 72ac39de3822..f9520225a211 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -61,6 +61,7 @@ struct media_device_info { #define MEDIA_ENT_T_DVB_BASE 0x00000000 #define MEDIA_ENT_T_V4L2_BASE 0x00010000 #define MEDIA_ENT_T_V4L2_SUBDEV_BASE 0x00020000 +#define MEDIA_ENT_T_CONNECTOR_BASE 0x00030000 /* * V4L2 entities - Those are used for DMA (mmap/DMABUF) and @@ -105,6 +106,13 @@ struct media_device_info { #define MEDIA_ENT_T_DVB_CA (MEDIA_ENT_T_DVB_BASE + 4) #define MEDIA_ENT_T_DVB_NET_DECAP (MEDIA_ENT_T_DVB_BASE + 5) +/* Connectors */ +#define MEDIA_ENT_T_CONN_RF (MEDIA_ENT_T_CONNECTOR_BASE + 1) +#define MEDIA_ENT_T_CONN_SVIDEO (MEDIA_ENT_T_CONNECTOR_BASE + 2) +#define MEDIA_ENT_T_CONN_COMPOSITE (MEDIA_ENT_T_CONNECTOR_BASE + 3) +/* For internal test signal generators and other debug connectors */ +#define MEDIA_ENT_T_CONN_TEST (MEDIA_ENT_T_CONNECTOR_BASE + 4) + #ifndef __KERNEL__ /* Legacy symbols used to avoid userspace compilation breakages */ #define MEDIA_ENT_TYPE_SHIFT 16 @@ -121,9 +129,9 @@ struct media_device_info { #define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_T_DEVNODE + 4) #endif -/* Entity types */ - +/* Entity flags */ #define MEDIA_ENT_FL_DEFAULT (1 << 0) +#define MEDIA_ENT_FL_CONNECTOR (1 << 1) struct media_entity_desc { __u32 id; -- cgit v1.2.3 From 39d1ebc6092f8266fb788733ca92b8492b1d69f2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 30 Aug 2015 09:53:57 -0300 Subject: [media] media-device: supress backlinks at G_TOPOLOGY ioctl Due to the graph traversal algorithm currently in usage, we need a copy of all data links. Those backlinks should not be send to userspace, as otherwise, all links there will be duplicated. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index fd19aecdcbb6..3b591d72c703 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -96,6 +96,7 @@ struct media_pipeline { * @reverse: Pointer to the link for the reverse direction of a pad to pad * link. * @flags: Link flags, as defined in uapi/media.h (MEDIA_LNK_FL_*) + * @is_backlink: Indicate if the link is a backlink. */ struct media_link { struct media_gobj graph_obj; @@ -112,6 +113,7 @@ struct media_link { }; struct media_link *reverse; unsigned long flags; + bool is_backlink; }; /** -- cgit v1.2.3 From 5e5387df0491679fb1210b231173c5279061e9c4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 4 Sep 2015 15:34:19 -0300 Subject: [media] media-entity: enforce check of interface and links creation Drivers should check if interfaces and interface links were created. Add a must_check for them. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 3b591d72c703..7128d3b0b848 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -373,14 +373,16 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, struct media_pipeline *pipe); void media_entity_pipeline_stop(struct media_entity *entity); -struct media_intf_devnode *media_devnode_create(struct media_device *mdev, - u32 type, u32 flags, - u32 major, u32 minor, - gfp_t gfp_flags); +struct media_intf_devnode * +__must_check media_devnode_create(struct media_device *mdev, + u32 type, u32 flags, + u32 major, u32 minor, + gfp_t gfp_flags); void media_devnode_remove(struct media_intf_devnode *devnode); -struct media_link *media_create_intf_link(struct media_entity *entity, - struct media_interface *intf, - u32 flags); +struct media_link * +__must_check media_create_intf_link(struct media_entity *entity, + struct media_interface *intf, + u32 flags); void __media_remove_intf_link(struct media_link *link); void media_remove_intf_link(struct media_link *link); void __media_remove_intf_links(struct media_interface *intf); -- cgit v1.2.3 From 77328043d9e6feb12e53a4fc5485cf664d2878e4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 4 Sep 2015 16:08:24 -0300 Subject: [media] media-entity: must check media_create_pad_link() Drivers should check if media_create_pad_link() actually worked. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 7128d3b0b848..0c7390d2edae 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -351,8 +351,9 @@ int media_entity_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads); void media_entity_cleanup(struct media_entity *entity); -int media_create_pad_link(struct media_entity *source, u16 source_pad, - struct media_entity *sink, u16 sink_pad, u32 flags); +__must_check int media_create_pad_link(struct media_entity *source, + u16 source_pad, struct media_entity *sink, + u16 sink_pad, u32 flags); void __media_entity_remove_links(struct media_entity *entity); void media_entity_remove_links(struct media_entity *entity); -- cgit v1.2.3 From 0e576b76f5470a2f8b2287958a2b9a3dd0f56f10 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 6 Sep 2015 09:33:39 -0300 Subject: [media] media-entity.h: rename entity.type to entity.function Entities should have one or more functions. Calling it as a type proofed to not be correct, as an entity could eventually have more than one type. So, rename the field as function. Please notice that this patch doesn't extend support for multiple function entities. Such change will happen when we have real case drivers using it. No functional changes. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 0c7390d2edae..70ccd6cf14c1 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -152,7 +152,8 @@ struct media_entity_operations { * * @graph_obj: Embedded structure containing the media object common data. * @name: Entity name. - * @type: Entity type, as defined in uapi/media.h (MEDIA_ENT_T_*) + * @function: Entity main function, as defined in uapi/media.h + * (MEDIA_ENT_F_*) * @revision: Entity revision - OBSOLETE - should be removed soon. * @flags: Entity flags, as defined in uapi/media.h (MEDIA_ENT_FL_*) * @group_id: Entity group ID - OBSOLETE - should be removed soon. @@ -179,7 +180,7 @@ struct media_entity_operations { struct media_entity { struct media_gobj graph_obj; /* must be first field in struct */ const char *name; - u32 type; + u32 function; u32 revision; unsigned long flags; u32 group_id; @@ -272,7 +273,7 @@ static inline bool is_media_entity_v4l2_io(struct media_entity *entity) if (!entity) return false; - switch (entity->type) { + switch (entity->function) { case MEDIA_ENT_T_V4L2_VIDEO: case MEDIA_ENT_T_V4L2_VBI: case MEDIA_ENT_T_V4L2_SWRADIO: @@ -287,7 +288,7 @@ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) if (!entity) return false; - switch (entity->type) { + switch (entity->function) { case MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN: case MEDIA_ENT_T_V4L2_SUBDEV_SENSOR: case MEDIA_ENT_T_V4L2_SUBDEV_FLASH: -- cgit v1.2.3 From d87cdb884486bfa795be99c83a5b3ac4d428ca84 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 6 Sep 2015 10:59:08 -0300 Subject: [media] media-device: export the entity function via new ioctl Now that entities have a main function, expose it via MEDIA_IOC_G_TOPOLOGY ioctl. Please notice that some entities may have secundary functions. Such use case will be addressed later, when we add support for the Media Controller properties. Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/media.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index f9520225a211..290dd5585dc8 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -276,7 +276,8 @@ struct media_links_enum { struct media_v2_entity { __u32 id; char name[64]; /* FIXME: move to a property? (RFC says so) */ - __u16 reserved[14]; + __u32 function; /* Main function of the entity */ + __u16 reserved[12]; }; /* Should match the specific fields at media_intf_devnode */ -- cgit v1.2.3 From 4ca72efaeffd0d244c44307abc9d4cb11f8ad475 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 10 Dec 2015 17:25:41 -0200 Subject: [media] uapi/media.h: Rename entities types to functions Rename the userspace types from MEDIA_ENT_T_ to MEDIA_ENT_F_ and add the backward compatibility bits. The changes at the .c files was generated by the following coccinelle script: @@ @@ -MEDIA_ENT_T_UNKNOWN +MEDIA_ENT_F_UNKNOWN @@ @@ -MEDIA_ENT_T_DVB_BASE +MEDIA_ENT_F_DVB_BASE @@ @@ -MEDIA_ENT_T_V4L2_BASE +MEDIA_ENT_F_V4L2_BASE @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_BASE +MEDIA_ENT_F_V4L2_SUBDEV_BASE @@ @@ -MEDIA_ENT_T_CONNECTOR_BASE +MEDIA_ENT_F_CONNECTOR_BASE @@ @@ -MEDIA_ENT_T_V4L2_VIDEO +MEDIA_ENT_F_IO_V4L @@ @@ -MEDIA_ENT_T_V4L2_VBI +MEDIA_ENT_F_IO_VBI @@ @@ -MEDIA_ENT_T_V4L2_SWRADIO +MEDIA_ENT_F_IO_SWRADIO @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN +MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN @@ @@ -MEDIA_ENT_T_CONN_RF +MEDIA_ENT_F_CONN_RF @@ @@ -MEDIA_ENT_T_CONN_SVIDEO +MEDIA_ENT_F_CONN_SVIDEO @@ @@ -MEDIA_ENT_T_CONN_COMPOSITE +MEDIA_ENT_F_CONN_COMPOSITE @@ @@ -MEDIA_ENT_T_CONN_TEST +MEDIA_ENT_F_CONN_TEST @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_SENSOR +MEDIA_ENT_F_CAM_SENSOR @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_FLASH +MEDIA_ENT_F_FLASH @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_LENS +MEDIA_ENT_F_LENS @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_DECODER +MEDIA_ENT_F_ATV_DECODER @@ @@ -MEDIA_ENT_T_V4L2_SUBDEV_TUNER +MEDIA_ENT_F_TUNER @@ @@ -MEDIA_ENT_T_DVB_DEMOD +MEDIA_ENT_F_DTV_DEMOD @@ @@ -MEDIA_ENT_T_DVB_DEMUX +MEDIA_ENT_F_TS_DEMUX @@ @@ -MEDIA_ENT_T_DVB_TSOUT +MEDIA_ENT_F_IO_DTV @@ @@ -MEDIA_ENT_T_DVB_CA +MEDIA_ENT_F_DTV_CA @@ @@ -MEDIA_ENT_T_DVB_NET_DECAP +MEDIA_ENT_F_DTV_NET_DECAP Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 18 +++---- include/uapi/linux/media.h | 122 +++++++++++++++++++++++-------------------- 2 files changed, 73 insertions(+), 67 deletions(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 70ccd6cf14c1..df84e8eeb24b 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -274,9 +274,9 @@ static inline bool is_media_entity_v4l2_io(struct media_entity *entity) return false; switch (entity->function) { - case MEDIA_ENT_T_V4L2_VIDEO: - case MEDIA_ENT_T_V4L2_VBI: - case MEDIA_ENT_T_V4L2_SWRADIO: + case MEDIA_ENT_F_IO_V4L: + case MEDIA_ENT_F_IO_VBI: + case MEDIA_ENT_F_IO_SWRADIO: return true; default: return false; @@ -289,12 +289,12 @@ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) return false; switch (entity->function) { - case MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN: - case MEDIA_ENT_T_V4L2_SUBDEV_SENSOR: - case MEDIA_ENT_T_V4L2_SUBDEV_FLASH: - case MEDIA_ENT_T_V4L2_SUBDEV_LENS: - case MEDIA_ENT_T_V4L2_SUBDEV_DECODER: - case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: + case MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN: + case MEDIA_ENT_F_CAM_SENSOR: + case MEDIA_ENT_F_FLASH: + case MEDIA_ENT_F_LENS: + case MEDIA_ENT_F_ATV_DECODER: + case MEDIA_ENT_F_TUNER: return true; default: diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 290dd5585dc8..ff6a8010c520 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -46,87 +46,93 @@ struct media_device_info { * Initial value to be used when a new entity is created * Drivers should change it to something useful */ -#define MEDIA_ENT_T_UNKNOWN 0x00000000 +#define MEDIA_ENT_F_UNKNOWN 0x00000000 /* - * Base numbers for entity types + * Base number ranges for entity functions * - * Please notice that the huge gap of 16 bits for each base is overkill! - * 8 bits is more than enough to avoid starving entity types for each - * subsystem. - * - * However, It is kept this way just to avoid binary breakages with the - * namespace provided on legacy versions of this header. + * NOTE: those ranges and entity function number are phased just to + * make it easier to maintain this file. Userspace should not rely on + * the ranges to identify a group of function types, as newer + * functions can be added with any name within the full u32 range. */ -#define MEDIA_ENT_T_DVB_BASE 0x00000000 -#define MEDIA_ENT_T_V4L2_BASE 0x00010000 -#define MEDIA_ENT_T_V4L2_SUBDEV_BASE 0x00020000 -#define MEDIA_ENT_T_CONNECTOR_BASE 0x00030000 +#define MEDIA_ENT_F_BASE 0x00000000 +#define MEDIA_ENT_F_OLD_BASE 0x00010000 +#define MEDIA_ENT_F_OLD_SUBDEV_BASE 0x00020000 /* - * V4L2 entities - Those are used for DMA (mmap/DMABUF) and - * read()/write() data I/O associated with the V4L2 devnodes. + * DVB entities */ -#define MEDIA_ENT_T_V4L2_VIDEO (MEDIA_ENT_T_V4L2_BASE + 1) - /* - * Please notice that numbers between MEDIA_ENT_T_V4L2_BASE + 2 and - * MEDIA_ENT_T_V4L2_BASE + 4 can't be used, as those values used - * to be declared for FB, ALSA and DVB entities. - * As those values were never actually used in practice, we're just - * adding them as backward compatibility macros and keeping the - * numberspace clean here. This way, we avoid breaking compilation, - * in the case of having some userspace application using the old - * symbols. - */ -#define MEDIA_ENT_T_V4L2_VBI (MEDIA_ENT_T_V4L2_BASE + 5) -#define MEDIA_ENT_T_V4L2_SWRADIO (MEDIA_ENT_T_V4L2_BASE + 6) - -/* V4L2 Sub-device entities */ +#define MEDIA_ENT_F_DTV_DEMOD (MEDIA_ENT_F_BASE + 1) +#define MEDIA_ENT_F_TS_DEMUX (MEDIA_ENT_F_BASE + 2) +#define MEDIA_ENT_F_DTV_CA (MEDIA_ENT_F_BASE + 3) +#define MEDIA_ENT_F_DTV_NET_DECAP (MEDIA_ENT_F_BASE + 4) /* + * Connectors + */ +#define MEDIA_ENT_F_CONN_RF (MEDIA_ENT_F_BASE + 21) +#define MEDIA_ENT_F_CONN_SVIDEO (MEDIA_ENT_F_BASE + 22) +#define MEDIA_ENT_F_CONN_COMPOSITE (MEDIA_ENT_F_BASE + 23) + /* For internal test signal generators and other debug connectors */ +#define MEDIA_ENT_F_CONN_TEST (MEDIA_ENT_F_BASE + 24) + +/* + * I/O entities + */ +#define MEDIA_ENT_F_IO_DTV (MEDIA_ENT_F_BASE + 31) +#define MEDIA_ENT_F_IO_VBI (MEDIA_ENT_F_BASE + 32) +#define MEDIA_ENT_F_IO_SWRADIO (MEDIA_ENT_F_BASE + 33) + +/* + * Don't touch on those. The ranges MEDIA_ENT_F_OLD_BASE and + * MEDIA_ENT_F_OLD_SUBDEV_BASE are kept to keep backward compatibility + * with the legacy v1 API.The number range is out of range by purpose: + * several previously reserved numbers got excluded from this range. + * * Subdevs are initialized with MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN, * in order to preserve backward compatibility. * Drivers should change to the proper subdev type before * registering the entity. */ -#define MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN MEDIA_ENT_T_V4L2_SUBDEV_BASE - -#define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 1) -#define MEDIA_ENT_T_V4L2_SUBDEV_FLASH (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 2) -#define MEDIA_ENT_T_V4L2_SUBDEV_LENS (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 3) - /* A converter of analogue video to its digital representation. */ -#define MEDIA_ENT_T_V4L2_SUBDEV_DECODER (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 4) - /* Tuner entity is actually both V4L2 and DVB subdev */ -#define MEDIA_ENT_T_V4L2_SUBDEV_TUNER (MEDIA_ENT_T_V4L2_SUBDEV_BASE + 5) - -/* DVB entities */ -#define MEDIA_ENT_T_DVB_DEMOD (MEDIA_ENT_T_DVB_BASE + 1) -#define MEDIA_ENT_T_DVB_DEMUX (MEDIA_ENT_T_DVB_BASE + 2) -#define MEDIA_ENT_T_DVB_TSOUT (MEDIA_ENT_T_DVB_BASE + 3) -#define MEDIA_ENT_T_DVB_CA (MEDIA_ENT_T_DVB_BASE + 4) -#define MEDIA_ENT_T_DVB_NET_DECAP (MEDIA_ENT_T_DVB_BASE + 5) - -/* Connectors */ -#define MEDIA_ENT_T_CONN_RF (MEDIA_ENT_T_CONNECTOR_BASE + 1) -#define MEDIA_ENT_T_CONN_SVIDEO (MEDIA_ENT_T_CONNECTOR_BASE + 2) -#define MEDIA_ENT_T_CONN_COMPOSITE (MEDIA_ENT_T_CONNECTOR_BASE + 3) -/* For internal test signal generators and other debug connectors */ -#define MEDIA_ENT_T_CONN_TEST (MEDIA_ENT_T_CONNECTOR_BASE + 4) + +#define MEDIA_ENT_F_IO_V4L (MEDIA_ENT_F_OLD_BASE + 1) + +#define MEDIA_ENT_F_CAM_SENSOR (MEDIA_ENT_F_OLD_SUBDEV_BASE + 1) +#define MEDIA_ENT_F_FLASH (MEDIA_ENT_F_OLD_SUBDEV_BASE + 2) +#define MEDIA_ENT_F_LENS (MEDIA_ENT_F_OLD_SUBDEV_BASE + 3) +#define MEDIA_ENT_F_ATV_DECODER (MEDIA_ENT_F_OLD_SUBDEV_BASE + 4) +#define MEDIA_ENT_F_TUNER (MEDIA_ENT_F_OLD_SUBDEV_BASE + 5) + +#define MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN MEDIA_ENT_F_OLD_SUBDEV_BASE #ifndef __KERNEL__ -/* Legacy symbols used to avoid userspace compilation breakages */ + +/* + * Legacy symbols used to avoid userspace compilation breakages + * + * Those symbols map the entity function into types and should be + * used only on legacy programs for legacy hardware. Don't rely + * on those for MEDIA_IOC_G_TOPOLOGY. + */ #define MEDIA_ENT_TYPE_SHIFT 16 #define MEDIA_ENT_TYPE_MASK 0x00ff0000 #define MEDIA_ENT_SUBTYPE_MASK 0x0000ffff -#define MEDIA_ENT_T_DEVNODE MEDIA_ENT_T_V4L2_BASE -#define MEDIA_ENT_T_V4L2_SUBDEV MEDIA_ENT_T_V4L2_SUBDEV_BASE - -#define MEDIA_ENT_T_DEVNODE_V4L MEDIA_ENT_T_V4L2_VIDEO - +#define MEDIA_ENT_T_DEVNODE MEDIA_ENT_F_OLD_BASE +#define MEDIA_ENT_T_DEVNODE_V4L MEDIA_ENT_F_IO_V4L #define MEDIA_ENT_T_DEVNODE_FB (MEDIA_ENT_T_DEVNODE + 2) #define MEDIA_ENT_T_DEVNODE_ALSA (MEDIA_ENT_T_DEVNODE + 3) #define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_T_DEVNODE + 4) + +#define MEDIA_ENT_T_UNKNOWN MEDIA_ENT_F_UNKNOWN +#define MEDIA_ENT_T_V4L2_VIDEO MEDIA_ENT_F_IO_V4L +#define MEDIA_ENT_T_V4L2_SUBDEV MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN +#define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR MEDIA_ENT_F_CAM_SENSOR +#define MEDIA_ENT_T_V4L2_SUBDEV_FLASH MEDIA_ENT_F_FLASH +#define MEDIA_ENT_T_V4L2_SUBDEV_LENS MEDIA_ENT_F_LENS +#define MEDIA_ENT_T_V4L2_SUBDEV_DECODER MEDIA_ENT_F_ATV_DECODER +#define MEDIA_ENT_T_V4L2_SUBDEV_TUNER MEDIA_ENT_F_TUNER #endif /* Entity flags */ -- cgit v1.2.3 From 0b3b72df9018c0386293c2f529b91ed17448288a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 9 Sep 2015 08:19:25 -0300 Subject: [media] media_entity: remove gfp_flags argument We should not be creating device nodes at IRQ contexts. So, the only flags we'll be using will be GFP_KERNEL. Let's remove the gfp_flags, in order to make the interface simpler. If we ever need it, it would be easy to revert those changes. While here, remove an extra blank line. Suggested-by: Sakari Ailus Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index df84e8eeb24b..cd3f3a77df2d 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -71,7 +71,6 @@ struct media_gobj { struct list_head list; }; - struct media_pipeline { }; @@ -378,8 +377,7 @@ void media_entity_pipeline_stop(struct media_entity *entity); struct media_intf_devnode * __must_check media_devnode_create(struct media_device *mdev, u32 type, u32 flags, - u32 major, u32 minor, - gfp_t gfp_flags); + u32 major, u32 minor); void media_devnode_remove(struct media_intf_devnode *devnode); struct media_link * __must_check media_create_intf_link(struct media_entity *entity, -- cgit v1.2.3 From ab22e77cd3d3073c8cac51b59713ef635678dfbe Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 07:44:40 -0200 Subject: [media] media framework: rename pads init function to media_entity_pads_init() With the MC next gen rework, what's left for media_entity_init() is to just initialize the PADs. However, certain devices, like a FLASH led/light doesn't have any input or output PAD. So, there's no reason why calling media_entity_init() would be mandatory. Also, despite its name, what this function actually does is to initialize the PADs data. So, rename it to media_entity_pads_init() in order to reflect that. The media entity actual init happens during entity register, at media_device_register_entity(). We should move init of num_links and num_backlinks to it. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index cd3f3a77df2d..32fef503d950 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -347,7 +347,7 @@ void media_gobj_init(struct media_device *mdev, struct media_gobj *gobj); void media_gobj_remove(struct media_gobj *gobj); -int media_entity_init(struct media_entity *entity, u16 num_pads, +int media_entity_pads_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads); void media_entity_cleanup(struct media_entity *entity); -- cgit v1.2.3 From 8ed8c88c460fa6ce71deb9847f78a5bff4dfcb0e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 08:02:19 -0200 Subject: [media] media-entity.h: get rid of revision and group_id fields Both revision and group_id fields were never used and were always initialized to zero. Remove them. Suggested-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 32fef503d950..031536723d8c 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -153,9 +153,7 @@ struct media_entity_operations { * @name: Entity name. * @function: Entity main function, as defined in uapi/media.h * (MEDIA_ENT_F_*) - * @revision: Entity revision - OBSOLETE - should be removed soon. * @flags: Entity flags, as defined in uapi/media.h (MEDIA_ENT_FL_*) - * @group_id: Entity group ID - OBSOLETE - should be removed soon. * @num_pads: Number of sink and source pads. * @num_links: Total number of links, forward and back, enabled and disabled. * @num_backlinks: Number of backlinks @@ -180,9 +178,7 @@ struct media_entity { struct media_gobj graph_obj; /* must be first field in struct */ const char *name; u32 function; - u32 revision; unsigned long flags; - u32 group_id; u16 num_pads; u16 num_links; -- cgit v1.2.3 From cc2dd94a051c8a467c66a258391cb980c3fb3312 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 08:21:39 -0200 Subject: [media] DocBook: Move media-framework.txt contents to media-device.h Instead of using a text file, let's put it together with the struct documentation for the Media Controller. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 378 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 378 insertions(+) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index 87ff299e1265..6728528df9e2 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -30,6 +30,384 @@ #include #include +/** + * DOC: Media Controller + * + * Linux kernel media framework + * ============================ + * + * This document describes the Linux kernel media framework, its data structures, + * functions and their usage. + * + * + * Introduction + * ------------ + * + * The media controller API is documented in DocBook format in + * Documentation/DocBook/media/v4l/media-controller.xml. This document will focus + * on the kernel-side implementation of the media framework. + * + * + * Abstract media device model + * --------------------------- + * + * Discovering a device internal topology, and configuring it at runtime, is one + * of the goals of the media framework. To achieve this, hardware devices are + * modelled as an oriented graph of building blocks called entities connected + * through pads. + * + * An entity is a basic media hardware building block. It can correspond to + * a large variety of logical blocks such as physical hardware devices + * (CMOS sensor for instance), logical hardware devices (a building block + * in a System-on-Chip image processing pipeline), DMA channels or physical + * connectors. + * + * A pad is a connection endpoint through which an entity can interact with + * other entities. Data (not restricted to video) produced by an entity + * flows from the entity's output to one or more entity inputs. Pads should + * not be confused with physical pins at chip boundaries. + * + * A link is a point-to-point oriented connection between two pads, either + * on the same entity or on different entities. Data flows from a source + * pad to a sink pad. + * + * + * Media device + * ------------ + * + * A media device is represented by a struct media_device instance, defined in + * include/media/media-device.h. Allocation of the structure is handled by the + * media device driver, usually by embedding the media_device instance in a + * larger driver-specific structure. + * + * Drivers register media device instances by calling + * + * media_device_register(struct media_device *mdev); + * + * The caller is responsible for initializing the media_device structure before + * registration. The following fields must be set: + * + * - dev must point to the parent device (usually a pci_dev, usb_interface or + * platform_device instance). + * + * - model must be filled with the device model name as a NUL-terminated UTF-8 + * string. The device/model revision must not be stored in this field. + * + * The following fields are optional: + * + * - serial is a unique serial number stored as a NUL-terminated ASCII string. + * The field is big enough to store a GUID in text form. If the hardware + * doesn't provide a unique serial number this field must be left empty. + * + * - bus_info represents the location of the device in the system as a + * NUL-terminated ASCII string. For PCI/PCIe devices bus_info must be set to + * "PCI:" (or "PCIe:") followed by the value of pci_name(). For USB devices, + * the usb_make_path() function must be used. This field is used by + * applications to distinguish between otherwise identical devices that don't + * provide a serial number. + * + * - hw_revision is the hardware device revision in a driver-specific format. + * When possible the revision should be formatted with the KERNEL_VERSION + * macro. + * + * - driver_version is formatted with the KERNEL_VERSION macro. The version + * minor must be incremented when new features are added to the userspace API + * without breaking binary compatibility. The version major must be + * incremented when binary compatibility is broken. + * + * Upon successful registration a character device named media[0-9]+ is created. + * The device major and minor numbers are dynamic. The model name is exported as + * a sysfs attribute. + * + * Drivers unregister media device instances by calling + * + * media_device_unregister(struct media_device *mdev); + * + * Unregistering a media device that hasn't been registered is *NOT* safe. + * + * + * Entities, pads and links + * ------------------------ + * + * - Entities + * + * Entities are represented by a struct media_entity instance, defined in + * include/media/media-entity.h. The structure is usually embedded into a + * higher-level structure, such as a v4l2_subdev or video_device instance, + * although drivers can allocate entities directly. + * + * Drivers initialize entity pads by calling + * + * media_entity_pads_init(struct media_entity *entity, u16 num_pads, + * struct media_pad *pads); + * + * If no pads are needed, drivers could directly fill entity->num_pads + * with 0 and entity->pads with NULL or to call the above function that + * will do the same. + * + * The media_entity name, type and flags fields should be initialized before + * calling media_device_register_entity(). Entities embedded in higher-level + * standard structures can have some of those fields set by the higher-level + * framework. + * + * As the number of pads is known in advance, the pads array is not allocated + * dynamically but is managed by the entity driver. Most drivers will embed the + * pads array in a driver-specific structure, avoiding dynamic allocation. + * + * Drivers must set the direction of every pad in the pads array before calling + * media_entity_pads_init. The function will initialize the other pads fields. + * + * Unlike the number of pads, the total number of links isn't always known in + * advance by the entity driver. As an initial estimate, media_entity_pads_init + * pre-allocates a number of links equal to the number of pads. The links array + * will be reallocated if it grows beyond the initial estimate. + * + * Drivers register entities with a media device by calling + * + * media_device_register_entity(struct media_device *mdev, + * struct media_entity *entity); + * + * Entities are identified by a unique positive integer ID. Drivers can provide an + * ID by filling the media_entity id field prior to registration, or request the + * media controller framework to assign an ID automatically. Drivers that provide + * IDs manually must ensure that all IDs are unique. IDs are not guaranteed to be + * contiguous even when they are all assigned automatically by the framework. + * + * Drivers unregister entities by calling + * + * media_device_unregister_entity(struct media_entity *entity); + * + * Unregistering an entity will not change the IDs of the other entities, and the + * ID will never be reused for a newly registered entity. + * + * When a media device is unregistered, all its entities are unregistered + * automatically. No manual entities unregistration is then required. + * + * Drivers free resources associated with an entity by calling + * + * media_entity_cleanup(struct media_entity *entity); + * + * This function must be called during the cleanup phase after unregistering the + * entity. Note that the media_entity instance itself must be freed explicitly by + * the driver if required. + * + * Entities have flags that describe the entity capabilities and state. + * + * MEDIA_ENT_FL_DEFAULT indicates the default entity for a given type. + * This can be used to report the default audio and video devices or the + * default camera sensor. + * + * Logical entity groups can be defined by setting the group ID of all member + * entities to the same non-zero value. An entity group serves no purpose in the + * kernel, but is reported to userspace during entities enumeration. + * + * Media device drivers should define groups if several entities are logically + * bound together. Example usages include reporting + * + * - ALSA, VBI and video nodes that carry the same media stream + * - lens and flash controllers associated with a sensor + * + * - Pads + * + * Pads are represented by a struct media_pad instance, defined in + * include/media/media-entity.h. Each entity stores its pads in a pads array + * managed by the entity driver. Drivers usually embed the array in a + * driver-specific structure. + * + * Pads are identified by their entity and their 0-based index in the pads array. + * Both information are stored in the media_pad structure, making the media_pad + * pointer the canonical way to store and pass link references. + * + * Pads have flags that describe the pad capabilities and state. + * + * MEDIA_PAD_FL_SINK indicates that the pad supports sinking data. + * MEDIA_PAD_FL_SOURCE indicates that the pad supports sourcing data. + * + * One and only one of MEDIA_PAD_FL_SINK and MEDIA_PAD_FL_SOURCE must be set for + * each pad. + * + * - Links + * + * Links are represented by a struct media_link instance, defined in + * include/media/media-entity.h. Each entity stores all links originating at or + * targeting any of its pads in a links array. A given link is thus stored + * twice, once in the source entity and once in the target entity. The array is + * pre-allocated and grows dynamically as needed. + * + * Drivers create links by calling + * + * media_create_pad_link(struct media_entity *source, u16 source_pad, + * struct media_entity *sink, u16 sink_pad, + * u32 flags); + * + * An entry in the link array of each entity is allocated and stores pointers + * to source and sink pads. + * + * Links have flags that describe the link capabilities and state. + * + * MEDIA_LNK_FL_ENABLED indicates that the link is enabled and can be used + * to transfer media data. When two or more links target a sink pad, only + * one of them can be enabled at a time. + * MEDIA_LNK_FL_IMMUTABLE indicates that the link enabled state can't be + * modified at runtime. If MEDIA_LNK_FL_IMMUTABLE is set, then + * MEDIA_LNK_FL_ENABLED must also be set since an immutable link is always + * enabled. + * + * + * Graph traversal + * --------------- + * + * The media framework provides APIs to iterate over entities in a graph. + * + * To iterate over all entities belonging to a media device, drivers can use the + * media_device_for_each_entity macro, defined in include/media/media-device.h. + * + * struct media_entity *entity; + * + * media_device_for_each_entity(entity, mdev) { + * // entity will point to each entity in turn + * ... + * } + * + * Drivers might also need to iterate over all entities in a graph that can be + * reached only through enabled links starting at a given entity. The media + * framework provides a depth-first graph traversal API for that purpose. + * + * Note that graphs with cycles (whether directed or undirected) are *NOT* + * supported by the graph traversal API. To prevent infinite loops, the graph + * traversal code limits the maximum depth to MEDIA_ENTITY_ENUM_MAX_DEPTH, + * currently defined as 16. + * + * Drivers initiate a graph traversal by calling + * + * media_entity_graph_walk_start(struct media_entity_graph *graph, + * struct media_entity *entity); + * + * The graph structure, provided by the caller, is initialized to start graph + * traversal at the given entity. + * + * Drivers can then retrieve the next entity by calling + * + * media_entity_graph_walk_next(struct media_entity_graph *graph); + * + * When the graph traversal is complete the function will return NULL. + * + * Graph traversal can be interrupted at any moment. No cleanup function call is + * required and the graph structure can be freed normally. + * + * Helper functions can be used to find a link between two given pads, or a pad + * connected to another pad through an enabled link + * + * media_entity_find_link(struct media_pad *source, + * struct media_pad *sink); + * + * media_entity_remote_pad(struct media_pad *pad); + * + * Refer to the kerneldoc documentation for more information. + * + * + * Use count and power handling + * ---------------------------- + * + * Due to the wide differences between drivers regarding power management needs, + * the media controller does not implement power management. However, the + * media_entity structure includes a use_count field that media drivers can use to + * track the number of users of every entity for power management needs. + * + * The use_count field is owned by media drivers and must not be touched by entity + * drivers. Access to the field must be protected by the media device graph_mutex + * lock. + * + * + * Links setup + * ----------- + * + * Link properties can be modified at runtime by calling + * + * media_entity_setup_link(struct media_link *link, u32 flags); + * + * The flags argument contains the requested new link flags. + * + * The only configurable property is the ENABLED link flag to enable/disable a + * link. Links marked with the IMMUTABLE link flag can not be enabled or disabled. + * + * When a link is enabled or disabled, the media framework calls the + * link_setup operation for the two entities at the source and sink of the link, + * in that order. If the second link_setup call fails, another link_setup call is + * made on the first entity to restore the original link flags. + * + * Media device drivers can be notified of link setup operations by setting the + * media_device::link_notify pointer to a callback function. If provided, the + * notification callback will be called before enabling and after disabling + * links. + * + * Entity drivers must implement the link_setup operation if any of their links + * is non-immutable. The operation must either configure the hardware or store + * the configuration information to be applied later. + * + * Link configuration must not have any side effect on other links. If an enabled + * link at a sink pad prevents another link at the same pad from being enabled, + * the link_setup operation must return -EBUSY and can't implicitly disable the + * first enabled link. + * + * + * Pipelines and media streams + * --------------------------- + * + * When starting streaming, drivers must notify all entities in the pipeline to + * prevent link states from being modified during streaming by calling + * + * media_entity_pipeline_start(struct media_entity *entity, + * struct media_pipeline *pipe); + * + * The function will mark all entities connected to the given entity through + * enabled links, either directly or indirectly, as streaming. + * + * The media_pipeline instance pointed to by the pipe argument will be stored in + * every entity in the pipeline. Drivers should embed the media_pipeline structure + * in higher-level pipeline structures and can then access the pipeline through + * the media_entity pipe field. + * + * Calls to media_entity_pipeline_start() can be nested. The pipeline pointer must + * be identical for all nested calls to the function. + * + * media_entity_pipeline_start() may return an error. In that case, it will + * clean up any of the changes it did by itself. + * + * When stopping the stream, drivers must notify the entities with + * + * media_entity_pipeline_stop(struct media_entity *entity); + * + * If multiple calls to media_entity_pipeline_start() have been made the same + * number of media_entity_pipeline_stop() calls are required to stop streaming. The + * media_entity pipe field is reset to NULL on the last nested stop call. + * + * Link configuration will fail with -EBUSY by default if either end of the link is + * a streaming entity. Links that can be modified while streaming must be marked + * with the MEDIA_LNK_FL_DYNAMIC flag. + * + * If other operations need to be disallowed on streaming entities (such as + * changing entities configuration parameters) drivers can explicitly check the + * media_entity stream_count field to find out if an entity is streaming. This + * operation must be done with the media_device graph_mutex held. + * + * + * Link validation + * --------------- + * + * Link validation is performed by media_entity_pipeline_start() for any + * entity which has sink pads in the pipeline. The + * media_entity::link_validate() callback is used for that purpose. In + * link_validate() callback, entity driver should check that the properties of + * the source pad of the connected entity and its own sink pad match. It is up + * to the type of the entity (and in the end, the properties of the hardware) + * what matching actually means. + * + * Subsystems should facilitate link validation by providing subsystem specific + * helper functions to provide easy access for commonly needed information, and + * in the end provide a way to use driver-specific callbacks. + */ + struct device; /** -- cgit v1.2.3 From f1fd3289e8c2b99cdf5c1c4426a7d28a809159c2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 09:13:23 -0200 Subject: [media] media-entity.h: convert media_entity_cleanup to inline This function was used in the past to free the links that were allocated by the media controller core. However, this is not needed anymore. We should likely get rid of the funcion on some function, but, for now, let's just convert into an inlined function and let the compiler to get rid of it. Suggested-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 031536723d8c..e9bc5857899c 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -345,7 +345,8 @@ void media_gobj_remove(struct media_gobj *gobj); int media_entity_pads_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads); -void media_entity_cleanup(struct media_entity *entity); + +static inline void media_entity_cleanup(struct media_entity *entity) {}; __must_check int media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, -- cgit v1.2.3 From db7ee32aa1859c155e634a4d5c44b9cff4c9a6e5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 11:06:08 -0200 Subject: [media] media-device.h: Improve documentation and update it Now that we moved the content of the media-framework.txt into the kerneldoc documentation, move the per-function specific documentation to the corresponding functions and clean it up. It would be good if we had already the markdown kernel-doc patches merged upstream, but, while we doesn't have it, let's make it less ugly at device-drivers.xml. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 429 +++++++++++++++++++------------------------ include/media/media-entity.h | 148 +++++++++++++++ 2 files changed, 339 insertions(+), 238 deletions(-) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index 6728528df9e2..65fdd44e05ef 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -33,23 +33,11 @@ /** * DOC: Media Controller * - * Linux kernel media framework - * ============================ - * - * This document describes the Linux kernel media framework, its data structures, - * functions and their usage. - * - * - * Introduction - * ------------ - * - * The media controller API is documented in DocBook format in - * Documentation/DocBook/media/v4l/media-controller.xml. This document will focus + * The media controller userspace API is documented in DocBook format in + * Documentation/DocBook/media/v4l/media-controller.xml. This document focus * on the kernel-side implementation of the media framework. * - * - * Abstract media device model - * --------------------------- + * * Abstract media device model: * * Discovering a device internal topology, and configuring it at runtime, is one * of the goals of the media framework. To achieve this, hardware devices are @@ -72,195 +60,104 @@ * pad to a sink pad. * * - * Media device - * ------------ + * * Media device: * - * A media device is represented by a struct media_device instance, defined in + * A media device is represented by a struct &media_device instance, defined in * include/media/media-device.h. Allocation of the structure is handled by the - * media device driver, usually by embedding the media_device instance in a + * media device driver, usually by embedding the &media_device instance in a * larger driver-specific structure. * * Drivers register media device instances by calling + * __media_device_register() via the macro media_device_register() + * and unregistered by calling + * media_device_unregister(). * - * media_device_register(struct media_device *mdev); - * - * The caller is responsible for initializing the media_device structure before - * registration. The following fields must be set: - * - * - dev must point to the parent device (usually a pci_dev, usb_interface or - * platform_device instance). - * - * - model must be filled with the device model name as a NUL-terminated UTF-8 - * string. The device/model revision must not be stored in this field. - * - * The following fields are optional: - * - * - serial is a unique serial number stored as a NUL-terminated ASCII string. - * The field is big enough to store a GUID in text form. If the hardware - * doesn't provide a unique serial number this field must be left empty. - * - * - bus_info represents the location of the device in the system as a - * NUL-terminated ASCII string. For PCI/PCIe devices bus_info must be set to - * "PCI:" (or "PCIe:") followed by the value of pci_name(). For USB devices, - * the usb_make_path() function must be used. This field is used by - * applications to distinguish between otherwise identical devices that don't - * provide a serial number. - * - * - hw_revision is the hardware device revision in a driver-specific format. - * When possible the revision should be formatted with the KERNEL_VERSION - * macro. - * - * - driver_version is formatted with the KERNEL_VERSION macro. The version - * minor must be incremented when new features are added to the userspace API - * without breaking binary compatibility. The version major must be - * incremented when binary compatibility is broken. - * - * Upon successful registration a character device named media[0-9]+ is created. - * The device major and minor numbers are dynamic. The model name is exported as - * a sysfs attribute. - * - * Drivers unregister media device instances by calling - * - * media_device_unregister(struct media_device *mdev); - * - * Unregistering a media device that hasn't been registered is *NOT* safe. - * - * - * Entities, pads and links - * ------------------------ + * * Entities, pads and links: * * - Entities * - * Entities are represented by a struct media_entity instance, defined in + * Entities are represented by a struct &media_entity instance, defined in * include/media/media-entity.h. The structure is usually embedded into a * higher-level structure, such as a v4l2_subdev or video_device instance, * although drivers can allocate entities directly. * * Drivers initialize entity pads by calling - * - * media_entity_pads_init(struct media_entity *entity, u16 num_pads, - * struct media_pad *pads); - * - * If no pads are needed, drivers could directly fill entity->num_pads - * with 0 and entity->pads with NULL or to call the above function that - * will do the same. - * - * The media_entity name, type and flags fields should be initialized before - * calling media_device_register_entity(). Entities embedded in higher-level - * standard structures can have some of those fields set by the higher-level - * framework. - * - * As the number of pads is known in advance, the pads array is not allocated - * dynamically but is managed by the entity driver. Most drivers will embed the - * pads array in a driver-specific structure, avoiding dynamic allocation. - * - * Drivers must set the direction of every pad in the pads array before calling - * media_entity_pads_init. The function will initialize the other pads fields. - * - * Unlike the number of pads, the total number of links isn't always known in - * advance by the entity driver. As an initial estimate, media_entity_pads_init - * pre-allocates a number of links equal to the number of pads. The links array - * will be reallocated if it grows beyond the initial estimate. + * media_entity_pads_init(). * * Drivers register entities with a media device by calling + * media_device_register_entity() + * and unregistred by calling + * media_device_unregister_entity(). * - * media_device_register_entity(struct media_device *mdev, - * struct media_entity *entity); + * - Interfaces * - * Entities are identified by a unique positive integer ID. Drivers can provide an - * ID by filling the media_entity id field prior to registration, or request the - * media controller framework to assign an ID automatically. Drivers that provide - * IDs manually must ensure that all IDs are unique. IDs are not guaranteed to be - * contiguous even when they are all assigned automatically by the framework. + * Interfaces are represented by a struct &media_interface instance, defined in + * include/media/media-entity.h. Currently, only one type of interface is + * defined: a device node. Such interfaces are represented by a struct + * &media_intf_devnode. * - * Drivers unregister entities by calling - * - * media_device_unregister_entity(struct media_entity *entity); - * - * Unregistering an entity will not change the IDs of the other entities, and the - * ID will never be reused for a newly registered entity. - * - * When a media device is unregistered, all its entities are unregistered - * automatically. No manual entities unregistration is then required. - * - * Drivers free resources associated with an entity by calling - * - * media_entity_cleanup(struct media_entity *entity); - * - * This function must be called during the cleanup phase after unregistering the - * entity. Note that the media_entity instance itself must be freed explicitly by - * the driver if required. - * - * Entities have flags that describe the entity capabilities and state. - * - * MEDIA_ENT_FL_DEFAULT indicates the default entity for a given type. - * This can be used to report the default audio and video devices or the - * default camera sensor. - * - * Logical entity groups can be defined by setting the group ID of all member - * entities to the same non-zero value. An entity group serves no purpose in the - * kernel, but is reported to userspace during entities enumeration. - * - * Media device drivers should define groups if several entities are logically - * bound together. Example usages include reporting - * - * - ALSA, VBI and video nodes that carry the same media stream - * - lens and flash controllers associated with a sensor + * Drivers initialize and create device node interfaces by calling + * media_devnode_create() + * and remove them by calling: + * media_devnode_remove(). * * - Pads * - * Pads are represented by a struct media_pad instance, defined in + * Pads are represented by a struct &media_pad instance, defined in * include/media/media-entity.h. Each entity stores its pads in a pads array * managed by the entity driver. Drivers usually embed the array in a * driver-specific structure. * - * Pads are identified by their entity and their 0-based index in the pads array. - * Both information are stored in the media_pad structure, making the media_pad - * pointer the canonical way to store and pass link references. + * Pads are identified by their entity and their 0-based index in the pads + * array. + * Both information are stored in the &media_pad structure, making the + * &media_pad pointer the canonical way to store and pass link references. * * Pads have flags that describe the pad capabilities and state. * - * MEDIA_PAD_FL_SINK indicates that the pad supports sinking data. - * MEDIA_PAD_FL_SOURCE indicates that the pad supports sourcing data. + * %MEDIA_PAD_FL_SINK indicates that the pad supports sinking data. + * %MEDIA_PAD_FL_SOURCE indicates that the pad supports sourcing data. * - * One and only one of MEDIA_PAD_FL_SINK and MEDIA_PAD_FL_SOURCE must be set for - * each pad. + * NOTE: One and only one of %MEDIA_PAD_FL_SINK and %MEDIA_PAD_FL_SOURCE must + * be set for each pad. * * - Links * - * Links are represented by a struct media_link instance, defined in - * include/media/media-entity.h. Each entity stores all links originating at or - * targeting any of its pads in a links array. A given link is thus stored - * twice, once in the source entity and once in the target entity. The array is - * pre-allocated and grows dynamically as needed. + * Links are represented by a struct &media_link instance, defined in + * include/media/media-entity.h. There are two types of links: + * + * 1. pad to pad links: * - * Drivers create links by calling + * Associate two entities via their PADs. Each entity has a list that points + * to all links originating at or targeting any of its pads. + * A given link is thus stored twice, once in the source entity and once in + * the target entity. * - * media_create_pad_link(struct media_entity *source, u16 source_pad, - * struct media_entity *sink, u16 sink_pad, - * u32 flags); + * Drivers create pad to pad links by calling: + * media_create_pad_link() and remove with media_entity_remove_links(). * - * An entry in the link array of each entity is allocated and stores pointers - * to source and sink pads. + * 2. interface to entity links: * - * Links have flags that describe the link capabilities and state. + * Associate one interface to a Link. * - * MEDIA_LNK_FL_ENABLED indicates that the link is enabled and can be used - * to transfer media data. When two or more links target a sink pad, only - * one of them can be enabled at a time. - * MEDIA_LNK_FL_IMMUTABLE indicates that the link enabled state can't be - * modified at runtime. If MEDIA_LNK_FL_IMMUTABLE is set, then - * MEDIA_LNK_FL_ENABLED must also be set since an immutable link is always - * enabled. + * Drivers create interface to entity links by calling: + * media_create_intf_link() and remove with media_remove_intf_links(). * + * NOTE: * - * Graph traversal - * --------------- + * Links can only be created after having both ends already created. + * + * Links have flags that describe the link capabilities and state. The + * valid values are described at media_create_pad_link() and + * media_create_intf_link(). + * + * Graph traversal: * * The media framework provides APIs to iterate over entities in a graph. * - * To iterate over all entities belonging to a media device, drivers can use the - * media_device_for_each_entity macro, defined in include/media/media-device.h. + * To iterate over all entities belonging to a media device, drivers can use + * the media_device_for_each_entity macro, defined in + * include/media/media-device.h. * * struct media_entity *entity; * @@ -279,126 +176,82 @@ * currently defined as 16. * * Drivers initiate a graph traversal by calling - * - * media_entity_graph_walk_start(struct media_entity_graph *graph, - * struct media_entity *entity); + * media_entity_graph_walk_start() * * The graph structure, provided by the caller, is initialized to start graph * traversal at the given entity. * * Drivers can then retrieve the next entity by calling - * - * media_entity_graph_walk_next(struct media_entity_graph *graph); + * media_entity_graph_walk_next() * * When the graph traversal is complete the function will return NULL. * - * Graph traversal can be interrupted at any moment. No cleanup function call is - * required and the graph structure can be freed normally. + * Graph traversal can be interrupted at any moment. No cleanup function call + * is required and the graph structure can be freed normally. * * Helper functions can be used to find a link between two given pads, or a pad * connected to another pad through an enabled link + * media_entity_find_link() and media_entity_remote_pad() * - * media_entity_find_link(struct media_pad *source, - * struct media_pad *sink); - * - * media_entity_remote_pad(struct media_pad *pad); - * - * Refer to the kerneldoc documentation for more information. - * - * - * Use count and power handling - * ---------------------------- - * - * Due to the wide differences between drivers regarding power management needs, - * the media controller does not implement power management. However, the - * media_entity structure includes a use_count field that media drivers can use to - * track the number of users of every entity for power management needs. + * Use count and power handling: * - * The use_count field is owned by media drivers and must not be touched by entity - * drivers. Access to the field must be protected by the media device graph_mutex - * lock. + * Due to the wide differences between drivers regarding power management + * needs, the media controller does not implement power management. However, + * the &media_entity structure includes a use_count field that media drivers + * can use to track the number of users of every entity for power management + * needs. * + * The &media_entity.@use_count field is owned by media drivers and must not be + * touched by entity drivers. Access to the field must be protected by the + * &media_device.@graph_mutex lock. * - * Links setup - * ----------- + * Links setup: * * Link properties can be modified at runtime by calling + * media_entity_setup_link() * - * media_entity_setup_link(struct media_link *link, u32 flags); - * - * The flags argument contains the requested new link flags. - * - * The only configurable property is the ENABLED link flag to enable/disable a - * link. Links marked with the IMMUTABLE link flag can not be enabled or disabled. - * - * When a link is enabled or disabled, the media framework calls the - * link_setup operation for the two entities at the source and sink of the link, - * in that order. If the second link_setup call fails, another link_setup call is - * made on the first entity to restore the original link flags. - * - * Media device drivers can be notified of link setup operations by setting the - * media_device::link_notify pointer to a callback function. If provided, the - * notification callback will be called before enabling and after disabling - * links. - * - * Entity drivers must implement the link_setup operation if any of their links - * is non-immutable. The operation must either configure the hardware or store - * the configuration information to be applied later. - * - * Link configuration must not have any side effect on other links. If an enabled - * link at a sink pad prevents another link at the same pad from being enabled, - * the link_setup operation must return -EBUSY and can't implicitly disable the - * first enabled link. - * - * - * Pipelines and media streams - * --------------------------- + * Pipelines and media streams: * * When starting streaming, drivers must notify all entities in the pipeline to * prevent link states from being modified during streaming by calling - * - * media_entity_pipeline_start(struct media_entity *entity, - * struct media_pipeline *pipe); + * media_entity_pipeline_start(). * * The function will mark all entities connected to the given entity through * enabled links, either directly or indirectly, as streaming. * - * The media_pipeline instance pointed to by the pipe argument will be stored in - * every entity in the pipeline. Drivers should embed the media_pipeline structure - * in higher-level pipeline structures and can then access the pipeline through - * the media_entity pipe field. + * The &media_pipeline instance pointed to by the pipe argument will be stored + * in every entity in the pipeline. Drivers should embed the &media_pipeline + * structure in higher-level pipeline structures and can then access the + * pipeline through the &media_entity pipe field. * - * Calls to media_entity_pipeline_start() can be nested. The pipeline pointer must - * be identical for all nested calls to the function. + * Calls to media_entity_pipeline_start() can be nested. The pipeline pointer + * must be identical for all nested calls to the function. * * media_entity_pipeline_start() may return an error. In that case, it will * clean up any of the changes it did by itself. * * When stopping the stream, drivers must notify the entities with - * - * media_entity_pipeline_stop(struct media_entity *entity); + * media_entity_pipeline_stop(). * * If multiple calls to media_entity_pipeline_start() have been made the same - * number of media_entity_pipeline_stop() calls are required to stop streaming. The - * media_entity pipe field is reset to NULL on the last nested stop call. + * number of media_entity_pipeline_stop() calls are required to stop streaming. + * The &media_entity pipe field is reset to NULL on the last nested stop call. * - * Link configuration will fail with -EBUSY by default if either end of the link is - * a streaming entity. Links that can be modified while streaming must be marked - * with the MEDIA_LNK_FL_DYNAMIC flag. + * Link configuration will fail with -%EBUSY by default if either end of the + * link is a streaming entity. Links that can be modified while streaming must + * be marked with the %MEDIA_LNK_FL_DYNAMIC flag. * * If other operations need to be disallowed on streaming entities (such as * changing entities configuration parameters) drivers can explicitly check the * media_entity stream_count field to find out if an entity is streaming. This * operation must be done with the media_device graph_mutex held. * - * - * Link validation - * --------------- + * Link validation: * * Link validation is performed by media_entity_pipeline_start() for any * entity which has sink pads in the pipeline. The - * media_entity::link_validate() callback is used for that purpose. In - * link_validate() callback, entity driver should check that the properties of + * &media_entity.@link_validate() callback is used for that purpose. In + * @link_validate() callback, entity driver should check that the properties of * the source pad of the connected entity and its own sink pad match. It is up * to the type of the entity (and in the end, the properties of the hardware) * what matching actually means. @@ -484,13 +337,113 @@ struct media_device { /* media_devnode to media_device */ #define to_media_device(node) container_of(node, struct media_device, devnode) +/** + * __media_device_register() - Registers a media device element + * + * @mdev: pointer to struct &media_device + * @owner: should be filled with %THIS_MODULE + * + * Users, should, instead, call the media_device_register() macro. + * + * The caller is responsible for initializing the media_device structure before + * registration. The following fields must be set: + * + * - dev must point to the parent device (usually a &pci_dev, &usb_interface or + * &platform_device instance). + * + * - model must be filled with the device model name as a NUL-terminated UTF-8 + * string. The device/model revision must not be stored in this field. + * + * The following fields are optional: + * + * - serial is a unique serial number stored as a NUL-terminated ASCII string. + * The field is big enough to store a GUID in text form. If the hardware + * doesn't provide a unique serial number this field must be left empty. + * + * - bus_info represents the location of the device in the system as a + * NUL-terminated ASCII string. For PCI/PCIe devices bus_info must be set to + * "PCI:" (or "PCIe:") followed by the value of pci_name(). For USB devices, + * the usb_make_path() function must be used. This field is used by + * applications to distinguish between otherwise identical devices that don't + * provide a serial number. + * + * - hw_revision is the hardware device revision in a driver-specific format. + * When possible the revision should be formatted with the KERNEL_VERSION + * macro. + * + * - driver_version is formatted with the KERNEL_VERSION macro. The version + * minor must be incremented when new features are added to the userspace API + * without breaking binary compatibility. The version major must be + * incremented when binary compatibility is broken. + * + * Notes: + * + * Upon successful registration a character device named media[0-9]+ is created. + * The device major and minor numbers are dynamic. The model name is exported as + * a sysfs attribute. + * + * Unregistering a media device that hasn't been registered is *NOT* safe. + */ int __must_check __media_device_register(struct media_device *mdev, struct module *owner); #define media_device_register(mdev) __media_device_register(mdev, THIS_MODULE) + +/** + * __media_device_unregister() - Unegisters a media device element + * + * @mdev: pointer to struct &media_device + */ void media_device_unregister(struct media_device *mdev); +/** + * media_device_register_entity() - registers a media entity inside a + * previously registered media device. + * + * @mdev: pointer to struct &media_device + * @entity: pointer to struct &media_entity to be registered + * + * Entities are identified by a unique positive integer ID. The media + * controller framework will such ID automatically. IDs are not guaranteed + * to be contiguous, and the ID number can change on newer Kernel versions. + * So, neither the driver nor userspace should hardcode ID numbers to refer + * to the entities, but, instead, use the framework to find the ID, when + * needed. + * + * The media_entity name, type and flags fields should be initialized before + * calling media_device_register_entity(). Entities embedded in higher-level + * standard structures can have some of those fields set by the higher-level + * framework. + * + * If the device has pads, media_entity_pads_init() should be called before + * this function. Otherwise, the &media_entity.@pad and &media_entity.@num_pads + * should be zeroed before calling this function. + * + * Entities have flags that describe the entity capabilities and state: + * + * %MEDIA_ENT_FL_DEFAULT indicates the default entity for a given type. + * This can be used to report the default audio and video devices or the + * default camera sensor. + */ int __must_check media_device_register_entity(struct media_device *mdev, struct media_entity *entity); + +/* + * media_device_unregister_entity() - unregisters a media entity. + * + * @entity: pointer to struct &media_entity to be unregistered + * + * All links associated with the entity and all PADs are automatically + * unregistered from the media_device when this function is called. + * + * Unregistering an entity will not change the IDs of the other entities and + * the previoully used ID will never be reused for a newly registered entities. + * + * When a media device is unregistered, all its entities are unregistered + * automatically. No manual entities unregistration is then required. + * + * Note: the media_entity instance itself must be freed explicitly by + * the driver if required. + */ void media_device_unregister_entity(struct media_entity *entity); struct media_device *media_device_get_devres(struct device *dev); struct media_device *media_device_find_devres(struct device *dev); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index e9bc5857899c..51a7353effd0 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -343,18 +343,112 @@ void media_gobj_init(struct media_device *mdev, struct media_gobj *gobj); void media_gobj_remove(struct media_gobj *gobj); +/** + * media_entity_pads_init() - Initialize the entity pads + * + * @entity: entity where the pads belong + * @num_pads: number of pads to be initialized + * @pads: pads array + * + * If no pads are needed, drivers could either directly fill + * &media_entity->@num_pads with 0 and &media_entity->@pads with NULL or call + * this function that will do the same. + * + * As the number of pads is known in advance, the pads array is not allocated + * dynamically but is managed by the entity driver. Most drivers will embed the + * pads array in a driver-specific structure, avoiding dynamic allocation. + * + * Drivers must set the direction of every pad in the pads array before calling + * media_entity_pads_init(). The function will initialize the other pads fields. + */ int media_entity_pads_init(struct media_entity *entity, u16 num_pads, struct media_pad *pads); +/** + * media_entity_cleanup() - free resources associated with an entity + * + * @entity: entity where the pads belong + * + * This function must be called during the cleanup phase after unregistering + * the entity (currently, it does nothing). + */ static inline void media_entity_cleanup(struct media_entity *entity) {}; +/** + * media_create_pad_link() - creates a link between two entities. + * + * @source: pointer to &media_entity of the source pad. + * @source_pad: number of the source pad in the pads array + * @sink: pointer to &media_entity of the sink pad. + * @sink_pad: number of the sink pad in the pads array. + * @flags: Link flags, as defined in include/uapi/linux/media.h. + * + * Valid values for flags: + * A %MEDIA_LNK_FL_ENABLED flag indicates that the link is enabled and can be + * used to transfer media data. When two or more links target a sink pad, + * only one of them can be enabled at a time. + * + * A %MEDIA_LNK_FL_IMMUTABLE flag indicates that the link enabled state can't + * be modified at runtime. If %MEDIA_LNK_FL_IMMUTABLE is set, then + * %MEDIA_LNK_FL_ENABLED must also be set since an immutable link is + * always enabled. + * + * NOTE: + * + * Before calling this function, media_entity_pads_init() and + * media_device_register_entity() should be called previously for both ends. + */ __must_check int media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flags); void __media_entity_remove_links(struct media_entity *entity); + +/** + * media_entity_remove_links() - remove all links associated with an entity + * + * @entity: pointer to &media_entity + * + * Note: this is called automatically when an entity is unregistered via + * media_device_register_entity(). + */ void media_entity_remove_links(struct media_entity *entity); int __media_entity_setup_link(struct media_link *link, u32 flags); + +/** + * media_entity_setup_link() - changes the link flags properties in runtime + * + * @link: pointer to &media_link + * @flags: the requested new link flags + * + * The only configurable property is the %MEDIA_LNK_FL_ENABLED link flag + * flag to enable/disable a link. Links marked with the + * %MEDIA_LNK_FL_IMMUTABLE link flag can not be enabled or disabled. + * + * When a link is enabled or disabled, the media framework calls the + * link_setup operation for the two entities at the source and sink of the + * link, in that order. If the second link_setup call fails, another + * link_setup call is made on the first entity to restore the original link + * flags. + * + * Media device drivers can be notified of link setup operations by setting the + * media_device::link_notify pointer to a callback function. If provided, the + * notification callback will be called before enabling and after disabling + * links. + * + * Entity drivers must implement the link_setup operation if any of their links + * is non-immutable. The operation must either configure the hardware or store + * the configuration information to be applied later. + * + * Link configuration must not have any side effect on other links. If an + * enabled link at a sink pad prevents another link at the same pad from + * being enabled, the link_setup operation must return -EBUSY and can't + * implicitly disable the first enabled link. + * + * NOTE: the valid values of the flags for the link is the same as described + * on media_create_pad_link(), for pad to pad links or the same as described + * on media_create_intf_link(), for interface to entity links. + */ int media_entity_setup_link(struct media_link *link, u32 flags); struct media_link *media_entity_find_link(struct media_pad *source, struct media_pad *sink); @@ -371,18 +465,72 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, struct media_pipeline *pipe); void media_entity_pipeline_stop(struct media_entity *entity); +/** + * media_devnode_create() - creates and initializes a device node interface + * + * @mdev: pointer to struct &media_device + * @type: type of the interface, as given by MEDIA_INTF_T_* macros + * as defined in the uapi/media/media.h header. + * @flags: Interface flags as defined in uapi/media/media.h. + * @major: Device node major number. + * @minor: Device node minor number. + * + * Return: if succeeded, returns a pointer to the newly allocated + * &media_intf_devnode pointer. + */ struct media_intf_devnode * __must_check media_devnode_create(struct media_device *mdev, u32 type, u32 flags, u32 major, u32 minor); +/** + * media_devnode_remove() - removes a device node interface + * + * @devnode: pointer to &media_intf_devnode to be freed. + * + * When a device node interface is removed, all links to it are automatically + * removed. + */ void media_devnode_remove(struct media_intf_devnode *devnode); struct media_link * + +/** + * media_create_intf_link() - creates a link between an entity and an interface + * + * @entity: pointer to %media_entity + * @intf: pointer to %media_interface + * @flags: Link flags, as defined in include/uapi/linux/media.h. + * + * + * Valid values for flags: + * The %MEDIA_LNK_FL_ENABLED flag indicates that the interface is connected to + * the entity hardware. That's the default value for interfaces. An + * interface may be disabled if the hardware is busy due to the usage + * of some other interface that it is currently controlling the hardware. + * A typical example is an hybrid TV device that handle only one type of + * stream on a given time. So, when the digital TV is streaming, + * the V4L2 interfaces won't be enabled, as such device is not able to + * also stream analog TV or radio. + * + * Note: + * + * Before calling this function, media_devnode_create() should be called for + * the interface and media_device_register_entity() should be called for the + * interface that will be part of the link. + */ __must_check media_create_intf_link(struct media_entity *entity, struct media_interface *intf, u32 flags); void __media_remove_intf_link(struct media_link *link); void media_remove_intf_link(struct media_link *link); void __media_remove_intf_links(struct media_interface *intf); +/** + * media_remove_intf_links() - remove all links associated with an interface + * + * @intf: pointer to &media_interface + * + * Note: this is called automatically when an entity is unregistered via + * media_device_register_entity() and by media_devnode_remove(). + */ void media_remove_intf_links(struct media_interface *intf); -- cgit v1.2.3 From 97d0a70ae5e2391f213966a69c3b6f96f2c9f25b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 11:12:57 -0200 Subject: [media] media: remove extra blank lines No functional changes. Suggested-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index 65fdd44e05ef..f9907a7728d4 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -463,8 +463,6 @@ struct media_device *media_device_find_devres(struct device *dev); /* Iterate over all links. */ #define media_device_for_each_link(link, mdev) \ list_for_each_entry(link, &(mdev)->links, graph_obj.list) - - #else static inline int media_device_register(struct media_device *mdev) { -- cgit v1.2.3 From c350ef830f2c3dfe80e9a777c8a64ac1fb186b9a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 11:55:40 -0200 Subject: [media] media_entity: rename media_obj functions to *_create *_destroy Those media_obj_* functions are actually creating/destroying media graph objects. So, rename them to better represent what they're actually doing. No functional changes. This was created via this small shell script: for i in $(git grep -l media_gobj_init); do sed s,media_gobj_init,media_gobj_create,g <$i >a && mv a $i; done for i in $(git grep -l media_gobj_remove); do sed s,media_gobj_remove,media_gobj_destroy,g <$i >a && mv a $i; done Suggested-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 51a7353effd0..1b954fb88def 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -338,10 +338,10 @@ struct media_entity_graph { #define intf_to_devnode(intf) \ container_of(intf, struct media_intf_devnode, intf) -void media_gobj_init(struct media_device *mdev, +void media_gobj_create(struct media_device *mdev, enum media_gobj_type type, struct media_gobj *gobj); -void media_gobj_remove(struct media_gobj *gobj); +void media_gobj_destroy(struct media_gobj *gobj); /** * media_entity_pads_init() - Initialize the entity pads -- cgit v1.2.3 From 1fc25d30a40c27b85510e6e598aec629532eb85c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 12:14:58 -0200 Subject: [media] media-entity.h: move kernel-doc tags from media-entity.c Several additional functions are described at media-entity.c. Moving them to the header file, to make the code cleaner and to have all such macros at the same place. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 136 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 134 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 1b954fb88def..d073b205e6a6 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -338,17 +338,43 @@ struct media_entity_graph { #define intf_to_devnode(intf) \ container_of(intf, struct media_intf_devnode, intf) +/** + * media_gobj_create - Initialize a graph object + * + * @mdev: Pointer to the media_device that contains the object + * @type: Type of the object + * @gobj: Pointer to the graph object + * + * This routine initializes the embedded struct media_gobj inside a + * media graph object. It is called automatically if media_*_create() + * calls are used. However, if the object (entity, link, pad, interface) + * is embedded on some other object, this function should be called before + * registering the object at the media controller. + */ void media_gobj_create(struct media_device *mdev, enum media_gobj_type type, struct media_gobj *gobj); + +/** + * media_gobj_destroy - Stop using a graph object on a media device + * + * @gobj: Pointer to the graph object + * + * This should be called by all routines like media_device_unregister() + * that remove/destroy media graph objects. + */ void media_gobj_destroy(struct media_gobj *gobj); /** * media_entity_pads_init() - Initialize the entity pads * * @entity: entity where the pads belong - * @num_pads: number of pads to be initialized - * @pads: pads array + * @num_pads: total number of sink and source pads + * @pads: Array of @num_pads pads. + * + * The pads array is managed by the entity driver and passed to + * media_entity_pads_init() where its pointer will be stored in the entity + * structure. * * If no pads are needed, drivers could either directly fill * &media_entity->@num_pads with 0 and &media_entity->@pads with NULL or call @@ -413,6 +439,20 @@ void __media_entity_remove_links(struct media_entity *entity); */ void media_entity_remove_links(struct media_entity *entity); +/** + * __media_entity_setup_link - Configure a media link without locking + * @link: The link being configured + * @flags: Link configuration flags + * + * The bulk of link setup is handled by the two entities connected through the + * link. This function notifies both entities of the link configuration change. + * + * If the link is immutable or if the current and new configuration are + * identical, return immediately. + * + * The user is expected to hold link->source->parent->mutex. If not, + * media_entity_setup_link() should be used instead. + */ int __media_entity_setup_link(struct media_link *link, u32 flags); /** @@ -450,19 +490,111 @@ int __media_entity_setup_link(struct media_link *link, u32 flags); * on media_create_intf_link(), for interface to entity links. */ int media_entity_setup_link(struct media_link *link, u32 flags); + +/** + * media_entity_find_link - Find a link between two pads + * @source: Source pad + * @sink: Sink pad + * + * Return a pointer to the link between the two entities. If no such link + * exists, return NULL. + */ struct media_link *media_entity_find_link(struct media_pad *source, struct media_pad *sink); + +/** + * media_entity_remote_pad - Find the pad at the remote end of a link + * @pad: Pad at the local end of the link + * + * Search for a remote pad connected to the given pad by iterating over all + * links originating or terminating at that pad until an enabled link is found. + * + * Return a pointer to the pad at the remote end of the first found enabled + * link, or NULL if no enabled link has been found. + */ struct media_pad *media_entity_remote_pad(struct media_pad *pad); +/** + * media_entity_get - Get a reference to the parent module + * + * @entity: The entity + * + * Get a reference to the parent media device module. + * + * The function will return immediately if @entity is NULL. + * + * Return a pointer to the entity on success or NULL on failure. + */ struct media_entity *media_entity_get(struct media_entity *entity); + +/** + * media_entity_put - Release the reference to the parent module + * + * @entity: The entity + * + * Release the reference count acquired by media_entity_get(). + * + * The function will return immediately if @entity is NULL. + */ void media_entity_put(struct media_entity *entity); +/** + * media_entity_graph_walk_start - Start walking the media graph at a given entity + * @graph: Media graph structure that will be used to walk the graph + * @entity: Starting entity + * + * This function initializes the graph traversal structure to walk the entities + * graph starting at the given entity. The traversal structure must not be + * modified by the caller during graph traversal. When done the structure can + * safely be freed. + */ void media_entity_graph_walk_start(struct media_entity_graph *graph, struct media_entity *entity); + +/** + * media_entity_graph_walk_next - Get the next entity in the graph + * @graph: Media graph structure + * + * Perform a depth-first traversal of the given media entities graph. + * + * The graph structure must have been previously initialized with a call to + * media_entity_graph_walk_start(). + * + * Return the next entity in the graph or NULL if the whole graph have been + * traversed. + */ struct media_entity * media_entity_graph_walk_next(struct media_entity_graph *graph); + +/** + * media_entity_pipeline_start - Mark a pipeline as streaming + * @entity: Starting entity + * @pipe: Media pipeline to be assigned to all entities in the pipeline. + * + * Mark all entities connected to a given entity through enabled links, either + * directly or indirectly, as streaming. The given pipeline object is assigned to + * every entity in the pipeline and stored in the media_entity pipe field. + * + * Calls to this function can be nested, in which case the same number of + * media_entity_pipeline_stop() calls will be required to stop streaming. The + * pipeline pointer must be identical for all nested calls to + * media_entity_pipeline_start(). + */ __must_check int media_entity_pipeline_start(struct media_entity *entity, struct media_pipeline *pipe); + +/** + * media_entity_pipeline_stop - Mark a pipeline as not streaming + * @entity: Starting entity + * + * Mark all entities connected to a given entity through enabled links, either + * directly or indirectly, as not streaming. The media_entity pipe field is + * reset to NULL. + * + * If multiple calls to media_entity_pipeline_start() have been made, the same + * number of calls to this function are required to mark the pipeline as not + * streaming. + */ void media_entity_pipeline_stop(struct media_entity *entity); /** -- cgit v1.2.3 From d1b9da2d606ecec587177c4c90f1905c57538149 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 12:41:12 -0200 Subject: [media] media-device.h: Let clearer that entity function must be initialized Improve the documentation to let it clear that the entity function must be initialized. Suggested-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 4 ++++ include/uapi/linux/media.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index f9907a7728d4..215a0d88241d 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -423,6 +423,10 @@ void media_device_unregister(struct media_device *mdev); * %MEDIA_ENT_FL_DEFAULT indicates the default entity for a given type. * This can be used to report the default audio and video devices or the * default camera sensor. + * + * NOTE: Drivers should set the entity function before calling this function. + * Please notice that the values %MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN and + * %MEDIA_ENT_F_UNKNOWN should not be used by the drivers. */ int __must_check media_device_register_entity(struct media_device *mdev, struct media_entity *entity); diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index ff6a8010c520..8d8e1a3e6e1a 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -92,7 +92,7 @@ struct media_device_info { * * Subdevs are initialized with MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN, * in order to preserve backward compatibility. - * Drivers should change to the proper subdev type before + * Drivers must change to the proper subdev type before * registering the entity. */ -- cgit v1.2.3 From b3b7a9f138b7539c25e036d398616f6737b08ff7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 16:07:57 -0200 Subject: [media] media-device: Use u64 ints for pointers By using u64 integers and pointers, we can get rid of compat32 logic. So, let's do it! Suggested-by: Arnd Bergmann Suggested-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/media.h | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'include') diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 8d8e1a3e6e1a..86f9753e5c03 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -23,6 +23,9 @@ #ifndef __LINUX_MEDIA_H #define __LINUX_MEDIA_H +#ifndef __KERNEL__ +#include +#endif #include #include #include @@ -320,27 +323,26 @@ struct media_v2_link { }; struct media_v2_topology { - __u32 topology_version; + __u64 topology_version; - __u32 num_entities; - struct media_v2_entity *entities; + __u64 num_entities; + __u64 ptr_entities; - __u32 num_interfaces; - struct media_v2_interface *interfaces; + __u64 num_interfaces; + __u64 ptr_interfaces; - __u32 num_pads; - struct media_v2_pad *pads; + __u64 num_pads; + __u64 ptr_pads; - __u32 num_links; - struct media_v2_link *links; - - struct { - __u32 reserved_num; - void *reserved_ptr; - } reserved_types[16]; - __u32 reserved[8]; + __u64 num_links; + __u64 ptr_links; }; +static inline void __user *media_get_uptr(__u64 arg) +{ + return (void __user *)(uintptr_t)arg; +} + /* ioctls */ #define MEDIA_IOC_DEVICE_INFO _IOWR('|', 0x00, struct media_device_info) -- cgit v1.2.3 From b3109d662d744c065f2a1da5e9b8d08f2189c2ac Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 11 Dec 2015 18:26:53 -0200 Subject: [media] media.h: let be clear that tuners need to use connectors The V4L2 core won't be adding connectors to the tuners and other entities that need them. Let it be clear. Suggested-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/media.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 86f9753e5c03..cacfceb0d81d 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -74,10 +74,11 @@ struct media_device_info { /* * Connectors */ +/* It is a responsibility of the entity drivers to add connectors and links */ #define MEDIA_ENT_F_CONN_RF (MEDIA_ENT_F_BASE + 21) #define MEDIA_ENT_F_CONN_SVIDEO (MEDIA_ENT_F_BASE + 22) #define MEDIA_ENT_F_CONN_COMPOSITE (MEDIA_ENT_F_BASE + 23) - /* For internal test signal generators and other debug connectors */ +/* For internal test signal generators and other debug connectors */ #define MEDIA_ENT_F_CONN_TEST (MEDIA_ENT_F_BASE + 24) /* @@ -105,6 +106,10 @@ struct media_device_info { #define MEDIA_ENT_F_FLASH (MEDIA_ENT_F_OLD_SUBDEV_BASE + 2) #define MEDIA_ENT_F_LENS (MEDIA_ENT_F_OLD_SUBDEV_BASE + 3) #define MEDIA_ENT_F_ATV_DECODER (MEDIA_ENT_F_OLD_SUBDEV_BASE + 4) +/* + * It is a responsibility of the entity drivers to add connectors and links + * for the tuner entities. + */ #define MEDIA_ENT_F_TUNER (MEDIA_ENT_F_OLD_SUBDEV_BASE + 5) #define MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN MEDIA_ENT_F_OLD_SUBDEV_BASE -- cgit v1.2.3 From 60266185d7f3eeae5714090e1e10840b96df91d2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 13 Dec 2015 08:20:46 -0200 Subject: [media] media-entity.h: Document some ancillary functions Add a basic documentation for most ancillary functions. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 58 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index d073b205e6a6..81aca1f5a09a 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -238,11 +238,21 @@ struct media_intf_devnode { u32 minor; }; +/** + * media_entity_id() - return the media entity graph object id + * + * @entity: pointer to entity + */ static inline u32 media_entity_id(struct media_entity *entity) { return entity->graph_obj.id; } +/** + * media_type() - return the media object type + * + * @gobj: pointer to the media graph object + */ static inline enum media_gobj_type media_type(struct media_gobj *gobj) { return gobj->id >> MEDIA_BITS_PER_LOCAL_ID; @@ -263,6 +273,15 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u32 local_id) return id; } +/** + * is_media_entity_v4l2_io() - identify if the entity main function + * is a V4L2 I/O + * + * @entity: pointer to entity + * + * Return: true if the entity main function is one of the V4L2 I/O types + * (video, VBI or SDR radio); false otherwise. + */ static inline bool is_media_entity_v4l2_io(struct media_entity *entity) { if (!entity) @@ -278,6 +297,16 @@ static inline bool is_media_entity_v4l2_io(struct media_entity *entity) } } +/** + * is_media_entity_v4l2_subdev - return true if the entity main function is + * associated with the V4L2 API subdev usage + * + * @entity: pointer to entity + * + * This is an ancillary function used by subdev-based V4L2 drivers. + * It checks if the entity function is one of functions used by a V4L2 subdev, + * e. g. camera-relatef functions, analog TV decoder, TV tuner, V4L2 DSPs. + */ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) { if (!entity) @@ -652,16 +681,43 @@ struct media_link * __must_check media_create_intf_link(struct media_entity *entity, struct media_interface *intf, u32 flags); +/** + * __media_remove_intf_link() - remove a single interface link + * + * @link: pointer to &media_link. + * + * Note: this is an unlocked version of media_remove_intf_link() + */ void __media_remove_intf_link(struct media_link *link); + +/** + * media_remove_intf_link() - remove a single interface link + * + * @link: pointer to &media_link. + * + * Note: prefer to use this one, instead of __media_remove_intf_link() + */ void media_remove_intf_link(struct media_link *link); + +/** + * __media_remove_intf_links() - remove all links associated with an interface + * + * @intf: pointer to &media_interface + * + * Note: this is an unlocked version of media_remove_intf_links(). + */ void __media_remove_intf_links(struct media_interface *intf); /** * media_remove_intf_links() - remove all links associated with an interface * * @intf: pointer to &media_interface * - * Note: this is called automatically when an entity is unregistered via + * Notes: + * + * this is called automatically when an entity is unregistered via * media_device_register_entity() and by media_devnode_remove(). + * + * Prefer to use this one, instead of __media_remove_intf_links(). */ void media_remove_intf_links(struct media_interface *intf); -- cgit v1.2.3 From b6e4ca8129ad65a0b1552586c1d42d2fd219661e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 13 Dec 2015 08:36:58 -0200 Subject: [media] media-device.h: document the last functions Add kernel-doc documentation for media_device_get_devres and media_device_find_devres. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index 215a0d88241d..ebc2f3a239eb 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -449,7 +449,29 @@ int __must_check media_device_register_entity(struct media_device *mdev, * the driver if required. */ void media_device_unregister_entity(struct media_entity *entity); + +/** + * media_device_get_devres() - get media device as device resource + * creates if one doesn't exist + * + * @dev: pointer to struct &device. + * + * Sometimes, the media controller &media_device needs to be shared by more + * than one driver. This function adds support for that, by dynamically + * allocating the &media_device and allowing it to be obtained from the + * struct &device associated with the common device where all sub-device + * components belong. So, for example, on an USB device with multiple + * interfaces, each interface may be handled by a separate per-interface + * drivers. While each interface have its own &device, they all share a + * common &device associated with the hole USB device. + */ struct media_device *media_device_get_devres(struct device *dev); + +/** + * media_device_find_devres() - find media device as device resource + * + * @dev: pointer to struct &device. + */ struct media_device *media_device_find_devres(struct device *dev); /* Iterate over all entities. */ -- cgit v1.2.3 From fe3c565e4cbcb2adeef063accc7852de739aaa36 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 13 Dec 2015 08:40:45 -0200 Subject: [media] media-devnode: move kernel-doc documentation to the header As we're using the headers file only for documentation, move the two kernel-doc macros to the header, and fix it to avoid warnings. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-devnode.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'include') diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h index 17ddae32060d..77e9d3159be8 100644 --- a/include/media/media-devnode.h +++ b/include/media/media-devnode.h @@ -86,8 +86,35 @@ struct media_devnode { /* dev to media_devnode */ #define to_media_devnode(cd) container_of(cd, struct media_devnode, dev) +/** + * media_devnode_register - register a media device node + * + * @mdev: media device node structure we want to register + * @owner: should be filled with %THIS_MODULE + * + * The registration code assigns minor numbers and registers the new device node + * with the kernel. An error is returned if no free minor number can be found, + * or if the registration of the device node fails. + * + * Zero is returned on success. + * + * Note that if the media_devnode_register call fails, the release() callback of + * the media_devnode structure is *not* called, so the caller is responsible for + * freeing any data. + */ int __must_check media_devnode_register(struct media_devnode *mdev, struct module *owner); + +/** + * media_devnode_unregister - unregister a media device node + * @mdev: the device node to unregister + * + * This unregisters the passed device. Future open calls will be met with + * errors. + * + * This function can safely be called if the device node has never been + * registered or has already been unregistered. + */ void media_devnode_unregister(struct media_devnode *mdev); static inline struct media_devnode *media_devnode_data(struct file *filp) -- cgit v1.2.3 From 75c7e295707e7a9d13691377f2154dcbae9a25f8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 13 Dec 2015 09:00:00 -0200 Subject: [media] media-devnode.h: document the remaining struct/functions There is one struct and two functions that were not documented. Add the corresponding kernel-doc documentation for them. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-devnode.h | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h index 77e9d3159be8..fe42f08e72bd 100644 --- a/include/media/media-devnode.h +++ b/include/media/media-devnode.h @@ -40,6 +40,20 @@ */ #define MEDIA_FLAG_REGISTERED 0 +/** + * struct media_file_operations - Media device file operations + * + * @owner: should be filled with %THIS_MODULE + * @read: pointer to the function that implements read() syscall + * @write: pointer to the function that implements write() syscall + * @poll: pointer to the function that implements poll() syscall + * @ioctl: pointer to the function that implements ioctl() syscall + * @compat_ioctl: pointer to the function that will handle 32 bits userspace + * calls to the the ioctl() syscall on a Kernel compiled with 64 bits. + * @open: pointer to the function that implements open() syscall + * @release: pointer to the function that will release the resources allocated + * by the @open function. + */ struct media_file_operations { struct module *owner; ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); @@ -53,7 +67,7 @@ struct media_file_operations { /** * struct media_devnode - Media device node - * @fops: pointer to struct media_file_operations with media device ops + * @fops: pointer to struct &media_file_operations with media device ops * @dev: struct device pointer for the media controller device * @cdev: struct cdev pointer character device * @parent: parent device @@ -117,11 +131,22 @@ int __must_check media_devnode_register(struct media_devnode *mdev, */ void media_devnode_unregister(struct media_devnode *mdev); +/** + * media_devnode_data - returns a pointer to the &media_devnode + * + * @filp: pointer to struct &file + */ static inline struct media_devnode *media_devnode_data(struct file *filp) { return filp->private_data; } +/** + * media_devnode_is_registered - returns true if &media_devnode is registered; + * false otherwise. + * + * @mdev: pointer to struct &media_devnode. + */ static inline int media_devnode_is_registered(struct media_devnode *mdev) { return test_bit(MEDIA_FLAG_REGISTERED, &mdev->flags); -- cgit v1.2.3 From 9832e155f1ed3030fdfaa19e72c06472dc2ecb1d Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Fri, 11 Dec 2015 20:57:08 -0200 Subject: [media] media-device: split media initialization and registration The media device node is registered and so made visible to user-space before entities are registered and links created which means that the media graph obtained by user-space could be only partially enumerated if that happens too early before all the graph has been created. To avoid this race condition, split the media init and registration in separate functions and only register the media device node when all the pending subdevices have been registered, either explicitly by the driver or asynchronously using v4l2_async_register_subdev(). The media_device_register() had a check for drivers not filling dev and model fields but all drivers in mainline set them and not doing it will be a driver bug so change the function return to void and add a BUG_ON() for dev being NULL instead. Also, add a media_device_cleanup() function that will destroy the graph_mutex that is initialized in media_device_init(). [mchehab@osg.samsung.com: Fix compilation if !CONFIG_MEDIA_CONTROLLER and remove two warnings added by this changeset] Suggested-by: Sakari Ailus Signed-off-by: Javier Martinez Canillas Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index ebc2f3a239eb..e01bbc427fcd 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -337,6 +337,32 @@ struct media_device { /* media_devnode to media_device */ #define to_media_device(node) container_of(node, struct media_device, devnode) +/** + * media_device_init() - Initializes a media device element + * + * @mdev: pointer to struct &media_device + * + * This function initializes the media device prior to its registration. + * The media device initialization and registration is split in two functions + * to avoid race conditions and make the media device available to user-space + * before the media graph has been completed. + * + * So drivers need to first initialize the media device, register any entity + * within the media device, create pad to pad links and then finally register + * the media device by calling media_device_register() as a final step. + */ +void media_device_init(struct media_device *mdev); + +/** + * media_device_cleanup() - Cleanups a media device element + * + * @mdev: pointer to struct &media_device + * + * This function that will destroy the graph_mutex that is + * initialized in media_device_init(). + */ +void media_device_cleanup(struct media_device *mdev); + /** * __media_device_register() - Registers a media device element * -- cgit v1.2.3 From 665faa971d087e8b968ef75d04079a7a462ddfca Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:17 -0200 Subject: [media] media: Introduce internal index for media entities The internal index can be used internally by the framework in order to keep track of entities for a purpose or another. The internal index is constant while it's registered to a media device, but the same index may be re-used once the entity having that index is unregistered. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 4 ++++ include/media/media-entity.h | 3 +++ 2 files changed, 7 insertions(+) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index e01bbc427fcd..2ab4e6803842 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -261,6 +261,7 @@ * in the end provide a way to use driver-specific callbacks. */ +struct ida; struct device; /** @@ -278,6 +279,7 @@ struct device; * @pad_id: Unique ID used on the last pad registered * @link_id: Unique ID used on the last link registered * @intf_devnode_id: Unique ID used on the last interface devnode registered + * @entity_internal_idx: Allocated internal entity indices * @entities: List of registered entities * @interfaces: List of registered interfaces * @pads: List of registered pads @@ -313,6 +315,8 @@ struct media_device { u32 pad_id; u32 link_id; u32 intf_devnode_id; + struct ida entity_internal_idx; + int entity_internal_idx_max; struct list_head entities; struct list_head interfaces; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 81aca1f5a09a..30e8f9fd3efa 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -157,6 +157,8 @@ struct media_entity_operations { * @num_pads: Number of sink and source pads. * @num_links: Total number of links, forward and back, enabled and disabled. * @num_backlinks: Number of backlinks + * @internal_idx: An unique internal entity specific number. The numbers are + * re-used if entities are unregistered or registered again. * @pads: Pads array with the size defined by @num_pads. * @links: List of data links. * @ops: Entity operations. @@ -183,6 +185,7 @@ struct media_entity { u16 num_pads; u16 num_links; u16 num_backlinks; + int internal_idx; struct media_pad *pads; struct list_head links; -- cgit v1.2.3 From c8d54cd53b43c514fbd8d36abf0f2f00f719dd54 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:44:32 -0200 Subject: [media] media: Add an API to manage entity enumerations This is useful in e.g. knowing whether certain operations have already been performed for an entity. The users include the framework itself (for graph walking) and a number of drivers. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 15 +++++ include/media/media-entity.h | 141 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 148 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index 2ab4e6803842..da4e12ca259c 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -341,6 +341,21 @@ struct media_device { /* media_devnode to media_device */ #define to_media_device(node) container_of(node, struct media_device, devnode) +/** + * media_entity_enum_init - Initialise an entity enumeration + * + * @e: Entity enumeration to be initialised + * @mdev: The related media device + * + * Returns zero on success or a negative error code. + */ +static inline __must_check int media_entity_enum_init( + struct media_entity_enum *ent_enum, struct media_device *mdev) +{ + return __media_entity_enum_init(ent_enum, + mdev->entity_internal_idx_max + 1); +} + /** * media_device_init() - Initializes a media device element * diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 30e8f9fd3efa..c593dbd3e030 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -23,7 +23,7 @@ #ifndef _MEDIA_ENTITY_H #define _MEDIA_ENTITY_H -#include +#include #include #include #include @@ -71,6 +71,32 @@ struct media_gobj { struct list_head list; }; +#define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 +#define MEDIA_ENTITY_ENUM_MAX_ID 64 + +/* + * The number of pads can't be bigger than the number of entities, + * as the worse-case scenario is to have one entity linked up to + * MEDIA_ENTITY_ENUM_MAX_ID - 1 entities. + */ +#define MEDIA_ENTITY_MAX_PADS (MEDIA_ENTITY_ENUM_MAX_ID - 1) + +/** + * struct media_entity_enum - An enumeration of media entities. + * + * @prealloc_bmap: Pre-allocated space reserved for media entities if the + * total number of entities does not exceed + * MEDIA_ENTITY_ENUM_MAX_ID. + * @bmap: Bit map in which each bit represents one entity at struct + * media_entity->internal_idx. + * @idx_max: Number of bits in bmap + */ +struct media_entity_enum { + DECLARE_BITMAP(prealloc_bmap, MEDIA_ENTITY_ENUM_MAX_ID); + unsigned long *bmap; + int idx_max; +}; + struct media_pipeline { }; @@ -329,15 +355,114 @@ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) } } -#define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 -#define MEDIA_ENTITY_ENUM_MAX_ID 64 +__must_check int __media_entity_enum_init(struct media_entity_enum *ent_enum, + int idx_max); +void media_entity_enum_cleanup(struct media_entity_enum *e); -/* - * The number of pads can't be bigger than the number of entities, - * as the worse-case scenario is to have one entity linked up to - * MEDIA_ENTITY_ENUM_MAX_ID - 1 entities. +/** + * media_entity_enum_zero - Clear the entire enum + * + * @e: Entity enumeration to be cleared */ -#define MEDIA_ENTITY_MAX_PADS (MEDIA_ENTITY_ENUM_MAX_ID - 1) +static inline void media_entity_enum_zero(struct media_entity_enum *ent_enum) +{ + bitmap_zero(ent_enum->bmap, ent_enum->idx_max); +} + +/** + * media_entity_enum_set - Mark a single entity in the enum + * + * @e: Entity enumeration + * @entity: Entity to be marked + */ +static inline void media_entity_enum_set(struct media_entity_enum *ent_enum, + struct media_entity *entity) +{ + if (WARN_ON(entity->internal_idx >= ent_enum->idx_max)) + return; + + __set_bit(entity->internal_idx, ent_enum->bmap); +} + +/** + * media_entity_enum_clear - Unmark a single entity in the enum + * + * @e: Entity enumeration + * @entity: Entity to be unmarked + */ +static inline void media_entity_enum_clear(struct media_entity_enum *ent_enum, + struct media_entity *entity) +{ + if (WARN_ON(entity->internal_idx >= ent_enum->idx_max)) + return; + + __clear_bit(entity->internal_idx, ent_enum->bmap); +} + +/** + * media_entity_enum_test - Test whether the entity is marked + * + * @e: Entity enumeration + * @entity: Entity to be tested + * + * Returns true if the entity was marked. + */ +static inline bool media_entity_enum_test(struct media_entity_enum *ent_enum, + struct media_entity *entity) +{ + if (WARN_ON(entity->internal_idx >= ent_enum->idx_max)) + return true; + + return test_bit(entity->internal_idx, ent_enum->bmap); +} + +/** + * media_entity_enum_test - Test whether the entity is marked, and mark it + * + * @e: Entity enumeration + * @entity: Entity to be tested + * + * Returns true if the entity was marked, and mark it before doing so. + */ +static inline bool media_entity_enum_test_and_set( + struct media_entity_enum *ent_enum, struct media_entity *entity) +{ + if (WARN_ON(entity->internal_idx >= ent_enum->idx_max)) + return true; + + return __test_and_set_bit(entity->internal_idx, ent_enum->bmap); +} + +/** + * media_entity_enum_test - Test whether the entire enum is empty + * + * @e: Entity enumeration + * @entity: Entity to be tested + * + * Returns true if the entity was marked. + */ +static inline bool media_entity_enum_empty(struct media_entity_enum *ent_enum) +{ + return bitmap_empty(ent_enum->bmap, ent_enum->idx_max); +} + +/** + * media_entity_enum_intersects - Test whether two enums intersect + * + * @e: First entity enumeration + * @f: Second entity enumeration + * + * Returns true if entity enumerations e and f intersect, otherwise false. + */ +static inline bool media_entity_enum_intersects( + struct media_entity_enum *ent_enum1, + struct media_entity_enum *ent_enum2) +{ + WARN_ON(ent_enum1->idx_max != ent_enum2->idx_max); + + return bitmap_intersects(ent_enum1->bmap, ent_enum2->bmap, + min(ent_enum1->idx_max, ent_enum2->idx_max)); +} struct media_entity_graph { struct { -- cgit v1.2.3 From 82c682905dbc9785f26711e34cb4d16ba3a798d7 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:19 -0200 Subject: [media] media: Move struct media_entity_graph definition up It will be needed in struct media_pipeline shortly. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index c593dbd3e030..e8ef40c809ad 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -97,6 +97,16 @@ struct media_entity_enum { int idx_max; }; +struct media_entity_graph { + struct { + struct media_entity *entity; + struct list_head *link; + } stack[MEDIA_ENTITY_ENUM_MAX_DEPTH]; + + DECLARE_BITMAP(entities, MEDIA_ENTITY_ENUM_MAX_ID); + int top; +}; + struct media_pipeline { }; @@ -464,16 +474,6 @@ static inline bool media_entity_enum_intersects( min(ent_enum1->idx_max, ent_enum2->idx_max)); } -struct media_entity_graph { - struct { - struct media_entity *entity; - struct list_head *link; - } stack[MEDIA_ENTITY_ENUM_MAX_DEPTH]; - - DECLARE_BITMAP(entities, MEDIA_ENTITY_ENUM_MAX_ID); - int top; -}; - #define gobj_to_entity(gobj) \ container_of(gobj, struct media_entity, graph_obj) -- cgit v1.2.3 From 434257f19ce0a6b635a84882257034ae79d2f274 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:20 -0200 Subject: [media] media: Add KernelDoc documentation for struct media_entity_graph KernelDoc doesn't appear to handle anonymous structs defined inside another gracefully. As the struct is internal to the framework graph walk algorithm, detailed documentation isn't seen very important. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index e8ef40c809ad..edfb6163caa3 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -97,6 +97,15 @@ struct media_entity_enum { int idx_max; }; +/** + * struct media_entity_graph - Media graph traversal state + * + * @stack: Graph traversal stack; the stack contains information + * on the path the media entities to be walked and the + * links through which they were reached. + * @entities: Visited entities + * @top: The top of the stack + */ struct media_entity_graph { struct { struct media_entity *entity; -- cgit v1.2.3 From 5dd8775dc6b480f67be11108d7cd798fba724cab Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:21 -0200 Subject: [media] media: Move media graph state for streamon/off to the pipeline The struct media_entity_graph was allocated in the stack, limiting the number of entities that could be reasonably allocated. Instead, move the struct to struct media_pipeline which is typically allocated using kmalloc() instead. The intent is to keep the enumeration around for later use for the duration of the streaming. As streaming is eventually stopped, an unfortunate memory allocation failure would prevent stopping the streaming. As no memory will need to be allocated, the problem is avoided altogether. Signed-off-by: Sakari Ailus Reviewed-by: Mauro Carvalho Chehab Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index edfb6163caa3..4dc3bef72c9d 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -116,7 +116,13 @@ struct media_entity_graph { int top; }; +/* + * struct media_pipeline - Media pipeline related information + * + * @graph: Media graph walk during pipeline start / stop + */ struct media_pipeline { + struct media_entity_graph graph; }; /** -- cgit v1.2.3 From e03d220336dd69292370393f5eee98ac17eda308 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:22 -0200 Subject: [media] media: Amend media graph walk API by init and cleanup functions Add media_entity_graph_walk_init() and media_entity_graph_walk_cleanup() functions in order to dynamically allocate memory for the graph. This is not done in media_entity_graph_walk_start() as there are situations where e.g. correct error handling, that itself may not fail, requires successful graph walk. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 4dc3bef72c9d..7f028ea84911 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -699,6 +699,10 @@ struct media_pad *media_entity_remote_pad(struct media_pad *pad); */ struct media_entity *media_entity_get(struct media_entity *entity); +__must_check int media_entity_graph_walk_init( + struct media_entity_graph *graph, struct media_device *mdev); +void media_entity_graph_walk_cleanup(struct media_entity_graph *graph); + /** * media_entity_put - Release the reference to the parent module * @@ -715,13 +719,16 @@ void media_entity_put(struct media_entity *entity); * @graph: Media graph structure that will be used to walk the graph * @entity: Starting entity * - * This function initializes the graph traversal structure to walk the entities - * graph starting at the given entity. The traversal structure must not be - * modified by the caller during graph traversal. When done the structure can - * safely be freed. + * Before using this function, media_entity_graph_walk_init() must be + * used to allocate resources used for walking the graph. This + * function initializes the graph traversal structure to walk the + * entities graph starting at the given entity. The traversal + * structure must not be modified by the caller during graph + * traversal. After the graph walk, the resources must be released + * using media_entity_graph_walk_cleanup(). */ void media_entity_graph_walk_start(struct media_entity_graph *graph, - struct media_entity *entity); + struct media_entity *entity); /** * media_entity_graph_walk_next - Get the next entity in the graph -- cgit v1.2.3 From 29d8da02d13020a18929a30692d454bd863d4207 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:28 -0200 Subject: [media] media: Use entity enums in graph walk This will also mean that the necessary graph related data structures will be allocated dynamically, removing the need for maximum ID checks. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 7f028ea84911..a53acb099c16 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -103,7 +103,7 @@ struct media_entity_enum { * @stack: Graph traversal stack; the stack contains information * on the path the media entities to be walked and the * links through which they were reached. - * @entities: Visited entities + * @ent_enum: Visited entities * @top: The top of the stack */ struct media_entity_graph { @@ -112,7 +112,7 @@ struct media_entity_graph { struct list_head *link; } stack[MEDIA_ENTITY_ENUM_MAX_DEPTH]; - DECLARE_BITMAP(entities, MEDIA_ENTITY_ENUM_MAX_ID); + struct media_entity_enum ent_enum; int top; }; -- cgit v1.2.3 From 74a4133079f739eb2f4604263fdb974ce10120a8 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:29 -0200 Subject: [media] media: Keep using the same graph walk object for a given pipeline Initialise a given graph walk object once, and then keep using it whilst the same pipeline is running. Once the pipeline is stopped, release the graph walk object. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index a53acb099c16..a47a7c8a93cf 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -119,9 +119,11 @@ struct media_entity_graph { /* * struct media_pipeline - Media pipeline related information * - * @graph: Media graph walk during pipeline start / stop + * @streaming_count: Streaming start count - streaming stop count + * @graph: Media graph walk during pipeline start / stop */ struct media_pipeline { + int streaming_count; struct media_entity_graph graph; }; -- cgit v1.2.3 From 030e89ecab55b6e105e19fa830a7a7160237f19a Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:36 -0200 Subject: [media] media: Remove pre-allocated entity enumeration bitmap The bitmaps for entity enumerations used to be statically allocated. Now that the drivers have been converted to use the new interface which explicitly initialises the enum objects, drop the pre-allocated bitmaps. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index a47a7c8a93cf..4d963a3684c9 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -72,27 +72,22 @@ struct media_gobj { }; #define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 -#define MEDIA_ENTITY_ENUM_MAX_ID 64 /* * The number of pads can't be bigger than the number of entities, * as the worse-case scenario is to have one entity linked up to - * MEDIA_ENTITY_ENUM_MAX_ID - 1 entities. + * 63 entities. */ -#define MEDIA_ENTITY_MAX_PADS (MEDIA_ENTITY_ENUM_MAX_ID - 1) +#define MEDIA_ENTITY_MAX_PADS 63 /** * struct media_entity_enum - An enumeration of media entities. * - * @prealloc_bmap: Pre-allocated space reserved for media entities if the - * total number of entities does not exceed - * MEDIA_ENTITY_ENUM_MAX_ID. * @bmap: Bit map in which each bit represents one entity at struct * media_entity->internal_idx. * @idx_max: Number of bits in bmap */ struct media_entity_enum { - DECLARE_BITMAP(prealloc_bmap, MEDIA_ENTITY_ENUM_MAX_ID); unsigned long *bmap; int idx_max; }; -- cgit v1.2.3 From 0798ce4a386d605af9ddbed724a8f4c8cccc1dab Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 16 Dec 2015 11:32:37 -0200 Subject: [media] media: Move MEDIA_ENTITY_MAX_PADS from media-entity.h to media-entity.c This isn't really a part of any interface drivers are expected to use. In order to keep drivers from using it, hide it in media-entity.c. This was always an arbitrary number and should be removed in the long run. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 4d963a3684c9..f915ed62ac81 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -73,13 +73,6 @@ struct media_gobj { #define MEDIA_ENTITY_ENUM_MAX_DEPTH 16 -/* - * The number of pads can't be bigger than the number of entities, - * as the worse-case scenario is to have one entity linked up to - * 63 entities. - */ -#define MEDIA_ENTITY_MAX_PADS 63 - /** * struct media_entity_enum - An enumeration of media entities. * -- cgit v1.2.3 From 92777994a52e6c1fe0a6156a8b49e83efea6fd2c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Dec 2015 13:53:04 -0200 Subject: [media] move documentation to the header files Some exported functions were still documented at the .c file, instead of documenting at the .h one. Move the documentation to the right place, as we only use headers at media device-drivers.xml DocBook. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 6 ++++++ include/media/media-entity.h | 18 ++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index da4e12ca259c..706afdb22d0d 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -428,6 +428,8 @@ void media_device_cleanup(struct media_device *mdev); * a sysfs attribute. * * Unregistering a media device that hasn't been registered is *NOT* safe. + * + * Return: returns zero on success or a negative error code. */ int __must_check __media_device_register(struct media_device *mdev, struct module *owner); @@ -437,6 +439,10 @@ int __must_check __media_device_register(struct media_device *mdev, * __media_device_unregister() - Unegisters a media device element * * @mdev: pointer to struct &media_device + * + * + * It is safe to call this function on an unregistered (but initialised) + * media device. */ void media_device_unregister(struct media_device *mdev); diff --git a/include/media/media-entity.h b/include/media/media-entity.h index f915ed62ac81..c4aaeb85229c 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -370,9 +370,23 @@ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) } } +/** + * __media_entity_enum_init - Initialise an entity enumeration + * + * @ent_enum: Entity enumeration to be initialised + * @idx_max: Maximum number of entities in the enumeration + * + * Return: Returns zero on success or a negative error code. + */ __must_check int __media_entity_enum_init(struct media_entity_enum *ent_enum, int idx_max); -void media_entity_enum_cleanup(struct media_entity_enum *e); + +/** + * media_entity_enum_cleanup - Release resources of an entity enumeration + * + * @ent_enum: Entity enumeration to be released + */ +void media_entity_enum_cleanup(struct media_entity_enum *ent_enum); /** * media_entity_enum_zero - Clear the entire enum @@ -847,6 +861,7 @@ void media_remove_intf_link(struct media_link *link); * Note: this is an unlocked version of media_remove_intf_links(). */ void __media_remove_intf_links(struct media_interface *intf); + /** * media_remove_intf_links() - remove all links associated with an interface * @@ -861,7 +876,6 @@ void __media_remove_intf_links(struct media_interface *intf); */ void media_remove_intf_links(struct media_interface *intf); - #define media_entity_call(entity, operation, args...) \ (((entity)->ops && (entity)->ops->operation) ? \ (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD) -- cgit v1.2.3 From aa360d3de3e5c8824d48e6e273d93ee69fb53cdf Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Dec 2015 13:56:14 -0200 Subject: [media] DocBook: document media_entity_graph_walk_cleanup() This function was added recently, but weren't documented. Add documentation for it. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index c4aaeb85229c..f90ff56888d4 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -705,6 +705,12 @@ struct media_entity *media_entity_get(struct media_entity *entity); __must_check int media_entity_graph_walk_init( struct media_entity_graph *graph, struct media_device *mdev); + +/** + * media_entity_graph_walk_cleanup - Release resources used by graph walk. + * + * @graph: Media graph structure that will be used to walk the graph + */ void media_entity_graph_walk_cleanup(struct media_entity_graph *graph); /** -- cgit v1.2.3 From 03e493388415df701d4b9e362021a83529018a3b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Dec 2015 13:58:31 -0200 Subject: [media] media-entity.h fix documentation for several parameters Several parameters added by the media_ent_enum patches were declared with wrong argument names: include/media/media-device.h:333: warning: No description found for parameter 'entity_internal_idx_max' include/media/media-device.h:354: warning: No description found for parameter 'ent_enum' include/media/media-device.h:354: warning: Excess function parameter 'e' description in 'media_entity_enum_init' include/media/media-device.h:333: warning: No description found for parameter 'entity_internal_idx_max' include/media/media-device.h:354: warning: No description found for parameter 'ent_enum' include/media/media-device.h:354: warning: Excess function parameter 'e' description in 'media_entity_enum_init' include/media/media-entity.h:397: warning: No description found for parameter 'ent_enum' include/media/media-entity.h:397: warning: Excess function parameter 'e' description in 'media_entity_enum_zero' include/media/media-entity.h:409: warning: No description found for parameter 'ent_enum' include/media/media-entity.h:409: warning: Excess function parameter 'e' description in 'media_entity_enum_set' include/media/media-entity.h:424: warning: No description found for parameter 'ent_enum' include/media/media-entity.h:424: warning: Excess function parameter 'e' description in 'media_entity_enum_clear' include/media/media-entity.h:441: warning: No description found for parameter 'ent_enum' include/media/media-entity.h:441: warning: Excess function parameter 'e' description in 'media_entity_enum_test' include/media/media-entity.h:458: warning: No description found for parameter 'ent_enum' include/media/media-entity.h:458: warning: Excess function parameter 'e' description in 'media_entity_enum_test_and_set' include/media/media-entity.h:474: warning: No description found for parameter 'ent_enum' include/media/media-entity.h:474: warning: Excess function parameter 'e' description in 'media_entity_enum_empty' include/media/media-entity.h:474: warning: Excess function parameter 'entity' description in 'media_entity_enum_empty' include/media/media-entity.h:489: warning: No description found for parameter 'ent_enum1' include/media/media-entity.h:489: warning: No description found for parameter 'ent_enum2' include/media/media-entity.h:489: warning: Excess function parameter 'e' description in 'media_entity_enum_intersects' include/media/media-entity.h:489: warning: Excess function parameter 'f' description in 'media_entity_enum_intersects' Fix them. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 6 ++++-- include/media/media-entity.h | 24 ++++++++++++------------ 2 files changed, 16 insertions(+), 14 deletions(-) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index 706afdb22d0d..0dc67f2c2d0a 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -279,7 +279,9 @@ struct device; * @pad_id: Unique ID used on the last pad registered * @link_id: Unique ID used on the last link registered * @intf_devnode_id: Unique ID used on the last interface devnode registered - * @entity_internal_idx: Allocated internal entity indices + * @entity_internal_idx: Unique internal entity ID used by the graph traversal + * algorithms + * @entity_internal_idx_max: Allocated internal entity indices * @entities: List of registered entities * @interfaces: List of registered interfaces * @pads: List of registered pads @@ -344,7 +346,7 @@ struct media_device { /** * media_entity_enum_init - Initialise an entity enumeration * - * @e: Entity enumeration to be initialised + * @ent_enum: Entity enumeration to be initialised * @mdev: The related media device * * Returns zero on success or a negative error code. diff --git a/include/media/media-entity.h b/include/media/media-entity.h index f90ff56888d4..855b47df6ed5 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -391,7 +391,7 @@ void media_entity_enum_cleanup(struct media_entity_enum *ent_enum); /** * media_entity_enum_zero - Clear the entire enum * - * @e: Entity enumeration to be cleared + * @ent_enum: Entity enumeration to be cleared */ static inline void media_entity_enum_zero(struct media_entity_enum *ent_enum) { @@ -401,7 +401,7 @@ static inline void media_entity_enum_zero(struct media_entity_enum *ent_enum) /** * media_entity_enum_set - Mark a single entity in the enum * - * @e: Entity enumeration + * @ent_enum: Entity enumeration * @entity: Entity to be marked */ static inline void media_entity_enum_set(struct media_entity_enum *ent_enum, @@ -416,7 +416,7 @@ static inline void media_entity_enum_set(struct media_entity_enum *ent_enum, /** * media_entity_enum_clear - Unmark a single entity in the enum * - * @e: Entity enumeration + * @ent_enum: Entity enumeration * @entity: Entity to be unmarked */ static inline void media_entity_enum_clear(struct media_entity_enum *ent_enum, @@ -431,7 +431,7 @@ static inline void media_entity_enum_clear(struct media_entity_enum *ent_enum, /** * media_entity_enum_test - Test whether the entity is marked * - * @e: Entity enumeration + * @ent_enum: Entity enumeration * @entity: Entity to be tested * * Returns true if the entity was marked. @@ -448,13 +448,14 @@ static inline bool media_entity_enum_test(struct media_entity_enum *ent_enum, /** * media_entity_enum_test - Test whether the entity is marked, and mark it * - * @e: Entity enumeration + * @ent_enum: Entity enumeration * @entity: Entity to be tested * * Returns true if the entity was marked, and mark it before doing so. */ -static inline bool media_entity_enum_test_and_set( - struct media_entity_enum *ent_enum, struct media_entity *entity) +static inline bool +media_entity_enum_test_and_set(struct media_entity_enum *ent_enum, + struct media_entity *entity) { if (WARN_ON(entity->internal_idx >= ent_enum->idx_max)) return true; @@ -463,10 +464,9 @@ static inline bool media_entity_enum_test_and_set( } /** - * media_entity_enum_test - Test whether the entire enum is empty + * media_entity_enum_empty - Test whether the entire enum is empty * - * @e: Entity enumeration - * @entity: Entity to be tested + * @ent_enum: Entity enumeration * * Returns true if the entity was marked. */ @@ -478,8 +478,8 @@ static inline bool media_entity_enum_empty(struct media_entity_enum *ent_enum) /** * media_entity_enum_intersects - Test whether two enums intersect * - * @e: First entity enumeration - * @f: Second entity enumeration + * @ent_enum1: First entity enumeration + * @ent_enum2: Second entity enumeration * * Returns true if entity enumerations e and f intersect, otherwise false. */ -- cgit v1.2.3 From 05b3b77cbbb01180b681bc9211f3d471123809ca Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Dec 2015 14:28:01 -0200 Subject: [media] media-device.h: use just one u32 counter for object ID Instead of using one u32 counter per type for object IDs, use just one counter. With such change, it makes sense to simplify the debug logs too. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 10 ++-------- include/media/media-entity.h | 21 ++++++++++----------- 2 files changed, 12 insertions(+), 19 deletions(-) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index 0dc67f2c2d0a..d3855898c3fc 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -275,10 +275,7 @@ struct device; * @driver_version: Device driver version * @topology_version: Monotonic counter for storing the version of the graph * topology. Should be incremented each time the topology changes. - * @entity_id: Unique ID used on the last entity registered - * @pad_id: Unique ID used on the last pad registered - * @link_id: Unique ID used on the last link registered - * @intf_devnode_id: Unique ID used on the last interface devnode registered + * @id: Unique ID used on the last registered graph object * @entity_internal_idx: Unique internal entity ID used by the graph traversal * algorithms * @entity_internal_idx_max: Allocated internal entity indices @@ -313,10 +310,7 @@ struct media_device { u32 topology_version; - u32 entity_id; - u32 pad_id; - u32 link_id; - u32 intf_devnode_id; + u32 id; struct ida entity_internal_idx; int entity_internal_idx_max; diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 855b47df6ed5..54be1496d542 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -47,8 +47,8 @@ enum media_gobj_type { }; #define MEDIA_BITS_PER_TYPE 8 -#define MEDIA_BITS_PER_LOCAL_ID (32 - MEDIA_BITS_PER_TYPE) -#define MEDIA_LOCAL_ID_MASK GENMASK(MEDIA_BITS_PER_LOCAL_ID - 1, 0) +#define MEDIA_BITS_PER_ID (32 - MEDIA_BITS_PER_TYPE) +#define MEDIA_ID_MASK GENMASK_ULL(MEDIA_BITS_PER_ID - 1, 0) /* Structs to represent the objects that belong to a media graph */ @@ -58,9 +58,8 @@ enum media_gobj_type { * @mdev: Pointer to the struct media_device that owns the object * @id: Non-zero object ID identifier. The ID should be unique * inside a media_device, as it is composed by - * MEDIA_BITS_PER_TYPE to store the type plus - * MEDIA_BITS_PER_LOCAL_ID to store a per-type ID - * (called as "local ID"). + * %MEDIA_BITS_PER_TYPE to store the type plus + * %MEDIA_BITS_PER_ID to store the ID * @list: List entry stored in one of the per-type mdev object lists * * All objects on the media graph should have this struct embedded @@ -299,20 +298,20 @@ static inline u32 media_entity_id(struct media_entity *entity) */ static inline enum media_gobj_type media_type(struct media_gobj *gobj) { - return gobj->id >> MEDIA_BITS_PER_LOCAL_ID; + return gobj->id >> MEDIA_BITS_PER_ID; } -static inline u32 media_localid(struct media_gobj *gobj) +static inline u32 media_id(struct media_gobj *gobj) { - return gobj->id & MEDIA_LOCAL_ID_MASK; + return gobj->id & MEDIA_ID_MASK; } -static inline u32 media_gobj_gen_id(enum media_gobj_type type, u32 local_id) +static inline u32 media_gobj_gen_id(enum media_gobj_type type, u64 local_id) { u32 id; - id = type << MEDIA_BITS_PER_LOCAL_ID; - id |= local_id & MEDIA_LOCAL_ID_MASK; + id = type << MEDIA_BITS_PER_ID; + id |= local_id & MEDIA_ID_MASK; return id; } -- cgit v1.2.3 From 630c0e80c984c0a9a325430d62770fd49f93f9b9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 16 Dec 2015 15:15:18 -0200 Subject: [media] media-entity.h: document the remaining functions There are two ancillary functions that are missing comments. While those are used only internally at media-entity.c, document them, for completeness. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 54be1496d542..79dd81fd463e 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -301,11 +301,22 @@ static inline enum media_gobj_type media_type(struct media_gobj *gobj) return gobj->id >> MEDIA_BITS_PER_ID; } +/** + * media_id() - return the media object ID + * + * @gobj: pointer to the media graph object + */ static inline u32 media_id(struct media_gobj *gobj) { return gobj->id & MEDIA_ID_MASK; } +/** + * media_gobj_gen_id() - encapsulates type and ID on at the object ID + * + * @type: object type as define at enum &media_gobj_type. + * @local_id: next ID, from struct &media_device.@id. + */ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u64 local_id) { u32 id; -- cgit v1.2.3 From 7c9d6731acf2816cd94e6c51f02ac8348dc7bb7e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 17 Dec 2015 09:07:38 -0200 Subject: [media] uapi/media.h: Use u32 for the number of graph objects While we need to keep a u64 alignment to avoid compat32 issues, having the number of entities/pads/links/interfaces represented by an u64 is incoherent with the ID number, with is an u32. In order to make it coherent, change those quantities to u32. Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/media.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index cacfceb0d81d..5dbb208e5451 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -330,16 +330,20 @@ struct media_v2_link { struct media_v2_topology { __u64 topology_version; - __u64 num_entities; + __u32 num_entities; + __u32 reserved1; __u64 ptr_entities; - __u64 num_interfaces; + __u32 num_interfaces; + __u32 reserved2; __u64 ptr_interfaces; - __u64 num_pads; + __u32 num_pads; + __u32 reserved3; __u64 ptr_pads; - __u64 num_links; + __u32 num_links; + __u32 reserved4; __u64 ptr_links; }; -- cgit v1.2.3 From b01cc9ce7c13e0463575332dfa3171727f706afb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 30 Dec 2015 09:45:48 -0200 Subject: [media] media-entitiy: add a function to create multiple links Sometimes, it is desired to create 1:n and n:1 or even n:n links between different entities with the same function. This is actually needed to support DVB devices that have multiple frontends. While we could do a function like that internally at the DVB core, such function is generic enough to be at media-entity, and it could be useful on some other places. So, add such function. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 51 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 79dd81fd463e..fe485d367985 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -613,6 +613,57 @@ static inline void media_entity_cleanup(struct media_entity *entity) {}; __must_check int media_create_pad_link(struct media_entity *source, u16 source_pad, struct media_entity *sink, u16 sink_pad, u32 flags); + +/** + * media_create_pad_links() - creates a link between two entities. + * + * @mdev: Pointer to the media_device that contains the object + * @source_function: Function of the source entities. Used only if @source is + * NULL. + * @source: pointer to &media_entity of the source pad. If NULL, it will use + * all entities that matches the @sink_function. + * @source_pad: number of the source pad in the pads array + * @sink_function: Function of the sink entities. Used only if @sink is NULL. + * @sink: pointer to &media_entity of the sink pad. If NULL, it will use + * all entities that matches the @sink_function. + * @sink_pad: number of the sink pad in the pads array. + * @flags: Link flags, as defined in include/uapi/linux/media.h. + * @allow_both_undefined: if true, then both @source and @sink can be NULL. + * In such case, it will create a crossbar between all entities that + * matches @source_function to all entities that matches @sink_function. + * If false, it will return 0 and won't create any link if both @source + * and @sink are NULL. + * + * Valid values for flags: + * A %MEDIA_LNK_FL_ENABLED flag indicates that the link is enabled and can be + * used to transfer media data. If multiple links are created and this + * flag is passed as an argument, only the first created link will have + * this flag. + * + * A %MEDIA_LNK_FL_IMMUTABLE flag indicates that the link enabled state can't + * be modified at runtime. If %MEDIA_LNK_FL_IMMUTABLE is set, then + * %MEDIA_LNK_FL_ENABLED must also be set since an immutable link is + * always enabled. + * + * It is common for some devices to have multiple source and/or sink entities + * of the same type that should be linked. While media_create_pad_link() + * creates link by link, this function is meant to allow 1:n, n:1 and even + * cross-bar (n:n) links. + * + * NOTE: Before calling this function, media_entity_pads_init() and + * media_device_register_entity() should be called previously for the entities + * to be linked. + */ +int media_create_pad_links(const struct media_device *mdev, + const u32 source_function, + struct media_entity *source, + const u16 source_pad, + const u32 sink_function, + struct media_entity *sink, + const u16 sink_pad, + u32 flags, + const bool allow_both_undefined); + void __media_entity_remove_links(struct media_entity *entity); /** -- cgit v1.2.3 From be0270ec89e6b9b49de7e533dd1f3a89ad34d205 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Dec 2015 12:03:47 -0200 Subject: [media] Postpone the addition of MEDIA_IOC_G_TOPOLOGY There are a few discussions left with regards to this ioctl: 1) the name of the new structs will contain _v2_ on it? 2) what's the best alternative to avoid compat32 issues? Due to that, let's postpone the addition of this new ioctl to the next Kernel version, to give people more time to discuss it. Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/media.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 5dbb208e5451..1e3c8cb43bd7 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -286,7 +286,7 @@ struct media_links_enum { * later, before the adding this API upstream. */ - +#if 0 /* Let's postpone it to Kernel 4.6 */ struct media_v2_entity { __u32 id; char name[64]; /* FIXME: move to a property? (RFC says so) */ @@ -351,6 +351,7 @@ static inline void __user *media_get_uptr(__u64 arg) { return (void __user *)(uintptr_t)arg; } +#endif /* ioctls */ @@ -358,6 +359,9 @@ static inline void __user *media_get_uptr(__u64 arg) #define MEDIA_IOC_ENUM_ENTITIES _IOWR('|', 0x01, struct media_entity_desc) #define MEDIA_IOC_ENUM_LINKS _IOWR('|', 0x02, struct media_links_enum) #define MEDIA_IOC_SETUP_LINK _IOWR('|', 0x03, struct media_link_desc) + +#if 0 /* Let's postpone it to Kernel 4.6 */ #define MEDIA_IOC_G_TOPOLOGY _IOWR('|', 0x04, struct media_v2_topology) +#endif #endif /* __LINUX_MEDIA_H */ -- cgit v1.2.3 From c698d639f72b55686ec3518d2bc8dc5f2eca9354 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Sun, 13 Dec 2015 15:33:19 -0500 Subject: i2c: create builtin_i2c_driver to avoid registration boilerplate In commit f309d4443130bf814e991f836e919dca22df37ae ("platform_device: better support builtin boilerplate avoidance") we introduced the builtin_driver macro. Here we use that support and extend it to I2C driver registration, so where a driver is clearly non-modular and builtin-only, we can register it in a similar fashion. And existing code that is clearly non-modular can be updated with the simple mapping of module_i2c_driver(...) ---> builtin_i2c_driver(...) We've essentially cloned the former to make the latter, and taken out the remove/module_exit parts since those never get used in a non-modular build of the code. A similar thing was done in commit b4eb6cdbbd13698704863f680c643c569909e1c2 ("PCI: Add builtin_pci_driver() to avoid registration boilerplate"). Signed-off-by: Paul Gortmaker Signed-off-by: Wolfram Sang --- include/linux/i2c.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/i2c.h b/include/linux/i2c.h index bc2b19ad9357..200cf13b00f6 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -655,7 +655,7 @@ static inline int i2c_adapter_id(struct i2c_adapter *adap) } /** - * module_i2c_driver() - Helper macro for registering a I2C driver + * module_i2c_driver() - Helper macro for registering a modular I2C driver * @__i2c_driver: i2c_driver struct * * Helper macro for I2C drivers which do not do anything special in module @@ -666,6 +666,17 @@ static inline int i2c_adapter_id(struct i2c_adapter *adap) module_driver(__i2c_driver, i2c_add_driver, \ i2c_del_driver) +/** + * builtin_i2c_driver() - Helper macro for registering a builtin I2C driver + * @__i2c_driver: i2c_driver struct + * + * Helper macro for I2C drivers which do not do anything special in their + * init. This eliminates a lot of boilerplate. Each driver may only + * use this macro once, and calling it replaces device_initcall(). + */ +#define builtin_i2c_driver(__i2c_driver) \ + builtin_driver(__i2c_driver, i2c_add_driver) + #endif /* I2C */ #if IS_ENABLED(CONFIG_OF) -- cgit v1.2.3 From c510eff6bebaa244e577b8f499e86606b5e5d4c7 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Thu, 14 Jan 2016 15:16:59 -0800 Subject: fsnotify: destroy marks with call_srcu instead of dedicated thread At the time that this code was originally written, call_srcu didn't exist, so this thread was required to ensure that we waited for that SRCU grace period to settle before finally freeing the object. It does exist now however and we can much more efficiently use call_srcu to handle this. That also allows us to potentially use srcu_barrier to ensure that they are all of the callbacks have run before proceeding. In order to conserve space, we union the rcu_head with the g_list. This will be necessary for nfsd which will allocate marks from a dedicated slabcache. We have to be able to ensure that all of the objects are destroyed before destroying the cache. That's fairly Signed-off-by: Jeff Layton Cc: Eric Paris Reviewed-by: Jan Kara Cc: "Paul E. McKenney" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fsnotify_backend.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 533c4408529a..6b7e89f45aa4 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -220,7 +220,10 @@ struct fsnotify_mark { /* List of marks by group->i_fsnotify_marks. Also reused for queueing * mark into destroy_list when it's waiting for the end of SRCU period * before it can be freed. [group->mark_mutex] */ - struct list_head g_list; + union { + struct list_head g_list; + struct rcu_head g_rcu; + }; /* Protects inode / mnt pointers, flags, masks */ spinlock_t lock; /* List of marks for inode / vfsmount [obj_lock] */ -- cgit v1.2.3 From 2bd03e49d66775da8cebdcc8d5bec7d68512ae87 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 14 Jan 2016 15:17:53 -0800 Subject: include/linux/dcache.h: remove semicolons from HASH_LEN_DECLARE A little cleanup - the invocation site provdes the semicolon. Cc: Rasmus Villemoes Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/dcache.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/dcache.h b/include/linux/dcache.h index d67ae119cf4e..7781ce110503 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -27,10 +27,10 @@ struct vfsmount; /* The hash is always the low bits of hash_len */ #ifdef __LITTLE_ENDIAN - #define HASH_LEN_DECLARE u32 hash; u32 len; + #define HASH_LEN_DECLARE u32 hash; u32 len #define bytemask_from_count(cnt) (~(~0ul << (cnt)*8)) #else - #define HASH_LEN_DECLARE u32 len; u32 hash; + #define HASH_LEN_DECLARE u32 len; u32 hash #define bytemask_from_count(cnt) (~(~0ul >> (cnt)*8)) #endif -- cgit v1.2.3 From 20b5c30398639b458371c228abfda829854b61c5 Mon Sep 17 00:00:00 2001 From: Vladimir Davydov Date: Thu, 14 Jan 2016 15:18:08 -0800 Subject: Revert "gfp: add __GFP_NOACCOUNT" This reverts commit 8f4fc071b192 ("gfp: add __GFP_NOACCOUNT"). Black-list kmem accounting policy (aka __GFP_NOACCOUNT) turned out to be fragile and difficult to maintain, because there seem to be many more allocations that should not be accounted than those that should be. Besides, false accounting an allocation might result in much worse consequences than not accounting at all, namely increased memory consumption due to pinned dead kmem caches. So it was decided to switch to the white-list policy. This patch reverts bits introducing the black-list policy. The white-list policy will be introduced later in the series. Signed-off-by: Vladimir Davydov Acked-by: Johannes Weiner Cc: Michal Hocko Cc: Tejun Heo Cc: Greg Thelen Cc: Christoph Lameter Cc: Pekka Enberg Cc: David Rientjes Cc: Joonsoo Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/gfp.h | 2 -- include/linux/memcontrol.h | 2 -- 2 files changed, 4 deletions(-) (limited to 'include') diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 8942af0813e3..075b014448f5 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -30,7 +30,6 @@ struct vm_area_struct; #define ___GFP_HARDWALL 0x20000u #define ___GFP_THISNODE 0x40000u #define ___GFP_ATOMIC 0x80000u -#define ___GFP_NOACCOUNT 0x100000u #define ___GFP_NOTRACK 0x200000u #define ___GFP_DIRECT_RECLAIM 0x400000u #define ___GFP_OTHER_NODE 0x800000u @@ -104,7 +103,6 @@ struct vm_area_struct; #define __GFP_HIGH ((__force gfp_t)___GFP_HIGH) #define __GFP_MEMALLOC ((__force gfp_t)___GFP_MEMALLOC) #define __GFP_NOMEMALLOC ((__force gfp_t)___GFP_NOMEMALLOC) -#define __GFP_NOACCOUNT ((__force gfp_t)___GFP_NOACCOUNT) /* * Reclaim modifiers diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index cd0e2413c358..2103f36b3bd3 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -773,8 +773,6 @@ static inline bool __memcg_kmem_bypass(gfp_t gfp) { if (!memcg_kmem_enabled()) return true; - if (gfp & __GFP_NOACCOUNT) - return true; if (in_interrupt() || (!current->mm) || (current->flags & PF_KTHREAD)) return true; return false; -- cgit v1.2.3 From a9bb7e620efdfd29b6d1c238041173e411670996 Mon Sep 17 00:00:00 2001 From: Vladimir Davydov Date: Thu, 14 Jan 2016 15:18:12 -0800 Subject: memcg: only account kmem allocations marked as __GFP_ACCOUNT Black-list kmem accounting policy (aka __GFP_NOACCOUNT) turned out to be fragile and difficult to maintain, because there seem to be many more allocations that should not be accounted than those that should be. Besides, false accounting an allocation might result in much worse consequences than not accounting at all, namely increased memory consumption due to pinned dead kmem caches. So this patch switches kmem accounting to the white-policy: now only those kmem allocations that are marked as __GFP_ACCOUNT are accounted to memcg. Currently, no kmem allocations are marked like this. The following patches will mark several kmem allocations that are known to be easily triggered from userspace and therefore should be accounted to memcg. Signed-off-by: Vladimir Davydov Acked-by: Johannes Weiner Acked-by: Michal Hocko Cc: Tejun Heo Cc: Greg Thelen Cc: Christoph Lameter Cc: Pekka Enberg Cc: David Rientjes Cc: Joonsoo Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/gfp.h | 9 +++++++++ include/linux/memcontrol.h | 2 ++ 2 files changed, 11 insertions(+) (limited to 'include') diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 075b014448f5..1dd59abe541d 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -30,6 +30,7 @@ struct vm_area_struct; #define ___GFP_HARDWALL 0x20000u #define ___GFP_THISNODE 0x40000u #define ___GFP_ATOMIC 0x80000u +#define ___GFP_ACCOUNT 0x100000u #define ___GFP_NOTRACK 0x200000u #define ___GFP_DIRECT_RECLAIM 0x400000u #define ___GFP_OTHER_NODE 0x800000u @@ -72,11 +73,15 @@ struct vm_area_struct; * * __GFP_THISNODE forces the allocation to be satisified from the requested * node with no fallbacks or placement policy enforcements. + * + * __GFP_ACCOUNT causes the allocation to be accounted to kmemcg (only relevant + * to kmem allocations). */ #define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE) #define __GFP_WRITE ((__force gfp_t)___GFP_WRITE) #define __GFP_HARDWALL ((__force gfp_t)___GFP_HARDWALL) #define __GFP_THISNODE ((__force gfp_t)___GFP_THISNODE) +#define __GFP_ACCOUNT ((__force gfp_t)___GFP_ACCOUNT) /* * Watermark modifiers -- controls access to emergency reserves @@ -195,6 +200,9 @@ struct vm_area_struct; * GFP_KERNEL is typical for kernel-internal allocations. The caller requires * ZONE_NORMAL or a lower zone for direct access but can direct reclaim. * + * GFP_KERNEL_ACCOUNT is the same as GFP_KERNEL, except the allocation is + * accounted to kmemcg. + * * GFP_NOWAIT is for kernel allocations that should not stall for direct * reclaim, start physical IO or use any filesystem callback. * @@ -234,6 +242,7 @@ struct vm_area_struct; */ #define GFP_ATOMIC (__GFP_HIGH|__GFP_ATOMIC|__GFP_KSWAPD_RECLAIM) #define GFP_KERNEL (__GFP_RECLAIM | __GFP_IO | __GFP_FS) +#define GFP_KERNEL_ACCOUNT (GFP_KERNEL | __GFP_ACCOUNT) #define GFP_NOWAIT (__GFP_KSWAPD_RECLAIM) #define GFP_NOIO (__GFP_RECLAIM) #define GFP_NOFS (__GFP_RECLAIM | __GFP_IO) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 2103f36b3bd3..c9d9a8e7b45f 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -773,6 +773,8 @@ static inline bool __memcg_kmem_bypass(gfp_t gfp) { if (!memcg_kmem_enabled()) return true; + if (!(gfp & __GFP_ACCOUNT)) + return true; if (in_interrupt() || (!current->mm) || (current->flags & PF_KTHREAD)) return true; return false; -- cgit v1.2.3 From 230e9fc2860450fbb1f33bdcf9093d92d7d91f5b Mon Sep 17 00:00:00 2001 From: Vladimir Davydov Date: Thu, 14 Jan 2016 15:18:15 -0800 Subject: slab: add SLAB_ACCOUNT flag Currently, if we want to account all objects of a particular kmem cache, we have to pass __GFP_ACCOUNT to each kmem_cache_alloc call, which is inconvenient. This patch introduces SLAB_ACCOUNT flag which if passed to kmem_cache_create will force accounting for every allocation from this cache even if __GFP_ACCOUNT is not passed. This patch does not make any of the existing caches use this flag - it will be done later in the series. Note, a cache with SLAB_ACCOUNT cannot be merged with a cache w/o SLAB_ACCOUNT, because merged caches share the same kmem_cache struct and hence cannot have different sets of SLAB_* flags. Thus using this flag will probably reduce the number of merged slabs even if kmem accounting is not used (only compiled in). Signed-off-by: Vladimir Davydov Suggested-by: Tejun Heo Acked-by: Johannes Weiner Acked-by: Michal Hocko Cc: Greg Thelen Cc: Christoph Lameter Cc: Pekka Enberg Cc: David Rientjes Cc: Joonsoo Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 15 +++++++-------- include/linux/slab.h | 5 +++++ 2 files changed, 12 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index c9d9a8e7b45f..5c97265c1c6e 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -766,15 +766,13 @@ static inline int memcg_cache_id(struct mem_cgroup *memcg) return memcg ? memcg->kmemcg_id : -1; } -struct kmem_cache *__memcg_kmem_get_cache(struct kmem_cache *cachep); +struct kmem_cache *__memcg_kmem_get_cache(struct kmem_cache *cachep, gfp_t gfp); void __memcg_kmem_put_cache(struct kmem_cache *cachep); -static inline bool __memcg_kmem_bypass(gfp_t gfp) +static inline bool __memcg_kmem_bypass(void) { if (!memcg_kmem_enabled()) return true; - if (!(gfp & __GFP_ACCOUNT)) - return true; if (in_interrupt() || (!current->mm) || (current->flags & PF_KTHREAD)) return true; return false; @@ -791,7 +789,9 @@ static inline bool __memcg_kmem_bypass(gfp_t gfp) static __always_inline int memcg_kmem_charge(struct page *page, gfp_t gfp, int order) { - if (__memcg_kmem_bypass(gfp)) + if (__memcg_kmem_bypass()) + return 0; + if (!(gfp & __GFP_ACCOUNT)) return 0; return __memcg_kmem_charge(page, gfp, order); } @@ -810,16 +810,15 @@ static __always_inline void memcg_kmem_uncharge(struct page *page, int order) /** * memcg_kmem_get_cache: selects the correct per-memcg cache for allocation * @cachep: the original global kmem cache - * @gfp: allocation flags. * * All memory allocated from a per-memcg cache is charged to the owner memcg. */ static __always_inline struct kmem_cache * memcg_kmem_get_cache(struct kmem_cache *cachep, gfp_t gfp) { - if (__memcg_kmem_bypass(gfp)) + if (__memcg_kmem_bypass()) return cachep; - return __memcg_kmem_get_cache(cachep); + return __memcg_kmem_get_cache(cachep, gfp); } static __always_inline void memcg_kmem_put_cache(struct kmem_cache *cachep) diff --git a/include/linux/slab.h b/include/linux/slab.h index 2037a861e367..3ffee7422012 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -86,6 +86,11 @@ #else # define SLAB_FAILSLAB 0x00000000UL #endif +#ifdef CONFIG_MEMCG_KMEM +# define SLAB_ACCOUNT 0x04000000UL /* Account to memcg */ +#else +# define SLAB_ACCOUNT 0x00000000UL +#endif /* The following flags affect the page allocator grouping pages by mobility */ #define SLAB_RECLAIM_ACCOUNT 0x00020000UL /* Objects are reclaimable */ -- cgit v1.2.3 From 5d097056c9a017a3b720849efb5432f37acabbac Mon Sep 17 00:00:00 2001 From: Vladimir Davydov Date: Thu, 14 Jan 2016 15:18:21 -0800 Subject: kmemcg: account certain kmem allocations to memcg Mark those kmem allocations that are known to be easily triggered from userspace as __GFP_ACCOUNT/SLAB_ACCOUNT, which makes them accounted to memcg. For the list, see below: - threadinfo - task_struct - task_delay_info - pid - cred - mm_struct - vm_area_struct and vm_region (nommu) - anon_vma and anon_vma_chain - signal_struct - sighand_struct - fs_struct - files_struct - fdtable and fdtable->full_fds_bits - dentry and external_name - inode for all filesystems. This is the most tedious part, because most filesystems overwrite the alloc_inode method. The list is far from complete, so feel free to add more objects. Nevertheless, it should be close to "account everything" approach and keep most workloads within bounds. Malevolent users will be able to breach the limit, but this was possible even with the former "account everything" approach (simply because it did not account everything in fact). [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Vladimir Davydov Acked-by: Johannes Weiner Acked-by: Michal Hocko Cc: Tejun Heo Cc: Greg Thelen Cc: Christoph Lameter Cc: Pekka Enberg Cc: David Rientjes Cc: Joonsoo Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/thread_info.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h index ff307b548ed3..b4c2a485b28a 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h @@ -56,9 +56,10 @@ extern long do_no_restart_syscall(struct restart_block *parm); #ifdef __KERNEL__ #ifdef CONFIG_DEBUG_STACK_USAGE -# define THREADINFO_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO) +# define THREADINFO_GFP (GFP_KERNEL_ACCOUNT | __GFP_NOTRACK | \ + __GFP_ZERO) #else -# define THREADINFO_GFP (GFP_KERNEL | __GFP_NOTRACK) +# define THREADINFO_GFP (GFP_KERNEL_ACCOUNT | __GFP_NOTRACK) #endif /* -- cgit v1.2.3 From 3aa2385111168187f24a6db04697c6fab0fab9b4 Mon Sep 17 00:00:00 2001 From: yalin wang Date: Thu, 14 Jan 2016 15:18:30 -0800 Subject: mm/vmscan.c: change trace_mm_vmscan_writepage() proto type Move trace_reclaim_flags() into trace function, so that we don't need caculate these flags if the trace is disabled. Signed-off-by: yalin wang Reviewed-by: Steven Rostedt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/trace/events/vmscan.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/trace/events/vmscan.h b/include/trace/events/vmscan.h index f66476b96264..dae7836e1f51 100644 --- a/include/trace/events/vmscan.h +++ b/include/trace/events/vmscan.h @@ -330,10 +330,9 @@ DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_memcg_isolate, TRACE_EVENT(mm_vmscan_writepage, - TP_PROTO(struct page *page, - int reclaim_flags), + TP_PROTO(struct page *page), - TP_ARGS(page, reclaim_flags), + TP_ARGS(page), TP_STRUCT__entry( __field(unsigned long, pfn) @@ -342,7 +341,7 @@ TRACE_EVENT(mm_vmscan_writepage, TP_fast_assign( __entry->pfn = page_to_pfn(page); - __entry->reclaim_flags = reclaim_flags; + __entry->reclaim_flags = trace_reclaim_flags(page); ), TP_printk("page=%p pfn=%lu flags=%s", -- cgit v1.2.3 From 8f235d1a3eb7198affe7cadf676a10afb8a46a1a Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Thu, 14 Jan 2016 15:18:33 -0800 Subject: mm: add PHYS_PFN, use it in __phys_to_pfn() __phys_to_pfn and __pfn_to_phys are symmetric, PHYS_PFN and PFN_PHYS are semmetric: - y = (phys_addr_t)x << PAGE_SHIFT - y >> PAGE_SHIFT = (phys_add_t)x - (unsigned long)(y >> PAGE_SHIFT) = x [akpm@linux-foundation.org: use macro arg name `x'] [arnd@arndb.de: include linux/pfn.h for PHYS_PFN definition] Signed-off-by: Chen Gang Cc: Oleg Nesterov Signed-off-by: Arnd Bergmann Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-generic/memory_model.h | 4 +++- include/linux/pfn.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-generic/memory_model.h b/include/asm-generic/memory_model.h index 4b4b056a6eb0..5148150cc80b 100644 --- a/include/asm-generic/memory_model.h +++ b/include/asm-generic/memory_model.h @@ -1,6 +1,8 @@ #ifndef __ASM_MEMORY_MODEL_H #define __ASM_MEMORY_MODEL_H +#include + #ifndef __ASSEMBLY__ #if defined(CONFIG_FLATMEM) @@ -72,7 +74,7 @@ /* * Convert a physical address to a Page Frame Number and back */ -#define __phys_to_pfn(paddr) ((unsigned long)((paddr) >> PAGE_SHIFT)) +#define __phys_to_pfn(paddr) PHYS_PFN(paddr) #define __pfn_to_phys(pfn) PFN_PHYS(pfn) #define page_to_pfn __page_to_pfn diff --git a/include/linux/pfn.h b/include/linux/pfn.h index 7646637221f3..97f3e88aead4 100644 --- a/include/linux/pfn.h +++ b/include/linux/pfn.h @@ -9,5 +9,6 @@ #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) #define PFN_DOWN(x) ((x) >> PAGE_SHIFT) #define PFN_PHYS(x) ((phys_addr_t)(x) << PAGE_SHIFT) +#define PHYS_PFN(x) ((unsigned long)((x) >> PAGE_SHIFT)) #endif -- cgit v1.2.3 From 4a8c7bb59ac85b038c29adf6d32ff56e11fbb267 Mon Sep 17 00:00:00 2001 From: Nathan Zimmer Date: Thu, 14 Jan 2016 15:18:36 -0800 Subject: mm/mempolicy.c: convert the shared_policy lock to a rwlock When running the SPECint_rate gcc on some very large boxes it was noticed that the system was spending lots of time in mpol_shared_policy_lookup(). The gamess benchmark can also show it and is what I mostly used to chase down the issue since the setup for that I found to be easier. To be clear the binaries were on tmpfs because of disk I/O requirements. We then used text replication to avoid icache misses and having all the copies banging on the memory where the instruction code resides. This results in us hitting a bottleneck in mpol_shared_policy_lookup() since lookup is serialised by the shared_policy lock. I have only reproduced this on very large (3k+ cores) boxes. The problem starts showing up at just a few hundred ranks getting worse until it threatens to livelock once it gets large enough. For example on the gamess benchmark at 128 ranks this area consumes only ~1% of time, at 512 ranks it consumes nearly 13%, and at 2k ranks it is over 90%. To alleviate the contention in this area I converted the spinlock to an rwlock. This allows a large number of lookups to happen simultaneously. The results were quite good reducing this consumtion at max ranks to around 2%. [akpm@linux-foundation.org: tidy up code comments] Signed-off-by: Nathan Zimmer Acked-by: David Rientjes Acked-by: Vlastimil Babka Cc: Nadia Yvette Chambers Cc: Naoya Horiguchi Cc: Mel Gorman Cc: "Aneesh Kumar K.V" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mempolicy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h index 3d385c81c153..2696c1f05ed1 100644 --- a/include/linux/mempolicy.h +++ b/include/linux/mempolicy.h @@ -122,7 +122,7 @@ struct sp_node { struct shared_policy { struct rb_root root; - spinlock_t lock; + rwlock_t lock; }; int vma_dup_policy(struct vm_area_struct *src, struct vm_area_struct *dst); -- cgit v1.2.3 From 0f0848e5118a4cb2cb92cef0c3af6f647649ff47 Mon Sep 17 00:00:00 2001 From: Joonsoo Kim Date: Thu, 14 Jan 2016 15:18:42 -0800 Subject: mm/page_isolation.c: add new tracepoint, test_pages_isolated cma allocation should be guranteeded to succeed. But sometimes it can fail in the current implementation. To track down the problem, we need to know which page is problematic and this new tracepoint will report it. Signed-off-by: Joonsoo Kim Acked-by: Michal Nazarewicz Acked-by: David Rientjes Cc: Minchan Kim Acked-by: Vlastimil Babka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/trace/events/page_isolation.h | 38 +++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 include/trace/events/page_isolation.h (limited to 'include') diff --git a/include/trace/events/page_isolation.h b/include/trace/events/page_isolation.h new file mode 100644 index 000000000000..6fb644029c80 --- /dev/null +++ b/include/trace/events/page_isolation.h @@ -0,0 +1,38 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM page_isolation + +#if !defined(_TRACE_PAGE_ISOLATION_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_PAGE_ISOLATION_H + +#include + +TRACE_EVENT(test_pages_isolated, + + TP_PROTO( + unsigned long start_pfn, + unsigned long end_pfn, + unsigned long fin_pfn), + + TP_ARGS(start_pfn, end_pfn, fin_pfn), + + TP_STRUCT__entry( + __field(unsigned long, start_pfn) + __field(unsigned long, end_pfn) + __field(unsigned long, fin_pfn) + ), + + TP_fast_assign( + __entry->start_pfn = start_pfn; + __entry->end_pfn = end_pfn; + __entry->fin_pfn = fin_pfn; + ), + + TP_printk("start_pfn=0x%lx end_pfn=0x%lx fin_pfn=0x%lx ret=%s", + __entry->start_pfn, __entry->end_pfn, __entry->fin_pfn, + __entry->end_pfn == __entry->fin_pfn ? "success" : "fail") +); + +#endif /* _TRACE_PAGE_ISOLATION_H */ + +/* This part must be outside protection */ +#include -- cgit v1.2.3 From ba5e9579433aefcdccdec207601e124d3bdf2a71 Mon Sep 17 00:00:00 2001 From: yalin wang Date: Thu, 14 Jan 2016 15:18:48 -0800 Subject: mm: change mm_vmscan_lru_shrink_inactive() proto types Move node_id zone_idx shrink flags into trace function, so thay we don't need caculate these args if the trace is disabled, and will make this function have less arguments. Signed-off-by: yalin wang Reviewed-by: Steven Rostedt Acked-by: Vlastimil Babka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/trace/events/vmscan.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/trace/events/vmscan.h b/include/trace/events/vmscan.h index dae7836e1f51..31763dd8db1c 100644 --- a/include/trace/events/vmscan.h +++ b/include/trace/events/vmscan.h @@ -352,11 +352,11 @@ TRACE_EVENT(mm_vmscan_writepage, TRACE_EVENT(mm_vmscan_lru_shrink_inactive, - TP_PROTO(int nid, int zid, - unsigned long nr_scanned, unsigned long nr_reclaimed, - int priority, int reclaim_flags), + TP_PROTO(struct zone *zone, + unsigned long nr_scanned, unsigned long nr_reclaimed, + int priority, int file), - TP_ARGS(nid, zid, nr_scanned, nr_reclaimed, priority, reclaim_flags), + TP_ARGS(zone, nr_scanned, nr_reclaimed, priority, file), TP_STRUCT__entry( __field(int, nid) @@ -368,12 +368,12 @@ TRACE_EVENT(mm_vmscan_lru_shrink_inactive, ), TP_fast_assign( - __entry->nid = nid; - __entry->zid = zid; + __entry->nid = zone_to_nid(zone); + __entry->zid = zone_idx(zone); __entry->nr_scanned = nr_scanned; __entry->nr_reclaimed = nr_reclaimed; __entry->priority = priority; - __entry->reclaim_flags = reclaim_flags; + __entry->reclaim_flags = trace_shrink_flags(file); ), TP_printk("nid=%d zid=%d nr_scanned=%ld nr_reclaimed=%ld priority=%d flags=%s", -- cgit v1.2.3 From 719ff32162865522273d8fa975bf99b32875738b Mon Sep 17 00:00:00 2001 From: Yaowei Bai Date: Thu, 14 Jan 2016 15:18:51 -0800 Subject: include/linux/hugetlb.h: is_file_hugepages() can be boolean Make is_file_hugepages() return bool to improve readability due to this particular function only using either one or zero as its return value. This patch also removed the if condition to make is_file_hugepages return directly. No functional change. Signed-off-by: Yaowei Bai Acked-by: Michal Hocko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/hugetlb.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index b0eb06423d5e..e76574d8f9b5 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -263,20 +263,18 @@ struct file *hugetlb_file_setup(const char *name, size_t size, vm_flags_t acct, struct user_struct **user, int creat_flags, int page_size_log); -static inline int is_file_hugepages(struct file *file) +static inline bool is_file_hugepages(struct file *file) { if (file->f_op == &hugetlbfs_file_operations) - return 1; - if (is_file_shm_hugepages(file)) - return 1; + return true; - return 0; + return is_file_shm_hugepages(file); } #else /* !CONFIG_HUGETLBFS */ -#define is_file_hugepages(file) 0 +#define is_file_hugepages(file) false static inline struct file * hugetlb_file_setup(const char *name, size_t size, vm_flags_t acctflag, struct user_struct **user, int creat_flags, -- cgit v1.2.3 From b4ad0c7e004a2cc0e52790eff72f5176b59ca386 Mon Sep 17 00:00:00 2001 From: Yaowei Bai Date: Thu, 14 Jan 2016 15:18:54 -0800 Subject: mm/memblock.c: memblock_is_memory()/reserved() can be boolean Make memblock_is_memory() and memblock_is_reserved return bool to improve readability due to these particular functions only using either one or zero as their return value. No functional change. Signed-off-by: Yaowei Bai Acked-by: Michal Hocko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memblock.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index fec66f86eeff..3a092fba2eb2 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -325,10 +325,10 @@ phys_addr_t memblock_mem_size(unsigned long limit_pfn); phys_addr_t memblock_start_of_DRAM(void); phys_addr_t memblock_end_of_DRAM(void); void memblock_enforce_memory_limit(phys_addr_t memory_limit); -int memblock_is_memory(phys_addr_t addr); +bool memblock_is_memory(phys_addr_t addr); int memblock_is_map_memory(phys_addr_t addr); int memblock_is_region_memory(phys_addr_t base, phys_addr_t size); -int memblock_is_reserved(phys_addr_t addr); +bool memblock_is_reserved(phys_addr_t addr); bool memblock_is_region_reserved(phys_addr_t base, phys_addr_t size); extern void __memblock_dump_all(void); -- cgit v1.2.3 From 06640290bfc6688062387f915c5df094e9872133 Mon Sep 17 00:00:00 2001 From: Yaowei Bai Date: Thu, 14 Jan 2016 15:18:57 -0800 Subject: include/linux/mmzone.h: remove unused is_unevictable_lru() Since commit a0b8cab3b9b2 ("mm: remove lru parameter from __pagevec_lru_add and remove parts of pagevec API") there's no user of this function anymore, so remove it. Signed-off-by: Yaowei Bai Acked-by: Michal Hocko Acked-by: Hillf Danton Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmzone.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include') diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index e23a9e704536..996384672c73 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -195,11 +195,6 @@ static inline int is_active_lru(enum lru_list lru) return (lru == LRU_ACTIVE_ANON || lru == LRU_ACTIVE_FILE); } -static inline int is_unevictable_lru(enum lru_list lru) -{ - return (lru == LRU_UNEVICTABLE); -} - struct zone_reclaim_stat { /* * The pageout code in vmscan.c keeps track of how many of the -- cgit v1.2.3 From c00eb15a8914b8ba84032a36044a5aaf7f71709d Mon Sep 17 00:00:00 2001 From: Yaowei Bai Date: Thu, 14 Jan 2016 15:19:00 -0800 Subject: mm/zonelist: enumerate zonelists array index Hardcoding index to zonelists array in gfp_zonelist() is not a good idea, let's enumerate it to improve readability. No functional change. [akpm@linux-foundation.org: coding-style fixes] [akpm@linux-foundation.org: fix CONFIG_NUMA=n build] [n-horiguchi@ah.jp.nec.com: fix warning in comparing enumerator] Signed-off-by: Yaowei Bai Cc: Michal Hocko Cc: David Rientjes Signed-off-by: Naoya Horiguchi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/gfp.h | 9 +++++---- include/linux/mmzone.h | 20 +++++++++----------- 2 files changed, 14 insertions(+), 15 deletions(-) (limited to 'include') diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 1dd59abe541d..91f74e741aa2 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -384,10 +384,11 @@ static inline enum zone_type gfp_zone(gfp_t flags) static inline int gfp_zonelist(gfp_t flags) { - if (IS_ENABLED(CONFIG_NUMA) && unlikely(flags & __GFP_THISNODE)) - return 1; - - return 0; +#ifdef CONFIG_NUMA + if (unlikely(flags & __GFP_THISNODE)) + return ZONELIST_NOFALLBACK; +#endif + return ZONELIST_FALLBACK; } /* diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 996384672c73..12c98dfc31b1 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -571,19 +571,17 @@ static inline bool zone_is_empty(struct zone *zone) /* Maximum number of zones on a zonelist */ #define MAX_ZONES_PER_ZONELIST (MAX_NUMNODES * MAX_NR_ZONES) +enum { + ZONELIST_FALLBACK, /* zonelist with fallback */ #ifdef CONFIG_NUMA - -/* - * The NUMA zonelists are doubled because we need zonelists that restrict the - * allocations to a single node for __GFP_THISNODE. - * - * [0] : Zonelist with fallback - * [1] : No fallback (__GFP_THISNODE) - */ -#define MAX_ZONELISTS 2 -#else -#define MAX_ZONELISTS 1 + /* + * The NUMA zonelists are doubled because we need zonelists that + * restrict the allocations to a single node for __GFP_THISNODE. + */ + ZONELIST_NOFALLBACK, /* zonelist without fallback (__GFP_THISNODE) */ #endif + MAX_ZONELISTS +}; /* * This struct contains information about a zone in a zonelist. It is stored -- cgit v1.2.3 From 5b80287a65da927742c6d43b1369bd5ed133aad1 Mon Sep 17 00:00:00 2001 From: Yaowei Bai Date: Thu, 14 Jan 2016 15:19:11 -0800 Subject: mm/mmzone.c: memmap_valid_within() can be boolean Make memmap_valid_within return bool due to this particular function only using either one or zero as its return value. No functional change. Signed-off-by: Yaowei Bai Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmzone.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 12c98dfc31b1..3b6fb71bbeb3 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -1200,13 +1200,13 @@ unsigned long __init node_memmap_size_bytes(int, unsigned long, unsigned long); * the zone and PFN linkages are still valid. This is expensive, but walkers * of the full memmap are extremely rare. */ -int memmap_valid_within(unsigned long pfn, +bool memmap_valid_within(unsigned long pfn, struct page *page, struct zone *zone); #else -static inline int memmap_valid_within(unsigned long pfn, +static inline bool memmap_valid_within(unsigned long pfn, struct page *page, struct zone *zone) { - return 1; + return true; } #endif /* CONFIG_ARCH_HAS_HOLES_MEMORYMODEL */ -- cgit v1.2.3 From 6a15a37097c7e02390bb08d83dac433c9f10144f Mon Sep 17 00:00:00 2001 From: Vlastimil Babka Date: Thu, 14 Jan 2016 15:19:20 -0800 Subject: mm, proc: reduce cost of /proc/pid/smaps for shmem mappings The previous patch has improved swap accounting for shmem mapping, which however made /proc/pid/smaps more expensive for shmem mappings, as we consult the radix tree for each pte_none entry, so the overal complexity is O(n*log(n)). We can reduce this significantly for mappings that cannot contain COWed pages, because then we can either use the statistics tha shmem object itself tracks (if the mapping contains the whole object, or the swap usage of the whole object is zero), or use the radix tree iterator, which is much more effective than repeated find_get_entry() calls. This patch therefore introduces a function shmem_swap_usage(vma) and makes /proc/pid/smaps use it when possible. Only for writable private mappings of shmem objects (i.e. tmpfs files) with the shmem object itself (partially) swapped outwe have to resort to the find_get_entry() approach. Hopefully such mappings are relatively uncommon. To demonstrate the diference, I have measured this on a process that creates a 2GB mapping and dirties single pages with a stride of 2MB, and time how long does it take to cat /proc/pid/smaps of this process 100 times. Private writable mapping of a /dev/shm/file (the most complex case): real 0m3.831s user 0m0.180s sys 0m3.212s Shared mapping of an almost full mapping of a partially swapped /dev/shm/file (which needs to employ the radix tree iterator). real 0m1.351s user 0m0.096s sys 0m0.768s Same, but with /dev/shm/file not swapped (so no radix tree walk needed) real 0m0.935s user 0m0.128s sys 0m0.344s Private anonymous mapping: real 0m0.949s user 0m0.116s sys 0m0.348s The cost is now much closer to the private anonymous mapping case, unless the shmem mapping is private and writable. Signed-off-by: Vlastimil Babka Cc: Hugh Dickins Cc: Jerome Marchand Cc: Konstantin Khlebnikov Acked-by: Michal Hocko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/shmem_fs.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index 50777b5b1e4c..bd58be5e7a2a 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -60,6 +60,8 @@ extern struct page *shmem_read_mapping_page_gfp(struct address_space *mapping, extern void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end); extern int shmem_unuse(swp_entry_t entry, struct page *page); +extern unsigned long shmem_swap_usage(struct vm_area_struct *vma); + static inline struct page *shmem_read_mapping_page( struct address_space *mapping, pgoff_t index) { -- cgit v1.2.3 From 48131e03ca4ed71d73fbe55c311a258c6fa2a090 Mon Sep 17 00:00:00 2001 From: Vlastimil Babka Date: Thu, 14 Jan 2016 15:19:23 -0800 Subject: mm, proc: reduce cost of /proc/pid/smaps for unpopulated shmem mappings Following the previous patch, further reduction of /proc/pid/smaps cost is possible for private writable shmem mappings with unpopulated areas where the page walk invokes the .pte_hole function. We can use radix tree iterator for each such area instead of calling find_get_entry() in a loop. This is possible at the extra maintenance cost of introducing another shmem function shmem_partial_swap_usage(). To demonstrate the diference, I have measured this on a process that creates a private writable 2GB mapping of a partially swapped out /dev/shm/file (which cannot employ the optimizations from the prvious patch) and doesn't populate it at all. I time how long does it take to cat /proc/pid/smaps of this process 100 times. Before this patch: real 0m3.831s user 0m0.180s sys 0m3.212s After this patch: real 0m1.176s user 0m0.180s sys 0m0.684s The time is similar to the case where a radix tree iterator is employed on the whole mapping. Signed-off-by: Vlastimil Babka Cc: Hugh Dickins Cc: Jerome Marchand Cc: Konstantin Khlebnikov Acked-by: Michal Hocko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/shmem_fs.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index bd58be5e7a2a..a43f41cb3c43 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -61,6 +61,8 @@ extern void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end); extern int shmem_unuse(swp_entry_t entry, struct page *page); extern unsigned long shmem_swap_usage(struct vm_area_struct *vma); +extern unsigned long shmem_partial_swap_usage(struct address_space *mapping, + pgoff_t start, pgoff_t end); static inline struct page *shmem_read_mapping_page( struct address_space *mapping, pgoff_t index) -- cgit v1.2.3 From eca56ff906bdd0239485e8b47154a6e73dd9a2f3 Mon Sep 17 00:00:00 2001 From: Jerome Marchand Date: Thu, 14 Jan 2016 15:19:26 -0800 Subject: mm, shmem: add internal shmem resident memory accounting Currently looking at /proc//status or statm, there is no way to distinguish shmem pages from pages mapped to a regular file (shmem pages are mapped to /dev/zero), even though their implication in actual memory use is quite different. The internal accounting currently counts shmem pages together with regular files. As a preparation to extend the userspace interfaces, this patch adds MM_SHMEMPAGES counter to mm_rss_stat to account for shmem pages separately from MM_FILEPAGES. The next patch will expose it to userspace - this patch doesn't change the exported values yet, by adding up MM_SHMEMPAGES to MM_FILEPAGES at places where MM_FILEPAGES was used before. The only user-visible change after this patch is the OOM killer message that separates the reported "shmem-rss" from "file-rss". [vbabka@suse.cz: forward-porting, tweak changelog] Signed-off-by: Jerome Marchand Signed-off-by: Vlastimil Babka Acked-by: Konstantin Khlebnikov Acked-by: Michal Hocko Acked-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm.h | 18 +++++++++++++++++- include/linux/mm_types.h | 7 ++++--- 2 files changed, 21 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/mm.h b/include/linux/mm.h index 00bad7793788..a8ab1fc0e9bc 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1361,10 +1361,26 @@ static inline void dec_mm_counter(struct mm_struct *mm, int member) atomic_long_dec(&mm->rss_stat.count[member]); } +/* Optimized variant when page is already known not to be PageAnon */ +static inline int mm_counter_file(struct page *page) +{ + if (PageSwapBacked(page)) + return MM_SHMEMPAGES; + return MM_FILEPAGES; +} + +static inline int mm_counter(struct page *page) +{ + if (PageAnon(page)) + return MM_ANONPAGES; + return mm_counter_file(page); +} + static inline unsigned long get_mm_rss(struct mm_struct *mm) { return get_mm_counter(mm, MM_FILEPAGES) + - get_mm_counter(mm, MM_ANONPAGES); + get_mm_counter(mm, MM_ANONPAGES) + + get_mm_counter(mm, MM_SHMEMPAGES); } static inline unsigned long get_mm_hiwater_rss(struct mm_struct *mm) diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index f8d1492a114f..207890be93c8 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -369,9 +369,10 @@ struct core_state { }; enum { - MM_FILEPAGES, - MM_ANONPAGES, - MM_SWAPENTS, + MM_FILEPAGES, /* Resident file mapping pages */ + MM_ANONPAGES, /* Resident anonymous pages */ + MM_SWAPENTS, /* Anonymous swap entries */ + MM_SHMEMPAGES, /* Resident shared memory pages */ NR_MM_COUNTERS }; -- cgit v1.2.3 From 244d63ee345bd9d45c87f665ef5e3f7bcd5db45b Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Thu, 14 Jan 2016 15:19:35 -0800 Subject: mm, vmalloc: remove VM_VPAGES VM_VPAGES is unnecessary, it's easier to check is_vmalloc_addr() when reading /proc/vmallocinfo. [akpm@linux-foundation.org: remove VM_VPAGES reference via kvfree()] Signed-off-by: David Rientjes Cc: Tetsuo Handa Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/vmalloc.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 3bff87a25a42..d1f1d338af20 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -14,7 +14,6 @@ struct vm_area_struct; /* vma defining user mapping in mm_types.h */ #define VM_ALLOC 0x00000002 /* vmalloc() */ #define VM_MAP 0x00000004 /* vmap()ed pages */ #define VM_USERMAP 0x00000008 /* suitable for remap_vmalloc_range */ -#define VM_VPAGES 0x00000010 /* buffer for pages was vmalloc'ed */ #define VM_UNINITIALIZED 0x00000020 /* vm_struct is not fully initialized */ #define VM_NO_GUARD 0x00000040 /* don't add guard page */ #define VM_KASAN 0x00000080 /* has allocated kasan shadow memory */ -- cgit v1.2.3 From 9ee11ba4251dddf1b0e507d184b25b1bd7820773 Mon Sep 17 00:00:00 2001 From: Vladimir Davydov Date: Thu, 14 Jan 2016 15:19:41 -0800 Subject: memcg: do not allow to disable tcp accounting after limit is set There are two bits defined for cg_proto->flags - MEMCG_SOCK_ACTIVATED and MEMCG_SOCK_ACTIVE - both are set in tcp_update_limit, but the former is never cleared while the latter can be cleared by unsetting the limit. This allows to disable tcp socket accounting for new sockets after it was enabled by writing -1 to memory.kmem.tcp.limit_in_bytes while still guaranteeing that memcg_socket_limit_enabled static key will be decremented on memcg destruction. This functionality looks dubious, because it is not clear what a use case would be. By enabling tcp accounting a user accepts the price. If they then find the performance degradation unacceptable, they can always restart their workload with tcp accounting disabled. It does not seem there is any need to flip it while the workload is running. Besides, it contradicts to how kmem accounting API works: writing whatever to memory.kmem.limit_in_bytes enables kmem accounting for the cgroup in question, after which it cannot be disabled. Therefore one might expect that writing -1 to memory.kmem.tcp.limit_in_bytes just enables socket accounting w/o limiting it, which might be useful by itself, but it isn't true. Since this API peculiarity is not documented anywhere, I propose to drop it. This will allow to simplify the code by dropping cg_proto->flags. Signed-off-by: Vladimir Davydov Cc: Johannes Weiner Cc: Michal Hocko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'include') diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 5c97265c1c6e..78a1ec2e23fc 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -85,22 +85,12 @@ enum mem_cgroup_events_target { MEM_CGROUP_NTARGETS, }; -/* - * Bits in struct cg_proto.flags - */ -enum cg_proto_flags { - /* Currently active and new sockets should be assigned to cgroups */ - MEMCG_SOCK_ACTIVE, - /* It was ever activated; we must disarm static keys on destruction */ - MEMCG_SOCK_ACTIVATED, -}; - struct cg_proto { struct page_counter memory_allocated; /* Current allocated memory. */ struct percpu_counter sockets_allocated; /* Current number of sockets. */ int memory_pressure; + bool active; long sysctl_mem[3]; - unsigned long flags; /* * memcg field is used to find which memcg we belong directly * Each memcg struct can hold more than one cg_proto, so container_of -- cgit v1.2.3 From d07e22597d1d355829b7b18ac19afa912cf758d1 Mon Sep 17 00:00:00 2001 From: Daniel Cashman Date: Thu, 14 Jan 2016 15:19:53 -0800 Subject: mm: mmap: add new /proc tunable for mmap_base ASLR Address Space Layout Randomization (ASLR) provides a barrier to exploitation of user-space processes in the presence of security vulnerabilities by making it more difficult to find desired code/data which could help an attack. This is done by adding a random offset to the location of regions in the process address space, with a greater range of potential offset values corresponding to better protection/a larger search-space for brute force, but also to greater potential for fragmentation. The offset added to the mmap_base address, which provides the basis for the majority of the mappings for a process, is set once on process exec in arch_pick_mmap_layout() and is done via hard-coded per-arch values, which reflect, hopefully, the best compromise for all systems. The trade-off between increased entropy in the offset value generation and the corresponding increased variability in address space fragmentation is not absolute, however, and some platforms may tolerate higher amounts of entropy. This patch introduces both new Kconfig values and a sysctl interface which may be used to change the amount of entropy used for offset generation on a system. The direct motivation for this change was in response to the libstagefright vulnerabilities that affected Android, specifically to information provided by Google's project zero at: http://googleprojectzero.blogspot.com/2015/09/stagefrightened.html The attack presented therein, by Google's project zero, specifically targeted the limited randomness used to generate the offset added to the mmap_base address in order to craft a brute-force-based attack. Concretely, the attack was against the mediaserver process, which was limited to respawning every 5 seconds, on an arm device. The hard-coded 8 bits used resulted in an average expected success rate of defeating the mmap ASLR after just over 10 minutes (128 tries at 5 seconds a piece). With this patch, and an accompanying increase in the entropy value to 16 bits, the same attack would take an average expected time of over 45 hours (32768 tries), which makes it both less feasible and more likely to be noticed. The introduced Kconfig and sysctl options are limited by per-arch minimum and maximum values, the minimum of which was chosen to match the current hard-coded value and the maximum of which was chosen so as to give the greatest flexibility without generating an invalid mmap_base address, generally a 3-4 bits less than the number of bits in the user-space accessible virtual address space. When decided whether or not to change the default value, a system developer should consider that mmap_base address could be placed anywhere up to 2^(value) bits away from the non-randomized location, which would introduce variable-sized areas above and below the mmap_base address such that the maximum vm_area_struct size may be reduced, preventing very large allocations. This patch (of 4): ASLR only uses as few as 8 bits to generate the random offset for the mmap base address on 32 bit architectures. This value was chosen to prevent a poorly chosen value from dividing the address space in such a way as to prevent large allocations. This may not be an issue on all platforms. Allow the specification of a minimum number of bits so that platforms desiring greater ASLR protection may determine where to place the trade-off. Signed-off-by: Daniel Cashman Cc: Russell King Acked-by: Kees Cook Cc: Ingo Molnar Cc: Jonathan Corbet Cc: Don Zickus Cc: Eric W. Biederman Cc: Heinrich Schuchardt Cc: Josh Poimboeuf Cc: Kirill A. Shutemov Cc: Naoya Horiguchi Cc: Andrea Arcangeli Cc: Mel Gorman Cc: Thomas Gleixner Cc: David Rientjes Cc: Mark Salyzyn Cc: Jeff Vander Stoep Cc: Nick Kralevich Cc: Catalin Marinas Cc: Will Deacon Cc: "H. Peter Anvin" Cc: Hector Marco-Gisbert Cc: Borislav Petkov Cc: Ralf Baechle Cc: Heiko Carstens Cc: Martin Schwidefsky Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include') diff --git a/include/linux/mm.h b/include/linux/mm.h index a8ab1fc0e9bc..d396753c0577 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -51,6 +51,17 @@ extern int sysctl_legacy_va_layout; #define sysctl_legacy_va_layout 0 #endif +#ifdef CONFIG_HAVE_ARCH_MMAP_RND_BITS +extern const int mmap_rnd_bits_min; +extern const int mmap_rnd_bits_max; +extern int mmap_rnd_bits __read_mostly; +#endif +#ifdef CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS +extern const int mmap_rnd_compat_bits_min; +extern const int mmap_rnd_compat_bits_max; +extern int mmap_rnd_compat_bits __read_mostly; +#endif + #include #include #include -- cgit v1.2.3 From c20cd45eb01748f0fba77a504f956b000df4ea73 Mon Sep 17 00:00:00 2001 From: Michal Hocko Date: Thu, 14 Jan 2016 15:20:12 -0800 Subject: mm: allow GFP_{FS,IO} for page_cache_read page cache allocation page_cache_read has been historically using page_cache_alloc_cold to allocate a new page. This means that mapping_gfp_mask is used as the base for the gfp_mask. Many filesystems are setting this mask to GFP_NOFS to prevent from fs recursion issues. page_cache_read is called from the vm_operations_struct::fault() context during the page fault. This context doesn't need the reclaim protection normally. ceph and ocfs2 which call filemap_fault from their fault handlers seem to be OK because they are not taking any fs lock before invoking generic implementation. xfs which takes XFS_MMAPLOCK_SHARED is safe from the reclaim recursion POV because this lock serializes truncate and punch hole with the page faults and it doesn't get involved in the reclaim. There is simply no reason to deliberately use a weaker allocation context when a __GFP_FS | __GFP_IO can be used. The GFP_NOFS protection might be even harmful. There is a push to fail GFP_NOFS allocations rather than loop within allocator indefinitely with a very limited reclaim ability. Once we start failing those requests the OOM killer might be triggered prematurely because the page cache allocation failure is propagated up the page fault path and end up in pagefault_out_of_memory. We cannot play with mapping_gfp_mask directly because that would be racy wrt. parallel page faults and it might interfere with other users who really rely on NOFS semantic from the stored gfp_mask. The mask is also inode proper so it would even be a layering violation. What we can do instead is to push the gfp_mask into struct vm_fault and allow fs layer to overwrite it should the callback need to be called with a different allocation context. Initialize the default to (mapping_gfp_mask | __GFP_FS | __GFP_IO) because this should be safe from the page fault path normally. Why do we care about mapping_gfp_mask at all then? Because this doesn't hold only reclaim protection flags but it also might contain zone and movability restrictions (GFP_DMA32, __GFP_MOVABLE and others) so we have to respect those. Signed-off-by: Michal Hocko Reported-by: Tetsuo Handa Acked-by: Jan Kara Acked-by: Vlastimil Babka Cc: Tetsuo Handa Cc: Mel Gorman Cc: Dave Chinner Cc: Mark Fasheh Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/mm.h b/include/linux/mm.h index d396753c0577..ec9d4559514d 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -236,10 +236,14 @@ extern pgprot_t protection_map[16]; * ->fault function. The vma's ->fault is responsible for returning a bitmask * of VM_FAULT_xxx flags that give details about how the fault was handled. * + * MM layer fills up gfp_mask for page allocations but fault handler might + * alter it if its implementation requires a different allocation context. + * * pgoff should be used in favour of virtual_address, if possible. */ struct vm_fault { unsigned int flags; /* FAULT_FLAG_xxx flags */ + gfp_t gfp_mask; /* gfp mask to be used for allocations */ pgoff_t pgoff; /* Logical page offset based on vma */ void __user *virtual_address; /* Faulting virtual address */ -- cgit v1.2.3 From a8d0143730d7b42c9fe6d1435d92ecce6863a62a Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:20:15 -0800 Subject: mm: page_alloc: generalize the dirty balance reserve The dirty balance reserve that dirty throttling has to consider is merely memory not available to userspace allocations. There is nothing writeback-specific about it. Generalize the name so that it's reusable outside of that context. Signed-off-by: Johannes Weiner Cc: Rik van Riel Cc: Mel Gorman Acked-by: Michal Hocko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmzone.h | 6 +++--- include/linux/swap.h | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 3b6fb71bbeb3..33bb1b19273e 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -356,10 +356,10 @@ struct zone { struct per_cpu_pageset __percpu *pageset; /* - * This is a per-zone reserve of pages that should not be - * considered dirtyable memory. + * This is a per-zone reserve of pages that are not available + * to userspace allocations. */ - unsigned long dirty_balance_reserve; + unsigned long totalreserve_pages; #ifndef CONFIG_SPARSEMEM /* diff --git a/include/linux/swap.h b/include/linux/swap.h index 7ba7dccaf0e7..066bd21765ad 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -287,7 +287,6 @@ static inline void workingset_node_shadows_dec(struct radix_tree_node *node) /* linux/mm/page_alloc.c */ extern unsigned long totalram_pages; extern unsigned long totalreserve_pages; -extern unsigned long dirty_balance_reserve; extern unsigned long nr_free_buffer_pages(void); extern unsigned long nr_free_pagecache_pages(void); -- cgit v1.2.3 From 8c9c1701c7c23a57ebfd1a0b27b87053ae43cfb5 Mon Sep 17 00:00:00 2001 From: Alexander Kuleshov Date: Thu, 14 Jan 2016 15:20:42 -0800 Subject: mm/memblock: introduce for_each_memblock_type() We already have the for_each_memblock() macro in which provides ability to iterate over memblock regions of a known type. The for_each_memblock() macro allows us to pass the pointer to the struct memblock_type, instead we need to pass name of the type. This patch introduces a new macro for_each_memblock_type() which allows us iterate over memblock regions with the given type when the type is unknown. Signed-off-by: Alexander Kuleshov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memblock.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 3a092fba2eb2..c0c4208a286f 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -399,6 +399,11 @@ static inline unsigned long memblock_region_reserved_end_pfn(const struct memblo region < (memblock.memblock_type.regions + memblock.memblock_type.cnt); \ region++) +#define for_each_memblock_type(memblock_type, rgn) \ + idx = 0; \ + rgn = &memblock_type->regions[idx]; \ + for (idx = 0; idx < memblock_type->cnt; \ + idx++,rgn = &memblock_type->regions[idx]) #ifdef CONFIG_ARCH_DISCARD_MEMBLOCK #define __init_memblock __meminit -- cgit v1.2.3 From 7d828602e5ef3297a69392a2d31264e4ab9c8bb7 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:20:56 -0800 Subject: mm: memcontrol: export root_mem_cgroup A later patch will need this symbol in files other than memcontrol.c, so export it now and replace mem_cgroup_root_css at the same time. Signed-off-by: Johannes Weiner Acked-by: Michal Hocko Acked-by: David S. Miller Reviewed-by: Vladimir Davydov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 78a1ec2e23fc..d0c724f53691 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -265,7 +265,8 @@ struct mem_cgroup { struct mem_cgroup_per_node *nodeinfo[0]; /* WARNING: nodeinfo must be the last member here */ }; -extern struct cgroup_subsys_state *mem_cgroup_root_css; + +extern struct mem_cgroup *root_mem_cgroup; /** * mem_cgroup_events - count memory events against a cgroup -- cgit v1.2.3 From 8c2c2358b236530bc2c79b4c2a447cbdbc3d96d7 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:20:59 -0800 Subject: net: tcp_memcontrol: properly detect ancestor socket pressure When charging socket memory, the code currently checks only the local page counter for excess to determine whether the memcg is under socket pressure. But even if the local counter is fine, one of the ancestors could have breached its limit, which should also force this child to enter socket pressure. This currently doesn't happen. Fix this by using page_counter_try_charge() first. If that fails, it means that either the local counter or one of the ancestors are in excess of their limit, and the child should enter socket pressure. Fixes: 3e32cb2e0a12 ("mm: memcontrol: lockless page counters") Signed-off-by: Johannes Weiner Acked-by: David S. Miller Reviewed-by: Vladimir Davydov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/net/sock.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/net/sock.h b/include/net/sock.h index e830c1006935..9ef3d7c984b4 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1193,11 +1193,13 @@ static inline void memcg_memory_allocated_add(struct cg_proto *prot, unsigned long amt, int *parent_status) { - page_counter_charge(&prot->memory_allocated, amt); + struct page_counter *counter; + + if (page_counter_try_charge(&prot->memory_allocated, amt, &counter)) + return; - if (page_counter_read(&prot->memory_allocated) > - prot->memory_allocated.limit) - *parent_status = OVER_LIMIT; + page_counter_charge(&prot->memory_allocated, amt); + *parent_status = OVER_LIMIT; } static inline void memcg_memory_allocated_sub(struct cg_proto *prot, -- cgit v1.2.3 From 931f3f4beb031cd483c1c8ab159ef1f8bdbe8888 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:02 -0800 Subject: net: tcp_memcontrol: remove bogus hierarchy pressure propagation When a cgroup currently breaches its socket memory limit, it enters memory pressure mode for itself and its *ancestors*. This throttles transmission in unrelated sibling and cousin subtrees that have nothing to do with the breached limit. On the contrary, breaching a limit should make that group and its *children* enter memory pressure mode. But this happens already, albeit lazily: if an ancestor limit is breached, siblings will enter memory pressure on their own once the next packet arrives for them. So no additional hierarchy code is needed. Remove the bogus stuff. Signed-off-by: Johannes Weiner Acked-by: David S. Miller Reviewed-by: Vladimir Davydov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/net/sock.h | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) (limited to 'include') diff --git a/include/net/sock.h b/include/net/sock.h index 9ef3d7c984b4..d3b035c7362b 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1155,14 +1155,8 @@ static inline void sk_leave_memory_pressure(struct sock *sk) if (*memory_pressure) *memory_pressure = 0; - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) { - struct cg_proto *cg_proto = sk->sk_cgrp; - struct proto *prot = sk->sk_prot; - - for (; cg_proto; cg_proto = parent_cg_proto(prot, cg_proto)) - cg_proto->memory_pressure = 0; - } - + if (mem_cgroup_sockets_enabled && sk->sk_cgrp) + sk->sk_cgrp->memory_pressure = 0; } static inline void sk_enter_memory_pressure(struct sock *sk) @@ -1170,13 +1164,8 @@ static inline void sk_enter_memory_pressure(struct sock *sk) if (!sk->sk_prot->enter_memory_pressure) return; - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) { - struct cg_proto *cg_proto = sk->sk_cgrp; - struct proto *prot = sk->sk_prot; - - for (; cg_proto; cg_proto = parent_cg_proto(prot, cg_proto)) - cg_proto->memory_pressure = 1; - } + if (mem_cgroup_sockets_enabled && sk->sk_cgrp) + sk->sk_cgrp->memory_pressure = 1; sk->sk_prot->enter_memory_pressure(sk); } -- cgit v1.2.3 From 3d596f7b907b0281b997cf30c92994a71ad0a1a9 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:05 -0800 Subject: net: tcp_memcontrol: protect all tcp_memcontrol calls by jump-label Move the jump-label from sock_update_memcg() and sock_release_memcg() to the callsite, and so eliminate those function calls when socket accounting is not enabled. This also eliminates the need for dummy functions because the calls will be optimized away if the Kconfig options are not enabled. Signed-off-by: Johannes Weiner Acked-by: David S. Miller Reviewed-by: Vladimir Davydov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'include') diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index d0c724f53691..85c437b0cbc0 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -694,17 +694,8 @@ static inline void mem_cgroup_wb_stats(struct bdi_writeback *wb, #endif /* CONFIG_CGROUP_WRITEBACK */ struct sock; -#if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM) void sock_update_memcg(struct sock *sk); void sock_release_memcg(struct sock *sk); -#else -static inline void sock_update_memcg(struct sock *sk) -{ -} -static inline void sock_release_memcg(struct sock *sk) -{ -} -#endif /* CONFIG_INET && CONFIG_MEMCG_KMEM */ #ifdef CONFIG_MEMCG_KMEM extern struct static_key memcg_kmem_enabled_key; -- cgit v1.2.3 From af95d7df4059cfeab7e7c244f3564214aada7dad Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:08 -0800 Subject: net: tcp_memcontrol: remove dead per-memcg count of allocated sockets The number of allocated sockets is used for calculations in the soft limit phase, where packets are accepted but the socket is under memory pressure. Since there is no soft limit phase in tcp_memcontrol, and memory pressure is only entered when packets are already dropped, this is actually dead code. Remove it. As this is the last user of parent_cg_proto(), remove that too. Signed-off-by: Johannes Weiner Acked-by: David S. Miller Reviewed-by: Vladimir Davydov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 1 - include/net/sock.h | 39 +++------------------------------------ 2 files changed, 3 insertions(+), 37 deletions(-) (limited to 'include') diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 85c437b0cbc0..15acc04ebdd3 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -87,7 +87,6 @@ enum mem_cgroup_events_target { struct cg_proto { struct page_counter memory_allocated; /* Current allocated memory. */ - struct percpu_counter sockets_allocated; /* Current number of sockets. */ int memory_pressure; bool active; long sysctl_mem[3]; diff --git a/include/net/sock.h b/include/net/sock.h index d3b035c7362b..1f15937ec208 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1098,19 +1098,9 @@ static inline void sk_refcnt_debug_release(const struct sock *sk) #if defined(CONFIG_MEMCG_KMEM) && defined(CONFIG_NET) extern struct static_key memcg_socket_limit_enabled; -static inline struct cg_proto *parent_cg_proto(struct proto *proto, - struct cg_proto *cg_proto) -{ - return proto->proto_cgroup(parent_mem_cgroup(cg_proto->memcg)); -} #define mem_cgroup_sockets_enabled static_key_false(&memcg_socket_limit_enabled) #else #define mem_cgroup_sockets_enabled 0 -static inline struct cg_proto *parent_cg_proto(struct proto *proto, - struct cg_proto *cg_proto) -{ - return NULL; -} #endif static inline bool sk_stream_memory_free(const struct sock *sk) @@ -1236,41 +1226,18 @@ sk_memory_allocated_sub(struct sock *sk, int amt) static inline void sk_sockets_allocated_dec(struct sock *sk) { - struct proto *prot = sk->sk_prot; - - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) { - struct cg_proto *cg_proto = sk->sk_cgrp; - - for (; cg_proto; cg_proto = parent_cg_proto(prot, cg_proto)) - percpu_counter_dec(&cg_proto->sockets_allocated); - } - - percpu_counter_dec(prot->sockets_allocated); + percpu_counter_dec(sk->sk_prot->sockets_allocated); } static inline void sk_sockets_allocated_inc(struct sock *sk) { - struct proto *prot = sk->sk_prot; - - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) { - struct cg_proto *cg_proto = sk->sk_cgrp; - - for (; cg_proto; cg_proto = parent_cg_proto(prot, cg_proto)) - percpu_counter_inc(&cg_proto->sockets_allocated); - } - - percpu_counter_inc(prot->sockets_allocated); + percpu_counter_inc(sk->sk_prot->sockets_allocated); } static inline int sk_sockets_allocated_read_positive(struct sock *sk) { - struct proto *prot = sk->sk_prot; - - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - return percpu_counter_read_positive(&sk->sk_cgrp->sockets_allocated); - - return percpu_counter_read_positive(prot->sockets_allocated); + return percpu_counter_read_positive(sk->sk_prot->sockets_allocated); } static inline int -- cgit v1.2.3 From 80f23124f57c77915a7b4201d8dcba38a38b23f0 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:11 -0800 Subject: net: tcp_memcontrol: simplify the per-memcg limit access tcp_memcontrol replicates the global sysctl_mem limit array per cgroup, but it only ever sets these entries to the value of the memory_allocated page_counter limit. Use the latter directly. Signed-off-by: Johannes Weiner Reviewed-by: Vladimir Davydov Acked-by: David S. Miller Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 1 - include/net/sock.h | 8 +++++--- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 15acc04ebdd3..6c91c1b73951 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -89,7 +89,6 @@ struct cg_proto { struct page_counter memory_allocated; /* Current allocated memory. */ int memory_pressure; bool active; - long sysctl_mem[3]; /* * memcg field is used to find which memcg we belong directly * Each memcg struct can hold more than one cg_proto, so container_of diff --git a/include/net/sock.h b/include/net/sock.h index 1f15937ec208..8b1f8e5d3a48 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1162,10 +1162,12 @@ static inline void sk_enter_memory_pressure(struct sock *sk) static inline long sk_prot_mem_limits(const struct sock *sk, int index) { - long *prot = sk->sk_prot->sysctl_mem; + long limit = sk->sk_prot->sysctl_mem[index]; + if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - prot = sk->sk_cgrp->sysctl_mem; - return prot[index]; + limit = min_t(long, limit, sk->sk_cgrp->memory_allocated.limit); + + return limit; } static inline void memcg_memory_allocated_add(struct cg_proto *prot, -- cgit v1.2.3 From e805605c721021879a1469bdae45c6f80bc985f4 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:14 -0800 Subject: net: tcp_memcontrol: sanitize tcp memory accounting callbacks There won't be a tcp control soft limit, so integrating the memcg code into the global skmem limiting scheme complicates things unnecessarily. Replace this with simple and clear charge and uncharge calls--hidden behind a jump label--to account skb memory. Note that this is not purely aesthetic: as a result of shoehorning the per-memcg code into the same memory accounting functions that handle the global level, the old code would compare the per-memcg consumption against the smaller of the per-memcg limit and the global limit. This allowed the total consumption of multiple sockets to exceed the global limit, as long as the individual sockets stayed within bounds. After this change, the code will always compare the per-memcg consumption to the per-memcg limit, and the global consumption to the global limit, and thus close this loophole. Without a soft limit, the per-memcg memory pressure state in sockets is generally questionable. However, we did it until now, so we continue to enter it when the hard limit is hit, and packets are dropped, to let other sockets in the cgroup know that they shouldn't grow their transmit windows, either. However, keep it simple in the new callback model and leave memory pressure lazily when the next packet is accepted (as opposed to doing it synchroneously when packets are processed). When packets are dropped, network performance will already be in the toilet, so that should be a reasonable trade-off. As described above, consumption is now checked on the per-memcg level and the global level separately. Likewise, memory pressure states are maintained on both the per-memcg level and the global level, and a socket is considered under pressure when either level asserts as much. Signed-off-by: Johannes Weiner Reviewed-by: Vladimir Davydov Acked-by: David S. Miller Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 19 +++++++++----- include/net/sock.h | 64 ++++++---------------------------------------- include/net/tcp.h | 5 ++-- 3 files changed, 24 insertions(+), 64 deletions(-) (limited to 'include') diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 6c91c1b73951..e4e77bd1dd39 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -660,12 +660,6 @@ void mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx) } #endif /* CONFIG_MEMCG */ -enum { - UNDER_LIMIT, - SOFT_LIMIT, - OVER_LIMIT, -}; - #ifdef CONFIG_CGROUP_WRITEBACK struct list_head *mem_cgroup_cgwb_list(struct mem_cgroup *memcg); @@ -694,6 +688,19 @@ static inline void mem_cgroup_wb_stats(struct bdi_writeback *wb, struct sock; void sock_update_memcg(struct sock *sk); void sock_release_memcg(struct sock *sk); +bool mem_cgroup_charge_skmem(struct cg_proto *proto, unsigned int nr_pages); +void mem_cgroup_uncharge_skmem(struct cg_proto *proto, unsigned int nr_pages); +#if defined(CONFIG_MEMCG_KMEM) && defined(CONFIG_INET) +static inline bool mem_cgroup_under_socket_pressure(struct cg_proto *proto) +{ + return proto->memory_pressure; +} +#else +static inline bool mem_cgroup_under_pressure(struct cg_proto *proto) +{ + return false; +} +#endif #ifdef CONFIG_MEMCG_KMEM extern struct static_key memcg_kmem_enabled_key; diff --git a/include/net/sock.h b/include/net/sock.h index 8b1f8e5d3a48..94a6c1a740b9 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1129,8 +1129,9 @@ static inline bool sk_under_memory_pressure(const struct sock *sk) if (!sk->sk_prot->memory_pressure) return false; - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - return !!sk->sk_cgrp->memory_pressure; + if (mem_cgroup_sockets_enabled && sk->sk_cgrp && + mem_cgroup_under_socket_pressure(sk->sk_cgrp)) + return true; return !!*sk->sk_prot->memory_pressure; } @@ -1144,9 +1145,6 @@ static inline void sk_leave_memory_pressure(struct sock *sk) if (*memory_pressure) *memory_pressure = 0; - - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - sk->sk_cgrp->memory_pressure = 0; } static inline void sk_enter_memory_pressure(struct sock *sk) @@ -1154,76 +1152,30 @@ static inline void sk_enter_memory_pressure(struct sock *sk) if (!sk->sk_prot->enter_memory_pressure) return; - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - sk->sk_cgrp->memory_pressure = 1; - sk->sk_prot->enter_memory_pressure(sk); } static inline long sk_prot_mem_limits(const struct sock *sk, int index) { - long limit = sk->sk_prot->sysctl_mem[index]; - - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - limit = min_t(long, limit, sk->sk_cgrp->memory_allocated.limit); - - return limit; -} - -static inline void memcg_memory_allocated_add(struct cg_proto *prot, - unsigned long amt, - int *parent_status) -{ - struct page_counter *counter; - - if (page_counter_try_charge(&prot->memory_allocated, amt, &counter)) - return; - - page_counter_charge(&prot->memory_allocated, amt); - *parent_status = OVER_LIMIT; -} - -static inline void memcg_memory_allocated_sub(struct cg_proto *prot, - unsigned long amt) -{ - page_counter_uncharge(&prot->memory_allocated, amt); + return sk->sk_prot->sysctl_mem[index]; } static inline long sk_memory_allocated(const struct sock *sk) { - struct proto *prot = sk->sk_prot; - - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - return page_counter_read(&sk->sk_cgrp->memory_allocated); - - return atomic_long_read(prot->memory_allocated); + return atomic_long_read(sk->sk_prot->memory_allocated); } static inline long -sk_memory_allocated_add(struct sock *sk, int amt, int *parent_status) +sk_memory_allocated_add(struct sock *sk, int amt) { - struct proto *prot = sk->sk_prot; - - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) { - memcg_memory_allocated_add(sk->sk_cgrp, amt, parent_status); - /* update the root cgroup regardless */ - atomic_long_add_return(amt, prot->memory_allocated); - return page_counter_read(&sk->sk_cgrp->memory_allocated); - } - - return atomic_long_add_return(amt, prot->memory_allocated); + return atomic_long_add_return(amt, sk->sk_prot->memory_allocated); } static inline void sk_memory_allocated_sub(struct sock *sk, int amt) { - struct proto *prot = sk->sk_prot; - - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - memcg_memory_allocated_sub(sk->sk_cgrp, amt); - - atomic_long_sub(amt, prot->memory_allocated); + atomic_long_sub(amt, sk->sk_prot->memory_allocated); } static inline void sk_sockets_allocated_dec(struct sock *sk) diff --git a/include/net/tcp.h b/include/net/tcp.h index a80255f4ca33..d9df80deba31 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -289,8 +289,9 @@ extern int tcp_memory_pressure; /* optimized version of sk_under_memory_pressure() for TCP sockets */ static inline bool tcp_under_memory_pressure(const struct sock *sk) { - if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - return !!sk->sk_cgrp->memory_pressure; + if (mem_cgroup_sockets_enabled && sk->sk_cgrp && + mem_cgroup_under_socket_pressure(sk->sk_cgrp)) + return true; return tcp_memory_pressure; } -- cgit v1.2.3 From baac50bbc3cdfd184ebf586b1704edbfcee866df Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:17 -0800 Subject: net: tcp_memcontrol: simplify linkage between socket and page counter There won't be any separate counters for socket memory consumed by protocols other than TCP in the future. Remove the indirection and link sockets directly to their owning memory cgroup. Signed-off-by: Johannes Weiner Reviewed-by: Vladimir Davydov Acked-by: David S. Miller Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 20 +++++--------------- include/net/sock.h | 25 ++++--------------------- include/net/tcp.h | 4 ++-- include/net/tcp_memcontrol.h | 1 - 4 files changed, 11 insertions(+), 39 deletions(-) (limited to 'include') diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index e4e77bd1dd39..7c085e4636ba 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -89,16 +89,6 @@ struct cg_proto { struct page_counter memory_allocated; /* Current allocated memory. */ int memory_pressure; bool active; - /* - * memcg field is used to find which memcg we belong directly - * Each memcg struct can hold more than one cg_proto, so container_of - * won't really cut. - * - * The elegant solution would be having an inverse function to - * proto_cgroup in struct proto, but that means polluting the structure - * for everybody, instead of just for memcg users. - */ - struct mem_cgroup *memcg; }; #ifdef CONFIG_MEMCG @@ -688,15 +678,15 @@ static inline void mem_cgroup_wb_stats(struct bdi_writeback *wb, struct sock; void sock_update_memcg(struct sock *sk); void sock_release_memcg(struct sock *sk); -bool mem_cgroup_charge_skmem(struct cg_proto *proto, unsigned int nr_pages); -void mem_cgroup_uncharge_skmem(struct cg_proto *proto, unsigned int nr_pages); +bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages); +void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages); #if defined(CONFIG_MEMCG_KMEM) && defined(CONFIG_INET) -static inline bool mem_cgroup_under_socket_pressure(struct cg_proto *proto) +static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg) { - return proto->memory_pressure; + return memcg->tcp_mem.memory_pressure; } #else -static inline bool mem_cgroup_under_pressure(struct cg_proto *proto) +static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg) { return false; } diff --git a/include/net/sock.h b/include/net/sock.h index 94a6c1a740b9..be96a8dcbc74 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -71,22 +71,6 @@ #include #include -struct cgroup; -struct cgroup_subsys; -#ifdef CONFIG_NET -int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss); -void mem_cgroup_sockets_destroy(struct mem_cgroup *memcg); -#else -static inline -int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss) -{ - return 0; -} -static inline -void mem_cgroup_sockets_destroy(struct mem_cgroup *memcg) -{ -} -#endif /* * This structure really needs to be cleaned up. * Most of it is for TCP, and not used by any of @@ -245,7 +229,6 @@ struct sock_common { /* public: */ }; -struct cg_proto; /** * struct sock - network layer representation of sockets * @__sk_common: shared layout with inet_timewait_sock @@ -310,7 +293,7 @@ struct cg_proto; * @sk_security: used by security modules * @sk_mark: generic packet mark * @sk_cgrp_data: cgroup data for this cgroup - * @sk_cgrp: this socket's cgroup-specific proto data + * @sk_memcg: this socket's memory cgroup association * @sk_write_pending: a write to stream socket waits to start * @sk_state_change: callback to indicate change in the state of the sock * @sk_data_ready: callback to indicate there is data to be processed @@ -446,7 +429,7 @@ struct sock { void *sk_security; #endif struct sock_cgroup_data sk_cgrp_data; - struct cg_proto *sk_cgrp; + struct mem_cgroup *sk_memcg; void (*sk_state_change)(struct sock *sk); void (*sk_data_ready)(struct sock *sk); void (*sk_write_space)(struct sock *sk); @@ -1129,8 +1112,8 @@ static inline bool sk_under_memory_pressure(const struct sock *sk) if (!sk->sk_prot->memory_pressure) return false; - if (mem_cgroup_sockets_enabled && sk->sk_cgrp && - mem_cgroup_under_socket_pressure(sk->sk_cgrp)) + if (mem_cgroup_sockets_enabled && sk->sk_memcg && + mem_cgroup_under_socket_pressure(sk->sk_memcg)) return true; return !!*sk->sk_prot->memory_pressure; diff --git a/include/net/tcp.h b/include/net/tcp.h index d9df80deba31..8ea19977ea53 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -289,8 +289,8 @@ extern int tcp_memory_pressure; /* optimized version of sk_under_memory_pressure() for TCP sockets */ static inline bool tcp_under_memory_pressure(const struct sock *sk) { - if (mem_cgroup_sockets_enabled && sk->sk_cgrp && - mem_cgroup_under_socket_pressure(sk->sk_cgrp)) + if (mem_cgroup_sockets_enabled && sk->sk_memcg && + mem_cgroup_under_socket_pressure(sk->sk_memcg)) return true; return tcp_memory_pressure; diff --git a/include/net/tcp_memcontrol.h b/include/net/tcp_memcontrol.h index 05b94d9453de..3a17b16ae8aa 100644 --- a/include/net/tcp_memcontrol.h +++ b/include/net/tcp_memcontrol.h @@ -1,7 +1,6 @@ #ifndef _TCP_MEMCG_H #define _TCP_MEMCG_H -struct cg_proto *tcp_proto_cgroup(struct mem_cgroup *memcg); int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss); void tcp_destroy_cgroup(struct mem_cgroup *memcg); #endif /* _TCP_MEMCG_H */ -- cgit v1.2.3 From 80e95fe0fdcde2812c341ad4209d62dc1a7af53b Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:20 -0800 Subject: mm: memcontrol: generalize the socket accounting jump label The unified hierarchy memory controller is going to use this jump label as well to control the networking callbacks. Move it to the memory controller code and give it a more generic name. Signed-off-by: Johannes Weiner Acked-by: Michal Hocko Reviewed-by: Vladimir Davydov Acked-by: David S. Miller Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 3 +++ include/net/sock.h | 7 ------- 2 files changed, 3 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 7c085e4636ba..03090e8e7fff 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -681,11 +681,14 @@ void sock_release_memcg(struct sock *sk); bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages); void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages); #if defined(CONFIG_MEMCG_KMEM) && defined(CONFIG_INET) +extern struct static_key memcg_sockets_enabled_key; +#define mem_cgroup_sockets_enabled static_key_false(&memcg_sockets_enabled_key) static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg) { return memcg->tcp_mem.memory_pressure; } #else +#define mem_cgroup_sockets_enabled 0 static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg) { return false; diff --git a/include/net/sock.h b/include/net/sock.h index be96a8dcbc74..b9e7b3d863a0 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1079,13 +1079,6 @@ static inline void sk_refcnt_debug_release(const struct sock *sk) #define sk_refcnt_debug_release(sk) do { } while (0) #endif /* SOCK_REFCNT_DEBUG */ -#if defined(CONFIG_MEMCG_KMEM) && defined(CONFIG_NET) -extern struct static_key memcg_socket_limit_enabled; -#define mem_cgroup_sockets_enabled static_key_false(&memcg_socket_limit_enabled) -#else -#define mem_cgroup_sockets_enabled 0 -#endif - static inline bool sk_stream_memory_free(const struct sock *sk) { if (sk->sk_wmem_queued >= sk->sk_sndbuf) -- cgit v1.2.3 From f7e1cb6ec51b041335b5ad4dd7aefb37a56d79a6 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:29 -0800 Subject: mm: memcontrol: account socket memory in unified hierarchy memory controller Socket memory can be a significant share of overall memory consumed by common workloads. In order to provide reasonable resource isolation in the unified hierarchy, this type of memory needs to be included in the tracking/accounting of a cgroup under active memory resource control. Overhead is only incurred when a non-root control group is created AND the memory controller is instructed to track and account the memory footprint of that group. cgroup.memory=nosocket can be specified on the boot commandline to override any runtime configuration and forcibly exclude socket memory from active memory resource control. Signed-off-by: Johannes Weiner Acked-by: David S. Miller Reviewed-by: Vladimir Davydov Acked-by: Michal Hocko Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 03090e8e7fff..a355f61a2ed3 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -170,6 +170,9 @@ struct mem_cgroup { unsigned long low; unsigned long high; + /* Range enforcement for interrupt charges */ + struct work_struct high_work; + unsigned long soft_limit; /* vmpressure notifications */ @@ -680,12 +683,16 @@ void sock_update_memcg(struct sock *sk); void sock_release_memcg(struct sock *sk); bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages); void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages); -#if defined(CONFIG_MEMCG_KMEM) && defined(CONFIG_INET) +#if defined(CONFIG_MEMCG) && defined(CONFIG_INET) extern struct static_key memcg_sockets_enabled_key; #define mem_cgroup_sockets_enabled static_key_false(&memcg_sockets_enabled_key) static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg) { +#ifdef CONFIG_MEMCG_KMEM return memcg->tcp_mem.memory_pressure; +#else + return false; +#endif } #else #define mem_cgroup_sockets_enabled 0 -- cgit v1.2.3 From 8e8ae645249b85c8ed6c178557f8db8613a6bcc7 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:32 -0800 Subject: mm: memcontrol: hook up vmpressure to socket pressure Let the networking stack know when a memcg is under reclaim pressure so that it can clamp its transmit windows accordingly. Whenever the reclaim efficiency of a cgroup's LRU lists drops low enough for a MEDIUM or HIGH vmpressure event to occur, assert a pressure state in the socket and tcp memory code that tells it to curb consumption growth from sockets associated with said control group. Traditionally, vmpressure reports for the entire subtree of a memcg under pressure, which drops useful information on the individual groups reclaimed. However, it's too late to change the userinterface, so add a second reporting mode that reports on the level of reclaim instead of at the level of pressure, and use that report for sockets. vmpressure events are naturally edge triggered, so for hysteresis assert socket pressure for a second to allow for subsequent vmpressure events to occur before letting the socket code return to normal. This will likely need finetuning for a wider variety of workloads, but for now stick to the vmpressure presets and keep hysteresis simple. Signed-off-by: Johannes Weiner Acked-by: David S. Miller Reviewed-by: Vladimir Davydov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 32 ++++++++++++++++++++++++++++---- include/linux/vmpressure.h | 7 +++++-- 2 files changed, 33 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index a355f61a2ed3..c5a51039df57 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -249,6 +249,10 @@ struct mem_cgroup { struct wb_domain cgwb_domain; #endif +#ifdef CONFIG_INET + unsigned long socket_pressure; +#endif + /* List of events which userspace want to receive */ struct list_head event_list; spinlock_t event_list_lock; @@ -290,18 +294,34 @@ struct lruvec *mem_cgroup_page_lruvec(struct page *, struct zone *); bool task_in_mem_cgroup(struct task_struct *task, struct mem_cgroup *memcg); struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p); -struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *memcg); static inline struct mem_cgroup *mem_cgroup_from_css(struct cgroup_subsys_state *css){ return css ? container_of(css, struct mem_cgroup, css) : NULL; } +#define mem_cgroup_from_counter(counter, member) \ + container_of(counter, struct mem_cgroup, member) + struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *, struct mem_cgroup *, struct mem_cgroup_reclaim_cookie *); void mem_cgroup_iter_break(struct mem_cgroup *, struct mem_cgroup *); +/** + * parent_mem_cgroup - find the accounting parent of a memcg + * @memcg: memcg whose parent to find + * + * Returns the parent memcg, or NULL if this is the root or the memory + * controller is in legacy no-hierarchy mode. + */ +static inline struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *memcg) +{ + if (!memcg->memory.parent) + return NULL; + return mem_cgroup_from_counter(memcg->memory.parent, memory); +} + static inline bool mem_cgroup_is_descendant(struct mem_cgroup *memcg, struct mem_cgroup *root) { @@ -689,10 +709,14 @@ extern struct static_key memcg_sockets_enabled_key; static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg) { #ifdef CONFIG_MEMCG_KMEM - return memcg->tcp_mem.memory_pressure; -#else - return false; + if (memcg->tcp_mem.memory_pressure) + return true; #endif + do { + if (time_before(jiffies, memcg->socket_pressure)) + return true; + } while ((memcg = parent_mem_cgroup(memcg))); + return false; } #else #define mem_cgroup_sockets_enabled 0 diff --git a/include/linux/vmpressure.h b/include/linux/vmpressure.h index 3e4535876d37..3347cc3ec0ab 100644 --- a/include/linux/vmpressure.h +++ b/include/linux/vmpressure.h @@ -12,6 +12,9 @@ struct vmpressure { unsigned long scanned; unsigned long reclaimed; + + unsigned long tree_scanned; + unsigned long tree_reclaimed; /* The lock is used to keep the scanned/reclaimed above in sync. */ struct spinlock sr_lock; @@ -26,7 +29,7 @@ struct vmpressure { struct mem_cgroup; #ifdef CONFIG_MEMCG -extern void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, +extern void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, bool tree, unsigned long scanned, unsigned long reclaimed); extern void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, int prio); @@ -40,7 +43,7 @@ extern int vmpressure_register_event(struct mem_cgroup *memcg, extern void vmpressure_unregister_event(struct mem_cgroup *memcg, struct eventfd_ctx *eventfd); #else -static inline void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, +static inline void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, bool tree, unsigned long scanned, unsigned long reclaimed) {} static inline void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, int prio) {} -- cgit v1.2.3 From ef12947c9c5a96af549c49f10e5503f0612a397c Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 14 Jan 2016 15:21:34 -0800 Subject: mm: memcontrol: switch to the updated jump-label API According to the direct use of struct static_key is deprecated. Update the socket and slab accounting code accordingly. Signed-off-by: Johannes Weiner Acked-by: David S. Miller Reported-by: Jason Baron Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index c5a51039df57..2292468f2a30 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -704,8 +704,8 @@ void sock_release_memcg(struct sock *sk); bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages); void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages); #if defined(CONFIG_MEMCG) && defined(CONFIG_INET) -extern struct static_key memcg_sockets_enabled_key; -#define mem_cgroup_sockets_enabled static_key_false(&memcg_sockets_enabled_key) +extern struct static_key_false memcg_sockets_enabled_key; +#define mem_cgroup_sockets_enabled static_branch_unlikely(&memcg_sockets_enabled_key) static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg) { #ifdef CONFIG_MEMCG_KMEM @@ -727,7 +727,7 @@ static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg) #endif #ifdef CONFIG_MEMCG_KMEM -extern struct static_key memcg_kmem_enabled_key; +extern struct static_key_false memcg_kmem_enabled_key; extern int memcg_nr_cache_ids; void memcg_get_cache_ids(void); @@ -743,7 +743,7 @@ void memcg_put_cache_ids(void); static inline bool memcg_kmem_enabled(void) { - return static_key_false(&memcg_kmem_enabled_key); + return static_branch_unlikely(&memcg_kmem_enabled_key); } static inline bool memcg_kmem_is_active(struct mem_cgroup *memcg) -- cgit v1.2.3 From 0eb77e9880321915322d42913c3b53241739c8aa Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Thu, 14 Jan 2016 15:21:40 -0800 Subject: vmstat: make vmstat_updater deferrable again and shut down on idle Currently the vmstat updater is not deferrable as a result of commit ba4877b9ca51 ("vmstat: do not use deferrable delayed work for vmstat_update"). This in turn can cause multiple interruptions of the applications because the vmstat updater may run at Make vmstate_update deferrable again and provide a function that folds the differentials when the processor is going to idle mode thus addressing the issue of the above commit in a clean way. Note that the shepherd thread will continue scanning the differentials from another processor and will reenable the vmstat workers if it detects any changes. Fixes: ba4877b9ca51 ("vmstat: do not use deferrable delayed work for vmstat_update") Signed-off-by: Christoph Lameter Cc: Michal Hocko Cc: Johannes Weiner Cc: Tetsuo Handa Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/vmstat.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 3e5d9075960f..73fae8c4a5fb 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -189,6 +189,7 @@ extern void __inc_zone_state(struct zone *, enum zone_stat_item); extern void dec_zone_state(struct zone *, enum zone_stat_item); extern void __dec_zone_state(struct zone *, enum zone_stat_item); +void quiet_vmstat(void); void cpu_vm_stats_fold(int cpu); void refresh_zone_stat_thresholds(void); @@ -249,6 +250,7 @@ static inline void __dec_zone_page_state(struct page *page, static inline void refresh_zone_stat_thresholds(void) { } static inline void cpu_vm_stats_fold(int cpu) { } +static inline void quiet_vmstat(void) { } static inline void drain_zonestat(struct zone *zone, struct per_cpu_pageset *pset) { } -- cgit v1.2.3 From d72ee911130631b50a8ccc615a7d4622c2062194 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Thu, 14 Jan 2016 15:22:01 -0800 Subject: mm: move lru_to_page to mm_inline.h Move lru_to_page() from internal.h to mm_inline.h. Signed-off-by: Geliang Tang Acked-by: Vlastimil Babka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm_inline.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h index cf55945c83fb..712e8c37a200 100644 --- a/include/linux/mm_inline.h +++ b/include/linux/mm_inline.h @@ -100,4 +100,6 @@ static __always_inline enum lru_list page_lru(struct page *page) return lru; } +#define lru_to_page(head) (list_entry((head)->prev, struct page, lru)) + #endif -- cgit v1.2.3 From d30b5545bdcf802ffc24ec7dbc6dc4036f6e3820 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Thu, 14 Jan 2016 15:22:04 -0800 Subject: include/linux/memblock.h: fix ordering of 'flags' argument in comments for_each_free_mem_range() and for_each_free_mem_range_reverse() both accept a 'flags' argument, the comment surrounding the macro placed the 'flags' documentation at the very end, while 'flags' is in fact the 3rd argument to the macro, so let's preserve natural ordering here. Fixes: fc6daaf931518 ("mm/memblock: add extra "flags" to memblock to allow selection of memory based on attribute") Signed-off-by: Florian Fainelli Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memblock.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/memblock.h b/include/linux/memblock.h index c0c4208a286f..173fb44e22f1 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -216,10 +216,10 @@ void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn, * for_each_free_mem_range - iterate through free memblock areas * @i: u64 used as loop variable * @nid: node selector, %NUMA_NO_NODE for all nodes + * @flags: pick from blocks based on memory attributes * @p_start: ptr to phys_addr_t for start address of the range, can be %NULL * @p_end: ptr to phys_addr_t for end address of the range, can be %NULL * @p_nid: ptr to int for nid of the range, can be %NULL - * @flags: pick from blocks based on memory attributes * * Walks over free (memory && !reserved) areas of memblock. Available as * soon as memblock is initialized. @@ -232,10 +232,10 @@ void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn, * for_each_free_mem_range_reverse - rev-iterate through free memblock areas * @i: u64 used as loop variable * @nid: node selector, %NUMA_NO_NODE for all nodes + * @flags: pick from blocks based on memory attributes * @p_start: ptr to phys_addr_t for start address of the range, can be %NULL * @p_end: ptr to phys_addr_t for end address of the range, can be %NULL * @p_nid: ptr to int for nid of the range, can be %NULL - * @flags: pick from blocks based on memory attributes * * Walks over free (memory && !reserved) areas of memblock in reverse * order. Available as soon as memblock is initialized. -- cgit v1.2.3 From 84638335900f1995495838fe1bd4870c43ec1f67 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Thu, 14 Jan 2016 15:22:07 -0800 Subject: mm: rework virtual memory accounting When inspecting a vague code inside prctl(PR_SET_MM_MEM) call (which testing the RLIMIT_DATA value to figure out if we're allowed to assign new @start_brk, @brk, @start_data, @end_data from mm_struct) it's been commited that RLIMIT_DATA in a form it's implemented now doesn't do anything useful because most of user-space libraries use mmap() syscall for dynamic memory allocations. Linus suggested to convert RLIMIT_DATA rlimit into something suitable for anonymous memory accounting. But in this patch we go further, and the changes are bundled together as: * keep vma counting if CONFIG_PROC_FS=n, will be used for limits * replace mm->shared_vm with better defined mm->data_vm * account anonymous executable areas as executable * account file-backed growsdown/up areas as stack * drop struct file* argument from vm_stat_account * enforce RLIMIT_DATA for size of data areas This way code looks cleaner: now code/stack/data classification depends only on vm_flags state: VM_EXEC & ~VM_WRITE -> code (VmExe + VmLib in proc) VM_GROWSUP | VM_GROWSDOWN -> stack (VmStk) VM_WRITE & ~VM_SHARED & !stack -> data (VmData) The rest (VmSize - VmData - VmStk - VmExe - VmLib) could be called "shared", but that might be strange beast like readonly-private or VM_IO area. - RLIMIT_AS limits whole address space "VmSize" - RLIMIT_STACK limits stack "VmStk" (but each vma individually) - RLIMIT_DATA now limits "VmData" Signed-off-by: Konstantin Khlebnikov Signed-off-by: Cyrill Gorcunov Cc: Quentin Casasnovas Cc: Vegard Nossum Acked-by: Linus Torvalds Cc: Willy Tarreau Cc: Andy Lutomirski Cc: Kees Cook Cc: Vladimir Davydov Cc: Pavel Emelyanov Cc: Peter Zijlstra Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm.h | 13 +++---------- include/linux/mm_types.h | 2 +- 2 files changed, 4 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/linux/mm.h b/include/linux/mm.h index ec9d4559514d..839d9e9a1c38 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1929,7 +1929,9 @@ extern void mm_drop_all_locks(struct mm_struct *mm); extern void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file); extern struct file *get_mm_exe_file(struct mm_struct *mm); -extern int may_expand_vm(struct mm_struct *mm, unsigned long npages); +extern bool may_expand_vm(struct mm_struct *, vm_flags_t, unsigned long npages); +extern void vm_stat_account(struct mm_struct *, vm_flags_t, long npages); + extern struct vm_area_struct *_install_special_mapping(struct mm_struct *mm, unsigned long addr, unsigned long len, unsigned long flags, @@ -2147,15 +2149,6 @@ typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr, extern int apply_to_page_range(struct mm_struct *mm, unsigned long address, unsigned long size, pte_fn_t fn, void *data); -#ifdef CONFIG_PROC_FS -void vm_stat_account(struct mm_struct *, unsigned long, struct file *, long); -#else -static inline void vm_stat_account(struct mm_struct *mm, - unsigned long flags, struct file *file, long pages) -{ - mm->total_vm += pages; -} -#endif /* CONFIG_PROC_FS */ #ifdef CONFIG_DEBUG_PAGEALLOC extern bool _debug_pagealloc_enabled; diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 207890be93c8..6bc9a0ce2253 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -427,7 +427,7 @@ struct mm_struct { unsigned long total_vm; /* Total pages mapped */ unsigned long locked_vm; /* Pages that have PG_mlocked set */ unsigned long pinned_vm; /* Refcount permanently increased */ - unsigned long shared_vm; /* Shared pages (files) */ + unsigned long data_vm; /* VM_WRITE & ~VM_SHARED/GROWSDOWN */ unsigned long exec_vm; /* VM_EXEC & ~VM_WRITE */ unsigned long stack_vm; /* VM_GROWSUP/DOWN */ unsigned long def_flags; -- cgit v1.2.3 From 543dfb2df8ebb3eb0b499eae1d63de1701a99b40 Mon Sep 17 00:00:00 2001 From: Joshua Clayton Date: Thu, 14 Jan 2016 15:22:10 -0800 Subject: mm: fix noisy sparse warning in LIBCFS_ALLOC_PRE() Running sparse on drivers/staging/lustre results in dozens of warnings: include/linux/gfp.h:281:41: warning: odd constant _Bool cast (400000 becomes 1) Use "!!" to explicitly convert to bool and get rid of the warning. Signed-off-by: Joshua Clayton Cc: Mel Gorman Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/gfp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 91f74e741aa2..28ad5f6494b0 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -278,7 +278,7 @@ static inline int gfpflags_to_migratetype(const gfp_t gfp_flags) static inline bool gfpflags_allow_blocking(const gfp_t gfp_flags) { - return (bool __force)(gfp_flags & __GFP_DIRECT_RECLAIM); + return !!(gfp_flags & __GFP_DIRECT_RECLAIM); } #ifdef CONFIG_HIGHMEM -- cgit v1.2.3 From 7d2eba0557c18f7522b98befed98799990dd4fdb Mon Sep 17 00:00:00 2001 From: Ebru Akagunduz Date: Thu, 14 Jan 2016 15:22:19 -0800 Subject: mm: add tracepoint for scanning pages This patch series makes swapin readahead up to a certain number to gain more thp performance and adds tracepoint for khugepaged_scan_pmd, collapse_huge_page, __collapse_huge_page_isolate. This patch series was written to deal with programs that access most, but not all, of their memory after they get swapped out. Currently these programs do not get their memory collapsed into THPs after the system swapped their memory out, while they would get THPs before swapping happened. This patch series was tested with a test program, it allocates 400MB of memory, writes to it, and then sleeps. I force the system to swap out all. Afterwards, the test program touches the area by writing and leaves a piece of it without writing. This shows how much swap in readahead made by the patch. Test results: After swapped out ------------------------------------------------------------------- | Anonymous | AnonHugePages | Swap | Fraction | ------------------------------------------------------------------- With patch | 90076 kB | 88064 kB | 309928 kB | %99 | ------------------------------------------------------------------- Without patch | 194068 kB | 192512 kB | 205936 kB | %99 | ------------------------------------------------------------------- After swapped in ------------------------------------------------------------------- | Anonymous | AnonHugePages | Swap | Fraction | ------------------------------------------------------------------- With patch | 201408 kB | 198656 kB | 198596 kB | %98 | ------------------------------------------------------------------- Without patch | 292624 kB | 192512 kB | 107380 kB | %65 | ------------------------------------------------------------------- This patch (of 3): Using static tracepoints, data of functions is recorded. It is good to automatize debugging without doing a lot of changes in the source code. This patch adds tracepoint for khugepaged_scan_pmd, collapse_huge_page and __collapse_huge_page_isolate. [dan.carpenter@oracle.com: add a missing tab] Signed-off-by: Ebru Akagunduz Acked-by: Kirill A. Shutemov Acked-by: Rik van Riel Cc: Naoya Horiguchi Cc: Andrea Arcangeli Cc: Joonsoo Kim Cc: Xie XiuQi Cc: Cyrill Gorcunov Cc: Mel Gorman Cc: David Rientjes Cc: Vlastimil Babka Cc: Aneesh Kumar K.V Cc: Hugh Dickins Cc: Johannes Weiner Cc: Michal Hocko Signed-off-by: Dan Carpenter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/trace/events/huge_memory.h | 136 +++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 include/trace/events/huge_memory.h (limited to 'include') diff --git a/include/trace/events/huge_memory.h b/include/trace/events/huge_memory.h new file mode 100644 index 000000000000..97d635cabac8 --- /dev/null +++ b/include/trace/events/huge_memory.h @@ -0,0 +1,136 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM huge_memory + +#if !defined(__HUGE_MEMORY_H) || defined(TRACE_HEADER_MULTI_READ) +#define __HUGE_MEMORY_H + +#include + +#include + +#define SCAN_STATUS \ + EM( SCAN_FAIL, "failed") \ + EM( SCAN_SUCCEED, "succeeded") \ + EM( SCAN_PMD_NULL, "pmd_null") \ + EM( SCAN_EXCEED_NONE_PTE, "exceed_none_pte") \ + EM( SCAN_PTE_NON_PRESENT, "pte_non_present") \ + EM( SCAN_PAGE_RO, "no_writable_page") \ + EM( SCAN_NO_REFERENCED_PAGE, "no_referenced_page") \ + EM( SCAN_PAGE_NULL, "page_null") \ + EM( SCAN_SCAN_ABORT, "scan_aborted") \ + EM( SCAN_PAGE_COUNT, "not_suitable_page_count") \ + EM( SCAN_PAGE_LRU, "page_not_in_lru") \ + EM( SCAN_PAGE_LOCK, "page_locked") \ + EM( SCAN_PAGE_ANON, "page_not_anon") \ + EM( SCAN_ANY_PROCESS, "no_process_for_page") \ + EM( SCAN_VMA_NULL, "vma_null") \ + EM( SCAN_VMA_CHECK, "vma_check_failed") \ + EM( SCAN_ADDRESS_RANGE, "not_suitable_address_range") \ + EM( SCAN_SWAP_CACHE_PAGE, "page_swap_cache") \ + EM( SCAN_DEL_PAGE_LRU, "could_not_delete_page_from_lru")\ + EM( SCAN_ALLOC_HUGE_PAGE_FAIL, "alloc_huge_page_failed") \ + EMe( SCAN_CGROUP_CHARGE_FAIL, "ccgroup_charge_failed") + +#undef EM +#undef EMe +#define EM(a, b) TRACE_DEFINE_ENUM(a); +#define EMe(a, b) TRACE_DEFINE_ENUM(a); + +SCAN_STATUS + +#undef EM +#undef EMe +#define EM(a, b) {a, b}, +#define EMe(a, b) {a, b} + +TRACE_EVENT(mm_khugepaged_scan_pmd, + + TP_PROTO(struct mm_struct *mm, unsigned long pfn, bool writable, + bool referenced, int none_or_zero, int status), + + TP_ARGS(mm, pfn, writable, referenced, none_or_zero, status), + + TP_STRUCT__entry( + __field(struct mm_struct *, mm) + __field(unsigned long, pfn) + __field(bool, writable) + __field(bool, referenced) + __field(int, none_or_zero) + __field(int, status) + ), + + TP_fast_assign( + __entry->mm = mm; + __entry->pfn = pfn; + __entry->writable = writable; + __entry->referenced = referenced; + __entry->none_or_zero = none_or_zero; + __entry->status = status; + ), + + TP_printk("mm=%p, scan_pfn=0x%lx, writable=%d, referenced=%d, none_or_zero=%d, status=%s", + __entry->mm, + __entry->pfn, + __entry->writable, + __entry->referenced, + __entry->none_or_zero, + __print_symbolic(__entry->status, SCAN_STATUS)) +); + +TRACE_EVENT(mm_collapse_huge_page, + + TP_PROTO(struct mm_struct *mm, int isolated, int status), + + TP_ARGS(mm, isolated, status), + + TP_STRUCT__entry( + __field(struct mm_struct *, mm) + __field(int, isolated) + __field(int, status) + ), + + TP_fast_assign( + __entry->mm = mm; + __entry->isolated = isolated; + __entry->status = status; + ), + + TP_printk("mm=%p, isolated=%d, status=%s", + __entry->mm, + __entry->isolated, + __print_symbolic(__entry->status, SCAN_STATUS)) +); + +TRACE_EVENT(mm_collapse_huge_page_isolate, + + TP_PROTO(unsigned long pfn, int none_or_zero, + bool referenced, bool writable, int status), + + TP_ARGS(pfn, none_or_zero, referenced, writable, status), + + TP_STRUCT__entry( + __field(unsigned long, pfn) + __field(int, none_or_zero) + __field(bool, referenced) + __field(bool, writable) + __field(int, status) + ), + + TP_fast_assign( + __entry->pfn = pfn; + __entry->none_or_zero = none_or_zero; + __entry->referenced = referenced; + __entry->writable = writable; + __entry->status = status; + ), + + TP_printk("scan_pfn=0x%lx, none_or_zero=%d, referenced=%d, writable=%d, status=%s", + __entry->pfn, + __entry->none_or_zero, + __entry->referenced, + __entry->writable, + __print_symbolic(__entry->status, SCAN_STATUS)) +); + +#endif /* __HUGE_MEMORY_H */ +#include -- cgit v1.2.3 From 9207f9d45b0ad071baa128e846d7e7ed85016df3 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Fri, 8 Jan 2016 15:21:46 +0300 Subject: net: preserve IP control block during GSO segmentation Skb_gso_segment() uses skb control block during segmentation. This patch adds 32-bytes room for previous control block which will be copied into all resulting segments. This patch fixes kernel crash during fragmenting forwarded packets. Fragmentation requires valid IP CB in skb for clearing ip options. Also patch removes custom save/restore in ovs code, now it's redundant. Signed-off-by: Konstantin Khlebnikov Link: http://lkml.kernel.org/r/CALYGNiP-0MZ-FExV2HutTvE9U-QQtkKSoE--KN=JQE5STYsjAA@mail.gmail.com Signed-off-by: David S. Miller --- include/linux/skbuff.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 07f9ccd28654..11f935c1a090 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -3551,7 +3551,8 @@ struct skb_gso_cb { int encap_level; __u16 csum_start; }; -#define SKB_GSO_CB(skb) ((struct skb_gso_cb *)(skb)->cb) +#define SKB_SGO_CB_OFFSET 32 +#define SKB_GSO_CB(skb) ((struct skb_gso_cb *)((skb)->cb + SKB_SGO_CB_OFFSET)) static inline int skb_tnl_header_len(const struct sk_buff *inner_skb) { -- cgit v1.2.3 From 34ae6a1aa0540f0f781dd265366036355fdc8930 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 15 Jan 2016 04:56:56 -0800 Subject: ipv6: update skb->csum when CE mark is propagated When a tunnel decapsulates the outer header, it has to comply with RFC 6080 and eventually propagate CE mark into inner header. It turns out IP6_ECN_set_ce() does not correctly update skb->csum for CHECKSUM_COMPLETE packets, triggering infamous "hw csum failure" messages and stack traces. Signed-off-by: Eric Dumazet Acked-by: Herbert Xu Signed-off-by: David S. Miller --- include/net/inet_ecn.h | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h index 84b20835b736..0dc0a51da38f 100644 --- a/include/net/inet_ecn.h +++ b/include/net/inet_ecn.h @@ -111,11 +111,24 @@ static inline void ipv4_copy_dscp(unsigned int dscp, struct iphdr *inner) struct ipv6hdr; -static inline int IP6_ECN_set_ce(struct ipv6hdr *iph) +/* Note: + * IP_ECN_set_ce() has to tweak IPV4 checksum when setting CE, + * meaning both changes have no effect on skb->csum if/when CHECKSUM_COMPLETE + * In IPv6 case, no checksum compensates the change in IPv6 header, + * so we have to update skb->csum. + */ +static inline int IP6_ECN_set_ce(struct sk_buff *skb, struct ipv6hdr *iph) { + __be32 from, to; + if (INET_ECN_is_not_ect(ipv6_get_dsfield(iph))) return 0; - *(__be32*)iph |= htonl(INET_ECN_CE << 20); + + from = *(__be32 *)iph; + to = from | htonl(INET_ECN_CE << 20); + *(__be32 *)iph = to; + if (skb->ip_summed == CHECKSUM_COMPLETE) + skb->csum = csum_add(csum_sub(skb->csum, from), to); return 1; } @@ -142,7 +155,7 @@ static inline int INET_ECN_set_ce(struct sk_buff *skb) case cpu_to_be16(ETH_P_IPV6): if (skb_network_header(skb) + sizeof(struct ipv6hdr) <= skb_tail_pointer(skb)) - return IP6_ECN_set_ce(ipv6_hdr(skb)); + return IP6_ECN_set_ce(skb, ipv6_hdr(skb)); break; } -- cgit v1.2.3