Jump to content
  • 0

Trying Pcduino2 on a newer kernel



After watching a video tutorial on youtube I have attempted to use the build scripts to create a newer image for my Pcduino V2. I had been initially using an image that I found on the archives which uses kernel 4.14, this worked fine for the most part apart from shutting down which would fail 9/10 to shutdown normally. the only way I could ensure that it would shutdown was to do poweroff -f otherwise it just went into a state where most things such as the wifi and usbs would no longer be detected and i was greeted with the message failed to reach target.poweroff. from what I could find out about the issue suggested that it was some kind of issue with systemd, but I could not find an actual solution.


Anyway I thought I would have ago at creating an image, I suppose given the age of the board issues are to be expected. I have had some success in fixes some of the issues encountered despite being relatively new to Armbian and Linux in general. After learning how to create patches, firstly I managed to get UART2 which was originally conflicting with the PMU as they shared the same assigned interrupt number of 3. From what I can tell this different to the normal PMU which I find that the power chip is normally referred to as there also appears to be some internal component within the A10 also called the 'PMU' . This seems to be something to do with core monitor as the A20 chip features 2 of these 'PMU's, one for each core. Looking at the user manual suggest that this should be 49. Now this has been patched I can use UART2 without getting an error although it is exposed as ttyS1 for some reason that I have yet to figure out.


The second patch I made was to get HDMI output working which I was able to do by using the Cubieboard as a point of reference as they share similar hardware. I found this out by initially using images targeted at the Cubieboard as they appear to be a lot more recent and provide HDMI out so I knew that copying the sections other would. Additionally I found  a way to get it working on my main 4K monitor after coming across a post which suggested lowering the size of the CMA buffer from the default size of 128mb to 64mb.


Now again the main problem I face is when I try to shutdown, this time it relates to a kernel panic:


[ 2508.547646] WARNING: CPU: 0 PID: 1 at drivers/i2c/i2c-core.h:41 i2c_transfer+                                                                             0x93/0xbc
[ 2508.561239] No atomic I2C transfer handler for 'i2c-1'
[ 2508.571971] Modules linked in: cfg80211 btusb btintel btrtl btbcm bluetooth a                                                                             xp20x_adc sun4i_gpadc_iio industrialio lima gpu_sched r8188eu(C) sun4i_ts ecdh_g                                                                             eneric rfkill ecc joydev input_leds sunxi_cedrus(C) v4l2_mem2mem videobuf2_dma_c                                                                             ontig videobuf2_memops videobuf2_v4l2 videobuf2_common zram evdev uio_pdrv_genir                                                                             q display_connector uio cpufreq_dt nfsd auth_rpcgss sch_fq_codel nfs_acl lockd g                                                                             race sunrpc ip_tables x_tables autofs4 pinctrl_axp209 sun4i_gpadc sunxi phy_gene                                                                             ric gpio_keys icplus(E)
[ 2508.635429] CPU: 0 PID: 1 Comm: systemd-shutdow Tainted: G         C  E     5                                                                             .15.32-sunxi #trunk
[ 2508.651044] Hardware name: Allwinner sun4i/sun5i Families
[ 2508.663328] [<c010cea9>] (unwind_backtrace) from [<c01095b9>] (show_stack+0x1                                                                             1/0x14)
[ 2508.678114] [<c01095b9>] (show_stack) from [<c09cc035>] (dump_stack_lvl+0x2b/                                                                             0x34)
[ 2508.692774] [<c09cc035>] (dump_stack_lvl) from [<c011b5a9>] (__warn+0xad/0xc0                                                                             )
[ 2508.707135] [<c011b5a9>] (__warn) from [<c09c5c23>] (warn_slowpath_fmt+0x5f/0                                                                             x7c)
[ 2508.721785] [<c09c5c23>] (warn_slowpath_fmt) from [<c0795a5f>] (i2c_transfer+                                                                             0x93/0xbc)
[ 2508.736949] [<c0795a5f>] (i2c_transfer) from [<c0795ac3>] (i2c_transfer_buffe                                                                             r_flags+0x3b/0x50)
[ 2508.752981] [<c0795ac3>] (i2c_transfer_buffer_flags) from [<c0697577>] (regma                                                                             p_i2c_write+0x13/0x24)
[ 2508.769489] [<c0697577>] (regmap_i2c_write) from [<c0694023>] (_regmap_raw_wr                                                                             ite_impl+0x48b/0x560)
[ 2508.786008] [<c0694023>] (_regmap_raw_write_impl) from [<c0694139>] (_regmap_                                                                             bus_raw_write+0x41/0x5c)
[ 2508.802806] [<c0694139>] (_regmap_bus_raw_write) from [<c06939b1>] (_regmap_w                                                                             rite+0x35/0xc8)
[ 2508.818874] [<c06939b1>] (_regmap_write) from [<c06948b5>] (regmap_write+0x29                                                                             /0x3c)
[ 2508.834263] [<c06948b5>] (regmap_write) from [<c069e723>] (axp20x_power_off+0                                                                             x23/0x30)
[ 2508.850053] [<c069e723>] (axp20x_power_off) from [<c0137ded>] (__do_sys_reboo                                                                             t+0xf5/0x16c)
[ 2508.866244] [<c0137ded>] (__do_sys_reboot) from [<c0100061>] (ret_fast_syscal                                                                             l+0x1/0x52)
[ 2508.882357] Exception stack(0xc154dfa8 to 0xc154dff0)
[ 2508.895490] dfa0:                   4321fedc bef4aaa8 fee1dead 28121969 4321f                                                                             edc 00000000
[ 2508.911883] dfc0: 4321fedc bef4aaa8 bef4aaa4 00000058 bef4aaa8 bef4aaa4 fffff                                                                             000 bef4aaac
[ 2508.928357] dfe0: 00000058 bef4aa1c b6eb81b5 b6e367e6
[ 2508.941715] ---[ end trace 8381275b8efb7dea ]---
[ 2510.584023] i2c i2c-1: mv64xxx: I2C bus locked, block: 1, time_left: 0
[ 2511.128016] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00                                                                             000000
[ 2511.175494] CPU: 0 PID: 1 Comm: systemd-shutdow Tainted: G        WC  E     5                                                                             .15.32-sunxi #trunk
[ 2511.192848] Hardware name: Allwinner sun4i/sun5i Families
[ 2511.206836] [<c010cea9>] (unwind_backtrace) from [<c01095b9>] (show_stack+0x1                                                                             1/0x14)
[ 2511.223311] [<c01095b9>] (show_stack) from [<c09cc035>] (dump_stack_lvl+0x2b/                                                                             0x34)
[ 2511.239614] [<c09cc035>] (dump_stack_lvl) from [<c09c5a4d>] (panic+0xc1/0x238                                                                             )
[ 2511.255555] [<c09c5a4d>] (panic) from [<c011fd5d>] (complete_and_exit+0x1/0x1                                                                             8)
[ 2511.271612] [<c011fd5d>] (complete_and_exit) from [<fee1dead>] (0xfee1dead)
[ 2511.287376] ---[ end Kernel panic - not syncing: Attempted to kill init! exit                                                                             code=0x00000000 ]---


I have seen 1 or 2 other post which appear to be a similar issue.


Aside from that SPI does not work, but I gather this is currently a more general issue due to changes in the way the SPIDEV works. it's strange, I can enable the overlay and specify the bus and it shows up under /dev as expected but it does not appear to be sending any date when try to interface with LCD screen. I did a loopback test and it return all zero as if the pins where disconnected. The last version I found it correctly worked on was a Cubieboard image with kernel 5.10. I did come across one post which suggested a possible fix although I'm not sure if this has been implemented yet.


I know this probably a bit of a length first post but thanks for taking the time to read and I look forward to hear suggestions of where to start looking next as I know I still have a lot to learn.


Here are the logs:









Link to comment
Share on other sites

1 answer to this question

Recommended Posts

  • 0

Well I finally a solution to the kernel panic on shutdown. I added a patch based on: https://github.com/torvalds/linux/commit/544a8d75f3d6e60e160cd92dc56321484598a993 which addressed the complaint of no atomic handler.


diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index 43bd2c4f3..3d8b86742 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -150,6 +150,7 @@ struct mv64xxx_i2c_data {
 	/* Clk div is 2 to the power n, not 2 to the power n + 1 */
 	bool			clk_n_base_0;
 	struct i2c_bus_recovery_info	rinfo;
+	bool			atomic;
 static struct mv64xxx_i2c_regs mv64xxx_i2c_regs_mv64xxx = {
@@ -179,7 +180,10 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data,
 	u32	dir = 0;
 	drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK |
+	if(!drv_data->atomic)
+		drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_INTEN;
 	if (msg->flags & I2C_M_RD)
 		dir = 1;
@@ -409,7 +413,8 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
 		drv_data->msg->buf[drv_data->byte_posn++] =
 			readl(drv_data->reg_base + drv_data->reg_offsets.data);
-		drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
+		if(!drv_data->atomic)
+			drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
 		writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
 			drv_data->reg_base + drv_data->reg_offsets.control);
 		drv_data->block = 0;
@@ -427,7 +432,8 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
 		drv_data->rc = -EIO;
-		drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
+		if(!drv_data->atomic)
+			drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_INTEN;
 		writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_STOP,
 			drv_data->reg_base + drv_data->reg_offsets.control);
 		drv_data->block = 0;
@@ -575,6 +581,18 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data)
 		spin_unlock_irqrestore(&drv_data->lock, flags);
+static void mv64xxx_i2c_wait_polling(struct mv64xxx_i2c_data *drv_data)
+	ktime_t timeout = ktime_add_ms(ktime_get(), drv_data->adapter.timeout);
+	while (READ_ONCE(drv_data->block) &&
+		ktime_compare(ktime_get(), timeout) < 0) {
+			udelay(5);
+			mv64xxx_i2c_intr(0, drv_data);
+	}
 static int
 mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg,
 				int is_last)
@@ -590,7 +608,10 @@ mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg,
 	spin_unlock_irqrestore(&drv_data->lock, flags);
-	mv64xxx_i2c_wait_for_completion(drv_data);
+	if(!drv_data->atomic)
+		mv64xxx_i2c_wait_for_completion(drv_data);
+	else
+		mv64xxx_i2c_wait_polling(drv_data);
 	return drv_data->rc;
@@ -717,7 +738,7 @@ mv64xxx_i2c_functionality(struct i2c_adapter *adap)
 static int
-mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
+mv64xxx_i2c_xfer_core(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
 	struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap);
 	int rc, ret = num;
@@ -730,7 +751,7 @@ mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
 	drv_data->msgs = msgs;
 	drv_data->num_msgs = num;
-	if (mv64xxx_i2c_can_offload(drv_data))
+	if (mv64xxx_i2c_can_offload(drv_data) && !drv_data->atomic)
 		rc = mv64xxx_i2c_offload_xfer(drv_data);
 		rc = mv64xxx_i2c_execute_msg(drv_data, &msgs[0], num == 1);
@@ -747,8 +768,25 @@ mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
 	return ret;
+static int mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
+	struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap);
+	drv_data->atomic = 0;
+	return mv64xxx_i2c_xfer_core(adap, msgs, num);
+static int mv64xxx_i2c_xfer_atomic(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
+	struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap);
+	drv_data->atomic = 1;
+	return mv64xxx_i2c_xfer_core(adap, msgs, num);
 static const struct i2c_algorithm mv64xxx_i2c_algo = {
 	.master_xfer = mv64xxx_i2c_xfer,
+	.master_xfer_atomic = mv64xxx_i2c_xfer_atomic,
 	.functionality = mv64xxx_i2c_functionality,


This may not be strictly be necessary as it still failed to shutdown until when looking through the options during the kernel configuration stage of the boot I found the following option:


Go to Device drivers > board level reset and power off

Then select regulator subsystem power off driver


Now when I shutdown the USB and 3v output are successfully turned off.


I thought that I should post this on the off chance that it may be usefully to someone with an A10/A20 board.

Link to comment
Share on other sites

Donate your old hardware to community. Start a giveaway Raffle!

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Answer this question...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...