diff options
Diffstat (limited to 'include')
53 files changed, 1258 insertions, 1113 deletions
diff --git a/include/aiodev.h b/include/aiodev.h index 56bd2da9f5..fb0807ad42 100644 --- a/include/aiodev.h +++ b/include/aiodev.h @@ -47,4 +47,13 @@ static inline const char *aiochannel_get_unit(struct aiochannel *aiochan) extern struct list_head aiodevices; #define for_each_aiodevice(aiodevice) list_for_each_entry(aiodevice, &aiodevices, list) +#ifdef CONFIG_AIODEV +int aiochannel_name_get_value(const char *chname, int *value); +#else +static inline int aiochannel_name_get_value(const char *chname, int *value) +{ + return -EOPNOTSUPP; +} +#endif + #endif diff --git a/include/boards/wolfvision/common.h b/include/boards/wolfvision/common.h new file mode 100644 index 0000000000..a9bf6acbbb --- /dev/null +++ b/include/boards/wolfvision/common.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Common board code functions WolfVision boards. + * + * Copyright (C) 2024 WolfVision GmbH. + */ + +#ifndef _BOARDS_WOLFVISION_COMMON_H +#define _BOARDS_WOLFVISION_COMMON_H + +#define WV_RK3568_HWID_MAX 17 + +struct wv_overlay { + const char *name; + const char *filename; + const void *data; +}; + +struct wv_rk3568_extension { + int adc_chan; + const char *name; + const struct wv_overlay overlays[WV_RK3568_HWID_MAX]; +}; + +int wolfvision_apply_overlay(const struct wv_overlay *overlay, char **files); + +int wolfvision_register_ethaddr(void); + +int wolfvision_rk3568_detect_hw(const struct wv_rk3568_extension *extensions, + int num_extensions, char **overlays); + +#endif /* _BOARDS_WOLFVISION_COMMON_H */ diff --git a/include/bootm.h b/include/bootm.h index ee2b574521..98ac5e5a93 100644 --- a/include/bootm.h +++ b/include/bootm.h @@ -34,6 +34,11 @@ struct bootm_data { * value of global.machine_id to Kernel. */ bool provide_machine_id; + /* + * provide_hostname - if true, try to add systemd.hostname= with value + * of global.hostname to Kernel. + */ + bool provide_hostname; unsigned long initrd_address; unsigned long os_address; unsigned long os_entry; @@ -147,6 +152,9 @@ int bootm_get_os_size(struct image_data *data); enum bootm_verify bootm_get_verify_mode(void); void bootm_set_verify_mode(enum bootm_verify mode); +bool bootm_signed_images_are_forced(void); +void bootm_force_signed_images(void); + #define UIMAGE_SOME_ADDRESS (UIMAGE_INVALID_ADDRESS - 1) void *booti_load_image(struct image_data *data, phys_addr_t *oftree); diff --git a/include/common.h b/include/common.h index b7b4d9e350..d7b5261bc9 100644 --- a/include/common.h +++ b/include/common.h @@ -127,6 +127,7 @@ void barebox_set_model(const char *); const char *barebox_get_hostname(void); void barebox_set_hostname(const char *); void barebox_set_hostname_no_overwrite(const char *); +bool barebox_hostname_is_valid(const char *s); const char *barebox_get_serial_number(void); void barebox_set_serial_number(const char *); diff --git a/include/console.h b/include/console.h index 69c0ec144b..62d13d7aa0 100644 --- a/include/console.h +++ b/include/console.h @@ -102,6 +102,7 @@ int console_set_active(struct console_device *cdev, unsigned active); unsigned console_get_active(struct console_device *cdev); int console_set_baudrate(struct console_device *cdev, unsigned baudrate); unsigned console_get_baudrate(struct console_device *cdev); +void console_set_stdoutpath(struct console_device *cdev, unsigned baudrate); struct console_device *of_console_by_stdout_path(void); diff --git a/include/device.h b/include/device.h new file mode 100644 index 0000000000..8c3561e5a2 --- /dev/null +++ b/include/device.h @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * (C) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> + */ + +#ifndef DEVICE_H +#define DEVICE_H + +#include <linux/types.h> + +enum dev_dma_coherence { + DEV_DMA_COHERENCE_DEFAULT = 0, + DEV_DMA_COHERENT, + DEV_DMA_NON_COHERENT, +}; + +struct device; +struct bus_type; +struct resource; +struct driver; +struct generic_pm_domain; +struct platform_device_id; +struct of_device_id; + +/** @brief Describes a particular device present in the system */ +struct device { + /*! This member (and 'type' described below) is used to match + * with a driver. This is a descriptive name and could be + * MPC5XXX_ether or imx_serial. Unless absolutely necessary, + * should not be modified directly and dev_set_name() should + * be used instead. + */ + char *name; + + /*! This member is used to store device's unique name as + * obtained by calling dev_id(). Internal field, do not + * access it directly. + */ + char *unique_name; + /*! The id is used to uniquely identify a device in the system. The id + * will show up under /dev/ as the device's name. Usually this is + * something like eth0 or nor0. */ + int id; + + enum dev_dma_coherence dma_coherent; + + struct resource *resource; + int num_resources; + + void *platform_data; /*! board specific information about this device */ + + /*! Devices of a particular class normaly need to store more + * information than struct device holds. + */ + void *priv; + void *type_data; /*! In case this device is a specific device, this pointer + * points to the type specific device, i.e. eth_device + */ + struct driver *driver; /*! The driver for this device */ + + struct list_head list; /* The list of all devices */ + struct list_head bus_list; /* our bus */ + struct list_head children; /* our children */ + struct list_head sibling; + struct list_head active; /* The list of all devices which have a driver */ + + struct device *parent; /* our parent, NULL if not present */ + + struct generic_pm_domain *pm_domain; /* attached power domain */ + + struct bus_type *bus; + + /*! The parameters for this device. This is used to carry information + * of board specific data from the board code to the device driver. */ + struct list_head parameters; + + struct list_head cdevs; + + const struct platform_device_id *id_entry; + union { + struct device_node *device_node; + struct device_node *of_node; + }; + + const struct of_device_id *of_id_entry; + + u64 dma_mask; + + unsigned long dma_offset; + + void (*info) (struct device *); + /* + * For devices which take longer to probe this is called + * when the driver should actually detect client devices + */ + int (*detect) (struct device *); + void (*rescan) (struct device *); + + /* + * if a driver probe is deferred, this stores the last error + */ + char *deferred_probe_reason; +}; + +struct device_alias { + struct device *dev; + struct list_head list; + char name[]; +}; + +#endif diff --git a/include/disks.h b/include/disks.h index ccb50d3ce9..a3673d1e27 100644 --- a/include/disks.h +++ b/include/disks.h @@ -3,6 +3,9 @@ #ifndef DISKS_H #define DISKS_H +#include <linux/types.h> +#include <linux/errno.h> + struct block_device; /** Size of one sector in bytes */ @@ -24,6 +27,14 @@ struct partition_entry { } __attribute__ ((packed)); extern int parse_partition_table(struct block_device*); + +#ifdef CONFIG_PARTITION_MANIPULATION int reparse_partition_table(struct block_device *blk); +#else +static inline int reparse_partition_table(struct block_device *blk) +{ + return -ENOSYS; +} +#endif #endif /* DISKS_H */ diff --git a/include/dma.h b/include/dma.h index df9807b4f2..4fcd114bb6 100644 --- a/include/dma.h +++ b/include/dma.h @@ -8,12 +8,12 @@ #include <malloc.h> #include <xfuncs.h> -#include <linux/kernel.h> +#include <linux/align.h> #include <dma-dir.h> #include <asm/dma.h> #include <asm/io.h> -#include <driver.h> +#include <device.h> #define DMA_ADDRESS_BROKEN NULL @@ -21,11 +21,21 @@ #define DMA_ALIGNMENT 32 #endif +#ifdef CONFIG_HAS_DMA +void *dma_alloc(size_t size); +void *dma_zalloc(size_t size); +#else static inline void *dma_alloc(size_t size) { - return xmemalign(DMA_ALIGNMENT, ALIGN(size, DMA_ALIGNMENT)); + return malloc(size); } +static inline void *dma_zalloc(size_t size) +{ + return calloc(size, 1); +} +#endif + static inline void dma_free(void *mem) { free(mem); diff --git a/include/driver.h b/include/driver.h index e02815d09b..c8eb7605e7 100644 --- a/include/driver.h +++ b/include/driver.h @@ -10,6 +10,7 @@ #include <linux/ioport.h> #include <linux/uuid.h> #include <linux/printk.h> +#include <device.h> #include <of.h> #include <init.h> #include <filetype.h> @@ -27,98 +28,6 @@ struct platform_device_id { unsigned long driver_data; }; -enum dev_dma_coherence { - DEV_DMA_COHERENCE_DEFAULT = 0, - DEV_DMA_COHERENT, - DEV_DMA_NON_COHERENT, -}; - -/** @brief Describes a particular device present in the system */ -struct device { - /*! This member (and 'type' described below) is used to match - * with a driver. This is a descriptive name and could be - * MPC5XXX_ether or imx_serial. Unless absolutely necessary, - * should not be modified directly and dev_set_name() should - * be used instead. - */ - char *name; - - /*! This member is used to store device's unique name as - * obtained by calling dev_id(). Internal field, do not - * access it directly. - */ - char *unique_name; - /*! The id is used to uniquely identify a device in the system. The id - * will show up under /dev/ as the device's name. Usually this is - * something like eth0 or nor0. */ - int id; - - enum dev_dma_coherence dma_coherent; - - struct resource *resource; - int num_resources; - - void *platform_data; /*! board specific information about this device */ - - /*! Devices of a particular class normaly need to store more - * information than struct device holds. - */ - void *priv; - void *type_data; /*! In case this device is a specific device, this pointer - * points to the type specific device, i.e. eth_device - */ - struct driver *driver; /*! The driver for this device */ - - struct list_head list; /* The list of all devices */ - struct list_head bus_list; /* our bus */ - struct list_head children; /* our children */ - struct list_head sibling; - struct list_head active; /* The list of all devices which have a driver */ - - struct device *parent; /* our parent, NULL if not present */ - - struct generic_pm_domain *pm_domain; /* attached power domain */ - - struct bus_type *bus; - - /*! The parameters for this device. This is used to carry information - * of board specific data from the board code to the device driver. */ - struct list_head parameters; - - struct list_head cdevs; - - const struct platform_device_id *id_entry; - union { - struct device_node *device_node; - struct device_node *of_node; - }; - - const struct of_device_id *of_id_entry; - - u64 dma_mask; - - unsigned long dma_offset; - - void (*info) (struct device *); - /* - * For devices which take longer to probe this is called - * when the driver should actually detect client devices - */ - int (*detect) (struct device *); - void (*rescan) (struct device *); - - /* - * if a driver probe is deferred, this stores the last error - */ - char *deferred_probe_reason; -}; - -struct device_alias { - struct device *dev; - struct list_head list; - char name[]; -}; - /** @brief Describes a driver present in the system */ struct driver { /*! The name of this driver. Used to match to @@ -615,7 +524,7 @@ struct cdev *cdev_create_loop(const char *path, ulong flags, loff_t offset); void cdev_remove_loop(struct cdev *cdev); int cdev_open(struct cdev *, unsigned long flags); int cdev_fdopen(struct cdev *cdev, unsigned long flags); -void cdev_close(struct cdev *cdev); +int cdev_close(struct cdev *cdev); int cdev_flush(struct cdev *cdev); ssize_t cdev_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulong flags); ssize_t cdev_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset, ulong flags); diff --git a/include/efi.h b/include/efi.h index 6bb5f8cb0a..a27cbe1f49 100644 --- a/include/efi.h +++ b/include/efi.h @@ -562,6 +562,9 @@ extern struct efi_runtime_services *RT; #define EFI_TIMESTAMP_PROTOCOL_GUID \ EFI_GUID(0xafbfde41, 0x2e6e, 0x4262, 0xba, 0x65, 0x62, 0xb9, 0x23, 0x6e, 0x54, 0x95) +#define EFI_I2C_MASTER_PROTOCOL_GUID \ + EFI_GUID(0xcd72881f, 0x45b5, 0x4feb, 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62) + /* barebox specific GUIDs */ #define EFI_BAREBOX_VENDOR_GUID \ EFI_GUID(0x5b91f69c, 0x8b88, 0x4a2b, 0x92, 0x69, 0x5f, 0x1d, 0x80, 0x2b, 0x51, 0x75) diff --git a/include/file-list.h b/include/file-list.h index 79190b0f19..1625f116a0 100644 --- a/include/file-list.h +++ b/include/file-list.h @@ -21,7 +21,6 @@ struct file_list_entry { struct file_list { struct list_head list; - int num_entries; }; struct file_list *file_list_parse(const char *str); @@ -47,7 +46,7 @@ struct file_list_entry *file_list_entry_by_name(struct file_list *files, const c static inline bool file_list_empty(struct file_list *files) { - return !files || !files->num_entries; + return !files || list_empty(&files->list); } #endif /* __FILE_LIST */ diff --git a/include/input/input.h b/include/input/input.h index d169c647bd..9445d20e56 100644 --- a/include/input/input.h +++ b/include/input/input.h @@ -14,6 +14,7 @@ struct input_event { struct input_device { struct list_head list; + struct device *parent; DECLARE_BITMAP(keys, KEY_CNT); }; diff --git a/include/linux/align.h b/include/linux/align.h new file mode 100644 index 0000000000..8df1b3dcd7 --- /dev/null +++ b/include/linux/align.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_ALIGN_H +#define _LINUX_ALIGN_H + +#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a) - 1) +#define ALIGN_DOWN(x, a) ALIGN((x) - ((a) - 1), (a)) +#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) +#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a))) +#define PTR_ALIGN_DOWN(p, a) ((typeof(p))ALIGN_DOWN((unsigned long)(p), (a))) +#define PTR_IS_ALIGNED(x, a) IS_ALIGNED((unsigned long)(x), (a)) +#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0) + +#endif diff --git a/include/linux/bch.h b/include/linux/bch.h index 295b4ef153..85fdce83d4 100644 --- a/include/linux/bch.h +++ b/include/linux/bch.h @@ -1,19 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Generic binary BCH encoding/decoding library * - * 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. - * - * 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. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * * Copyright © 2011 Parrot S.A. * * Author: Ivan Djelic <ivan.djelic@parrot.com> @@ -45,6 +33,7 @@ * @cache: log-based polynomial representation buffer * @elp: error locator polynomial * @poly_2t: temporary polynomials of degree 2t + * @swap_bits: swap bits within data and syndrome bytes */ struct bch_control { unsigned int m; @@ -63,16 +52,18 @@ struct bch_control { int *cache; struct gf_poly *elp; struct gf_poly *poly_2t[4]; + bool swap_bits; }; -struct bch_control *init_bch(int m, int t, unsigned int prim_poly); +struct bch_control *bch_init(int m, int t, unsigned int prim_poly, + bool swap_bits); -void free_bch(struct bch_control *bch); +void bch_free(struct bch_control *bch); -void encode_bch(struct bch_control *bch, const uint8_t *data, +void bch_encode(struct bch_control *bch, const uint8_t *data, unsigned int len, uint8_t *ecc); -int decode_bch(struct bch_control *bch, const uint8_t *data, unsigned int len, +int bch_decode(struct bch_control *bch, const uint8_t *data, unsigned int len, const uint8_t *recv_ecc, const uint8_t *calc_ecc, const unsigned int *syn, unsigned int *errloc); diff --git a/include/linux/clk.h b/include/linux/clk.h index 7ba0679d03..bd107962fb 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -708,8 +708,10 @@ static inline int clk_hw_register(struct device *dev, struct clk_hw *hw) struct clk *clk_lookup(const char *name); -void clk_dump(int verbose); -void clk_dump_one(struct clk *clk, int verbose); +#define CLK_DUMP_VERBOSE (1 << 0) +#define CLK_DUMP_JSON (1 << 1) +void clk_dump(int flags); +void clk_dump_one(struct clk *clk, int flags); struct clk *clk_register_composite(const char *name, const char * const *parent_names, int num_parents, diff --git a/include/linux/device.h b/include/linux/device.h index d892a9cb0e..66294910ab 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -12,13 +12,11 @@ #define __devm_wrapper(fn, dev, ...) ({ BUG_ON(!dev); fn(__VA_ARGS__); }) #define devm_kmalloc(...) __devm_wrapper(kmalloc, __VA_ARGS__) -#define devm_krealloc(...) __devm_wrapper(krealloc, __VA_ARGS__) #define devm_kvasprintf(...) __devm_wrapper(kvasprintf, __VA_ARGS__) #define devm_kasprintf(...) __devm_wrapper(kasprintf, __VA_ARGS__) #define devm_kzalloc(...) __devm_wrapper(kzalloc, __VA_ARGS__) #define devm_kmalloc_array(...) __devm_wrapper(kmalloc_array, __VA_ARGS__) #define devm_kcalloc(...) __devm_wrapper(kcalloc, __VA_ARGS__) -#define devm_krealloc_array(...) __devm_wrapper(krealloc_array, __VA_ARGS__) #define devm_kfree(...) __devm_wrapper(kfree, __VA_ARGS__) #define devm_kstrdup(...) __devm_wrapper(kstrdup, __VA_ARGS__) #define devm_kstrdup_const(...) __devm_wrapper(kstrdup_const, __VA_ARGS__) diff --git a/include/linux/export.h b/include/linux/export.h index a136d727d1..e8ec826366 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -4,6 +4,8 @@ #ifndef __ASSEMBLY__ +#include <module.h> + #define THIS_MODULE 0 #if defined(CONFIG_MODULES) && !defined(__DISABLE_EXPORTS) diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index 531ed14725..e04f516b31 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -45,6 +45,8 @@ struct gpio_descs { DECLARE_FLEX_ARRAY(struct gpio_desc *, desc); }; +bool gpiod_slice_acquired(struct gpio_desc *); + #if defined(CONFIG_OFDEVICE) && defined(CONFIG_GPIOLIB) /* returned gpio descriptor can be passed to any normal gpio_* function */ diff --git a/include/linux/is_defined.h b/include/linux/is_defined.h new file mode 100644 index 0000000000..bfefca033f --- /dev/null +++ b/include/linux/is_defined.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LINUX_IS_DEFINED_H_ +#define __LINUX_IS_DEFINED_H_ + +#define __ARG_PLACEHOLDER_1 0, +#define __take_second_arg(__ignored, val, ...) val + +/* + * The use of "&&" / "||" is limited in certain expressions. + * The following enable to calculate "and" / "or" with macro expansion only. + */ +#define __and(x, y) ___and(x, y) +#define ___and(x, y) ____and(__ARG_PLACEHOLDER_##x, y) +#define ____and(arg1_or_junk, y) __take_second_arg(arg1_or_junk y, 0) + +#define __or(x, y) ___or(x, y) +#define ___or(x, y) ____or(__ARG_PLACEHOLDER_##x, y) +#define ____or(arg1_or_junk, y) __take_second_arg(arg1_or_junk 1, y) + +/* + * Helper macros to use CONFIG_ options in C/CPP expressions. Note that + * these only work with boolean and tristate options. + */ + +/* + * Getting something that works in C and CPP for an arg that may or may + * not be defined is tricky. Here, if we have "#define CONFIG_BOOGER 1" + * we match on the placeholder define, insert the "0," for arg1 and generate + * the triplet (0, 1, 0). Then the last step cherry picks the 2nd arg (a one). + * When CONFIG_BOOGER is not defined, we generate a (... 1, 0) pair, and when + * the last step cherry picks the 2nd arg, we get a zero. + */ +#define __is_defined(x) ___is_defined(x) +#define ___is_defined(val) ____is_defined(__ARG_PLACEHOLDER_##val) +#define ____is_defined(arg1_or_junk) __take_second_arg(arg1_or_junk 1, 0) + +#define __if_defined(x, a, b) ___if_defined(__is_defined(x), a, b) +#define ___if_defined(val, a, b) ____if_defined(val, a, b) +#define ____if_defined(val, a, b) ____if_defined_##val(a, b) +#define ____if_defined_1(a, b) a +#define ____if_defined_0(a, b) b + +#endif diff --git a/include/linux/kconfig.h b/include/linux/kconfig.h index fec5076eda..58f68adbba 100644 --- a/include/linux/kconfig.h +++ b/include/linux/kconfig.h @@ -3,38 +3,7 @@ #define __LINUX_KCONFIG_H #include <generated/autoconf.h> - -#define __ARG_PLACEHOLDER_1 0, -#define __take_second_arg(__ignored, val, ...) val - -/* - * The use of "&&" / "||" is limited in certain expressions. - * The following enable to calculate "and" / "or" with macro expansion only. - */ -#define __and(x, y) ___and(x, y) -#define ___and(x, y) ____and(__ARG_PLACEHOLDER_##x, y) -#define ____and(arg1_or_junk, y) __take_second_arg(arg1_or_junk y, 0) - -#define __or(x, y) ___or(x, y) -#define ___or(x, y) ____or(__ARG_PLACEHOLDER_##x, y) -#define ____or(arg1_or_junk, y) __take_second_arg(arg1_or_junk 1, y) - -/* - * Helper macros to use CONFIG_ options in C/CPP expressions. Note that - * these only work with boolean and tristate options. - */ - -/* - * Getting something that works in C and CPP for an arg that may or may - * not be defined is tricky. Here, if we have "#define CONFIG_BOOGER 1" - * we match on the placeholder define, insert the "0," for arg1 and generate - * the triplet (0, 1, 0). Then the last step cherry picks the 2nd arg (a one). - * When CONFIG_BOOGER is not defined, we generate a (... 1, 0) pair, and when - * the last step cherry picks the 2nd arg, we get a zero. - */ -#define __is_defined(x) ___is_defined(x) -#define ___is_defined(val) ____is_defined(__ARG_PLACEHOLDER_##val) -#define ____is_defined(arg1_or_junk) __take_second_arg(arg1_or_junk 1, 0) +#include <linux/is_defined.h> /* * IS_BUILTIN(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y', 0 diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 4e50f60751..c411ac0860 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -10,6 +10,7 @@ #include <linux/container_of.h> #include <linux/instruction_pointer.h> #include <linux/minmax.h> +#include <linux/align.h> /** * REPEAT_BYTE - repeat the value @x multiple times as an unsigned long value @@ -19,14 +20,6 @@ */ #define REPEAT_BYTE(x) ((~0ul / 0xff) * (x)) -#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a) - 1) -#define ALIGN_DOWN(x, a) ALIGN((x) - ((a) - 1), (a)) -#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) -#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a))) -#define PTR_ALIGN_DOWN(p, a) ((typeof(p))ALIGN_DOWN((unsigned long)(p), (a))) -#define PTR_IS_ALIGNED(x, a) IS_ALIGNED((unsigned long)(x), (a)) -#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0) - #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) diff --git a/include/linux/list.h b/include/linux/list.h index 60b0111f46..2b3a39ea81 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -592,6 +592,21 @@ static inline void list_splice_tail_init(struct list_head *list, pos = n, n = pos->prev) /** + * list_count_nodes - count nodes in the list + * @head: the head for your list. + */ +static inline size_t list_count_nodes(struct list_head *head) +{ + struct list_head *pos; + size_t count = 0; + + list_for_each(pos, head) + count++; + + return count; +} + +/** * list_for_each_entry - iterate over list of given type * @pos: the type * to use as a loop cursor. * @head: the head for your list. diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 54cb2ec64c..8d99dff27f 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -198,13 +198,16 @@ struct mtd_info { void (*_sync) (struct mtd_info *mtd); /* Chip-supported device locking */ - int (*_lock) (struct mtd_info *mtd, loff_t ofs, size_t len); - int (*_unlock) (struct mtd_info *mtd, loff_t ofs, size_t len); + int (*_lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); + int (*_unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); + int (*_is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len); + int (*_block_isreserved) (struct mtd_info *mtd, loff_t ofs); /* Bad block management functions */ int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs); int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs); int (*_block_markgood) (struct mtd_info *mtd, loff_t ofs); + int (*_max_bad_blocks) (struct mtd_info *mtd, loff_t ofs, size_t len); int (*of_fixup)(struct mtd_info *mtd, struct device_node *root); diff --git a/include/linux/mtd/nand-ecc-sw-bch.h b/include/linux/mtd/nand-ecc-sw-bch.h new file mode 100644 index 0000000000..9da9969505 --- /dev/null +++ b/include/linux/mtd/nand-ecc-sw-bch.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright © 2011 Ivan Djelic <ivan.djelic@parrot.com> + * + * This file is the header for the NAND BCH ECC implementation. + */ + +#ifndef __MTD_NAND_ECC_SW_BCH_H__ +#define __MTD_NAND_ECC_SW_BCH_H__ + +#include <linux/mtd/nand.h> +#include <linux/bch.h> + +/** + * struct nand_ecc_sw_bch_conf - private software BCH ECC engine structure + * @req_ctx: Save request context and tweak the original request to fit the + * engine needs + * @code_size: Number of bytes needed to store a code (one code per step) + * @calc_buf: Buffer to use when calculating ECC bytes + * @code_buf: Buffer to use when reading (raw) ECC bytes from the chip + * @bch: BCH control structure + * @errloc: error location array + * @eccmask: XOR ecc mask, allows erased pages to be decoded as valid + */ +struct nand_ecc_sw_bch_conf { + struct nand_ecc_req_tweak_ctx req_ctx; + unsigned int code_size; + u8 *calc_buf; + u8 *code_buf; + struct bch_control *bch; + unsigned int *errloc; + unsigned char *eccmask; +}; + +#if IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_BCH) + +int nand_ecc_sw_bch_calculate(struct nand_device *nand, + const unsigned char *buf, unsigned char *code); +int nand_ecc_sw_bch_correct(struct nand_device *nand, unsigned char *buf, + unsigned char *read_ecc, unsigned char *calc_ecc); +int nand_ecc_sw_bch_init_ctx(struct nand_device *nand); +void nand_ecc_sw_bch_cleanup_ctx(struct nand_device *nand); +struct nand_ecc_engine *nand_ecc_sw_bch_get_engine(void); + +#else /* !CONFIG_MTD_NAND_ECC_SW_BCH */ + +static inline int nand_ecc_sw_bch_calculate(struct nand_device *nand, + const unsigned char *buf, + unsigned char *code) +{ + return -ENOTSUPP; +} + +static inline int nand_ecc_sw_bch_correct(struct nand_device *nand, + unsigned char *buf, + unsigned char *read_ecc, + unsigned char *calc_ecc) +{ + return -ENOTSUPP; +} + +static inline int nand_ecc_sw_bch_init_ctx(struct nand_device *nand) +{ + return -ENOTSUPP; +} + +static inline void nand_ecc_sw_bch_cleanup_ctx(struct nand_device *nand) {} + +#endif /* CONFIG_MTD_NAND_ECC_SW_BCH */ + +#endif /* __MTD_NAND_ECC_SW_BCH_H__ */ diff --git a/include/linux/mtd/nand-ecc-sw-hamming.h b/include/linux/mtd/nand-ecc-sw-hamming.h new file mode 100644 index 0000000000..c6c71894c5 --- /dev/null +++ b/include/linux/mtd/nand-ecc-sw-hamming.h @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2000-2010 Steven J. Hill <sjhill@realitydiluted.com> + * David Woodhouse <dwmw2@infradead.org> + * Thomas Gleixner <tglx@linutronix.de> + * + * This file is the header for the NAND Hamming ECC implementation. + */ + +#ifndef __MTD_NAND_ECC_SW_HAMMING_H__ +#define __MTD_NAND_ECC_SW_HAMMING_H__ + +#include <linux/mtd/nand.h> + +/** + * struct nand_ecc_sw_hamming_conf - private software Hamming ECC engine structure + * @req_ctx: Save request context and tweak the original request to fit the + * engine needs + * @code_size: Number of bytes needed to store a code (one code per step) + * @calc_buf: Buffer to use when calculating ECC bytes + * @code_buf: Buffer to use when reading (raw) ECC bytes from the chip + * @sm_order: Smart Media special ordering + */ +struct nand_ecc_sw_hamming_conf { + struct nand_ecc_req_tweak_ctx req_ctx; + unsigned int code_size; + u8 *calc_buf; + u8 *code_buf; + unsigned int sm_order; +}; + +#if IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING) + +int nand_ecc_sw_hamming_init_ctx(struct nand_device *nand); +void nand_ecc_sw_hamming_cleanup_ctx(struct nand_device *nand); +int ecc_sw_hamming_calculate(const unsigned char *buf, unsigned int step_size, + unsigned char *code, bool sm_order); +int nand_ecc_sw_hamming_calculate(struct nand_device *nand, + const unsigned char *buf, + unsigned char *code); +int ecc_sw_hamming_correct(unsigned char *buf, unsigned char *read_ecc, + unsigned char *calc_ecc, unsigned int step_size, + bool sm_order); +int nand_ecc_sw_hamming_correct(struct nand_device *nand, unsigned char *buf, + unsigned char *read_ecc, + unsigned char *calc_ecc); + +#else /* !CONFIG_MTD_NAND_ECC_SW_HAMMING */ + +static inline int nand_ecc_sw_hamming_init_ctx(struct nand_device *nand) +{ + return -ENOTSUPP; +} + +static inline void nand_ecc_sw_hamming_cleanup_ctx(struct nand_device *nand) {} + +static inline int ecc_sw_hamming_calculate(const unsigned char *buf, + unsigned int step_size, + unsigned char *code, bool sm_order) +{ + return -ENOTSUPP; +} + +static inline int nand_ecc_sw_hamming_calculate(struct nand_device *nand, + const unsigned char *buf, + unsigned char *code) +{ + return -ENOTSUPP; +} + +static inline int ecc_sw_hamming_correct(unsigned char *buf, + unsigned char *read_ecc, + unsigned char *calc_ecc, + unsigned int step_size, bool sm_order) +{ + return -ENOTSUPP; +} + +static inline int nand_ecc_sw_hamming_correct(struct nand_device *nand, + unsigned char *buf, + unsigned char *read_ecc, + unsigned char *calc_ecc) +{ + return -ENOTSUPP; +} + +#endif /* CONFIG_MTD_NAND_ECC_SW_HAMMING */ + +#endif /* __MTD_NAND_ECC_SW_HAMMING_H__ */ diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 6ce5c1d041..ef2546490d 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -19,8 +19,8 @@ struct nand_device; * is supported now. If you add a chip with bigger oobsize/page * adjust this accordingly. */ -#define NAND_MAX_OOBSIZE 640 -#define NAND_MAX_PAGESIZE 8192 +#define NAND_MAX_OOBSIZE 640 +#define NAND_MAX_PAGESIZE 8192 /** * struct nand_memory_organization - Memory organization structure @@ -91,7 +91,18 @@ struct nand_pos { }; /** + * enum nand_page_io_req_type - Direction of an I/O request + * @NAND_PAGE_READ: from the chip, to the controller + * @NAND_PAGE_WRITE: from the controller, to the chip + */ +enum nand_page_io_req_type { + NAND_PAGE_READ = 0, + NAND_PAGE_WRITE, +}; + +/** * struct nand_page_io_req - NAND I/O request object + * @type: the type of page I/O: read or write * @pos: the position this I/O request is targeting * @dataoffs: the offset within the page * @datalen: number of data bytes to read from/write to this page @@ -107,6 +118,7 @@ struct nand_pos { * specific commands/operations. */ struct nand_page_io_req { + enum nand_page_io_req_type type; struct nand_pos pos; unsigned int dataoffs; unsigned int datalen; @@ -123,18 +135,77 @@ struct nand_page_io_req { int mode; }; +const struct mtd_ooblayout_ops *nand_get_small_page_ooblayout(void); +const struct mtd_ooblayout_ops *nand_get_large_page_ooblayout(void); +const struct mtd_ooblayout_ops *nand_get_large_page_hamming_ooblayout(void); + +/** + * enum nand_ecc_engine_type - NAND ECC engine type + * @NAND_ECC_ENGINE_TYPE_INVALID: Invalid value + * @NAND_ECC_ENGINE_TYPE_NONE: No ECC correction + * @NAND_ECC_ENGINE_TYPE_SOFT: Software ECC correction + * @NAND_ECC_ENGINE_TYPE_ON_HOST: On host hardware ECC correction + * @NAND_ECC_ENGINE_TYPE_ON_DIE: On chip hardware ECC correction + */ +enum nand_ecc_engine_type { + NAND_ECC_ENGINE_TYPE_INVALID, + NAND_ECC_ENGINE_TYPE_NONE, + NAND_ECC_ENGINE_TYPE_SOFT, + NAND_ECC_ENGINE_TYPE_ON_HOST, + NAND_ECC_ENGINE_TYPE_ON_DIE, +}; + +/** + * enum nand_ecc_placement - NAND ECC bytes placement + * @NAND_ECC_PLACEMENT_UNKNOWN: The actual position of the ECC bytes is unknown + * @NAND_ECC_PLACEMENT_OOB: The ECC bytes are located in the OOB area + * @NAND_ECC_PLACEMENT_INTERLEAVED: Syndrome layout, there are ECC bytes + * interleaved with regular data in the main + * area + */ +enum nand_ecc_placement { + NAND_ECC_PLACEMENT_UNKNOWN, + NAND_ECC_PLACEMENT_OOB, + NAND_ECC_PLACEMENT_INTERLEAVED, +}; + +/** + * enum nand_ecc_algo - NAND ECC algorithm + * @NAND_ECC_ALGO_UNKNOWN: Unknown algorithm + * @NAND_ECC_ALGO_HAMMING: Hamming algorithm + * @NAND_ECC_ALGO_BCH: Bose-Chaudhuri-Hocquenghem algorithm + * @NAND_ECC_ALGO_RS: Reed-Solomon algorithm + */ +enum nand_ecc_algo { + NAND_ECC_ALGO_UNKNOWN, + NAND_ECC_ALGO_HAMMING, + NAND_ECC_ALGO_BCH, + NAND_ECC_ALGO_RS, +}; + /** * struct nand_ecc_props - NAND ECC properties + * @engine_type: ECC engine type + * @placement: OOB placement (if relevant) + * @algo: ECC algorithm (if relevant) * @strength: ECC strength * @step_size: Number of bytes per step + * @flags: Misc properties */ struct nand_ecc_props { + enum nand_ecc_engine_type engine_type; + enum nand_ecc_placement placement; + enum nand_ecc_algo algo; unsigned int strength; unsigned int step_size; + unsigned int flags; }; #define NAND_ECCREQ(str, stp) { .strength = (str), .step_size = (stp) } +/* NAND ECC misc flags */ +#define NAND_ECC_MAXIMIZE_STRENGTH BIT(0) + /** * struct nand_bbt - bad block table object * @cache: in memory BBT cache @@ -166,18 +237,177 @@ struct nand_ops { }; /** + * struct nand_ecc_context - Context for the ECC engine + * @conf: basic ECC engine parameters + * @nsteps: number of ECC steps + * @total: total number of bytes used for storing ECC codes, this is used by + * generic OOB layouts + * @priv: ECC engine driver private data + */ +struct nand_ecc_context { + struct nand_ecc_props conf; + unsigned int nsteps; + unsigned int total; + void *priv; +}; + +/** + * struct nand_ecc_engine_ops - ECC engine operations + * @init_ctx: given a desired user configuration for the pointed NAND device, + * requests the ECC engine driver to setup a configuration with + * values it supports. + * @cleanup_ctx: clean the context initialized by @init_ctx. + * @prepare_io_req: is called before reading/writing a page to prepare the I/O + * request to be performed with ECC correction. + * @finish_io_req: is called after reading/writing a page to terminate the I/O + * request and ensure proper ECC correction. + */ +struct nand_ecc_engine_ops { + int (*init_ctx)(struct nand_device *nand); + void (*cleanup_ctx)(struct nand_device *nand); + int (*prepare_io_req)(struct nand_device *nand, + struct nand_page_io_req *req); + int (*finish_io_req)(struct nand_device *nand, + struct nand_page_io_req *req); +}; + +/** + * enum nand_ecc_engine_integration - How the NAND ECC engine is integrated + * @NAND_ECC_ENGINE_INTEGRATION_INVALID: Invalid value + * @NAND_ECC_ENGINE_INTEGRATION_PIPELINED: Pipelined engine, performs on-the-fly + * correction, does not need to copy + * data around + * @NAND_ECC_ENGINE_INTEGRATION_EXTERNAL: External engine, needs to bring the + * data into its own area before use + */ +enum nand_ecc_engine_integration { + NAND_ECC_ENGINE_INTEGRATION_INVALID, + NAND_ECC_ENGINE_INTEGRATION_PIPELINED, + NAND_ECC_ENGINE_INTEGRATION_EXTERNAL, +}; + +/** + * struct nand_ecc_engine - ECC engine abstraction for NAND devices + * @dev: Host device + * @node: Private field for registration time + * @ops: ECC engine operations + * @integration: How the engine is integrated with the host + * (only relevant on %NAND_ECC_ENGINE_TYPE_ON_HOST engines) + * @priv: Private data + */ +struct nand_ecc_engine { + struct device *dev; + struct list_head node; + struct nand_ecc_engine_ops *ops; + enum nand_ecc_engine_integration integration; + void *priv; +}; + +void of_get_nand_ecc_user_config(struct nand_device *nand); +int nand_ecc_init_ctx(struct nand_device *nand); +void nand_ecc_cleanup_ctx(struct nand_device *nand); +int nand_ecc_prepare_io_req(struct nand_device *nand, + struct nand_page_io_req *req); +int nand_ecc_finish_io_req(struct nand_device *nand, + struct nand_page_io_req *req); +bool nand_ecc_is_strong_enough(struct nand_device *nand); + +#if IS_REACHABLE(CONFIG_MTD_NAND_CORE) +int nand_ecc_register_on_host_hw_engine(struct nand_ecc_engine *engine); +int nand_ecc_unregister_on_host_hw_engine(struct nand_ecc_engine *engine); +#else +static inline int +nand_ecc_register_on_host_hw_engine(struct nand_ecc_engine *engine) +{ + return -ENOTSUPP; +} +static inline int +nand_ecc_unregister_on_host_hw_engine(struct nand_ecc_engine *engine) +{ + return -ENOTSUPP; +} +#endif + +struct nand_ecc_engine *nand_ecc_get_sw_engine(struct nand_device *nand); +struct nand_ecc_engine *nand_ecc_get_on_die_hw_engine(struct nand_device *nand); +struct nand_ecc_engine *nand_ecc_get_on_host_hw_engine(struct nand_device *nand); +void nand_ecc_put_on_host_hw_engine(struct nand_device *nand); +struct device *nand_ecc_get_engine_dev(struct device *host); + +#if IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING) +struct nand_ecc_engine *nand_ecc_sw_hamming_get_engine(void); +#else +static inline struct nand_ecc_engine *nand_ecc_sw_hamming_get_engine(void) +{ + return NULL; +} +#endif /* CONFIG_MTD_NAND_ECC_SW_HAMMING */ + +#if IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_BCH) +struct nand_ecc_engine *nand_ecc_sw_bch_get_engine(void); +#else +static inline struct nand_ecc_engine *nand_ecc_sw_bch_get_engine(void) +{ + return NULL; +} +#endif /* CONFIG_MTD_NAND_ECC_SW_BCH */ + +/** + * struct nand_ecc_req_tweak_ctx - Help for automatically tweaking requests + * @orig_req: Pointer to the original IO request + * @nand: Related NAND device, to have access to its memory organization + * @page_buffer_size: Real size of the page buffer to use (can be set by the + * user before the tweaking mechanism initialization) + * @oob_buffer_size: Real size of the OOB buffer to use (can be set by the + * user before the tweaking mechanism initialization) + * @spare_databuf: Data bounce buffer + * @spare_oobbuf: OOB bounce buffer + * @bounce_data: Flag indicating a data bounce buffer is used + * @bounce_oob: Flag indicating an OOB bounce buffer is used + */ +struct nand_ecc_req_tweak_ctx { + struct nand_page_io_req orig_req; + struct nand_device *nand; + unsigned int page_buffer_size; + unsigned int oob_buffer_size; + void *spare_databuf; + void *spare_oobbuf; + bool bounce_data; + bool bounce_oob; +}; + +int nand_ecc_init_req_tweaking(struct nand_ecc_req_tweak_ctx *ctx, + struct nand_device *nand); +void nand_ecc_cleanup_req_tweaking(struct nand_ecc_req_tweak_ctx *ctx); +void nand_ecc_tweak_req(struct nand_ecc_req_tweak_ctx *ctx, + struct nand_page_io_req *req); +void nand_ecc_restore_req(struct nand_ecc_req_tweak_ctx *ctx, + struct nand_page_io_req *req); + +/** * struct nand_ecc - Information relative to the ECC + * @defaults: Default values, depend on the underlying subsystem * @requirements: ECC requirements from the NAND chip perspective + * @user_conf: User desires in terms of ECC parameters + * @ctx: ECC context for the ECC engine, derived from the device @requirements + * the @user_conf and the @defaults + * @ondie_engine: On-die ECC engine reference, if any + * @engine: ECC engine actually bound */ struct nand_ecc { + struct nand_ecc_props defaults; struct nand_ecc_props requirements; + struct nand_ecc_props user_conf; + struct nand_ecc_context ctx; + struct nand_ecc_engine *ondie_engine; + struct nand_ecc_engine *engine; }; /** * struct nand_device - NAND device * @mtd: MTD instance attached to the NAND device * @memorg: memory layout - * @ecc: ECC information + * @ecc: NAND ECC object attached to the NAND device * @rowconv: position to row address converter * @bbt: bad block table info * @ops: NAND operations attached to the NAND device @@ -185,7 +415,7 @@ struct nand_ecc { * Generic NAND object. Specialized NAND layers (raw NAND, SPI NAND, OneNAND) * should declare their own NAND object embedding a nand_device struct (that's * how inheritance is done). - * struct_nand_device->memorg and struct_nand_device->ecc.requirement should + * struct_nand_device->memorg and struct_nand_device->ecc.requirements should * be filled at device detection time to reflect the NAND device * capabilities/requirements. Once this is done nanddev_init() can be called. * It will take care of converting NAND information into MTD ones, which means @@ -399,9 +629,35 @@ nanddev_get_memorg(struct nand_device *nand) return &nand->memorg; } -int nanddev_init(struct nand_device *nand, const struct nand_ops *ops, - struct module *owner); -void nanddev_cleanup(struct nand_device *nand); +/** + * nanddev_get_ecc_conf() - Extract the ECC configuration from a NAND device + * @nand: NAND device + */ +static inline const struct nand_ecc_props * +nanddev_get_ecc_conf(struct nand_device *nand) +{ + return &nand->ecc.ctx.conf; +} + +/** + * nanddev_get_ecc_nsteps() - Extract the number of ECC steps + * @nand: NAND device + */ +static inline unsigned int +nanddev_get_ecc_nsteps(struct nand_device *nand) +{ + return nand->ecc.ctx.nsteps; +} + +/** + * nanddev_get_ecc_bytes_per_step() - Extract the number of ECC bytes per step + * @nand: NAND device + */ +static inline unsigned int +nanddev_get_ecc_bytes_per_step(struct nand_device *nand) +{ + return nand->ecc.ctx.total / nand->ecc.ctx.nsteps; +} /** * nanddev_get_ecc_requirements() - Extract the ECC requirements from a NAND @@ -415,6 +671,47 @@ nanddev_get_ecc_requirements(struct nand_device *nand) } /** + * nanddev_set_ecc_requirements() - Assign the ECC requirements of a NAND + * device + * @nand: NAND device + * @reqs: Requirements + */ +static inline void +nanddev_set_ecc_requirements(struct nand_device *nand, + const struct nand_ecc_props *reqs) +{ + nand->ecc.requirements = *reqs; +} + +int nanddev_init(struct nand_device *nand, const struct nand_ops *ops, + struct module *owner); +void nanddev_cleanup(struct nand_device *nand); + +/** + * nanddev_set_of_node() - Attach a DT node to a NAND device + * @nand: NAND device + * @np: DT node + * + * Attach a DT node to a NAND device. + */ +static inline void nanddev_set_of_node(struct nand_device *nand, + struct device_node *np) +{ + mtd_set_of_node(&nand->mtd, np); +} + +/** + * nanddev_get_of_node() - Retrieve the DT node attached to a NAND device + * @nand: NAND device + * + * Return: the DT node attached to @nand. + */ +static inline struct device_node *nanddev_get_of_node(struct nand_device *nand) +{ + return mtd_get_of_node(&nand->mtd); +} + +/** * nanddev_offs_to_pos() - Convert an absolute NAND offset into a NAND position * @nand: NAND device * @offs: absolute NAND offset (usually passed by the MTD layer) @@ -597,11 +894,13 @@ static inline void nanddev_pos_next_page(struct nand_device *nand, * layer. */ static inline void nanddev_io_iter_init(struct nand_device *nand, + enum nand_page_io_req_type reqtype, loff_t offs, struct mtd_oob_ops *req, struct nand_io_iter *iter) { struct mtd_info *mtd = nanddev_to_mtd(nand); + iter->req.type = reqtype; iter->req.mode = req->mode; iter->req.dataoffs = nanddev_offs_to_pos(nand, offs, &iter->req.pos); iter->req.ooboffs = req->ooboffs; @@ -671,16 +970,24 @@ static inline bool nanddev_io_iter_end(struct nand_device *nand, * * Should be used for iterate over pages that are contained in an MTD request. */ -#define nanddev_io_for_each_page(nand, start, req, iter) \ - for (nanddev_io_iter_init(nand, start, req, iter); \ +#define nanddev_io_for_each_page(nand, type, start, req, iter) \ + for (nanddev_io_iter_init(nand, type, start, req, iter); \ !nanddev_io_iter_end(nand, iter); \ nanddev_io_iter_next_page(nand, iter)) bool nanddev_isbad(struct nand_device *nand, const struct nand_pos *pos); bool nanddev_isreserved(struct nand_device *nand, const struct nand_pos *pos); -int nanddev_erase(struct nand_device *nand, const struct nand_pos *pos); int nanddev_markbad(struct nand_device *nand, const struct nand_pos *pos); +/* ECC related functions */ +int nanddev_ecc_engine_init(struct nand_device *nand); +void nanddev_ecc_engine_cleanup(struct nand_device *nand); + +static inline void *nand_to_ecc_ctx(struct nand_device *nand) +{ + return nand->ecc.ctx.priv; +} + /* BBT related functions */ enum nand_bbt_block_status { NAND_BBT_BLOCK_STATUS_UNKNOWN, diff --git a/include/linux/mtd/onfi.h b/include/linux/mtd/onfi.h index 339ac79856..55ab2e4d62 100644 --- a/include/linux/mtd/onfi.h +++ b/include/linux/mtd/onfi.h @@ -11,6 +11,7 @@ #define __LINUX_MTD_ONFI_H #include <linux/types.h> +#include <linux/bitfield.h> /* ONFI version bits */ #define ONFI_VERSION_1_0 BIT(1) @@ -24,17 +25,22 @@ #define ONFI_VERSION_4_0 BIT(9) /* ONFI features */ -#define ONFI_FEATURE_16_BIT_BUS (1 << 0) -#define ONFI_FEATURE_EXT_PARAM_PAGE (1 << 7) +#define ONFI_FEATURE_16_BIT_BUS BIT(0) +#define ONFI_FEATURE_NV_DDR BIT(5) +#define ONFI_FEATURE_EXT_PARAM_PAGE BIT(7) /* ONFI timing mode, used in both asynchronous and synchronous mode */ -#define ONFI_TIMING_MODE_0 (1 << 0) -#define ONFI_TIMING_MODE_1 (1 << 1) -#define ONFI_TIMING_MODE_2 (1 << 2) -#define ONFI_TIMING_MODE_3 (1 << 3) -#define ONFI_TIMING_MODE_4 (1 << 4) -#define ONFI_TIMING_MODE_5 (1 << 5) -#define ONFI_TIMING_MODE_UNKNOWN (1 << 6) +#define ONFI_DATA_INTERFACE_SDR 0 +#define ONFI_DATA_INTERFACE_NVDDR BIT(4) +#define ONFI_DATA_INTERFACE_NVDDR2 BIT(5) +#define ONFI_TIMING_MODE_0 BIT(0) +#define ONFI_TIMING_MODE_1 BIT(1) +#define ONFI_TIMING_MODE_2 BIT(2) +#define ONFI_TIMING_MODE_3 BIT(3) +#define ONFI_TIMING_MODE_4 BIT(4) +#define ONFI_TIMING_MODE_5 BIT(5) +#define ONFI_TIMING_MODE_UNKNOWN BIT(6) +#define ONFI_TIMING_MODE_PARAM(x) FIELD_GET(GENMASK(3, 0), (x)) /* ONFI feature number/address */ #define ONFI_FEATURE_NUMBER 256 @@ -49,7 +55,8 @@ #define ONFI_SUBFEATURE_PARAM_LEN 4 /* ONFI optional commands SET/GET FEATURES supported? */ -#define ONFI_OPT_CMD_SET_GET_FEATURES (1 << 2) +#define ONFI_OPT_CMD_READ_CACHE BIT(1) +#define ONFI_OPT_CMD_SET_GET_FEATURES BIT(2) struct nand_onfi_params { /* rev info and features block */ @@ -93,14 +100,15 @@ struct nand_onfi_params { /* electrical parameter block */ u8 io_pin_capacitance_max; - __le16 async_timing_mode; + __le16 sdr_timing_modes; __le16 program_cache_timing_mode; __le16 t_prog; __le16 t_bers; __le16 t_r; __le16 t_ccs; - __le16 src_sync_timing_mode; - u8 src_ssync_features; + u8 nvddr_timing_modes; + u8 nvddr2_timing_modes; + u8 nvddr_nvddr2_features; __le16 clk_pin_capacitance_typ; __le16 io_pin_capacitance_typ; __le16 input_pin_capacitance_typ; @@ -160,7 +168,9 @@ struct onfi_ext_param_page { * @tBERS: Block erase time * @tR: Page read time * @tCCS: Change column setup time - * @async_timing_mode: Supported asynchronous timing mode + * @fast_tCAD: Command/Address/Data slow or fast delay (NV-DDR only) + * @sdr_timing_modes: Supported asynchronous/SDR timing modes + * @nvddr_timing_modes: Supported source synchronous/NV-DDR timing modes * @vendor_revision: Vendor specific revision number * @vendor: Vendor specific data */ @@ -170,7 +180,9 @@ struct onfi_params { u16 tBERS; u16 tR; u16 tCCS; - u16 async_timing_mode; + bool fast_tCAD; + u16 sdr_timing_modes; + u16 nvddr_timing_modes; u16 vendor_revision; u8 vendor[88]; }; diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 54a788cc18..585397aa9a 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -14,17 +14,17 @@ #define __LINUX_MTD_RAWNAND_H #include <linux/mtd/mtd.h> +#include <linux/mtd/nand.h> #include <linux/mtd/flashchip.h> #include <linux/mtd/bbm.h> #include <linux/mtd/jedec.h> -#include <linux/mtd/nand.h> #include <linux/mtd/onfi.h> -#include <linux/bitmap.h> #include <linux/mutex.h> #include <linux/types.h> #include <common.h> struct nand_chip; +struct gpio_desc; /* The maximum number of NAND chips in an array */ #define NAND_MAX_CHIPS 8 @@ -67,6 +67,8 @@ struct nand_chip; /* Extended commands for large page devices */ #define NAND_CMD_READSTART 0x30 +#define NAND_CMD_READCACHESEQ 0x31 +#define NAND_CMD_READCACHEEND 0x3f #define NAND_CMD_RNDOUTSTART 0xE0 #define NAND_CMD_CACHEDPROG 0x15 @@ -84,38 +86,14 @@ struct nand_chip; /* * Constants for ECC_MODES */ -enum nand_ecc_mode { +enum nand_ecc_legacy_mode { NAND_ECC_INVALID, NAND_ECC_NONE, NAND_ECC_SOFT, + NAND_ECC_SOFT_BCH, NAND_ECC_HW, NAND_ECC_HW_SYNDROME, NAND_ECC_ON_DIE, - NAND_ECC_HW_OOB_FIRST, - NAND_ECC_SOFT_BCH -}; - -/** - * enum nand_ecc_engine_type - NAND ECC engine type - * @NAND_ECC_ENGINE_TYPE_INVALID: Invalid value - * @NAND_ECC_ENGINE_TYPE_NONE: No ECC correction - * @NAND_ECC_ENGINE_TYPE_SOFT: Software ECC correction - * @NAND_ECC_ENGINE_TYPE_ON_HOST: On host hardware ECC correction - * @NAND_ECC_ENGINE_TYPE_ON_DIE: On chip hardware ECC correction - */ -enum nand_ecc_engine_type { - NAND_ECC_ENGINE_TYPE_INVALID, - NAND_ECC_ENGINE_TYPE_NONE, - NAND_ECC_ENGINE_TYPE_SOFT, - NAND_ECC_ENGINE_TYPE_ON_HOST, - NAND_ECC_ENGINE_TYPE_ON_DIE, -}; - -enum nand_ecc_algo { - NAND_ECC_ALGO_UNKNOWN, - NAND_ECC_ALGO_HAMMING, - NAND_ECC_ALGO_BCH, - NAND_ECC_ALGO_RS, }; /* @@ -135,7 +113,6 @@ enum nand_ecc_algo { * pages and you want to rely on the default implementation. */ #define NAND_ECC_GENERIC_ERASED_CHECK BIT(0) -#define NAND_ECC_MAXIMIZE BIT(1) /* * Option constants for bizarre disfunctionality and real @@ -261,6 +238,7 @@ enum nand_ecc_algo { * struct nand_parameters - NAND generic parameters from the parameter page * @model: Model name * @supports_set_get_features: The NAND chip supports setting/getting features + * @supports_read_cache: The NAND chip supports read cache operations * @set_feature_list: Bitmap of features that can be set * @get_feature_list: Bitmap of features that can be get * @onfi: ONFI specific parameters @@ -269,6 +247,7 @@ struct nand_parameters { /* Generic parameters */ const char *model; bool supports_set_get_features; + bool supports_read_cache; DECLARE_BITMAP(set_feature_list, ONFI_FEATURE_NUMBER); DECLARE_BITMAP(get_feature_list, ONFI_FEATURE_NUMBER); @@ -330,7 +309,7 @@ static const struct nand_ecc_caps __name = { \ /** * struct nand_ecc_ctrl - Control structure for ECC * @engine_type: ECC engine type - * @mode: ECC mode + * @placement: OOB bytes placement * @algo: ECC algorithm * @steps: number of ECC steps per page * @size: data bytes per ECC step @@ -340,7 +319,6 @@ static const struct nand_ecc_caps __name = { \ * @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) - * @priv: pointer to private ECC control data * @calc_buf: buffer for calculated ECC, size is oobsize. * @code_buf: buffer for ECC read from flash, size is oobsize. * @hwctl: function to control hardware ECC generator. Must only @@ -358,7 +336,7 @@ static const struct nand_ecc_caps __name = { \ * controller and always return contiguous in-band and * out-of-band data even if they're not stored * contiguously on the NAND chip (e.g. - * NAND_ECC_HW_SYNDROME interleaves in-band and + * NAND_ECC_PLACEMENT_INTERLEAVED interleaves in-band and * out-of-band data). * @write_page_raw: function to write a raw page without ECC. This function * should hide the specific layout used by the ECC @@ -366,7 +344,7 @@ static const struct nand_ecc_caps __name = { \ * in-band and out-of-band data. ECC controller is * responsible for doing the appropriate transformations * to adapt to its specific layout (e.g. - * NAND_ECC_HW_SYNDROME interleaves in-band and + * NAND_ECC_PLACEMENT_INTERLEAVED interleaves in-band and * out-of-band data). * @read_page: function to read a page according to the ECC generator * requirements; returns maximum number of bitflips corrected in @@ -383,7 +361,7 @@ static const struct nand_ecc_caps __name = { \ */ struct nand_ecc_ctrl { enum nand_ecc_engine_type engine_type; - enum nand_ecc_mode mode; + enum nand_ecc_placement placement; enum nand_ecc_algo algo; int steps; int size; @@ -393,7 +371,6 @@ struct nand_ecc_ctrl { int prepad; int postpad; unsigned int options; - void *priv; u8 *calc_buf; u8 *code_buf; void (*hwctl)(struct nand_chip *chip, int mode); @@ -426,8 +403,8 @@ struct nand_ecc_ctrl { * This struct defines the timing requirements of a SDR NAND chip. * These information can be found in every NAND datasheets and the timings * meaning are described in the ONFI specifications: - * www.onfi.org/~/media/ONFI/specs/onfi_3_1_spec.pdf (chapter 4.15 Timing - * Parameters) + * https://media-www.micron.com/-/media/client/onfi/specs/onfi_3_1_spec.pdf + * (chapter 4.15 Timing Parameters) * * All these timings are expressed in picoseconds. * @@ -513,11 +490,127 @@ struct nand_sdr_timings { }; /** + * struct nand_nvddr_timings - NV-DDR NAND chip timings + * + * This struct defines the timing requirements of a NV-DDR NAND data interface. + * These information can be found in every NAND datasheets and the timings + * meaning are described in the ONFI specifications: + * https://media-www.micron.com/-/media/client/onfi/specs/onfi_4_1_gold.pdf + * (chapter 4.18.2 NV-DDR) + * + * All these timings are expressed in picoseconds. + * + * @tBERS_max: Block erase time + * @tCCS_min: Change column setup time + * @tPROG_max: Page program time + * @tR_max: Page read time + * @tAC_min: Access window of DQ[7:0] from CLK + * @tAC_max: Access window of DQ[7:0] from CLK + * @tADL_min: ALE to data loading time + * @tCAD_min: Command, Address, Data delay + * @tCAH_min: Command/Address DQ hold time + * @tCALH_min: W/R_n, CLE and ALE hold time + * @tCALS_min: W/R_n, CLE and ALE setup time + * @tCAS_min: Command/address DQ setup time + * @tCEH_min: CE# high hold time + * @tCH_min: CE# hold time + * @tCK_min: Average clock cycle time + * @tCS_min: CE# setup time + * @tDH_min: Data hold time + * @tDQSCK_min: Start of the access window of DQS from CLK + * @tDQSCK_max: End of the access window of DQS from CLK + * @tDQSD_min: Min W/R_n low to DQS/DQ driven by device + * @tDQSD_max: Max W/R_n low to DQS/DQ driven by device + * @tDQSHZ_max: W/R_n high to DQS/DQ tri-state by device + * @tDQSQ_max: DQS-DQ skew, DQS to last DQ valid, per access + * @tDS_min: Data setup time + * @tDSC_min: DQS cycle time + * @tFEAT_max: Busy time for Set Features and Get Features + * @tITC_max: Interface and Timing Mode Change time + * @tQHS_max: Data hold skew factor + * @tRHW_min: Data output cycle to command, address, or data input cycle + * @tRR_min: Ready to RE# low (data only) + * @tRST_max: Device reset time, measured from the falling edge of R/B# to the + * rising edge of R/B#. + * @tWB_max: WE# high to SR[6] low + * @tWHR_min: WE# high to RE# low + * @tWRCK_min: W/R_n low to data output cycle + * @tWW_min: WP# transition to WE# low + */ +struct nand_nvddr_timings { + u64 tBERS_max; + u32 tCCS_min; + u64 tPROG_max; + u64 tR_max; + u32 tAC_min; + u32 tAC_max; + u32 tADL_min; + u32 tCAD_min; + u32 tCAH_min; + u32 tCALH_min; + u32 tCALS_min; + u32 tCAS_min; + u32 tCEH_min; + u32 tCH_min; + u32 tCK_min; + u32 tCS_min; + u32 tDH_min; + u32 tDQSCK_min; + u32 tDQSCK_max; + u32 tDQSD_min; + u32 tDQSD_max; + u32 tDQSHZ_max; + u32 tDQSQ_max; + u32 tDS_min; + u32 tDSC_min; + u32 tFEAT_max; + u32 tITC_max; + u32 tQHS_max; + u32 tRHW_min; + u32 tRR_min; + u32 tRST_max; + u32 tWB_max; + u32 tWHR_min; + u32 tWRCK_min; + u32 tWW_min; +}; + +/* + * While timings related to the data interface itself are mostly different + * between SDR and NV-DDR, timings related to the internal chip behavior are + * common. IOW, the following entries which describe the internal delays have + * the same definition and are shared in both SDR and NV-DDR timing structures: + * - tADL_min + * - tBERS_max + * - tCCS_min + * - tFEAT_max + * - tPROG_max + * - tR_max + * - tRR_min + * - tRST_max + * - tWB_max + * + * The below macros return the value of a given timing, no matter the interface. + */ +#define NAND_COMMON_TIMING_PS(conf, timing_name) \ + nand_interface_is_sdr(conf) ? \ + nand_get_sdr_timings(conf)->timing_name : \ + nand_get_nvddr_timings(conf)->timing_name + +#define NAND_COMMON_TIMING_MS(conf, timing_name) \ + PSEC_TO_MSEC(NAND_COMMON_TIMING_PS((conf), timing_name)) + +#define NAND_COMMON_TIMING_NS(conf, timing_name) \ + PSEC_TO_NSEC(NAND_COMMON_TIMING_PS((conf), timing_name)) + +/** * enum nand_interface_type - NAND interface type * @NAND_SDR_IFACE: Single Data Rate interface + * @NAND_NVDDR_IFACE: Double Data Rate interface */ enum nand_interface_type { NAND_SDR_IFACE, + NAND_NVDDR_IFACE, }; /** @@ -526,6 +619,7 @@ enum nand_interface_type { * @timings: The timing information * @timings.mode: Timing mode as defined in the specification * @timings.sdr: Use it when @type is %NAND_SDR_IFACE. + * @timings.nvddr: Use it when @type is %NAND_NVDDR_IFACE. */ struct nand_interface_config { enum nand_interface_type type; @@ -533,6 +627,7 @@ struct nand_interface_config { unsigned int mode; union { struct nand_sdr_timings sdr; + struct nand_nvddr_timings nvddr; }; } timings; }; @@ -547,6 +642,15 @@ static bool nand_interface_is_sdr(const struct nand_interface_config *conf) } /** + * nand_interface_is_nvddr - get the interface type + * @conf: The data interface + */ +static bool nand_interface_is_nvddr(const struct nand_interface_config *conf) +{ + return conf->type == NAND_NVDDR_IFACE; +} + +/** * nand_get_sdr_timings - get SDR timing from data interface * @conf: The data interface */ @@ -560,6 +664,19 @@ nand_get_sdr_timings(const struct nand_interface_config *conf) } /** + * nand_get_nvddr_timings - get NV-DDR timing from data interface + * @conf: The data interface + */ +static inline const struct nand_nvddr_timings * +nand_get_nvddr_timings(const struct nand_interface_config *conf) +{ + if (!nand_interface_is_nvddr(conf)) + return ERR_PTR(-EINVAL); + + return &conf->timings.nvddr; +} + +/** * struct nand_op_cmd_instr - Definition of a command instruction * @opcode: the command to issue in one cycle */ @@ -899,6 +1016,8 @@ struct nand_op_parser { /** * struct nand_operation - NAND operation descriptor * @cs: the CS line to select for this NAND operation + * @deassert_wp: set to true when the operation requires the WP pin to be + * de-asserted (ERASE, PROG, ...) * @instrs: array of instructions to execute * @ninstrs: length of the @instrs array * @@ -906,6 +1025,7 @@ struct nand_op_parser { */ struct nand_operation { unsigned int cs; + bool deassert_wp; const struct nand_op_instr *instrs; unsigned int ninstrs; }; @@ -917,6 +1037,14 @@ struct nand_operation { .ninstrs = ARRAY_SIZE(_instrs), \ } +#define NAND_DESTRUCTIVE_OPERATION(_cs, _instrs) \ + { \ + .cs = _cs, \ + .deassert_wp = true, \ + .instrs = _instrs, \ + .ninstrs = ARRAY_SIZE(_instrs), \ + } + int nand_op_parser_exec_op(struct nand_chip *chip, const struct nand_op_parser *parser, const struct nand_operation *op, bool check_only); @@ -973,7 +1101,7 @@ static inline void nand_op_trace(const char *prefix, * @exec_op: controller specific method to execute NAND operations. * This method replaces chip->legacy.cmdfunc(), * chip->legacy.{read,write}_{buf,byte,word}(), - * chip->legacy.dev_ready() and chip->legacy.waifunc(). + * chip->legacy.dev_ready() and chip->legacy.waitfunc(). * @setup_interface: setup the data interface and timing. If chipnr is set to * %NAND_DATA_IFACE_CHECK_ONLY this means the configuration * should not be applied but only checked. @@ -994,10 +1122,22 @@ struct nand_controller_ops { * * @lock: lock used to serialize accesses to the NAND controller * @ops: NAND controller operations. + * @supported_op: NAND controller known-to-be-supported operations, + * only writable by the core after initial checking. + * @supported_op.data_only_read: The controller supports reading more data from + * the bus without restarting an entire read operation nor + * changing the column. + * @supported_op.cont_read: The controller supports sequential cache reads. + * @controller_wp: the controller is in charge of handling the WP pin. */ struct nand_controller { struct mutex lock; const struct nand_controller_ops *ops; + struct { + unsigned int data_only_read: 1; + unsigned int cont_read: 1; + } supported_op; + bool controller_wp; }; static inline void nand_controller_init(struct nand_controller *nfc) @@ -1087,6 +1227,16 @@ struct nand_manufacturer { }; /** + * struct nand_secure_region - NAND secure region structure + * @offset: Offset of the start of the secure region + * @size: Size of the secure region + */ +struct nand_secure_region { + u64 offset; + u64 size; +}; + +/** * struct nand_chip - NAND Private Flash Chip Data * @base: Inherit from the generic NAND device * @id: Holds NAND ID @@ -1131,11 +1281,19 @@ struct nand_manufacturer { * @lock: Lock protecting the suspended field. Also used to serialize accesses * to the NAND device * @suspended: Set to 1 when the device is suspended, 0 when it's not + * @resume_wq: wait queue to sleep if rawnand is in suspended state. * @cur_cs: Currently selected target. -1 means no target selected, otherwise we * should always have cur_cs >= 0 && cur_cs < nanddev_ntargets(). * NAND Controller drivers should not modify this value, but they're * allowed to read it. * @read_retries: The number of read retry modes supported + * @secure_regions: Structure containing the secure regions info + * @nr_secure_regions: Number of secure regions + * @cont_read: Sequential page read internals + * @cont_read.ongoing: Whether a continuous read is ongoing or not + * @cont_read.first_page: Start of the continuous read operation + * @cont_read.pause_page: End of the current sequential cache read operation + * @cont_read.last_page: End of the continuous read operation * @controller: The hardware controller structure which is shared among multiple * independent devices * @ecc: The ECC controller structure @@ -1185,6 +1343,14 @@ struct nand_chip { unsigned int suspended : 1; int cur_cs; int read_retries; + struct nand_secure_region *secure_regions; + u8 nr_secure_regions; + struct { + bool ongoing; + unsigned int first_page; + unsigned int pause_page; + unsigned int last_page; + } cont_read; /* Externals */ struct nand_controller *controller; @@ -1195,9 +1361,6 @@ struct nand_chip { unsigned int bbt_type; }; -const struct mtd_ooblayout_ops *nand_get_small_page_ooblayout(void); -const struct mtd_ooblayout_ops *nand_get_large_page_ooblayout(void); - static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd) { return container_of(mtd, struct nand_chip, base.mtd); @@ -1340,7 +1503,8 @@ static inline bool nand_is_slc(struct nand_chip *chip) } /** - * Check if the opcode's address should be sent only on the lower 8 bits + * nand_opcode_8bits - Check if the opcode's address should be sent only on the + * lower 8 bits * @command: opcode to check */ static inline int nand_opcode_8bits(unsigned int command) @@ -1357,6 +1521,20 @@ static inline int nand_opcode_8bits(unsigned int command) return 0; } +int rawnand_sw_hamming_init(struct nand_chip *chip); +int rawnand_sw_hamming_calculate(struct nand_chip *chip, + const unsigned char *buf, + unsigned char *code); +int rawnand_sw_hamming_correct(struct nand_chip *chip, + unsigned char *buf, + unsigned char *read_ecc, + unsigned char *calc_ecc); +void rawnand_sw_hamming_cleanup(struct nand_chip *chip); +int rawnand_sw_bch_init(struct nand_chip *chip); +int rawnand_sw_bch_correct(struct nand_chip *chip, unsigned char *buf, + unsigned char *read_ecc, unsigned char *calc_ecc); +void rawnand_sw_bch_cleanup(struct nand_chip *chip); + int nand_check_erased_ecc_chunk(void *data, int datalen, void *ecc, int ecclen, void *extraoob, int extraooblen, @@ -1395,6 +1573,7 @@ int nand_reset_op(struct nand_chip *chip); int nand_readid_op(struct nand_chip *chip, u8 addr, void *buf, unsigned int len); int nand_status_op(struct nand_chip *chip, u8 *status); +int nand_exit_status_op(struct nand_chip *chip); int nand_erase_op(struct nand_chip *chip, unsigned int eraseblock); int nand_read_page_op(struct nand_chip *chip, unsigned int page, unsigned int offset_in_page, void *buf, unsigned int len); @@ -1417,6 +1596,8 @@ int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len, bool force_8bit, bool check_only); int nand_write_data_op(struct nand_chip *chip, const void *buf, unsigned int len, bool force_8bit); +int nand_read_page_hwecc_oob_first(struct nand_chip *chip, uint8_t *buf, + int oob_required, int page); /* Scan and identify a NAND device */ int nand_scan_with_ids(struct nand_chip *chip, unsigned int max_chips, @@ -1436,14 +1617,12 @@ void nand_wait_ready(struct nand_chip *chip); */ void nand_cleanup(struct nand_chip *chip); -struct gpio_desc; - /* * External helper for controller drivers that have to implement the WAITRDY * instruction and have no physical pin to check it. */ int nand_soft_waitrdy(struct nand_chip *chip, unsigned long timeout_ms); -int nand_gpio_waitrdy(struct nand_chip *chip, struct gpio_desc *gpio, +int nand_gpio_waitrdy(struct nand_chip *chip, struct gpio_desc *gpiod, unsigned long timeout_ms); /* Select/deselect a NAND target. */ @@ -1475,6 +1654,10 @@ static inline void *nand_get_data_buf(struct nand_chip *chip) return chip->data_buf; } +/* Parse the gpio-cs property */ +int rawnand_dt_parse_gpio_cs(struct device *dev, struct gpio_desc ***cs_array, + unsigned int *ncs_array); + int nand_scan_ident(struct nand_chip *chip, unsigned int max_chips, struct nand_flash_dev *table); int nand_scan_tail(struct nand_chip *chip); @@ -1486,7 +1669,7 @@ static inline int onfi_get_async_timing_mode(struct nand_chip *chip) { if (!chip->parameters.onfi) return ONFI_TIMING_MODE_UNKNOWN; - return chip->parameters.onfi->async_timing_mode; + return chip->parameters.onfi->sdr_timing_modes; } const struct nand_sdr_timings *onfi_async_timing_mode_to_sdr_timings(int mode); diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 0db192e4d3..8bdaff4ebf 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -3,7 +3,7 @@ #ifndef _LINUX_PAGEMAP_H #define _LINUX_PAGEMAP_H -#include <linux/kernel.h> +#include <linux/align.h> /* * Copyright 1995 Linus Torvalds diff --git a/include/linux/pci.h b/include/linux/pci.h index aa29ff5d17..f6511e0095 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -25,6 +25,7 @@ #include <linux/ioport.h> #include <linux/list.h> #include <linux/compiler.h> +#include <linux/resource_ext.h> #include <driver.h> #include <errno.h> #include <io.h> @@ -139,14 +140,14 @@ enum { PCI_BUS_RESOURCE_MEM_PREF = 2, PCI_BUS_RESOURCE_BUSN = 3, }; + struct pci_bus { struct pci_controller *host; /* associated host controller */ - struct device *parent; - struct pci_bus *parent_bus; /* parent bus */ + struct pci_dev *self; + struct pci_bus *parent; /* Parent bus this bridge is on */ struct list_head node; /* node in list of buses */ struct list_head children; /* list of child buses */ struct list_head devices; /* list of devices on this bus */ - struct resource *resource[PCI_BRIDGE_RESOURCE_NUM]; unsigned char number; /* bus number */ unsigned char primary; /* number of primary bridge */ @@ -184,6 +185,8 @@ struct pci_controller { unsigned long io_offset; unsigned long io_map_base; + struct list_head windows; /* resource_entry */ + unsigned int index; /* Optional access method for writing the bus number */ @@ -277,6 +280,7 @@ int pci_register_device(struct pci_dev *pdev); extern struct list_head pci_root_buses; /* list of all known PCI buses */ +extern void pci_controller_init(struct pci_controller *hose); extern void register_pci_controller(struct pci_controller *hose); int pci_bus_read_config_byte(struct pci_bus *bus, unsigned int devfn, @@ -393,4 +397,31 @@ static inline const struct pci_device_id *pci_match_id(const struct pci_device_i { return NULL; } #endif +/* drivers/pci/bus.c */ +void pci_add_resource_offset(struct list_head *resources, struct resource *res, + resource_size_t offset); +void pci_add_resource(struct list_head *resources, struct resource *res); + +struct pci_controller *pci_find_host_bridge(struct pci_bus *bus); + +struct pci_bus_region { + u64 start; + u64 end; +}; + +void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region, + struct resource *res); +void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res, + struct pci_bus_region *region); + +/* drivers/pci/of.c */ +#ifdef CONFIG_OFDEVICE +int of_pci_bridge_init(struct device *dev, struct pci_controller *bridge); +#else +static inline int of_pci_bridge_init(struct device *dev, struct pci_controller *bridge) +{ + return 0; +} +#endif + #endif /* LINUX_PCI_H */ diff --git a/include/linux/resource_ext.h b/include/linux/resource_ext.h new file mode 100644 index 0000000000..ff0339df56 --- /dev/null +++ b/include/linux/resource_ext.h @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2015, Intel Corporation + * Author: Jiang Liu <jiang.liu@linux.intel.com> + */ +#ifndef _LINUX_RESOURCE_EXT_H +#define _LINUX_RESOURCE_EXT_H +#include <linux/types.h> +#include <linux/list.h> +#include <linux/ioport.h> +#include <linux/slab.h> + +/* Represent resource window for bridge devices */ +struct resource_win { + struct resource res; /* In master (CPU) address space */ + resource_size_t offset; /* Translation offset for bridge */ +}; + +/* + * Common resource list management data structure and interfaces to support + * ACPI, PNP and PCI host bridge etc. + */ +struct resource_entry { + struct list_head node; + struct resource *res; /* In master (CPU) address space */ + resource_size_t offset; /* Translation offset for bridge */ + struct resource __res; /* Default storage for res */ +}; + +extern struct resource_entry * +resource_list_create_entry(struct resource *res, size_t extra_size); +extern void resource_list_free(struct list_head *head); + +static inline void resource_list_add(struct resource_entry *entry, + struct list_head *head) +{ + list_add(&entry->node, head); +} + +static inline void resource_list_add_tail(struct resource_entry *entry, + struct list_head *head) +{ + list_add_tail(&entry->node, head); +} + +static inline void resource_list_del(struct resource_entry *entry) +{ + list_del(&entry->node); +} + +static inline void resource_list_free_entry(struct resource_entry *entry) +{ + kfree(entry); +} + +static inline void +resource_list_destroy_entry(struct resource_entry *entry) +{ + resource_list_del(entry); + resource_list_free_entry(entry); +} + +#define resource_list_for_each_entry(entry, list) \ + list_for_each_entry((entry), (list), node) + +#define resource_list_for_each_entry_safe(entry, tmp, list) \ + list_for_each_entry_safe((entry), (tmp), (list), node) + +static inline struct resource_entry * +resource_list_first_type(struct list_head *list, unsigned long type) +{ + struct resource_entry *entry; + + resource_list_for_each_entry(entry, list) { + if (resource_type(entry->res) == type) + return entry; + } + return NULL; +} + +#endif /* _LINUX_RESOURCE_EXT_H */ diff --git a/include/linux/slab.h b/include/linux/slab.h index dc80808938..eba3593d75 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -3,7 +3,8 @@ #ifndef _LINUX_SLAB_H #define _LINUX_SLAB_H -#include <malloc.h> +#include <dma.h> +#include <linux/overflow.h> #include <linux/string.h> #define SLAB_CONSISTENCY_CHECKS 0 @@ -32,7 +33,7 @@ static inline void *kmalloc(size_t size, gfp_t flags) { - return malloc(size); + return dma_alloc(size); } struct kmem_cache { @@ -58,12 +59,12 @@ struct kmem_cache *kmem_cache_create(const char *name, unsigned int size, static inline void kmem_cache_destroy(struct kmem_cache *cache) { - free(cache); + dma_free(cache); } static inline void kfree(const void *mem) { - free((void *)mem); + dma_free((void *)mem); } static inline void *kmem_cache_alloc(struct kmem_cache *cache, gfp_t flags) @@ -87,7 +88,7 @@ static inline void kmem_cache_free(struct kmem_cache *cache, void *mem) static inline void *kzalloc(size_t size, gfp_t flags) { - return calloc(size, 1); + return dma_zalloc(size); } /** @@ -98,17 +99,12 @@ static inline void *kzalloc(size_t size, gfp_t flags) */ static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags) { - return kmalloc(n * size, flags); + return kmalloc(size_mul(n, size), flags); } static inline void *kcalloc(size_t n, size_t size, gfp_t flags) { - return calloc(n, size); -} - -static inline void *krealloc(void *ptr, size_t size, gfp_t flags) -{ - return realloc(ptr, size); + return dma_zalloc(size_mul(n, size)); } static inline char *kstrdup(const char *str, gfp_t flags) diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index c3ee403abf..cc570657e5 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -521,6 +521,10 @@ extern struct usb_string *usb_gstrings_attach(struct usb_composite_dev *cdev, extern int usb_string_ids_n(struct usb_composite_dev *c, unsigned n); +extern void composite_setup_complete(struct usb_ep *ep, + struct usb_request *req); +extern int composite_queue_setup_request(struct usb_composite_dev *cdev); + extern void composite_disconnect(struct usb_gadget *gadget); extern void composite_reset(struct usb_gadget *gadget); diff --git a/include/mach/imx/devices-imx1.h b/include/mach/imx/devices-imx1.h deleted file mode 100644 index 64c917d714..0000000000 --- a/include/mach/imx/devices-imx1.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include <mach/imx/devices.h> -#include <mach/imx/imx1-regs.h> - -static inline struct device *imx1_add_uart0(void) -{ - return imx_add_uart_imx1((void *)MX1_UART1_BASE_ADDR, 0); -} - -static inline struct device *imx1_add_uart1(void) -{ - return imx_add_uart_imx1((void *)MX1_UART2_BASE_ADDR, 1); -} diff --git a/include/mach/imx/devices-imx21.h b/include/mach/imx/devices-imx21.h deleted file mode 100644 index bcc91276f4..0000000000 --- a/include/mach/imx/devices-imx21.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include <mach/imx/devices.h> -#include <mach/imx/imx21-regs.h> - -static inline struct device *imx21_add_uart0(void) -{ - return imx_add_uart_imx21((void *)MX21_UART1_BASE_ADDR, 0); -} - -static inline struct device *imx21_add_uart1(void) -{ - return imx_add_uart_imx21((void *)MX21_UART2_BASE_ADDR, 1); -} - -static inline struct device *imx21_add_uart2(void) -{ - return imx_add_uart_imx21((void *)MX21_UART2_BASE_ADDR, 2); -} - -static inline struct device *imx21_add_uart3(void) -{ - return imx_add_uart_imx21((void *)MX21_UART2_BASE_ADDR, 3); -} - -static inline struct device *imx21_add_nand(struct imx_nand_platform_data *pdata) -{ - return imx_add_nand((void *)0xDF003000, pdata); -} - -static inline struct device *imx21_add_fb(struct imx_fb_platform_data *pdata) -{ - return imx_add_fb((void *)0x10021000, pdata); -} - diff --git a/include/mach/imx/devices-imx25.h b/include/mach/imx/devices-imx25.h deleted file mode 100644 index 058f2a89a1..0000000000 --- a/include/mach/imx/devices-imx25.h +++ /dev/null @@ -1,84 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include <mach/imx/devices.h> -#include <mach/imx/imx25-regs.h> - -static inline struct device *imx25_add_i2c0(struct i2c_platform_data *pdata) -{ - return imx_add_i2c((void *)MX25_I2C1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx25_add_i2c1(struct i2c_platform_data *pdata) -{ - return imx_add_i2c((void *)MX25_I2C2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx25_add_i2c2(struct i2c_platform_data *pdata) -{ - return imx_add_i2c((void *)MX25_I2C3_BASE_ADDR, 2, pdata); -} - -static inline struct device *imx25_add_spi0(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx35((void *)MX25_CSPI1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx25_add_spi1(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx35((void *)MX25_CSPI2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx25_add_spi2(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx35((void *)MX25_CSPI3_BASE_ADDR, 2, pdata); -} - -static inline struct device *imx25_add_uart0(void) -{ - return imx_add_uart_imx21((void *)MX25_UART1_BASE_ADDR, 0); -} - -static inline struct device *imx25_add_uart1(void) -{ - return imx_add_uart_imx21((void *)MX25_UART2_BASE_ADDR, 1); -} - -static inline struct device *imx25_add_uart2(void) -{ - return imx_add_uart_imx21((void *)MX25_UART3_BASE_ADDR, 2); -} - -static inline struct device *imx25_add_uart3(void) -{ - return imx_add_uart_imx21((void *)MX25_UART4_BASE_ADDR, 3); -} - -static inline struct device *imx25_add_uart4(void) -{ - return imx_add_uart_imx21((void *)MX25_UART5_BASE_ADDR, 4); -} - -static inline struct device *imx25_add_nand(struct imx_nand_platform_data *pdata) -{ - return imx_add_nand((void *)MX25_NFC_BASE_ADDR, pdata); -} - -static inline struct device *imx25_add_fb(struct imx_fb_platform_data *pdata) -{ - return imx_add_fb((void *)MX25_LCDC_BASE_ADDR, pdata); -} - -static inline struct device *imx25_add_fec(struct fec_platform_data *pdata) -{ - return imx_add_fec_imx27((void *)MX25_FEC_BASE_ADDR, pdata); -} - -static inline struct device *imx25_add_mmc0(struct esdhc_platform_data *pdata) -{ - return imx_add_esdhc_imx25((void *)MX25_ESDHC1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx25_add_mmc1(struct esdhc_platform_data *pdata) -{ - return imx_add_esdhc_imx25((void *)MX25_ESDHC2_BASE_ADDR, 1, pdata); -} diff --git a/include/mach/imx/devices-imx27.h b/include/mach/imx/devices-imx27.h deleted file mode 100644 index 28013e3bf5..0000000000 --- a/include/mach/imx/devices-imx27.h +++ /dev/null @@ -1,89 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include <mach/imx/devices.h> -#include <mach/imx/imx27-regs.h> - -static inline struct device *imx27_add_spi0(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx27((void *)MX27_CSPI1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx27_add_spi1(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx27((void *)MX27_CSPI2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx27_add_i2c0(struct i2c_platform_data *pdata) -{ - return imx_add_i2c((void *)MX27_I2C1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx27_add_i2c1(struct i2c_platform_data *pdata) -{ - return imx_add_i2c((void *)MX27_I2C2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx27_add_uart0(void) -{ - return imx_add_uart_imx21((void *)MX27_UART1_BASE_ADDR, 0); -} - -static inline struct device *imx27_add_uart1(void) -{ - return imx_add_uart_imx21((void *)MX27_UART2_BASE_ADDR, 1); -} - -static inline struct device *imx27_add_uart2(void) -{ - return imx_add_uart_imx21((void *)MX27_UART3_BASE_ADDR, 2); -} - -static inline struct device *imx27_add_uart3(void) -{ - return imx_add_uart_imx21((void *)MX27_UART4_BASE_ADDR, 3); -} - -static inline struct device *imx27_add_nand(struct imx_nand_platform_data *pdata) -{ - return imx_add_nand((void *)MX27_NFC_BASE_ADDR, pdata); -} - -static inline struct device *imx27_add_fb(struct imx_fb_platform_data *pdata) -{ - return imx_add_fb((void *)MX27_LCDC_BASE_ADDR, pdata); -} - -static inline struct device *imx27_add_fec(struct fec_platform_data *pdata) -{ - return imx_add_fec_imx27((void *)MX27_FEC_BASE_ADDR, pdata); -} - -static inline struct device *imx27_add_mmc0(void *pdata) -{ - return imx_add_mmc((void *)MX27_SDHC1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx27_add_mmc1(void *pdata) -{ - return imx_add_mmc((void *)MX27_SDHC2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx27_add_mmc2(void *pdata) -{ - return imx_add_mmc((void *)MX27_SDHC3_BASE_ADDR, 2, pdata); -} - -static inline struct device *imx27_add_usbotg(void *pdata) -{ - return imx_add_usb((void *)MX27_USB_OTG_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx27_add_usbh1(void *pdata) -{ - return imx_add_usb((void *)MX27_USB_OTG_BASE_ADDR + 0x200, 1, pdata); -} - -static inline struct device *imx27_add_usbh2(void *pdata) -{ - return imx_add_usb((void *)MX27_USB_OTG_BASE_ADDR + 0x400, 2, pdata); -} diff --git a/include/mach/imx/devices-imx31.h b/include/mach/imx/devices-imx31.h deleted file mode 100644 index 8be3e0d582..0000000000 --- a/include/mach/imx/devices-imx31.h +++ /dev/null @@ -1,94 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include <mach/imx/imx31-regs.h> -#include <mach/imx/devices.h> - -static inline struct device *imx31_add_i2c0(void *pdata) -{ - return imx_add_i2c((void *)MX31_I2C1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx31_add_i2c1(void *pdata) -{ - return imx_add_i2c((void *)MX31_I2C2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx31_add_i2c2(void *pdata) -{ - return imx_add_i2c((void *)MX31_I2C3_BASE_ADDR, 2, pdata); -} - -static inline struct device *imx31_add_spi0(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx35((void *)MX31_CSPI1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx31_add_spi1(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx35((void *)MX31_CSPI2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx31_add_spi2(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx35((void *)MX31_CSPI3_BASE_ADDR, 2, pdata); -} - -static inline struct device *imx31_add_uart0(void) -{ - return imx_add_uart_imx21((void *)MX31_UART1_BASE_ADDR, 0); -} - -static inline struct device *imx31_add_uart1(void) -{ - return imx_add_uart_imx21((void *)MX31_UART2_BASE_ADDR, 1); -} - -static inline struct device *imx31_add_uart2(void) -{ - return imx_add_uart_imx21((void *)MX31_UART3_BASE_ADDR, 2); -} - -static inline struct device *imx31_add_uart3(void) -{ - return imx_add_uart_imx21((void *)MX31_UART4_BASE_ADDR, 3); -} - -static inline struct device *imx31_add_uart4(void) -{ - return imx_add_uart_imx21((void *)MX31_UART5_BASE_ADDR, 4); -} - -static inline struct device *imx31_add_nand(struct imx_nand_platform_data *pdata) -{ - return imx_add_nand((void *)MX31_NFC_BASE_ADDR, pdata); -} - -static inline struct device *imx31_add_fb(struct imx_ipu_fb_platform_data *pdata) -{ - return imx_add_ipufb((void *)MX31_IPU_CTRL_BASE_ADDR, pdata); -} - -static inline struct device *imx31_add_mmc0(void *pdata) -{ - return imx_add_mmc((void *)MX31_SDHC1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx31_add_mmc1(void *pdata) -{ - return imx_add_mmc((void *)MX31_SDHC2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx31_add_usbotg(void *pdata) -{ - return imx_add_usb((void *)MX31_USB_OTG_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx31_add_usbh1(void *pdata) -{ - return imx_add_usb((void *)MX31_USB_OTG_BASE_ADDR + 0x200, 1, pdata); -} - -static inline struct device *imx31_add_usbh2(void *pdata) -{ - return imx_add_usb((void *)MX31_USB_OTG_BASE_ADDR + 0x400, 2, pdata); -} diff --git a/include/mach/imx/devices-imx35.h b/include/mach/imx/devices-imx35.h deleted file mode 100644 index 68d6671592..0000000000 --- a/include/mach/imx/devices-imx35.h +++ /dev/null @@ -1,74 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include <mach/imx/devices.h> -#include <mach/imx/imx35-regs.h> - -static inline struct device *imx35_add_i2c0(struct i2c_platform_data *pdata) -{ - return imx_add_i2c((void *)MX35_I2C1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx35_add_i2c1(struct i2c_platform_data *pdata) -{ - return imx_add_i2c((void *)MX35_I2C2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx35_add_i2c2(struct i2c_platform_data *pdata) -{ - return imx_add_i2c((void *)MX35_I2C3_BASE_ADDR, 2, pdata); -} - -static inline struct device *imx35_add_spi0(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx35((void *)MX35_CSPI1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx35_add_spi(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx35((void *)MX35_CSPI2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx35_add_uart0(void) -{ - return imx_add_uart_imx21((void *)MX35_UART1_BASE_ADDR, 0); -} - -static inline struct device *imx35_add_uart1(void) -{ - return imx_add_uart_imx21((void *)MX35_UART2_BASE_ADDR, 1); -} - -static inline struct device *imx35_add_uart2(void) -{ - return imx_add_uart_imx21((void *)MX35_UART3_BASE_ADDR, 2); -} - -static inline struct device *imx35_add_nand(struct imx_nand_platform_data *pdata) -{ - return imx_add_nand((void *)MX35_NFC_BASE_ADDR, pdata); -} - -static inline struct device *imx35_add_fb(struct imx_ipu_fb_platform_data *pdata) -{ - return imx_add_ipufb((void *)MX35_IPU_CTRL_BASE_ADDR, pdata); -} - -static inline struct device *imx35_add_fec(struct fec_platform_data *pdata) -{ - return imx_add_fec_imx27((void *)MX35_FEC_BASE_ADDR, pdata); -} - -static inline struct device *imx35_add_mmc0(struct esdhc_platform_data *pdata) -{ - return imx_add_esdhc_imx25((void *)MX35_ESDHC1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx35_add_mmc1(struct esdhc_platform_data *pdata) -{ - return imx_add_esdhc_imx25((void *)MX35_ESDHC2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx35_add_mmc2(struct esdhc_platform_data *pdata) -{ - return imx_add_esdhc_imx25((void *)MX35_ESDHC3_BASE_ADDR, 2, pdata); -} diff --git a/include/mach/imx/devices-imx50.h b/include/mach/imx/devices-imx50.h deleted file mode 100644 index ee577d99ec..0000000000 --- a/include/mach/imx/devices-imx50.h +++ /dev/null @@ -1,84 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include <mach/imx/devices.h> -#include <mach/imx/imx50-regs.h> - -static inline struct device *imx50_add_spi0(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx51((void *)MX50_ECSPI1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx50_add_spi1(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx51((void *)MX50_ECSPI2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx50_add_cspi(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx35((void *)MX50_CSPI_BASE_ADDR, 2, pdata); -} - -static inline struct device *imx50_add_i2c0(struct i2c_platform_data *pdata) -{ - return imx_add_i2c((void *)MX50_I2C1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx50_add_i2c1(struct i2c_platform_data *pdata) -{ - return imx_add_i2c((void *)MX50_I2C2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx50_add_i2c2(struct i2c_platform_data *pdata) -{ - return imx_add_i2c((void *)MX50_I2C3_BASE_ADDR, 2, pdata); -} - -static inline struct device *imx50_add_uart0(void) -{ - return imx_add_uart_imx21((void *)MX50_UART1_BASE_ADDR, 0); -} - -static inline struct device *imx50_add_uart1(void) -{ - return imx_add_uart_imx21((void *)MX50_UART2_BASE_ADDR, 1); -} - -static inline struct device *imx50_add_uart2(void) -{ - return imx_add_uart_imx21((void *)MX50_UART3_BASE_ADDR, 2); -} - -static inline struct device *imx50_add_uart3(void) -{ - return imx_add_uart_imx21((void *)MX50_UART4_BASE_ADDR, 3); -} - -static inline struct device *imx50_add_fec(struct fec_platform_data *pdata) -{ - return imx_add_fec_imx27((void *)MX50_FEC_BASE_ADDR, pdata); -} - -static inline struct device *imx50_add_mmc0(struct esdhc_platform_data *pdata) -{ - return imx5_add_esdhc((void *)MX50_ESDHC1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx50_add_mmc1(struct esdhc_platform_data *pdata) -{ - return imx5_add_esdhc((void *)MX50_ESDHC2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx50_add_mmc2(struct esdhc_platform_data *pdata) -{ - return imx5_add_esdhc((void *)MX50_ESDHC3_BASE_ADDR, 2, pdata); -} - -static inline struct device *imx50_add_mmc3(struct esdhc_platform_data *pdata) -{ - return imx5_add_esdhc((void *)MX50_ESDHC4_BASE_ADDR, 3, pdata); -} - -static inline struct device *imx50_add_kpp(struct matrix_keymap_data *pdata) -{ - return imx_add_kpp((void *)MX50_KPP_BASE_ADDR, pdata); -} diff --git a/include/mach/imx/devices-imx51.h b/include/mach/imx/devices-imx51.h deleted file mode 100644 index 34e550d3c8..0000000000 --- a/include/mach/imx/devices-imx51.h +++ /dev/null @@ -1,117 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include <linux/sizes.h> -#include <mach/imx/devices.h> -#include <mach/imx/imx51-regs.h> - -static inline struct device *imx51_add_spi0(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx51((void *)MX51_ECSPI1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx51_add_spi1(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx51((void *)MX51_ECSPI2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx51_add_cspi(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx35((void *)MX51_CSPI_BASE_ADDR, 2, pdata); -} - -static inline struct device *imx51_add_i2c0(struct i2c_platform_data *pdata) -{ - return imx_add_i2c((void *)MX51_I2C1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx51_add_i2c1(struct i2c_platform_data *pdata) -{ - return imx_add_i2c((void *)MX51_I2C2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx51_add_uart0(void) -{ - return imx_add_uart_imx21((void *)MX51_UART1_BASE_ADDR, 0); -} - -static inline struct device *imx51_add_uart1(void) -{ - return imx_add_uart_imx21((void *)MX51_UART2_BASE_ADDR, 1); -} - -static inline struct device *imx51_add_uart2(void) -{ - return imx_add_uart_imx21((void *)MX51_UART3_BASE_ADDR, 2); -} - -static inline struct device *imx51_add_fec(struct fec_platform_data *pdata) -{ - return imx_add_fec_imx27((void *)MX51_MXC_FEC_BASE_ADDR, pdata); -} - -static inline struct device *imx51_add_mmc0(struct esdhc_platform_data *pdata) -{ - return imx_add_esdhc_imx5((void *)MX51_MMC_SDHC1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx51_add_mmc1(struct esdhc_platform_data *pdata) -{ - return imx_add_esdhc_imx5((void *)MX51_MMC_SDHC2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx51_add_mmc2(struct esdhc_platform_data *pdata) -{ - return imx_add_esdhc_imx5((void *)MX51_MMC_SDHC3_BASE_ADDR, 2, pdata); -} - -static inline struct device *imx51_add_nand(struct imx_nand_platform_data *pdata) -{ - struct resource res[] = { - { - .start = MX51_NFC_BASE_ADDR, - .end = MX51_NFC_BASE_ADDR + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, { - .start = MX51_NFC_AXI_BASE_ADDR, - .end = MX51_NFC_AXI_BASE_ADDR + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - }; - struct device *dev = xzalloc(sizeof(*dev)); - - dev->resource = xzalloc(sizeof(struct resource) * ARRAY_SIZE(res)); - memcpy(dev->resource, res, sizeof(struct resource) * ARRAY_SIZE(res)); - dev->num_resources = ARRAY_SIZE(res); - dev_set_name(dev, "imx_nand"); - dev->id = DEVICE_ID_DYNAMIC; - dev->platform_data = pdata; - - platform_device_register(dev); - - return dev; -} - -static inline struct device *imx51_add_kpp(struct matrix_keymap_data *pdata) -{ - return imx_add_kpp((void *)MX51_KPP_BASE_ADDR, pdata); -} - -static inline struct device *imx51_add_pata(void) -{ - return imx_add_pata((void *)MX51_ATA_BASE_ADDR); -} - -static inline struct device *imx51_add_usbotg(void *pdata) -{ - return imx_add_usb((void *)MX51_OTG_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx51_add_usbh1(void *pdata) -{ - return imx_add_usb((void *)MX51_OTG_BASE_ADDR + 0x200, 1, pdata); -} - -static inline struct device *imx51_add_usbh2(void *pdata) -{ - return imx_add_usb((void *)MX51_OTG_BASE_ADDR + 0x400, 2, pdata); -} diff --git a/include/mach/imx/devices-imx53.h b/include/mach/imx/devices-imx53.h deleted file mode 100644 index 080573dfd4..0000000000 --- a/include/mach/imx/devices-imx53.h +++ /dev/null @@ -1,89 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include <mach/imx/devices.h> -#include <mach/imx/imx53-regs.h> - -static inline struct device *imx53_add_cspi(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx35((void *)MX53_CSPI_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx53_add_spi0(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx51((void *)MX53_ECSPI1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx53_add_spi1(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx51((void *)MX53_ECSPI2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx53_add_i2c0(struct i2c_platform_data *pdata) -{ - return imx_add_i2c((void *)MX53_I2C1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx53_add_i2c1(struct i2c_platform_data *pdata) -{ - return imx_add_i2c((void *)MX53_I2C2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx53_add_i2c2(struct i2c_platform_data *pdata) -{ - return imx_add_i2c((void *)MX53_I2C3_BASE_ADDR, 2, pdata); -} - -static inline struct device *imx53_add_uart0(void) -{ - return imx_add_uart_imx21((void *)MX53_UART1_BASE_ADDR, 0); -} - -static inline struct device *imx53_add_uart1(void) -{ - return imx_add_uart_imx21((void *)MX53_UART2_BASE_ADDR, 1); -} - -static inline struct device *imx53_add_uart2(void) -{ - return imx_add_uart_imx21((void *)MX53_UART3_BASE_ADDR, 2); -} - -static inline struct device *imx53_add_uart3(void) -{ - return imx_add_uart_imx21((void *)MX53_UART4_BASE_ADDR, 3); -} - -static inline struct device *imx53_add_fec(struct fec_platform_data *pdata) -{ - return imx_add_fec_imx27((void *)MX53_FEC_BASE_ADDR, pdata); -} - -static inline struct device *imx53_add_mmc0(struct esdhc_platform_data *pdata) -{ - return imx_add_esdhc_imx5((void *)MX53_ESDHC1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx53_add_mmc1(struct esdhc_platform_data *pdata) -{ - return imx_add_esdhc_imx5((void *)MX53_ESDHC2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx53_add_mmc2(struct esdhc_platform_data *pdata) -{ - return imx_add_esdhc_imx5((void *)MX53_ESDHC3_BASE_ADDR, 2, pdata); -} - -static inline struct device *imx53_add_mmc3(struct esdhc_platform_data *pdata) -{ - return imx_add_esdhc_imx5((void *)MX53_ESDHC4_BASE_ADDR, 3, pdata); -} - -static inline struct device *imx53_add_kpp(struct matrix_keymap_data *pdata) -{ - return imx_add_kpp((void *)MX53_KPP_BASE_ADDR, pdata); -} - -static inline struct device *imx53_add_sata(void) -{ - return add_generic_device("imx53-sata", 0, NULL, MX53_SATA_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); -} diff --git a/include/mach/imx/devices-imx6.h b/include/mach/imx/devices-imx6.h deleted file mode 100644 index 9c9c788e51..0000000000 --- a/include/mach/imx/devices-imx6.h +++ /dev/null @@ -1,100 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include <mach/imx/devices.h> -#include <mach/imx/imx6-regs.h> - -static inline struct device *imx6_add_uart0(void) -{ - return imx_add_uart_imx21((void *)MX6_UART1_BASE_ADDR, 0); -} - -static inline struct device *imx6_add_uart1(void) -{ - return imx_add_uart_imx21((void *)MX6_UART2_BASE_ADDR, 1); -} - -static inline struct device *imx6_add_uart2(void) -{ - return imx_add_uart_imx21((void *)MX6_UART3_BASE_ADDR, 2); -} - -static inline struct device *imx6_add_uart3(void) -{ - return imx_add_uart_imx21((void *)MX6_UART4_BASE_ADDR, 3); -} - -static inline struct device *imx6_add_fec(struct fec_platform_data *pdata) -{ - return imx_add_fec_imx6((void *)MX6_ENET_BASE_ADDR, pdata); -} - -static inline struct device *imx6_add_spi0(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx51((void *)MX6_ECSPI1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx6_add_spi1(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx51((void *)MX6_ECSPI2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx6_add_spi2(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx51((void *)MX6_ECSPI3_BASE_ADDR, 2, pdata); -} - -static inline struct device *imx6_add_spi3(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx51((void *)MX6_ECSPI4_BASE_ADDR, 3, pdata); -} - -static inline struct device *imx6_add_spi4(struct spi_imx_master *pdata) -{ - return imx_add_spi_imx51((void *)MX6_ECSPI5_BASE_ADDR, 4, pdata); -} - -static inline struct device *imx6_add_i2c0(struct i2c_platform_data *pdata) -{ - return imx_add_i2c((void *)MX6_I2C1_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx6_add_i2c1(struct i2c_platform_data *pdata) -{ - return imx_add_i2c((void *)MX6_I2C2_BASE_ADDR, 1, pdata); -} - -static inline struct device *imx6_add_i2c2(struct i2c_platform_data *pdata) -{ - return imx_add_i2c((void *)MX6_I2C3_BASE_ADDR, 2, pdata); -} - -static inline struct device *imx6_add_sata(void) -{ - return add_generic_device("imx6-sata", 0, NULL, MX6_SATA_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL); -} - -static inline struct device *imx6_add_usbotg(void *pdata) -{ - add_generic_device("imx-usb-phy", 0, NULL, MX6_USBPHY1_BASE_ADDR, 0x1000, - IORESOURCE_MEM, NULL); - - return imx_add_usb((void *)MX6_USBOH3_USB_BASE_ADDR, 0, pdata); -} - -static inline struct device *imx6_add_usbh1(void *pdata) -{ - add_generic_device("imx-usb-phy", 1, NULL, MX6_USBPHY2_BASE_ADDR, 0x1000, - IORESOURCE_MEM, NULL); - - return imx_add_usb((void *)MX6_USBOH3_USB_BASE_ADDR + 0x200, 1, pdata); -} - -static inline struct device *imx6_add_usbh2(void *pdata) -{ - return imx_add_usb((void *)MX6_USBOH3_USB_BASE_ADDR + 0x400, 2, pdata); -} - -static inline struct device *imx6_add_usbh3(void *pdata) -{ - return imx_add_usb((void *)MX6_USBOH3_USB_BASE_ADDR + 0x600, 2, pdata); -} diff --git a/include/mach/imx/devices.h b/include/mach/imx/devices.h deleted file mode 100644 index ace2962fc3..0000000000 --- a/include/mach/imx/devices.h +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include <platform_data/eth-fec.h> -#include <input/matrix_keypad.h> -#include <i2c/i2c.h> -#include <mach/imx/spi.h> -#include <mach/imx/imx-nand.h> -#include <platform_data/imxfb.h> -#include <mach/imx/imx-ipu-fb.h> -#include <platform_data/mmc-esdhc-imx.h> -#include <linux/usb/chipidea-imx.h> - -struct device *imx_add_fec_imx27(void *base, struct fec_platform_data *pdata); -struct device *imx_add_fec_imx6(void *base, struct fec_platform_data *pdata); -struct device *imx_add_spi_imx27(void *base, int id, struct spi_imx_master *pdata); -struct device *imx_add_spi_imx35(void *base, int id, struct spi_imx_master *pdata); -struct device *imx_add_spi_imx51(void *base, int id, struct spi_imx_master *pdata); -struct device *imx_add_i2c(void *base, int id, struct i2c_platform_data *pdata); -struct device *imx_add_uart_imx1(void *base, int id); -struct device *imx_add_uart_imx21(void *base, int id); -struct device *imx_add_nand(void *base, struct imx_nand_platform_data *pdata); -struct device *imx_add_fb(void *base, struct imx_fb_platform_data *pdata); -struct device *imx_add_ipufb(void *base, struct imx_ipu_fb_platform_data *pdata); -struct device *imx_add_mmc(void *base, int id, void *pdata); -struct device *imx_add_esdhc_imx25(void *base, int id, struct esdhc_platform_data *pdata); -struct device *imx_add_esdhc_imx5(void *base, int id, struct esdhc_platform_data *pdata); -struct device *imx_add_kpp(void *base, struct matrix_keymap_data *pdata); -struct device *imx_add_pata(void *base); -struct device *imx_add_usb(void *base, int id, struct imxusb_platformdata *pdata); diff --git a/include/mach/rockchip/bbu.h b/include/mach/rockchip/bbu.h index 2cc9b74081..9ae137b0e6 100644 --- a/include/mach/rockchip/bbu.h +++ b/include/mach/rockchip/bbu.h @@ -6,14 +6,16 @@ #include <bbu.h> #ifdef CONFIG_BAREBOX_UPDATE -int rk3568_bbu_mmc_register(const char *name, unsigned long flags, +int rockchip_bbu_mmc_register(const char *name, unsigned long flags, const char *devicefile); #else -static inline int rk3568_bbu_mmc_register(const char *name, unsigned long flags, +static inline int rockchip_bbu_mmc_register(const char *name, unsigned long flags, const char *devicefile) { return -ENOSYS; } #endif +#define rk3568_bbu_mmc_register rockchip_bbu_mmc_register + # endif /* __MACH_ROCKCHIP_BBU_H */ diff --git a/include/mach/zynqmp/firmware-zynqmp.h b/include/mach/zynqmp/firmware-zynqmp.h index 00c63058f4..9f833189d3 100644 --- a/include/mach/zynqmp/firmware-zynqmp.h +++ b/include/mach/zynqmp/firmware-zynqmp.h @@ -119,8 +119,19 @@ struct zynqmp_eemi_ops { const struct zynqmp_eemi_ops *zynqmp_pm_get_eemi_ops(void); +#if defined(CONFIG_ARCH_ZYNQMP) int zynqmp_pm_set_sd_tapdelay(u32 node_id, u32 type, u32 value); int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type); +#else +static inline int zynqmp_pm_set_sd_tapdelay(u32 node_id, u32 type, u32 value) +{ + return -ENOSYS; +} +static inline int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type) +{ + return -ENOSYS; +} +#endif int zynqmp_pm_write_ggs(u32 index, u32 value); int zynqmp_pm_read_ggs(u32 index, u32 *value); diff --git a/include/mci.h b/include/mci.h index 52bf84ecdb..6aa33f1542 100644 --- a/include/mci.h +++ b/include/mci.h @@ -446,7 +446,6 @@ static inline bool mci_timing_is_ddr(enum mci_timing timing) { switch (timing) { case MMC_TIMING_UHS_DDR50: - case MMC_TIMING_MMC_HS200: case MMC_TIMING_MMC_DDR52: case MMC_TIMING_MMC_HS400: return true; @@ -559,15 +558,14 @@ struct mci { struct mci_host *host; /**< the host for this card */ struct device dev; /**< the device for our disk (mcix) */ unsigned version; - bool sdio; /**< card is a SDIO card */ - /** != 0 when a high capacity card is connected (OCR -> OCR_HCS) */ - int high_capacity; unsigned card_caps; /**< Card's capabilities */ unsigned ocr; /**< card's "operation condition register" */ unsigned scr[2]; unsigned csd[4]; /**< card's "card specific data register" */ unsigned cid[4]; /**< card's "card identification register" */ - unsigned short rca; /* FIXME */ + unsigned short rca; /**< relative card address */ + bool sdio; /**< card is a SDIO card */ + bool high_capacity; /**< high capacity card is connected (OCR -> OCR_HCS) */ unsigned tran_speed; /**< Maximum transfer speed */ /** currently used data block length for read accesses */ unsigned read_bl_len; diff --git a/include/nand.h b/include/nand.h index f0114a227d..4fb52e9f82 100644 --- a/include/nand.h +++ b/include/nand.h @@ -4,7 +4,7 @@ struct nand_bb; -#ifdef CONFIG_NAND +#ifdef CONFIG_MTD_NAND_CORE int dev_add_bb_dev(const char *filename, const char *name); int dev_remove_bb_dev(const char *name); struct cdev *mtd_add_bb(struct mtd_info *mtd, const char *name); diff --git a/include/of.h b/include/of.h index 9eef6d7f13..f99cff5cf5 100644 --- a/include/of.h +++ b/include/of.h @@ -240,11 +240,22 @@ extern int of_property_read_u32_array(const struct device_node *np, size_t sz); extern int of_property_read_u64(const struct device_node *np, const char *propname, u64 *out_value); - +extern int of_property_read_variable_u8_array(const struct device_node *np, + const char *propname, u8 *out_values, + size_t sz_min, size_t sz_max); +extern int of_property_read_variable_u16_array(const struct device_node *np, + const char *propname, u16 *out_values, + size_t sz_min, size_t sz_max); +extern int of_property_read_variable_u32_array(const struct device_node *np, + const char *propname, + u32 *out_values, + size_t sz_min, + size_t sz_max); extern int of_property_read_variable_u64_array(const struct device_node *np, const char *propname, u64 *out_values, - size_t sz); + size_t sz_min, + size_t sz_max); extern int of_property_read_string(struct device_node *np, const char *propname, @@ -669,10 +680,34 @@ static inline int of_property_read_u64(const struct device_node *np, return -ENOSYS; } +static inline int of_property_read_variable_u8_array(const struct device_node *np, + const char *propname, u8 *out_values, + size_t sz_min, size_t sz_max) +{ + return -ENOSYS; +} + +static inline int of_property_read_variable_u16_array(const struct device_node *np, + const char *propname, u16 *out_values, + size_t sz_min, size_t sz_max) +{ + return -ENOSYS; +} + +static inline int of_property_read_variable_u32_array(const struct device_node *np, + const char *propname, + u32 *out_values, + size_t sz_min, + size_t sz_max) +{ + return -ENOSYS; +} + static inline int of_property_read_variable_u64_array(const struct device_node *np, const char *propname, u64 *out_values, - size_t sz) + size_t sz_min, + size_t sz_max) { return -ENOSYS; } @@ -1166,7 +1201,7 @@ static inline int of_property_read_u64_array(const struct device_node *np, u64 *out_values, size_t sz) { int ret = of_property_read_variable_u64_array(np, propname, out_values, - sz); + sz, 0); if (ret >= 0) return 0; else diff --git a/include/platform_data/gpio-intel.h b/include/platform_data/gpio-intel.h new file mode 100644 index 0000000000..4da4764998 --- /dev/null +++ b/include/platform_data/gpio-intel.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef __GPIO_INTEL_H +#define __GPIO_INTEL_H + +#include <linux/types.h> + +struct gpio_intel_platform_data { + resource_size_t community_base; + resource_size_t community_size; + unsigned int ngpios; +}; + +static inline struct device *add_intel_gpio_device( + struct gpio_intel_platform_data *pdata +) +{ + return add_generic_device("intel-gpio", DEVICE_ID_DYNAMIC, NULL, + pdata->community_base, pdata->community_size, + IORESOURCE_MEM, pdata); +} + +#endif /* __GPIO_INTEL_H */ diff --git a/include/pwm.h b/include/pwm.h index 4d403fe174..b90ac1de42 100644 --- a/include/pwm.h +++ b/include/pwm.h @@ -8,20 +8,32 @@ struct pwm_device; struct device; -#define PWM_POLARITY_NORMAL 0 +/** + * enum pwm_polarity - polarity of a PWM signal + * @PWM_POLARITY_NORMAL: a high signal for the duration of the duty- + * cycle, followed by a low signal for the remainder of the pulse + * period + * @PWM_POLARITY_INVERSED: a low signal for the duration of the duty- + * cycle, followed by a high signal for the remainder of the pulse + * period + */ +enum pwm_polarity { + PWM_POLARITY_NORMAL, + PWM_POLARITY_INVERSED, +}; /* * struct pwm_state - state of a PWM channel - * @period_ns: PWM period (in nanoseconds) - * @duty_ns: PWM duty cycle (in nanoseconds) + * @period: PWM period (in nanoseconds) + * @duty_cycle: PWM duty cycle (in nanoseconds) * @polarity: PWM polarity - * @p_enable: PWM enabled status + * @enabled: PWM enabled status */ struct pwm_state { - unsigned int period_ns; - unsigned int duty_ns; + unsigned int period; + unsigned int duty_cycle; unsigned int polarity; - unsigned int p_enable; + unsigned int enabled; }; void pwm_print(void); @@ -91,9 +103,9 @@ pwm_set_relative_duty_cycle(struct pwm_state *state, unsigned int duty_cycle, if (!scale || duty_cycle > scale) return -EINVAL; - state->duty_ns = DIV_ROUND_CLOSEST_ULL((u64)duty_cycle * - state->period_ns, - scale); + state->duty_cycle = DIV_ROUND_CLOSEST_ULL((u64)duty_cycle * + state->period, + scale); return 0; } @@ -123,17 +135,20 @@ int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state); struct pwm_ops { int (*request)(struct pwm_chip *chip); void (*free)(struct pwm_chip *chip); - int (*apply)(struct pwm_chip *chip, const struct pwm_state *state); + int (*apply)(struct pwm_chip *chip, struct pwm_device *pwm, + const struct pwm_state *state); }; /** * struct pwm_chip - abstract a PWM + * @dev: device providing the PWMs * @id: The id of this pwm * @devname: unique identifier for this pwm * @ops: The callbacks for this PWM * @state: current state of the PWM */ struct pwm_chip { + struct device *dev; int id; const char *devname; const struct pwm_ops *ops; @@ -141,7 +156,7 @@ struct pwm_chip { struct pwm_state state; }; -int pwmchip_add(struct pwm_chip *chip, struct device *dev); +int pwmchip_add(struct pwm_chip *chip); int pwmchip_remove(struct pwm_chip *chip); #endif /* __PWM_H */ diff --git a/include/string.h b/include/string.h index 2f2af85b55..4ee3be6d93 100644 --- a/include/string.h +++ b/include/string.h @@ -33,4 +33,6 @@ static inline bool streq_ptr(const char *a, const char *b) return strcmp_ptr(a, b) == 0; } +bool isempty(const char *s); + #endif /* __STRING_H */ diff --git a/include/usb_dfu_trailer.h b/include/usb_dfu_trailer.h deleted file mode 100644 index 64b8407275..0000000000 --- a/include/usb_dfu_trailer.h +++ /dev/null @@ -1,32 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef _USB_DFU_TRAILER_H -#define _USB_DFU_TRAILER_H - -/* trailer handling for DFU files */ - -#define BAREBOX_DFU_TRAILER_V1 1 -#define BAREBOX_DFU_TRAILER_MAGIC 0x19731978 -struct barebox_dfu_trailer { - u_int32_t magic; - u_int16_t version; - u_int16_t length; - u_int16_t vendor; - u_int16_t product; - u_int32_t revision; -} __attribute__((packed)); - -/* we mirror the trailer because we want it to be longer in later versions - * while keeping backwards compatibility */ -static inline void dfu_trailer_mirror(struct barebox_dfu_trailer *trailer, - unsigned char *eof) -{ - int i; - int len = sizeof(struct barebox_dfu_trailer); - unsigned char *src = eof - len; - unsigned char *dst = (unsigned char *) trailer; - - for (i = 0; i < len; i++) - dst[len-1-i] = src[i]; -} - -#endif /* _USB_DFU_TRAILER_H */ |