* Author: Neil Armstrong <narmstrong@baylibre.com>
*/
-#include "meson-gx-u-boot.dtsi"
+#include "meson-gxl-u-boot.dtsi"
+
+&dwc2 {
+ status = "okay";
+};
* Author: Neil Armstrong <narmstrong@baylibre.com>
*/
-#include "meson-gx-u-boot.dtsi"
+#include "meson-gxl-u-boot.dtsi"
+
+&dwc2 {
+ status = "okay";
+};
*/
#include "meson-gxl-u-boot.dtsi"
+
+&dwc2 {
+ status = "okay";
+};
* Author: Neil Armstrong <narmstrong@baylibre.com>
*/
-#include "meson-gx-u-boot.dtsi"
+#include "meson-gxl-u-boot.dtsi"
/ {
aliases {
};
};
+&dwc2 {
+ status = "okay";
+};
+
&sd_emmc_c {
status = "okay";
pinctrl-0 = <&emmc_pins>;
* Author: Neil Armstrong <narmstrong@baylibre.com>
*/
-#include "meson-gx-u-boot.dtsi"
+#include "meson-gxl-u-boot.dtsi"
+
+&dwc2 {
+ status = "okay";
+};
* Author: Neil Armstrong <narmstrong@baylibre.com>
*/
+#include "meson-g12-common-u-boot.dtsi"
+
/ {
aliases {
spi0 = &spifc;
CONFIG_MESON_G12A_USB_PHY=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_MESON_G12A=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MESON_EE_POWER_DOMAIN=y
CONFIG_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_RESET=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_DWC3=y
+CONFIG_USB_KEYBOARD=y
# CONFIG_USB_DWC3_GADGET is not set
CONFIG_USB_DWC3_MESON_G12A=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DWC2_OTG=y
CONFIG_USB_GADGET_DWC2_OTG_PHY_BUS_WIDTH_8=y
CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_DM_VIDEO=y
+# CONFIG_VIDEO_BPP8 is not set
+# CONFIG_VIDEO_BPP16 is not set
+CONFIG_SYS_WHITE_ON_BLACK=y
+CONFIG_VIDEO_MESON=y
+CONFIG_VIDEO_DT_SIMPLEFB=y
CONFIG_OF_LIBFDT_OVERLAY=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_DWC3=y
+CONFIG_USB_KEYBOARD=y
# CONFIG_USB_DWC3_GADGET is not set
CONFIG_USB_DWC3_MESON_G12A=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DWC2_OTG_PHY_BUS_WIDTH_8=y
CONFIG_USB_GADGET_DOWNLOAD=y
CONFIG_DM_VIDEO=y
+# CONFIG_VIDEO_BPP8 is not set
+# CONFIG_VIDEO_BPP16 is not set
+CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_MESON=y
CONFIG_VIDEO_DT_SIMPLEFB=y
CONFIG_OF_LIBFDT_OVERLAY=y
CONFIG_OF_LIVE=y
CONFIG_OF_HOSTFILE=y
CONFIG_DEFAULT_DEVICE_TREE="sandbox64"
-CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_NETCONSOLE=y
CONFIG_IP_DEFRAG=y
CONFIG_REGMAP=y
CONFIG_OF_LIVE=y
CONFIG_OF_HOSTFILE=y
CONFIG_DEFAULT_DEVICE_TREE="sandbox"
-CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_NETCONSOLE=y
CONFIG_IP_DEFRAG=y
CONFIG_REGMAP=y
CONFIG_OF_CONTROL=y
CONFIG_OF_HOSTFILE=y
CONFIG_DEFAULT_DEVICE_TREE="sandbox"
-CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_NETCONSOLE=y
CONFIG_IP_DEFRAG=y
CONFIG_REGMAP=y
CONFIG_OF_HOSTFILE=y
CONFIG_DEFAULT_DEVICE_TREE="sandbox"
CONFIG_SPL_OF_PLATDATA=y
-CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_NETCONSOLE=y
CONFIG_IP_DEFRAG=y
CONFIG_SPL_DM=y
====================================
U-Boot supports SPI and SPI flash emulation in sandbox. This must be enabled
-using the --spi_sf paramter when starting U-Boot.
+via a device tree.
For example:
-$ make O=sandbox sandbox_config
-$ make O=sandbox
-$ ./sandbox/u-boot --spi_sf 0:0:W25Q128:b/chromeos_peach/out/image.bin
-
-The four parameters to spi_sf are:
-
- SPI bus number (typically 0)
- SPI chip select number (typically 0)
- SPI chip to emulate
- File containing emulated data
+ spi@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0 1>;
+ compatible = "sandbox,spi";
+ cs-gpios = <0>, <&gpio_a 0>;
+ spi.bin@0 {
+ reg = <0>;
+ compatible = "spansion,m25p16", "jedec,spi-nor";
+ spi-max-frequency = <40000000>;
+ sandbox,filename = "spi.bin";
+ };
+ };
Supported chips are W25Q16 (2MB), W25Q32 (4MB) and W25Q128 (16MB). Once
U-Boot it started you can use 'sf' commands as normal. For example:
-$ ./b/sandbox/u-boot --spi_sf 0:0:W25Q128:b/chromeos_peach/out/image.bin \
- -c "sf probe; sf test 0 100000; sf read 0 1000 1000; \
- sf erase 1000 1000; sf write 0 1000 1000"
-
-
-U-Boot 2013.10-00237-gd4e0fdb (Nov 07 2013 - 20:08:15)
-
-DRAM: 128 MiB
-Using default environment
-
-In: serial
-Out: serial
-Err: serial
-SF: Detected W25Q128BV with page size 256 Bytes, erase size 4 KiB, total 16 MiB
-SPI flash test:
-0 erase: 1 ticks, 1024000 KiB/s 8192.000 Mbps
-1 check: 2 ticks, 512000 KiB/s 4096.000 Mbps
-2 write: 6 ticks, 170666 KiB/s 1365.328 Mbps
-3 read: 0 ticks, 1048576000 KiB/s -201326.-592 Mbps
-Test passed
-0 erase: 1 ticks, 1024000 KiB/s 8192.000 Mbps
-1 check: 2 ticks, 512000 KiB/s 4096.000 Mbps
-2 write: 6 ticks, 170666 KiB/s 1365.328 Mbps
-3 read: 0 ticks, 1048576000 KiB/s -201326.-592 Mbps
-SF: 4096 bytes @ 0x1000 Read: OK
-SF: 4096 bytes @ 0x1000 Erased: OK
-SF: 4096 bytes @ 0x1000 Written: OK
-
+$ dd if=/dev/zero of=spi.bin bs=1M count=2
+$ u-boot -T
Since the SPI bus is fully implemented as well as the SPI flash connected to
it, you can also use low-level SPI commands to access the flash. For example
this reads the device ID from the emulated chip:
=> sspi 0 32 9f
-FFEF4018
+SF: Detected m25p16 with page size 256 Bytes, erase size 64 KiB, total 2 MiB
+FF202015
Simon Glass
Sandbox supports SPI and SPI flash emulation.
-This is controlled by the spi_sf argument, the format of which is::
-
- bus:cs:device:file
-
- bus - SPI bus number
- cs - SPI chip select number
- device - SPI device emulation name
- file - File on disk containing the data
-
-For example::
-
- dd if=/dev/zero of=spi.bin bs=1M count=4
- ./u-boot --spi_sf 0:0:M25P16:spi.bin
+The device can be enabled via a device tree, for example::
+
+ spi@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0 1>;
+ compatible = "sandbox,spi";
+ cs-gpios = <0>, <&gpio_a 0>;
+ spi.bin@0 {
+ reg = <0>;
+ compatible = "spansion,m25p16", "jedec,spi-nor";
+ spi-max-frequency = <40000000>;
+ sandbox,filename = "spi.bin";
+ };
+ };
+
+The file must be created in advance::
+
+ $ dd if=/dev/zero of=spi.bin bs=1M count=2
+ $ u-boot -T
+
+Here, you can use "-T" or "-D" option to specify test.dtb or u-boot.dtb,
+respectively, or "-d <file>" for your own dtb.
With this setup you can issue SPI flash commands as normal::
This is issuing a READ_ID command and getting back 20 (ST Micro) part
0x2015 (the M25P16).
-Drivers are connected to a particular bus/cs using sandbox's state
-structure (see the 'spi' member). A set of operations must be provided
-for each driver.
-
-
-Configuration settings for the curious are:
-
-CONFIG_SANDBOX_SPI_MAX_BUS:
- The maximum number of SPI buses supported by the driver (default 1).
-
-CONFIG_SANDBOX_SPI_MAX_CS:
- The maximum number of chip selects supported by the driver (default 10).
-
-CONFIG_SPI_IDLE_VAL:
- The idle value on the SPI bus
-
Block Device Emulation
----------------------
* Written by Simon Glass <sjg@chromium.org>
*/
-#include <asm/types.h>
-#include <asm/io.h>
#include <common.h>
#include <dm.h>
-#include <mapmem.h>
#include <dm/of_access.h>
+#include <mapmem.h>
+#include <asm/types.h>
+#include <asm/io.h>
int dev_read_u32(const struct udevice *dev, const char *propname, u32 *outp)
{
#include <dm/device_compat.h>
#include <linux/err.h>
+/*
+ * This assigned unique hex value is constant and is derived from the two ASCII
+ * letters 'DW' followed by a 16-bit unsigned number
+ */
+#define DW_I2C_COMP_TYPE 0x44570140
+
#ifdef CONFIG_SYS_I2C_DW_ENABLE_STATUS_UNSUPPORTED
static int dw_i2c_enable(struct i2c_regs *i2c_base, bool enable)
{
return 0;
}
-static int calc_bus_speed(struct dw_i2c *priv, int speed, ulong bus_clk,
- struct dw_i2c_speed_config *config)
+/**
+ * calc_bus_speed() - Calculate the config to use for a particular i2c speed
+ *
+ * @priv: Private information for the driver (NULL if not using driver model)
+ * @i2c_base: Registers for the I2C controller
+ * @speed: Required i2c speed in Hz
+ * @bus_clk: Input clock to the I2C controller in Hz (e.g. IC_CLK)
+ * @config: Returns the config to use for this speed
+ * @return 0 if OK, -ve on error
+ */
+static int calc_bus_speed(struct dw_i2c *priv, struct i2c_regs *regs, int speed,
+ ulong bus_clk, struct dw_i2c_speed_config *config)
{
const struct dw_scl_sda_cfg *scl_sda_cfg = NULL;
- struct i2c_regs *regs = priv->regs;
enum i2c_speed_mode i2c_spd;
- u32 comp_param1;
int spk_cnt;
int ret;
- comp_param1 = readl(®s->comp_param1);
-
if (priv)
scl_sda_cfg = priv->scl_sda_cfg;
/* Allow high speed if there is no config, or the config allows it */
/* Check is high speed possible and fall back to fast mode if not */
if (i2c_spd == IC_SPEED_MODE_HIGH) {
+ u32 comp_param1;
+
+ comp_param1 = readl(®s->comp_param1);
if ((comp_param1 & DW_IC_COMP_PARAM_1_SPEED_MODE_MASK)
!= DW_IC_COMP_PARAM_1_SPEED_MODE_HIGH)
i2c_spd = IC_SPEED_MODE_FAST;
return 0;
}
-/*
- * _dw_i2c_set_bus_speed - Set the i2c speed
- * @speed: required i2c speed
+/**
+ * _dw_i2c_set_bus_speed() - Set the i2c speed
*
- * Set the i2c speed.
+ * @priv: Private information for the driver (NULL if not using driver model)
+ * @i2c_base: Registers for the I2C controller
+ * @speed: Required i2c speed in Hz
+ * @bus_clk: Input clock to the I2C controller in Hz (e.g. IC_CLK)
+ * @return 0 if OK, -ve on error
*/
static int _dw_i2c_set_bus_speed(struct dw_i2c *priv, struct i2c_regs *i2c_base,
unsigned int speed, unsigned int bus_clk)
unsigned int ena;
int ret;
- ret = calc_bus_speed(priv, speed, bus_clk, &config);
+ ret = calc_bus_speed(priv, i2c_base, speed, bus_clk, &config);
if (ret)
return ret;
int designware_i2c_probe(struct udevice *bus)
{
struct dw_i2c *priv = dev_get_priv(bus);
+ uint comp_type;
+
+ comp_type = readl(&priv->regs->comp_type);
+ if (comp_type != DW_I2C_COMP_TYPE) {
+ log_err("I2C bus %s has unknown type %#x\n", bus->name,
+ comp_type);
+ return -ENXIO;
+ }
+
+ log_info("I2C bus %s version %#x\n", bus->name,
+ readl(&priv->regs->comp_version));
return __dw_i2c_init(priv->regs, 0, 0);
}
udelay(delay);
/* Toggle SCL until slave release SDA */
- while (scl_count-- >= 0) {
+ for (; scl_count; --scl_count) {
i2c_gpio_set_pin(scl_pin, 1);
udelay(delay);
i2c_gpio_set_pin(scl_pin, 0);
u32 pagesize; /* page size in bytes */
u32 addr_offset_mask; /* bits in addr used for offset overflow */
u32 offset_len; /* size in bytes of offset */
+ u32 start_offset; /* valid start offset inside memory, by default 0 */
};
int i2c_eeprom_read(struct udevice *dev, int offset, uint8_t *buf, int size)
i2c_set_chip_addr_offset_mask(dev, data->addr_offset_mask);
/* Verify that the chip is functional */
- ret = i2c_eeprom_read(dev, 0, &test_byte, 1);
+ /*
+ * Not all eeproms start from offset 0. Valid offset is available
+ * in the platform data struct.
+ */
+ ret = i2c_eeprom_read(dev, data->start_offset, &test_byte, 1);
if (ret)
return -ENODEV;
.pagesize = 16,
.addr_offset_mask = 0,
.offset_len = 1,
+ .start_offset = 0x80,
};
static const struct i2c_eeprom_drv_data atmel24c32_data = {
struct usb_interface *iface;
struct usb_interface_descriptor *iface_desc;
int ep_in_found = 0, ep_out_found = 0;
- int i;
-
struct r8152 *tp;
+ int i;
/* let's examine the device now */
iface = &dev->config.if_desc[ifnum];
if ((iface->ep_desc[i].bmAttributes &
USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
u8 ep_addr = iface->ep_desc[i].bEndpointAddress;
- if ((ep_addr & USB_DIR_IN) && !ep_in_found) {
- ss->ep_in = ep_addr &
- USB_ENDPOINT_NUMBER_MASK;
- ep_in_found = 1;
+
+ if (ep_addr & USB_DIR_IN) {
+ if (!ep_in_found) {
+ ss->ep_in = ep_addr &
+ USB_ENDPOINT_NUMBER_MASK;
+ ep_in_found = 1;
+ }
} else {
if (!ep_out_found) {
ss->ep_out = ep_addr &
ret = regulator_set_enable(priv->vbus_supply,
(type == USB_INIT_DEVICE) ?
false : true);
- if (ret) {
- puts("Error enabling VBUS supply\n");
+ if (ret && ret != -ENOSYS) {
+ printf("Error enabling VBUS supply (ret=%i)\n", ret);
return ret;
}
}
ret = regulator_set_enable(priv->vbus_supply,
(type == USB_INIT_DEVICE) ?
false : true);
- if (ret) {
- puts("Error enabling VBUS supply\n");
+ if (ret && ret != -ENOSYS) {
+ printf("Error enabling VBUS supply (ret=%i)\n", ret);
return ret;
}
}
to update the log there and then, knowing that the script will
do the rest.
+Commit-changes: n
+- This line will not appear in the cover-letter changelog
+<blank line>
+ This tag is like Series-changes, except changes in this changelog will
+ only appear in the changelog of the commit this tag is in. This is
+ useful when you want to add notes which may not make sense in the cover
+ letter. For example, you can have short changes such as "New" or
+ "Lint".
+
+Cover-changes: n
+- This line will only appear in the cover letter
+<blank line>
+ This tag is like Series-changes, except changes in this changelog will
+ only appear in the cover-letter changelog. This is useful to summarize
+ changes made with Commit-changes, or to add additional context to
+ changes.
+
Patch-cc: Their Name <email>
This copies a single patch to another email address. Note that the
Cc: used by git send-email is ignored by patman, but will be
interpreted by git send-email if you use it.
Series-process-log: sort, uniq
- This tells patman to sort and/or uniq the change logs. It is
- assumed that each change log entry is only a single line long.
+ This tells patman to sort and/or uniq the change logs. Changes may be
+ multiple lines long, as long as each subsequent line of a change begins
+ with a whitespace character. For example,
+
+- This change
+ continues onto the next line
+- But this change is separate
+
Use 'sort' to sort the entries, and 'uniq' to include only
unique entries. If omitted, no change log processing is done.
Separate each tag with a comma.
not later when you can't remember which patch you changed. You can always
go back and change or remove logs from commits.
+7. Some mailing lists have size limits and when we add binary contents to
+our patches it's easy to exceed the size limits. Use "--no-binary" to
+generate patches without any binary contents. You are supposed to include
+a link to a git repository in your "Commit-notes", "Series-notes" or
+"Cover-letter" for maintainers to fetch the original commit.
+
+8. Patches will have no changelog entries for revisions where they did not
+change. For clarity, if there are no changes for this patch in the most
+recent revision of the series, a note will be added. For example, a patch
+with the following tags in the commit
+
+ Series-version: 5
+ Series-changes: 2
+ - Some change
+
+ Series-changes: 4
+ - Another change
+
+would have a changelog of
+
+ (no changes since v4)
+
+ Changes in v4:
+ - Another change
+
+ Changes in v2:
+ - Some change
Other thoughts
==============
Series-prefix: RFC
Series-cc: Stefan Brüns <stefan.bruens@rwth-aachen.de>
Cover-letter-cc: Lord Mëlchett <clergy@palace.gov>
- Series-version: 2
+ Series-version: 3
+ Patch-cc: fred
+ Series-process-log: sort, uniq
Series-changes: 4
- Some changes
+ - Multi
+ line
+ change
+
+ Commit-changes: 2
+ - Changes only for this commit
+
+ Cover-changes: 4
+ - Some notes for the cover letter
Cover-letter:
test: A test patch series
This is a test of how the cover
- leter
+ letter
works
END
and this in the first commit:
+ Commit-changes: 2
+ - second revision change
+
Series-notes:
some notes
about some things
expected = '''
This is a test of how the cover
-leter
+letter
works
some notes
from the first commit
Changes in v4:
+- Multi
+ line
+ change
- Some changes
+- Some notes for the cover letter
Simon Glass (2):
pci: Correct cast for sandbox
subject = [line for line in lines if line.startswith('Subject')]
self.assertEqual('Subject: [RFC %d/%d]' % (i + 1, count),
subject[0][:18])
+
+ # Check that we got our commit notes
+ start = 0
+ expected = ''
+
if i == 0:
- # Check that we got our commit notes
- self.assertEqual('---', lines[17])
- self.assertEqual('Some notes about', lines[18])
- self.assertEqual('the first commit', lines[19])
+ start = 17
+ expected = '''---
+Some notes about
+the first commit
+
+(no changes since v2)
+
+Changes in v2:
+- second revision change'''
+ elif i == 1:
+ start = 17
+ expected = '''---
+
+Changes in v4:
+- Multi
+ line
+ change
+- Some changes
+
+Changes in v2:
+- Changes only for this commit'''
+
+ if expected:
+ expected = expected.splitlines()
+ self.assertEqual(expected, lines[start:(start+len(expected))])
if result.return_code != 0:
raise OSError('git fetch: %s' % result.stderr)
-def CreatePatches(start, count, series):
+def CreatePatches(start, count, ignore_binary, series):
"""Create a series of patches from the top of the current branch.
The patch files are written to the current directory using
if series.get('version'):
version = '%s ' % series['version']
cmd = ['git', 'format-patch', '-M', '--signoff']
+ if ignore_binary:
+ cmd.append('--no-binary')
if series.get('cover'):
cmd.append('--cover-letter')
prefix = series.GetPatchPrefix()
parser.add_option('-i', '--ignore-errors', action='store_true',
dest='ignore_errors', default=False,
help='Send patches email even if patch errors are found')
+parser.add_option('-l', '--limit-cc', dest='limit', type='int',
+ default=None, help='Limit the cc list to LIMIT entries [default: %default]')
parser.add_option('-m', '--no-maintainers', action='store_false',
dest='add_maintainers', default=True,
help="Don't cc the file maintainers automatically")
-parser.add_option('-l', '--limit-cc', dest='limit', type='int',
- default=None, help='Limit the cc list to LIMIT entries [default: %default]')
parser.add_option('-n', '--dry-run', action='store_true', dest='dry_run',
default=False, help="Do a dry run (create but don't email patches)")
parser.add_option('-p', '--project', default=project.DetectProject(),
default=0, help='Commit to start creating patches from (0 = HEAD)')
parser.add_option('-t', '--ignore-bad-tags', action='store_true',
default=False, help='Ignore bad tags / aliases')
-parser.add_option('--test', action='store_true', dest='test',
- default=False, help='run tests')
parser.add_option('-v', '--verbose', action='store_true', dest='verbose',
default=False, help='Verbose output of errors and warnings')
+parser.add_option('-T', '--thread', action='store_true', dest='thread',
+ default=False, help='Create patches as a single thread')
parser.add_option('--cc-cmd', dest='cc_cmd', type='string', action='store',
default=None, help='Output cc list for patch file (used by git)')
+parser.add_option('--no-binary', action='store_true', dest='ignore_binary',
+ default=False,
+ help="Do not output contents of changes in binary files")
parser.add_option('--no-check', action='store_false', dest='check_patch',
default=True,
help="Don't check for patch compliance")
parser.add_option('--no-tags', action='store_false', dest='process_tags',
- default=True, help="Don't process subject tags as aliaes")
+ default=True, help="Don't process subject tags as aliases")
parser.add_option('--smtp-server', type='str',
help="Specify the SMTP server to 'git send-email'")
-parser.add_option('-T', '--thread', action='store_true', dest='thread',
- default=False, help='Create patches as a single thread')
+parser.add_option('--test', action='store_true', dest='test',
+ default=False, help='run tests')
parser.usage += """
if options.count:
series = patchstream.GetMetaData(options.start, options.count)
cover_fname, args = gitutil.CreatePatches(options.start, options.count,
- series)
+ options.ignore_binary, series)
# Fix up the patch files to our liking, and insert the cover letter
patchstream.FixPatches(series, args)
# Signoffs
re_signoff = re.compile('^Signed-off-by: *(.*)')
-# The start of the cover letter
-re_cover = re.compile('^Cover-letter:')
-
-# A cover letter Cc
-re_cover_cc = re.compile('^Cover-letter-cc: *(.*)')
+# Cover letter tag
+re_cover = re.compile('^Cover-([a-z-]*): *(.*)')
# Patch series tag
re_series_tag = re.compile('^Series-([a-z-]*): *(.*)')
# We detect these since checkpatch doesn't always do it
re_space_before_tab = re.compile('^[+].* \t')
+# Match indented lines for changes
+re_leading_whitespace = re.compile('^\s')
+
# States we can be in - can we use range() and still have comments?
STATE_MSG_HEADER = 0 # Still in the message header
STATE_PATCH_SUBJECT = 1 # In patch subject (first line of log for a commit)
def __init__(self, series, name=None, is_log=False):
self.skip_blank = False # True to skip a single blank line
self.found_test = False # Found a TEST= line
- self.lines_after_test = 0 # MNumber of lines found after TEST=
+ self.lines_after_test = 0 # Number of lines found after TEST=
self.warn = [] # List of warnings we have collected
self.linenum = 1 # Output line number we are up to
self.in_section = None # Name of start...END section we are in
self.section = [] # The current section...END section
self.series = series # Info about the patch series
self.is_log = is_log # True if indent like git log
- self.in_change = 0 # Non-zero if we are in a change list
+ self.in_change = None # Name of the change list we are in
+ self.change_version = 0 # Non-zero if we are in a change list
+ self.change_lines = [] # Lines of the current change
self.blank_count = 0 # Number of blank lines stored up
self.state = STATE_MSG_HEADER # What state are we in?
self.signoff = [] # Contents of signoff line
self.skip_blank = True
self.section = []
+ def ParseVersion(self, value, line):
+ """Parse a version from a *-changes tag
+
+ Args:
+ value: Tag value (part after 'xxx-changes: '
+ line: Source line containing tag
+
+ Returns:
+ The version as an integer
+ """
+ try:
+ return int(value)
+ except ValueError as str:
+ raise ValueError("%s: Cannot decode version info '%s'" %
+ (self.commit.hash, line))
+
+ def FinalizeChange(self):
+ """Finalize a (multi-line) change and add it to the series or commit"""
+ if not self.change_lines:
+ return
+ change = '\n'.join(self.change_lines)
+
+ if self.in_change == 'Series':
+ self.series.AddChange(self.change_version, self.commit, change)
+ elif self.in_change == 'Cover':
+ self.series.AddChange(self.change_version, None, change)
+ elif self.in_change == 'Commit':
+ self.commit.AddChange(self.change_version, change)
+ self.change_lines = []
+
def ProcessLine(self, line):
"""Process a single line of a patch file or commit log
change_id_match = re_change_id.match(line)
commit_tag_match = re_commit_tag.match(line)
cover_match = re_cover.match(line)
- cover_cc_match = re_cover_cc.match(line)
signoff_match = re_signoff.match(line)
+ leading_whitespace_match = re_leading_whitespace.match(line)
tag_match = None
if self.state == STATE_PATCH_HEADER:
tag_match = re_tag.match(line)
# If a tag is detected, or a new commit starts
if series_tag_match or commit_tag_match or change_id_match or \
- cover_match or cover_cc_match or signoff_match or \
- self.state == STATE_MSG_HEADER:
+ cover_match or signoff_match or self.state == STATE_MSG_HEADER:
# but we are already in a section, this means 'END' is missing
# for that section, fix it up.
if self.in_section:
# but we are already in a change list, that means a blank line
# is missing, fix it up.
if self.in_change:
- self.warn.append("Missing 'blank line' in section 'Series-changes'")
- self.in_change = 0
+ self.warn.append("Missing 'blank line' in section '%s-changes'" % self.in_change)
+ self.FinalizeChange()
+ self.in_change = None
+ self.change_version = 0
# If we are in a section, keep collecting lines until we see END
if self.in_section:
elif self.skip_blank and is_blank:
self.skip_blank = False
- # Detect the start of a cover letter section
+ # Detect Cover-xxx tags
elif cover_match:
- self.in_section = 'cover'
- self.skip_blank = False
-
- elif cover_cc_match:
- value = cover_cc_match.group(1)
- self.AddToSeries(line, 'cover-cc', value)
+ name = cover_match.group(1)
+ value = cover_match.group(2)
+ if name == 'letter':
+ self.in_section = 'cover'
+ self.skip_blank = False
+ elif name == 'letter-cc':
+ self.AddToSeries(line, 'cover-cc', value)
+ elif name == 'changes':
+ self.in_change = 'Cover'
+ self.change_version = self.ParseVersion(value, line)
# If we are in a change list, key collected lines until a blank one
elif self.in_change:
if is_blank:
# Blank line ends this change list
- self.in_change = 0
+ self.FinalizeChange()
+ self.in_change = None
+ self.change_version = 0
elif line == '---':
- self.in_change = 0
+ self.FinalizeChange()
+ self.in_change = None
+ self.change_version = 0
out = self.ProcessLine(line)
- else:
- if self.is_log:
- self.series.AddChange(self.in_change, self.commit, line)
+ elif self.is_log:
+ if not leading_whitespace_match:
+ self.FinalizeChange()
+ self.change_lines.append(line)
self.skip_blank = False
# Detect Series-xxx tags
value = series_tag_match.group(2)
if name == 'changes':
# value is the version number: e.g. 1, or 2
- try:
- value = int(value)
- except ValueError as str:
- raise ValueError("%s: Cannot decode version info '%s'" %
- (self.commit.hash, line))
- self.in_change = int(value)
+ self.in_change = 'Series'
+ self.change_version = self.ParseVersion(value, line)
else:
self.AddToSeries(line, name, value)
self.skip_blank = True
if name == 'notes':
self.AddToCommit(line, name, value)
self.skip_blank = True
+ elif name == 'changes':
+ self.in_change = 'Commit'
+ self.change_version = self.ParseVersion(value, line)
# Detect the start of a new commit
elif commit_match:
elif line == '---':
self.state = STATE_DIFFS
- # Output the tags (signeoff first), then change list
+ # Output the tags (signoff first), then change list
out = []
log = self.series.MakeChangeLog(self.commit)
out += [line]
def Finalize(self):
"""Close out processing of this patch stream"""
+ self.FinalizeChange()
self.CloseCommit()
if self.lines_after_test:
self.warn.append('Found %d lines after TEST=' %
# Copyright (c) 2011 The Chromium OS Authors.
#
+from __future__ import print_function
+
+import collections
import itertools
import os
Changes in v4:
- Jog the dial back closer to the widget
- Changes in v3: None
Changes in v2:
- Fix the widget
- Jog the dial
- etc.
+ If there are no new changes in a patch, a note will be added
+
+ (no changes since v2)
+
+ Changes in v2:
+ - Fix the widget
+ - Jog the dial
"""
+ # Collect changes from the series and this commit
+ changes = collections.defaultdict(list)
+ for version, changelist in self.changes.items():
+ changes[version] += changelist
+ if commit:
+ for version, changelist in commit.changes.items():
+ changes[version] += [[commit, text] for text in changelist]
+
+ versions = sorted(changes, reverse=True)
+ newest_version = 1
+ if 'version' in self:
+ newest_version = max(newest_version, int(self.version))
+ if versions:
+ newest_version = max(newest_version, versions[0])
+
final = []
process_it = self.get('process_log', '').split(',')
process_it = [item.strip() for item in process_it]
need_blank = False
- for change in sorted(self.changes, reverse=True):
+ for version in versions:
out = []
- for this_commit, text in self.changes[change]:
+ for this_commit, text in changes[version]:
if commit and this_commit != commit:
continue
if 'uniq' not in process_it or text not in out:
out.append(text)
- line = 'Changes in v%d:' % change
- have_changes = len(out) > 0
if 'sort' in process_it:
out = sorted(out)
+ have_changes = len(out) > 0
+ line = 'Changes in v%d:' % version
if have_changes:
out.insert(0, line)
- else:
- out = [line + ' None']
- if need_blank:
- out.insert(0, '')
+ if version < newest_version and len(final) == 0:
+ out.insert(0, '')
+ out.insert(0, '(no changes since v%d)' % version)
+ newest_version = 0
+ # Only add a new line if we output something
+ if need_blank:
+ out.insert(0, '')
+ need_blank = False
final += out
- need_blank = have_changes
- if self.changes:
+ need_blank = need_blank or have_changes
+
+ if len(final) > 0:
final.append('')
+ elif newest_version != 1:
+ final = ['(no changes since v1)', '']
return final
def DoChecks(self):
Fix it with a cast.
Signed-off-by: Simon Glass <sjg@chromium.org>
+Commit-changes: 2
+- Changes only for this commit
+
Series-notes:
some notes
about some things
Cover-letter-cc: Lord Mëlchett <clergy@palace.gov>
Series-version: 3
Patch-cc: fred
+Series-process-log: sort, uniq
Series-changes: 4
- Some changes
+- Multi
+ line
+ change
+
+Commit-changes: 2
+- Changes only for this commit
+
+Cover-changes: 4
+- Some notes for the cover letter
Cover-letter:
test: A test patch series
This is a test of how the cover
-leter
+letter
works
END
---
Fix it with a cast.
Signed-off-by: Simon Glass <sjg@chromium.org>
+ Commit-changes: 2
+ - second revision change
+
Series-notes:
some notes
about some things
Cover-letter-cc: Lord Mëlchett <clergy@palace.gov>
Series-version: 3
Patch-cc: fred
+ Series-process-log: sort, uniq
Series-changes: 4
- Some changes
+ - Multi
+ line
+ change
+
+ Commit-changes: 2
+ - Changes only for this commit
+
+ Cover-changes: 4
+ - Some notes for the cover letter
Cover-letter:
test: A test patch series
This is a test of how the cover
- leter
+ letter
works
END