diff --git a/prdoc/pr_6544.prdoc b/prdoc/pr_6544.prdoc
new file mode 100644
index 0000000000000..f2bc9627697dd
--- /dev/null
+++ b/prdoc/pr_6544.prdoc
@@ -0,0 +1,14 @@
+# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
+# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json
+
+title: Add and test events to conviction voting pallet
+
+doc:
+  - audience: Runtime Dev
+    description: |
+      Add event for the unlocking of an expired conviction vote's funds, and test recently added
+      voting events.
+
+crates:
+  - name: pallet-conviction-voting
+    bump: major
diff --git a/substrate/frame/conviction-voting/src/lib.rs b/substrate/frame/conviction-voting/src/lib.rs
index 85da1aed3c273..31bd6b85ec866 100644
--- a/substrate/frame/conviction-voting/src/lib.rs
+++ b/substrate/frame/conviction-voting/src/lib.rs
@@ -171,10 +171,12 @@ pub mod pallet {
 		Delegated(T::AccountId, T::AccountId),
 		/// An \[account\] has cancelled a previous delegation operation.
 		Undelegated(T::AccountId),
-		/// An account that has voted
+		/// An account has voted
 		Voted { who: T::AccountId, vote: AccountVote<BalanceOf<T, I>> },
-		/// A vote that been removed
+		/// A vote has been removed
 		VoteRemoved { who: T::AccountId, vote: AccountVote<BalanceOf<T, I>> },
+		/// The lockup period of a conviction vote expired, and the funds have been unlocked.
+		VoteUnlocked { who: T::AccountId, class: ClassOf<T, I> },
 	}
 
 	#[pallet::error]
@@ -315,6 +317,7 @@ pub mod pallet {
 			ensure_signed(origin)?;
 			let target = T::Lookup::lookup(target)?;
 			Self::update_lock(&class, &target);
+			Self::deposit_event(Event::VoteUnlocked { who: target, class });
 			Ok(())
 		}
 
diff --git a/substrate/frame/conviction-voting/src/tests.rs b/substrate/frame/conviction-voting/src/tests.rs
index 37cdd7a5b3388..dd9ee33ee1835 100644
--- a/substrate/frame/conviction-voting/src/tests.rs
+++ b/substrate/frame/conviction-voting/src/tests.rs
@@ -238,27 +238,52 @@ fn basic_stuff() {
 fn basic_voting_works() {
 	new_test_ext().execute_with(|| {
 		assert_ok!(Voting::vote(RuntimeOrigin::signed(1), 3, aye(2, 5)));
+		System::assert_last_event(tests::RuntimeEvent::Voting(Event::Voted {
+			who: 1,
+			vote: aye(2, 5),
+		}));
 		assert_eq!(tally(3), Tally::from_parts(10, 0, 2));
 		assert_ok!(Voting::vote(RuntimeOrigin::signed(1), 3, nay(2, 5)));
+		System::assert_last_event(tests::RuntimeEvent::Voting(Event::Voted {
+			who: 1,
+			vote: nay(2, 5),
+		}));
 		assert_eq!(tally(3), Tally::from_parts(0, 10, 0));
 		assert_eq!(Balances::usable_balance(1), 8);
 
 		assert_ok!(Voting::vote(RuntimeOrigin::signed(1), 3, aye(5, 1)));
+		System::assert_last_event(tests::RuntimeEvent::Voting(Event::Voted {
+			who: 1,
+			vote: aye(5, 1),
+		}));
 		assert_eq!(tally(3), Tally::from_parts(5, 0, 5));
 		assert_ok!(Voting::vote(RuntimeOrigin::signed(1), 3, nay(5, 1)));
 		assert_eq!(tally(3), Tally::from_parts(0, 5, 0));
 		assert_eq!(Balances::usable_balance(1), 5);
 
 		assert_ok!(Voting::vote(RuntimeOrigin::signed(1), 3, aye(10, 0)));
+		System::assert_last_event(tests::RuntimeEvent::Voting(Event::Voted {
+			who: 1,
+			vote: aye(10, 0),
+		}));
 		assert_eq!(tally(3), Tally::from_parts(1, 0, 10));
+
 		assert_ok!(Voting::vote(RuntimeOrigin::signed(1), 3, nay(10, 0)));
 		assert_eq!(tally(3), Tally::from_parts(0, 1, 0));
 		assert_eq!(Balances::usable_balance(1), 0);
 
 		assert_ok!(Voting::remove_vote(RuntimeOrigin::signed(1), None, 3));
+		System::assert_last_event(tests::RuntimeEvent::Voting(Event::VoteRemoved {
+			who: 1,
+			vote: nay(10, 0),
+		}));
 		assert_eq!(tally(3), Tally::from_parts(0, 0, 0));
 
 		assert_ok!(Voting::unlock(RuntimeOrigin::signed(1), class(3), 1));
+		System::assert_last_event(tests::RuntimeEvent::Voting(Event::VoteUnlocked {
+			who: 1,
+			class: class(3),
+		}));
 		assert_eq!(Balances::usable_balance(1), 10);
 	});
 }
@@ -267,15 +292,32 @@ fn basic_voting_works() {
 fn split_voting_works() {
 	new_test_ext().execute_with(|| {
 		assert_ok!(Voting::vote(RuntimeOrigin::signed(1), 3, split(10, 0)));
+		System::assert_last_event(tests::RuntimeEvent::Voting(Event::Voted {
+			who: 1,
+			vote: split(10, 0),
+		}));
 		assert_eq!(tally(3), Tally::from_parts(1, 0, 10));
+
 		assert_ok!(Voting::vote(RuntimeOrigin::signed(1), 3, split(5, 5)));
+		System::assert_last_event(tests::RuntimeEvent::Voting(Event::Voted {
+			who: 1,
+			vote: split(5, 5),
+		}));
 		assert_eq!(tally(3), Tally::from_parts(0, 0, 5));
 		assert_eq!(Balances::usable_balance(1), 0);
 
 		assert_ok!(Voting::remove_vote(RuntimeOrigin::signed(1), None, 3));
+		System::assert_last_event(tests::RuntimeEvent::Voting(Event::VoteRemoved {
+			who: 1,
+			vote: split(5, 5),
+		}));
 		assert_eq!(tally(3), Tally::from_parts(0, 0, 0));
 
 		assert_ok!(Voting::unlock(RuntimeOrigin::signed(1), class(3), 1));
+		System::assert_last_event(tests::RuntimeEvent::Voting(Event::VoteUnlocked {
+			who: 1,
+			class: class(3),
+		}));
 		assert_eq!(Balances::usable_balance(1), 10);
 	});
 }
@@ -284,25 +326,48 @@ fn split_voting_works() {
 fn abstain_voting_works() {
 	new_test_ext().execute_with(|| {
 		assert_ok!(Voting::vote(RuntimeOrigin::signed(1), 3, split_abstain(0, 0, 10)));
+		System::assert_last_event(tests::RuntimeEvent::Voting(Event::Voted {
+			who: 1,
+			vote: split_abstain(0, 0, 10),
+		}));
 		assert_eq!(tally(3), Tally::from_parts(0, 0, 10));
-		assert_ok!(Voting::vote(RuntimeOrigin::signed(2), 3, split_abstain(0, 0, 20)));
-		assert_eq!(tally(3), Tally::from_parts(0, 0, 30));
-		assert_ok!(Voting::vote(RuntimeOrigin::signed(2), 3, split_abstain(10, 0, 10)));
-		assert_eq!(tally(3), Tally::from_parts(1, 0, 30));
+
+		assert_ok!(Voting::vote(RuntimeOrigin::signed(6), 3, split_abstain(10, 0, 20)));
+		System::assert_last_event(tests::RuntimeEvent::Voting(Event::Voted {
+			who: 6,
+			vote: split_abstain(10, 0, 20),
+		}));
+		assert_eq!(tally(3), Tally::from_parts(1, 0, 40));
+
+		assert_ok!(Voting::vote(RuntimeOrigin::signed(6), 3, split_abstain(0, 0, 40)));
+		System::assert_last_event(tests::RuntimeEvent::Voting(Event::Voted {
+			who: 6,
+			vote: split_abstain(0, 0, 40),
+		}));
+
+		assert_eq!(tally(3), Tally::from_parts(0, 0, 50));
 		assert_eq!(Balances::usable_balance(1), 0);
-		assert_eq!(Balances::usable_balance(2), 0);
+		assert_eq!(Balances::usable_balance(6), 20);
 
 		assert_ok!(Voting::remove_vote(RuntimeOrigin::signed(1), None, 3));
-		assert_eq!(tally(3), Tally::from_parts(1, 0, 20));
-
-		assert_ok!(Voting::remove_vote(RuntimeOrigin::signed(2), None, 3));
+		System::assert_last_event(tests::RuntimeEvent::Voting(Event::VoteRemoved {
+			who: 1,
+			vote: split_abstain(0, 0, 10),
+		}));
+		assert_eq!(tally(3), Tally::from_parts(0, 0, 40));
+
+		assert_ok!(Voting::remove_vote(RuntimeOrigin::signed(6), Some(class(3)), 3));
+		System::assert_last_event(tests::RuntimeEvent::Voting(Event::VoteRemoved {
+			who: 6,
+			vote: split_abstain(0, 0, 40),
+		}));
 		assert_eq!(tally(3), Tally::from_parts(0, 0, 0));
 
 		assert_ok!(Voting::unlock(RuntimeOrigin::signed(1), class(3), 1));
 		assert_eq!(Balances::usable_balance(1), 10);
 
-		assert_ok!(Voting::unlock(RuntimeOrigin::signed(2), class(3), 2));
-		assert_eq!(Balances::usable_balance(2), 20);
+		assert_ok!(Voting::unlock(RuntimeOrigin::signed(6), class(3), 6));
+		assert_eq!(Balances::usable_balance(6), 60);
 	});
 }
 
diff --git a/substrate/frame/conviction-voting/src/types.rs b/substrate/frame/conviction-voting/src/types.rs
index d6bbb678a14b3..aa7dd578fbad6 100644
--- a/substrate/frame/conviction-voting/src/types.rs
+++ b/substrate/frame/conviction-voting/src/types.rs
@@ -117,14 +117,9 @@ impl<
 	pub fn from_parts(
 		ayes_with_conviction: Votes,
 		nays_with_conviction: Votes,
-		ayes: Votes,
+		support: Votes,
 	) -> Self {
-		Self {
-			ayes: ayes_with_conviction,
-			nays: nays_with_conviction,
-			support: ayes,
-			dummy: PhantomData,
-		}
+		Self { ayes: ayes_with_conviction, nays: nays_with_conviction, support, dummy: PhantomData }
 	}
 
 	/// Add an account's vote into the tally.